Added cache miss function for input values.
This commit is contained in:
parent
5ff8e7c6c1
commit
a8d709caf6
@ -202,8 +202,7 @@ P2P.prototype._hasPeers = function() {
|
||||
};
|
||||
|
||||
P2P.prototype._initCache = function() {
|
||||
this._inv = LRU(2000);
|
||||
this._cache = [];
|
||||
this._inv = LRU(1000);
|
||||
};
|
||||
|
||||
P2P.prototype._initP2P = function() {
|
||||
@ -332,7 +331,7 @@ P2P.prototype._setResourceFilter = function(filter, resource) {
|
||||
};
|
||||
|
||||
P2P.prototype._startBcoin = function() {
|
||||
const network = ['livenet', 'live', 'main', 'mainnet'].indexOf(this.node.network) !== -1? 'main' : 'testnet'
|
||||
const network = ['livenet', 'live', 'main', 'mainnet'].indexOf(this.node.network) !== -1? 'main' : 'testnet';
|
||||
this._bcoin = new Bcoin({
|
||||
network: network,
|
||||
prefix: this.node.datadir
|
||||
|
||||
@ -8,6 +8,8 @@ var _ = require('lodash');
|
||||
var LRU = require('lru-cache');
|
||||
var Unit = require('bitcore-lib').Unit;
|
||||
var log = require('../../index').log;
|
||||
var async = require('async');
|
||||
var assert = require('assert');
|
||||
|
||||
function TransactionService(options) {
|
||||
BaseService.call(this, options);
|
||||
@ -16,7 +18,7 @@ function TransactionService(options) {
|
||||
this._block = this.node.services.block;
|
||||
this._p2p = this.node.services.p2p;
|
||||
this._timestamp = this.node.services.timestamp;
|
||||
this._inputValuesCache = LRU(1E6); // this should speed up syncing
|
||||
this._inputValuesCache = LRU(500000); // this should speed up syncing
|
||||
}
|
||||
|
||||
inherits(TransactionService, BaseService);
|
||||
@ -48,9 +50,11 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
||||
|
||||
var self = this;
|
||||
|
||||
var _tx;
|
||||
var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool;
|
||||
|
||||
var key = self.encoding.encodeTransactionKey(txid);
|
||||
|
||||
self._db.get(key, function(err, tx) {
|
||||
|
||||
if(err) {
|
||||
@ -67,9 +71,8 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
||||
|
||||
if (memTx) {
|
||||
memTx.confirmations = 0;
|
||||
return callback(null, memTx);
|
||||
_tx = memTx;
|
||||
}
|
||||
return callback();
|
||||
|
||||
});
|
||||
|
||||
@ -77,16 +80,61 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
||||
|
||||
if (tx) {
|
||||
tx.confirmations = self._p2p.getBestHeight - tx.__height;
|
||||
return callback(null, tx);
|
||||
_tx = tx;
|
||||
}
|
||||
return callback();
|
||||
|
||||
}
|
||||
|
||||
if (!_tx) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
// TODO: this could cause crazy amounts of recursion if input values are missing from the entire chain of txs
|
||||
self._addMissingInputValues(_tx, callback);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
TransactionService.prototype._addMissingInputValues = function(tx, callback) {
|
||||
|
||||
// if we have cache misses from when we populated input values,
|
||||
// then we must go and find them after the fact (lazy-load).
|
||||
var self = this;
|
||||
async.eachOfLimit(tx.inputs, 4, function(input, index, next) {
|
||||
|
||||
var inputSatoshis = tx.__inputValues[index];
|
||||
|
||||
if (inputSatoshis >= 0) {
|
||||
return next();
|
||||
}
|
||||
|
||||
var outputIndex = input.prevout.index;
|
||||
self.getTransaction(input.prevout.txid(), function(err, _tx) {
|
||||
|
||||
if (err || !_tx) {
|
||||
return next(err || new Error('tx not found for tx id: ' + input.prevout.txid()));
|
||||
}
|
||||
|
||||
var output = _tx.outputs[outputIndex];
|
||||
assert(output, 'Expected an output, but did not get one for tx: ' + _tx.txid() + ' outputIndex: ' + outputIndex);
|
||||
tx.__inputValues[index] = Unit.fromBTC(output.value).toSatoshis();
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
|
||||
}, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
callback(null, tx);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
TransactionService.prototype.sendTransaction = function(tx, callback) {
|
||||
this._p2p.sendTransaction(tx, callback);
|
||||
};
|
||||
@ -216,6 +264,10 @@ TransactionService.prototype._processTransaction = function(tx, opts) {
|
||||
|
||||
// input values
|
||||
tx.__inputValues = this._getInputValues(tx); //if there are any nulls here, this is a cache miss
|
||||
if (_.compact(tx.__inputValues).length < tx.inputs.length) {
|
||||
log.debug('Transaction Service: Cache miss for tx id: ' + tx.txid());
|
||||
}
|
||||
|
||||
//timestamp
|
||||
tx.__timestamp = this._getBlockTimestamp(opts.block.rhash());
|
||||
//height
|
||||
|
||||
@ -122,4 +122,18 @@ describe('Transaction Service', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#_addMissingInputValues', function() {
|
||||
it('should add missing input values on a tx', function(done) {
|
||||
sandbox.stub(txService, 'getTransaction').callsArgWith(1, null, tx);
|
||||
tx.__inputValues = [];
|
||||
txService._addMissingInputValues(tx, function(err, tx) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
tx.__inputValues.should.deep.equal([113903300000000, 113903300000000, 50000000000000, 113903300000000 ]);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user