From 31344d770e66d658eb191c4b16de964965caede4 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Thu, 27 Apr 2023 03:40:55 +0530 Subject: [PATCH] Adding 'before' option to address APIs - Similar to 'after' option but inverse of it. ie, if before txid is passed, then query list/values before the given txid - 'before' and 'after' option can be use in combination or individually - cache system for address summary api wont be used with 'after' and/or 'before' option is used --- lib/services/address/index.js | 76 +++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/lib/services/address/index.js b/lib/services/address/index.js index 6c327b2a..37932776 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -179,8 +179,8 @@ AddressService.prototype.getAddressHistory = function(addresses, options, stream var self = this; options = options || {}; - //options.from = options.from || 0; //Deprecated, use `after` option - //options.to = options.to || 0xffffffff; //Deprecated, use `after` option + //options.from = options.from || 0; //Deprecated, use `after` and `before` option + //options.to = options.to || 0xffffffff; //Deprecated, use `after` and `before` option if(!_.isFunction(callback)){ //if only 3 args, then streamer is callback callback = streamer; @@ -323,8 +323,8 @@ AddressService.prototype.getAddressSummary = function(address, options, streamer var self = this; options = options || {}; - //options.from = options.from || 0; //Deprecated - //options.to = options.to || 0xffffffff; //Deprecated + //options.from = options.from || 0; //Deprecated, use `after` and `before` option + //options.to = options.to || 0xffffffff; //Deprecated, use `after` and `before` option if (_.isUndefined(options.queryMempool)) { options.queryMempool = true; @@ -351,7 +351,7 @@ AddressService.prototype.getAddressSummary = function(address, options, streamer txApperances: 0, }; - var useCache = _.isUndefined(options.after); + var useCache = _.isUndefined(options.after) && _.isUndefined(options.before); var lastTx, lastBlock; self._loadCache(address, result, useCache, function(err, lastCachedTx) { @@ -485,7 +485,7 @@ AddressService.prototype._storeCache = function(address, lastCacheTx, lastCacheB AddressService.prototype._loadCache = function(address, result, useCache, callback) { const self = this; - if(!useCache) //skip if useCache is false (cases like 'after' parameter is used by client) + if(!useCache) //skip if useCache is false (cases like 'after' and/or 'before' parameter is used by client) return callback(); var key = self._encoding.encodeAddressCacheKey(address); @@ -871,28 +871,18 @@ AddressService.prototype.stop = function(callback) { AddressService.prototype._getTxidStream = function(address, options) { - var start; - if(options.after) { - start = this._encoding.encodeAddressIndexKey(address, options.start, options.after, 0xffffffff, 1, 0xffffffff); //0xffffffff is for getting after the txid - } else { - start = this._encoding.encodeAddressIndexKey(address, options.start); - } + var criteria = {}; - var endHeightBuf = new Buffer(4); - endHeightBuf.writeUInt32BE(options.end); - - var end = Buffer.concat([ - start.slice(0, address.length + 4), - endHeightBuf, - new Buffer(new Array(83).join('f'), 'hex') - ]); - - var criteria = { - gte: start, - 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 + if(options.after) + criteria.gt = this._encoding.encodeAddressIndexKey(address, options.start, options.after, 0xffffffff, 1, 0xffffffff); //0xffffffff is for getting after the txid + else + criteria.gte = this._encoding.encodeAddressIndexKey(address, options.start); + + if(options.before) + criteria.lt = this._encoding.encodeAddressIndexKey(address, options.end, options.before); //get before the txid + else + criteria.lte = this._encoding.encodeAddressIndexKey(address, options.end, Array(65).join('f'), 0xffffffff, 1, 0xffffffff); + //reverse option can be used explictly when latest tx are required if(options.reverse) criteria.reverse = true; @@ -1020,8 +1010,8 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre options.start = options.start || 0; options.end = options.end || 0xffffffff; - //options.from = options.from || 0; //Deprecated, use `after` option - //options.to = options.to || 0xffffffff; //Deprecated, use `after` option + //options.from = options.from || 0; //Deprecated, use `after` and `before` option + //options.to = options.to || 0xffffffff; //Deprecated, use `after` and `before` option if (_.isUndefined(options.queryMempool)) { options.queryMempool = true; @@ -1100,7 +1090,7 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre waterfall_array.push( //Find start height if `after` option is passed - function start_fall(next){ + function parse_after_id(next){ if(_.isUndefined(options.after)) { return next(); @@ -1124,6 +1114,32 @@ AddressService.prototype._streamAddressSummary = function(address, options, stre }); + waterfall_array.push( + //Find end height if `before` option is passed + function parse_before_id(next){ + + if(_.isUndefined(options.before)) { + return next(); + } + + self._transaction.getTransaction(options.before, options, function(err, tx) { + + if(tx && tx.confirmations && tx.height <= options.end) { + + options.end = tx.height; + + } else { + + delete options.before; + + } + + next(); + + }); + + }); + // stream the confirmed txids out of the address index function query_confirmed_txids(next) {