6 #include <chainparams.h> 40 const std::vector<std::shared_ptr<CBlock>>* g_chain;
43 template <
bool INVALID>
44 void initialize_chain()
49 static const auto setup{
53 .setup_validation_interface =
false,
54 .min_validation_cache =
true,
57 if constexpr (INVALID) {
58 auto& chainman{*setup->m_node.chainman};
59 for (
const auto& block : chain) {
61 bool processed{chainman.ProcessNewBlockHeaders({*block},
true, dummy)};
63 const auto* index{
WITH_LOCK(::
cs_main,
return chainman.m_blockman.LookupBlockIndex(block->GetHash()))};
67 g_setup = setup.get();
70 template <
bool INVALID>
74 auto& setup{*g_setup};
75 bool dirty_chainman{
false};
80 Assert(!chainman.SnapshotBlockhash());
85 if (fuzzed_data_provider.ConsumeBool()) {
87 outfile <<
Span{metadata};
89 auto msg_start = chainman.GetParams().MessageStart();
90 int base_blockheight{fuzzed_data_provider.ConsumeIntegralInRange<
int>(1, 2 *
COINBASE_MATURITY)};
91 uint256 base_blockhash{g_chain->at(base_blockheight - 1)->GetHash()};
92 uint64_t m_coins_count{fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(1, 3 *
COINBASE_MATURITY)};
97 if (fuzzed_data_provider.ConsumeBool()) {
99 outfile <<
Span{file_data};
102 for (
const auto& block : *g_chain) {
103 auto coinbase{block->vtx.at(0)};
104 outfile << coinbase->GetHash();
107 outfile <<
Coin(coinbase->vout[0], height, 1);
111 if constexpr (INVALID) {
115 const auto& coinbase{g_chain->back()->vtx.back()};
116 outfile << coinbase->GetHash();
119 outfile <<
Coin{coinbase->vout[0], 999, 0};
123 const auto ActivateFuzzedSnapshot{[&] {
125 auto msg_start = chainman.GetParams().MessageStart();
129 }
catch (
const std::ios_base::failure&) {
132 return !!chainman.ActivateSnapshot(infile, metadata,
true);
135 if (fuzzed_data_provider.ConsumeBool()) {
137 if constexpr (!INVALID) {
138 for (
const auto& block : *g_chain) {
140 bool processed{chainman.ProcessNewBlockHeaders({*block},
true, dummy)};
142 const auto* index{
WITH_LOCK(::
cs_main,
return chainman.m_blockman.LookupBlockIndex(block->GetHash()))};
145 dirty_chainman =
true;
149 if (ActivateFuzzedSnapshot()) {
151 Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash->IsNull());
152 Assert(*chainman.ActiveChainstate().m_from_snapshot_blockhash ==
153 *chainman.SnapshotBlockhash());
154 const auto& coinscache{chainman.ActiveChainstate().CoinsTip()};
155 for (
const auto& block : *g_chain) {
156 Assert(coinscache.HaveCoin(
COutPoint{block->vtx.at(0)->GetHash(), 0}));
157 const auto* index{chainman.m_blockman.LookupBlockIndex(block->GetHash())};
160 if (index->nHeight == chainman.GetSnapshotBaseHeight()) {
161 auto params{chainman.GetParams().AssumeutxoForHeight(index->nHeight)};
162 Assert(params.has_value());
163 Assert(params.value().m_chain_tx_count == index->m_chain_tx_count);
165 Assert(index->m_chain_tx_count == 0);
168 Assert(g_chain->size() == coinscache.GetCacheSize());
169 dirty_chainman =
true;
171 Assert(!chainman.SnapshotBlockhash());
172 Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash);
175 Assert(!ActivateFuzzedSnapshot());
176 if constexpr (INVALID) {
181 if (dirty_chainman) {
182 setup.m_node.chainman.reset();
183 setup.m_make_chainman();
184 setup.LoadVerifyActivateChainstate();
197 FUZZ_TARGET(utxo_snapshot , .
init = initialize_chain<false>) { utxo_snapshot_fuzz<false>(buffer); }
198 FUZZ_TARGET(utxo_snapshot_invalid, .
init = initialize_chain<true>) { utxo_snapshot_fuzz<true>(buffer); }
FILE * fopen(const fs::path &p, const char *mode)
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
Non-refcounted RAII wrapper for FILE*.
std::vector< B > ConsumeRandomLengthByteVector(FuzzedDataProvider &fuzzed_data_provider, const std::optional< size_t > &max_length=std::nullopt) noexcept
std::span< const uint8_t > FuzzBufferType
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
An outpoint - a combination of a transaction hash and an index n into its vout.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const ChainType chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
A Span is an object that can refer to a contiguous sequence of objects.
std::vector< std::shared_ptr< CBlock > > CreateBlockChain(size_t total_height, const CChainParams ¶ms)
Create a blockchain, starting from genesis.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
std::unique_ptr< ChainstateManager > chainman
Testing setup that configures a complete environment.
#define Assert(val)
Identity function.