From a6ca8f324396522e9748c9a7bbefb3bf1c74a436 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Mon, 4 Nov 2024 12:31:44 +0000 Subject: [PATCH] fuzz: Fix difficulty target generation in p2p_headers_presync The hardcoded nBits range would occasionally produce values for the difficulty target that were too low, causing the total work of the test chain to exceed MinimumChainWork. This fix uses ConsumeArithUInt256InRange to properly generate targets that will produce header chains with less work than MinimumChainWork. --- src/test/fuzz/p2p_headers_presync.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/test/fuzz/p2p_headers_presync.cpp b/src/test/fuzz/p2p_headers_presync.cpp index 2670aa8ee4e1a..5c9ce8723df49 100644 --- a/src/test/fuzz/p2p_headers_presync.cpp +++ b/src/test/fuzz/p2p_headers_presync.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -89,10 +90,23 @@ CBlockHeader ConsumeHeader(FuzzedDataProvider& fuzzed_data_provider, const uint2 { CBlockHeader header; header.nNonce = 0; - // Either use the previous difficulty or let the fuzzer choose - header.nBits = fuzzed_data_provider.ConsumeBool() ? - prev_nbits : - fuzzed_data_provider.ConsumeIntegralInRange(0x17058EBE, 0x1D00FFFF); + // Either use the previous difficulty or let the fuzzer choose. The upper target in the + // range comes from the bits value of the genesis block, which is 0x1d00ffff. The lower + // target comes from the bits value of mainnet block 840000, which is 0x17034219. + // Calling lower_target.SetCompact(0x17034219) and upper_target.SetCompact(0x1d00ffff) + // should return the values below. + // + // RPC commands to verify: + // getblockheader 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // getblockheader 0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5 + if (fuzzed_data_provider.ConsumeBool()) { + header.nBits = prev_nbits; + } else { + arith_uint256 lower_target = UintToArith256(uint256{"0000000000000000000342190000000000000000000000000000000000000000"}); + arith_uint256 upper_target = UintToArith256(uint256{"00000000ffff0000000000000000000000000000000000000000000000000000"}); + arith_uint256 target = ConsumeArithUInt256InRange(fuzzed_data_provider, lower_target, upper_target); + header.nBits = target.GetCompact(); + } header.nTime = ConsumeTime(fuzzed_data_provider); header.hashPrevBlock = prev_hash; header.nVersion = fuzzed_data_provider.ConsumeIntegral();