From 3c29e20df2face4a57531e105ca7660a2bc400e9 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 19 Feb 2016 22:02:52 -0800 Subject: [PATCH] refactor pool.search. --- lib/bcoin/pool.js | 111 +++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 71 deletions(-) diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 7da1eb04..20859c19 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -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);