diff options
Diffstat (limited to 'src/policy/rbf.cpp')
-rw-r--r-- | src/policy/rbf.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp index 95b74123c9..5d1db6b58d 100644 --- a/src/policy/rbf.cpp +++ b/src/policy/rbf.cpp @@ -129,3 +129,35 @@ std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& } return std::nullopt; } + +std::optional<std::string> PaysMoreThanConflicts(const CTxMemPool::setEntries& setIterConflicting, + CFeeRate newFeeRate, + const uint256& hash) +{ + for (const auto& mi : setIterConflicting) { + // Don't allow the replacement to reduce the feerate of the + // mempool. + // + // We usually don't want to accept replacements with lower + // feerates than what they replaced as that would lower the + // feerate of the next block. Requiring that the feerate always + // be increased is also an easy-to-reason about way to prevent + // DoS attacks via replacements. + // + // We only consider the feerates of transactions being directly + // replaced, not their indirect descendants. While that does + // mean high feerate children are ignored when deciding whether + // or not to replace, we do require the replacement to pay more + // overall fees too, mitigating most cases. + CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); + if (newFeeRate <= oldFeeRate) + { + return strprintf("rejecting replacement %s; new feerate %s <= old feerate %s", + hash.ToString(), + newFeeRate.ToString(), + oldFeeRate.ToString()); + } + } + return std::nullopt; +} + |