From 5c103aeb6cd418604c1c0c8eb0e065a5695874c7 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 8 May 2014 14:32:47 +0400 Subject: [PATCH] chain: storage support --- lib/bcoin/chain.js | 54 ++++++++++++++++++++++++++++++++++++++-------- lib/bcoin/pool.js | 3 ++- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 9b97b133..60e8ddf8 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -14,6 +14,8 @@ function Chain(options) { EventEmitter.call(this); this.options = options || {}; + this.prefix = 'bt/chain/'; + this.storage = this.options.storage; this.strict = this.options.strict || false; this.block = { list: [], @@ -37,6 +39,8 @@ function Chain(options) { this.request = new utils.RequestCache(); this.fromJSON(preload); + + this._init(); } util.inherits(Chain, EventEmitter); module.exports = Chain; @@ -45,6 +49,24 @@ function compareTs(a, b) { return a -b; } +Chain.prototype._init = function _init() { + if (!this._storage) + return; + + var self = this; + var s = this._storage.createReadStream({ + start: this._prefix, + end: this._prefix + 'z' + }) + s.on('data', function(data) { + var hash = data.key.slice(self.prefix.length); + self.addIndex(hash, data.value.ts, data.value.height); + }); + s.on('error', function(err) { + self.emit('error', err); + }); +}; + Chain.prototype._getRange = function _getRange(hash, ts, futureOnly) { var pos = utils.binaryInsert(this.index.ts, ts, compareTs, true); var start = Math.min(Math.max(0, pos), this.index.ts.length - 1); @@ -87,22 +109,36 @@ Chain.prototype.probeIndex = function probeIndex(hash, ts) { return false; }; -Chain.prototype.addIndex = function addIndex(hash, ts) { +Chain.prototype.addIndex = function addIndex(hash, ts, height) { if (this.probeIndex(hash, ts)) return; var pos = utils.binaryInsert(this.index.ts, ts, compareTs, true); // Avoid duplicates - if (this.index.hashes[pos] !== hash && - this.index.hashes[pos - 1] !== hash && - this.index.hashes[pos + 1] !== hash) { - this.index.ts.splice(pos, 0, ts); - this.index.hashes.splice(pos, 0, hash); - this.index.bloom.add(hash, 'hex'); - assert(pos > 0); - this.index.heights.splice(pos, 0, this.index.heights[pos - 1] + 1); + if (this.index.hashes[pos] === hash || + this.index.hashes[pos - 1] === hash || + this.index.hashes[pos + 1] === hash) { + return; } + + this.index.ts.splice(pos, 0, ts); + this.index.hashes.splice(pos, 0, hash); + this.index.bloom.add(hash, 'hex'); + assert(pos > 0); + if (!height) + height = this.index.heights[pos - 1] + 1; + this.index.heights.splice(pos, 0, height); + + if (!this.storage) + return; + + var self = this; + var obj = { ts: ts, height: height }; + this.storage.put(this.prefix + hash, obj, function(err) { + if (err) + self.emit('error', err); + }); }; Chain.prototype.add = function add(block) { diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index ca240600..de9d3d54 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -13,6 +13,7 @@ function Pool(options) { EventEmitter.call(this); this.options = options || {}; + this.storage = this.options.storage; this.destroyed = false; this.size = options.size || 32; this.parallel = options.parallel || 2000; @@ -30,7 +31,7 @@ function Pool(options) { }; this.maxRetries = options.maxRetries || 42; this.requestTimeout = options.requestTimeout || 10000; - this.chain = new bcoin.chain(); + this.chain = new bcoin.chain({ storage: this.storage }); this.watchMap = {}; this.bloom = new bcoin.bloom(8 * 1024, 10,