From 95ecf1abe929ff804efe7c25970e28a24cfea750 Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Fri, 2 Feb 2024 12:40:43 +0100 Subject: [PATCH] make mempool fee estimation optional --- chain/default_fee_estimator.go | 22 ++++++++++++++++++++ chain/fee_estimator.go | 20 ++++++++++++++++-- interceptor/intercept_handler.go | 34 +++++++++++-------------------- lsps2/intercept_handler.go | 35 +++++++++++--------------------- main.go | 29 ++++++++++++++++---------- mempool/mempool_client.go | 2 +- 6 files changed, 83 insertions(+), 59 deletions(-) create mode 100644 chain/default_fee_estimator.go diff --git a/chain/default_fee_estimator.go b/chain/default_fee_estimator.go new file mode 100644 index 0000000..07ab7d9 --- /dev/null +++ b/chain/default_fee_estimator.go @@ -0,0 +1,22 @@ +package chain + +import "context" + +type DefaultFeeEstimator struct { + targetConf uint32 +} + +func NewDefaultFeeEstimator(targetConf uint32) *DefaultFeeEstimator { + return &DefaultFeeEstimator{ + targetConf: targetConf, + } +} + +func (e *DefaultFeeEstimator) EstimateFeeRate( + context.Context, + FeeStrategy, +) (*FeeEstimation, error) { + return &FeeEstimation{ + TargetConf: &e.targetConf, + }, nil +} diff --git a/chain/fee_estimator.go b/chain/fee_estimator.go index 8560a68..db50840 100644 --- a/chain/fee_estimator.go +++ b/chain/fee_estimator.go @@ -1,6 +1,9 @@ package chain -import "context" +import ( + "context" + "fmt" +) type FeeStrategy int @@ -13,7 +16,20 @@ const ( ) type FeeEstimation struct { - SatPerVByte float64 + SatPerVByte *float64 + TargetConf *uint32 +} + +func (f *FeeEstimation) String() string { + feeStr := "" + confStr := "" + if f.SatPerVByte != nil { + feeStr = fmt.Sprintf("%.5f", *f.SatPerVByte) + } + if f.TargetConf != nil { + confStr = fmt.Sprintf("%v", *f.TargetConf) + } + return fmt.Sprintf("satPerVbyte %s, targetConf %s", feeStr, confStr) } type FeeEstimator interface { diff --git a/interceptor/intercept_handler.go b/interceptor/intercept_handler.go index 08120f4..c837c3f 100644 --- a/interceptor/intercept_handler.go +++ b/interceptor/intercept_handler.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/hex" - "fmt" "log" "math/big" "time" @@ -354,32 +353,23 @@ func (i *Interceptor) openChannel(paymentHash, destination []byte, incomingAmoun capacity++ } - var targetConf *uint32 - confStr := "" - var feeEstimation *float64 - feeStr := "" - if i.feeEstimator != nil { - fee, err := i.feeEstimator.EstimateFeeRate( - context.Background(), - i.feeStrategy, - ) - if err == nil { - feeEstimation = &fee.SatPerVByte - feeStr = fmt.Sprintf("%.5f", *feeEstimation) - } else { - log.Printf("Error estimating chain fee, fallback to target conf: %v", err) - targetConf = &i.config.TargetConf - confStr = fmt.Sprintf("%v", *targetConf) + fee, err := i.feeEstimator.EstimateFeeRate( + context.Background(), + i.feeStrategy, + ) + if err != nil || fee == nil { + log.Printf("Error estimating chain fee, fallback to target conf: %v", err) + fee = &chain.FeeEstimation{ + TargetConf: &i.config.TargetConf, } } log.Printf( - "Opening zero conf channel. Paymenthash: %x, Destination: %x, capacity: %v, fee: %s, targetConf: %s", + "Opening zero conf channel. Paymenthash: %x, Destination: %x, capacity: %v, fee: %s", paymentHash, destination, capacity, - feeStr, - confStr, + fee.String(), ) channelPoint, err := i.client.OpenChannel(&lightning.OpenChannelRequest{ Destination: destination, @@ -387,8 +377,8 @@ func (i *Interceptor) openChannel(paymentHash, destination []byte, incomingAmoun MinConfs: i.config.MinConfs, IsPrivate: true, IsZeroConf: true, - FeeSatPerVByte: feeEstimation, - TargetConf: targetConf, + FeeSatPerVByte: fee.SatPerVByte, + TargetConf: fee.TargetConf, }) if err != nil { log.Printf("paymenthash %x, client.OpenChannelSync(%x, %v) error: %v", paymentHash, destination, capacity, err) diff --git a/lsps2/intercept_handler.go b/lsps2/intercept_handler.go index 6843397..a9e1eec 100644 --- a/lsps2/intercept_handler.go +++ b/lsps2/intercept_handler.go @@ -3,7 +3,6 @@ package lsps2 import ( "context" "encoding/hex" - "fmt" "log" "math" "strings" @@ -414,23 +413,14 @@ func (i *Interceptor) ensureChannelOpen(payment *paymentState) { return } - var targetConf *uint32 - confStr := "" - var feeEstimation *float64 - feeStr := "" - if i.feeEstimator != nil { - fee, err := i.feeEstimator.EstimateFeeRate( - context.Background(), - i.config.FeeStrategy, - ) - if err == nil { - feeEstimation = &fee.SatPerVByte - feeStr = fmt.Sprintf("%.5f", *feeEstimation) - } else { - log.Printf("Error estimating chain fee, fallback to target "+ - "conf: %v", err) - targetConf = &i.config.TargetConf - confStr = fmt.Sprintf("%v", *targetConf) + fee, err := i.feeEstimator.EstimateFeeRate( + context.Background(), + i.config.FeeStrategy, + ) + if err != nil || fee == nil { + log.Printf("Error estimating chain fee, fallback to target conf: %v", err) + fee = &chain.FeeEstimation{ + TargetConf: &i.config.TargetConf, } } @@ -439,11 +429,10 @@ func (i *Interceptor) ensureChannelOpen(payment *paymentState) { log.Printf( "LSPS2: Opening zero conf channel. Destination: %x, capacity: %v, "+ - "fee: %s, targetConf: %s", + "fee: %s", destination, capacity, - feeStr, - confStr, + fee.String(), ) channelPoint, err := i.client.OpenChannel(&lightning.OpenChannelRequest{ @@ -452,8 +441,8 @@ func (i *Interceptor) ensureChannelOpen(payment *paymentState) { MinConfs: i.config.MinConfs, IsPrivate: true, IsZeroConf: true, - FeeSatPerVByte: feeEstimation, - TargetConf: targetConf, + FeeSatPerVByte: fee.SatPerVByte, + TargetConf: fee.TargetConf, }) if err != nil { log.Printf( diff --git a/main.go b/main.go index d0bfa7e..aa9a4a3 100644 --- a/main.go +++ b/main.go @@ -59,16 +59,6 @@ func main() { log.Fatalf("failed to create nodes service: %v", err) } - mempoolUrl := os.Getenv("MEMPOOL_API_BASE_URL") - if mempoolUrl == "" { - log.Fatalf("No mempool url configured.") - } - - feeEstimator, err := mempool.NewMempoolClient(mempoolUrl) - if err != nil { - log.Fatalf("failed to initialize mempool client: %v", err) - } - var feeStrategy chain.FeeStrategy envFeeStrategy := os.Getenv("MEMPOOL_PRIORITY") switch strings.ToLower(envFeeStrategy) { @@ -85,7 +75,17 @@ func main() { default: feeStrategy = chain.FeeStrategyEconomy } - log.Printf("using mempool api for fee estimation: %v, fee strategy: %v:%v", mempoolUrl, envFeeStrategy, feeStrategy) + + var mempoolClient *mempool.MempoolClient + mempoolUrl := os.Getenv("MEMPOOL_API_BASE_URL") + if mempoolUrl != "" { + mempoolClient, err = mempool.NewMempoolClient(mempoolUrl) + if err != nil { + log.Fatalf("failed to initialize mempool client: %v", err) + } + + log.Printf("using mempool api for fee estimation: %v, fee strategy: %v:%v", mempoolUrl, envFeeStrategy, feeStrategy) + } databaseUrl := os.Getenv("DATABASE_URL") pool, err := postgresql.PgConnect(databaseUrl) @@ -111,6 +111,13 @@ func main() { var interceptors []interceptor.HtlcInterceptor for _, node := range nodes { var htlcInterceptor interceptor.HtlcInterceptor + var feeEstimator chain.FeeEstimator + if mempoolClient == nil { + feeEstimator = chain.NewDefaultFeeEstimator(node.NodeConfig.TargetConf) + } else { + feeEstimator = mempoolClient + } + if node.NodeConfig.Lnd != nil { client, err := lnd.NewLndClient(node.NodeConfig.Lnd) if err != nil { diff --git a/mempool/mempool_client.go b/mempool/mempool_client.go index f24e747..b32b5bb 100644 --- a/mempool/mempool_client.go +++ b/mempool/mempool_client.go @@ -85,6 +85,6 @@ func (m *MempoolClient) EstimateFeeRate( } return &chain.FeeEstimation{ - SatPerVByte: rate, + SatPerVByte: &rate, }, nil }