diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp index 5a9df1e48a4..825fada9dda 100644 --- a/src/test/fuzz/utxo_snapshot.cpp +++ b/src/test/fuzz/utxo_snapshot.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,31 @@ using node::SnapshotMetadata; namespace { const std::vector>* g_chain; -TestingSetup* g_setup; +TestingSetup* g_setup{nullptr}; + +/** Sanity check the assumeutxo values hardcoded in chainparams for the fuzz target. */ +void sanity_check_snapshot() +{ + Assert(g_chain && g_setup == nullptr); + + // Create a temporary chainstate manager to connect the chain to. + const auto tmp_setup{MakeNoLogFileContext(ChainType::REGTEST, TestOpts{.setup_net = false})}; + const auto& node{tmp_setup->m_node}; + for (auto& block: *g_chain) { + ProcessBlock(node, block); + } + + // Connect the chain to the tmp chainman and sanity check the chainparams snapshot values. + LOCK(cs_main); + auto& cs{node.chainman->ActiveChainstate()}; + cs.ForceFlushStateToDisk(); + const auto stats{*Assert(kernel::ComputeUTXOStats(kernel::CoinStatsHashType::HASH_SERIALIZED, &cs.CoinsDB(), node.chainman->m_blockman))}; + const auto cp_au_data{*Assert(node.chainman->GetParams().AssumeutxoForHeight(2 * COINBASE_MATURITY))}; + Assert(stats.nHeight == cp_au_data.height); + Assert(stats.nTransactions + 1 == cp_au_data.m_chain_tx_count); // +1 for the genesis tx. + Assert(stats.hashBlock == cp_au_data.blockhash); + Assert(AssumeutxoHash{stats.hashSerialized} == cp_au_data.hash_serialized); +} template void initialize_chain() @@ -47,6 +72,10 @@ void initialize_chain() const auto params{CreateChainParams(ArgsManager{}, ChainType::REGTEST)}; static const auto chain{CreateBlockChain(2 * COINBASE_MATURITY, *params)}; g_chain = &chain; + + // Make sure we can generate a valid snapshot. + sanity_check_snapshot(); + static const auto setup{ MakeNoLogFileContext(ChainType::REGTEST, TestOpts{