From 774d830fffbaa9bf259a9b0c4c882ca1f8529f00 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Sun, 5 Feb 2023 03:12:04 +0530 Subject: [PATCH] Improvements to API query options - Stop request-stream process when stop-flag is on - Changed: order of reading db to forward (so that continuity will be preserved with `after` option and ws api calls). And changes required for the same. - Deprecating options (from and to) in calls that are not supported - Added: Temporary support for from and to option in getAddressHistory --- lib/services/address/index.js | 107 ++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/lib/services/address/index.js b/lib/services/address/index.js index 0cf0d0fb..81bb9712 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -177,8 +177,8 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream var self = this; options = options || {}; - options.from = options.from || 0; - options.to = options.to || 0xffffffff; + //options.from = options.from || 0; //Deprecated, use `after` option + //options.to = options.to || 0xffffffff; //Deprecated, use `after` option if(typeof callback !== 'function'){ //if only 3 args, then streamer is callback callback = streamer; @@ -207,8 +207,10 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream if(!options.txNotNeeded) { results.totalCount++; + if(results.items.length < MAX_TX_QUERY_LIMIT && !results.items.some(x => x.txid() === tx.txid())) //push only if tx not already in array - results.items.push(tx); + results.items.unshift(tx); //using unshift, so that recent tx (low) are at front + } streamer(null, tx); @@ -225,6 +227,13 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream results.items.sort((a, b) => b.__height - a.__height || a.txid().localeCompare(b.txid())); results.totalCount = parseInt(results.totalCount.toFixed()); + //Quick support for `from` and `to` options (DEPRECATED! Not recommeded to use) + if( !_.isUndefined(options.from) || !_.isUndefined(options.to)) { + options.from = options.from || 0; + options.to = options.to || 0xffffffff; //Max value of to will actually be MAX_TX_QUERY_LIMIT + results.items = results.items.slice(options.from, options.to); + } + callback(null, results); }) @@ -258,7 +267,7 @@ AddressService.prototype.__getAddressSummary = function(address, options, callba txApperances: 0, }; - self.getAddressHistory(address, options, function(err, results) { + self.__getAddressHistory(address, options, function(err, results) { //old fn if (err) { return callback(err); @@ -281,8 +290,8 @@ AddressService.prototype.getAddressSummary = function(address, options, streamer var self = this; options = options || {}; - options.from = options.from || 0; - options.to = options.to || 0xffffffff; + //options.from = options.from || 0; //Deprecated + //options.to = options.to || 0xffffffff; //Deprecated options.txNotNeeded = true; //no need to store tx details in result if (_.isUndefined(options.queryMempool)) { @@ -328,6 +337,8 @@ AddressService.prototype.getAddressSummary = function(address, options, streamer result.totalReceivedSat = parseInt(result.totalReceivedSat.toFixed()); result.totalSentSat = parseInt(result.totalSentSat.toFixed()); result.txApperances = parseInt(result.txApperances.toFixed()); + result.unconfirmedBalanceSat = parseInt(result.unconfirmedBalanceSat.toFixed()); + result.unconfirmedTxApperances = parseInt(result.unconfirmedTxApperances.toFixed()); result.balance = Unit.fromSatoshis(result.balanceSat).toBTC(); result.totalReceived = Unit.fromSatoshis(result.totalReceivedSat).toBTC(); @@ -463,7 +474,7 @@ AddressService.prototype._getInputResults = function(tx, address) { }; -AddressService.prototype._aggregateAddressSummaryResult = function (tx, address, result, options){ +AddressService.prototype._aggregateAddressSummaryResult = function (tx, address, result, options) { var self = this; @@ -486,12 +497,21 @@ AddressService.prototype._aggregateAddressSummaryResult = function (tx, address, } if (!options.noTxList) { + if (!result.transactions) { result.transactions = []; } + let txid = tx.txid(); - if(!result.transactions.includes(txid) && result.transactions.length < MAX_TX_QUERY_LIMIT) //push txid only if its not in the array (list limit not maxed out) - result.transactions.push(txid); + if(!result.transactions.includes(txid)) { //push txid only if its not in the array + + result.transactions.unshift(txid); //using unshift, so that recent tx (low confirmation) are at front + + if(result.transactions.length > MAX_TX_QUERY_LIMIT) + result.transactions.pop(); //pop the oldest tx in list (when list limit is maxed out) + + } + } } @@ -676,9 +696,10 @@ AddressService.prototype._getTxidStream = function(address, options) { var criteria = { gte: start, - lte: end, - reverse: true // txids stream from low confirmations to high confirmations + lte: end + //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 // txid stream var txidStream = this._db.createKeyStream(criteria); @@ -690,6 +711,7 @@ AddressService.prototype._getTxidStream = function(address, options) { return txidStream; }; +//(used by old fn) AddressService.prototype._getAddressTxHistory = function(options, callback) { var self = this; @@ -718,6 +740,7 @@ AddressService.prototype._getAddressTxHistory = function(options, callback) { }; +//(used by old fn) AddressService.prototype._getAddressTxidHistory = function(address, options, callback) { var self = this; @@ -781,7 +804,9 @@ AddressService.prototype._getAddressTxidHistory = function(address, options, cal return; } - results.push({ txid: txInfo.txid, height: txInfo.height }); + if(!results.some(r => r.txid == txInfo.txid)) //add txid to array only if its not already there + results.push({ txid: txInfo.txid, height: txInfo.height }); + callback(); }; @@ -800,8 +825,8 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre options.start = options.start || 0; options.end = options.end || 0xffffffff; - options.from = options.from || 0; //TODO: check from/to options are working or not - options.to = options.to || 0xffffffff; + //options.from = options.from || 0; //Deprecated, use `after` option + //options.to = options.to || 0xffffffff; //Deprecated, use `after` option if (_.isUndefined(options.queryMempool)) { options.queryMempool = true; @@ -858,7 +883,7 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre streamer(err, tx); - if(err){ + if(err || options.flag_stop){ q.kill(); return callback(); @@ -868,34 +893,14 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre async.waterfall([ - // query the mempool for relevant txs for this address - function(next) { - - if (!options.queryMempool) { - return next(null, []); - } - - self._mempool.getTxidsByAddress(address, 'both', next); - }, - - // 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(); - }, - + //Find start height if `after` option is passed function(next){ if(_.isUndefined(options.after)) { return next(); } - self._transaction.getTransaction(id.txid, options, function(err, tx) { + self._transaction.getTransaction(options.after, options, function(err, tx) { if(tx && tx.confirmations && tx.height >= options.start) { @@ -934,6 +939,10 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre }); txIdTransformStream._transform = function(chunk, enc, cb) { + + if(options.flag_stop)//stop data query + return txIdTransformStream.unpipe(); + var txInfo = self._encoding.decodeAddressIndexKey(chunk); q.push({ txid: txInfo.txid, height: txInfo.height }, chunkCallback); @@ -943,7 +952,29 @@ 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) { + + if (!options.queryMempool) { + return next(null, []); + } + + self._mempool.getTxidsByAddress(address, 'both', next); + }, + + // 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(); + }, + ], callback); }