@@ -48,26 +48,27 @@ RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction& tx)
4848}
4949
5050std::optional<std::string> GetEntriesForConflicts (const CTransaction& tx,
51- CTxMemPool& pool,
52- const CTxMemPool::setEntries& iters_conflicting,
53- CTxMemPool::setEntries& all_conflicts)
51+ CTxMemPool& pool,
52+ const CTxMemPool::setEntries& iters_conflicting,
53+ CTxMemPool::setEntries& all_conflicts)
5454{
5555 AssertLockHeld (pool.cs );
5656 const uint256 txid = tx.GetHash ();
5757 uint64_t nConflictingCount = 0 ;
5858 for (const auto & mi : iters_conflicting) {
5959 nConflictingCount += mi->GetCountWithDescendants ();
60- // This potentially overestimates the number of actual descendants but we just want to be
61- // conservative to avoid doing too much work.
60+ // BIP125 Rule #5: don't consider replacing more than MAX_BIP125_REPLACEMENT_CANDIDATES
61+ // entries from the mempool. This potentially overestimates the number of actual
62+ // descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
63+ // times), but we just want to be conservative to avoid doing too much work.
6264 if (nConflictingCount > MAX_BIP125_REPLACEMENT_CANDIDATES) {
6365 return strprintf (" rejecting replacement %s; too many potential replacements (%d > %d)\n " ,
6466 txid.ToString (),
6567 nConflictingCount,
6668 MAX_BIP125_REPLACEMENT_CANDIDATES);
6769 }
6870 }
69- // If not too many to replace, then calculate the set of
70- // transactions that would have to be evicted
71+ // Calculate the set of all transactions that would have to be evicted.
7172 for (CTxMemPool::txiter it : iters_conflicting) {
7273 pool.CalculateDescendants (it, all_conflicts);
7374 }
@@ -81,19 +82,19 @@ std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx,
8182 AssertLockHeld (pool.cs );
8283 std::set<uint256> parents_of_conflicts;
8384 for (const auto & mi : iters_conflicting) {
84- for (const CTxIn & txin : mi->GetTx ().vin ) {
85+ for (const CTxIn& txin : mi->GetTx ().vin ) {
8586 parents_of_conflicts.insert (txin.prevout .hash );
8687 }
8788 }
8889
8990 for (unsigned int j = 0 ; j < tx.vin .size (); j++) {
90- // We don't want to accept replacements that require low feerate junk to be mined first.
91- // Ideally we'd keep track of the ancestor feerates and make the decision based on that, but
92- // for now requiring all new inputs to be confirmed works.
91+ // BIP125 Rule #2: We don't want to accept replacements that require low feerate junk to be
92+ // mined first. Ideally we'd keep track of the ancestor feerates and make the decision
93+ // based on that, but for now requiring all new inputs to be confirmed works.
9394 //
9495 // Note that if you relax this to make RBF a little more useful, this may break the
95- // CalculateMempoolAncestors RBF relaxation, above. See the comment above the first
96- // CalculateMempoolAncestors call for more info .
96+ // CalculateMempoolAncestors RBF relaxation which subtracts the conflict count/size from the
97+ // descendant limit .
9798 if (!parents_of_conflicts.count (tx.vin [j].prevout .hash )) {
9899 // Rather than check the UTXO set - potentially expensive - it's cheaper to just check
99100 // if the new input refers to a tx that's in the mempool.
@@ -111,7 +112,7 @@ std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries&
111112 const uint256& txid)
112113{
113114 for (CTxMemPool::txiter ancestorIt : ancestors) {
114- const uint256 & hashAncestor = ancestorIt->GetTx ().GetHash ();
115+ const uint256& hashAncestor = ancestorIt->GetTx ().GetHash ();
115116 if (direct_conflicts.count (hashAncestor)) {
116117 return strprintf (" %s spends conflicting transaction %s" ,
117118 txid.ToString (),
@@ -153,16 +154,17 @@ std::optional<std::string> PaysForRBF(CAmount original_fees,
153154 CFeeRate relay_fee,
154155 const uint256& txid)
155156{
156- // The replacement must pay greater fees than the transactions it
157- // replaces - if we did the bandwidth used by those conflicting
158- // transactions would not be paid for.
157+ // BIP125 Rule #3: The replacement fees must be greater than or equal to fees of the
158+ // transactions it replaces, otherwise the bandwidth used by those conflicting transactions
159+ // would not be paid for.
159160 if (replacement_fees < original_fees) {
160161 return strprintf (" rejecting replacement %s, less fees than conflicting txs; %s < %s" ,
161162 txid.ToString (), FormatMoney (replacement_fees), FormatMoney (original_fees));
162163 }
163164
164- // Finally in addition to paying more fees than the conflicts the
165- // new transaction must pay for its own bandwidth.
165+ // BIP125 Rule #4: The new transaction must pay for its own bandwidth. Otherwise, we have a DoS
166+ // vector where attackers can cause a transaction to be replaced (and relayed) repeatedly by
167+ // increasing the fee by tiny amounts.
166168 CAmount additional_fees = replacement_fees - original_fees;
167169 if (additional_fees < relay_fee.GetFee (replacement_vsize)) {
168170 return strprintf (" rejecting replacement %s, not enough additional fees to relay; %s < %s" ,
0 commit comments