Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
501/*client_maxfeerate=*/ {}, // checked by caller502};503}505/** Parameters for test package mempool validation through testmempoolaccept. */506static ATMPArgs PackageTestAccept(int64_t accept_time,507std::vector<COutPoint>& coins_to_uncache) {508return ATMPArgs{/*accept_time=*/ accept_time,509/*bypass_limits=*/ false,510/*coins_to_uncache=*/ coins_to_uncache,511/*test_accept=*/ true,512/*allow_replacement=*/ false,513/*allow_sibling_eviction=*/ false,514/*package_submission=*/ false, // not submitting to mempool515/*package_feerates=*/ false,516/*client_maxfeerate=*/ {}, // checked by caller517};518}520/** Parameters for child-with-parents package validation. */521static ATMPArgs PackageChildWithParents(int64_t accept_time,522std::vector<COutPoint>& coins_to_uncache, const std::optional<CFeeRate>& client_maxfeerate) {523return ATMPArgs{/*accept_time=*/ accept_time,524/*bypass_limits=*/ false,525/*coins_to_uncache=*/ coins_to_uncache,526/*test_accept=*/ false,527/*allow_replacement=*/ true,528/*allow_sibling_eviction=*/ false,529/*package_submission=*/ true,530/*package_feerates=*/ true,531/*client_maxfeerate=*/ client_maxfeerate,532};533}535/** Parameters for a single transaction within a package. */536static ATMPArgs SingleInPackageAccept(const ATMPArgs& package_args) {537return ATMPArgs{/*accept_time=*/ package_args.m_accept_time,538/*bypass_limits=*/ false,539/*coins_to_uncache=*/ package_args.m_coins_to_uncache,540/*test_accept=*/ package_args.m_test_accept,541/*allow_replacement=*/ true,542/*allow_sibling_eviction=*/ true,543/*package_submission=*/ true, // trim at the end of AcceptPackage()544/*package_feerates=*/ false, // only 1 transaction545/*client_maxfeerate=*/ package_args.m_client_maxfeerate,546};547}549private:550// Private ctor to avoid exposing details to clients and allowing the possibility of551// mixing up the order of the arguments. Use static functions above instead.552ATMPArgs(int64_t accept_time,553bool bypass_limits,554std::vector<COutPoint>& coins_to_uncache,555bool test_accept,556bool allow_replacement,557bool allow_sibling_eviction,558bool package_submission,559bool package_feerates,560std::optional<CFeeRate> client_maxfeerate)561: m_accept_time{accept_time},562m_bypass_limits{bypass_limits},563m_coins_to_uncache{coins_to_uncache},564m_test_accept{test_accept},565m_allow_replacement{allow_replacement},566m_allow_sibling_eviction{allow_sibling_eviction},567m_package_submission{package_submission},568m_package_feerates{package_feerates},569m_client_maxfeerate{client_maxfeerate}570{571// If we are using package feerates, we must be doing package submission.572// It also means sibling eviction is not permitted.573if (m_package_feerates) {574Assume(m_package_submission);575Assume(!m_allow_sibling_eviction);576}577if (m_allow_sibling_eviction) Assume(m_allow_replacement);578}579};581/** Clean up all non-chainstate coins from m_view and m_viewmempool. */582void CleanupTemporaryCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);584// Single transaction acceptance585MempoolAcceptResult AcceptSingleTransactionAndCleanup(const CTransactionRef& ptx, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {586LOCK(m_pool.cs);587MempoolAcceptResult result = AcceptSingleTransactionInternal(ptx, args);588ClearSubPackageState();589return result;590}591MempoolAcceptResult AcceptSingleTransactionInternal(const CTransactionRef& ptx, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);593/**594* Multiple transaction acceptance. Transactions may or may not be interdependent, but must not595* conflict with each other, and the transactions cannot already be in the mempool. Parents must596* come before children if any dependencies exist.597*/598PackageMempoolAcceptResult AcceptMultipleTransactionsAndCleanup(const std::vector<CTransactionRef>& txns, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {599LOCK(m_pool.cs);600PackageMempoolAcceptResult result = AcceptMultipleTransactionsInternal(txns, args);601ClearSubPackageState();602return result;603}604PackageMempoolAcceptResult AcceptMultipleTransactionsInternal(const std::vector<CTransactionRef>& txns, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);606/**607* Submission of a subpackage.608* If subpackage size == 1, calls AcceptSingleTransaction() with adjusted ATMPArgs to609* enable sibling eviction and creates a PackageMempoolAcceptResult610* wrapping the result.611*612* If subpackage size > 1, calls AcceptMultipleTransactions() with the provided ATMPArgs.613*614* Also cleans up all non-chainstate coins from m_view at the end.615*/616PackageMempoolAcceptResult AcceptSubPackage(const std::vector<CTransactionRef>& subpackage, ATMPArgs& args)617EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);619/**620* Package (more specific than just multiple transactions) acceptance. Package must be a child621* with all of its unconfirmed parents, and topologically sorted.622*/623PackageMempoolAcceptResult AcceptPackage(const Package& package, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);625private:626// All the intermediate state that gets passed between the various levels627// of checking a given transaction.628struct Workspace {629explicit Workspace(const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}630/** Txids of mempool transactions that this transaction directly conflicts with or may631* replace via sibling eviction. */632std::set<Txid> m_conflicts;633/** Iterators to mempool entries that this transaction directly conflicts with or may634* replace via sibling eviction. */635CTxMemPool::setEntries m_iters_conflicting;636/** All mempool parents of this transaction. */637std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> m_parents;638/* Handle to the tx in the changeset */639CTxMemPool::ChangeSet::TxHandle m_tx_handle;640/** Whether RBF-related data structures (m_conflicts, m_iters_conflicting,641* m_replaced_transactions) include a sibling in addition to txns with conflicting inputs. */642bool m_sibling_eviction{false};644/** Virtual size of the transaction as used by the mempool, calculated using serialized size645* of the transaction and sigops. */646int64_t m_vsize;647/** Fees paid by this transaction: total input amounts subtracted by total output amounts. */648CAmount m_base_fees;649/** Base fees + any fee delta set by the user with prioritisetransaction. */650CAmount m_modified_fees;652/** If we're doing package validation (i.e. m_package_feerates=true), the "effective"653* package feerate of this transaction is the total fees divided by the total size of654* transactions (which may include its ancestors and/or descendants). */655CFeeRate m_package_feerate{0};657const CTransactionRef& m_ptx;658/** Txid. */659const Txid& m_hash;660TxValidationState m_state;661/** A temporary cache containing serialized transaction data for signature verification.662* Reused across PolicyScriptChecks and ConsensusScriptChecks. */663PrecomputedTransactionData m_precomputed_txdata;664};666// Run the policy checks on a given transaction, excluding any script checks.667// Looks up inputs, calculates feerate, considers replacement, evaluates668// package limits, etc. As this function can be invoked for "free" by a peer,669// only tests that are fast should be done here (to avoid CPU DoS).670bool PreChecks(ATMPArgs& args, Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);672// Run checks for mempool replace-by-fee, only used in AcceptSingleTransaction.673bool ReplacementChecks(Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);675bool PackageRBFChecks(const std::vector<CTransactionRef>& txns,676std::vector<Workspace>& workspaces,677PackageValidationState& package_state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);679// Run the script checks using our policy flags. As this can be slow, we should680// only invoke this on transactions that have otherwise passed policy checks.681bool PolicyScriptChecks(Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);683// Re-run the script checks, using consensus flags, and try to cache the684// result in the scriptcache. This should be done after685// PolicyScriptChecks(). This requires that all inputs either be in our686// utxo set or in the mempool.687bool ConsensusScriptChecks(Workspace& ws) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);689// Try to add the transaction to the mempool, removing any conflicts first.690void FinalizeSubpackage(const ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);692// Submit all transactions to the mempool and call ConsensusScriptChecks to add to the script693// cache - should only be called after successful validation of all transactions in the package.694// Does not call LimitMempoolSize(), so mempool max_size_bytes may be temporarily exceeded.695bool SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& workspaces, PackageValidationState& package_state,696std::map<Wtxid, MempoolAcceptResult>& results)697EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);699// Compare a package's feerate against minimum allowed.700bool CheckFeeRate(size_t package_size, CAmount package_fee, TxValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_pool.cs)701{702AssertLockHeld(::cs_main);703AssertLockHeld(m_pool.cs);704CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size);705if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {706return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));707}709if (package_fee < m_pool.m_opts.min_relay_feerate.GetFee(package_size)) {710return state.Invalid(TxValidationResult::TX_RECONSIDERABLE, "min relay fee not met",711strprintf("%d < %d", package_fee, m_pool.m_opts.min_relay_feerate.GetFee(package_size)));712}713return true;714}716ValidationCache& GetValidationCache()717{718return m_active_chainstate.m_chainman.m_validation_cache;719}721private:722CTxMemPool& m_pool;724/** Holds a cached view of available coins from the UTXO set, mempool, and artificial temporary coins (to enable package validation).725* The view doesn't track whether a coin previously existed but has now been spent. We detect conflicts in other ways:726* - conflicts within a transaction are checked in CheckTransaction (bad-txns-inputs-duplicate)727* - conflicts within a package are checked in IsWellFormedPackage (conflict-in-package)728* - conflicts with an existing mempool transaction are found in CTxMemPool::GetConflictTx and replacements are allowed729* The temporary coins should persist between individual transaction checks so that package validation is possible,730* but must be cleaned up when we finish validating a subpackage, whether accepted or rejected. The cache must also731* be cleared when mempool contents change (when a changeset is applied or when the mempool trims itself) because it732* can return cached coins that no longer exist in the backend. Use CleanupTemporaryCoins() anytime you are finished733* with a SubPackageState or call LimitMempoolSize().734*/735CCoinsViewCache m_view;737// These are the two possible backends for m_view.738/** When m_view is connected to m_viewmempool as its backend, it can pull coins from the mempool and from the UTXO739* set. This is also where temporary coins are stored. */740CCoinsViewMemPool m_viewmempool;742Chainstate& m_active_chainstate;744// Fields below are per *sub*package state and must be reset prior to subsequent745// AcceptSingleTransaction and AcceptMultipleTransactions invocations746struct SubPackageState {747/** Aggregated modified fees of all transactions, used to calculate package feerate. */748CAmount m_total_modified_fees{0};749/** Aggregated virtual size of all transactions, used to calculate package feerate. */750int64_t m_total_vsize{0};