Address routes fixes.

This commit is contained in:
Chris Kleeschulte 2017-08-15 12:48:16 -04:00
parent d0eaedbb01
commit 72770944db
2 changed files with 70 additions and 33 deletions

View File

@ -16,12 +16,12 @@ var AddressService = function(options) {
BaseService.call(this, options); BaseService.call(this, options);
this._db = this.node.services.db; this._db = this.node.services.db;
this._tx = this.node.services.transaction; this._tx = this.node.services.transaction;
this._header = this.node.services.header;
this._timestamp = this.node.services.timestamp;
this._network = this.node.network; this._network = this.node.network;
if (this._network === 'livenet') { if (this._network === 'livenet') {
this._network = 'main'; this._network = 'main';
} }
this._timestamp = this.node.services.timestamp;
this._p2p = this.node.services.p2p;
}; };
inherits(AddressService, BaseService); inherits(AddressService, BaseService);
@ -47,17 +47,19 @@ AddressService.prototype.getAddressHistory = function(addresses, options, callba
self._getAddressHistory(address, options, next); self._getAddressHistory(address, options, next);
}, function(err, res) { }, function(err, txLists) {
if(err) { if(err) {
return callback(err); return callback(err);
} }
var txList = _.flatten(txLists);
var results = { var results = {
totalItems: res.length, totalItems: txList.length,
from: options.from, from: options.from,
to: options.to, to: options.to,
items: res items: txList
}; };
callback(null, results); callback(null, results);
@ -108,11 +110,12 @@ AddressService.prototype.getAddressSummary = function(address, options, callback
// tx stream // tx stream
var txStream = new Transform({ objectMode: true, highWaterMark: 1000 }); var txStream = new Transform({ objectMode: true, highWaterMark: 1000 });
txStream.on('end', function() { txStream.on('end', function() {
result.balance = Unit.fromSatoshis(result.balanceSat).toBTC(); result.balance = result.balanceSat;
result.totalReceived = Unit.fromSatoshis(result.totalReceivedSat).toBTC(); result.totalReceived = result.totalReceivedSat;
result.totalSent = Unit.fromSatoshis(result.totalSentSat).toBTC(); result.totalSent = result.totalSentSat;
result.unconfirmedBalance = Unit.fromSatoshis(result.unconfirmedBalanceSat).toBTC(); result.unconfirmedBalance = result.unconfirmedBalanceSat;
callback(null, result); callback(null, result);
}); });
@ -128,37 +131,50 @@ AddressService.prototype.getAddressSummary = function(address, options, callback
if(err) { if(err) {
log.error(err); log.error(err);
txStream.emit('error', err); txStream.emit('error', err);
return callback(); return;
} }
if (!tx) { if (!tx) {
log.error('Could not find tx for txid: ' + key.txid + '. This should not be possible, check indexes.'); 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.transactions.push(tx.txid());
result.txApperances++; result.txApperances++;
// is this an input?
if (key.input) { if (key.input) {
result.balanceSat -= tx.__inputValues[key.index]; return self._transaction.getInputValues(key.txid, null, function(err, tx) {
result.totalSentSat += tx.__inputValues[key.index];
if (confirmations < 1) { if(err) {
result.unconfirmedBalanceSat -= tx.__inputValues[key.index]; log.error(err);
result.unconfirmedTxApperances++; 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; if (confirmations < 1) {
result.totalReceivedSat += tx.outputs[key.index].value; result.unconfirmedBalanceSat -= tx.__inputValues[key.index];
result.unconfirmedTxApperances++;
}
if (confirmations < 1) { callback();
result.unconfirmedBalanceSat += tx.inputValues[key.index];
result.unconfirmedTxApperances++; });
}
}
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(); callback();
@ -190,19 +206,26 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c
var results = []; var results = [];
var start = self._encoding.encodeUtxoIndexKey(address); 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 = { var criteria = {
gte: start, gte: start,
lt: utils.getTerminalKey(start) lt: end
}; };
var utxoStream = self._db.createReadStream(criteria); var utxoStream = self._db.createReadStream(criteria);
var streamErr; var streamErr;
utxoStream.on('end', function() { utxoStream.on('end', function() {
if (streamErr) { if (streamErr) {
return callback(streamErr); return callback(streamErr);
} }
callback(null, results); callback(null, results);
}); });
utxoStream.on('error', function(err) { utxoStream.on('error', function(err) {
@ -210,8 +233,10 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c
}); });
utxoStream.on('data', function(data) { utxoStream.on('data', function(data) {
var key = self._encoding.decodeUtxoIndexKey(data.key); var key = self._encoding.decodeUtxoIndexKey(data.key);
var value = self._encoding.decodeUtxoIndexValue(data.value); var value = self._encoding.decodeUtxoIndexValue(data.value);
results.push({ results.push({
address: address, address: address,
txid: key.txid, txid: key.txid,
@ -219,10 +244,11 @@ AddressService.prototype.getAddressUnspentOutputs = function(address, options, c
ts: value.timestamp, ts: value.timestamp,
scriptPubKey: value.script.toString('hex'), scriptPubKey: value.script.toString('hex'),
amount: Unit.fromSatoshis(value.satoshis).toBTC(), amount: Unit.fromSatoshis(value.satoshis).toBTC(),
confirmations: self._p2p.getBestHeight() - value.height, confirmations: self._header.getBestHeight() - value.height,
satoshis: value.satoshis, satoshis: value.satoshis,
confirmationsFromCache: true confirmationsFromCache: true
}); });
}); });
}; };
@ -260,8 +286,11 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
var self = this; var self = this;
options = options || {}; options = options || {};
// var from = options.from || 0; options.start = options.start || 0;
// var to = options.to || 0xffffffff; options.end = options.end || 0xffffffff;
var endHeightBuf = new Buffer(4);
endHeightBuf.writeUInt32BE(options.end);
if (_.isUndefined(options.queryMempool)) { if (_.isUndefined(options.queryMempool)) {
options.queryMempool = true; options.queryMempool = true;
@ -269,7 +298,11 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
var results = []; var results = [];
var start = self._encoding.encodeAddressIndexKey(address, options.start); 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 = { var criteria = {
gte: start, gte: start,
@ -288,10 +321,13 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
var streamErr; var streamErr;
txStream.on('end', function() { txStream.on('end', function() {
if (streamErr) { if (streamErr) {
return callback(streamErr); return callback(streamErr);
} }
callback(null, results); callback(null, results);
}); });
// pipe txids into tx stream for processing // pipe txids into tx stream for processing
@ -311,6 +347,7 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
if (!tx) { if (!tx) {
log.error('Could not find tx for txid: ' + key.txid + '. This should not be possible, check indexes.'); log.error('Could not find tx for txid: ' + key.txid + '. This should not be possible, check indexes.');
txStream.emit('error', err);
return callback(); return callback();
} }
@ -472,7 +509,7 @@ AddressService.prototype._processOutput = function(tx, output, index, opts) {
} }
address.network = this._network; address.network = this._network;
var address = address.toString(); address = address.toString();
var txid = tx.txid(); var txid = tx.txid();
var addressKey = this._encoding.encodeAddressIndexKey(address, opts.block.height, txid); var addressKey = this._encoding.encodeAddressIndexKey(address, opts.block.height, txid);
var utxoKey = this._encoding.encodeUtxoIndexKey(address, txid, index); var utxoKey = this._encoding.encodeUtxoIndexKey(address, txid, index);

View File

@ -36,7 +36,7 @@ TransactionService.prototype.getAPIMethods = function() {
['getRawTransaction', this, this.getRawTransaction, 1], ['getRawTransaction', this, this.getRawTransaction, 1],
['getTransaction', this, this.getTransaction, 1], ['getTransaction', this, this.getTransaction, 1],
['getDetailedTransaction', this, this.getDetailedTransaction, 1], ['getDetailedTransaction', this, this.getDetailedTransaction, 1],
['getInputValues', this, this._getInputValues, 1] ['getInputValues', this, this._addMissingInputValues, 1]
]; ];
}; };