Fixed mempool gathering.

This commit is contained in:
Chris Kleeschulte 2017-10-09 16:24:25 -04:00
parent fba71ee1aa
commit 5007104a4f
No known key found for this signature in database
GPG Key ID: 33195D27EF6BDB7F
7 changed files with 119 additions and 80 deletions

View File

@ -11,7 +11,6 @@ var _ = bitcore.deps._;
var Encoding = require('./encoding');
var Transform = require('stream').Transform;
var assert = require('assert');
var Stream = require('stream');
var utils = require('../../utils');
var AddressService = function(options) {
@ -373,17 +372,34 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
async.waterfall([
// query the mempool for relevant txs for this address
function(next) {
if (!options.queryMempool) {
return next();
return next(null, []);
}
self._mempool.getTxidsByAddress(address, next);
self._mempool.getTxsByAddress(address, next);
},
// add the meta data such as input values, etc.
function(mempoolTxs, next) {
if (mempoolTxs.length <= 0) {
return next();
}
async.mapSeries(mempoolTxs, function(tx, next) {
self._transaction.setTxMetaInfo(tx, options, next);
}, function(err, txs) {
if (err) {
return next(err);
}
options.results = txs;
next();
});
},
// stream the rest of the confirmed txids out of the address index
function(mempoolTxids, next) {
function(next) {
var txStream = self._getTxStream(address, options);
@ -395,20 +411,6 @@ AddressService.prototype._getAddressHistory = function(address, options, callbac
log.error('Address Service: txstream err: ' + err);
txStream.unpipe();
});
if (mempoolTxids.length > 0) {
var mempoolTxidStream = new Stream.Readable({ objectMode: true });
mempoolTxidStream.pipe(txStream);
mempoolTxids.forEach(function(txid) {
mempoolTxidStream.push(txid);
});
mempoolTxidStream.push(null);
}
var txidStream = self._getTxidStream(address, options);
txidStream.pipe(txStream);
}

View File

@ -138,7 +138,7 @@ MempoolService.prototype.getMempoolTransaction = function(txid, callback) {
};
// TODO optimize this using another index?
MempoolService.prototype.getTxidsByAddress = function(address, callback) {
MempoolService.prototype.getTxsByAddress = function(address, callback) {
var self = this;
var results = [];
@ -162,9 +162,9 @@ MempoolService.prototype.getTxidsByAddress = function(address, callback) {
stream.on('data', function(data) {
var tx = self._encoding.decodeMempoolTransactionValue(data.value);
var txid = self._involvesAddress(tx, address);
if (txid) {
results.push(txid);
tx = self._involvesAddress(tx, address);
if (tx) {
results.push(tx);
}
});
@ -193,7 +193,7 @@ MempoolService.prototype._involvesAddress = function(tx, address) {
for(var i = 0; i < collections.length; i++) {
var hasAddress = contains(collections[i], this._network);
if (hasAddress) {
return tx.txid();
return tx;
}
}

View File

@ -42,7 +42,8 @@ TransactionService.prototype.getAPIMethods = function() {
return [
['getRawTransaction', this, this.getRawTransaction, 1],
['getTransaction', this, this.getTransaction, 1],
['getDetailedTransaction', this, this.getDetailedTransaction, 1]
['getDetailedTransaction', this, this.getDetailedTransaction, 1],
['setTxMetaInfo', this, this.setTxMetaInfo, 2]
];
};
@ -119,7 +120,7 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
self._getTransaction.bind(self, txid, options),
self._getSupplementaryTransactionInfo.bind(self),
self._getMempoolTransaction.bind(self),
self._setMetaInfo.bind(self)
self.setTxMetaInfo.bind(self)
], callback);
};
@ -151,42 +152,75 @@ TransactionService.prototype._getSupplementaryTransactionInfo = function(txid, t
});
};
TransactionService.prototype._setMetaInfo = function(tx, options, callback) {
TransactionService.prototype.setTxMetaInfo = function(tx, options, callback) {
var self = this;
if (!tx) {
return callback();
}
// output values
var outputSatoshis = 0;
tx.outputs.forEach(function(output) {
outputSatoshis += output.value;
});
tx.outputSatoshis = outputSatoshis;
//input values
if (!tx.inputs[0].isCoinbase()) {
var inputSatoshis = 0;
tx.__inputValues.forEach(function(val) {
if (val >+ 0) {
inputSatoshis += val;
async.waterfall([
function(next) {
if (tx.__inputValues) {
return next(null, tx);
}
});
// the tx's that contain these input values could, themselves be unconfirmed
// we are also assuming that this tx is from thet mempool
self._getInputValues(tx, options, function(err, inputValues) {
var feeSatoshis = inputSatoshis - outputSatoshis;
tx.inputSatoshis = inputSatoshis;
tx.feeSatoshis = feeSatoshis;
if (err) {
return callback(err);
}
}
tx.__inputValues = inputValues;
tx.confirmations = 0;
tx.blockHash = null;
tx.__blockHash = null;
next(null, tx);
callback(null, tx);
});
},
function(tx, next) {
// output values
var outputSatoshis = 0;
tx.outputs.forEach(function(output) {
outputSatoshis += output.value;
});
tx.outputSatoshis = outputSatoshis;
//input values
if (!tx.inputs[0].isCoinbase()) {
var inputSatoshis = 0;
assert(tx.__inputValues.length === tx.inputs.length,
'Transaction Service: input values length is not the same as the number of inputs.');
tx.__inputValues.forEach(function(val) {
if (val >+ 0) {
inputSatoshis += val;
}
});
var feeSatoshis = inputSatoshis - outputSatoshis;
tx.inputSatoshis = inputSatoshis;
tx.feeSatoshis = feeSatoshis;
}
next(null, tx);
}
], function(err, tx) {
if (err) {
return callback(err);
}
callback(null, tx);
});
};
@ -209,21 +243,7 @@ TransactionService.prototype._getMempoolTransaction = function(txid, tx, options
return callback(null, tx, options);
}
// the tx's that contain these input values could, themselves be unconfirmed
self._getInputValues(tx, options, function(err, inputValues) {
if (err) {
return callback(err);
}
tx.__inputValues = inputValues;
tx.confirmations = 0;
tx.blockHash = null;
tx.__blockHash = null;
callback(null, tx, options);
});
callback(null, tx, options);
});
};

18
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "bitcore-node",
"version": "5.0.0-beta.15",
"version": "5.0.0-beta.16",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -4266,14 +4266,6 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
@ -4293,6 +4285,14 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",

View File

@ -5,7 +5,7 @@
"node": ">=8.0.0"
},
"author": "BitPay <dev@bitpay.com>",
"version": "5.0.0-beta.15",
"version": "5.0.0-beta.16",
"main": "./index.js",
"repository": "git://github.com/bitpay/bitcore-node.git",
"homepage": "https://github.com/bitpay/bitcore-node",

View File

@ -81,8 +81,8 @@ describe('Address Service', function() {
var getHeaderHash = sandbox.stub().callsArgWith(1, null, 'aa');
var getBlockHeader = sandbox.stub().callsArgWith(1, null, 'aa');
var getTxidsByAddress = sandbox.stub().callsArgWith(1, null, []);
addressService._mempool = { getTxidsByAddress: getTxidsByAddress };
var getTxsByAddress = sandbox.stub().callsArgWith(1, null, []);
addressService._mempool = { getTxsByAddress: getTxsByAddress };
addressService._header = {
getHeaderHash: getHeaderHash,
@ -108,7 +108,7 @@ describe('Address Service', function() {
if (err) {
return done(err);
}
expect(getTxidsByAddress.calledOnce).to.be.true;
expect(getTxsByAddress.calledOnce).to.be.true;
expect(getTransaction.calledOnce).to.be.true;
expect(res).to.deep.equal([
{

View File

@ -111,4 +111,21 @@ describe('Transaction Service', function() {
});
});
describe('#setMetaTxInfo', function() {
it('should set the appropriate meta data on a tx.', function(done) {
sandbox.stub(txService, '_getInputValues').callsArgWith(2, null, [2]);
var tx = { outputs: [ { value: 1 } ], inputs: [ { value: 2, isCoinbase: sinon.stub().returns(false) } ] };
txService.setTxMetaInfo(tx, {}, function(err, _tx) {
if (err) {
return done(err);
}
_tx.__inputValues.should.deep.equal([2]);
_tx.confirmations.should.equal(0);
_tx.inputSatoshis.should.equal(2);
done();
});
});
});
});