From 9468b00d1cb0fa043afd5bc701891d593075337c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 28 Apr 2016 23:01:34 -0700 Subject: [PATCH] refactor. cleanup. --- lib/bcoin/chain.js | 44 +++++++--------- lib/bcoin/pool.js | 128 +++++++++++++++++---------------------------- lib/bcoin/tx.js | 8 +-- 3 files changed, 70 insertions(+), 110 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 8b6ccb17..0f7c93c8 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -828,14 +828,24 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac tx = block.txs[i]; hash = tx.hash('hex'); - // Coinbases do not have prevouts + // Count sigops (legacy + scripthash? + witness?) + sigops += tx.getSigopsCost(flags); + + if (sigops > constants.block.MAX_SIGOPS_COST) { + return callback(new VerifyError(block, + 'invalid', + 'bad-blk-sigops', + 100)); + } + + // Coinbases do not have prevouts. if (tx.isCoinbase()) continue; for (j = 0; j < tx.inputs.length; j++) { input = tx.inputs[j]; - // Ensure tx is not double spending an output + // Ensure tx is not double spending an output. if (!input.coin) { assert(!historical, 'BUG: Spent inputs in historical data!'); return callback(new VerifyError(block, @@ -858,8 +868,8 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac bcoin.debug('TX:'); bcoin.debug(tx); bcoin.debug('Input (%d):', j); - bcoin.debug(tx.inputs[j]); - bcoin.debug('TX with coins:'); + bcoin.debug(input); + bcoin.debug('Serialized TX (with coins):'); bcoin.debug(tx.toExtended('hex', true)); bcoin.debug('Flags: %d', flags); assert(!historical, 'BUG: Invalid inputs in historical data!'); @@ -870,16 +880,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac } } - // Count sigops (legacy + scripthash? + witness?) - sigops += tx.getSigopsCost(flags); - - if (sigops > constants.block.MAX_SIGOPS_COST) { - return callback(new VerifyError(block, - 'invalid', - 'bad-blk-sigops', - 100)); - } - + // Contextual sanity checks. if (!tx.checkInputs(height, ret)) { return callback(new VerifyError(block, 'invalid', @@ -888,6 +889,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac } } + // Make sure the miner isn't trying to conjure more coins. if (block.getClaimed().cmp(block.getReward()) > 0) return callback(new VerifyError(block, 'invalid', 'bad-cb-amount', 100)); @@ -1705,17 +1707,12 @@ Chain.prototype.has = function has(hash, callback) { * @param {Function} callback - Returns [Error, {@link ChainBlock}]. */ -Chain.prototype.byTime = function byTime(ts, callback, force) { +Chain.prototype.byTime = function byTime(ts, callback) { var self = this; var start = 0; var end = this.height; var pos, delta; - // var unlock = this._lock(byTime, [ts, callback], force); - // if (!unlock) - // return; - // callback = utils.wrap(callback, unlock); - function done(err, result) { if (err) return callback(err); @@ -1863,14 +1860,9 @@ Chain.prototype.getProgress = function getProgress() { * @param {Function} callback - Returns [Error, Hash[]]. */ -Chain.prototype.getHashRange = function getHashRange(start, end, callback, force) { +Chain.prototype.getHashRange = function getHashRange(start, end, callback) { var self = this; - // var unlock = this._lock(getHashRange, [start, end, callback], force); - // if (!unlock) - // return; - // callback = utils.wrap(callback, unlock); - this.byTime(start, function(err, start) { if (err) return callback(err); diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index ec39ca35..5eb61caa 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -279,8 +279,6 @@ Pool.prototype._init = function _init() { this.chain.on('orphan', function(block, data, peer) { self.emit('orphan', data, peer); - // Resolve orphan chain - // self.resolveOrphan(self.peers.load, null, data.hash); }); this.chain.on('full', function() { @@ -343,18 +341,6 @@ Pool.prototype.resolveOrphan = function resolveOrphan(peer, top, orphan, callbac return callback(); } - // If we're already processing the block - // that would resolve this, ignore. - // if (self.request.map[orphan.soil]) { - // bcoin.debug('Already requested orphan "soil".'); - // return callback(); - // } - - // if (self.chain.hasPending(orphan.soil)) { - // bcoin.debug('Already processing orphan "soil".'); - // return callback(); - // } - peer.getBlocks(locator, orphan.root); callback(); @@ -794,14 +780,6 @@ Pool.prototype._handleInv = function _handleInv(hashes, peer, callback) { }); }; -Pool.prototype._prehandleTX = function _prehandleTX(tx, peer, callback) { - return callback(null, tx); -}; - -Pool.prototype._prehandleBlock = function _prehandleBlock(block, peer, callback) { - return callback(null, block); -}; - Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) { var self = this; var requested; @@ -820,52 +798,47 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) { return callback(); } - this._prehandleBlock(block, peer, function(err) { - if (err) - return callback(err); + this.chain.add(block, function(err) { + if (err) { + if (err.type === 'VerifyError') { + if (err.score >= 0) + peer.sendReject(block, err.code, err.reason, err.score); - self.chain.add(block, function(err) { - if (err) { - if (err.type === 'VerifyError') { - if (err.score >= 0) - peer.sendReject(block, err.code, err.reason, err.score); - - if (err.reason === 'bad-prevblk') { - if (peer === self.peers.load) - self.resolveOrphan(peer, null, block.hash('hex')); - } - - self.scheduleRequests(peer); - - return callback(err); + if (err.reason === 'bad-prevblk') { + if (peer === self.peers.load) + self.resolveOrphan(peer, null, block.hash('hex')); } + + self.scheduleRequests(peer); + return callback(err); } + return callback(err); + } - self.scheduleRequests(peer); + self.scheduleRequests(peer); - self.emit('chain-progress', self.chain.getProgress(), peer); + self.emit('chain-progress', self.chain.getProgress(), peer); - if (self.chain.total % 20 === 0) { - bcoin.debug( - 'Status: tip=%s ts=%s height=%d blocks=%d orphans=%d active=%d' - + ' queue=%d target=%s peers=%d pending=%d highest=%d jobs=%d', - block.rhash, - utils.date(block.ts), - self.chain.height, - self.chain.total, - self.chain.orphan.count, - self.request.activeBlocks, - peer.queue.block.length, - block.bits, - self.peers.all.length, - self.chain.locker.pending.length, - self.chain.bestHeight, - self.chain.locker.jobs.length); - } + if (self.chain.total % 20 === 0) { + bcoin.debug( + 'Status: tip=%s ts=%s height=%d blocks=%d orphans=%d active=%d' + + ' queue=%d target=%s peers=%d pending=%d highest=%d jobs=%d', + block.rhash, + utils.date(block.ts), + self.chain.height, + self.chain.total, + self.chain.orphan.count, + self.request.activeBlocks, + peer.queue.block.length, + block.bits, + self.peers.all.length, + self.chain.locker.pending.length, + self.chain.bestHeight, + self.chain.locker.jobs.length); + } - return callback(); - }); + return callback(); }); }; @@ -990,7 +963,7 @@ Pool.prototype._createPeer = function _createPeer(options) { for (i = 0; i < txs.length; i++) { hash = txs[i]; - if (self.markTX(hash, 0)) + if (self._markTX(hash, 0)) self.getData(peer, self.tx.type, hash); } }); @@ -1018,7 +991,7 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) { callback = utils.asyncify(callback); requested = this.fulfill(tx); - updated = this.markTX(tx, 1); + updated = this._markTX(tx, 1); function addMempool(tx, callback) { if (!self.mempool) @@ -1030,27 +1003,22 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) { self.mempool.addTX(tx, callback); } - this._prehandleTX(tx, peer, function(err) { - if (err) - return callback(err); - - addMempool(tx, function(err) { - if (err) { - if (err.type === 'VerifyError') { - if (err.score >= 0) - peer.sendReject(tx, err.code, err.reason, err.score); - return callback(); - } + addMempool(tx, function(err) { + if (err) { + if (err.type === 'VerifyError') { + if (err.score >= 0) + peer.sendReject(tx, err.code, err.reason, err.score); + return callback(); } + } - if (updated || tx.block) - self.emit('tx', tx, peer); + if (updated || tx.block) + self.emit('tx', tx, peer); - if (self.options.spv && tx.block) - self.emit('watched', tx, peer); + if (self.options.spv && tx.block) + self.emit('watched', tx, peer); - return callback(); - }); + return callback(); }); }; @@ -1212,7 +1180,7 @@ Pool.prototype._addPeer = function _addPeer() { }); }; -Pool.prototype.markTX = function(hash, state) { +Pool.prototype._markTX = function(hash, state) { if (hash.hash) hash = hash.hash('hex'); diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 93bd6756..acbb0401 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -946,7 +946,7 @@ TX.prototype.getScripthashSigops = function getScripthashSigops() { continue; if (input.coin.script.isScripthash()) - total += input.coin.script.getSigops(input.script); + total += input.coin.script.getScripthashSigops(input.script); } return total; @@ -994,10 +994,12 @@ TX.prototype.getSigopsCost = function getSigopsCost(flags) { */ TX.prototype.getSigops = function getSigops(flags) { + var scale = constants.WITNESS_SCALE_FACTOR; + if (flags == null) flags = constants.flags.STANDARD_VERIFY_FLAGS; - return (this.getSigopsCost(flags) + 3) / 4 | 0; + return (this.getSigopsCost(flags) + scale - 1) / scale | 0; }; /** @@ -1202,8 +1204,6 @@ TX.prototype.hasStandardInputs = function hasStandardInputs(flags) { if ((flags & constants.flags.VERIFY_P2SH) && input.coin.script.isScripthash()) { - assert(input.script.isPushOnly()); - stack = new Stack(); try {