@@ -472,8 +472,10 @@ class MemPoolAccept
472
472
*/
473
473
std::vector<COutPoint>& m_coins_to_uncache;
474
474
const bool m_test_accept;
475
- /* * Disable BIP125 RBFing; disallow all conflicts with mempool transactions. */
476
- const bool disallow_mempool_conflicts;
475
+ /* * Whether we allow transactions to replace mempool transactions by BIP125 rules. If false,
476
+ * any transaction spending the same inputs as a transaction in the mempool is considered
477
+ * a conflict. */
478
+ const bool m_allow_bip125_replacement{true };
477
479
};
478
480
479
481
// Single transaction acceptance
@@ -482,7 +484,7 @@ class MemPoolAccept
482
484
/* *
483
485
* Multiple transaction acceptance. Transactions may or may not be interdependent,
484
486
* but must not conflict with each other. Parents must come before children if any
485
- * dependencies exist, otherwise a TX_MISSING_INPUTS error will be returned .
487
+ * dependencies exist.
486
488
*/
487
489
PackageMempoolAcceptResult AcceptMultipleTransactions (const std::vector<CTransactionRef>& txns, ATMPArgs& args) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
488
490
@@ -619,6 +621,10 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
619
621
{
620
622
const CTransaction* ptxConflicting = m_pool.GetConflictTx (txin.prevout );
621
623
if (ptxConflicting) {
624
+ if (!args.m_allow_bip125_replacement ) {
625
+ // Transaction conflicts with a mempool tx, but we're not allowing replacements.
626
+ return state.Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " bip125-replacement-disallowed" );
627
+ }
622
628
if (!setConflicts.count (ptxConflicting->GetHash ()))
623
629
{
624
630
// Allow opt-out of transaction replacement by setting
@@ -645,7 +651,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
645
651
break ;
646
652
}
647
653
}
648
- if (fReplacementOptOut || args. disallow_mempool_conflicts ) {
654
+ if (fReplacementOptOut ) {
649
655
return state.Invalid (TxValidationResult::TX_MEMPOOL_POLICY, " txn-mempool-conflict" );
650
656
}
651
657
@@ -1080,65 +1086,15 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
1080
1086
{
1081
1087
AssertLockHeld (cs_main);
1082
1088
1089
+ // These context-free package limits can be done before taking the mempool lock.
1083
1090
PackageValidationState package_state;
1084
- const unsigned int package_count = txns.size ();
1085
-
1086
- // These context-free package limits can be checked before taking the mempool lock.
1087
- if (package_count > MAX_PACKAGE_COUNT) {
1088
- package_state.Invalid (PackageValidationResult::PCKG_POLICY, " package-too-many-transactions" );
1089
- return PackageMempoolAcceptResult (package_state, {});
1090
- }
1091
-
1092
- const int64_t total_size = std::accumulate (txns.cbegin (), txns.cend (), 0 ,
1093
- [](int64_t sum, const auto & tx) { return sum + GetVirtualTransactionSize (*tx); });
1094
- // If the package only contains 1 tx, it's better to report the policy violation on individual tx size.
1095
- if (package_count > 1 && total_size > MAX_PACKAGE_SIZE * 1000 ) {
1096
- package_state.Invalid (PackageValidationResult::PCKG_POLICY, " package-too-large" );
1097
- return PackageMempoolAcceptResult (package_state, {});
1098
- }
1091
+ if (!CheckPackage (txns, package_state)) return PackageMempoolAcceptResult (package_state, {});
1099
1092
1100
- // Construct workspaces and check package policies.
1101
1093
std::vector<Workspace> workspaces{};
1102
- workspaces.reserve (package_count);
1103
- {
1104
- std::unordered_set<uint256, SaltedTxidHasher> later_txids;
1105
- std::transform (txns.cbegin (), txns.cend (), std::inserter (later_txids, later_txids.end ()),
1106
- [](const auto & tx) { return tx->GetHash (); });
1107
- // Require the package to be sorted in order of dependency, i.e. parents appear before children.
1108
- // An unsorted package will fail anyway on missing-inputs, but it's better to quit earlier and
1109
- // fail on something less ambiguous (missing-inputs could also be an orphan or trying to
1110
- // spend nonexistent coins).
1111
- for (const auto & tx : txns) {
1112
- for (const auto & input : tx->vin ) {
1113
- if (later_txids.find (input.prevout .hash ) != later_txids.end ()) {
1114
- // The parent is a subsequent transaction in the package.
1115
- package_state.Invalid (PackageValidationResult::PCKG_POLICY, " package-not-sorted" );
1116
- return PackageMempoolAcceptResult (package_state, {});
1117
- }
1118
- }
1119
- later_txids.erase (tx->GetHash ());
1120
- workspaces.emplace_back (Workspace (tx));
1121
- }
1122
- }
1094
+ workspaces.reserve (txns.size ());
1095
+ std::transform (txns.cbegin (), txns.cend (), std::back_inserter (workspaces),
1096
+ [](const auto & tx) { return Workspace (tx); });
1123
1097
std::map<const uint256, const MempoolAcceptResult> results;
1124
- {
1125
- // Don't allow any conflicting transactions, i.e. spending the same inputs, in a package.
1126
- std::unordered_set<COutPoint, SaltedOutpointHasher> inputs_seen;
1127
- for (const auto & tx : txns) {
1128
- for (const auto & input : tx->vin ) {
1129
- if (inputs_seen.find (input.prevout ) != inputs_seen.end ()) {
1130
- // This input is also present in another tx in the package.
1131
- package_state.Invalid (PackageValidationResult::PCKG_POLICY, " conflict-in-package" );
1132
- return PackageMempoolAcceptResult (package_state, {});
1133
- }
1134
- }
1135
- // Batch-add all the inputs for a tx at a time. If we added them 1 at a time, we could
1136
- // catch duplicate inputs within a single tx. This is a more severe, consensus error,
1137
- // and we want to report that from CheckTransaction instead.
1138
- std::transform (tx->vin .cbegin (), tx->vin .cend (), std::inserter (inputs_seen, inputs_seen.end ()),
1139
- [](const auto & input) { return input.prevout ; });
1140
- }
1141
- }
1142
1098
1143
1099
LOCK (m_pool.cs );
1144
1100
@@ -1151,10 +1107,10 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
1151
1107
return PackageMempoolAcceptResult (package_state, std::move (results));
1152
1108
}
1153
1109
// Make the coins created by this transaction available for subsequent transactions in the
1154
- // package to spend. Since we already checked conflicts in the package and RBFs are
1155
- // impossible , we don't need to track the coins spent. Note that this logic will need to be
1156
- // updated if RBFs in packages are allowed in the future.
1157
- assert (args.disallow_mempool_conflicts );
1110
+ // package to spend. Since we already checked conflicts in the package and we don't allow
1111
+ // replacements , we don't need to track the coins spent. Note that this logic will need to be
1112
+ // updated if package replace-by-fee is allowed in the future.
1113
+ assert (! args.m_allow_bip125_replacement );
1158
1114
m_viewmempool.PackageAddTransaction (ws.m_ptx );
1159
1115
}
1160
1116
@@ -1188,7 +1144,7 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
1188
1144
{
1189
1145
std::vector<COutPoint> coins_to_uncache;
1190
1146
MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache,
1191
- test_accept, /* disallow_mempool_conflicts */ false };
1147
+ test_accept, /* m_allow_bip125_replacement */ true };
1192
1148
1193
1149
assert (std::addressof (::ChainstateActive ()) == std::addressof (active_chainstate));
1194
1150
const MempoolAcceptResult result = MemPoolAccept (pool, active_chainstate).AcceptSingleTransaction (tx, args);
@@ -1225,12 +1181,11 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
1225
1181
std::vector<COutPoint> coins_to_uncache;
1226
1182
const CChainParams& chainparams = Params ();
1227
1183
MemPoolAccept::ATMPArgs args { chainparams, GetTime (), /* bypass_limits */ false , coins_to_uncache,
1228
- test_accept, /* disallow_mempool_conflicts */ true };
1184
+ test_accept, /* m_allow_bip125_replacement */ false };
1229
1185
assert (std::addressof (::ChainstateActive ()) == std::addressof (active_chainstate));
1230
1186
const PackageMempoolAcceptResult result = MemPoolAccept (pool, active_chainstate).AcceptMultipleTransactions (package, args);
1231
1187
1232
1188
// Uncache coins pertaining to transactions that were not submitted to the mempool.
1233
- // Ensure the cache is still within its size limits.
1234
1189
for (const COutPoint& hashTx : coins_to_uncache) {
1235
1190
active_chainstate.CoinsTip ().Uncache (hashTx);
1236
1191
}
0 commit comments