Branch data Line data Source code
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>
8 : : #include <kernel/mempool_entry.h>
9 : : #include <policy/feerate.h>
10 : : #include <primitives/transaction.h>
11 : : #include <sync.h>
12 : : #include <tinyformat.h>
13 : : #include <txmempool.h>
14 : : #include <uint256.h>
15 : : #include <util/moneystr.h>
16 : : #include <util/rbf.h>
17 [ + - ]: 2 :
18 [ + - ]: 2 : #include <limits>
19 : : #include <vector>
20 : :
21 : 0 : RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool)
22 : : {
23 : 0 : AssertLockHeld(pool.cs);
24 : :
25 : : // First check the transaction itself.
26 [ # # ]: 0 : if (SignalsOptInRBF(tx)) {
27 : 0 : return RBFTransactionState::REPLACEABLE_BIP125;
28 : : }
29 : :
30 : : // If this transaction is not in our mempool, then we can't be sure
31 : : // we will know about all its inputs.
32 [ # # ]: 0 : if (!pool.exists(GenTxid::Txid(tx.GetHash()))) {
33 : 0 : return RBFTransactionState::UNKNOWN;
34 : : }
35 : :
36 : : // If all the inputs have nSequence >= maxint-1, it still might be
37 : : // signaled for RBF if any unconfirmed parents have signaled.
38 : 0 : const CTxMemPoolEntry entry{*pool.mapTx.find(tx.GetHash())};
39 [ # # ][ # # ]: 0 : auto ancestors{pool.AssumeCalculateMemPoolAncestors(__func__, entry, CTxMemPool::Limits::NoLimits(),
40 : : /*fSearchForParents=*/false)};
41 : :
42 [ # # ]: 0 : for (CTxMemPool::txiter it : ancestors) {
43 [ # # ][ # # ]: 0 : if (SignalsOptInRBF(it->GetTx())) {
[ # # ][ # # ]
44 : 0 : return RBFTransactionState::REPLACEABLE_BIP125;
45 : : }
46 : : }
47 : 0 : return RBFTransactionState::FINAL;
48 : 0 : }
49 : :
50 : 0 : RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction& tx)
51 : : {
52 : : // If we don't have a local mempool we can only check the transaction itself.
53 : 0 : return SignalsOptInRBF(tx) ? RBFTransactionState::REPLACEABLE_BIP125 : RBFTransactionState::UNKNOWN;
54 : : }
55 : :
56 : 0 : std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
57 : : CTxMemPool& pool,
58 : : const CTxMemPool::setEntries& iters_conflicting,
59 : : CTxMemPool::setEntries& all_conflicts)
60 : : {
61 : 0 : AssertLockHeld(pool.cs);
62 : 0 : const uint256 txid = tx.GetHash();
63 : 0 : uint64_t nConflictingCount = 0;
64 [ # # ]: 0 : for (const auto& mi : iters_conflicting) {
65 : 0 : nConflictingCount += mi->GetCountWithDescendants();
66 : : // Rule #5: don't consider replacing more than MAX_REPLACEMENT_CANDIDATES
67 : : // entries from the mempool. This potentially overestimates the number of actual
68 : : // descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
69 : : // times), but we just want to be conservative to avoid doing too much work.
70 [ # # ]: 0 : if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) {
71 [ # # ]: 0 : return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
72 : 0 : txid.ToString(),
73 : : nConflictingCount,
74 : : MAX_REPLACEMENT_CANDIDATES);
75 : : }
76 : : }
77 : : // Calculate the set of all transactions that would have to be evicted.
78 [ # # ]: 0 : for (CTxMemPool::txiter it : iters_conflicting) {
79 : 0 : pool.CalculateDescendants(it, all_conflicts);
80 : : }
81 : 0 : return std::nullopt;
82 : 0 : }
83 : :
84 : 0 : std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx,
85 : : const CTxMemPool& pool,
86 : : const CTxMemPool::setEntries& iters_conflicting)
87 : : {
88 : 0 : AssertLockHeld(pool.cs);
89 : 0 : std::set<uint256> parents_of_conflicts;
90 [ # # ]: 0 : for (const auto& mi : iters_conflicting) {
91 [ # # ][ # # ]: 0 : for (const CTxIn& txin : mi->GetTx().vin) {
[ # # ]
92 [ # # ]: 0 : parents_of_conflicts.insert(txin.prevout.hash);
93 : : }
94 : : }
95 : :
96 [ # # ]: 0 : for (unsigned int j = 0; j < tx.vin.size(); j++) {
97 : : // Rule #2: We don't want to accept replacements that require low feerate junk to be
98 : : // mined first. Ideally we'd keep track of the ancestor feerates and make the decision
99 : : // based on that, but for now requiring all new inputs to be confirmed works.
100 : : //
101 : : // Note that if you relax this to make RBF a little more useful, this may break the
102 : : // CalculateMempoolAncestors RBF relaxation which subtracts the conflict count/size from the
103 : : // descendant limit.
104 [ # # ][ # # ]: 0 : if (!parents_of_conflicts.count(tx.vin[j].prevout.hash)) {
105 : : // Rather than check the UTXO set - potentially expensive - it's cheaper to just check
106 : : // if the new input refers to a tx that's in the mempool.
107 [ # # ][ # # ]: 0 : if (pool.exists(GenTxid::Txid(tx.vin[j].prevout.hash))) {
[ # # ]
108 [ # # ]: 0 : return strprintf("replacement %s adds unconfirmed input, idx %d",
109 [ # # ][ # # ]: 0 : tx.GetHash().ToString(), j);
110 : : }
111 : 0 : }
112 : 0 : }
113 : 0 : return std::nullopt;
114 : 0 : }
115 : :
116 : 0 : std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors,
117 : : const std::set<uint256>& direct_conflicts,
118 : : const uint256& txid)
119 : : {
120 [ # # ]: 0 : for (CTxMemPool::txiter ancestorIt : ancestors) {
121 : 0 : const uint256& hashAncestor = ancestorIt->GetTx().GetHash();
122 [ # # ]: 0 : if (direct_conflicts.count(hashAncestor)) {
123 [ # # ]: 0 : return strprintf("%s spends conflicting transaction %s",
124 : 0 : txid.ToString(),
125 [ # # ]: 0 : hashAncestor.ToString());
126 : : }
127 : : }
128 : 0 : return std::nullopt;
129 : 0 : }
130 : :
131 : 0 : std::optional<std::string> PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting,
132 : : CFeeRate replacement_feerate,
133 : : const uint256& txid)
134 : : {
135 [ # # ]: 0 : for (const auto& mi : iters_conflicting) {
136 : : // Don't allow the replacement to reduce the feerate of the mempool.
137 : : //
138 : : // We usually don't want to accept replacements with lower feerates than what they replaced
139 : : // as that would lower the feerate of the next block. Requiring that the feerate always be
140 : : // increased is also an easy-to-reason about way to prevent DoS attacks via replacements.
141 : : //
142 : : // We only consider the feerates of transactions being directly replaced, not their indirect
143 : : // descendants. While that does mean high feerate children are ignored when deciding whether
144 : : // or not to replace, we do require the replacement to pay more overall fees too, mitigating
145 : : // most cases.
146 : 0 : CFeeRate original_feerate(mi->GetModifiedFee(), mi->GetTxSize());
147 [ # # ]: 0 : if (replacement_feerate <= original_feerate) {
148 [ # # ]: 0 : return strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
149 : 0 : txid.ToString(),
150 [ # # ]: 0 : replacement_feerate.ToString(),
151 [ # # ]: 0 : original_feerate.ToString());
152 : : }
153 : : }
154 : 0 : return std::nullopt;
155 : 0 : }
156 : :
157 : 0 : std::optional<std::string> PaysForRBF(CAmount original_fees,
158 : : CAmount replacement_fees,
159 : : size_t replacement_vsize,
160 : : CFeeRate relay_fee,
161 : : const uint256& txid)
162 : : {
163 : : // Rule #3: The replacement fees must be greater than or equal to fees of the
164 : : // transactions it replaces, otherwise the bandwidth used by those conflicting transactions
165 : : // would not be paid for.
166 [ # # ]: 0 : if (replacement_fees < original_fees) {
167 [ # # ]: 0 : return strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
168 [ # # ][ # # ]: 0 : txid.ToString(), FormatMoney(replacement_fees), FormatMoney(original_fees));
169 : : }
170 : :
171 : : // Rule #4: The new transaction must pay for its own bandwidth. Otherwise, we have a DoS
172 : : // vector where attackers can cause a transaction to be replaced (and relayed) repeatedly by
173 : : // increasing the fee by tiny amounts.
174 : 0 : CAmount additional_fees = replacement_fees - original_fees;
175 [ # # ]: 0 : if (additional_fees < relay_fee.GetFee(replacement_vsize)) {
176 [ # # ]: 0 : return strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
177 : 0 : txid.ToString(),
178 [ # # ]: 0 : FormatMoney(additional_fees),
179 [ # # ][ # # ]: 0 : FormatMoney(relay_fee.GetFee(replacement_vsize)));
180 : : }
181 : 0 : return std::nullopt;
182 : 0 : }
|