@@ -1443,12 +1443,12 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
14431443 m_view.SetBackend (m_dummy);
14441444
14451445 LOCK (m_pool.cs );
1446- // Stores final results that won't change
1446+ // Stores results from which we will create the returned PackageMempoolAcceptResult.
1447+ // A result may be changed if a mempool transaction is evicted later due to LimitMempoolSize().
14471448 std::map<uint256, MempoolAcceptResult> results_final;
1448- // Results from individual validation. "Nonfinal" because if a transaction fails by itself but
1449- // succeeds later (i.e. when evaluated with a fee-bumping child), the result changes (though not
1450- // reflected in this map). If a transaction fails more than once, we want to return the first
1451- // result, when it was considered on its own. So changes will only be from invalid -> valid.
1449+ // Results from individual validation which will be returned if no other result is available for
1450+ // this transaction. "Nonfinal" because if a transaction fails by itself but succeeds later
1451+ // (i.e. when evaluated with a fee-bumping child), the result in this map may be discarded.
14521452 std::map<uint256, MempoolAcceptResult> individual_results_nonfinal;
14531453 bool quit_early{false };
14541454 std::vector<CTransactionRef> txns_package_eval;
@@ -1514,32 +1514,28 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
15141514 }
15151515 }
15161516
1517- // Quit early because package validation won't change the result or the entire package has
1518- // already been submitted.
1519- if (quit_early || txns_package_eval.empty ()) {
1520- for (const auto & [wtxid, mempoolaccept_res] : individual_results_nonfinal) {
1521- Assume (results_final.emplace (wtxid, mempoolaccept_res).second );
1522- Assume (mempoolaccept_res.m_result_type == MempoolAcceptResult::ResultType::INVALID);
1523- }
1524- return PackageMempoolAcceptResult (package_state_quit_early, std::move (results_final));
1525- }
1526- // Validate the (deduplicated) transactions as a package. Note that submission_result has its
1527- // own PackageValidationState; package_state_quit_early is unused past this point.
1528- auto submission_result = AcceptSubPackage (txns_package_eval, args);
1529- // Include already-in-mempool transaction results in the final result.
1530- for (const auto & [wtxid, mempoolaccept_res] : results_final) {
1531- Assume (submission_result.m_tx_results .emplace (wtxid, mempoolaccept_res).second );
1532- Assume (mempoolaccept_res.m_result_type != MempoolAcceptResult::ResultType::INVALID);
1533- }
1534- if (submission_result.m_state .GetResult () == PackageValidationResult::PCKG_TX) {
1535- // Package validation failed because one or more transactions failed. Provide a result for
1536- // each transaction; if a transaction doesn't have an entry in submission_result,
1537- // include the previous individual failure reason.
1538- submission_result.m_tx_results .insert (individual_results_nonfinal.cbegin (),
1539- individual_results_nonfinal.cend ());
1540- Assume (submission_result.m_tx_results .size () == package.size ());
1541- }
1542- return submission_result;
1517+ auto multi_submission_result = quit_early || txns_package_eval.empty () ? PackageMempoolAcceptResult (package_state_quit_early, {}) :
1518+ AcceptSubPackage (txns_package_eval, args);
1519+ PackageValidationState& package_state_final = multi_submission_result.m_state ;
1520+
1521+ for (const auto & tx : package) {
1522+ const auto & wtxid = tx->GetWitnessHash ();
1523+ if (multi_submission_result.m_tx_results .count (wtxid) > 0 ) {
1524+ // We shouldn't have re-submitted if the tx result was already in results_final.
1525+ Assume (results_final.count (wtxid) == 0 );
1526+ results_final.emplace (wtxid, multi_submission_result.m_tx_results .at (wtxid));
1527+ } else if (const auto it{results_final.find (wtxid)}; it != results_final.end ()) {
1528+ // Already-in-mempool transaction.
1529+ Assume (it->second .m_result_type != MempoolAcceptResult::ResultType::INVALID);
1530+ Assume (individual_results_nonfinal.count (wtxid) == 0 );
1531+ } else if (const auto it{individual_results_nonfinal.find (wtxid)}; it != individual_results_nonfinal.end ()) {
1532+ Assume (it->second .m_result_type == MempoolAcceptResult::ResultType::INVALID);
1533+ // Interesting result from previous processing.
1534+ results_final.emplace (wtxid, it->second );
1535+ }
1536+ }
1537+ Assume (results_final.size () == package.size ());
1538+ return PackageMempoolAcceptResult (package_state_final, std::move (results_final));
15431539}
15441540
15451541} // anon namespace
0 commit comments