MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / AcceptPackage

Method AcceptPackage

src/validation.cpp:1628–1777  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1626}
1627
1628PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package, ATMPArgs& args)
1629{
1630 Assert(!package.empty());
1631 AssertLockHeld(cs_main);
1632 // Used if returning a PackageMempoolAcceptResult directly from this function.
1633 PackageValidationState package_state_quit_early;
1634
1635 // There are two topologies we are able to handle through this function:
1636 // (1) A single transaction
1637 // (2) A child-with-parents package.
1638 // Check that the package is well-formed. If it isn't, we won't try to validate any of the
1639 // transactions and thus won't return any MempoolAcceptResults, just a package-wide error.
1640
1641 // Context-free package checks.
1642 if (!IsWellFormedPackage(package, package_state_quit_early)) {
1643 return PackageMempoolAcceptResult(package_state_quit_early, {});
1644 }
1645
1646 if (package.size() > 1 && !IsChildWithParents(package)) {
1647 // All transactions in the package must be a parent of the last transaction. This is just an
1648 // opportunity for us to fail fast on a context-free check without taking the mempool lock.
1649 package_state_quit_early.Invalid(PackageValidationResult::PCKG_POLICY, "package-not-child-with-parents");
1650 return PackageMempoolAcceptResult(package_state_quit_early, {});
1651 }
1652
1653 LOCK(m_pool.cs);
1654 // Stores results from which we will create the returned PackageMempoolAcceptResult.
1655 // A result may be changed if a mempool transaction is evicted later due to LimitMempoolSize().
1656 std::map<Wtxid, MempoolAcceptResult> results_final;
1657 // Results from individual validation which will be returned if no other result is available for
1658 // this transaction. "Nonfinal" because if a transaction fails by itself but succeeds later
1659 // (i.e. when evaluated with a fee-bumping child), the result in this map may be discarded.
1660 std::map<Wtxid, MempoolAcceptResult> individual_results_nonfinal;
1661 // Tracks whether we think package submission could result in successful entry to the mempool
1662 bool quit_early{false};
1663 std::vector<CTransactionRef> txns_package_eval;
1664 for (const auto& tx : package) {
1665 const auto& wtxid = tx->GetWitnessHash();
1666 const auto& txid = tx->GetHash();
1667 // There are 3 possibilities: already in mempool, same-txid-diff-wtxid already in mempool,
1668 // or not in mempool. An already confirmed tx is treated as one not in mempool, because all
1669 // we know is that the inputs aren't available.
1670 if (m_pool.exists(wtxid)) {
1671 // Exact transaction already exists in the mempool.
1672 // Node operators are free to set their mempool policies however they please, nodes may receive
1673 // transactions in different orders, and malicious counterparties may try to take advantage of
1674 // policy differences to pin or delay propagation of transactions. As such, it's possible for
1675 // some package transaction(s) to already be in the mempool, and we don't want to reject the
1676 // entire package in that case (as that could be a censorship vector). De-duplicate the
1677 // transactions that are already in the mempool, and only call AcceptMultipleTransactions() with
1678 // the new transactions. This ensures we don't double-count transaction counts and sizes when
1679 // checking ancestor/descendant limits, or double-count transaction fees for fee-related policy.
1680 const auto& entry{*Assert(m_pool.GetEntry(txid))};
1681 results_final.emplace(wtxid, MempoolAcceptResult::MempoolTx(entry.GetTxSize(), entry.GetFee()));
1682 } else if (m_pool.exists(txid)) {
1683 // Transaction with the same non-witness data but different witness (same txid,
1684 // different wtxid) already exists in the mempool.
1685 //

Callers 1

ProcessNewPackageFunction · 0.80

Calls 15

IsWellFormedPackageFunction · 0.85
IsChildWithParentsFunction · 0.85
InvalidMethod · 0.80
emplaceMethod · 0.80
GetTxMethod · 0.80
GetResultMethod · 0.80
findMethod · 0.80
emptyMethod · 0.45
sizeMethod · 0.45
GetHashMethod · 0.45
existsMethod · 0.45

Tested by

no test coverage detected