Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
tx_pool.cpp
Go to the documentation of this file.
1// Copyright (c) 2021-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6#include <node/context.h>
7#include <node/mempool_args.h>
8#include <node/miner.h>
11#include <test/fuzz/fuzz.h>
12#include <test/fuzz/util.h>
14#include <test/util/mining.h>
15#include <test/util/script.h>
17#include <test/util/txmempool.h>
18#include <util/check.h>
19#include <util/rbf.h>
20#include <util/translation.h>
21#include <validation.h>
22#include <validationinterface.h>
23
26using util::ToString;
27
28namespace {
29
30const TestingSetup* g_setup;
31std::vector<COutPoint> g_outpoints_coinbase_init_mature;
32std::vector<COutPoint> g_outpoints_coinbase_init_immature;
33
34struct MockedTxPool : public CTxMemPool {
35 void RollingFeeUpdate() EXCLUSIVE_LOCKS_REQUIRED(!cs)
36 {
37 LOCK(cs);
38 lastRollingFeeUpdate = GetTime();
39 blockSinceLastRollingFeeBump = true;
40 }
41};
42
43void initialize_tx_pool()
44{
45 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
46 g_setup = testing_setup.get();
47
48 for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
49 COutPoint prevout{MineBlock(g_setup->m_node, P2WSH_OP_TRUE)};
50 // Remember the txids to avoid expensive disk access later on
51 auto& outpoints = i < COINBASE_MATURITY ?
52 g_outpoints_coinbase_init_mature :
53 g_outpoints_coinbase_init_immature;
54 outpoints.push_back(prevout);
55 }
56 g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
57}
58
59struct TransactionsDelta final : public CValidationInterface {
60 std::set<CTransactionRef>& m_removed;
61 std::set<CTransactionRef>& m_added;
62
63 explicit TransactionsDelta(std::set<CTransactionRef>& r, std::set<CTransactionRef>& a)
64 : m_removed{r}, m_added{a} {}
65
66 void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t /* mempool_sequence */) override
67 {
68 Assert(m_added.insert(tx.info.m_tx).second);
69 }
70
71 void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t /* mempool_sequence */) override
72 {
73 Assert(m_removed.insert(tx).second);
74 }
75};
76
77void SetMempoolConstraints(ArgsManager& args, FuzzedDataProvider& fuzzed_data_provider)
78{
79 args.ForceSetArg("-limitancestorcount",
80 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 50)));
81 args.ForceSetArg("-limitancestorsize",
82 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202)));
83 args.ForceSetArg("-limitdescendantcount",
84 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 50)));
85 args.ForceSetArg("-limitdescendantsize",
86 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202)));
87 args.ForceSetArg("-maxmempool",
88 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 200)));
89 args.ForceSetArg("-mempoolexpiry",
90 ToString(fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 999)));
91}
92
93void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, Chainstate& chainstate)
94{
95 WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
96 {
97 BlockAssembler::Options options;
98 options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT);
99 options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};
100 auto assembler = BlockAssembler{chainstate, &tx_pool, options};
101 auto block_template = assembler.CreateNewBlock(CScript{} << OP_TRUE);
102 Assert(block_template->block.vtx.size() >= 1);
103 }
104 const auto info_all = tx_pool.infoAll();
105 if (!info_all.empty()) {
106 const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx;
107 WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, MemPoolRemovalReason::BLOCK /* dummy */));
108 assert(tx_pool.size() < info_all.size());
109 WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
110 }
111 g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
112}
113
114void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chainstate)
115{
116 const auto time = ConsumeTime(fuzzed_data_provider,
117 chainstate.m_chain.Tip()->GetMedianTimePast() + 1,
118 std::numeric_limits<decltype(chainstate.m_chain.Tip()->nTime)>::max());
119 SetMockTime(time);
120}
121
122std::unique_ptr<CTxMemPool> MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeContext& node)
123{
124 // Take the default options for tests...
126
127 // ...override specific options for this specific fuzz suite
128 mempool_opts.check_ratio = 1;
129 mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool();
130
131 // ...and construct a CTxMemPool from it
132 bilingual_str error;
133 auto mempool{std::make_unique<CTxMemPool>(std::move(mempool_opts), error)};
134 // ... ignore the error since it might be beneficial to fuzz even when the
135 // mempool size is unreasonably small
136 Assert(error.empty() || error.original.starts_with("-maxmempool must be at least "));
137 return mempool;
138}
139
140void CheckATMPInvariants(const MempoolAcceptResult& res, bool txid_in_mempool, bool wtxid_in_mempool)
141{
142
143 switch (res.m_result_type) {
145 {
146 Assert(txid_in_mempool);
147 Assert(wtxid_in_mempool);
148 Assert(res.m_state.IsValid());
149 Assert(!res.m_state.IsInvalid());
150 Assert(res.m_vsize);
151 Assert(res.m_base_fees);
154 Assert(!res.m_other_wtxid);
155 break;
156 }
158 {
159 // It may be already in the mempool since in ATMP cases we don't set MEMPOOL_ENTRY or DIFFERENT_WITNESS
160 Assert(!res.m_state.IsValid());
161 Assert(res.m_state.IsInvalid());
162
163 const bool is_reconsiderable{res.m_state.GetResult() == TxValidationResult::TX_RECONSIDERABLE};
164 Assert(!res.m_vsize);
165 Assert(!res.m_base_fees);
166 // Fee information is provided if the failure is TX_RECONSIDERABLE.
167 // In other cases, validation may be unable or unwilling to calculate the fees.
168 Assert(res.m_effective_feerate.has_value() == is_reconsiderable);
169 Assert(res.m_wtxids_fee_calculations.has_value() == is_reconsiderable);
170 Assert(!res.m_other_wtxid);
171 break;
172 }
174 {
175 // ATMP never sets this; only set in package settings
176 Assert(false);
177 break;
178 }
180 {
181 // ATMP never sets this; only set in package settings
182 Assert(false);
183 break;
184 }
185 }
186}
187
188FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
189{
190 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
191 const auto& node = g_setup->m_node;
192 auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
193
194 MockTime(fuzzed_data_provider, chainstate);
195
196 // All RBF-spendable outpoints
197 std::set<COutPoint> outpoints_rbf;
198 // All outpoints counting toward the total supply (subset of outpoints_rbf)
199 std::set<COutPoint> outpoints_supply;
200 for (const auto& outpoint : g_outpoints_coinbase_init_mature) {
201 Assert(outpoints_supply.insert(outpoint).second);
202 }
203 outpoints_rbf = outpoints_supply;
204
205 // The sum of the values of all spendable outpoints
206 constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN};
207
208 SetMempoolConstraints(*node.args, fuzzed_data_provider);
209 auto tx_pool_{MakeMempool(fuzzed_data_provider, node)};
210 MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.get());
211
212 chainstate.SetMempool(&tx_pool);
213
214 // Helper to query an amount
215 const CCoinsViewMemPool amount_view{WITH_LOCK(::cs_main, return &chainstate.CoinsTip()), tx_pool};
216 const auto GetAmount = [&](const COutPoint& outpoint) {
217 Coin c;
218 Assert(amount_view.GetCoin(outpoint, c));
219 return c.out.nValue;
220 };
221
222 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
223 {
224 {
225 // Total supply is the mempool fee + all outpoints
226 CAmount supply_now{WITH_LOCK(tx_pool.cs, return tx_pool.GetTotalFee())};
227 for (const auto& op : outpoints_supply) {
228 supply_now += GetAmount(op);
229 }
230 Assert(supply_now == SUPPLY_TOTAL);
231 }
232 Assert(!outpoints_supply.empty());
233
234 // Create transaction to add to the mempool
235 const CTransactionRef tx = [&] {
236 CMutableTransaction tx_mut;
237 tx_mut.version = fuzzed_data_provider.ConsumeBool() ? TRUC_VERSION : CTransaction::CURRENT_VERSION;
238 tx_mut.nLockTime = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<uint32_t>();
239 const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size());
240 const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size() * 2);
241
242 CAmount amount_in{0};
243 for (int i = 0; i < num_in; ++i) {
244 // Pop random outpoint
245 auto pop = outpoints_rbf.begin();
246 std::advance(pop, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, outpoints_rbf.size() - 1));
247 const auto outpoint = *pop;
248 outpoints_rbf.erase(pop);
249 amount_in += GetAmount(outpoint);
250
251 // Create input
252 const auto sequence = ConsumeSequence(fuzzed_data_provider);
253 const auto script_sig = CScript{};
254 const auto script_wit_stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE};
255 CTxIn in;
256 in.prevout = outpoint;
257 in.nSequence = sequence;
258 in.scriptSig = script_sig;
259 in.scriptWitness.stack = script_wit_stack;
260
261 tx_mut.vin.push_back(in);
262 }
263 const auto amount_fee = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-1000, amount_in);
264 const auto amount_out = (amount_in - amount_fee) / num_out;
265 for (int i = 0; i < num_out; ++i) {
266 tx_mut.vout.emplace_back(amount_out, P2WSH_OP_TRUE);
267 }
268 auto tx = MakeTransactionRef(tx_mut);
269 // Restore previously removed outpoints
270 for (const auto& in : tx->vin) {
271 Assert(outpoints_rbf.insert(in.prevout).second);
272 }
273 return tx;
274 }();
275
276 if (fuzzed_data_provider.ConsumeBool()) {
277 MockTime(fuzzed_data_provider, chainstate);
278 }
279 if (fuzzed_data_provider.ConsumeBool()) {
280 tx_pool.RollingFeeUpdate();
281 }
282 if (fuzzed_data_provider.ConsumeBool()) {
283 const auto& txid = fuzzed_data_provider.ConsumeBool() ?
284 tx->GetHash() :
285 PickValue(fuzzed_data_provider, outpoints_rbf).hash;
286 const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN);
287 tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
288 }
289
290 // Remember all removed and added transactions
291 std::set<CTransactionRef> removed;
292 std::set<CTransactionRef> added;
293 auto txr = std::make_shared<TransactionsDelta>(removed, added);
294 node.validation_signals->RegisterSharedValidationInterface(txr);
295 const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
296
297 // Make sure ProcessNewPackage on one transaction works.
298 // The result is not guaranteed to be the same as what is returned by ATMP.
299 const auto result_package = WITH_LOCK(::cs_main,
300 return ProcessNewPackage(chainstate, tx_pool, {tx}, true, /*client_maxfeerate=*/{}));
301 // If something went wrong due to a package-specific policy, it might not return a
302 // validation result for the transaction.
303 if (result_package.m_state.GetResult() != PackageValidationResult::PCKG_POLICY) {
304 auto it = result_package.m_tx_results.find(tx->GetWitnessHash());
305 Assert(it != result_package.m_tx_results.end());
306 Assert(it->second.m_result_type == MempoolAcceptResult::ResultType::VALID ||
307 it->second.m_result_type == MempoolAcceptResult::ResultType::INVALID);
308 }
309
310 const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
311 const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
312 node.validation_signals->SyncWithValidationInterfaceQueue();
313 node.validation_signals->UnregisterSharedValidationInterface(txr);
314
315 bool txid_in_mempool = tx_pool.exists(GenTxid::Txid(tx->GetHash()));
316 bool wtxid_in_mempool = tx_pool.exists(GenTxid::Wtxid(tx->GetWitnessHash()));
317 CheckATMPInvariants(res, txid_in_mempool, wtxid_in_mempool);
318
319 Assert(accepted != added.empty());
320 if (accepted) {
321 Assert(added.size() == 1); // For now, no package acceptance
322 Assert(tx == *added.begin());
324 } else {
325 // Do not consider rejected transaction removed
326 removed.erase(tx);
327 }
328
329 // Helper to insert spent and created outpoints of a tx into collections
330 using Sets = std::vector<std::reference_wrapper<std::set<COutPoint>>>;
331 const auto insert_tx = [](Sets created_by_tx, Sets consumed_by_tx, const auto& tx) {
332 for (size_t i{0}; i < tx.vout.size(); ++i) {
333 for (auto& set : created_by_tx) {
334 Assert(set.get().emplace(tx.GetHash(), i).second);
335 }
336 }
337 for (const auto& in : tx.vin) {
338 for (auto& set : consumed_by_tx) {
339 Assert(set.get().insert(in.prevout).second);
340 }
341 }
342 };
343 // Add created outpoints, remove spent outpoints
344 {
345 // Outpoints that no longer exist at all
346 std::set<COutPoint> consumed_erased;
347 // Outpoints that no longer count toward the total supply
348 std::set<COutPoint> consumed_supply;
349 for (const auto& removed_tx : removed) {
350 insert_tx(/*created_by_tx=*/{consumed_erased}, /*consumed_by_tx=*/{outpoints_supply}, /*tx=*/*removed_tx);
351 }
352 for (const auto& added_tx : added) {
353 insert_tx(/*created_by_tx=*/{outpoints_supply, outpoints_rbf}, /*consumed_by_tx=*/{consumed_supply}, /*tx=*/*added_tx);
354 }
355 for (const auto& p : consumed_erased) {
356 Assert(outpoints_supply.erase(p) == 1);
357 Assert(outpoints_rbf.erase(p) == 1);
358 }
359 for (const auto& p : consumed_supply) {
360 Assert(outpoints_supply.erase(p) == 1);
361 }
362 }
363 }
364 Finish(fuzzed_data_provider, tx_pool, chainstate);
365}
366
367FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
368{
369 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
370 const auto& node = g_setup->m_node;
371 auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
372
373 MockTime(fuzzed_data_provider, chainstate);
374
375 std::vector<Txid> txids;
376 txids.reserve(g_outpoints_coinbase_init_mature.size());
377 for (const auto& outpoint : g_outpoints_coinbase_init_mature) {
378 txids.push_back(outpoint.hash);
379 }
380 for (int i{0}; i <= 3; ++i) {
381 // Add some immature and non-existent outpoints
382 txids.push_back(g_outpoints_coinbase_init_immature.at(i).hash);
383 txids.push_back(Txid::FromUint256(ConsumeUInt256(fuzzed_data_provider)));
384 }
385
386 SetMempoolConstraints(*node.args, fuzzed_data_provider);
387 auto tx_pool_{MakeMempool(fuzzed_data_provider, node)};
388 MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(tx_pool_.get());
389
390 chainstate.SetMempool(&tx_pool);
391
392 LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
393 {
394 const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids);
395
396 if (fuzzed_data_provider.ConsumeBool()) {
397 MockTime(fuzzed_data_provider, chainstate);
398 }
399 if (fuzzed_data_provider.ConsumeBool()) {
400 tx_pool.RollingFeeUpdate();
401 }
402 if (fuzzed_data_provider.ConsumeBool()) {
403 const auto txid = fuzzed_data_provider.ConsumeBool() ?
404 mut_tx.GetHash() :
405 PickValue(fuzzed_data_provider, txids);
406 const auto delta = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-50 * COIN, +50 * COIN);
407 tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
408 }
409
410 const auto tx = MakeTransactionRef(mut_tx);
411 const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
412 const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
413 const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
414 if (accepted) {
415 txids.push_back(tx->GetHash());
417 }
418 }
419 Finish(fuzzed_data_provider, tx_pool, chainstate);
420}
421} // namespace
int64_t CAmount
Amount in satoshis (Can be negative)
Definition amount.h:12
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition amount.h:15
ArgsManager & args
Definition bitcoind.cpp:270
#define Assert(val)
Identity function.
Definition check.h:77
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition args.cpp:545
uint32_t nTime
Definition chain.h:189
int64_t GetMedianTimePast() const
Definition chain.h:278
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition chain.h:433
int Height() const
Return the maximal height in the chain.
Definition chain.h:462
CCoinsView that brings transactions from a mempool into view.
Definition txmempool.h:835
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition feerate.h:33
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition transaction.h:29
Serialized script, used inside transaction inputs and outputs.
Definition script.h:414
static const uint32_t CURRENT_VERSION
An input of a transaction.
Definition transaction.h:67
uint32_t nSequence
Definition transaction.h:71
CScript scriptSig
Definition transaction.h:70
CScriptWitness scriptWitness
Only serialized through CTransaction.
Definition transaction.h:72
COutPoint prevout
Definition transaction.h:69
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:304
CAmount nValue
Implement this to subscribe to events generated in validation and mempool.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition validation.h:513
CChain m_chain
The current chain of blockheaders we consult and build on.
Definition validation.h:593
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Definition validation.h:619
A UTXO entry.
Definition coins.h:33
CTxOut out
unspent transaction output
Definition coins.h:36
T ConsumeIntegralInRange(T min, T max)
static GenTxid Wtxid(const uint256 &hash)
static GenTxid Txid(const uint256 &hash)
bool IsValid() const
Definition validation.h:122
Result GetResult() const
Definition validation.h:125
bool IsInvalid() const
Definition validation.h:123
Generate a new block, without valid proof-of-work.
Definition miner.h:140
std::unique_ptr< CBlockTemplate > CreateNewBlock(const CScript &scriptPubKeyIn)
Construct a new block template with coinbase to scriptPubKeyIn.
Definition miner.cpp:109
static transaction_identifier FromUint256(const uint256 &id)
@ TX_RECONSIDERABLE
fails some policy, but might be acceptable if submitted in a (different) package
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
Definition consensus.h:15
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule)
Definition consensus.h:19
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:8
#define FUZZ_TARGET(...)
Definition fuzz.h:35
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Definition fuzz.h:22
uint64_t sequence
static void pool cs
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
@ BLOCK
Removed for block.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition string.h:156
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
@ OP_TRUE
Definition script.h:83
std::unique_ptr< T > MakeNoLogFileContext(const ChainType chain_type=ChainType::REGTEST, TestOpts opts={})
Make a test setup that has disk access to the debug.log file disabled.
node::NodeContext m_node
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< CTxIn > vin
std::vector< std::vector< unsigned char > > stack
Definition script.h:577
Validation result for a transaction evaluated by MemPoolAccept (single or package).
Definition validation.h:128
const std::optional< int64_t > m_vsize
Virtual size as used by the mempool, calculated using serialized size and sigops.
Definition validation.h:145
const ResultType m_result_type
Result type.
Definition validation.h:137
const std::optional< CAmount > m_base_fees
Raw base fees in satoshis.
Definition validation.h:147
const TxValidationState m_state
Contains information about why the transaction failed.
Definition validation.h:140
const std::optional< CFeeRate > m_effective_feerate
The feerate at which this transaction was considered.
Definition validation.h:153
const std::optional< uint256 > m_other_wtxid
The wtxid of the transaction in the mempool which has the same txid but different witness.
Definition validation.h:162
const std::optional< std::vector< Wtxid > > m_wtxids_fee_calculations
Contains the wtxids of the transactions used for fee-related checks.
Definition validation.h:159
Testing setup that configures a complete environment.
const CTransactionRef m_tx
Bilingual messages:
Definition translation.h:18
bool empty() const
Definition translation.h:29
std::string original
Definition translation.h:19
Options struct containing options for constructing a CTxMemPool.
NodeContext struct containing references to chain state and connection state.
Definition context.h:55
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
Definition context.h:85
#define LOCK(cs)
Definition sync.h:257
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition sync.h:301
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition util.cpp:155
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition util.cpp:34
CMutableTransaction ConsumeTransaction(FuzzedDataProvider &fuzzed_data_provider, const std::optional< std::vector< Txid > > &prevout_txids, const int max_num_in, const int max_num_out) noexcept
Definition util.cpp:42
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
Definition util.cpp:29
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
Definition util.h:47
uint256 ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition util.h:169
COutPoint MineBlock(const NodeContext &node, const CScript &coinbase_scriptPubKey)
Returns the generated coin.
Definition mining.cpp:63
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
Definition script.h:11
static const CScript P2WSH_OP_TRUE
Definition script.h:12
void CheckMempoolTRUCInvariants(const CTxMemPool &tx_pool)
For every transaction in tx_pool, check TRUC invariants:
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
Definition txmempool.cpp:20
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition time.cpp:44
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition time.cpp:32
static constexpr decltype(CTransaction::version) TRUC_VERSION
Definition truc_policy.h:20
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept, const std::optional< CFeeRate > &client_maxfeerate)
Validate (and maybe submit) a package to the mempool.
MempoolAcceptResult AcceptToMemoryPool(Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept)
Try to add a transaction to the mempool.
assert(!tx.IsCoinBase())