diff options
author | Greg Sanders <gsanders87@gmail.com> | 2024-01-19 15:20:33 -0500 |
---|---|---|
committer | Greg Sanders <gsanders87@gmail.com> | 2024-03-18 10:32:00 -0400 |
commit | 2079b80854e2595f6f696e7c13a56c7f2a7da9f4 (patch) | |
tree | ab42fae71ea1aa30bccdc9598aa02284a3f93d98 /src/policy | |
parent | 66d966dcfaad3638f84654e710f403cb0a0a2ac7 (diff) | |
download | bitcoin-2079b80854e2595f6f696e7c13a56c7f2a7da9f4.tar.xz |
Implement ImprovesFeerateDiagram
This new function takes the populated sets of
direct and all conflicts computed in the current
mempool, assuming the replacements are a single
chunk, and computes a diagram check.
The diagram check only works against cluster
sizes of 2 or less, and fails if it encounters
a different topology.
Co-authored-by: Suhas Daftuar <sdaftuar@chaincode.com>
Diffstat (limited to 'src/policy')
-rw-r--r-- | src/policy/rbf.cpp | 23 | ||||
-rw-r--r-- | src/policy/rbf.h | 26 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp index f0830d8f22..a2c6990657 100644 --- a/src/policy/rbf.cpp +++ b/src/policy/rbf.cpp @@ -19,6 +19,8 @@ #include <limits> #include <vector> +#include <compare> + RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool) { AssertLockHeld(pool.cs); @@ -181,3 +183,24 @@ std::optional<std::string> PaysForRBF(CAmount original_fees, } return std::nullopt; } + +std::optional<std::pair<DiagramCheckError, std::string>> ImprovesFeerateDiagram(CTxMemPool& pool, + const CTxMemPool::setEntries& direct_conflicts, + const CTxMemPool::setEntries& all_conflicts, + CAmount replacement_fees, + int64_t replacement_vsize) +{ + // Require that the replacement strictly improve the mempool's feerate diagram. + std::vector<FeeFrac> old_diagram, new_diagram; + + const auto diagram_results{pool.CalculateFeerateDiagramsForRBF(replacement_fees, replacement_vsize, direct_conflicts, all_conflicts)}; + + if (!diagram_results.has_value()) { + return std::make_pair(DiagramCheckError::UNCALCULABLE, util::ErrorString(diagram_results).original); + } + + if (!std::is_gt(CompareFeerateDiagram(diagram_results.value().second, diagram_results.value().first))) { + return std::make_pair(DiagramCheckError::FAILURE, "insufficient feerate: does not improve feerate diagram"); + } + return std::nullopt; +} diff --git a/src/policy/rbf.h b/src/policy/rbf.h index 5a33ed64a3..252fbec8e3 100644 --- a/src/policy/rbf.h +++ b/src/policy/rbf.h @@ -9,7 +9,9 @@ #include <primitives/transaction.h> #include <threadsafety.h> #include <txmempool.h> +#include <util/feefrac.h> +#include <compare> #include <cstddef> #include <cstdint> #include <optional> @@ -33,6 +35,13 @@ enum class RBFTransactionState { FINAL, }; +enum class DiagramCheckError { + /** Unable to calculate due to topology or other reason */ + UNCALCULABLE, + /** New diagram wasn't strictly superior */ + FAILURE, +}; + /** * Determine whether an unconfirmed transaction is signaling opt-in to RBF * according to BIP 125 @@ -106,4 +115,21 @@ std::optional<std::string> PaysForRBF(CAmount original_fees, CFeeRate relay_fee, const uint256& txid); +/** + * The replacement transaction must improve the feerate diagram of the mempool. + * @param[in] pool The mempool. + * @param[in] direct_conflicts Set of in-mempool txids corresponding to the direct conflicts i.e. + * input double-spends with the proposed transaction + * @param[in] all_conflicts Set of mempool entries corresponding to all transactions to be evicted + * @param[in] replacement_fees Fees of proposed replacement package + * @param[in] replacement_vsize Size of proposed replacement package + * @returns error type and string if mempool diagram doesn't improve, otherwise std::nullopt. + */ +std::optional<std::pair<DiagramCheckError, std::string>> ImprovesFeerateDiagram(CTxMemPool& pool, + const CTxMemPool::setEntries& direct_conflicts, + const CTxMemPool::setEntries& all_conflicts, + CAmount replacement_fees, + int64_t replacement_vsize) + EXCLUSIVE_LOCKS_REQUIRED(pool.cs); + #endif // BITCOIN_POLICY_RBF_H |