TODO: This section should start from
AcceptPackage() and flow through from there, including
AcceptMultipleTransactions() as a sub-section.
It’s possible to consider multiple transactions for validation together, via
AcceptMultipleTransactions() found in src/net_processing.cpp. It’s currently only available from tests (
test/tx_package_tests.cpp) and the
testmempoolaccept RPC (via
ProcessNewPackage()), but the intention is for it to be available to packages received from the P2P network in the future.
The flow here is similar to
AcceptSingleTransaction() in that we start by grabbing
cs_main before initializing validation state and workspaces, however this time we use
PackageValidationState and a vector of workspaces,
std::vector<Workspace>. Each transaction therefore has it’s own workspace but all transactions in the package share a single validation state. This aligns with the goal of either accepting or rejecting the entire package as a single entity.
Next come two
for loops over the vector of workspaces (i.e. transactions). The first performs the
PreChecks(), but this time also freeing up coins to be spent by other transactions in this package. This would not usually be possible (nor make sense) within an
AcceptTransaction() flow, but within a package we want to be able to validate transactions who use as inputs, other transactions not yet added to our mempool:
// Make the coins created by this transaction available for subsequent transactions in the
// package to spend. Since we already checked conflicts in the package and we don't allow
// replacements, we don't need to track the coins spent. Note that this logic will need to be
// updated if package replace-by-fee is allowed in the future.
PreChecks do not fail, we call
m_viewmempool.PackageAddTransaction() passing in the workspace. This adds the transaction to a map in our Mempool called
std::unordered_map<COutPoint, Coin, SaltedOutpointHasher> m_temp_added;, which is essentially a temporary cache somewhere in-between being validated and being fully added to the mempool.
TODO: Fix after adding section on
After this first loop we perform
PackageMempoolChecks() which first asserts that transactions are not already in the mempool, before checking the "PackageLimits".