@@ -1443,12 +1443,12 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
1443
1443
m_view.SetBackend (m_dummy);
1444
1444
1445
1445
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().
1447
1448
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.
1452
1452
std::map<uint256, MempoolAcceptResult> individual_results_nonfinal;
1453
1453
bool quit_early{false };
1454
1454
std::vector<CTransactionRef> txns_package_eval;
@@ -1514,32 +1514,28 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
1514
1514
}
1515
1515
}
1516
1516
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));
1543
1539
}
1544
1540
1545
1541
} // anon namespace
0 commit comments