refactor miner.

This commit is contained in:
Christopher Jeffrey 2016-07-01 04:59:34 -07:00
parent 46d7fba13a
commit f1bbd7736a
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 93 additions and 67 deletions

View File

@ -339,8 +339,6 @@ Miner.prototype.mineBlock = function mineBlock(version, callback) {
*/ */
function MinerBlock(options) { function MinerBlock(options) {
var i;
if (!(this instanceof MinerBlock)) if (!(this instanceof MinerBlock))
return new MinerBlock(options); return new MinerBlock(options);
@ -348,77 +346,96 @@ function MinerBlock(options) {
this.workerPool = options.workerPool; this.workerPool = options.workerPool;
this.tip = options.tip; this.tip = options.tip;
this.height = options.tip.height + 1; 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.extraNonce = new bn(0);
this.iterations = 0; this.iterations = 0;
this.coinbaseFlags = options.coinbaseFlags; this.coinbaseFlags = options.coinbaseFlags;
this.witness = options.witness; this.witness = options.witness;
this.address = options.address; this.address = options.address;
this.witnessNonce = null;
this.network = bcoin.network.get(options.network); this.network = bcoin.network.get(options.network);
// Create a coinbase this.coinbase = new bcoin.tx();
this.coinbase = new bcoin.mtx(); this.coinbase.mutable = true;
this.coinbase.addInput({ this.block = new bcoin.block();
prevout: { this.block.mutable = true;
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.coinbase.addOutput({ this._init();
address: this.address, }
value: 0
});
// Create our block /**
this.block = new bcoin.block({ * Initialize the block.
mutable: true, * @private
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
});
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) { if (options.txs) {
for (i = 0; i < options.txs.length; i++) for (i = 0; i < options.txs.length; i++)
this.block.addTX(options.txs[i]); 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
});
} }
// Update coinbase since our coinbase was added. // Update coinbase since our coinbase was added.
@ -436,20 +453,29 @@ utils.inherits(MinerBlock, EventEmitter);
MinerBlock.prototype.updateCommitment = function updateCommitment() { MinerBlock.prototype.updateCommitment = function updateCommitment() {
var output = this.coinbase.outputs[1]; var output = this.coinbase.outputs[1];
var hash = this.block.getCommitmentHash(); var flags = this.coinbaseFlags;
var commit = bcoin.script.createCommitment(hash, this.coinbaseFlags); var hash;
output.script = commit;
// 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() { MinerBlock.prototype.updateCoinbase = function updateCoinbase() {
var input = this.coinbase.inputs[0]; var input = this.coinbase.inputs[0];
var output = this.coinbase.outputs[0]; var output = this.coinbase.outputs[0];
// Update extra nonce.
input.script.set(1, this.extraNonce); input.script.set(1, this.extraNonce);
input.script.compile(); input.script.compile();
// Update reward.
output.value = this.block.getReward(this.network); output.value = this.block.getReward(this.network);
}; };
@ -465,7 +491,10 @@ MinerBlock.prototype.updateMerkle = function updateMerkle() {
if (this.witness) if (this.witness)
this.updateCommitment(); this.updateCommitment();
// Update timestamp.
this.block.ts = Math.max(bcoin.now(), this.tip.ts + 1); this.block.ts = Math.max(bcoin.now(), this.tip.ts + 1);
// Recalculate merkle root.
this.block.merkleRoot = this.block.getMerkleRoot('hex'); this.block.merkleRoot = this.block.getMerkleRoot('hex');
}; };
@ -609,8 +638,6 @@ MinerBlock.prototype.mine = function mine(callback) {
if (!self.findNonce()) if (!self.findNonce())
return self.mine(callback); return self.mine(callback);
self.block.txs[0] = self.block.txs[0].toTX();
return callback(null, self.block); return callback(null, self.block);
}, 100); }, 100);
}; };
@ -622,7 +649,6 @@ MinerBlock.prototype.mine = function mine(callback) {
MinerBlock.prototype.mineSync = function mineSync() { MinerBlock.prototype.mineSync = function mineSync() {
while (!this.findNonce()); while (!this.findNonce());
this.block.txs[0] = this.block.txs[0].toTX();
return this.block; return this.block;
}; };

View File

@ -2568,7 +2568,7 @@ Script.fromAddress = function fromAddress(address) {
* @returns {Script} * @returns {Script}
*/ */
Script.createCommitment = function createCommitment(hash, flags) { Script.fromCommitment = function fromCommitment(hash, flags) {
var p; var p;
if (!flags) if (!flags)