diff --git a/lib/bcoin/miner.js b/lib/bcoin/miner.js index a82c34ca..a5f0b4b5 100644 --- a/lib/bcoin/miner.js +++ b/lib/bcoin/miner.js @@ -339,8 +339,6 @@ Miner.prototype.mineBlock = function mineBlock(version, callback) { */ function MinerBlock(options) { - var i; - if (!(this instanceof MinerBlock)) return new MinerBlock(options); @@ -348,77 +346,96 @@ function MinerBlock(options) { this.workerPool = options.workerPool; this.tip = options.tip; this.height = options.tip.height + 1; - this.target = utils.fromCompact(options.target).toArrayLike(Buffer, 'le', 32); + this.bits = options.target; + this.target = utils.fromCompact(this.bits).toArrayLike(Buffer, 'le', 32); this.extraNonce = new bn(0); this.iterations = 0; this.coinbaseFlags = options.coinbaseFlags; this.witness = options.witness; this.address = options.address; - this.witnessNonce = null; this.network = bcoin.network.get(options.network); - // Create a coinbase - this.coinbase = new bcoin.mtx(); + this.coinbase = new bcoin.tx(); + this.coinbase.mutable = true; - this.coinbase.addInput({ - prevout: { - hash: constants.NULL_HASH, - index: 0xffffffff - }, - coin: null, - script: bcoin.script.fromArray([ - // Height (required in v2+ blocks) - bcoin.script.array(this.height), - // extraNonce - incremented when - // the nonce overflows. - bcoin.script.array(0), - // Add a nonce to ensure we don't - // collide with a previous coinbase - // of ours. This isn't really - // necessary nowdays due to bip34 - // (used above). - bcoin.script.array(utils.nonce()), - // Let the world know this little - // miner succeeded. - new Buffer(this.coinbaseFlags, 'utf8') - ]), - witness: new bcoin.witness(), - sequence: 0xffffffff - }); + this.block = new bcoin.block(); + this.block.mutable = true; - this.coinbase.addOutput({ - address: this.address, - value: 0 - }); + this._init(); +} - // Create our block - this.block = new bcoin.block({ - mutable: true, - version: options.version, - prevBlock: this.tip.hash, - merkleRoot: constants.NULL_HASH, - ts: Math.max(bcoin.now(), this.tip.ts + 1), - bits: options.target, - nonce: 0, - height: this.height - }); +/** + * Initialize the block. + * @private + */ - this.block.addTX(this.coinbase); +MinerBlock.prototype._init = function _init() { + var options = this.options; + var block = this.block; + var cb = this.coinbase; + var i, input, output, hash, witnessNonce; + + // Coinbase input. + input = new bcoin.input(); + + // Height (required in v2+ blocks) + input.script.set(0, new bn(this.height)); + + // extraNonce - incremented when + // the nonce overflows. + input.script.set(1, this.extraNonce); + + // Add a nonce to ensure we don't + // collide with a previous coinbase + // of ours. This isn't really + // necessary nowdays due to bip34 + // (used above). + input.script.set(2, utils.nonce()); + + // Let the world know this little + // miner succeeded. + input.script.set(3, this.coinbaseFlags); + + input.script.compile(); + + cb.inputs.push(input); + + // Reward output. + output = new bcoin.output(); + output.script = bcoin.script.fromAddress(this.address); + + cb.outputs.push(output); + + // If we're using segwit, we need to + // set up the nonce and commitment. + if (this.witness) { + // Our witness nonce is the hash256 + // of the previous block hash. + hash = new Buffer(this.tip.hash, 'hex'); + witnessNonce = utils.hash256(hash); + + // Set up the witness nonce. + input.witness.set(0, witnessNonce); + input.witness.compile(); + + // Commitment output. + cb.outputs.push(new bcoin.output()); + } + + // Setup our block. + block.version = options.version; + block.prevBlock = this.tip.hash; + block.merkleRoot = constants.NULL_HASH; + block.ts = Math.max(bcoin.now(), this.tip.ts + 1); + block.bits = this.bits; + block.nonce = 0; + block.height = this.height; + + block.addTX(cb); if (options.txs) { for (i = 0; i < options.txs.length; i++) - this.block.addTX(options.txs[i]); - } - - if (this.witness) { - // Set up the witness nonce and - // commitment output for segwit. - this.witnessNonce = utils.hash256(new Buffer(this.tip.hash, 'hex')); - this.coinbase.inputs[0].witness.items[0] = this.witnessNonce; - this.coinbase.addOutput({ - script: new bcoin.script(), - value: 0 - }); + block.addTX(options.txs[i]); } // Update coinbase since our coinbase was added. @@ -436,20 +453,29 @@ utils.inherits(MinerBlock, EventEmitter); MinerBlock.prototype.updateCommitment = function updateCommitment() { var output = this.coinbase.outputs[1]; - var hash = this.block.getCommitmentHash(); - var commit = bcoin.script.createCommitment(hash, this.coinbaseFlags); - output.script = commit; + var flags = this.coinbaseFlags; + var hash; + + // Recalculate witness merkle root. + hash = this.block.getCommitmentHash(); + + // Update commitment. + output.script = bcoin.script.fromCommitment(hash, flags); }; /** - * Update the extranonce and coinbase reward. + * Update the extra nonce and coinbase reward. */ MinerBlock.prototype.updateCoinbase = function updateCoinbase() { var input = this.coinbase.inputs[0]; var output = this.coinbase.outputs[0]; + + // Update extra nonce. input.script.set(1, this.extraNonce); input.script.compile(); + + // Update reward. output.value = this.block.getReward(this.network); }; @@ -465,7 +491,10 @@ MinerBlock.prototype.updateMerkle = function updateMerkle() { if (this.witness) this.updateCommitment(); + // Update timestamp. this.block.ts = Math.max(bcoin.now(), this.tip.ts + 1); + + // Recalculate merkle root. this.block.merkleRoot = this.block.getMerkleRoot('hex'); }; @@ -609,8 +638,6 @@ MinerBlock.prototype.mine = function mine(callback) { if (!self.findNonce()) return self.mine(callback); - self.block.txs[0] = self.block.txs[0].toTX(); - return callback(null, self.block); }, 100); }; @@ -622,7 +649,6 @@ MinerBlock.prototype.mine = function mine(callback) { MinerBlock.prototype.mineSync = function mineSync() { while (!this.findNonce()); - this.block.txs[0] = this.block.txs[0].toTX(); return this.block; }; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index f9d877a6..772f8ede 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -2568,7 +2568,7 @@ Script.fromAddress = function fromAddress(address) { * @returns {Script} */ -Script.createCommitment = function createCommitment(hash, flags) { +Script.fromCommitment = function fromCommitment(hash, flags) { var p; if (!flags)