diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index bd1b8972..36682775 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -366,46 +366,38 @@ Chain.prototype._compress = function compress() { this.block.bloom.add(this.block.list[i].hash('hex'), 'hex'); }; -Chain.prototype.has = function has(hash, noProbe, cb) { +Chain.prototype.has = function has(hash, noIndex, cb) { var i; - if (typeof noProbe === 'function') { - cb = noProbe; - noProbe = false; + if (typeof noIndex === 'function') { + cb = noIndex; + noIndex = false; } if (this.loading) { this.once('load', function() { - this.has(hash, noProbe, cb); + this.has(hash, noIndex, cb); }); return; } cb = utils.asyncify(cb); - if (this.block.bloom.test(hash, 'hex')) { - if (this.strict) { - for (i = 0; i < this.block.list.length; i++) - if (this.block.list[i].hash('hex') === hash) - return cb(true); - } else { - return cb(true); - } - } + if (this.hasCache(hash)) + return cb(true); if (this.hasOrphan(hash)) return cb(true); - if (!noProbe && this.hasBlock(hash)) - return cb(true); + if (!noIndex) { + if (this.hasBlock(hash)) + return cb(true); + } return cb(false); }; Chain.prototype.byHeight = function byHeight(height) { - if (this.loading) - return null; - var index = this.index.heights.indexOf(height); if (index === -1) @@ -419,20 +411,7 @@ Chain.prototype.byHeight = function byHeight(height) { }; }; -Chain.prototype.getTip = function() { - var index = this.index.hashes.length - 1; - return { - index: index, - hash: this.index.hashes[index], - ts: this.index.ts[index], - height: this.index.heights[index] - }; -}; - Chain.prototype.byHash = function byHash(hash) { - if (this.loading) - return null; - if (Array.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) @@ -452,27 +431,71 @@ Chain.prototype.byHash = function byHash(hash) { }; Chain.prototype.hasBlock = function hasBlock(hash) { - if (this.loading) - return false; - if (Array.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); + // return this.byHash(hash); return this.index.bloom.test(hash, 'hex'); }; Chain.prototype.hasOrphan = function hasOrphan(hash) { - if (this.loading) + return !!this.getOrphan(hash); +}; + +Chain.prototype.hasCache = function hasCache(hash) { + if (Array.isArray(hash)) + hash = utils.toHex(hash); + else if (hash.hash) + hash = hash.hash('hex'); + + if (!this.block.bloom.test(hash, 'hex')) return false; + if (this.strict) + return !!this.getCache(hash); + + return true; +}; + +Chain.prototype.getBlock = function getBlock(hash) { + if (typeof hash === 'number') + return this.byHeight(hash); + return this.byHash(hash); +}; + +Chain.prototype.getOrphan = function getOrphan(hash) { + if (Array.isArray(hash)) + hash = utils.toHex(hash); + else if (hash.hash) + hash = hash.hash('hex'); + + return this.orphan.bmap[hash] || null; +}; + +Chain.prototype.getCache = function getCache(hash) { + var i; + if (Array.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); - return !!this.orphan.bmap[hash]; + for (i = 0; i < this.block.list.length; i++) { + if (this.block.list[i].hash('hex') === hash) + return this.block.list[i]; + } +}; + +Chain.prototype.getTip = function() { + var index = this.index.hashes.length - 1; + return { + index: index, + hash: this.index.hashes[index], + ts: this.index.ts[index], + height: this.index.heights[index] + }; }; Chain.prototype.get = function get(hash, force, cb) { @@ -484,25 +507,20 @@ Chain.prototype.get = function get(hash, force, cb) { } // Cached block found - if (!force && this.block.bloom.test(hash, 'hex')) { - for (i = 0; i < this.block.list.length; i++) { - if (this.block.list[i].hash('hex') === hash) { - // NOTE: we return right after the statement - so `block` should be - // valid at the time of nextTick call - block = this.block.list[i]; - bcoin.utils.nextTick(function() { - cb(block); - }); - return; + if (!force) { + if (this.block.bloom.test(hash, 'hex')) { + block = this.getCache(hash); + if (block) { + bcoin.utils.nextTick(cb.bind(null, block)); + return block; } + // False positive: + // assert(false); } - // False positive: - // assert(false); + if (this.hasOrphan(hash)) + return cb(this.getOrphan(hash)); } - if (!force && this.orphan.bmap[hash]) - return cb(this.orphan.bmap[hash]); - if (this.request.add(hash, cb)) this.emit('missing', hash, null, null); }; @@ -626,6 +644,18 @@ Chain.prototype.height = function height() { return this.getTip().height; }; +Chain.prototype.target = function target(last) { + assert(false); +}; + +Chain.prototype.retarget = function retarget(last, firstTs) { + assert(false); +}; + +Chain.prototype.compact = function compact() { + assert(false); +}; + Chain.prototype._save = function(hash, obj) { var self = this; diff --git a/lib/bcoin/fullchain.js b/lib/bcoin/fullchain.js index 0208504c..8554abed 100644 --- a/lib/bcoin/fullchain.js +++ b/lib/bcoin/fullchain.js @@ -263,37 +263,29 @@ Chain.prototype.add = function add(block) { return err; }; -Chain.prototype.has = function has(hash, noProbe, cb) { - if (typeof noProbe === 'function') { - cb = noProbe; - noProbe = false; +Chain.prototype.has = function has(hash, noIndex, cb) { + if (typeof noIndex === 'function') { + cb = noIndex; + noIndex = false; } if (this.loading) { this.once('load', function() { - this.has(hash, noProbe, cb); + this.has(hash, noIndex, cb); }); return; } cb = utils.asyncify(cb); - // assert(!noProbe); - return cb(this.hasBlock(hash) || this.hasOrphan(hash)); }; Chain.prototype.byHeight = function byHeight(height) { - if (this.loading) - return null; - return this.index.entries[height] || null; }; Chain.prototype.byHash = function byHash(hash) { - if (this.loading) - return null; - if (Array.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) @@ -302,30 +294,39 @@ Chain.prototype.byHash = function byHash(hash) { return this.byHeight(this.index.heights[hash]); }; -Chain.prototype.getTip = function getTip() { - if (this.loading) - return null; - - return this.index.entries[this.index.entries.length - 1]; -}; - Chain.prototype.hasBlock = function hasBlock(hash) { - if (this.loading) - return false; - return !!this.byHash(hash); }; Chain.prototype.hasOrphan = function hasOrphan(hash) { - if (this.loading) - return false; + return !!this.getOrphan(hash); +}; +Chain.prototype.hasCache = function hasCache(hash) { + assert(false); +}; + +Chain.prototype.getBlock = function getBlock(hash) { + if (typeof hash === 'number') + return this.byHeight(hash); + return this.byHash(hash); +}; + +Chain.prototype.getOrphan = function getOrphan(hash) { if (Array.isArray(hash)) hash = utils.toHex(hash); else if (hash.hash) hash = hash.hash('hex'); - return !!this.orphan.bmap[hash]; + return this.orphan.bmap[hash] || null; +}; + +Chain.prototype.getCache = function getCache(hash) { + assert(false); +}; + +Chain.prototype.getTip = function getTip() { + return this.index.entries[this.index.entries.length - 1]; }; Chain.prototype.get = function get(hash, force, cb) { @@ -360,9 +361,6 @@ Chain.prototype.getLast = function getLast(cb) { }; Chain.prototype.getStartHeight = function getStartHeight() { - if (this.loading) - return 0; - return this.index.entries[this.index.entries.length - 1].height; }; @@ -509,6 +507,10 @@ Chain.prototype.retarget = function retarget(last, firstTs) { return utils.toCompact(target); }; +Chain.prototype.compact = function compact() { + assert(false); +}; + Chain.prototype._save = function(hash, obj) { var self = this; diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 82efec79..32d6a8d2 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -311,7 +311,7 @@ Pool.prototype._addLoader = function _addLoader() { peer.loadBlocks(self.chain.locatorHashes(), 0); // Request block if we don't have it - if (!self.chain.hasBlock(hash)) + if (!self.chain.hasBlock(hash) && !self.chain.hasOrphan(hash)) self._request('block', hash); }