diff --git a/config.go b/config.go index 53f8f36e5..f20517c27 100644 --- a/config.go +++ b/config.go @@ -751,6 +751,7 @@ func DefaultConfig() Config { Sweeper: lncfg.DefaultSweeperConfig(), Htlcswitch: &lncfg.Htlcswitch{ MailboxDeliveryTimeout: htlcswitch.DefaultMailboxDeliveryTimeout, + QuiescenceTimeout: lncfg.DefaultQuiescenceTimeout, }, GRPC: &GRPCConfig{ ServerPingTime: defaultGrpcServerPingTime, diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 3aa47caf3..1a6fd7988 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -301,6 +301,12 @@ type ChannelLinkConfig struct { // AuxTrafficShaper is an optional auxiliary traffic shaper that can be // used to manage the bandwidth of the link. AuxTrafficShaper fn.Option[AuxTrafficShaper] + + // QuiescenceTimeout is the max duration that the channel can be + // quiesced. Any dependent protocols (dynamic commitments, splicing, + // etc.) must finish their operations under this timeout value, + // otherwise the node will disconnect. + QuiescenceTimeout time.Duration } // channelLink is the service which drives a channel's commitment update @@ -497,7 +503,7 @@ func NewChannelLink(cfg ChannelLinkConfig, sendMsg: func(s lnwire.Stfu) error { return cfg.Peer.SendMessage(false, &s) }, - timeoutDuration: defaultQuiescenceTimeout, + timeoutDuration: cfg.QuiescenceTimeout, onTimeout: func() { cfg.Peer.Disconnect(ErrQuiescenceTimeout) }, diff --git a/htlcswitch/quiescer.go b/htlcswitch/quiescer.go index 468ad5e70..e16935d85 100644 --- a/htlcswitch/quiescer.go +++ b/htlcswitch/quiescer.go @@ -47,13 +47,9 @@ var ( // ErrQuiescenceTimeout indicates that the quiescer has been quiesced // beyond the allotted time. - ErrQuiescenceTimeout = fmt.Errorf( - "quiescence timeout", - ) + ErrQuiescenceTimeout = fmt.Errorf("quiescence timeout") ) -const defaultQuiescenceTimeout = 30 * time.Second - type StfuReq = fn.Req[fn.Unit, fn.Result[lntypes.ChannelParty]] // Quiescer is the public interface of the quiescence mechanism. Callers of the diff --git a/lncfg/htlcswitch.go b/lncfg/htlcswitch.go index 613b18991..9942df22b 100644 --- a/lncfg/htlcswitch.go +++ b/lncfg/htlcswitch.go @@ -11,11 +11,21 @@ var ( // where both side send 483 payments at the same time to stress test // lnd. MaxMailboxDeliveryTimeout = 2 * time.Minute + + // minQuiescenceTimeout specifies the minimal timeout value that can be + // used for `QuiescenceTimeout`. + minQuiescenceTimeout = 30 * time.Second + + // DefaultQuiescenceTimeout specifies the default value to be used for + // `QuiescenceTimeout`. + DefaultQuiescenceTimeout = 60 * time.Second ) //nolint:ll type Htlcswitch struct { MailboxDeliveryTimeout time.Duration `long:"mailboxdeliverytimeout" description:"The timeout value when delivering HTLCs to a channel link. Setting this value too small will result in local payment failures if large number of payments are sent over a short period."` + + QuiescenceTimeout time.Duration `long:"quiescencetimeout" description:"The max duration that the channel can be quiesced. Any dependent protocols (dynamic commitments, splicing, etc.) must finish their operations under this timeout value, otherwise the node will disconnect."` } // Validate checks the values configured for htlcswitch. @@ -30,5 +40,10 @@ func (h *Htlcswitch) Validate() error { MaxMailboxDeliveryTimeout) } + if h.QuiescenceTimeout < minQuiescenceTimeout { + return fmt.Errorf("quiescencetimeout: %v below minimal: %v", + h.QuiescenceTimeout, minQuiescenceTimeout) + } + return nil } diff --git a/peer/brontide.go b/peer/brontide.go index 213f28c76..34e504a37 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -438,6 +438,12 @@ type Config struct { // should have the quiescence feature disabled. DisallowQuiescence bool + // QuiescenceTimeout is the max duration that the channel can be + // quiesced. Any dependent protocols (dynamic commitments, splicing, + // etc.) must finish their operations under this timeout value, + // otherwise the node will disconnect. + QuiescenceTimeout time.Duration + // MaxFeeExposure limits the number of outstanding fees in a channel. // This value will be passed to created links. MaxFeeExposure lnwire.MilliSatoshi @@ -1449,7 +1455,8 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint, ShouldFwdExpEndorsement: p.cfg.ShouldFwdExpEndorsement, DisallowQuiescence: p.cfg.DisallowQuiescence || !p.remoteFeatures.HasFeature(lnwire.QuiescenceOptional), - AuxTrafficShaper: p.cfg.AuxTrafficShaper, + AuxTrafficShaper: p.cfg.AuxTrafficShaper, + QuiescenceTimeout: p.cfg.QuiescenceTimeout, } // Before adding our new link, purge the switch of any pending or live diff --git a/sample-lnd.conf b/sample-lnd.conf index 58020a8ba..7e105de27 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -1913,6 +1913,10 @@ ; are sent over a short period. ; htlcswitch.mailboxdeliverytimeout=1m +; The max duration that the channel can be quiesced. Any dependent protocols +; (dynamic commitments, splicing, etc.) must finish their operations under this +; timeout value, otherwise the node will disconnect. +; htlcswitch.quiescencetimeout=1m [grpc] diff --git a/server.go b/server.go index 3626158fd..952877d6e 100644 --- a/server.go +++ b/server.go @@ -4529,6 +4529,7 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, AddLocalAlias: s.aliasMgr.AddLocalAlias, DisallowRouteBlinding: s.cfg.ProtocolOptions.NoRouteBlinding(), DisallowQuiescence: s.cfg.ProtocolOptions.NoQuiescence(), + QuiescenceTimeout: s.cfg.Htlcswitch.QuiescenceTimeout, MaxFeeExposure: thresholdMSats, Quit: s.quit, AuxLeafStore: s.implCfg.AuxLeafStore,