diff --git a/lib/mining/minerblock.js b/lib/mining/minerblock.js index 4e4664ea..73ee7f27 100644 --- a/lib/mining/minerblock.js +++ b/lib/mining/minerblock.js @@ -11,6 +11,7 @@ var assert = require('assert'); var util = require('../utils/util'); var btcutils = require('../btc/utils'); var co = require('../utils/co'); +var StaticWriter = require('../utils/staticwriter'); var constants = require('../protocol/constants'); var Network = require('../protocol/network'); var BN = require('bn.js'); @@ -54,7 +55,8 @@ function MinerBlock(options) { this.target = btcutils.fromCompact(this.bits).toArrayLike(Buffer, 'le', 32); this.locktime = options.locktime; this.flags = options.flags; - this.extraNonce = new BN(0); + this.nonce1 = 0; + this.nonce2 = 0; this.iterations = 0; this.coinbaseFlags = options.coinbaseFlags; this.witness = options.witness; @@ -132,20 +134,15 @@ MinerBlock.prototype._init = function _init() { // 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, util.nonce()); - // Let the world know this little // miner succeeded. - input.script.set(3, this.coinbaseFlags); + input.script.set(1, this.coinbaseFlags); + + input.script.set(2, util.nonce().slice(0, 4)); + + // extraNonce - incremented when + // the nonce overflows. + input.script.set(3, this.extraNonce()); input.script.compile(); @@ -219,7 +216,7 @@ MinerBlock.prototype.updateCoinbase = function updateCoinbase() { var output = this.coinbase.outputs[0]; // Update extra nonce. - input.script.set(1, this.extraNonce); + input.script.set(3, this.extraNonce()); input.script.compile(); // Update reward. @@ -235,7 +232,12 @@ MinerBlock.prototype.updateNonce = function updateNonce() { // Overflow the nonce and increment the extraNonce. this.block.nonce = 0; - this.extraNonce.iaddn(1); + + this.nonce1++; + this.nonce1 &= 0xffffffffffff; + + if (this.nonce1 === 0) + this.nonce2++; // We incremented the extraNonce, need to update coinbase. this.updateCoinbase(); @@ -263,6 +265,20 @@ MinerBlock.prototype.updateMerkle = function updateMerkle() { this.block.merkleRoot = this.block.createMerkleRoot('hex'); }; +/** + * Render extraNonce. + * @returns {Buffer} + */ + +MinerBlock.prototype.extraNonce = function extraNonce() { + var bw = new StaticWriter(12); + bw.writeU32BE(this.nonce1 / 0x10000 | 0); + bw.writeU16BE(this.nonce1 & 0xffff); + bw.writeU32BE(this.nonce2 / 0x10000 | 0); + bw.writeU16BE(this.nonce2 & 0xffff); + return bw.render(); +}; + /** * Add a transaction to the block. Rebuilds the merkle tree, * updates coinbase and commitment. @@ -475,6 +491,7 @@ MinerBlock.prototype.commit = function commit(nonce) { this.block.nonce = nonce; this.block.mutable = false; this.coinbase.mutable = false; + return this.block; }; /** diff --git a/lib/utils/encoding.js b/lib/utils/encoding.js index 60d6b4d3..64cc27ad 100644 --- a/lib/utils/encoding.js +++ b/lib/utils/encoding.js @@ -851,6 +851,18 @@ encoding.U32 = function U32(num) { return data; }; +/** + * Serialize number as a u32be. + * @param {Number} num + * @returns {Buffer} + */ + +encoding.U32BE = function U32BE(num) { + var data = new Buffer(4); + data.writeUInt32BE(num, 0, true); + return data; +}; + /** * Get size of varint-prefixed bytes. * @param {Buffer} data