77#include < consensus/merkle.h>
88#include < net.h>
99#include < net_processing.h>
10+ #include < node/warnings.h>
1011#include < random.h>
1112#include < test/fuzz/FuzzedDataProvider.h>
1213#include < test/fuzz/fuzz.h>
1617#include < test/util/net.h>
1718#include < test/util/script.h>
1819#include < test/util/setup_common.h>
20+ #include < test/util/txmempool.h>
1921#include < test/util/validation.h>
2022#include < util/fs.h>
2123#include < validationinterface.h>
@@ -27,14 +29,14 @@ using namespace util::hex_literals;
2729
2830namespace {
2931
32+ TestingSetup* g_setup;
33+
3034// ! Fee each created tx will pay.
3135const CAmount AMOUNT_FEE{1000 };
3236// ! Cached coinbases that each iteration can copy and use.
33- // std::vector<COutPoint> g_mature_coinbase;
37+ std::vector<COutPoint> g_mature_coinbase;
3438// ! Constant value used to create valid headers.
3539uint32_t g_nBits;
36- // ! Cached path to the datadir created during init.
37- fs::path g_cached_path;
3840// ! One for each block the fuzzer generates.
3941struct BlockInfo {
4042 std::shared_ptr<CBlock> block;
@@ -72,50 +74,108 @@ class FuzzedDirectoryWrapper
7274 }
7375};
7476
77+ void ResetChainman (TestingSetup& setup)
78+ {
79+ SetMockTime (setup.m_node .chainman ->GetParams ().GenesisBlock ().Time ());
80+
81+ bilingual_str error{};
82+ setup.m_node .mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest (setup.m_node ), error);
83+ Assert (error.empty ());
84+
85+ setup.m_node .chainman .reset ();
86+ setup.m_make_chainman ();
87+ setup.LoadVerifyActivateChainstate ();
88+
89+ node::BlockAssembler::Options options;
90+ options.coinbase_output_script = P2WSH_OP_TRUE;
91+
92+ g_mature_coinbase.clear ();
93+
94+ for (int i = 0 ; i < 2 * COINBASE_MATURITY; ++i) {
95+ COutPoint prevout{MineBlock (setup.m_node , options)};
96+ if (i < COINBASE_MATURITY) {
97+ g_mature_coinbase.push_back (prevout);
98+ }
99+ }
100+
101+ setup.m_node .validation_signals ->SyncWithValidationInterfaceQueue ();
102+ }
103+
75104} // namespace
76105
77- void initialize_cmpctblock () { }
106+ void initialize_cmpctblock () {
107+ static const auto testing_setup = MakeNoLogFileContext<TestingSetup>(
108+ /* chain_type=*/ ChainType::REGTEST,
109+ {.coins_db_in_memory = true ,
110+ .block_tree_db_in_memory = true ,
111+ .setup_validation_interface = false ,
112+ .setup_validation_interface_no_scheduler = true });
113+
114+ g_setup = testing_setup.get ();
115+ g_nBits = Params ().GenesisBlock ().nBits ;
116+
117+ ResetChainman (*g_setup);
118+ }
78119
79120FUZZ_TARGET (cmpctblock, .init=initialize_cmpctblock)
80121{
81122 SeedRandomStateForTest (SeedRand::ZEROS);
82123 FuzzedDataProvider fuzzed_data_provider (buffer.data (), buffer.size ());
83124
84- std::vector<COutPoint> g_mature_coinbase;
85-
86125 const auto mock_start_time{1610000000 };
126+ SetMockTime (mock_start_time);
87127
88- const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(
89- /* chain_type=*/ ChainType::REGTEST,
90- {.extra_args = {strprintf (" -mocktime=%d" , mock_start_time).c_str ()},
91- .coins_db_in_memory = true ,
92- .block_tree_db_in_memory = true ,
93- .setup_validation_interface = false ,
94- .setup_validation_interface_no_scheduler = true });
128+ // chainman.DisableNextWrite???
95129
96- node::BlockAssembler::Options options;
97- options.coinbase_output_script = P2WSH_OP_TRUE;
130+ // const auto mock_start_time{1610000000};
98131
99- for (int i = 0 ; i < 2 * COINBASE_MATURITY; ++i) {
132+ // node::BlockAssembler::Options options;
133+ // options.coinbase_output_script = P2WSH_OP_TRUE;
134+
135+ /* for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
100136 COutPoint prevout{MineBlock(testing_setup->m_node, options)};
101137 if (i < COINBASE_MATURITY) {
102138 g_mature_coinbase.push_back(prevout);
103139 }
104- }
140+ }*/
105141
106- g_nBits = Params ().GenesisBlock ().nBits ;
142+ // g_nBits = Params().GenesisBlock().nBits;
107143
108- auto setup = testing_setup.get ();
144+ /*
145+ auto setup = g_setup.get();
109146
110147 setup->m_node.validation_signals->RegisterValidationInterface(setup->m_node.peerman.get());
111148 setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
112149 auto& chainman = static_cast<TestChainstateManager&>(*setup->m_node.chainman);
113150 chainman.ResetIbd();
151+ */
152+ auto setup = g_setup;
153+
154+ auto & chainman = static_cast <TestChainstateManager&>(*setup->m_node .chainman );
155+ const auto block_index_size{WITH_LOCK (chainman.GetMutex (), return chainman.BlockIndex ().size ())};
156+ SetMockTime (1610000000 );
157+ chainman.ResetIbd ();
158+
159+ unsigned long initial_mempool_size = setup->m_node .mempool ->size ();
160+
161+ node::Warnings warnings{};
162+ NetGroupManager netgroupman{{}};
163+ AddrMan addrman{netgroupman, /* deterministic=*/ true , /* consistency_check_ratio=*/ 0 };
164+ auto & connman = *static_cast <ConnmanTestMsg*>(setup->m_node .connman .get ());
165+ auto peerman = PeerManager::make (connman, addrman,
166+ /* banman=*/ nullptr , chainman,
167+ *g_setup->m_node .mempool , warnings,
168+ PeerManager::Options{
169+ .reconcile_txs = true ,
170+ .deterministic_rng = true ,
171+ });
172+ connman.SetMsgProc (peerman.get ());
173+
174+ setup->m_node .validation_signals ->RegisterValidationInterface (peerman.get ());
114175
115176 LOCK (NetEventsInterface::g_msgproc_mutex);
116177
117178 std::vector<CNode*> peers;
118- auto & connman = *static_cast <ConnmanTestMsg*>(setup->m_node .connman .get ());
119179 for (int i = 0 ; i < 4 ; ++i) {
120180 peers.push_back (ConsumeNodeAsUniquePtr (fuzzed_data_provider, i).release ());
121181 CNode& p2p_node = *peers.back ();
@@ -390,4 +450,14 @@ FUZZ_TARGET(cmpctblock, .init=initialize_cmpctblock)
390450
391451 setup->m_node .validation_signals ->SyncWithValidationInterfaceQueue ();
392452 setup->m_node .connman ->StopNodes ();
453+ setup->m_node .validation_signals ->UnregisterAllValidationInterfaces ();
454+
455+ if (block_index_size != WITH_LOCK (chainman.GetMutex (), return chainman.BlockIndex ().size ())) {
456+ ResetChainman (*g_setup);
457+ }
458+
459+ // TODO: Combine
460+ if (initial_mempool_size != setup->m_node .mempool ->size ()) {
461+ ResetChainman (*g_setup);
462+ }
393463}
0 commit comments