31std::vector<COutPoint> g_outpoints_coinbase_init_mature;
32std::vector<COutPoint> g_outpoints_coinbase_init_immature;
38 lastRollingFeeUpdate =
GetTime();
39 blockSinceLastRollingFeeBump =
true;
43void initialize_tx_pool()
46 g_setup = testing_setup.get();
52 g_outpoints_coinbase_init_mature :
53 g_outpoints_coinbase_init_immature;
54 outpoints.push_back(prevout);
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;
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());
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)};
140void CheckATMPInvariants(
const MempoolAcceptResult& res,
bool txid_in_mempool,
bool wtxid_in_mempool)
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);
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);
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
#define Assert(val)
Identity function.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
int64_t GetMedianTimePast() const
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
int Height() const
Return the maximal height in the chain.
CCoinsView that brings transactions from a mempool into view.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
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.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
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.
CChain m_chain
The current chain of blockheaders we consult and build on.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
CTxOut out
unspent transaction output
T ConsumeIntegralInRange(T min, T max)
static GenTxid Wtxid(const uint256 &hash)
static GenTxid Txid(const uint256 &hash)
Generate a new block, without valid proof-of-work.
std::unique_ptr< CBlockTemplate > CreateNewBlock(const CScript &scriptPubKeyIn)
Construct a new block template with coinbase to scriptPubKeyIn.
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)
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.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
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.
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
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.
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< std::vector< unsigned char > > stack
Validation result for a transaction evaluated by MemPoolAccept (single or package).
const std::optional< int64_t > m_vsize
Virtual size as used by the mempool, calculated using serialized size and sigops.
const ResultType m_result_type
Result type.
const std::optional< CAmount > m_base_fees
Raw base fees in satoshis.
const TxValidationState m_state
Contains information about why the transaction failed.
const std::optional< CFeeRate > m_effective_feerate
The feerate at which this transaction was considered.
const std::optional< uint256 > m_other_wtxid
The wtxid of the transaction in the mempool which has the same txid but different witness.
const std::optional< std::vector< Wtxid > > m_wtxids_fee_calculations
Contains the wtxids of the transactions used for fee-related checks.
Testing setup that configures a complete environment.
const CTransactionRef m_tx
Options struct containing options for constructing a CTxMemPool.
NodeContext struct containing references to chain state and connection state.
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
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
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
uint256 ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept
COutPoint MineBlock(const NodeContext &node, const CScript &coinbase_scriptPubKey)
Returns the generated coin.
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
static const CScript P2WSH_OP_TRUE
void CheckMempoolTRUCInvariants(const CTxMemPool &tx_pool)
For every transaction in tx_pool, check TRUC invariants:
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
static constexpr decltype(CTransaction::version) TRUC_VERSION
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.