1 // Copyright (c) 2016-2022 The Limenka 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 #ifndef LIMENKA_POLICY_RBF_H
6 #define LIMENKA_POLICY_RBF_H
7 8 #include <consensus/amount.h>
9 #include <policy/policy.h>
10 #include <primitives/transaction.h>
11 #include <threadsafety.h>
12 #include <txmempool.h>
13 #include <util/feefrac.h>
14 15 #include <compare>
16 #include <cstddef>
17 #include <cstdint>
18 #include <optional>
19 #include <set>
20 #include <string>
21 22 class CFeeRate;
23 class uint256;
24 25 /** Maximum number of transactions that can be replaced by RBF (Rule #5). This includes all
26 * mempool conflicts and their descendants. */
27 static constexpr uint32_t MAX_REPLACEMENT_CANDIDATES{100};
28 29 /** The rbf state of unconfirmed transactions */
30 enum class RBFTransactionState {
31 /** Unconfirmed tx that does not signal rbf and is not in the mempool */
32 UNKNOWN,
33 /** Either this tx or a mempool ancestor signals rbf */
34 REPLACEABLE_BIP125,
35 /** Neither this tx nor a mempool ancestor signals rbf */
36 FINAL,
37 };
38 39 enum class DiagramCheckError {
40 /** Unable to calculate due to topology or other reason */
41 UNCALCULABLE,
42 /** New diagram wasn't strictly superior */
43 FAILURE,
44 };
45 46 /**
47 * Determine whether an unconfirmed transaction is signaling opt-in to RBF
48 * according to BIP 125
49 * This involves checking sequence numbers of the transaction, as well
50 * as the sequence numbers of all in-mempool ancestors.
51 *
52 * @param tx The unconfirmed transaction
53 * @param pool The mempool, which may contain the tx
54 *
55 * @return The rbf state
56 */
57 RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs);
58 RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction& tx);
59 60 /** Get all descendants of iters_conflicting. Checks that there are no more than
61 * MAX_REPLACEMENT_CANDIDATES potential entries. May overestimate if the entries in
62 * iters_conflicting have overlapping descendants.
63 * @param[in] iters_conflicting The set of iterators to mempool entries.
64 * @param[out] all_conflicts Populated with all the mempool entries that would be replaced,
65 * which includes iters_conflicting and all entries' descendants.
66 * Not cleared at the start; any existing mempool entries will
67 * remain in the set.
68 * @returns an error message if MAX_REPLACEMENT_CANDIDATES may be exceeded, otherwise a std::nullopt.
69 */
70 std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx, CTxMemPool& pool,
71 const CTxMemPool::setEntries& iters_conflicting,
72 CTxMemPool::setEntries& all_conflicts,
73 const ignore_rejects_type& ignore_rejects=empty_ignore_rejects)
74 EXCLUSIVE_LOCKS_REQUIRED(pool.cs);
75 76 /** The replacement transaction may only include an unconfirmed input if that input was included in
77 * one of the original transactions.
78 * @returns error message if tx spends unconfirmed inputs not also spent by iters_conflicting,
79 * otherwise std::nullopt. */
80 std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx, const CTxMemPool& pool,
81 const CTxMemPool::setEntries& iters_conflicting)
82 EXCLUSIVE_LOCKS_REQUIRED(pool.cs);
83 84 /** Check the intersection between two sets of transactions (a set of mempool entries and a set of
85 * txids) to make sure they are disjoint.
86 * @param[in] ancestors Set of mempool entries corresponding to ancestors of the
87 * replacement transactions.
88 * @param[in] direct_conflicts Set of txids corresponding to the mempool conflicts
89 * (candidates to be replaced).
90 * @param[in] txid Transaction ID, included in the error message if violation occurs.
91 * @param[out] out_violates_policy Assigned to true if there are any policy-only conflicts.
92 * @returns error message if the sets intersect (consensus-only conflicts), std::nullopt if they are disjoint or only intersect on policy matters.
93 */
94 std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors,
95 const std::map<Txid, bool>& direct_conflicts,
96 const uint256& txid, bool* out_violates_policy);
97 98 /** Check that the feerate of the replacement transaction(s) is higher than the feerate of each
99 * of the transactions in iters_conflicting.
100 * @param[in] iters_conflicting The set of mempool entries.
101 * @returns error message if fees insufficient, otherwise std::nullopt.
102 */
103 std::optional<std::string> PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting,
104 CFeeRate replacement_feerate, const uint256& txid);
105 106 /** The replacement transaction must pay more fees than the original transactions. The additional
107 * fees must pay for the replacement's bandwidth at or above the incremental relay feerate.
108 * @param[in] original_fees Total modified fees of original transaction(s).
109 * @param[in] replacement_fees Total modified fees of replacement transaction(s).
110 * @param[in] replacement_vsize Total virtual size of replacement transaction(s).
111 * @param[in] relay_fee The node's minimum feerate for transaction relay.
112 * @param[in] txid Transaction ID, included in the error message if violation occurs.
113 * @returns error string if fees are insufficient, otherwise std::nullopt.
114 */
115 std::optional<std::string> PaysForRBF(CAmount original_fees,
116 CAmount replacement_fees,
117 size_t replacement_vsize,
118 CFeeRate relay_fee,
119 const uint256& txid);
120 121 /**
122 * The replacement transaction must improve the feerate diagram of the mempool.
123 * @param[in] changeset The changeset containing proposed additions/removals
124 * @returns error type and string if mempool diagram doesn't improve, otherwise std::nullopt.
125 */
126 std::optional<std::pair<DiagramCheckError, std::string>> ImprovesFeerateDiagram(CTxMemPool::ChangeSet& changeset);
127 128 #endif // LIMENKA_POLICY_RBF_H
129