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.
This commit is contained in:
marcofleon 2024-11-04 12:31:44 +00:00
parent fa327c77e3
commit a6ca8f3243

View file

@ -1,3 +1,4 @@
#include <arith_uint256.h>
#include <blockencodings.h>
#include <net.h>
#include <net_processing.h>
@ -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<uint32_t>(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<int32_t>();