From e4778c31561713486904f790564b9a5651d13506 Mon Sep 17 00:00:00 2001 From: Gijs van Dam Date: Thu, 31 Oct 2024 12:11:55 +0100 Subject: [PATCH 1/4] tapcfg: bump minimalCompatibleVersion To support the new `min_relay_fee_sat_per_kw` in the `lnd` RPC call `EstimateFee`, we need to bump the `minimalCompatibleVersion` to `0.18.4`. --- tapcfg/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tapcfg/config.go b/tapcfg/config.go index bf869d923..96c9ecd00 100644 --- a/tapcfg/config.go +++ b/tapcfg/config.go @@ -186,8 +186,8 @@ var ( // required in lnd to run tapd. minimalCompatibleVersion = &verrpc.Version{ AppMajor: 0, - AppMinor: 17, - AppPatch: 99, + AppMinor: 18, + AppPatch: 4, // We don't actually require the invoicesrpc calls. But if we // try to use lndclient on an lnd that doesn't have it enabled, From 07ead54a6e439984c858d3532712d1bf58b865fa Mon Sep 17 00:00:00 2001 From: Gijs van Dam Date: Thu, 31 Oct 2024 12:15:43 +0100 Subject: [PATCH 2/4] tap: remove check for support GetBlockHeader With the `minimalCompatibleVersion` bumped to `0.18.4` we can assume support for the `GetBlockHeader` RPC call. This removes the check for support of the `GetBlockHeader` RPC call. --- chain_bridge.go | 53 +++++-------------------------------------------- 1 file changed, 5 insertions(+), 48 deletions(-) diff --git a/chain_bridge.go b/chain_bridge.go index 9d66b4c9d..d04547f8c 100644 --- a/chain_bridge.go +++ b/chain_bridge.go @@ -18,7 +18,6 @@ import ( "github.com/lightninglabs/taproot-assets/tapgarden" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/funding" - "github.com/lightningnetwork/lnd/lnrpc/verrpc" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -37,8 +36,6 @@ const ( type LndRpcChainBridge struct { lnd *lndclient.LndServices - getBlockHeaderSupported *bool - blockTimestampCache *lru.Cache[uint32, cacheableTimestamp] assetStore *tapdb.AssetStore @@ -138,31 +135,6 @@ func (l *LndRpcChainBridge) GetBlockHash(ctx context.Context, return blockHash, nil } -// GetBlockHeaderSupported returns true if the chain backend supports the -// `GetBlockHeader` RPC call. -func (l *LndRpcChainBridge) GetBlockHeaderSupported(ctx context.Context) bool { - // Check if we've already asserted the compatibility of the chain - // backend. - if l.getBlockHeaderSupported != nil { - return *l.getBlockHeaderSupported - } - - // The ChainKit.GetBlockHeader() RPC call was added in lnd v0.17.1. - getBlockHeaderMinimalVersion := &verrpc.Version{ - AppMajor: 0, - AppMinor: 17, - AppPatch: 1, - } - - getBlockHeaderUnsupported := lndclient.AssertVersionCompatible( - l.lnd.Version, getBlockHeaderMinimalVersion, - ) - getBlockHeaderSupported := getBlockHeaderUnsupported == nil - - l.getBlockHeaderSupported = &getBlockHeaderSupported - return *l.getBlockHeaderSupported -} - // VerifyBlock returns an error if a block (with given header and height) is not // present on-chain. It also checks to ensure that block height corresponds to // the given block header. @@ -194,12 +166,7 @@ func (l *LndRpcChainBridge) VerifyBlock(ctx context.Context, // Ensure that the block header corresponds to a block on-chain. Fetch // only the corresponding block header and not the entire block if // supported. - if l.GetBlockHeaderSupported(ctx) { - _, err = l.GetBlockHeader(ctx, header.BlockHash()) - return err - } - - _, err = l.GetBlock(ctx, header.BlockHash()) + _, err = l.GetBlockHeader(ctx, header.BlockHash()) return err } @@ -233,20 +200,10 @@ func (l *LndRpcChainBridge) GetBlockTimestamp(ctx context.Context, return 0 } - // Let's see if we can get the block header directly. - var header *wire.BlockHeader - if l.GetBlockHeaderSupported(ctx) { - header, err = l.GetBlockHeader(ctx, hash) - if err != nil { - return 0 - } - } else { - block, err := l.lnd.ChainKit.GetBlock(ctx, hash) - if err != nil { - return 0 - } - - header = &block.Header + // Get block header. + header, err := l.GetBlockHeader(ctx, hash) + if err != nil { + return 0 } ts := uint32(header.Timestamp.Unix()) From 05ad64b07a2bbecc9f1a8239ed659bfefb189897 Mon Sep 17 00:00:00 2001 From: Gijs van Dam Date: Thu, 31 Oct 2024 15:13:54 +0100 Subject: [PATCH 3/4] tap: remove lnd version check from FundVirtualPsbt This commit removes the version check for lnd in the `FundVirtualPsbt` since we can assume the new coin selection mode in the FundPsbt call with the minimal lnd version now being `0.18.4`. --- rpcserver.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index e8de18b53..efe0599c9 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -52,7 +52,6 @@ import ( "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/lnrpc/verrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwire" @@ -78,17 +77,6 @@ var ( // P2TRChangeType is the type of change address that should be used for // funding PSBTs, as we'll always want to use P2TR change addresses. P2TRChangeType = walletrpc.ChangeAddressType_CHANGE_ADDRESS_TYPE_P2TR - - // fundPsbtCoinSelectVersion is the version of lnd that enabled better - // coin selection support in the FundPsbt RPC call. - fundPsbtCoinSelectVersion = &verrpc.Version{ - AppMajor: 0, - AppMinor: 17, - AppPatch: 99, - BuildTags: []string{ - "signrpc", "walletrpc", "chainrpc", "invoicesrpc", - }, - } ) const ( @@ -2304,22 +2292,6 @@ func (r *rpcServer) CommitVirtualPsbts(ctx context.Context, req *wrpc.CommitVirtualPsbtsRequest) (*wrpc.CommitVirtualPsbtsResponse, error) { - // For this call we require `lnd` to be at least v0.17.99-beta (which - // will become v0.18.0-beta eventually) as we need the new coin - // selection mode in the FundPsbt call. - fundPsbtCoinSelectNotSupportedErr := fmt.Errorf("connected lnd "+ - "version %v does not support advanced coin selection in the "+ - "FundPsbt RPC, need at least v%d.%d.%d for this call", - r.cfg.Lnd.Version.Version, fundPsbtCoinSelectVersion.AppMajor, - fundPsbtCoinSelectVersion.AppMinor, - fundPsbtCoinSelectVersion.AppPatch) - verErr := lndclient.AssertVersionCompatible( - r.cfg.Lnd.Version, fundPsbtCoinSelectVersion, - ) - if verErr != nil { - return nil, fundPsbtCoinSelectNotSupportedErr - } - if len(req.VirtualPsbts) == 0 { return nil, fmt.Errorf("no virtual PSBTs specified") } From e11176505107ddcc783af708fb2bffa6ca98bfe8 Mon Sep 17 00:00:00 2001 From: Gijs van Dam Date: Wed, 30 Oct 2024 17:06:24 +0100 Subject: [PATCH 4/4] multi: add minrelayfee check to tapchannel funding This commit adds `MinRelayFee` to the `WalletAnchor` and uses it during tapchannel funding to check whether the feerate meets the minimum relay fee. --- docs/examples/basic-price-oracle/go.mod | 2 +- docs/examples/basic-price-oracle/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- tapchannel/aux_funding_controller.go | 12 ++++++++++++ tapgarden/interface.go | 4 ++++ tapgarden/mock.go | 8 ++++++++ wallet_anchor.go | 8 ++++++++ 8 files changed, 38 insertions(+), 6 deletions(-) diff --git a/docs/examples/basic-price-oracle/go.mod b/docs/examples/basic-price-oracle/go.mod index 97c439693..626476fe5 100644 --- a/docs/examples/basic-price-oracle/go.mod +++ b/docs/examples/basic-price-oracle/go.mod @@ -92,7 +92,7 @@ require ( github.com/kkdai/bstream v1.0.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect - github.com/lightninglabs/lndclient v0.18.4-1 // indirect + github.com/lightninglabs/lndclient v0.18.4-3 // indirect github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd // indirect github.com/lightninglabs/neutrino/cache v1.1.2 // indirect github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect diff --git a/docs/examples/basic-price-oracle/go.sum b/docs/examples/basic-price-oracle/go.sum index 99dad4ae5..a38fa5d17 100644 --- a/docs/examples/basic-price-oracle/go.sum +++ b/docs/examples/basic-price-oracle/go.sum @@ -418,8 +418,8 @@ github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQ github.com/lightninglabs/lightning-node-connect v0.2.5-alpha h1:ZRVChwczFXK0CEbxOCWwUA6TIZvrkE0APd1T3WjFAwg= github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY= github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4= -github.com/lightninglabs/lndclient v0.18.4-1 h1:k2UnxHGNH243NRe5/dL2sKgrxc8WMHbFQRdnCtfilwc= -github.com/lightninglabs/lndclient v0.18.4-1/go.mod h1:/HLqmZGL9MtP8F1g+laq+L9VrsugBN5tsTct3C5wWCg= +github.com/lightninglabs/lndclient v0.18.4-3 h1:Xk3ZuCQE4ZlF70jaToryL2MvRcryiE0zTfUjJbmzUBY= +github.com/lightninglabs/lndclient v0.18.4-3/go.mod h1:/HLqmZGL9MtP8F1g+laq+L9VrsugBN5tsTct3C5wWCg= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd h1:D8aRocHpoCv43hL8egXEMYyPmyOiefFHZ66338KQB2s= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk= github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g= diff --git a/go.mod b/go.mod index 5cc91ecd3..9963af80f 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/lib/pq v1.10.9 github.com/lightninglabs/aperture v0.3.2-beta.0.20241015115230-d59b5514c19a github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 - github.com/lightninglabs/lndclient v0.18.4-1 + github.com/lightninglabs/lndclient v0.18.4-3 github.com/lightninglabs/neutrino/cache v1.1.2 github.com/lightningnetwork/lnd v0.18.3-beta.rc3.0.20241025090009-615f3d633e61 github.com/lightningnetwork/lnd/cert v1.2.2 diff --git a/go.sum b/go.sum index 4bbb981a4..ff805b32f 100644 --- a/go.sum +++ b/go.sum @@ -486,8 +486,8 @@ github.com/lightninglabs/lightning-node-connect v0.2.5-alpha h1:ZRVChwczFXK0CEbx github.com/lightninglabs/lightning-node-connect v0.2.5-alpha/go.mod h1:A9Pof9fETkH+F67BnOmrBDThPKstqp73wlImWOZvTXQ= github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY= github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4= -github.com/lightninglabs/lndclient v0.18.4-1 h1:k2UnxHGNH243NRe5/dL2sKgrxc8WMHbFQRdnCtfilwc= -github.com/lightninglabs/lndclient v0.18.4-1/go.mod h1:/HLqmZGL9MtP8F1g+laq+L9VrsugBN5tsTct3C5wWCg= +github.com/lightninglabs/lndclient v0.18.4-3 h1:Xk3ZuCQE4ZlF70jaToryL2MvRcryiE0zTfUjJbmzUBY= +github.com/lightninglabs/lndclient v0.18.4-3/go.mod h1:/HLqmZGL9MtP8F1g+laq+L9VrsugBN5tsTct3C5wWCg= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd h1:D8aRocHpoCv43hL8egXEMYyPmyOiefFHZ66338KQB2s= github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk= github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g= diff --git a/tapchannel/aux_funding_controller.go b/tapchannel/aux_funding_controller.go index dbfc05e80..e0c5c9e37 100644 --- a/tapchannel/aux_funding_controller.go +++ b/tapchannel/aux_funding_controller.go @@ -1354,6 +1354,18 @@ func (f *FundingController) processFundingReq(fundingFlows fundingFlowIndex, fundReq.PeerPub.SerializeCompressed()) } + // Before we proceed, we'll make sure the fee rate we're using is above + // the min relay fee. + minRelayFee, err := f.cfg.ChainWallet.MinRelayFee(fundReq.ctx) + if err != nil { + return fmt.Errorf("unable to establish min_relay_fee: %w", + err) + } + if fundReq.FeeRate.FeePerKWeight() < minRelayFee { + return fmt.Errorf("fee rate %v too low, min_relay_fee: %v", + fundReq.FeeRate.FeePerKWeight(), minRelayFee) + } + // To start, we'll make a new pending asset funding desc. This'll be // our scratch pad during the asset funding process. tempPID, err := newPendingChanID() diff --git a/tapgarden/interface.go b/tapgarden/interface.go index cfe9b71ff..3814d8bd0 100644 --- a/tapgarden/interface.go +++ b/tapgarden/interface.go @@ -372,6 +372,10 @@ type WalletAnchor interface { // relevant to the wallet are sent over. SubscribeTransactions(context.Context) (<-chan lndclient.Transaction, <-chan error, error) + + // MinRelayFee returns the current minimum relay fee based on + // our chain backend in sat/kw. + MinRelayFee(ctx context.Context) (chainfee.SatPerKWeight, error) } // KeyRing is a mirror of the keychain.KeyRing interface, with the addition of diff --git a/tapgarden/mock.go b/tapgarden/mock.go index bd363c077..94cfa9712 100644 --- a/tapgarden/mock.go +++ b/tapgarden/mock.go @@ -302,6 +302,14 @@ func (m *MockWalletAnchor) ListTransactions(ctx context.Context, _, _ int32, return m.Transactions, nil } +// MinRelayFee estimates the minimum fee rate required for a +// transaction. +func (m *MockWalletAnchor) MinRelayFee( + ctx context.Context) (chainfee.SatPerKWeight, error) { + + return chainfee.SatPerKWeight(10), nil +} + type MockChainBridge struct { FeeEstimateSignal chan struct{} PublishReq chan *wire.MsgTx diff --git a/wallet_anchor.go b/wallet_anchor.go index e2144d22d..91653855c 100644 --- a/wallet_anchor.go +++ b/wallet_anchor.go @@ -218,6 +218,14 @@ func (l *LndRpcWalletAnchor) ListChannels( return l.lnd.Client.ListChannels(ctx, true, false) } +// MinRelayFee estimates the minimum fee rate required for a +// transaction. +func (l *LndRpcWalletAnchor) MinRelayFee( + ctx context.Context) (chainfee.SatPerKWeight, error) { + + return l.lnd.WalletKit.MinRelayFee(ctx) +} + // A compile time assertion to ensure LndRpcWalletAnchor meets the // tapgarden.WalletAnchor interface. var _ tapgarden.WalletAnchor = (*LndRpcWalletAnchor)(nil)