@@ -596,10 +596,10 @@ class MemPoolAccept
596
596
597
597
// Submit all transactions to the mempool and call ConsensusScriptChecks to add to the script
598
598
// cache - should only be called after successful validation of all transactions in the package.
599
- // The package may end up partially-submitted after size limitting ; returns true if all
599
+ // The package may end up partially-submitted after size limiting ; returns true if all
600
600
// transactions are successfully added to the mempool, false otherwise.
601
- bool FinalizePackage (const ATMPArgs& args, std::vector<Workspace>& workspaces, PackageValidationState& package_state,
602
- std::map<const uint256, const MempoolAcceptResult>& results)
601
+ bool SubmitPackage (const ATMPArgs& args, std::vector<Workspace>& workspaces, PackageValidationState& package_state,
602
+ std::map<const uint256, const MempoolAcceptResult>& results)
603
603
EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);
604
604
605
605
// Compare a package's feerate against minimum allowed.
@@ -1038,12 +1038,17 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
1038
1038
return true ;
1039
1039
}
1040
1040
1041
- bool MemPoolAccept::FinalizePackage (const ATMPArgs& args, std::vector<Workspace>& workspaces,
1042
- PackageValidationState& package_state,
1043
- std::map<const uint256, const MempoolAcceptResult>& results)
1041
+ bool MemPoolAccept::SubmitPackage (const ATMPArgs& args, std::vector<Workspace>& workspaces,
1042
+ PackageValidationState& package_state,
1043
+ std::map<const uint256, const MempoolAcceptResult>& results)
1044
1044
{
1045
1045
AssertLockHeld (cs_main);
1046
1046
AssertLockHeld (m_pool.cs );
1047
+ // Sanity check: none of the transactions should be in the mempool, and none of the transactions
1048
+ // should have a same-txid-different-witness equivalent in the mempool.
1049
+ assert (std::all_of (workspaces.cbegin (), workspaces.cend (), [this ](const auto & ws){
1050
+ return !m_pool.exists (GenTxid::Txid (ws.m_ptx ->GetHash ())); }));
1051
+
1047
1052
bool all_submitted = true ;
1048
1053
// ConsensusScriptChecks adds to the script cache and is therefore consensus-critical;
1049
1054
// CheckInputsFromMempoolAndCache asserts that transactions only spend coins available from the
@@ -1058,10 +1063,10 @@ bool MemPoolAccept::FinalizePackage(const ATMPArgs& args, std::vector<Workspace>
1058
1063
1059
1064
// Re-calculate mempool ancestors to call addUnchecked(). They may have changed since the
1060
1065
// last calculation done in PreChecks, since package ancestors have already been submitted.
1061
- std::string err_string ;
1066
+ std::string unused_err_string ;
1062
1067
if (!m_pool.CalculateMemPoolAncestors (*ws.m_entry , ws.m_ancestors , m_limit_ancestors,
1063
1068
m_limit_ancestor_size, m_limit_descendants,
1064
- m_limit_descendant_size, err_string )) {
1069
+ m_limit_descendant_size, unused_err_string )) {
1065
1070
results.emplace (ws.m_ptx ->GetWitnessHash (), MempoolAcceptResult::Failure (ws.m_state ));
1066
1071
// Since PreChecks() and PackageMempoolChecks() both enforce limits, this should never fail.
1067
1072
all_submitted = Assume (false );
@@ -1188,7 +1193,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
1188
1193
1189
1194
if (args.m_test_accept ) return PackageMempoolAcceptResult (package_state, std::move (results));
1190
1195
1191
- if (!FinalizePackage (args, workspaces, package_state, results)) {
1196
+ if (!SubmitPackage (args, workspaces, package_state, results)) {
1192
1197
package_state.Invalid (PackageValidationResult::PCKG_TX, " submission failed" );
1193
1198
return PackageMempoolAcceptResult (package_state, std::move (results));
1194
1199
}
@@ -1214,11 +1219,13 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
1214
1219
return PackageMempoolAcceptResult (package_state, {});
1215
1220
}
1216
1221
1217
- const auto & child = package[package.size () - 1 ];
1222
+ // IsChildWithParents() guarantees the package is > 1 transactions.
1223
+ assert (package.size () > 1 );
1218
1224
// The package must be 1 child with all of its unconfirmed parents. The package is expected to
1219
1225
// be sorted, so the last transaction is the child.
1226
+ const auto & child = package.back ();
1220
1227
std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
1221
- std::transform (package.cbegin (), package.end () - 1 ,
1228
+ std::transform (package.cbegin (), package.cend () - 1 ,
1222
1229
std::inserter (unconfirmed_parent_txids, unconfirmed_parent_txids.end ()),
1223
1230
[](const auto & tx) { return tx->GetHash (); });
1224
1231
@@ -1348,12 +1355,12 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
1348
1355
}();
1349
1356
1350
1357
// Uncache coins pertaining to transactions that were not submitted to the mempool.
1351
- // Ensure the coins cache is still within limits.
1352
1358
if (test_accept || result.m_state .IsInvalid ()) {
1353
1359
for (const COutPoint& hashTx : coins_to_uncache) {
1354
1360
active_chainstate.CoinsTip ().Uncache (hashTx);
1355
1361
}
1356
1362
}
1363
+ // Ensure the coins cache is still within limits.
1357
1364
BlockValidationState state_dummy;
1358
1365
active_chainstate.FlushStateToDisk (state_dummy, FlushStateMode::PERIODIC);
1359
1366
return result;
0 commit comments