From e180672583968188ced34b56186a8edafb584f30 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Sun, 23 Apr 2023 02:55:49 +0530 Subject: [PATCH] Adding reverse option to address history query - Using option `reverse` as true will query the latest 1000 (max val) tx instead of the 1st 1000 tx. --- lib/services/address/index.js | 73 +++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/lib/services/address/index.js b/lib/services/address/index.js index 2b70b8f2..3c2c2044 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -195,9 +195,13 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream options.mempoolOnly = false; } + if(_.isUndefined(options.reverse)) { + options.reverse = false; + } + var old_support = false; //Quick support for `from` and `to` options (DEPRECATED! Not recommeded to use) - if( !_.isUndefined(options.from) || !_.isUndefined(options.to)) { + if(!_.isUndefined(options.from) || !_.isUndefined(options.to)) { old_support = true; options.from = options.from || 0; options.to = options.to || 0xffffffff; //Max value of to will actually be MAX_TX_QUERY_LIMIT_HISTORY @@ -223,13 +227,18 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream addr_count++; - if(!results.items.some(x => x.txid() === tx.txid())) //push only if tx not already in array - results.items.unshift(tx); //using unshift, so that recent tx (low) are at front + if(!results.items.some(x => x.txid() === tx.txid())) {//add only if tx not already in array + if(!options.reverse) + results.items.unshift(tx); //using unshift, so that recent tx (low) are at front + else + results.items.push(tx); + } + if(results.items.length > MAX_TX_QUERY_LIMIT_HISTORY) { //remove items from array when overflown results.items.sort((a, b) => (b.__height || 0xffffffff) - (a.__height || 0xffffffff) || b.txid().localeCompare(a.txid())); let del_count = results.items.length - MAX_TX_QUERY_LIMIT_HISTORY; - let start_index = old_support ? MAX_TX_QUERY_LIMIT_HISTORY : 0; + let start_index = (old_support || options.reverse) ? MAX_TX_QUERY_LIMIT_HISTORY : 0; results.items.splice(start_index, del_count); results.incomplete = true; @@ -884,7 +893,9 @@ AddressService.prototype._getTxidStream = function(address, options) { //reverse: true // txids stream from low confirmations to high confirmations }; //NOTE: commentted reverse to keep the order in asc when reading to preserve continuity when using `after` option - + //reverse option can be used explictly when latest tx are required + if(options.reverse) + criteria.reverse = true; // txid stream var txidStream = this._db.createKeyStream(criteria); @@ -1020,6 +1031,10 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre options.mempoolOnly = false; } + if (_.isUndefined(options.reverse)) { + options.reverse = false; + } + //declare the queue to process tx data var tmpTxList = {}; //store processed txid temporarily to ignore duplication @@ -1081,10 +1096,11 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre } - async.waterfall([ + const waterfall_array = []; + waterfall_array.push( //Find start height if `after` option is passed - function(next){ + function start_fall(next){ if(_.isUndefined(options.after)) { return next(); @@ -1106,10 +1122,10 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre }); - }, + }); - // stream the rest of the confirmed txids out of the address index - function(next) { + // stream the confirmed txids out of the address index + function query_confirmed_txids(next) { if (options.mempoolOnly) { //Option to query from mempool only (ie, unconfirmed txs only) return next(); @@ -1145,31 +1161,38 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre var txidStream = self._getTxidStream(address, options); txidStream.pipe(txIdTransformStream); - }, + } // query the mempool for relevant txs for this address - function(next) { + function query_mempool_txids(next) { if (!options.queryMempool) { return next(null, []); } - self._mempool.getTxidsByAddress(address, 'both', next); - }, + self._mempool.getTxidsByAddress(address, 'both', function(mempoolTxids) { - // add the meta data such as input values, etc. - function(mempoolTxids, next) { + if (mempoolTxids.length <= 0) { + return next(); + } + + mempoolTxids.map(id => q.push(id, chunkCallback)); + next(); + }); - if (mempoolTxids.length <= 0) { - return next(); - } + } - mempoolTxids.map(id => q.push(id, chunkCallback)); - next(); - }, + if(options.reverse){ //when queried txs in reverse key order, mempool first then confirmed + waterfall_array.push(query_mempool_txids); + waterfall_array.push(query_confirmed_txids); + } else { //when queried tx in key order, confirmed tx 1st, then mempool + waterfall_array.push(query_confirmed_txids); + waterfall_array.push(query_mempool_txids); + } + waterfall_array.push( //wait for queue to complete - function(next) { + function end_fall(next) { if(!q.started || q.idle()) //No tx in query (or) already finished querying return next(); @@ -1177,9 +1200,9 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre else q.drain = () => next(); - } + }); - ], callback); + async.waterfall(waterfall_array, callback); }