minerblock: ensure constant coinbase size.
This commit is contained in:
parent
09c2357552
commit
f2964e06fb
@ -550,6 +550,7 @@ MinerOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
if (typeof flags === 'string')
|
||||
flags = new Buffer(flags, 'utf8');
|
||||
assert(Buffer.isBuffer(flags));
|
||||
assert(flags.length <= 20, 'Coinbase flags > 20 bytes.');
|
||||
this.coinbaseFlags = flags;
|
||||
}
|
||||
|
||||
|
||||
@ -116,9 +116,12 @@ MinerBlock.prototype.getRate = function() {
|
||||
|
||||
MinerBlock.prototype._init = function _init() {
|
||||
var scale = consensus.WITNESS_SCALE_FACTOR;
|
||||
var hash = encoding.ZERO_HASH;
|
||||
var block = this.block;
|
||||
var cb = this.coinbase;
|
||||
var input, output, nonce;
|
||||
var input, output, commit, padding;
|
||||
|
||||
assert(this.coinbaseFlags.length <= 20);
|
||||
|
||||
// Setup our block.
|
||||
block.version = this.version;
|
||||
@ -136,7 +139,7 @@ MinerBlock.prototype._init = function _init() {
|
||||
|
||||
// Let the world know this little
|
||||
// miner succeeded.
|
||||
input.script.set(1, this.coinbaseFlags);
|
||||
input.script.set(1, encoding.ZERO_HASH160);
|
||||
|
||||
// Smaller nonce for good measure.
|
||||
input.script.set(2, util.nonce().slice(0, 4));
|
||||
@ -147,42 +150,97 @@ MinerBlock.prototype._init = function _init() {
|
||||
|
||||
input.script.compile();
|
||||
|
||||
// Set up the witness nonce.
|
||||
if (this.witness) {
|
||||
input.witness.set(0, block.createWitnessNonce());
|
||||
input.witness.compile();
|
||||
}
|
||||
|
||||
cb.inputs.push(input);
|
||||
|
||||
// Reward output.
|
||||
output = new Output();
|
||||
output.script.fromAddress(this.address);
|
||||
output.script.fromPubkeyhash(encoding.ZERO_HASH160);
|
||||
|
||||
cb.outputs.push(output);
|
||||
|
||||
// If we're using segwit, we need to
|
||||
// set up the nonce and commitment.
|
||||
// If we're using segwit, we
|
||||
// need to set up the commitment.
|
||||
if (this.witness) {
|
||||
// Our witness nonce is the hash256
|
||||
// of the previous block hash.
|
||||
nonce = block.createWitnessNonce();
|
||||
|
||||
// Set up the witness nonce.
|
||||
input.witness.set(0, nonce);
|
||||
input.witness.compile();
|
||||
|
||||
// Commitment output.
|
||||
cb.outputs.push(new Output());
|
||||
commit = new Output();
|
||||
commit.script.fromCommitment(hash);
|
||||
cb.outputs.push(commit);
|
||||
}
|
||||
|
||||
block.txs.push(cb);
|
||||
|
||||
// Update commitments.
|
||||
this.refresh();
|
||||
|
||||
// Initialize weight.
|
||||
this.weight = this.block.getWeight();
|
||||
this.weight = block.getWeight();
|
||||
|
||||
// 4 extra bytes for varint tx count.
|
||||
this.weight += 4 * scale;
|
||||
|
||||
// Padding for the CB height (constant size).
|
||||
padding = 5 - input.script.code[0].getSize();
|
||||
assert(padding >= 0);
|
||||
|
||||
this.weight += padding * scale;
|
||||
|
||||
// Reserved size.
|
||||
// Without segwit:
|
||||
// Block weight = 840
|
||||
// Block stripped size = 210
|
||||
// Block size = 210
|
||||
// CB weight = 500
|
||||
// CB stripped size = 125
|
||||
// CB size = 125
|
||||
// Sigops cost = 4
|
||||
// With segwit:
|
||||
// Block weight = 1064
|
||||
// Block stripped size = 257
|
||||
// Block size = 293
|
||||
// CB weight = 724
|
||||
// CB stripped size = 172
|
||||
// CB size = 208
|
||||
// Sigops cost = 4
|
||||
if (!this.witness) {
|
||||
assert.equal(this.weight, 840);
|
||||
assert.equal(block.getBaseSize() + 4 + padding, 210);
|
||||
assert.equal(block.getSize() + 4 + padding, 210);
|
||||
assert.equal(cb.getWeight() + padding * scale, 500);
|
||||
assert.equal(cb.getBaseSize() + padding, 125);
|
||||
assert.equal(cb.getSize() + padding, 125);
|
||||
} else {
|
||||
assert.equal(this.weight, 1064);
|
||||
assert.equal(block.getBaseSize() + 4 + padding, 257);
|
||||
assert.equal(block.getSize() + 4 + padding, 293);
|
||||
assert.equal(cb.getWeight() + padding * scale, 724);
|
||||
assert.equal(cb.getBaseSize() + padding, 172);
|
||||
assert.equal(cb.getSize() + padding, 208);
|
||||
}
|
||||
|
||||
// Initialize sigops weight.
|
||||
this.sigops = cb.getSigopsCost(null, this.flags);
|
||||
this.sigops = 4;
|
||||
|
||||
// Setup coinbase flags (variable size).
|
||||
input.script.set(1, this.coinbaseFlags);
|
||||
input.script.compile();
|
||||
|
||||
// Setup output script (variable size).
|
||||
output.script.clear();
|
||||
output.script.fromAddress(this.address);
|
||||
|
||||
// Update commitments.
|
||||
this.refresh();
|
||||
|
||||
// Ensure the variable size
|
||||
// stuff didn't break anything.
|
||||
assert(block.getWeight() <= this.weight,
|
||||
'Coinbase exceeds reserved size!');
|
||||
|
||||
assert(cb.getSigopsCost(null, this.flags) <= this.sigops,
|
||||
'Coinbase exceeds reserved sigops');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -208,7 +266,6 @@ MinerBlock.prototype.refresh = function refresh() {
|
||||
|
||||
MinerBlock.prototype.updateCommitment = function updateCommitment() {
|
||||
var output = this.coinbase.outputs[1];
|
||||
var flags = this.coinbaseFlags;
|
||||
var hash;
|
||||
|
||||
// Recalculate witness merkle root.
|
||||
@ -216,7 +273,7 @@ MinerBlock.prototype.updateCommitment = function updateCommitment() {
|
||||
|
||||
// Update commitment.
|
||||
output.script.clear();
|
||||
output.script.fromCommitment(hash, flags);
|
||||
output.script.fromCommitment(hash);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user