aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/coinselection.h
diff options
context:
space:
mode:
authorMurch <murch@murch.one>2022-11-02 15:20:16 -0400
committerMurch <murch@murch.one>2023-09-13 14:33:58 -0400
commit2e35e944dab09eff30952233f8dfc0b12c4553d5 (patch)
tree29e769b0ee96b8dc8ebd578876577c9bf1200578 /src/wallet/coinselection.h
parent3e3e05241128f68cf12f73ee06ff997395643885 (diff)
downloadbitcoin-2e35e944dab09eff30952233f8dfc0b12c4553d5.tar.xz
Bump unconfirmed parent txs to target feerate
When a transaction uses an unconfirmed input, preceding this commit it would not consider the feerate of the parent transaction. Given a parent transaction with a lower ancestor feerate, this resulted in the new transaction's ancestor feerate undershooting the target feerate. This commit changes how we calculate the effective value of unconfirmed UTXOs. The effective value of unconfirmed UTXOs is decreased by the fee necessary to bump its ancestry to the target feerate. This also impacts the calculation of the waste metric: since the estimate for the current fee is increased by the bump fees, unconfirmed UTXOs current fees appear less favorable compared to their unchanged long term fees. This has one caveat: if multiple UTXOs have overlapping ancestries, each of their individual estimates will account for bumping all ancestors.
Diffstat (limited to 'src/wallet/coinselection.h')
-rw-r--r--src/wallet/coinselection.h21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index fd75ad67a0..dd1a7bd66a 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -17,6 +17,7 @@
#include <optional>
+
namespace wallet {
//! lower bound for randomly-chosen target change amount
static constexpr CAmount CHANGE_LOWER{50000};
@@ -26,10 +27,10 @@ static constexpr CAmount CHANGE_UPPER{1000000};
/** A UTXO under consideration for use in funding a new transaction. */
struct COutput {
private:
- /** The output's value minus fees required to spend it.*/
+ /** The output's value minus fees required to spend it and bump its unconfirmed ancestors to the target feerate. */
std::optional<CAmount> effective_value;
- /** The fee required to spend this output at the transaction's target feerate. */
+ /** The fee required to spend this output at the transaction's target feerate and to bump its unconfirmed ancestors to the target feerate. */
std::optional<CAmount> fee;
public:
@@ -71,6 +72,9 @@ public:
/** The fee required to spend this output at the consolidation feerate. */
CAmount long_term_fee{0};
+ /** The fee necessary to bump this UTXO's ancestor transactions to the target feerate */
+ CAmount ancestor_bump_fees{0};
+
COutput(const COutPoint& outpoint, const CTxOut& txout, int depth, int input_bytes, bool spendable, bool solvable, bool safe, int64_t time, bool from_me, const std::optional<CFeeRate> feerate = std::nullopt)
: outpoint{outpoint},
txout{txout},
@@ -83,6 +87,7 @@ public:
from_me{from_me}
{
if (feerate) {
+ // base fee without considering potential unconfirmed ancestors
fee = input_bytes < 0 ? 0 : feerate.value().GetFee(input_bytes);
effective_value = txout.nValue - fee.value();
}
@@ -104,6 +109,16 @@ public:
return outpoint < rhs.outpoint;
}
+ void ApplyBumpFee(CAmount bump_fee)
+ {
+ assert(bump_fee >= 0);
+ ancestor_bump_fees = bump_fee;
+ assert(fee);
+ *fee += bump_fee;
+ // Note: assert(effective_value - bump_fee == nValue - fee.value());
+ effective_value = txout.nValue - fee.value();
+ }
+
CAmount GetFee() const
{
assert(fee.has_value());
@@ -355,6 +370,8 @@ public:
[[nodiscard]] CAmount GetSelectedEffectiveValue() const;
+ [[nodiscard]] CAmount GetTotalBumpFees() const;
+
void Clear();
void AddInput(const OutputGroup& group);