129 auto& connman = *
static_cast<ConnmanTestMsg*
>(setup->m_node.connman.get());
131 auto& mempool = *setup->m_node.mempool;
134 chainman.DisableNextWrite();
135 const size_t initial_index_size{
WITH_LOCK(chainman.GetMutex(),
return chainman.BlockIndex().size())};
137 AddrMan addrman{*setup->m_node.netgroupman,
true, 0};
140 mempool, *setup->m_node.warnings,
142 .deterministic_rng = true,
144 connman.SetMsgProc(peerman.get());
146 setup->m_node.validation_signals->RegisterValidationInterface(peerman.get());
147 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
151 std::vector<CNode*> peers;
152 for (
int i = 0; i < 4; ++i) {
154 CNode& p2p_node = *peers.back();
155 FillNode(fuzzed_data_provider, connman, p2p_node);
156 connman.AddTestNode(p2p_node);
160 std::vector<BlockInfo> info;
163 std::vector<std::pair<COutPoint, CAmount>> mature_coinbase = g_mature_coinbase;
165 const uint64_t initial_sequence{
WITH_LOCK(mempool.cs,
return mempool.GetSequence())};
175 unsigned long mempool_size = mempool.size();
176 if (mempool_size != 0 && fuzzed_data_provider.
ConsumeBool()) {
180 amount_in = tx->vout[0].nValue;
181 }
else if (info.size() != 0 && fuzzed_data_provider.
ConsumeBool()) {
183 auto info_it = info.begin();
185 auto tx_it = info_it->block->vtx.begin();
186 std::advance(tx_it, fuzzed_data_provider.
ConsumeIntegralInRange<
size_t>(0, info_it->block->vtx.size() - 1));
187 outpoint =
COutPoint(tx_it->get()->GetHash(), 0);
188 amount_in = tx_it->get()->vout[0].nValue;
190 auto coinbase_it = mature_coinbase.begin();
191 std::advance(coinbase_it, fuzzed_data_provider.
ConsumeIntegralInRange<
size_t>(0, mature_coinbase.size() - 1));
192 outpoint = coinbase_it->first;
193 amount_in = coinbase_it->second;
197 const auto script_sig =
CScript{};
198 const auto script_wit_stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE};
205 tx_mut.
vin.push_back(in);
207 const CAmount amount_out = amount_in - AMOUNT_FEE;
208 tx_mut.
vout.emplace_back(amount_out, P2WSH_OP_TRUE);
210 auto tx = MakeTransactionRef(tx_mut);
214 auto create_block = [&]() {
218 if (info.size() == 0 || fuzzed_data_provider.
ConsumeBool()) {
220 prev = chainman.ActiveChain().Tip()->GetBlockHash();
221 height = chainman.ActiveChain().Height() + 1;
224 prev = info[index].hash;
225 height = info[index].height + 1;
228 const auto new_time =
WITH_LOCK(
::cs_main,
return chainman.ActiveChain().Tip()->GetMedianTimePast() + 1);
233 header.
nBits = g_nBits;
234 header.
nTime = new_time;
237 std::shared_ptr<CBlock> block = std::make_shared<CBlock>();
241 coinbase_tx.
vin.resize(1);
242 coinbase_tx.
vin[0].prevout.SetNull();
244 coinbase_tx.
vout.resize(1);
247 block->vtx.push_back(MakeTransactionRef(coinbase_tx));
249 const auto mempool_size = mempool.size();
250 if (fuzzed_data_provider.
ConsumeBool() && mempool_size != 0) {
256 for (
size_t i = random_idx; i < random_idx + num_txns; ++i) {
257 CTransactionRef mempool_tx = mempool.txns_randomized[i % mempool_size].second->GetSharedTx();
258 block->vtx.push_back(mempool_tx);
265 for (
size_t i = 0; i < new_txns; ++i) {
267 block->vtx.push_back(non_mempool_tx);
272 chainman.GenerateCoinbaseCommitment(*block, pindexPrev);
278 BlockInfo block_info;
279 block_info.block = block;
280 block_info.hash = block->GetHash();
281 block_info.height = height;
288 bool sent_net_msg =
true;
289 bool requested_hb =
false;
290 bool sent_sendcmpct =
false;
291 bool valid_sendcmpct =
false;
294 fuzzed_data_provider,
297 std::shared_ptr<CBlock> cblock;
300 if (fuzzed_data_provider.
ConsumeBool() && info.size() != 0) {
302 cblock = info[index].block;
304 BlockInfo block_info = create_block();
305 cblock = block_info.block;
306 info.push_back(block_info);
310 FuzzedCBlockHeaderAndShortTxIDs cmpctblock(*cblock, nonce);
319 size_t num_erased = 1;
320 size_t num_txs = cblock->vtx.size();
322 for (
size_t i = 0; i < num_txs; ++i) {
329 uint64_t coinbase_shortid = cmpctblock.GetShortID(cblock->vtx[0]->GetWitnessHash());
330 cmpctblock.RemoveCoinbasePrefill();
331 cmpctblock.InsertCoinbaseShortTxID(coinbase_shortid);
337 uint16_t prefill_idx = num_erased == 0 ? i : i - prev_idx - 1;
341 cmpctblock.AddPrefilledTx(std::move(prefilledtx));
344 cmpctblock.EraseShortTxIDs(i - num_erased);
348 assert(cmpctblock.PrefilledTxCount() + cmpctblock.ShortTxIDCount() == num_txs);
355 size_t num_blocks = info.size();
356 if (num_blocks == 0) {
357 sent_net_msg =
false;
363 const BlockInfo& block_info = info[index];
366 std::shared_ptr<CBlock> cblock = block_info.block;
368 for (
size_t i = 0; i < cblock->vtx.size(); i++) {
371 block_txn.
txn.push_back(cblock->vtx[i]);
378 size_t num_blocks = info.size();
379 if (num_blocks == 0) {
380 sent_net_msg =
false;
386 CBlock block = *info[index].block;
388 std::vector<CBlock> headers;
389 headers.emplace_back(block);
399 sent_sendcmpct =
true;
404 BlockInfo block_info = create_block();
405 info.push_back(block_info);
406 sent_net_msg =
false;
419 node_clock.
set(tip_time);
422 sent_net_msg =
false;
430 connman.FlushSendBuffer(random_node);
431 (void)connman.ReceiveMsgFrom(random_node, std::move(net_msg));
433 bool more_work{
true};
437 more_work = connman.ProcessMessagesOnce(random_node);
438 peerman->SendMessages(random_node);
441 std::vector<CNodeStats> stats;
442 connman.GetNodeStats(stats);
447 if (stat.m_bip152_highbandwidth_to) {
449 CNode* hb_peer = peers[stat.nodeid];
463 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
464 setup->m_node.validation_signals->UnregisterAllValidationInterfaces();
467 const size_t end_index_size{
WITH_LOCK(chainman.GetMutex(),
return chainman.BlockIndex().size())};
468 const uint64_t end_sequence{
WITH_LOCK(mempool.cs,
return mempool.GetSequence())};
470 if (initial_index_size != end_index_size || initial_sequence != end_sequence) {
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.