lnwallet+sweep: cap conf target used in fee estimator

This commit is contained in:
yyforyongyu 2024-03-18 10:56:41 +08:00
parent 1fa8ca72ee
commit 0fc5301d12
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868
3 changed files with 35 additions and 7 deletions

View file

@ -17,11 +17,11 @@ import (
)
const (
// maxBlockTarget is the highest number of blocks confirmations that
// MaxBlockTarget is the highest number of blocks confirmations that
// a WebAPIEstimator will cache fees for. This number is chosen
// because it's the highest number of confs bitcoind will return a fee
// estimate for.
maxBlockTarget uint32 = 1008
MaxBlockTarget uint32 = 1008
// minBlockTarget is the lowest number of blocks confirmations that
// a WebAPIEstimator will cache fees for. Requesting an estimate for
@ -463,11 +463,11 @@ func (b *BitcoindEstimator) Stop() error {
func (b *BitcoindEstimator) EstimateFeePerKW(
numBlocks uint32) (SatPerKWeight, error) {
if numBlocks > maxBlockTarget {
if numBlocks > MaxBlockTarget {
log.Debugf("conf target %d exceeds the max value, "+
"use %d instead.", numBlocks, maxBlockTarget,
"use %d instead.", numBlocks, MaxBlockTarget,
)
numBlocks = maxBlockTarget
numBlocks = MaxBlockTarget
}
feeEstimate, err := b.fetchEstimate(numBlocks, b.feeMode)
@ -761,8 +761,8 @@ func NewWebAPIEstimator(api WebAPIFeeSource, noCache bool) *WebAPIEstimator {
func (w *WebAPIEstimator) EstimateFeePerKW(numBlocks uint32) (
SatPerKWeight, error) {
if numBlocks > maxBlockTarget {
numBlocks = maxBlockTarget
if numBlocks > MaxBlockTarget {
numBlocks = MaxBlockTarget
} else if numBlocks < minBlockTarget {
return 0, fmt.Errorf("conf target of %v is too low, minimum "+
"accepted is %v", numBlocks, minBlockTarget)

View file

@ -276,6 +276,16 @@ func (l *LinearFeeFunction) estimateFeeRate(
ConfTarget: confTarget,
}
// If the conf target is greater or equal to the max allowed value
// (1008), we will use the min relay fee instead.
if confTarget >= chainfee.MaxBlockTarget {
minFeeRate := l.estimator.RelayFeePerKW()
log.Debugf("Conf target %v is greater than max block target, "+
"using min relay fee rate %v", confTarget, minFeeRate)
return minFeeRate, nil
}
// endingFeeRate comes from budget/txWeight, which means the returned
// fee rate will always be capped by this value, hence we don't need to
// worry about overpay.

View file

@ -19,6 +19,7 @@ func TestLinearFeeFunctionNew(t *testing.T) {
// Create testing params.
maxFeeRate := chainfee.SatPerKWeight(10000)
estimatedFeeRate := chainfee.SatPerKWeight(500)
minRelayFeeRate := chainfee.SatPerKWeight(100)
confTarget := uint32(6)
// Assert init fee function with zero conf value returns an error.
@ -62,6 +63,23 @@ func TestLinearFeeFunctionNew(t *testing.T) {
rt.ErrorContains(err, "fee rate delta is zero")
rt.Nil(f)
// When the conf target is >= 1008, the min relay fee should be used.
//
// Mock the fee estimator to reutrn the fee rate.
estimator.On("RelayFeePerKW").Return(minRelayFeeRate).Once()
largeConf := uint32(1008)
f, err = NewLinearFeeFunction(maxFeeRate, largeConf, estimator)
rt.NoError(err)
rt.NotNil(f)
// Assert the internal state.
rt.Equal(minRelayFeeRate, f.startingFeeRate)
rt.Equal(maxFeeRate, f.endingFeeRate)
rt.Equal(minRelayFeeRate, f.currentFeeRate)
rt.NotZero(f.deltaFeeRate)
rt.Equal(largeConf, f.width)
// Check a successfully created fee function.
//
// Mock the fee estimator to return the fee rate.