Bitcoin Core 28.99.0
P2P Digital Currency
rbf.cpp
Go to the documentation of this file.
1// Copyright (c) 2016-2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <policy/rbf.h>
6
7#include <consensus/amount.h>
9#include <policy/feerate.h>
11#include <sync.h>
12#include <tinyformat.h>
13#include <txmempool.h>
14#include <uint256.h>
15#include <util/check.h>
16#include <util/moneystr.h>
17#include <util/rbf.h>
18
19#include <limits>
20#include <vector>
21
22#include <compare>
23
25{
26 AssertLockHeld(pool.cs);
27
28 // First check the transaction itself.
29 if (SignalsOptInRBF(tx)) {
31 }
32
33 // If this transaction is not in our mempool, then we can't be sure
34 // we will know about all its inputs.
35 if (!pool.exists(GenTxid::Txid(tx.GetHash()))) {
37 }
38
39 // If all the inputs have nSequence >= maxint-1, it still might be
40 // signaled for RBF if any unconfirmed parents have signaled.
41 const auto& entry{*Assert(pool.GetEntry(tx.GetHash()))};
42 auto ancestors{pool.AssumeCalculateMemPoolAncestors(__func__, entry, CTxMemPool::Limits::NoLimits(),
43 /*fSearchForParents=*/false)};
44
45 for (CTxMemPool::txiter it : ancestors) {
46 if (SignalsOptInRBF(it->GetTx())) {
48 }
49 }
51}
52
54{
55 // If we don't have a local mempool we can only check the transaction itself.
57}
58
59std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
60 CTxMemPool& pool,
61 const CTxMemPool::setEntries& iters_conflicting,
62 CTxMemPool::setEntries& all_conflicts)
63{
64 AssertLockHeld(pool.cs);
65 const uint256 txid = tx.GetHash();
66 uint64_t nConflictingCount = 0;
67 for (const auto& mi : iters_conflicting) {
68 nConflictingCount += mi->GetCountWithDescendants();
69 // Rule #5: don't consider replacing more than MAX_REPLACEMENT_CANDIDATES
70 // entries from the mempool. This potentially overestimates the number of actual
71 // descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
72 // times), but we just want to be conservative to avoid doing too much work.
73 if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) {
74 return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
75 txid.ToString(),
76 nConflictingCount,
78 }
79 }
80 // Calculate the set of all transactions that would have to be evicted.
81 for (CTxMemPool::txiter it : iters_conflicting) {
82 pool.CalculateDescendants(it, all_conflicts);
83 }
84 return std::nullopt;
85}
86
87std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx,
88 const CTxMemPool& pool,
89 const CTxMemPool::setEntries& iters_conflicting)
90{
91 AssertLockHeld(pool.cs);
92 std::set<uint256> parents_of_conflicts;
93 for (const auto& mi : iters_conflicting) {
94 for (const CTxIn& txin : mi->GetTx().vin) {
95 parents_of_conflicts.insert(txin.prevout.hash);
96 }
97 }
98
99 for (unsigned int j = 0; j < tx.vin.size(); j++) {
100 // Rule #2: We don't want to accept replacements that require low feerate junk to be
101 // mined first. Ideally we'd keep track of the ancestor feerates and make the decision
102 // based on that, but for now requiring all new inputs to be confirmed works.
103 //
104 // Note that if you relax this to make RBF a little more useful, this may break the
105 // CalculateMempoolAncestors RBF relaxation which subtracts the conflict count/size from the
106 // descendant limit.
107 if (!parents_of_conflicts.count(tx.vin[j].prevout.hash)) {
108 // Rather than check the UTXO set - potentially expensive - it's cheaper to just check
109 // if the new input refers to a tx that's in the mempool.
110 if (pool.exists(GenTxid::Txid(tx.vin[j].prevout.hash))) {
111 return strprintf("replacement %s adds unconfirmed input, idx %d",
112 tx.GetHash().ToString(), j);
113 }
114 }
115 }
116 return std::nullopt;
117}
118
119std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors,
120 const std::set<Txid>& direct_conflicts,
121 const uint256& txid)
122{
123 for (CTxMemPool::txiter ancestorIt : ancestors) {
124 const Txid& hashAncestor = ancestorIt->GetTx().GetHash();
125 if (direct_conflicts.count(hashAncestor)) {
126 return strprintf("%s spends conflicting transaction %s",
127 txid.ToString(),
128 hashAncestor.ToString());
129 }
130 }
131 return std::nullopt;
132}
133
134std::optional<std::string> PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting,
135 CFeeRate replacement_feerate,
136 const uint256& txid)
137{
138 for (const auto& mi : iters_conflicting) {
139 // Don't allow the replacement to reduce the feerate of the mempool.
140 //
141 // We usually don't want to accept replacements with lower feerates than what they replaced
142 // as that would lower the feerate of the next block. Requiring that the feerate always be
143 // increased is also an easy-to-reason about way to prevent DoS attacks via replacements.
144 //
145 // We only consider the feerates of transactions being directly replaced, not their indirect
146 // descendants. While that does mean high feerate children are ignored when deciding whether
147 // or not to replace, we do require the replacement to pay more overall fees too, mitigating
148 // most cases.
149 CFeeRate original_feerate(mi->GetModifiedFee(), mi->GetTxSize());
150 if (replacement_feerate <= original_feerate) {
151 return strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
152 txid.ToString(),
153 replacement_feerate.ToString(),
154 original_feerate.ToString());
155 }
156 }
157 return std::nullopt;
158}
159
160std::optional<std::string> PaysForRBF(CAmount original_fees,
161 CAmount replacement_fees,
162 size_t replacement_vsize,
163 CFeeRate relay_fee,
164 const uint256& txid)
165{
166 // Rule #3: The replacement fees must be greater than or equal to fees of the
167 // transactions it replaces, otherwise the bandwidth used by those conflicting transactions
168 // would not be paid for.
169 if (replacement_fees < original_fees) {
170 return strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
171 txid.ToString(), FormatMoney(replacement_fees), FormatMoney(original_fees));
172 }
173
174 // Rule #4: The new transaction must pay for its own bandwidth. Otherwise, we have a DoS
175 // vector where attackers can cause a transaction to be replaced (and relayed) repeatedly by
176 // increasing the fee by tiny amounts.
177 CAmount additional_fees = replacement_fees - original_fees;
178 if (additional_fees < relay_fee.GetFee(replacement_vsize)) {
179 return strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
180 txid.ToString(),
181 FormatMoney(additional_fees),
182 FormatMoney(relay_fee.GetFee(replacement_vsize)));
183 }
184 return std::nullopt;
185}
186
187std::optional<std::pair<DiagramCheckError, std::string>> ImprovesFeerateDiagram(CTxMemPool::ChangeSet& changeset)
188{
189 // Require that the replacement strictly improves the mempool's feerate diagram.
190 const auto chunk_results{changeset.CalculateChunksForRBF()};
191
192 if (!chunk_results.has_value()) {
193 return std::make_pair(DiagramCheckError::UNCALCULABLE, util::ErrorString(chunk_results).original);
194 }
195
196 if (!std::is_gt(CompareChunks(chunk_results.value().second, chunk_results.value().first))) {
197 return std::make_pair(DiagramCheckError::FAILURE, "insufficient feerate: does not improve feerate diagram");
198 }
199 return std::nullopt;
200}
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
#define Assert(val)
Identity function.
Definition: check.h:85
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition: feerate.h:33
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
Definition: feerate.cpp:39
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given vsize in vbytes.
Definition: feerate.cpp:23
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:296
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:343
const std::vector< CTxIn > vin
Definition: transaction.h:306
An input of a transaction.
Definition: transaction.h:67
util::Result< std::pair< std::vector< FeeFrac >, std::vector< FeeFrac > > > CalculateChunksForRBF()
Calculate the sorted chunks for the old and new mempool relating to the clusters that would be affect...
Definition: txmempool.cpp:1315
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:304
setEntries AssumeCalculateMemPoolAncestors(std::string_view calling_fn_name, const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Same as CalculateMemPoolAncestors, but always returns a (non-optional) setEntries.
Definition: txmempool.cpp:275
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:390
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:396
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
Definition: txmempool.h:393
bool exists(const GenTxid &gtxid) const
Definition: txmempool.h:647
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
Definition: txmempool.cpp:571
const CTxMemPoolEntry * GetEntry(const Txid &txid) const LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(cs)
Definition: txmempool.cpp:877
static GenTxid Txid(const uint256 &hash)
Definition: transaction.h:434
std::string ToString() const
Definition: uint256.cpp:47
std::string ToString() const
256-bit opaque blob.
Definition: uint256.h:190
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:19
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:93
std::optional< std::string > HasNoNewUnconfirmed(const CTransaction &tx, const CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting)
The replacement transaction may only include an unconfirmed input if that input was included in one o...
Definition: rbf.cpp:87
std::optional< std::pair< DiagramCheckError, std::string > > ImprovesFeerateDiagram(CTxMemPool::ChangeSet &changeset)
The replacement transaction must improve the feerate diagram of the mempool.
Definition: rbf.cpp:187
std::optional< std::string > PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, const uint256 &txid)
The replacement transaction must pay more fees than the original transactions.
Definition: rbf.cpp:160
RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction &tx)
Definition: rbf.cpp:53
std::optional< std::string > EntriesAndTxidsDisjoint(const CTxMemPool::setEntries &ancestors, const std::set< Txid > &direct_conflicts, const uint256 &txid)
Check the intersection between two sets of transactions (a set of mempool entries and a set of txids)...
Definition: rbf.cpp:119
std::optional< std::string > PaysMoreThanConflicts(const CTxMemPool::setEntries &iters_conflicting, CFeeRate replacement_feerate, const uint256 &txid)
Check that the feerate of the replacement transaction(s) is higher than the feerate of each of the tr...
Definition: rbf.cpp:134
RBFTransactionState IsRBFOptIn(const CTransaction &tx, const CTxMemPool &pool)
Determine whether an unconfirmed transaction is signaling opt-in to RBF according to BIP 125 This inv...
Definition: rbf.cpp:24
std::optional< std::string > GetEntriesForConflicts(const CTransaction &tx, CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting, CTxMemPool::setEntries &all_conflicts)
Get all descendants of iters_conflicting.
Definition: rbf.cpp:59
RBFTransactionState
The rbf state of unconfirmed transactions.
Definition: rbf.h:29
@ UNKNOWN
Unconfirmed tx that does not signal rbf and is not in the mempool.
@ FINAL
Neither this tx nor a mempool ancestor signals rbf.
@ REPLACEABLE_BIP125
Either this tx or a mempool ancestor signals rbf.
static constexpr uint32_t MAX_REPLACEMENT_CANDIDATES
Maximum number of transactions that can be replaced by RBF (Rule #5).
Definition: rbf.h:26
@ FAILURE
New diagram wasn't strictly superior
@ UNCALCULABLE
Unable to calculate due to topology or other reason.
static constexpr MemPoolLimits NoLimits()
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1165
std::partial_ordering CompareChunks(Span< const FeeFrac > chunks0, Span< const FeeFrac > chunks1)
Compare the feerate diagrams implied by the provided sorted chunks data.
Definition: feefrac.cpp:10
bool SignalsOptInRBF(const CTransaction &tx)
Check whether the sequence numbers on this transaction are signaling opt-in to replace-by-fee,...
Definition: rbf.cpp:9
AssertLockHeld(pool.cs)