From 24060f04bbacb494f8f12b5161711458edd8db8a Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 3 Apr 2016 04:11:26 -0700 Subject: [PATCH] fix and improve miner. --- lib/bcoin/bst.js | 2 +- lib/bcoin/fullnode.js | 9 +++++++-- lib/bcoin/miner.js | 32 +++++++++++++++++++++++++++----- lib/bcoin/spvnode.js | 9 +++++++-- lib/bcoin/utils.js | 4 ++-- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/lib/bcoin/bst.js b/lib/bcoin/bst.js index 2241df99..134331e2 100644 --- a/lib/bcoin/bst.js +++ b/lib/bcoin/bst.js @@ -416,7 +416,7 @@ BST.prototype.batch = function batch(ops, options, callback) { batch = new Batch(this, options); if (ops) { - batch.ops = ops; + batch.ops = ops.slice(); return batch.write(callback); } diff --git a/lib/bcoin/fullnode.js b/lib/bcoin/fullnode.js index 564596da..cc0df80b 100644 --- a/lib/bcoin/fullnode.js +++ b/lib/bcoin/fullnode.js @@ -34,6 +34,8 @@ Fullnode.prototype._init = function _init() { var self = this; var options; + this.wallet = null; + this.chain = new bcoin.chain(this, { preload: false, spv: false, @@ -142,10 +144,10 @@ Fullnode.prototype._init = function _init() { utils.debug('Node is loaded.'); } - options = { + options = utils.merge({ id: 'primary', passphrase: this.options.passphrase - }; + }, this.options.wallet || {}); utils.serial([ this.chain.open.bind(this.chain), @@ -166,6 +168,8 @@ Fullnode.prototype._init = function _init() { if (!self.miner.address) self.miner.address = wallet.getAddress(); + self.wallet = wallet; + load(); }); }); @@ -203,6 +207,7 @@ Fullnode.prototype.open = function open(callback) { Fullnode.prototype.close = Fullnode.prototype.destroy = function destroy(callback) { + this.wallet.destroy(); utils.serial([ this.http.close.bind(this.http), this.walletdb.close.bind(this.walletdb), diff --git a/lib/bcoin/miner.js b/lib/bcoin/miner.js index be596210..9603c82a 100644 --- a/lib/bcoin/miner.js +++ b/lib/bcoin/miner.js @@ -110,8 +110,14 @@ Miner.prototype.start = function start() { var self = this; // Wait for `tip`. - if (!this.last) + this.last = this.last || this.chain.tip; + if (!this.last) { + this.chain.on('tip', function(tip) { + self.last = tip; + self.start(); + }); return; + } this.stop(); @@ -214,7 +220,7 @@ Miner.prototype.createBlock = function createBlock(callback) { return callback(err); } - ts = Math.max(utils.now(), this.last.ts + 1); + ts = Math.max(utils.now(), self.last.ts + 1); target = self.chain.getTarget(self.last, ts); @@ -354,7 +360,7 @@ Miner.prototype.iterate = function iterate() { self.chain.add(self.block, function(err) { if (err) { if (err.type === 'VerifyError') - utils.debug('Miner: %s could not be added to chain.', block.rhash); + utils.debug('Miner: %s could not be added to chain.', self.block.rhash); return self.emit('error', err); } @@ -368,7 +374,7 @@ Miner.prototype.iterate = function iterate() { }; Miner.prototype.__defineGetter__('hashes', function() { - return new bn(this.iterations).muln(0xffffffff).addn(this.block.nonce); + return new bn(this.iterations).mul(utils.U32).addn(this.block.nonce); }); Miner.prototype.__defineGetter__('rate', function() { @@ -391,6 +397,7 @@ Miner.prototype.sendStatus = function sendStatus() { Miner.prototype.findNonce = function findNonce() { var data = this.block.abbr(); + var target = this.block.target.toBuffer('le', 32); var now; // Track how long we've been at it. @@ -399,7 +406,7 @@ Miner.prototype.findNonce = function findNonce() { // The heart and soul of the miner: match the target. while (this.block.nonce <= 0xffffffff) { // Hash and test against the next target - if (utils.testTarget(this.block.target, this.dsha256(data))) + if (rcmp(this.dsha256(data), target) < 0) return true; // Increment the nonce to get a different hash @@ -446,6 +453,21 @@ Miner.prototype.findNonce = function findNonce() { return false; }; +function rcmp(a, b) { + var i; + + assert(a.length === b.length); + + for (i = a.length - 1; i >= 0; i--) { + if (a[i] < b[i]) + return -1; + if (a[i] > b[i]) + return 1; + } + + return 0; +} + /** * Expose */ diff --git a/lib/bcoin/spvnode.js b/lib/bcoin/spvnode.js index cb66560a..173e5100 100644 --- a/lib/bcoin/spvnode.js +++ b/lib/bcoin/spvnode.js @@ -34,6 +34,8 @@ SPVNode.prototype._init = function _init() { var self = this; var options; + this.wallet = null; + this.chain = new bcoin.chain(this, { preload: this.options.preload, spv: true, @@ -108,10 +110,10 @@ SPVNode.prototype._init = function _init() { utils.debug('Node is loaded.'); } - options = { + options = utils.merge({ id: 'primary', passphrase: this.options.passphrase - }; + }, this.options.wallet || {}); // Create or load the primary wallet. utils.serial([ @@ -126,6 +128,8 @@ SPVNode.prototype._init = function _init() { if (err) return next(err); + self.wallet = wallet; + next(); }); }); @@ -163,6 +167,7 @@ SPVNode.prototype.open = function open(callback) { SPVNode.prototype.close = SPVNode.prototype.destroy = function destroy(callback) { + this.wallet.destroy(); utils.parallel([ this.http.close.bind(this.http), this.pool.close.bind(this.pool), diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index 351aa9e1..526362ee 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -1420,7 +1420,7 @@ utils.sizePush = function sizePush(num) { return 5; }; -utils.cmp = function(a, b) { +utils.cmp = function cmp(a, b) { var len, i; if (a.compare) @@ -1449,7 +1449,7 @@ utils.cmp = function(a, b) { // $ man 3 memcmp (see NetBSD's consttime_memequal) // This protects us against timing attacks when // comparing an input against a secret string. -utils.ccmp = function(a, b) { +utils.ccmp = function ccmp(a, b) { var res = 0; var i;