multi: support config bitcoind fee estimate mode

This commit is contained in:
yyforyongyu 2020-03-13 16:41:08 +08:00
parent 1d2985ce33
commit 97da7b3444
5 changed files with 66 additions and 11 deletions

View File

@ -343,7 +343,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
HTTPPostMode: true, HTTPPostMode: true,
} }
if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest { if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest {
ltndLog.Infof("Initializing bitcoind backed fee estimator") ltndLog.Infof("Initializing bitcoind backed fee estimator in "+
"%s mode", bitcoindMode.EstimateMode)
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
// if we're using bitcoind as a backend, then we can // if we're using bitcoind as a backend, then we can
@ -351,7 +352,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// coded value. // coded value.
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000) fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
cc.feeEstimator, err = chainfee.NewBitcoindEstimator( cc.feeEstimator, err = chainfee.NewBitcoindEstimator(
*rpcConfig, fallBackFeeRate.FeePerKWeight(), *rpcConfig, bitcoindMode.EstimateMode,
fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -360,7 +362,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
return nil, err return nil, err
} }
} else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest { } else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest {
ltndLog.Infof("Initializing litecoind backed fee estimator") ltndLog.Infof("Initializing litecoind backed fee estimator in "+
"%s mode", bitcoindMode.EstimateMode)
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
// if we're using litecoind as a backend, then we can // if we're using litecoind as a backend, then we can
@ -368,7 +371,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// coded value. // coded value.
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000) fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
cc.feeEstimator, err = chainfee.NewBitcoindEstimator( cc.feeEstimator, err = chainfee.NewBitcoindEstimator(
*rpcConfig, fallBackFeeRate.FeePerKWeight(), *rpcConfig, bitcoindMode.EstimateMode,
fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -152,6 +152,11 @@ var (
defaultTorSOCKS = net.JoinHostPort("localhost", strconv.Itoa(defaultTorSOCKSPort)) defaultTorSOCKS = net.JoinHostPort("localhost", strconv.Itoa(defaultTorSOCKSPort))
defaultTorDNS = net.JoinHostPort(defaultTorDNSHost, strconv.Itoa(defaultTorDNSPort)) defaultTorDNS = net.JoinHostPort(defaultTorDNSHost, strconv.Itoa(defaultTorDNSPort))
defaultTorControl = net.JoinHostPort("localhost", strconv.Itoa(defaultTorControlPort)) defaultTorControl = net.JoinHostPort("localhost", strconv.Itoa(defaultTorControlPort))
// bitcoindEsimateModes defines all the legal values for bitcoind's
// estimatesmartfee RPC call.
defaultBitcoindEstimateMode = "CONSERVATIVE"
bitcoindEstimateModes = [2]string{"ECONOMICAL", defaultBitcoindEstimateMode}
) )
type chainConfig struct { type chainConfig struct {
@ -200,6 +205,7 @@ type bitcoindConfig struct {
RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"` RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
ZMQPubRawBlock string `long:"zmqpubrawblock" description:"The address listening for ZMQ connections to deliver raw block notifications"` ZMQPubRawBlock string `long:"zmqpubrawblock" description:"The address listening for ZMQ connections to deliver raw block notifications"`
ZMQPubRawTx string `long:"zmqpubrawtx" description:"The address listening for ZMQ connections to deliver raw transaction notifications"` ZMQPubRawTx string `long:"zmqpubrawtx" description:"The address listening for ZMQ connections to deliver raw transaction notifications"`
EstimateMode string `long:"estimatemode" description:"The fee estimate mode. Must be either ECONOMICAL or CONSERVATIVE."`
} }
type autoPilotConfig struct { type autoPilotConfig struct {
@ -384,8 +390,9 @@ func loadConfig() (*config, error) {
RPCCert: defaultBtcdRPCCertFile, RPCCert: defaultBtcdRPCCertFile,
}, },
BitcoindMode: &bitcoindConfig{ BitcoindMode: &bitcoindConfig{
Dir: defaultBitcoindDir, Dir: defaultBitcoindDir,
RPCHost: defaultRPCHost, RPCHost: defaultRPCHost,
EstimateMode: defaultBitcoindEstimateMode,
}, },
Litecoin: &chainConfig{ Litecoin: &chainConfig{
MinHTLCIn: defaultLitecoinMinHTLCInMSat, MinHTLCIn: defaultLitecoinMinHTLCInMSat,
@ -401,8 +408,9 @@ func loadConfig() (*config, error) {
RPCCert: defaultLtcdRPCCertFile, RPCCert: defaultLtcdRPCCertFile,
}, },
LitecoindMode: &bitcoindConfig{ LitecoindMode: &bitcoindConfig{
Dir: defaultLitecoindDir, Dir: defaultLitecoindDir,
RPCHost: defaultRPCHost, RPCHost: defaultRPCHost,
EstimateMode: defaultBitcoindEstimateMode,
}, },
UnsafeDisconnect: true, UnsafeDisconnect: true,
MaxPendingChannels: DefaultMaxPendingChannels, MaxPendingChannels: DefaultMaxPendingChannels,
@ -1211,6 +1219,15 @@ func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
} }
} }
// Ensure that if the estimate mode is set, that it is a legal
// value.
if conf.EstimateMode != "" {
err := checkEstimateMode(conf.EstimateMode)
if err != nil {
return err
}
}
// If all of RPCUser, RPCPass, ZMQBlockHost, and ZMQTxHost are // If all of RPCUser, RPCPass, ZMQBlockHost, and ZMQTxHost are
// set, we assume those parameters are good to use. // set, we assume those parameters are good to use.
if conf.RPCUser != "" && conf.RPCPass != "" && if conf.RPCUser != "" && conf.RPCPass != "" &&
@ -1448,6 +1465,18 @@ func checkZMQOptions(zmqBlockHost, zmqTxHost string) error {
return nil return nil
} }
// checkEstimateMode ensures that the provided estimate mode is legal.
func checkEstimateMode(estimateMode string) error {
for _, mode := range bitcoindEstimateModes {
if estimateMode == mode {
return nil
}
}
return fmt.Errorf("estimatemode must be one of the following: %v",
bitcoindEstimateModes[:])
}
// normalizeNetwork returns the common name of a network type used to create // normalizeNetwork returns the common name of a network type used to create
// file paths. This allows differently versioned networks to use the same path. // file paths. This allows differently versioned networks to use the same path.
func normalizeNetwork(network string) string { func normalizeNetwork(network string) string {

View File

@ -208,6 +208,7 @@ bitcoind:
--bitcoind.rpcpass= Password for RPC connections --bitcoind.rpcpass= Password for RPC connections
--bitcoind.zmqpubrawblock= The address listening for ZMQ connections to deliver raw block notifications --bitcoind.zmqpubrawblock= The address listening for ZMQ connections to deliver raw block notifications
--bitcoind.zmqpubrawtx= The address listening for ZMQ connections to deliver raw transaction notifications --bitcoind.zmqpubrawtx= The address listening for ZMQ connections to deliver raw transaction notifications
--bitcoind.estimatemode= The fee estimate mode. Must be either "ECONOMICAL" or "CONSERVATIVE". (default: CONSERVATIVE)
``` ```
## Using btcd ## Using btcd
@ -367,6 +368,9 @@ lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --bitcoin.node=bitcoin
the default `bitcoind` settings, having more than one instance of `lnd`, or the default `bitcoind` settings, having more than one instance of `lnd`, or
`lnd` plus any application that consumes the RPC could cause `lnd` to miss `lnd` plus any application that consumes the RPC could cause `lnd` to miss
crucial updates from the backend. crucial updates from the backend.
- The default fee estimate mode in `bitcoind` is CONSERVATIVE. You can set
`bitcoind.estimatemode=ECONOMICAL` to change it into ECONOMICAL. Futhermore,
if you start `bitcoind` in `regtest`, this configuration won't take any effect.
# Creating a wallet # Creating a wallet

View File

@ -286,6 +286,11 @@ type BitcoindEstimator struct {
// through the network. // through the network.
minFeePerKW SatPerKWeight minFeePerKW SatPerKWeight
// feeMode is the estimate_mode to use when calling "estimatesmartfee".
// It can be either "ECONOMICAL" or "CONSERVATIVE", and it's default
// to "CONSERVATIVE".
feeMode string
bitcoindConn *rpcclient.Client bitcoindConn *rpcclient.Client
} }
@ -294,7 +299,7 @@ type BitcoindEstimator struct {
// bitcoind node, and also a fall back fee rate. The fallback fee rate is used // bitcoind node, and also a fall back fee rate. The fallback fee rate is used
// in the occasion that the estimator has insufficient data, or returns zero // in the occasion that the estimator has insufficient data, or returns zero
// for a fee estimate. // for a fee estimate.
func NewBitcoindEstimator(rpcConfig rpcclient.ConnConfig, func NewBitcoindEstimator(rpcConfig rpcclient.ConnConfig, feeMode string,
fallBackFeeRate SatPerKWeight) (*BitcoindEstimator, error) { fallBackFeeRate SatPerKWeight) (*BitcoindEstimator, error) {
rpcConfig.DisableConnectOnNew = true rpcConfig.DisableConnectOnNew = true
@ -309,6 +314,7 @@ func NewBitcoindEstimator(rpcConfig rpcclient.ConnConfig,
return &BitcoindEstimator{ return &BitcoindEstimator{
fallbackFeePerKW: fallBackFeeRate, fallbackFeePerKW: fallBackFeeRate,
bitcoindConn: chainConn, bitcoindConn: chainConn,
feeMode: feeMode,
}, nil }, nil
} }
@ -403,9 +409,15 @@ func (b *BitcoindEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, err
if err != nil { if err != nil {
return 0, err return 0, err
} }
// TODO: Allow selection of economical/conservative modifiers.
// The mode must be either ECONOMICAL or CONSERVATIVE.
mode, err := json.Marshal(b.feeMode)
if err != nil {
return 0, err
}
resp, err := b.bitcoindConn.RawRequest( resp, err := b.bitcoindConn.RawRequest(
"estimatesmartfee", []json.RawMessage{target}, "estimatesmartfee", []json.RawMessage{target, mode},
) )
if err != nil { if err != nil {
return 0, err return 0, err

View File

@ -230,6 +230,9 @@ bitcoin.node=btcd
; bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 ; bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
; bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 ; bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
; Fee estimate mode for bitcoind. It must be either "ECONOMICAL" or "CONSERVATIVE".
; If unset, the default value is "CONSERVATIVE".
; bitcoind.estimatemode=CONSERVATIVE
[neutrino] [neutrino]
@ -311,6 +314,9 @@ litecoin.node=ltcd
; litecoind.zmqpubrawblock=tcp://127.0.0.1:28332 ; litecoind.zmqpubrawblock=tcp://127.0.0.1:28332
; litecoind.zmqpubrawtx=tcp://127.0.0.1:28333 ; litecoind.zmqpubrawtx=tcp://127.0.0.1:28333
; Fee estimate mode for litecoind. It must be either "ECONOMICAL" or "CONSERVATIVE".
; If unset, the default value is "CONSERVATIVE".
; litecoind.estimatemode=CONSERVATIVE
[autopilot] [autopilot]