Skip to content

Commit 9698b81

Browse files
committed
[refactor] back-fill results in AcceptPackage
Instead of populating the last PackageMempoolAcceptResult with stuff from results_final and individual_results_nonfinal, fill results_final and create a PackageMempoolAcceptResult using that one. A future commit will add LimitMempoolSize() which may change the status of each of these transactions from "already in mempool" or "submitted to mempool" to "no longer in mempool". We will change those transactions' results here. A future commit also gets rid of the last AcceptSubPackage outside of the loop. It makes more sense to use results_final as the place where all results end up.
1 parent 8ad7ad3 commit 9698b81

File tree

1 file changed

+27
-31
lines changed

1 file changed

+27
-31
lines changed

src/validation.cpp

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)