diff --git a/lib/services/bitcoind.js b/lib/services/bitcoind.js index edf0537e..1ef76e90 100644 --- a/lib/services/bitcoind.js +++ b/lib/services/bitcoind.js @@ -394,28 +394,69 @@ Bitcoin.prototype.getAddressUnspentOutputs = function(addressArg, options, callb } }; +Bitcoin.prototype._getBalanceFromMempool = function(deltas) { + var satoshis = 0; + for (var i = 0; i < deltas.length; i++) { + satoshis += deltas[i].satoshis; + } + return satoshis; +}; + +Bitcoin.prototype._getTxidsFromMempool = function(deltas) { + var mempoolTxids = []; + var mempoolTxidsKnown = {}; + for (var i = 0; i < deltas.length; i++) { + var txid = deltas[i].txid; + if (!mempoolTxidsKnown[txid]) { + mempoolTxids.push(txid); + mempoolTxidsKnown[txid] = true; + } + } + return mempoolTxids; +}; + Bitcoin.prototype.getAddressTxids = function(addressArg, options, callback) { var self = this; + var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var addresses = [addressArg]; if (Array.isArray(addressArg)) { addresses = addressArg; } var cacheKey = addresses.join(''); + var mempoolTxids = []; var txids = self.txidsCache.get(cacheKey); - if (txids) { - return setImmediate(function() { - callback(null, txids); - }); - } else { - self.client.getAddressTxids({addresses: addresses}, function(err, response) { + + function finish() { + if (txids) { + var allTxids = mempoolTxids.reverse().concat(txids); + return setImmediate(function() { + callback(null, allTxids); + }); + } else { + self.client.getAddressTxids({addresses: addresses}, function(err, response) { + if (err) { + return callback(err); + } + response.result.reverse(); + self.txidsCache.set(cacheKey, response.result); + var allTxids = mempoolTxids.reverse().concat(response.result); + return callback(null, allTxids); + }); + } + } + + if (queryMempool) { + self.client.getAddressMempool({addresses: addresses}, function(err, response) { if (err) { return callback(err); } - response.result.reverse(); - self.txidsCache.set(cacheKey, response.result); - return callback(null, response.result); + mempoolTxids = self._getTxidsFromMempool(response.result); + finish(); }); + } else { + finish(); } + }; Bitcoin.prototype._getConfirmationsDetail = function(transaction) { @@ -585,10 +626,11 @@ Bitcoin.prototype.getAddressHistory = function(addressArg, options, callback) { }; Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { - // TODO: optional mempool var self = this; var summary = {}; + var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var summaryTxids = []; + var mempoolTxids = []; var addresses = [addressArg]; if (Array.isArray(addressArg)) { @@ -597,14 +639,10 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { var cacheKey = addresses.join(''); - if (_.isUndefined(options.queryMempool)) { - options.queryMempool = true; - } - function querySummary() { async.parallel([ function getTxList(done) { - self.getAddressTxids(addressArg, options, function(err, txids) { + self.getAddressTxids(addressArg, {queryMempool: false}, function(err, txids) { if (err) { return done(err); } @@ -623,14 +661,29 @@ Bitcoin.prototype.getAddressSummary = function(addressArg, options, callback) { summary.balance = data.balance; done(); }); - } + }, + function getMempool(done) { + if (!queryMempool) { + return done(); + } + self.client.getAddressMempool({'addresses': [addressArg]}, function(err, response) { + if (err) { + return done(err); + } + mempoolTxids = self._getTxidsFromMempool(response.result); + summary.unconfirmedAppearances = mempoolTxids.length; + summary.unconfirmedBalance = self._getBalanceFromMempool(response.result); + done(); + }); + }, ], function(err) { if (err) { return callback(err); } self.summaryCache.set(cacheKey, summary); if (!options.noTxList) { - summary.txids = summaryTxids; + var allTxids = mempoolTxids.reverse().concat(summaryTxids); + summary.txids = allTxids; } callback(null, summary); });