From 09ee8b7f278627b917f0784adf23cbc76cae5fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Mon, 12 May 2025 22:41:04 +0200 Subject: [PATCH] node: avoid recomputing block hash in `ReadBlock` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminate one SHA‑256 double‑hash computation of the header per block read by reusing the hash for: * proof‑of‑work verification; * (optional) integrity check against the supplied hash. --- src/node/blockstorage.cpp | 23 ++++++++++++----------- src/node/blockstorage.h | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index f8cdd4ce08c..04936ec99da 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -38,6 +38,7 @@ #include #include +#include #include namespace kernel { @@ -989,7 +990,7 @@ bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationSt return true; } -bool BlockManager::ReadBlock(CBlock& block, const FlatFilePos& pos) const +bool BlockManager::ReadBlock(CBlock& block, const FlatFilePos& pos, const std::optional& expected_hash) const { block.SetNull(); @@ -1007,8 +1008,10 @@ bool BlockManager::ReadBlock(CBlock& block, const FlatFilePos& pos) const return false; } + const auto block_hash{block.GetHash()}; + // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits, GetConsensus())) { + if (!CheckProofOfWork(block_hash, block.nBits, GetConsensus())) { LogError("Errors in block header at %s while reading block", pos.ToString()); return false; } @@ -1019,21 +1022,19 @@ bool BlockManager::ReadBlock(CBlock& block, const FlatFilePos& pos) const return false; } + if (expected_hash && block_hash != *expected_hash) { + LogError("GetHash() doesn't match index at %s while reading block (%s != %s)", + pos.ToString(), block_hash.ToString(), expected_hash->ToString()); + return false; + } + return true; } bool BlockManager::ReadBlock(CBlock& block, const CBlockIndex& index) const { const FlatFilePos block_pos{WITH_LOCK(cs_main, return index.GetBlockPos())}; - - if (!ReadBlock(block, block_pos)) { - return false; - } - if (block.GetHash() != index.GetBlockHash()) { - LogError("GetHash() doesn't match index for %s at %s while reading block", index.ToString(), block_pos.ToString()); - return false; - } - return true; + return ReadBlock(block, block_pos, index.GetBlockHash()); } bool BlockManager::ReadRawBlock(std::vector& block, const FlatFilePos& pos) const diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index 324f8e68605..9405f68c6cf 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -411,7 +411,7 @@ public: void UnlinkPrunedFiles(const std::set& setFilesToPrune) const; /** Functions for disk access for blocks */ - bool ReadBlock(CBlock& block, const FlatFilePos& pos) const; + bool ReadBlock(CBlock& block, const FlatFilePos& pos, const std::optional& expected_hash = {}) const; bool ReadBlock(CBlock& block, const CBlockIndex& index) const; bool ReadRawBlock(std::vector& block, const FlatFilePos& pos) const;