Address routes fixes.
This commit is contained in:
parent
d0eaedbb01
commit
72770944db
@ -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);
|
||||||
|
|||||||
@ -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]
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user