Repository: bitcoin/bitcoin
File: src/test/fuzz/p2p_headers_presync.cpp (C++)

Code before:

void HeadersSyncSetup::SendMessage(FuzzedDataProvider& fuzzed_data_provider, CSerializedNetMsg&& msg)
{
    auto& connman = static_cast<ConnmanTestMsg&>(*m_node.connman);
    CNode& connection = *PickValue(fuzzed_data_provider, m_connections);

    connman.FlushSendBuffer(connection);
    (void)connman.ReceiveMsgFrom(connection, std::move(msg));
    connection.fPauseSend = false;
    try {
        connman.ProcessMessagesOnce(connection);
    } catch (const std::ios_base::failure&) {
    }
    m_node.peerman->SendMessages(&connection);
}

CBlockHeader ConsumeHeader(FuzzedDataProvider& fuzzed_data_provider, const uint256& prev_hash, uint32_t prev_nbits)
{
    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);
    header.nTime = ConsumeTime(fuzzed_data_provider);
    header.hashPrevBlock = prev_hash;
    header.nVersion = fuzzed_data_provider.ConsumeIntegral<int32_t>();
    return header;
}

CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& prev_hash, uint32_t prev_nbits)
{
    auto header = ConsumeHeader(fuzzed_data_provider, prev_hash, prev_nbits);
    // In order to reach the headers acceptance logic, the block is
    // constructed in a way that will pass the mutation checks.
    CBlock block{header};
    CMutableTransaction tx;
    tx.vin.resize(1);
    tx.vout.resize(1);
    tx.vout[0].nValue = 0;
    tx.vin[0].scriptSig.resize(2);
    block.vtx.push_back(MakeTransactionRef(tx));
    block.hashMerkleRoot = block.vtx[0]->GetHash();
    return block;
}

void FinalizeHeader(CBlockHeader& header, const ChainstateManager& chainman)
{
    while (!CheckProofOfWork(header.GetHash(), header.nBits, chainman.GetParams().GetConsensus())) {
        ++(header.nNonce);
    }

Review comment (suggestion):
```suggestion
    // should return the values below.
    //
    // RPC commands to verify:
    // getblockheader 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
    // getblockheader 0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5
```

nit: Perhaps add the rpc commands that can be used to verify the values to the comment

Code after:
}

void HeadersSyncSetup::SendMessage(FuzzedDataProvider& fuzzed_data_provider, CSerializedNetMsg&& msg)
{
    auto& connman = static_cast<ConnmanTestMsg&>(*m_node.connman);
    CNode& connection = *PickValue(fuzzed_data_provider, m_connections);

    connman.FlushSendBuffer(connection);
    (void)connman.ReceiveMsgFrom(connection, std::move(msg));
    connection.fPauseSend = false;
    try {
        connman.ProcessMessagesOnce(connection);
    } catch (const std::ios_base::failure&) {
    }
    m_node.peerman->SendMessages(&connection);
}

CBlockHeader ConsumeHeader(FuzzedDataProvider& fuzzed_data_provider, const uint256& prev_hash, uint32_t prev_nbits)
{
    CBlockHeader header;
    header.nNonce = 0;
    // 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>();
    return header;
}

CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& prev_hash, uint32_t prev_nbits)
{
    auto header = ConsumeHeader(fuzzed_data_provider, prev_hash, prev_nbits);
    // In order to reach the headers acceptance logic, the block is
    // constructed in a way that will pass the mutation checks.
    CBlock block{header};
    CMutableTransaction tx;