[validation] Cache merkle root and witness commitment checks

Slight performance improvement by avoiding duplicate work.

Github-Pull: #29412
Rebased-From: 1ec6bbeb8d
pull/29531/head
dergoegge 9 months ago committed by Ava Chow
parent de97ecf14f
commit 0667441a7b
No known key found for this signature in database
GPG Key ID: 17565732E08E5E41

@ -71,8 +71,10 @@ public:
// network and disk // network and disk
std::vector<CTransactionRef> vtx; std::vector<CTransactionRef> vtx;
// memory only // Memory-only flags for caching expensive checks
mutable bool fChecked; mutable bool fChecked; // CheckBlock()
mutable bool m_checked_witness_commitment{false}; // CheckWitnessCommitment()
mutable bool m_checked_merkle_root{false}; // CheckMerkleRoot()
CBlock() CBlock()
{ {
@ -96,6 +98,8 @@ public:
CBlockHeader::SetNull(); CBlockHeader::SetNull();
vtx.clear(); vtx.clear();
fChecked = false; fChecked = false;
m_checked_witness_commitment = false;
m_checked_merkle_root = false;
} }
CBlockHeader GetBlockHeader() const CBlockHeader GetBlockHeader() const

@ -3488,6 +3488,8 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state) static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
{ {
if (block.m_checked_merkle_root) return true;
bool mutated; bool mutated;
uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
if (block.hashMerkleRoot != hashMerkleRoot2) if (block.hashMerkleRoot != hashMerkleRoot2)
@ -3499,12 +3501,15 @@ static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
if (mutated) if (mutated)
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txns-duplicate", "duplicate transaction"); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txns-duplicate", "duplicate transaction");
block.m_checked_merkle_root = true;
return true; return true;
} }
static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_commitment, BlockValidationState& state) static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_commitment, BlockValidationState& state)
{ {
if (expect_witness_commitment) { if (expect_witness_commitment) {
if (block.m_checked_witness_commitment) return true;
int commitpos = GetWitnessCommitmentIndex(block); int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != NO_WITNESS_COMMITMENT) { if (commitpos != NO_WITNESS_COMMITMENT) {
bool malleated = false; bool malleated = false;
@ -3520,6 +3525,7 @@ static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_comm
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__)); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__));
} }
block.m_checked_witness_commitment = true;
return true; return true;
} }
} }

Loading…
Cancel
Save