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);
170 auto& mempool = *
setup->m_node.mempool;
173 chainman.DisableNextWrite();
174 const size_t initial_index_size{
WITH_LOCK(chainman.GetMutex(),
return chainman.BlockIndex().size())};
180 mempool, *
setup->m_node.warnings,
182 .deterministic_rng = true,
184 connman.SetMsgProc(peerman.get());
186 setup->m_node.validation_signals->RegisterValidationInterface(peerman.get());
187 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
191 std::vector<CNode*> peers;
192 for (
int i = 0; i < 4; ++i) {
194 CNode& p2p_node = *peers.back();
196 connman.AddTestNode(p2p_node);
200 std::vector<BlockInfo> info;
203 std::vector<std::pair<COutPoint, CAmount>> mature_coinbase = g_mature_coinbase;
205 const uint64_t initial_sequence{
WITH_LOCK(mempool.cs,
return mempool.GetSequence())};
215 unsigned long mempool_size = mempool.size();
220 amount_in = tx->vout[0].nValue;
223 auto info_it = info.begin();
225 auto tx_it = info_it->block->vtx.begin();
227 outpoint =
COutPoint(tx_it->get()->GetHash(), 0);
228 amount_in = tx_it->get()->vout[0].nValue;
230 auto coinbase_it = mature_coinbase.begin();
232 outpoint = coinbase_it->first;
233 amount_in = coinbase_it->second;
237 const auto script_sig =
CScript{};
245 tx_mut.
vin.push_back(in);
247 const CAmount amount_out = amount_in - AMOUNT_FEE;
254 auto create_block = [&]() {
260 prev = chainman.ActiveChain().Tip()->GetBlockHash();
261 height = chainman.ActiveChain().Height() + 1;
264 prev = info[index].hash;
265 height = info[index].height + 1;
268 const auto new_time =
WITH_LOCK(
::cs_main,
return chainman.ActiveChain().Tip()->GetMedianTimePast() + 1);
273 header.
nBits = g_nBits;
274 header.
nTime = new_time;
277 std::shared_ptr<CBlock> block = std::make_shared<CBlock>();
281 coinbase_tx.
vin.resize(1);
282 coinbase_tx.
vin[0].prevout.SetNull();
284 coinbase_tx.
vout.resize(1);
289 const auto mempool_size = mempool.size();
296 for (
size_t i = random_idx; i < random_idx + num_txns; ++i) {
297 CTransactionRef mempool_tx = mempool.txns_randomized[i % mempool_size].second->GetSharedTx();
298 block->vtx.push_back(mempool_tx);
305 for (
size_t i = 0; i < new_txns; ++i) {
307 block->vtx.push_back(non_mempool_tx);
312 chainman.GenerateCoinbaseCommitment(*block, pindexPrev);
318 BlockInfo block_info;
319 block_info.block = block;
320 block_info.hash = block->GetHash();
321 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;
439 sent_sendcmpct =
true;
444 BlockInfo block_info = create_block();
445 info.push_back(block_info);
446 sent_net_msg =
false;
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.
Helper to initialize the global NodeClock, let a duration elapse, and reset it after use in a test.
Helper to initialize the global MockableSteadyClock, let a duration elapse, and reset it after use in...
T ConsumeIntegralInRange(T min, T max)
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
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()
for(const auto &cache :caches)
LIMITED_WHILE(provider.remaining_bytes(), 10000)
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.
std::thread thread
Thread variable should be after other struct members so the thread does not start until the other mem...
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.
SeedRandomStateForTest(SeedRand::ZEROS)
void FillNode(FuzzedDataProvider &fuzzed_data_provider, ConnmanTestMsg &connman, CNode &node) noexcept
std::unique_ptr< CNode > ConsumeNodeAsUniquePtr(FuzzedDataProvider &fdp, FakeSteadyClock &clock, 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.
@ 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
FuzzedDataProvider & fuzzed_data_provider