refactor pool.search.

This commit is contained in:
Christopher Jeffrey 2016-02-19 22:02:52 -08:00
parent 48d7b95d61
commit 3c29e20df2

View File

@ -1363,27 +1363,15 @@ Pool.prototype.searchWallet = function(w, h) {
});
};
Pool.prototype.search = function search(id, range, e) {
Pool.prototype.search = function search(id, range, callback) {
var self = this;
var hashes, pending, listener, timeout, done, total, cb;
assert(!this.loading);
if (!this.options.spv)
return;
if (typeof e === 'function') {
cb = e;
e = null;
}
e = e || new EventEmitter();
// Optional id argument
if ((id !== null
&& typeof id === 'object'
&& !utils.isBuffer(id))
|| typeof id === 'number') {
if (range == null) {
range = id;
id = null;
}
@ -1398,63 +1386,42 @@ Pool.prototype.search = function search(id, range, e) {
else
range = { start: 0, end: 0 };
// Last 5 days by default, this covers 1000 blocks that we have in the
// chain by default
if (!range.end)
range.end = utils.now();
if (!range.start)
range.start = utils.now() - 432000;
if (cb) {
e.once('end', function(empty) {
if (empty)
return cb(new Error('Not found.'), false);
return cb(null, true);
});
}
if (id)
this.watch(id);
done = function(empty) {
e.emit('end', empty);
clearInterval(timeout);
self.removeListener('block', listener);
callback = utils.asyncify(callback);
function done(err, completed) {
self.removeListener('block', onBlock);
if (id)
self.unwatch(id);
};
callback(err, completed);
}
this.on('block', listener = function(block) {
function onBlock(block) {
if (block.ts >= range.end)
done();
});
done(null, true);
}
// Estimated number of blocks in time range
total = (range.end - range.start) / network.powTargetSpacing | 0;
if (total === 0)
total = 1;
// 500 blocks every 3 seconds
total = (total / 500 | 0) * 3;
// Add half the total time and convert to ms
total = (total + Math.ceil(total / 2)) * 1000;
timeout = setTimeout(done.bind(null, true), total);
this.on('block', onBlock);
if (range.start < this.chain.tip.ts) {
this.chain.resetTimeAsync(range.start, function(err) {
if (err)
throw err;
return done(err);
self.stopSync();
self.startSync();
});
} else {
done(null, false);
}
return e;
};
Pool.prototype.getData = function getData(peer, type, hash, options, cb) {
@ -1597,10 +1564,10 @@ Pool.prototype.sendBlock = function sendBlock(block) {
Pool.prototype.getTX = function getTX(hash, range, cb) {
var self = this;
var cbs, tx, finished, req, delta;
var cbs, tx, found, delta;
if (!this.peers.load)
return setTimeout(this.getBlock.bind(this, hash, cb), 1000);
return setTimeout(this.getTX.bind(this, hash, cb), 1000);
if (!this.options.spv)
return cb(new Error('Cannot get tx with full node'));
@ -1621,9 +1588,9 @@ Pool.prototype.getTX = function getTX(hash, range, cb) {
// Add request without queueing it to get notification at the time of load
tx = null;
finished = false;
req = this.getData(this.peers.load, 'tx', hash, { noQueue: true }, function(t) {
finished = true;
found = false;
this.getData(this.peers.load, 'tx', hash, { noQueue: true }, function(t) {
found = true;
tx = t;
});
@ -1636,20 +1603,23 @@ Pool.prototype.getTX = function getTX(hash, range, cb) {
else
range = { start: utils.now() - delta, end: 0 };
function doSearch() {
var e = self.search(hash, range);
e.on('end', function(empty) {
if (finished) {
delete self.validate.map[hash];
cbs.forEach(function(cb) {
cb(null, tx, range);
});
return;
}
function done(err, tx, range) {
delete self.validate.map[hash];
cbs.forEach(function(cb) {
cb(err, tx, range);
});
}
// Tried everything, but still no matches
if (empty)
return cb(new Error('Not found.'));
(function next() {
self.search(hash, range, function(err, completed) {
if (err)
return done(err);
if (found)
return done(null, tx, range);
if (!completed)
return done();
// Not found yet, continue scanning
range.end = range.start;
@ -1657,20 +1627,19 @@ Pool.prototype.getTX = function getTX(hash, range, cb) {
if (range.start < 0)
range.start = 0;
doSearch();
next();
});
}
doSearch();
})();
};
Pool.prototype.sendTX = function sendTX(tx) {
var flags = constants.flags.STANDARD_VERIFY_FLAGS;
// This is to avoid getting banned by
// bitcoind nodes. Possibly check
// sigops. Call isStandard and/or
// isStandardInputs as well.
if (tx.hasPrevout()) {
if (!tx.verify(null, true)) {
if (!tx.verify(null, true, flags)) {
utils.debug(
'Could not relay TX (%s). It does not verify.',
tx.rhash);