From 72770944db674739b1b200a5d7fdb8bcb92150df Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Tue, 15 Aug 2017 12:48:16 -0400 Subject: [PATCH] Address routes fixes. --- lib/services/address/index.js | 101 ++++++++++++++++++++---------- lib/services/transaction/index.js | 2 +- 2 files changed, 70 insertions(+), 33 deletions(-) diff --git a/lib/services/address/index.js b/lib/services/address/index.js index 0fe9830b..07cc80f8 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -16,12 +16,12 @@ var AddressService = function(options) { BaseService.call(this, options); this._db = this.node.services.db; this._tx = this.node.services.transaction; + this._header = this.node.services.header; + this._timestamp = this.node.services.timestamp; this._network = this.node.network; if (this._network === 'livenet') { this._network = 'main'; } - this._timestamp = this.node.services.timestamp; - this._p2p = this.node.services.p2p; }; inherits(AddressService, BaseService); @@ -47,17 +47,19 @@ AddressService.prototype.getAddressHistory = function(addresses, options, callba self._getAddressHistory(address, options, next); - }, function(err, res) { + }, function(err, txLists) { if(err) { return callback(err); } + var txList = _.flatten(txLists); + var results = { - totalItems: res.length, + totalItems: txList.length, from: options.from, to: options.to, - items: res + items: txList }; callback(null, results); @@ -108,11 +110,12 @@ AddressService.prototype.getAddressSummary = function(address, options, callback // tx stream var txStream = new Transform({ objectMode: true, highWaterMark: 1000 }); + txStream.on('end', function() { - result.balance = Unit.fromSatoshis(result.balanceSat).toBTC(); - result.totalReceived = Unit.fromSatoshis(result.totalReceivedSat).toBTC(); - result.totalSent = Unit.fromSatoshis(result.totalSentSat).toBTC(); - result.unconfirmedBalance = Unit.fromSatoshis(result.unconfirmedBalanceSat).toBTC(); + result.balance = result.balanceSat; + result.totalReceived = result.totalReceivedSat; + result.totalSent = result.totalSentSat; + result.unconfirmedBalance = result.unconfirmedBalanceSat; callback(null, result); }); @@ -128,37 +131,50 @@ AddressService.prototype.getAddressSummary = function(address, options, callback if(err) { log.error(err); txStream.emit('error', err); - return callback(); + return; } if (!tx) { log.error('Could not find tx for txid: ' + key.txid + '. This should not be possible, check indexes.'); - return callback(); + txStream.emit('error', new Error('Txid should map to a tx.')); + return; } - var confirmations = self._p2p.getBestHeight() - key.height; + var confirmations = self._header.getBestHeight() - key.height; + result.transactions.push(tx.txid()); result.txApperances++; - + // is this an input? if (key.input) { - result.balanceSat -= tx.__inputValues[key.index]; - result.totalSentSat += tx.__inputValues[key.index]; + return self._transaction.getInputValues(key.txid, null, function(err, tx) { - if (confirmations < 1) { - result.unconfirmedBalanceSat -= tx.__inputValues[key.index]; - result.unconfirmedTxApperances++; - } + if(err) { + log.error(err); + txStream.emit('error', err); + return; + } - } else { + result.balanceSat -= tx.__inputValues[key.index]; + result.totalSentSat += tx.__inputValues[key.index]; - result.balanceSat += tx.outputs[key.index].value; - result.totalReceivedSat += tx.outputs[key.index].value; + if (confirmations < 1) { + result.unconfirmedBalanceSat -= tx.__inputValues[key.index]; + result.unconfirmedTxApperances++; + } - if (confirmations < 1) { - result.unconfirmedBalanceSat += tx.inputValues[key.index]; - result.unconfirmedTxApperances++; - } + callback(); + + }); + + } + + result.balanceSat += tx.outputs[key.index].value; + result.totalReceivedSat += tx.outputs[key.index].value; + + if (confirmations < 1) { + result.unconfirmedBalanceSat += tx.__inputValues[key.index]; + result.unconfirmedTxApperances++; } callback(); @@ -190,19 +206,26 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c var results = []; var start = self._encoding.encodeUtxoIndexKey(address); + var final = new Buffer(new Array(73).join('f'), 'hex'); + var end = Buffer.concat([ start.slice(0, -36), final ]); + var criteria = { gte: start, - lt: utils.getTerminalKey(start) + lt: end }; var utxoStream = self._db.createReadStream(criteria); var streamErr; + utxoStream.on('end', function() { + if (streamErr) { return callback(streamErr); } + callback(null, results); + }); utxoStream.on('error', function(err) { @@ -210,8 +233,10 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c }); utxoStream.on('data', function(data) { + var key = self._encoding.decodeUtxoIndexKey(data.key); var value = self._encoding.decodeUtxoIndexValue(data.value); + results.push({ address: address, txid: key.txid, @@ -219,10 +244,11 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c ts: value.timestamp, scriptPubKey: value.script.toString('hex'), amount: Unit.fromSatoshis(value.satoshis).toBTC(), - confirmations: self._p2p.getBestHeight() - value.height, + confirmations: self._header.getBestHeight() - value.height, satoshis: value.satoshis, confirmationsFromCache: true }); + }); }; @@ -260,8 +286,11 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac var self = this; options = options || {}; - // var from = options.from || 0; - // var to = options.to || 0xffffffff; + options.start = options.start || 0; + options.end = options.end || 0xffffffff; + + var endHeightBuf = new Buffer(4); + endHeightBuf.writeUInt32BE(options.end); if (_.isUndefined(options.queryMempool)) { options.queryMempool = true; @@ -269,7 +298,11 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac var results = []; var start = self._encoding.encodeAddressIndexKey(address, options.start); - var end = self._encoding.encodeAddressIndexKey(address, 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, @@ -288,10 +321,13 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac var streamErr; txStream.on('end', function() { + if (streamErr) { return callback(streamErr); } + callback(null, results); + }); // pipe txids into tx stream for processing @@ -311,6 +347,7 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac if (!tx) { log.error('Could not find tx for txid: ' + key.txid + '. This should not be possible, check indexes.'); + txStream.emit('error', err); return callback(); } @@ -472,7 +509,7 @@ AddressService.prototype._processOutput = function(tx, output, index, opts) { } address.network = this._network; - var address = address.toString(); + address = address.toString(); var txid = tx.txid(); var addressKey = this._encoding.encodeAddressIndexKey(address, opts.block.height, txid); var utxoKey = this._encoding.encodeUtxoIndexKey(address, txid, index); diff --git a/lib/services/transaction/index.js b/lib/services/transaction/index.js index a1b4ae4c..67ff999b 100644 --- a/lib/services/transaction/index.js +++ b/lib/services/transaction/index.js @@ -36,7 +36,7 @@ TransactionService.prototype.getAPIMethods = function() { ['getRawTransaction', this, this.getRawTransaction, 1], ['getTransaction', this, this.getTransaction, 1], ['getDetailedTransaction', this, this.getDetailedTransaction, 1], - ['getInputValues', this, this._getInputValues, 1] + ['getInputValues', this, this._addMissingInputValues, 1] ]; };