Merge bitcoin/bitcoin#32638: blocks: force hash validations on disk read

9341b5333a blockstorage: make block read hash checks explicit (Lőrinc)
2371b9f4ee test/bench: verify hash in `ComputeFilter` reads (Lőrinc)
5d235d50d6 net: assert block hash in `ProcessGetBlockData` and `ProcessMessage` (Lőrinc)

Pull request description:

  A follow-up to https://github.com/bitcoin/bitcoin/pull/32487#discussion_r2094072165, after which validating the hash of a read block from disk doesn't incur the cost of calculating its hash anymore.

  ### Summary

  This PR adds explicit checks that the read block header's hash matches the one we were expecting.

  ### Context

  After the previous PR, validating a block's hash during read operations became essentially free. This PR leverages that by requiring callers to provide a block's expected hash (or `std::nullopt`), preventing silent failures caused by corrupted or mismatched data. Most `ReadBlock` usages were updated with expected hashes and now fail on mismatch.

  ### Changes

  * added hash assertions in `ProcessGetBlockData` and `ProcessMessage` to validate that the block read from disk matches the expected hash;
  * updated tests and benchmark to pass the correct block hash to `ReadBlock()`, ensuring the hash validation is tested - or none if we already expect PoW failure;
  * removed the default value for `expected_hash`, requiring an explicit hash for all block reads.

  ### Why is the hash still optional (but no longer has a default value)

  * for header-error tests, where the goal is to trigger failures early in the parsing process;
  * for out-of-order orphan blocks, where the child hash isn't available before the initial disk read.

ACKs for top commit:
  maflcko:
    review ACK 9341b5333a 🕙
  achow101:
    ACK 9341b5333a
  hodlinator:
    ACK 9341b5333a
  janb84:
    re ACK 9341b5333a

Tree-SHA512: cf1d4fff4c15e3f8898ec284929cb83d7e747125d4ee759e77d369f1716728e843ef98030be32c8d608956a96ae2fbefa0e801200c333b9eefd6c086ec032e1f
This commit is contained in:
Ava Chow
2025-06-27 13:28:26 -07:00
6 changed files with 18 additions and 16 deletions

View File

@@ -190,12 +190,12 @@ BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file)
BOOST_CHECK_EQUAL(read_block.nVersion, 0);
{
ASSERT_DEBUG_LOG("Errors in block header");
BOOST_CHECK(!blockman.ReadBlock(read_block, pos1));
BOOST_CHECK(!blockman.ReadBlock(read_block, pos1, {}));
BOOST_CHECK_EQUAL(read_block.nVersion, 1);
}
{
ASSERT_DEBUG_LOG("Errors in block header");
BOOST_CHECK(!blockman.ReadBlock(read_block, pos2));
BOOST_CHECK(!blockman.ReadBlock(read_block, pos2, {}));
BOOST_CHECK_EQUAL(read_block.nVersion, 2);
}
@@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(blockmanager_flush_block_file)
BOOST_CHECK_EQUAL(blockman.CalculateCurrentUsage(), (TEST_BLOCK_SIZE + STORAGE_HEADER_BYTES) * 2);
// Block 2 was not overwritten:
blockman.ReadBlock(read_block, pos2);
BOOST_CHECK(!blockman.ReadBlock(read_block, pos2, {}));
BOOST_CHECK_EQUAL(read_block.nVersion, 2);
}

View File

@@ -17,7 +17,7 @@ bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex& block_index,
LOCK(::cs_main);
CBlock block;
if (!blockman.ReadBlock(block, block_index.GetBlockPos())) {
if (!blockman.ReadBlock(block, block_index)) {
return false;
}