33// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
55#include < consensus/validation.h>
6+ #include < miner.h>
67#include < test/fuzz/FuzzedDataProvider.h>
78#include < test/fuzz/fuzz.h>
89#include < test/fuzz/util.h>
@@ -77,13 +78,44 @@ void SetMempoolConstraints(ArgsManager& args, FuzzedDataProvider& fuzzed_data_pr
7778 ToString (fuzzed_data_provider.ConsumeIntegralInRange <unsigned >(0 , 999 )));
7879}
7980
81+ void Finish (FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CChainState& chainstate)
82+ {
83+ WITH_LOCK (::cs_main, tx_pool.check (chainstate));
84+ {
85+ BlockAssembler::Options options;
86+ options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange (0U , MAX_BLOCK_WEIGHT);
87+ options.blockMinFeeRate = CFeeRate{ConsumeMoney (fuzzed_data_provider)};
88+ auto assembler = BlockAssembler{chainstate, *static_cast <CTxMemPool*>(&tx_pool), ::Params (), options};
89+ auto block_template = assembler.CreateNewBlock (CScript{} << OP_TRUE);
90+ Assert (block_template->block .vtx .size () >= 1 );
91+ }
92+ const auto info_all = tx_pool.infoAll ();
93+ if (!info_all.empty ()) {
94+ const auto & tx_to_remove = *PickValue (fuzzed_data_provider, info_all).tx ;
95+ WITH_LOCK (tx_pool.cs , tx_pool.removeRecursive (tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK));
96+ std::vector<uint256> all_txids;
97+ tx_pool.queryHashes (all_txids);
98+ assert (all_txids.size () < info_all.size ());
99+ WITH_LOCK (::cs_main, tx_pool.check (chainstate));
100+ }
101+ SyncWithValidationInterfaceQueue ();
102+ }
103+
104+ void MockTime (FuzzedDataProvider& fuzzed_data_provider, const CChainState& chainstate)
105+ {
106+ const auto time = ConsumeTime (fuzzed_data_provider,
107+ chainstate.m_chain .Tip ()->GetMedianTimePast () + 1 ,
108+ std::numeric_limits<decltype (chainstate.m_chain .Tip ()->nTime )>::max ());
109+ SetMockTime (time);
110+ }
111+
80112FUZZ_TARGET_INIT (tx_pool_standard, initialize_tx_pool)
81113{
82114 FuzzedDataProvider fuzzed_data_provider (buffer.data (), buffer.size ());
83115 const auto & node = g_setup->m_node ;
84116 auto & chainstate = node.chainman ->ActiveChainstate ();
85117
86- SetMockTime ( ConsumeTime ( fuzzed_data_provider) );
118+ MockTime ( fuzzed_data_provider, chainstate );
87119 SetMempoolConstraints (*node.args , fuzzed_data_provider);
88120
89121 // All RBF-spendable outpoints
@@ -163,7 +195,7 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
163195 }();
164196
165197 if (fuzzed_data_provider.ConsumeBool ()) {
166- SetMockTime ( ConsumeTime ( fuzzed_data_provider) );
198+ MockTime ( fuzzed_data_provider, chainstate );
167199 }
168200 if (fuzzed_data_provider.ConsumeBool ()) {
169201 SetMempoolConstraints (*node.args , fuzzed_data_provider);
@@ -237,23 +269,17 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
237269 }
238270 }
239271 }
240- WITH_LOCK (::cs_main, tx_pool.check (chainstate));
241- const auto info_all = tx_pool.infoAll ();
242- if (!info_all.empty ()) {
243- const auto & tx_to_remove = *PickValue (fuzzed_data_provider, info_all).tx ;
244- WITH_LOCK (tx_pool.cs , tx_pool.removeRecursive (tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK));
245- std::vector<uint256> all_txids;
246- tx_pool.queryHashes (all_txids);
247- assert (all_txids.size () < info_all.size ());
248- WITH_LOCK (::cs_main, tx_pool.check (chainstate));
249- }
250- SyncWithValidationInterfaceQueue ();
272+ Finish (fuzzed_data_provider, tx_pool, chainstate);
251273}
252274
253275FUZZ_TARGET_INIT (tx_pool, initialize_tx_pool)
254276{
255277 FuzzedDataProvider fuzzed_data_provider (buffer.data (), buffer.size ());
256278 const auto & node = g_setup->m_node ;
279+ auto & chainstate = node.chainman ->ActiveChainstate ();
280+
281+ MockTime (fuzzed_data_provider, chainstate);
282+ SetMempoolConstraints (*node.args , fuzzed_data_provider);
257283
258284 std::vector<uint256> txids;
259285 for (const auto & outpoint : g_outpoints_coinbase_init_mature) {
@@ -265,11 +291,29 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
265291 txids.push_back (ConsumeUInt256 (fuzzed_data_provider));
266292 }
267293
268- CTxMemPool tx_pool{/* estimator */ nullptr , /* check_ratio */ 1 };
294+ CTxMemPool tx_pool_{/* estimator */ nullptr , /* check_ratio */ 1 };
295+ MockedTxPool& tx_pool = *static_cast <MockedTxPool*>(&tx_pool_);
269296
270297 while (fuzzed_data_provider.ConsumeBool ()) {
271298 const auto mut_tx = ConsumeTransaction (fuzzed_data_provider, txids);
272299
300+ if (fuzzed_data_provider.ConsumeBool ()) {
301+ MockTime (fuzzed_data_provider, chainstate);
302+ }
303+ if (fuzzed_data_provider.ConsumeBool ()) {
304+ SetMempoolConstraints (*node.args , fuzzed_data_provider);
305+ }
306+ if (fuzzed_data_provider.ConsumeBool ()) {
307+ tx_pool.RollingFeeUpdate ();
308+ }
309+ if (fuzzed_data_provider.ConsumeBool ()) {
310+ const auto & txid = fuzzed_data_provider.ConsumeBool () ?
311+ mut_tx.GetHash () :
312+ PickValue (fuzzed_data_provider, txids);
313+ const auto delta = fuzzed_data_provider.ConsumeIntegralInRange <CAmount>(-50 * COIN, +50 * COIN);
314+ tx_pool.PrioritiseTransaction (txid, delta);
315+ }
316+
273317 const auto tx = MakeTransactionRef (mut_tx);
274318 const bool bypass_limits = fuzzed_data_provider.ConsumeBool ();
275319 ::fRequireStandard = fuzzed_data_provider.ConsumeBool ();
@@ -278,8 +322,7 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
278322 if (accepted) {
279323 txids.push_back (tx->GetHash ());
280324 }
281-
282- SyncWithValidationInterfaceQueue ();
283325 }
326+ Finish (fuzzed_data_provider, tx_pool, chainstate);
284327}
285328} // namespace
0 commit comments