Skip to content

Commit c57889d

Browse files
glozowmurchandamus
authored andcommitted
[node] interface to get bump fees
1 parent c24851b commit c57889d

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/interfaces/chain.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,43 @@ class Chain
216216
//! Calculate mempool ancestor and descendant counts for the given transaction.
217217
virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0;
218218

219+
//! For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified
220+
// feerate, including bumping its ancestors. For example, if the target feerate is 10sat/vbyte
221+
// and this outpoint refers to a mempool transaction at 3sat/vbyte, the bump fee includes the
222+
// cost to bump the mempool transaction to 10sat/vbyte (i.e. 7 * mempooltx.vsize). If that
223+
// transaction also has, say, an unconfirmed parent with a feerate of 1sat/vbyte, the bump fee
224+
// includes the cost to bump the parent (i.e. 9 * parentmempooltx.vsize).
225+
//
226+
// If the outpoint comes from an unconfirmed transaction that is already above the target
227+
// feerate or bumped by its descendant(s) already, it does not need to be bumped. Its bump fee
228+
// is 0. Likewise, if any of the transaction's ancestors are already bumped by a transaction
229+
// in our mempool, they are not included in the transaction's bump fee.
230+
//
231+
// Also supported is bump-fee calculation in the case of replacements. If an outpoint
232+
// conflicts with another transaction in the mempool, it is assumed that the goal is to replace
233+
// that transaction. As such, the calculation will exclude the to-be-replaced transaction, but
234+
// will include the fee-bumping cost. If bump fees of descendants of the to-be-replaced
235+
// transaction are requested, the value will be 0. Fee-related RBF rules are not included as
236+
// they are logically distinct.
237+
//
238+
// Any outpoints that are otherwise unavailable from the mempool (e.g. UTXOs from confirmed
239+
// transactions or transactions not yet broadcast by the wallet) are given a bump fee of 0.
240+
//
241+
// If multiple outpoints come from the same transaction (which would be very rare because
242+
// it means that one transaction has multiple change outputs or paid the same wallet using multiple
243+
// outputs in the same transaction) or have shared ancestry, the bump fees are calculated
244+
// independently, i.e. as if only one of them is spent. This may result in double-fee-bumping. This
245+
// caveat can be rectified per use of the sister-function CalculateCombinedBumpFee(…).
246+
virtual std::map<COutPoint, CAmount> CalculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;
247+
248+
//! Calculate the combined bump fee for an input set per the same strategy
249+
// as in CalculateIndividualBumpFees(…).
250+
// Unlike CalculateIndividualBumpFees(…), this does not return individual
251+
// bump fees per outpoint, but a single bump fee for the shared ancestry.
252+
// The combined bump fee may be used to correct overestimation due to
253+
// shared ancestry by multiple UTXOs after coin selection.
254+
virtual std::optional<CAmount> CalculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;
255+
219256
//! Get the node's package limits.
220257
//! Currently only returns the ancestor and descendant count limits, but could be enhanced to
221258
//! return more policy settings.

src/node/interfaces.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <node/coin.h>
2929
#include <node/context.h>
3030
#include <node/interface_ui.h>
31+
#include <node/mini_miner.h>
3132
#include <node/transaction.h>
3233
#include <policy/feerate.h>
3334
#include <policy/fees.h>
@@ -665,6 +666,26 @@ class ChainImpl : public Chain
665666
if (!m_node.mempool) return;
666667
m_node.mempool->GetTransactionAncestry(txid, ancestors, descendants, ancestorsize, ancestorfees);
667668
}
669+
670+
std::map<COutPoint, CAmount> CalculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
671+
{
672+
if (!m_node.mempool) {
673+
std::map<COutPoint, CAmount> bump_fees;
674+
for (const auto& outpoint : outpoints) {
675+
bump_fees.emplace(std::make_pair(outpoint, 0));
676+
}
677+
return bump_fees;
678+
}
679+
return MiniMiner(*m_node.mempool, outpoints).CalculateBumpFees(target_feerate);
680+
}
681+
682+
std::optional<CAmount> CalculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
683+
{
684+
if (!m_node.mempool) {
685+
return 0;
686+
}
687+
return MiniMiner(*m_node.mempool, outpoints).CalculateTotalBumpFees(target_feerate);
688+
}
668689
void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) override
669690
{
670691
const CTxMemPool::Limits default_limits{};

0 commit comments

Comments
 (0)