Difference between long-term-fee-rate and discard fee-rate
Difference between long-term-fee-rate and discard fee-rate
Loading saved threads...
yancy · External communityPost link
External question — Bitcoin Stack Exchange
Author: yancy
Original post: https://bitcoin.stackexchange.com/questions/130861
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
In the bitcoin-core codebase, it seems that discard fee-rate and long-term fee-rate are used interchangeably when computing the cost of change. Consider the following code
excerpts:
cost_of_change = discard_feerate.GetFee(change_spend_size) + effective_feerate.GetFee(change_output_size);
ref:
https://github.com/bitcoin/bitcoin/blob/2990bd773551c835ab0b6b59d85730adab2fd428/src/wallet/spend.cpp#L1182
and also:
cost_of_change = effective_feerate.GetFee(change_output_size) + long_term_feerate.GetFee(change_spend_size);
ref:
https://github.com/bitcoin/bitcoin/blob/2990bd773551c835ab0b6b59d85730adab2fd428/src/wallet/test/fuzz/coinselection.cpp#L96
In both of these snippets, the cost_of_change is being computed, however, one uses the long-term fee-rate while the other uses the discard fee-rate. Are these two terms actually distinct or can they be used interchangeably?
To my knowledge, cost_of_change should be calculated using the discard fee_rate, and the long_term fee_rate is useful as a parameter within the selection algorithm for knowing if the current fee-rate is cheap or expensive. And yet, I see these two code pieces which seem to conflate the two.
Quote
Report
MillionMiner · External communityPost link
External answer — Bitcoin Stack Exchange
Author: MillionMiner
Original post: https://bitcoin.stackexchange.com/a/130862
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
The discard feerate and the long-term feerate are both estimates of what it'll cost to spend a UTXO in the future, and since Bitcoin Core v24 both default to 10 sat/vB, which is precisely why they get confused. The difference is which UTXO each one prices, and at which stage of building the transaction. The discard feerate governs a single change output; the long-term feerate governs input selection.
The discard feerate (-discardfee, DEFAULT_DISCARD_FEE = 10 sat/vB, added in PR #10817) answers one question: once a selection leaves some leftover value, is that leftover worth turning into change, or should it just go to the fee? A change output costs you twice, once to create now and again to spend later, and the discard rate prices that future spend. If the change would be dust at that rate, meaning it would cost more to redeem than it's worth, Core drops it into the fee rather than creating an output you'd never economically spend. In Branch and Bound this is the cost_of_change window, discard_feerate.GetFee(change_spend_size) + effective_feerate.GetFee(change_output_size), within which giving the excess to fee beats making change. Two bounds apply from the option's own help text: the effective rate is floored by the dust relay fee and capped by the longest-target fee estimate, so a very high -discardfee can't discard arbitrarily large change.
The long-term feerate (-consolidatefeerate, default 10 sat/vB) lives only inside the waste metric that scores candidate input sets, and it represents the feerate at which you'd be content to consolidate UTXOs. Waste includes, per input, input_size × (current_feerate − long_term_feerate), and the sign of that difference is the entire mechanism. When the current feerate sits above the long-term rate, each extra input adds positive waste, so the wallet prefers fewer inputs and avoids overpaying to move coins while fees are high. When the current feerate sits below it, each extra input adds negative waste, so the wallet prefers more inputs and consolidates cheaply now, since spending them later is expected to cost more. It never changes the fee you actually pay on this transaction; it only decides which valid input set wins. Before PR #22009 (v24) this was the dynamic 1008-block estimateSmartFee value, swapped for a static configurable rate because the week-out estimate often sat near the floor and skewed selection toward constant consolidation.
So both encode "what will it cost to spend a coin later," both live in the coin-selection and change machinery, and both default to 10 sat/vB, but they act on different coins at different moments. The discard feerate acts on the change output and whether it survives, applied after a selection is made to trim uneconomical change. The long-term feerate acts on the inputs and how many to pick, applied during selection to compare whole input sets.
Quote
Report
Murch · External communityPost link
External answer — Bitcoin Stack Exchange
Author: Murch
Original post: https://bitcoin.stackexchange.com/a/130874
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
The long-term feerate estimate and discard feerate are not interchangeable. The discard feerate is used to calculate a node’s dust limits for various output types. The long-term feerate is used to configure a node’s border between consolidatory and thrifty coin selection behavior. You are right that the calculation of
m_cost_of_change
should use the discard feerate to be consistent.
Regarding the code snippet from the fuzz test: CoinGrinder doesn’t use
coin_params.m_cost_of_change
and the comparison of selection results from CoinGrinder, SRD, and Knapsack does not need it either as only the weight of the selections is relevant. So,
line 96
in that fuzz test is both incorrect
and
dead code. It should be removed. The PR author¹ should be ashamed!
¹ Who is this Murch character anyway?
Quote
Report
Post Reply
Quoted from Forex.com.bd-Editorial External answer — Bitcoin Stack Exchange Author: Murch Source score (net votes, not local likes): 1 Original post: https://bitcoin.stackexchange.com/a/130874 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. The long-term feerate estimate and discard feerate are not interchangeable. The discard feerate is used to calculate a node’s dust limits for various output types. The long-term feerate is used to configure a node’s border between consolidatory and thrifty coin selection behavior. You are right that the calculation of m_cost_of_change should use the discard feerate to be consistent. Regarding the code snippet from the fuzz test: CoinGrinder doesn’t use coin_params.m_cost_of_change and the comparison of selection results from CoinGrinder, SRD, and Knapsack does not need it either as only the weight of the selections is relevant. So, line 96 in that fuzz test is both incorrect and dead code. It should be removed. The PR author¹ should be ashamed! ¹ Who is this Murch character anyway?
Checking account access…