7#include <chainparams.h>
31 header.
nNonce = nonce_counter++;
37 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
47 CBlockIndex* genesis = chainman.ActiveChainstate().m_chain[0];
48 int nonce_counter = 0;
49 std::vector<CBlockIndex*> blocks;
50 blocks.push_back(genesis);
51 bool abort_run{
false};
53 std::vector<CBlockIndex*> pruned_blocks;
66 CBlockIndex* index = blockman.AddToBlockIndex(header, chainman.m_best_header);
69 blocks.push_back(index);
81 chainman.InvalidBlockFound(index, state);
85 block.
vtx = std::vector<CTransactionRef>(nTx);
87 chainman.ReceivedBlockTransactions(block, index, pos);
96 auto& chain = chainman.ActiveChain();
100 CBlockIndex* best_tip = chainman.FindMostWorkChain();
102 if (best_tip == chain.Tip())
break;
104 const CBlockIndex* fork = chain.FindFork(best_tip);
110 assert(blockman.m_have_pruned);
116 chain.SetTip(*chain[fork->
nHeight]);
119 std::vector<CBlockIndex*> to_connect;
122 to_connect.push_back(it);
126 for (
CBlockIndex* block : to_connect | std::views::reverse) {
133 chainman.InvalidBlockFound(block, state);
135 chainman.InvalidChainFound(to_connect.front());
142 chain.SetTip(*block);
143 chainman.ActiveChainstate().PruneBlockIndexCandidates();
158 auto& chain = chainman.ActiveChain();
161 if (prune_block != chain.Tip() && (prune_block->nStatus &
BLOCK_HAVE_DATA)) {
162 blockman.m_have_pruned =
true;
163 prune_block->nStatus &= ~BLOCK_HAVE_DATA;
164 prune_block->nStatus &= ~BLOCK_HAVE_UNDO;
165 prune_block->nFile = 0;
166 prune_block->nDataPos = 0;
167 prune_block->nUndoPos = 0;
168 auto range = blockman.m_blocks_unlinked.equal_range(prune_block->pprev);
169 while (range.first != range.second) {
170 std::multimap<CBlockIndex*, CBlockIndex*>::iterator _it = range.first;
172 if (_it->second == prune_block) {
173 blockman.m_blocks_unlinked.erase(_it);
176 pruned_blocks.push_back(prune_block);
182 size_t num_pruned = pruned_blocks.size();
183 if (num_pruned == 0)
return;
188 block.
vtx = std::vector<CTransactionRef>(index->nTx);
190 chainman.ReceivedBlockTransactions(block, index, pos);
193 pruned_blocks.erase(pruned_blocks.begin() + i);
197 chainman.CheckBlockIndex();
205 chainman.m_best_header = genesis;
206 chainman.ResetBestInvalid();
207 chainman.nBlockSequenceId = 2;
208 chainman.ActiveChain().SetTip(*genesis);
209 chainman.ActiveChainstate().setBlockIndexCandidates.clear();
210 chainman.m_cached_finished_ibd =
false;
211 blockman.m_blocks_unlinked.clear();
212 blockman.m_have_pruned =
false;
213 blockman.CleanupForFuzzing();
216 for (
auto it = blockman.m_block_index.begin(); it != blockman.m_block_index.end();) {
217 if (it->first != genesis_hash) {
218 it = blockman.m_block_index.erase(it);
223 chainman.ActiveChainstate().TryAddBlockIndexCandidate(genesis);
224 assert(blockman.m_block_index.size() == 1);
225 assert(chainman.ActiveChainstate().setBlockIndexCandidates.size() == 1);
226 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
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)
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
int64_t 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)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
FuzzedDataProvider & fuzzed_data_provider