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

Code before:
}

CBlockHeader ConsumeBlockHeader(FuzzedDataProvider& provider)
{
    CBlockHeader header;
    header.nVersion = provider.ConsumeIntegral<decltype(header.nVersion)>();
    header.hashPrevBlock = g_block_hash;
    header.hashMerkleRoot = g_block_hash;
    header.nTime = provider.ConsumeIntegral<decltype(header.nTime)>();
    header.nBits = g_bits;
    header.nNonce = provider.ConsumeIntegral<decltype(header.nNonce)>();
    return header;
}

} // namespace

void init_block_index()
{
    static const auto testing_setup = MakeNoLogFileContext<>(ChainType::MAIN);
    g_setup = testing_setup.get();
}

FUZZ_TARGET(block_index, .init = init_block_index)
{
    FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
    auto block_index = kernel::BlockTreeDB(DBParams{
        .path = "", // Memory only.
        .cache_bytes = 1 << 20, // 1MB.
        .memory_only = true,
    });

    // Generate a number of block files to be stored in the index.
    int files_count = fuzzed_data_provider.ConsumeIntegralInRange(1, 100);
    std::vector<std::unique_ptr<CBlockFileInfo>> files;
    files.reserve(files_count);
    std::vector<std::pair<int, const CBlockFileInfo*>> files_info;
    files_info.reserve(files_count);
    for (int i = 0; i < files_count; i++) {
        if (auto file_info = ConsumeDeserializable<CBlockFileInfo>(fuzzed_data_provider)) {
            files.push_back(std::make_unique<CBlockFileInfo>(std::move(*file_info)));
            files_info.emplace_back(i, files.back().get());
        } else {
            return;
        }
    }

    // Generate a number of block headers to be stored in the index.
    int blocks_count = fuzzed_data_provider.ConsumeIntegralInRange(files_count * 10, files_count * 100);
    std::vector<std::unique_ptr<CBlockIndex>> blocks;
    blocks.reserve(blocks_count);
    std::vector<const CBlockIndex*> blocks_info;

Review comment (performance):
nit (feel free to ignore):

```diff
diff --git a/src/test/fuzz/block_index.cpp b/src/test/fuzz/block_index.cpp
index 7885eda747..3f2a55f310 100644
--- a/src/test/fuzz/block_index.cpp
+++ b/src/test/fuzz/block_index.cpp
@@ -54,11 +54,6 @@ void init_block_index()
 FUZZ_TARGET(block_index, .init = init_block_index)
 {
     FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
-    auto block_index = kernel::BlockTreeDB(DBParams{
-        .path = "", // Memory only.
-        .cache_bytes = 1 << 20, // 1MB.
-        .memory_only = true,
-    });
 
     // Generate a number of block files to be stored in the index.
     int files_count = fuzzed_data_provider.ConsumeIntegralInRange(1, 100);
@@ -75,6 +70,12 @@ FUZZ_TARGET(block_index, .init = init_block_index)
         }
     }
 
+    auto block_index = kernel::BlockTreeDB(DBParams{
+        .path = "", // Memory only.
+        .cache_bytes = 1 << 20, // 1MB.
+        .memory_only = true,
+    });
+
     // Generate a number of block headers to be stored in the index.
     int blocks_count = fuzzed_data_provider.ConsumeIntegralInRange(files_count * 10, files_count * 100);
     std::vector<std::unique_ptr<CBlockIndex>> blocks;
```

we could initialize the DB after having the files.

Code after:

CBlockHeader ConsumeBlockHeader(FuzzedDataProvider& provider)
{
    CBlockHeader header;
    header.nVersion = provider.ConsumeIntegral<decltype(header.nVersion)>();
    header.hashPrevBlock = g_block_hash;
    header.hashMerkleRoot = g_block_hash;
    header.nTime = provider.ConsumeIntegral<decltype(header.nTime)>();
    header.nBits = Params().GenesisBlock().nBits;
    header.nNonce = provider.ConsumeIntegral<decltype(header.nNonce)>();
    return header;
}

} // namespace

void init_block_index()
{
    static const auto testing_setup = MakeNoLogFileContext<>(ChainType::MAIN);
    g_setup = testing_setup.get();
    g_block_hash = Params().GenesisBlock().GetHash();
}

FUZZ_TARGET(block_index, .init = init_block_index)
{
    FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
    auto block_index = kernel::BlockTreeDB(DBParams{
        .path = "", // Memory only.
        .cache_bytes = 1 << 20, // 1MB.
        .memory_only = true,
    });

    // Generate a number of block files to be stored in the index.
    int files_count = fuzzed_data_provider.ConsumeIntegralInRange(1, 100);
    std::vector<std::unique_ptr<CBlockFileInfo>> files;
    files.reserve(files_count);
    std::vector<std::pair<int, const CBlockFileInfo*>> files_info;
    files_info.reserve(files_count);
    for (int i = 0; i < files_count; i++) {
        if (auto file_info = ConsumeDeserializable<CBlockFileInfo>(fuzzed_data_provider)) {
            files.push_back(std::make_unique<CBlockFileInfo>(std::move(*file_info)));
            files_info.emplace_back(i, files.back().get());
        } else {
            return;
        }
    }

    // Generate a number of block headers to be stored in the index.
    int blocks_count = fuzzed_data_provider.ConsumeIntegralInRange(files_count * 10, files_count * 100);
    std::vector<std::unique_ptr<CBlockIndex>> blocks;
    blocks.reserve(blocks_count);
    std::vector<const CBlockIndex*> blocks_info;