8#include <chainparams.h>
46#include <boost/multi_index/detail/hash_index_iterator.hpp>
66std::vector<std::pair<COutPoint, CAmount>> g_mature_coinbase;
71 std::shared_ptr<CBlock> block;
83 prefilledtxn.push_back(std::move(prefilledtx));
86 void RemoveCoinbasePrefill()
88 prefilledtxn.erase(prefilledtxn.begin());
91 void InsertCoinbaseShortTxID(uint64_t shorttxid)
93 shorttxids.insert(shorttxids.begin(), shorttxid);
96 void EraseShortTxIDs(
size_t index)
98 shorttxids.erase(shorttxids.begin() + index);
101 size_t PrefilledTxCount() {
102 return prefilledtxn.size();
105 size_t ShortTxIDCount() {
106 return shorttxids.size();
115 setup.m_node.mempool.reset();
119 setup.m_node.chainman.reset();
120 setup.m_make_chainman();
121 setup.LoadVerifyActivateChainstate();
126 g_mature_coinbase.
clear();
132 CAmount subsidy{
setup.m_node.chainman->ActiveChainstate().CoinsTip().GetCoin(prevout)->out.nValue};
133 g_mature_coinbase.emplace_back(prevout, subsidy);
142 void insert(std::function<
void()> func)
override { std::thread(std::move(func)).join(); }
143 void flush()
override {}
144 size_t size()
override {
return 0; }
153 static const auto testing_setup = MakeNoLogFileContext<TestingSetup>();
157 testing_setup->m_node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<ImmediateBackgroundTaskRunner>());
158 ResetChainmanAndMempool(*
g_setup);
169 auto& mempool = *
setup->m_node.mempool;
172 chainman.DisableNextWrite();
173 const size_t initial_index_size{
WITH_LOCK(chainman.GetMutex(),
return chainman.BlockIndex().size())};
179 mempool, *
setup->m_node.warnings,
181 .deterministic_rng = true,
183 connman.SetMsgProc(peerman.get());
185 setup->m_node.validation_signals->RegisterValidationInterface(peerman.get());
186 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
190 std::vector<CNode*> peers;
191 for (
int i = 0; i < 4; ++i) {
193 CNode& p2p_node = *peers.back();
195 connman.AddTestNode(p2p_node);
199 std::vector<BlockInfo> info;
202 std::vector<std::pair<COutPoint, CAmount>> mature_coinbase = g_mature_coinbase;
204 const uint64_t initial_sequence{
WITH_LOCK(mempool.cs,
return mempool.GetSequence())};
214 unsigned long mempool_size = mempool.size();
219 amount_in = tx->vout[0].nValue;
222 auto info_it = info.begin();
224 auto tx_it = info_it->block->vtx.begin();
226 outpoint =
COutPoint(tx_it->get()->GetHash(), 0);
227 amount_in = tx_it->get()->vout[0].nValue;
229 auto coinbase_it = mature_coinbase.begin();
231 outpoint = coinbase_it->first;
232 amount_in = coinbase_it->second;
236 const auto script_sig =
CScript{};
244 tx_mut.
vin.push_back(in);
246 const CAmount amount_out = amount_in - AMOUNT_FEE;
253 auto create_block = [&]() {
259 prev = chainman.ActiveChain().Tip()->GetBlockHash();
260 height = chainman.ActiveChain().Height() + 1;
263 prev = info[index].hash;
264 height = info[index].height + 1;
267 const auto new_time =
WITH_LOCK(
::cs_main,
return chainman.ActiveChain().Tip()->GetMedianTimePast() + 1);
272 header.
nBits = g_nBits;
273 header.
nTime = new_time;
276 std::shared_ptr<CBlock> block = std::make_shared<CBlock>();
280 coinbase_tx.
vin.resize(1);
281 coinbase_tx.
vin[0].prevout.SetNull();
283 coinbase_tx.
vout.resize(1);
288 const auto mempool_size = mempool.size();
295 for (
size_t i = random_idx; i < random_idx + num_txns; ++i) {
296 CTransactionRef mempool_tx = mempool.txns_randomized[i % mempool_size].second->GetSharedTx();
297 block->vtx.push_back(mempool_tx);
304 for (
size_t i = 0; i < new_txns; ++i) {
306 block->vtx.push_back(non_mempool_tx);
311 chainman.GenerateCoinbaseCommitment(*block, pindexPrev);
317 BlockInfo block_info;
318 block_info.block = block;
319 block_info.hash = block->GetHash();
320 block_info.height = height;
328 bool sent_net_msg =
true;
329 bool requested_hb =
false;
330 bool sent_sendcmpct =
false;
331 bool valid_sendcmpct =
false;
337 std::shared_ptr<CBlock> cblock;
341 size_t index = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, info.size() - 1);
342 cblock = info[index].block;
344 BlockInfo block_info = create_block();
345 cblock = block_info.block;
346 info.push_back(block_info);
350 FuzzedCBlockHeaderAndShortTxIDs cmpctblock(*cblock,
nonce);
353 CBlockHeaderAndShortTxIDs base_cmpctblock = cmpctblock;
354 net_msg = NetMsg::Make(NetMsgType::CMPCTBLOCK, base_cmpctblock);
359 size_t num_erased = 1;
360 size_t num_txs = cblock->vtx.size();
362 for (
size_t i = 0; i < num_txs; ++i) {
369 uint64_t coinbase_shortid = cmpctblock.GetShortID(cblock->vtx[0]->GetWitnessHash());
370 cmpctblock.RemoveCoinbasePrefill();
371 cmpctblock.InsertCoinbaseShortTxID(coinbase_shortid);
377 uint16_t prefill_idx = num_erased == 0 ? i : i - prev_idx - 1;
381 cmpctblock.AddPrefilledTx(std::move(prefilledtx));
384 cmpctblock.EraseShortTxIDs(i - num_erased);
388 assert(cmpctblock.PrefilledTxCount() + cmpctblock.ShortTxIDCount() == num_txs);
395 size_t num_blocks = info.size();
396 if (num_blocks == 0) {
397 sent_net_msg =
false;
403 const BlockInfo& block_info = info[index];
406 std::shared_ptr<CBlock> cblock = block_info.block;
408 for (
size_t i = 0; i < cblock->vtx.size(); i++) {
411 block_txn.
txn.push_back(cblock->vtx[i]);
418 size_t num_blocks = info.size();
419 if (num_blocks == 0) {
420 sent_net_msg =
false;
426 CBlock block = *info[index].block;
428 std::vector<CBlock> headers;
429 headers.emplace_back(block);
439 sent_sendcmpct =
true;
444 BlockInfo block_info = create_block();
445 info.push_back(block_info);
446 sent_net_msg =
false;
459 clock_ctx.set(tip_time);
462 sent_net_msg =
false;
470 connman.FlushSendBuffer(random_node);
471 (void)connman.ReceiveMsgFrom(random_node, std::move(net_msg));
473 bool more_work{
true};
477 more_work = connman.ProcessMessagesOnce(random_node);
478 peerman->SendMessages(random_node);
481 std::vector<CNodeStats> stats;
482 connman.GetNodeStats(stats);
487 if (stat.m_bip152_highbandwidth_to) {
489 CNode* hb_peer = peers[stat.nodeid];
503 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
504 setup->m_node.validation_signals->UnregisterAllValidationInterfaces();
507 const size_t end_index_size{
WITH_LOCK(chainman.GetMutex(),
return chainman.BlockIndex().size())};
508 const uint64_t end_sequence{
WITH_LOCK(mempool.cs,
return mempool.GetSequence())};
510 if (initial_index_size != end_index_size || initial_sequence != end_sequence) {
512 ResetChainmanAndMempool(*
g_setup);
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
const TestingSetup * g_setup
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
Stochastic address manager.
std::vector< CTransactionRef > txn
CBlockHeaderAndShortTxIDs()=default
Dummy for deserialization.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
const CBlock & GenesisBlock() const
Information about a peer.
bool IsInboundConn() const
bool IsOutboundOrBlockRelayConn() const
bool IsManualConn() const
bool IsAddrFetchConn() const
std::atomic_bool fPauseSend
std::atomic_bool fDisconnect
bool m_bip152_highbandwidth_from
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
static const uint32_t CURRENT_VERSION
An input of a transaction.
CScriptWitness scriptWitness
Only serialized through CTransaction.
T ConsumeIntegralInRange(T min, T max)
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, node::Warnings &warnings, Options opts)
static const uint256 ZERO
virtual size_t size()=0
Returns the number of currently pending events.
virtual void flush()=0
Forces the processing of all pending events.
virtual void insert(std::function< void()> func)=0
The callback can either be queued for later/asynchronous/threaded processing, or be executed immediat...
void MakeRandDeterministicDANGEROUS(const uint256 &seed) noexcept
Internal function to set g_determinstic_rng.
FUZZ_TARGET(cmpctblock,.init=initialize_cmpctblock)
void initialize_cmpctblock()
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule)
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.
is used externally by mining IPC clients, so it should only declare simple data definitions.
CSerializedNetMsg Make(std::string msg_type, Args &&... args)
constexpr const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
constexpr const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids".
constexpr const char * BLOCKTXN
Contains a BlockTransactions.
constexpr const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
constexpr const char * TX
The tx message transmits a single transaction.
static constexpr uint64_t CMPCTBLOCKS_VERSION
The compactblocks version we support.
static constexpr TransactionSerParams TX_WITH_WITNESS
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< std::vector< unsigned char > > stack
void ResetIbd()
Reset the ibd cache to its initial state.
Testing setup that configures a complete environment.
Block template creation options.
CScript coinbase_output_script
Script to put in the coinbase transaction.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
This header provides an interface and simple implementation for a task runner.
void FillNode(FuzzedDataProvider &fuzzed_data_provider, ConnmanTestMsg &connman, CNode &node) noexcept
std::unique_ptr< CNode > ConsumeNodeAsUniquePtr(FuzzedDataProvider &fdp, const std::optional< NodeId > &node_id_in=std::nullopt)
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
void FinalizeHeader(CBlockHeader &header, const ChainstateManager &chainman)
COutPoint MineBlock(const NodeContext &node, const node::BlockCreateOptions &assembler_options)
Returns the generated coin.
void SeedRandomStateForTest(SeedRand seedtype)
Seed the global RNG state for testing and log the seed value.
@ ZEROS
Seed with a compile time constant of zeros.
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
static const CScript P2WSH_OP_TRUE
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
static constexpr decltype(CTransaction::version) TRUC_VERSION
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
for(const CTxIn &txin :tx.vin)
FuzzedDataProvider & fuzzed_data_provider