lnwallet: enforce backend node's min relay fee floor
In this commit, we fix an issue where sometimes transactions wouldn't provide enough of a fee to be relayed by the backend node. This would especially cause issues when sweeping outputs after a contract breach, etc. Now, we'll fetch the minimum relay fee from the backend node and ensure it is set as a lower bound if the estimated fee ends up dipping below it.
This commit is contained in:
parent
28b12116e4
commit
3c33a8cb67
@ -95,6 +95,12 @@ type BtcdFeeEstimator struct {
|
|||||||
// actually produce fee estimates.
|
// actually produce fee estimates.
|
||||||
fallBackFeeRate SatPerVByte
|
fallBackFeeRate SatPerVByte
|
||||||
|
|
||||||
|
// minFeeRate is the minimum relay fee, in sat/vbyte, of the backend
|
||||||
|
// node. This will be used as the default fee rate of a transaction when
|
||||||
|
// the estimated fee rate is too low to allow the transaction to
|
||||||
|
// propagate through the network.
|
||||||
|
minFeeRate SatPerVByte
|
||||||
|
|
||||||
btcdConn *rpcclient.Client
|
btcdConn *rpcclient.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +134,22 @@ func (b *BtcdFeeEstimator) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Once the connection to the backend node has been established, we'll
|
||||||
|
// query it for its minimum relay fee.
|
||||||
|
info, err := b.btcdConn.GetInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
relayFee, err := btcutil.NewAmount(info.RelayFee)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fee rate is expressed in sat/KB, so we'll manually convert it to
|
||||||
|
// our desired sat/vbyte rate.
|
||||||
|
b.minFeeRate = SatPerVByte(relayFee / 1000)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,12 +205,20 @@ func (b *BtcdFeeEstimator) fetchEstimatePerVSize(
|
|||||||
// The value returned is expressed in fees per KB, while we want
|
// The value returned is expressed in fees per KB, while we want
|
||||||
// fee-per-byte, so we'll divide by 1000 to map to satoshis-per-byte
|
// fee-per-byte, so we'll divide by 1000 to map to satoshis-per-byte
|
||||||
// before returning the estimate.
|
// before returning the estimate.
|
||||||
satPerByte := satPerKB / 1000
|
satPerByte := SatPerVByte(satPerKB / 1000)
|
||||||
|
|
||||||
|
// Before proceeding, we'll make sure that this fee rate respects the
|
||||||
|
// minimum relay fee set on the backend node.
|
||||||
|
if satPerByte < b.minFeeRate {
|
||||||
|
walletLog.Debugf("Using backend node's minimum relay fee rate "+
|
||||||
|
"of %v sat/vbyte", b.minFeeRate)
|
||||||
|
satPerByte = b.minFeeRate
|
||||||
|
}
|
||||||
|
|
||||||
walletLog.Debugf("Returning %v sat/vbyte for conf target of %v",
|
walletLog.Debugf("Returning %v sat/vbyte for conf target of %v",
|
||||||
int64(satPerByte), confTarget)
|
int64(satPerByte), confTarget)
|
||||||
|
|
||||||
return SatPerVByte(satPerByte), nil
|
return satPerByte, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure that BtcdFeeEstimator implements the
|
// A compile-time assertion to ensure that BtcdFeeEstimator implements the
|
||||||
@ -204,6 +234,12 @@ type BitcoindFeeEstimator struct {
|
|||||||
// actually produce fee estimates.
|
// actually produce fee estimates.
|
||||||
fallBackFeeRate SatPerVByte
|
fallBackFeeRate SatPerVByte
|
||||||
|
|
||||||
|
// minFeeRate is the minimum relay fee, in sat/vbyte, of the backend
|
||||||
|
// node. This will be used as the default fee rate of a transaction when
|
||||||
|
// the estimated fee rate is too low to allow the transaction to
|
||||||
|
// propagate through the network.
|
||||||
|
minFeeRate SatPerVByte
|
||||||
|
|
||||||
bitcoindConn *rpcclient.Client
|
bitcoindConn *rpcclient.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,6 +271,32 @@ func NewBitcoindFeeEstimator(rpcConfig rpcclient.ConnConfig,
|
|||||||
//
|
//
|
||||||
// NOTE: This method is part of the FeeEstimator interface.
|
// NOTE: This method is part of the FeeEstimator interface.
|
||||||
func (b *BitcoindFeeEstimator) Start() error {
|
func (b *BitcoindFeeEstimator) Start() error {
|
||||||
|
// Once the connection to the backend node has been established, we'll
|
||||||
|
// query it for its minimum relay fee. Since the `getinfo` RPC has been
|
||||||
|
// deprecated for `bitcoind`, we'll need to send a `getnetworkinfo`
|
||||||
|
// command as a raw request.
|
||||||
|
resp, err := b.bitcoindConn.RawRequest("getnetworkinfo", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the response to retrieve the relay fee in sat/KB.
|
||||||
|
info := struct {
|
||||||
|
RelayFee float64 `json:"relayfee"`
|
||||||
|
}{}
|
||||||
|
if err := json.Unmarshal(resp, &info); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
relayFee, err := btcutil.NewAmount(info.RelayFee)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fee rate is expressed in sat/KB, so we'll manually convert it to
|
||||||
|
// our desired sat/vbyte rate.
|
||||||
|
b.minFeeRate = SatPerVByte(relayFee / 1000)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,12 +366,20 @@ func (b *BitcoindFeeEstimator) fetchEstimatePerVSize(
|
|||||||
// The value returned is expressed in fees per KB, while we want
|
// The value returned is expressed in fees per KB, while we want
|
||||||
// fee-per-byte, so we'll divide by 1000 to map to satoshis-per-byte
|
// fee-per-byte, so we'll divide by 1000 to map to satoshis-per-byte
|
||||||
// before returning the estimate.
|
// before returning the estimate.
|
||||||
satPerByte := satPerKB / 1000
|
satPerByte := SatPerVByte(satPerKB / 1000)
|
||||||
|
|
||||||
|
// Before proceeding, we'll make sure that this fee rate respects the
|
||||||
|
// minimum relay fee set on the backend node.
|
||||||
|
if satPerByte < b.minFeeRate {
|
||||||
|
walletLog.Debugf("Using backend node's minimum relay fee rate "+
|
||||||
|
"of %v sat/vbyte", b.minFeeRate)
|
||||||
|
satPerByte = b.minFeeRate
|
||||||
|
}
|
||||||
|
|
||||||
walletLog.Debugf("Returning %v sat/vbyte for conf target of %v",
|
walletLog.Debugf("Returning %v sat/vbyte for conf target of %v",
|
||||||
int64(satPerByte), confTarget)
|
int64(satPerByte), confTarget)
|
||||||
|
|
||||||
return SatPerVByte(satPerByte), nil
|
return satPerByte, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure that BitcoindFeeEstimator implements the
|
// A compile-time assertion to ensure that BitcoindFeeEstimator implements the
|
||||||
|
Loading…
Reference in New Issue
Block a user