diff options
-rw-r--r-- | src/consensus/validation.h | 27 | ||||
-rw-r--r-- | src/validation.cpp | 26 | ||||
-rw-r--r-- | src/validation.h | 5 |
3 files changed, 30 insertions, 28 deletions
diff --git a/src/consensus/validation.h b/src/consensus/validation.h index 2a93a090d6..e007c481df 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -12,6 +12,12 @@ #include <primitives/transaction.h> #include <primitives/block.h> +/** Index marker for when no witness commitment is present in a coinbase transaction. */ +static constexpr int NO_WITNESS_COMMITMENT{-1}; + +/** Minimum size of a witness commitment structure. Defined in BIP 141. **/ +static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38}; + /** A "reason" why a transaction was invalid, suitable for determining whether the * provider of the transaction should be banned/ignored/disconnected/etc. */ @@ -151,4 +157,25 @@ static inline int64_t GetTransactionInputWeight(const CTxIn& txin) return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION); } +/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */ +inline int GetWitnessCommitmentIndex(const CBlock& block) +{ + int commitpos = NO_WITNESS_COMMITMENT; + if (!block.vtx.empty()) { + for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { + const CTxOut& vout = block.vtx[0]->vout[o]; + if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT && + vout.scriptPubKey[0] == OP_RETURN && + vout.scriptPubKey[1] == 0x24 && + vout.scriptPubKey[2] == 0xaa && + vout.scriptPubKey[3] == 0x21 && + vout.scriptPubKey[4] == 0xa9 && + vout.scriptPubKey[5] == 0xed) { + commitpos = o; + } + } + } + return commitpos; +} + #endif // BITCOIN_CONSENSUS_VALIDATION_H diff --git a/src/validation.cpp b/src/validation.cpp index cf2f9dde62..be1374e810 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3395,31 +3395,11 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa return (height >= params.SegwitHeight); } -int GetWitnessCommitmentIndex(const CBlock& block) -{ - int commitpos = -1; - if (!block.vtx.empty()) { - for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { - const CTxOut& vout = block.vtx[0]->vout[o]; - if (vout.scriptPubKey.size() >= MINIMUM_WITNESS_COMMITMENT && - vout.scriptPubKey[0] == OP_RETURN && - vout.scriptPubKey[1] == 0x24 && - vout.scriptPubKey[2] == 0xaa && - vout.scriptPubKey[3] == 0x21 && - vout.scriptPubKey[4] == 0xa9 && - vout.scriptPubKey[5] == 0xed) { - commitpos = o; - } - } - } - return commitpos; -} - void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) { int commitpos = GetWitnessCommitmentIndex(block); static const std::vector<unsigned char> nonce(32, 0x00); - if (commitpos != -1 && IsWitnessEnabled(pindexPrev, consensusParams) && !block.vtx[0]->HasWitness()) { + if (commitpos != NO_WITNESS_COMMITMENT && IsWitnessEnabled(pindexPrev, consensusParams) && !block.vtx[0]->HasWitness()) { CMutableTransaction tx(*block.vtx[0]); tx.vin[0].scriptWitness.stack.resize(1); tx.vin[0].scriptWitness.stack[0] = nonce; @@ -3433,7 +3413,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc int commitpos = GetWitnessCommitmentIndex(block); std::vector<unsigned char> ret(32, 0x00); if (consensusParams.SegwitHeight != std::numeric_limits<int>::max()) { - if (commitpos == -1) { + if (commitpos == NO_WITNESS_COMMITMENT) { uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr); CHash256().Write(witnessroot).Write(ret).Finalize(witnessroot); CTxOut out; @@ -3571,7 +3551,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat bool fHaveWitness = false; if (nHeight >= consensusParams.SegwitHeight) { int commitpos = GetWitnessCommitmentIndex(block); - if (commitpos != -1) { + if (commitpos != NO_WITNESS_COMMITMENT) { bool malleated = false; uint256 hashWitness = BlockWitnessMerkleRoot(block, &malleated); // The malleation check is ignored; as the transaction tree itself diff --git a/src/validation.h b/src/validation.h index 534162d64a..f3738a49ec 100644 --- a/src/validation.h +++ b/src/validation.h @@ -93,8 +93,6 @@ static const unsigned int DEFAULT_CHECKLEVEL = 3; // one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB // Setting the target to >= 550 MiB will make it likely we can respect the target. static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; -/** Minimum size of a witness commitment structure. Defined in BIP 141. **/ -static constexpr size_t MINIMUM_WITNESS_COMMITMENT{38}; struct BlockHasher { @@ -306,9 +304,6 @@ bool TestBlockValidity(BlockValidationState& state, const CChainParams& chainpar * Note that transaction witness validation rules are always enforced when P2SH is enforced. */ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params); -/** Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found */ -int GetWitnessCommitmentIndex(const CBlock& block); - /** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); |