aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordergoegge <n.goeggi@gmail.com>2024-02-06 10:07:18 +0000
committerglozow <gloriajzhao@gmail.com>2024-03-05 10:24:35 +0000
commit8141498f3ad3ae9c42c32346ee73dc7f29e72cb5 (patch)
tree1c8f330010a801d1d0c0da88fb896440687bc963 /src
parent0c5c5962cbfdfd532cebc6706d5b838488b89d53 (diff)
[validation] Cache merkle root and witness commitment checks
Slight performance improvement by avoiding duplicate work. Github-Pull: #29412 Rebased-From: 1ec6bbeb8d27d31647d1433ccb87b362f6d81f90
Diffstat (limited to 'src')
-rw-r--r--src/primitives/block.h8
-rw-r--r--src/validation.cpp6
2 files changed, 12 insertions, 2 deletions
diff --git a/src/primitives/block.h b/src/primitives/block.h
index 99accfc7dd..832f8a03f7 100644
--- a/src/primitives/block.h
+++ b/src/primitives/block.h
@@ -71,8 +71,10 @@ public:
// network and disk
std::vector<CTransactionRef> vtx;
- // memory only
- mutable bool fChecked;
+ // Memory-only flags for caching expensive checks
+ mutable bool fChecked; // CheckBlock()
+ mutable bool m_checked_witness_commitment{false}; // CheckWitnessCommitment()
+ mutable bool m_checked_merkle_root{false}; // CheckMerkleRoot()
CBlock()
{
@@ -95,6 +97,8 @@ public:
CBlockHeader::SetNull();
vtx.clear();
fChecked = false;
+ m_checked_witness_commitment = false;
+ m_checked_merkle_root = false;
}
CBlockHeader GetBlockHeader() const
diff --git a/src/validation.cpp b/src/validation.cpp
index a2128b231e..f02d1e32a4 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3623,6 +3623,8 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
{
+ if (block.m_checked_merkle_root) return true;
+
bool mutated;
uint256 merkle_root = BlockMerkleRoot(block, &mutated);
if (block.hashMerkleRoot != merkle_root) {
@@ -3642,6 +3644,7 @@ static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
/*debug_message=*/"duplicate transaction");
}
+ block.m_checked_merkle_root = true;
return true;
}
@@ -3654,6 +3657,8 @@ static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_commitment, BlockValidationState& state)
{
if (expect_witness_commitment) {
+ if (block.m_checked_witness_commitment) return true;
+
int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != NO_WITNESS_COMMITMENT) {
assert(!block.vtx.empty() && !block.vtx[0]->vin.empty());
@@ -3679,6 +3684,7 @@ static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_comm
/*debug_message=*/strprintf("%s : witness merkle commitment mismatch", __func__));
}
+ block.m_checked_witness_commitment = true;
return true;
}
}