@@ -559,7 +559,7 @@ class MemPoolAccept
559
559
/**
560
560
* Multiple transaction acceptance. Transactions may or may not be interdependent,
561
561
* but must not conflict with each other. Parents must come before children if any
562
- * dependencies exist, otherwise a TX_MISSING_INPUTS error will be returned .
562
+ * dependencies exist.
563
563
*/
564
564
PackageMempoolAcceptResult AcceptMultipleTransactions(const std::vector<CTransactionRef>& txns, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
565
565
@@ -982,65 +982,15 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
982
982
{
983
983
AssertLockHeld(cs_main);
984
984
985
+ // These context-free package limits can be done before taking the mempool lock.
985
986
PackageValidationState package_state;
986
- const unsigned int package_count = txns.size( );
987
+ if (!CheckPackage(txns, package_state)) return PackageMempoolAcceptResult(package_state, {} );
987
988
988
- // These context-free package limits can be checked before taking the mempool lock.
989
- if (package_count > MAX_PACKAGE_COUNT) {
990
- package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-too-many-transactions");
991
- return PackageMempoolAcceptResult(package_state, {});
992
- }
993
-
994
- const int64_t total_size = std::accumulate(txns.cbegin(), txns.cend(), 0,
995
- [](int64_t sum, const auto& tx) { return sum + GetVirtualTransactionSize(*tx); });
996
- // If the package only contains 1 tx, it's better to report the policy violation on individual tx size.
997
- if (package_count > 1 && total_size > MAX_PACKAGE_SIZE * 1000) {
998
- package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-too-large");
999
- return PackageMempoolAcceptResult(package_state, {});
1000
- }
1001
-
1002
- // Construct workspaces and check package policies.
1003
989
std::vector<Workspace> workspaces{};
1004
- workspaces.reserve(package_count);
1005
- {
1006
- std::unordered_set<uint256, SaltedTxidHasher> later_txids;
1007
- std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()),
1008
- [](const auto& tx) { return tx->GetHash(); });
1009
- // Require the package to be sorted in order of dependency, i.e. parents appear before children.
1010
- // An unsorted package will fail anyway on missing-inputs, but it's better to quit earlier and
1011
- // fail on something less ambiguous (missing-inputs could also be an orphan or trying to
1012
- // spend nonexistent coins).
1013
- for (const auto& tx : txns) {
1014
- for (const auto& input : tx->vin) {
1015
- if (later_txids.find(input.prevout.hash) != later_txids.end()) {
1016
- // The parent is a subsequent transaction in the package.
1017
- package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-not-sorted");
1018
- return PackageMempoolAcceptResult(package_state, {});
1019
- }
1020
- }
1021
- later_txids.erase(tx->GetHash());
1022
- workspaces.emplace_back(Workspace(tx));
1023
- }
1024
- }
990
+ workspaces.reserve(txns.size());
991
+ std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
992
+ [](const auto& tx) { return Workspace(tx); });
1025
993
std::map<const uint256, const MempoolAcceptResult> results;
1026
- {
1027
- // Don't allow any conflicting transactions, i.e. spending the same inputs, in a package.
1028
- std::unordered_set<COutPoint, SaltedOutpointHasher> inputs_seen;
1029
- for (const auto& tx : txns) {
1030
- for (const auto& input : tx->vin) {
1031
- if (inputs_seen.find(input.prevout) != inputs_seen.end()) {
1032
- // This input is also present in another tx in the package.
1033
- package_state.Invalid(PackageValidationResult::PCKG_POLICY, "conflict-in-package");
1034
- return PackageMempoolAcceptResult(package_state, {});
1035
- }
1036
- }
1037
- // Batch-add all the inputs for a tx at a time. If we added them 1 at a time, we could
1038
- // catch duplicate inputs within a single tx. This is a more severe, consensus error,
1039
- // and we want to report that from CheckTransaction instead.
1040
- std::transform(tx->vin.cbegin(), tx->vin.cend(), std::inserter(inputs_seen, inputs_seen.end()),
1041
- [](const auto& input) { return input.prevout; });
1042
- }
1043
- }
1044
994
1045
995
LOCK(m_pool.cs);
1046
996
@@ -1127,7 +1077,6 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
1127
1077
const PackageMempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args);
1128
1078
1129
1079
// Uncache coins pertaining to transactions that were not submitted to the mempool.
1130
- // Ensure the cache is still within its size limits.
1131
1080
for (const COutPoint& hashTx : coins_to_uncache) {
1132
1081
active_chainstate.CoinsTip().Uncache(hashTx);
1133
1082
}
0 commit comments