7#include <chainparams.h>
32 header.
nNonce = nonce_counter++;
38 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
48 CBlockIndex* genesis = chainman.ActiveChainstate().m_chain[0];
49 int nonce_counter = 0;
50 std::vector<CBlockIndex*> blocks;
51 blocks.push_back(genesis);
52 bool abort_run{
false};
54 std::vector<CBlockIndex*> pruned_blocks;
67 CBlockIndex* index = blockman.AddToBlockIndex(header, chainman.m_best_header);
70 blocks.push_back(index);
82 chainman.InvalidBlockFound(index, state);
86 block.
vtx = std::vector<CTransactionRef>(nTx);
88 chainman.ReceivedBlockTransactions(block, index, pos);
97 auto& chain = chainman.ActiveChain();
101 CBlockIndex* best_tip = chainman.FindMostWorkChain();
103 if (best_tip == chain.Tip())
break;
105 const CBlockIndex* fork = chain.FindFork(best_tip);
111 assert(blockman.m_have_pruned);
117 chain.SetTip(*chain[fork->
nHeight]);
120 std::vector<CBlockIndex*> to_connect;
123 to_connect.push_back(it);
127 for (
CBlockIndex* block : to_connect | std::views::reverse) {
134 chainman.InvalidBlockFound(block, state);
136 chainman.InvalidChainFound(to_connect.front());
143 chain.SetTip(*block);
144 chainman.ActiveChainstate().PruneBlockIndexCandidates();
159 auto& chain = chainman.ActiveChain();
162 if (prune_block != chain.Tip() && (prune_block->nStatus &
BLOCK_HAVE_DATA)) {
163 blockman.m_have_pruned =
true;
164 prune_block->nStatus &= ~BLOCK_HAVE_DATA;
165 prune_block->nStatus &= ~BLOCK_HAVE_UNDO;
166 prune_block->nFile = 0;
167 prune_block->nDataPos = 0;
168 prune_block->nUndoPos = 0;
169 auto range = blockman.m_blocks_unlinked.equal_range(prune_block->pprev);
170 while (range.first != range.second) {
171 std::multimap<CBlockIndex*, CBlockIndex*>::iterator _it = range.first;
173 if (_it->second == prune_block) {
174 blockman.m_blocks_unlinked.erase(_it);
177 pruned_blocks.push_back(prune_block);
183 size_t num_pruned = pruned_blocks.size();
184 if (num_pruned == 0)
return;
189 block.
vtx = std::vector<CTransactionRef>(index->nTx);
191 chainman.ReceivedBlockTransactions(block, index, pos);
194 pruned_blocks.erase(pruned_blocks.begin() + i);
198 chainman.CheckBlockIndex();
206 chainman.m_best_header = genesis;
207 chainman.ResetBestInvalid();
208 chainman.nBlockSequenceId = 2;
209 chainman.ActiveChain().SetTip(*genesis);
210 chainman.ActiveChainstate().setBlockIndexCandidates.clear();
211 chainman.m_cached_is_ibd =
true;
212 blockman.m_blocks_unlinked.clear();
213 blockman.m_have_pruned =
false;
214 blockman.CleanupForFuzzing();
217 for (
auto it = blockman.m_block_index.begin(); it != blockman.m_block_index.end();) {
218 if (it->first != genesis_hash) {
219 it = blockman.m_block_index.erase(it);
224 chainman.ActiveChainstate().TryAddBlockIndexCandidate(genesis);
225 assert(blockman.m_block_index.size() == 1);
226 assert(chainman.ActiveChainstate().setBlockIndexCandidates.size() == 1);
227 assert(chainman.ActiveChain().Height() == 0);
FUZZ_TARGET(block_index_tree,.init=initialize_block_index_tree)
CBlockHeader ConsumeBlockHeader(FuzzedDataProvider &provider, uint256 prev_hash, int &nonce_counter)
void initialize_block_index_tree()
const TestingSetup * g_setup
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
@ BLOCK_HAVE_DATA
full block available in blk*.dat
@ BLOCK_FAILED_VALID
stage after last reached validness failed
const CChainParams & Params()
Return the currently selected parameters.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
uint256 GetBlockHash() const
unsigned int nTx
Number of transactions in this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
const CBlock & GenesisBlock() const
T ConsumeIntegralInRange(T min, T max)
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Testing setup that configures a complete environment.
std::unique_ptr< ChainstateManager > chainman
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
FuzzedDataProvider & fuzzed_data_provider