31 std::vector<COutPoint> g_outpoints_coinbase_init_mature;
32 std::vector<COutPoint> g_outpoints_coinbase_init_immature;
38 lastRollingFeeUpdate =
GetTime();
39 blockSinceLastRollingFeeBump =
true;
43 void initialize_tx_pool()
45 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
46 g_setup = testing_setup.get();
52 g_outpoints_coinbase_init_mature :
53 g_outpoints_coinbase_init_immature;
54 outpoints.push_back(prevout);
56 g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
60 std::set<CTransactionRef>& m_removed;
61 std::set<CTransactionRef>& m_added;
63 explicit TransactionsDelta(std::set<CTransactionRef>& r, std::set<CTransactionRef>& a)
64 : m_removed{r}, m_added{a} {}
73 Assert(m_removed.insert(tx).second);
97 BlockAssembler::Options options;
101 auto block_template = assembler.CreateNewBlock(
CScript{} <<
OP_TRUE);
102 Assert(block_template->block.vtx.size() >= 1);
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;
108 assert(tx_pool.size() < info_all.size());
111 g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
116 const auto time =
ConsumeTime(fuzzed_data_provider,
118 std::numeric_limits<decltype(chainstate.
m_chain.
Tip()->
nTime)>::max());
129 mempool_opts.require_standard = fuzzed_data_provider.
ConsumeBool();
133 auto mempool{std::make_unique<CTxMemPool>(std::move(mempool_opts), error)};
140 void CheckATMPInvariants(
const MempoolAcceptResult& res,
bool txid_in_mempool,
bool wtxid_in_mempool)
191 const auto&
node = g_setup->m_node;
194 MockTime(fuzzed_data_provider, chainstate);
197 std::set<COutPoint> 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);
203 outpoints_rbf = outpoints_supply;
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());
212 chainstate.SetMempool(&tx_pool);
216 const auto GetAmount = [&](
const COutPoint& outpoint) {
218 Assert(amount_view.GetCoin(outpoint, c));
227 for (
const auto& op : outpoints_supply) {
228 supply_now += GetAmount(op);
230 Assert(supply_now == SUPPLY_TOTAL);
232 Assert(!outpoints_supply.empty());
243 for (
int i = 0; i < num_in; ++i) {
245 auto pop = outpoints_rbf.begin();
247 const auto outpoint = *pop;
248 outpoints_rbf.erase(pop);
249 amount_in += GetAmount(outpoint);
253 const auto script_sig =
CScript{};
261 tx_mut.
vin.push_back(in);
264 const auto amount_out = (amount_in - amount_fee) / num_out;
265 for (
int i = 0; i < num_out; ++i) {
270 for (
const auto& in : tx->vin) {
277 MockTime(fuzzed_data_provider, chainstate);
280 tx_pool.RollingFeeUpdate();
283 const auto& txid = fuzzed_data_provider.
ConsumeBool() ?
285 PickValue(fuzzed_data_provider, outpoints_rbf).hash;
287 tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
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();
304 auto it = result_package.m_tx_results.find(tx->GetWitnessHash());
305 Assert(it != result_package.m_tx_results.end());
312 node.validation_signals->SyncWithValidationInterfaceQueue();
313 node.validation_signals->UnregisterSharedValidationInterface(txr);
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);
319 Assert(accepted != added.empty());
321 Assert(added.size() == 1);
322 Assert(tx == *added.begin());
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);
337 for (
const auto& in : tx.vin) {
338 for (
auto&
set : consumed_by_tx) {
346 std::set<COutPoint> consumed_erased;
348 std::set<COutPoint> consumed_supply;
349 for (
const auto& removed_tx : removed) {
350 insert_tx({consumed_erased}, {outpoints_supply}, *removed_tx);
352 for (
const auto& added_tx : added) {
353 insert_tx({outpoints_supply, outpoints_rbf}, {consumed_supply}, *added_tx);
355 for (
const auto& p : consumed_erased) {
356 Assert(outpoints_supply.erase(p) == 1);
357 Assert(outpoints_rbf.erase(p) == 1);
359 for (
const auto& p : consumed_supply) {
360 Assert(outpoints_supply.erase(p) == 1);
364 Finish(fuzzed_data_provider, tx_pool, chainstate);
370 const auto&
node = g_setup->m_node;
373 MockTime(fuzzed_data_provider, chainstate);
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);
380 for (
int i{0}; i <= 3; ++i) {
382 txids.push_back(g_outpoints_coinbase_init_immature.at(i).hash);
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());
390 chainstate.SetMempool(&tx_pool);
397 MockTime(fuzzed_data_provider, chainstate);
400 tx_pool.RollingFeeUpdate();
403 const auto txid = fuzzed_data_provider.
ConsumeBool() ?
407 tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
411 const bool bypass_limits = fuzzed_data_provider.
ConsumeBool();
415 txids.push_back(tx->GetHash());
419 Finish(fuzzed_data_provider, tx_pool, chainstate);
std::shared_ptr< const CTransaction > CTransactionRef
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
const std::optional< CFeeRate > m_effective_feerate
The feerate at which this transaction was considered.
static GenTxid Wtxid(const uint256 &hash)
Generate a new block, without valid proof-of-work.
const std::optional< std::vector< Wtxid > > m_wtxids_fee_calculations
Contains the wtxids of the transactions used for fee-related checks.
The package itself is invalid (e.g. too many transactions).
Valid, transaction was already in the mempool.
static const CScript P2WSH_OP_TRUE
CScriptWitness scriptWitness
Only serialized through CTransaction.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int Height() const
Return the maximal height in the chain.
CTxOut out
unspent transaction output
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
std::vector< std::vector< unsigned char > > stack
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
const std::optional< int64_t > m_vsize
Virtual size as used by the mempool, calculated using serialized size and sigops. ...
const TxValidationState m_state
Contains information about why the transaction failed.
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
const std::optional< CAmount > m_base_fees
Raw base fees in satoshis.
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.
const ResultType m_result_type
Result type.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
CChain m_chain
The current chain of blockheaders we consult and build on.
Implement this to subscribe to events generated in validation and mempool.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
int64_t CAmount
Amount in satoshis (Can be negative)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
static const uint32_t CURRENT_VERSION
NodeContext struct containing references to chain state and connection state.
static decltype(CTransaction::version) constexpr TRUC_VERSION
Chainstate stores and provides an API to update our local knowledge of the current best chain...
An input of a transaction.
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
fails some policy, but might be acceptable if submitted in a (different) package
Validation result for a transaction evaluated by MemPoolAccept (single or package).
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
int64_t GetMedianTimePast() const
const std::optional< uint256 > m_other_wtxid
The wtxid of the transaction in the mempool which has the same txid but different witness...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
COutPoint MineBlock(const NodeContext &node, const CScript &coinbase_scriptPubKey)
Returns the generated coin.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void CheckMempoolTRUCInvariants(const CTxMemPool &tx_pool)
For every transaction in tx_pool, check TRUC invariants:
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
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
Serialized script, used inside transaction inputs and outputs.
static transaction_identifier FromUint256(const uint256 &id)
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
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.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
const CTransactionRef m_tx
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
A mutable version of CTransaction.
Options struct containing options for constructing a CTxMemPool.
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
T ConsumeIntegralInRange(T min, T max)
uint256 ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept
int64_t GetTime()
DEPRECATED, see GetTime.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
CCoinsView that brings transactions from a mempool into view.
Testing setup that configures a complete environment.
static GenTxid Txid(const uint256 &hash)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define Assert(val)
Identity function.
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
static constexpr CAmount COIN
The amount of satoshis in one BTC.