Skip to content

Commit

Permalink
Remove restrictions on coinbase witness
Browse files Browse the repository at this point in the history
This relaxes the restriction on the coinbase witness that limited it to
only having one entry that must be 32 bytes; instead there may be up to
255 items on the coinbase witness stack, and they may be any length.

In order to have multiple entries on the coinbase witness stack, the
number of entries must be specified in the coinbase commitment, by
changing the witness commitment from a 36 byte push:

  OP_RETURN [ 0xaa 0x21 0xa9 0xed HASH ]

to a 37 byte push:

  OP_RETURN [ 0xaa 0x21 0xa9 0xed HASH N ]

where N is the number of entries on the coinbase witness stack (from 0
to 255).
  • Loading branch information
ajtowns committed Mar 17, 2016
1 parent 0a25cca commit 86c55b0
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3063,9 +3063,17 @@ bool IsWitnessEnabled(const CBlock& block, const CBlockIndex* pindexPrev, const
}


bool CheckWitnessCommitAndNonce(const CBlock& block, int commitpos, CValidationState& state)
bool CheckWitnessCommit(const CBlock& block, int commitpos, CValidationState& state)
{
if (block.vtx[0].wit.vtxinwit.size() != 1 || block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.size() != 1 || block.vtx[0].wit.vtxinwit[0].scriptWitness.stack[0].size() != 32) {
size_t stack_size;

if (block.vtx[0].vout[commitpos].scriptPubKey[1] == 0x24) {
stack_size = 1;
} else {
stack_size = block.vtx[0].vout[commitpos].scriptPubKey[38];
}

if (block.vtx[0].wit.vtxinwit.size() != 1 || block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.size() != stack_size) {
return state.DoS(100, error("%s : invalid witness commitment size", __func__), REJECT_INVALID, "bad-witness-merkle-size", true);
}

Expand All @@ -3088,7 +3096,9 @@ int FindWitnessCommitPos(const CBlock& block)
for (size_t o = 0; o < block.vtx[0].vout.size(); o++) {
if (block.vtx[0].vout[o].scriptPubKey.size() >= 38
&& block.vtx[0].vout[o].scriptPubKey[0] == OP_RETURN
&& block.vtx[0].vout[o].scriptPubKey[1] == 0x24
&& (block.vtx[0].vout[o].scriptPubKey[1] == 0x24
|| (block.vtx[0].vout[o].scriptPubKey[1] == 0x25
&& block.vtx[0].vout[o].scriptPubKey.size() >= 39))
&& block.vtx[0].vout[o].scriptPubKey[2] == 0xaa
&& block.vtx[0].vout[o].scriptPubKey[3] == 0x21
&& block.vtx[0].vout[o].scriptPubKey[4] == 0xa9
Expand Down Expand Up @@ -3222,7 +3232,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
if (IsWitnessEnabled(block, pindexPrev, consensusParams)) {
int commitpos = FindWitnessCommitPos(block);
if (commitpos != -1) {
if (!CheckWitnessCommitAndNonce(block, commitpos, state)) {
if (!CheckWitnessCommit(block, commitpos, state)) {
return false;
}

Expand Down

0 comments on commit 86c55b0

Please sign in to comment.