chainfee: fetch new relay fee from bitcoind
This commit adds a fetchMinMempoolFee function to the BitcoindEstimator that fetches the current min mempool fee from the bitcoind backend. The commit then also updates the BitcoindEstimator to use a minFeeManager for it's minFeeManager member and uses the fetchMinMempoolFee function to initialise this.
This commit is contained in:
2 files changed
+39
-32
No files matched your search
@@ -280,11 +280,11 @@ type BitcoindEstimator struct {
|
|||||||
// produce fee estimates.
|
// produce fee estimates.
|
||||||
fallbackFeePerKW SatPerKWeight
|
fallbackFeePerKW SatPerKWeight
|
||||||
|
|
||||||
// minFeePerKW is the minimum fee, in sat/kw, that we should enforce.
|
// minFeeManager is used to keep track of the minimum fee, in sat/kw,
|
||||||
// This will be used as the default fee rate for a transaction when the
|
// that we should enforce. This will be used as the default fee rate
|
||||||
// estimated fee rate is too low to allow the transaction to propagate
|
// for a transaction when the estimated fee rate is too low to allow
|
||||||
// through the network.
|
// the transaction to propagate through the network.
|
||||||
minFeePerKW SatPerKWeight
|
minFeeManager *minFeeManager
|
||||||
|
|
||||||
// feeMode is the estimate_mode to use when calling "estimatesmartfee".
|
// feeMode is the estimate_mode to use when calling "estimatesmartfee".
|
||||||
// It can be either "ECONOMICAL" or "CONSERVATIVE", and it's default
|
// It can be either "ECONOMICAL" or "CONSERVATIVE", and it's default
|
||||||
@@ -324,43 +324,47 @@ func NewBitcoindEstimator(rpcConfig rpcclient.ConnConfig, feeMode string,
|
|||||||
// NOTE: This method is part of the Estimator interface.
|
// NOTE: This method is part of the Estimator interface.
|
||||||
func (b *BitcoindEstimator) Start() error {
|
func (b *BitcoindEstimator) Start() error {
|
||||||
// Once the connection to the backend node has been established, we'll
|
// 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
|
// initialise the minimum relay fee manager which will query
|
||||||
// deprecated for `bitcoind`, we'll need to send a `getnetworkinfo`
|
// the backend node for its minimum mempool fee.
|
||||||
// command as a raw request.
|
relayFeeManager, err := newMinFeeManager(
|
||||||
resp, err := b.bitcoindConn.RawRequest("getnetworkinfo", nil)
|
defaultUpdateInterval,
|
||||||
|
b.fetchMinMempoolFee,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
b.minFeeManager = relayFeeManager
|
||||||
|
|
||||||
// Parse the response to retrieve the relay fee in sat/KB.
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetchMinMempoolFee is used to fetch the minimum fee that the backend node
|
||||||
|
// requires for a tx to enter its mempool. The returned fee will be the
|
||||||
|
// maximum of the minimum relay fee and the minimum mempool fee.
|
||||||
|
func (b *BitcoindEstimator) fetchMinMempoolFee() (SatPerKWeight, error) {
|
||||||
|
resp, err := b.bitcoindConn.RawRequest("getmempoolinfo", nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the response to retrieve the min mempool fee in sat/KB.
|
||||||
|
// mempoolminfee is the maximum of minrelaytxfee and
|
||||||
|
// minimum mempool fee
|
||||||
info := struct {
|
info := struct {
|
||||||
RelayFee float64 `json:"relayfee"`
|
MempoolMinFee float64 `json:"mempoolminfee"`
|
||||||
}{}
|
}{}
|
||||||
if err := json.Unmarshal(resp, &info); err != nil {
|
if err := json.Unmarshal(resp, &info); err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
relayFee, err := btcutil.NewAmount(info.RelayFee)
|
minMempoolFee, err := btcutil.NewAmount(info.MempoolMinFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fee rate is expressed in sat/kb, so we'll manually convert it to
|
// The fee rate is expressed in sat/kb, so we'll manually convert it to
|
||||||
// our desired sat/kw rate.
|
// our desired sat/kw rate.
|
||||||
minRelayFeePerKw := SatPerKVByte(relayFee).FeePerKWeight()
|
return SatPerKVByte(minMempoolFee).FeePerKWeight(), nil
|
||||||
|
|
||||||
// By default, we'll use the backend node's minimum relay fee as the
|
|
||||||
// minimum fee rate we'll propose for transacations. However, if this
|
|
||||||
// happens to be lower than our fee floor, we'll enforce that instead.
|
|
||||||
b.minFeePerKW = minRelayFeePerKw
|
|
||||||
if b.minFeePerKW < FeePerKwFloor {
|
|
||||||
b.minFeePerKW = FeePerKwFloor
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("Using minimum fee rate of %v sat/kw",
|
|
||||||
int64(b.minFeePerKW))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops any spawned goroutines and cleans up the resources used
|
// Stop stops any spawned goroutines and cleans up the resources used
|
||||||
@@ -406,7 +410,7 @@ func (b *BitcoindEstimator) EstimateFeePerKW(
|
|||||||
//
|
//
|
||||||
// NOTE: This method is part of the Estimator interface.
|
// NOTE: This method is part of the Estimator interface.
|
||||||
func (b *BitcoindEstimator) RelayFeePerKW() SatPerKWeight {
|
func (b *BitcoindEstimator) RelayFeePerKW() SatPerKWeight {
|
||||||
return b.minFeePerKW
|
return b.minFeeManager.fetchMinFee()
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchEstimate returns a fee estimate for a transaction to be confirmed in
|
// fetchEstimate returns a fee estimate for a transaction to be confirmed in
|
||||||
@@ -453,12 +457,13 @@ func (b *BitcoindEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, err
|
|||||||
satPerKw := SatPerKVByte(satPerKB).FeePerKWeight()
|
satPerKw := SatPerKVByte(satPerKB).FeePerKWeight()
|
||||||
|
|
||||||
// Finally, we'll enforce our fee floor.
|
// Finally, we'll enforce our fee floor.
|
||||||
if satPerKw < b.minFeePerKW {
|
minRelayFee := b.minFeeManager.fetchMinFee()
|
||||||
|
if satPerKw < minRelayFee {
|
||||||
log.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
log.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
||||||
"using fee floor of %v sat/kw instead", satPerKw,
|
"using fee floor of %v sat/kw instead", satPerKw,
|
||||||
b.minFeePerKW)
|
minRelayFee)
|
||||||
|
|
||||||
satPerKw = b.minFeePerKW
|
satPerKw = minRelayFee
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Returning %v sat/kw for conf target of %v",
|
log.Debugf("Returning %v sat/kw for conf target of %v",
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultUpdateInterval = 10 * time.Minute
|
||||||
|
|
||||||
// minFeeManager is used to store and update the minimum fee that is required
|
// minFeeManager is used to store and update the minimum fee that is required
|
||||||
// by a transaction to be accepted to the mempool. The minFeeManager ensures
|
// by a transaction to be accepted to the mempool. The minFeeManager ensures
|
||||||
// that the backend used to fetch the fee is not queried too regularly.
|
// that the backend used to fetch the fee is not queried too regularly.
|
||||||
|
|||||||
Reference in new issue
Block a user