diff --git a/config.go b/config.go index 57b0f5f3d..ef187e6a6 100644 --- a/config.go +++ b/config.go @@ -444,6 +444,8 @@ type Config struct { Sweeper *lncfg.Sweeper `group:"sweeper" namespace:"sweeper"` + Htlcswitch *lncfg.Htlcswitch `group:"htlcswitch" namespace:"htlcswitch"` + // LogWriter is the root logger that all of the daemon's subloggers are // hooked up to. LogWriter *build.RotatingLogWriter @@ -462,6 +464,8 @@ type Config struct { } // DefaultConfig returns all default values for the Config struct. +// +// nolint:lll func DefaultConfig() Config { return Config{ LndDir: DefaultLndDir, @@ -643,6 +647,9 @@ func DefaultConfig() Config { Sweeper: &lncfg.Sweeper{ BatchWindowDuration: sweep.DefaultBatchWindowDuration, }, + Htlcswitch: &lncfg.Htlcswitch{ + MailboxDeliveryTimeout: htlcswitch.DefaultMailboxDeliveryTimeout, + }, } } @@ -1660,6 +1667,7 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser, cfg.RPCMiddleware, cfg.RemoteSigner, cfg.Sweeper, + cfg.Htlcswitch, ) if err != nil { return nil, err diff --git a/docs/release-notes/release-notes-0.16.0.md b/docs/release-notes/release-notes-0.16.0.md index 4c6f78c01..e49bda3b3 100644 --- a/docs/release-notes/release-notes-0.16.0.md +++ b/docs/release-notes/release-notes-0.16.0.md @@ -168,6 +168,9 @@ certain large transactions](https://github.com/lightningnetwork/lnd/pull/7100). received](https://github.com/lightningnetwork/lnd/pull/7126) to avoid CPU spike. +* [A new config option, `mailboxdeliverytimeout` has been added to + `htlcswitch`](https://github.com/lightningnetwork/lnd/pull/7066). + ## Code Health * [test: use `T.TempDir` to create temporary test diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index 0c9bd303f..c544bff15 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -190,15 +190,17 @@ func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error) EpochChan: make(chan *chainntnfs.BlockEpoch), ConfChan: make(chan *chainntnfs.TxConfirmation), }, - FwdEventTicker: ticker.NewForce(DefaultFwdEventInterval), - LogEventTicker: ticker.NewForce(DefaultLogInterval), - AckEventTicker: ticker.NewForce(DefaultAckInterval), - HtlcNotifier: &mockHTLCNotifier{}, - Clock: clock.NewDefaultClock(), - HTLCExpiry: time.Hour, - DustThreshold: DefaultDustThreshold, - SignAliasUpdate: signAliasUpdate, - IsAlias: isAlias, + FwdEventTicker: ticker.NewForce( + DefaultFwdEventInterval, + ), + LogEventTicker: ticker.NewForce(DefaultLogInterval), + AckEventTicker: ticker.NewForce(DefaultAckInterval), + HtlcNotifier: &mockHTLCNotifier{}, + Clock: clock.NewDefaultClock(), + MailboxDeliveryTimeout: time.Hour, + DustThreshold: DefaultDustThreshold, + SignAliasUpdate: signAliasUpdate, + IsAlias: isAlias, } return New(cfg, startingHeight) diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index c04a42df2..8b2120d3e 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -39,9 +39,9 @@ const ( // fails in a forwarding package. DefaultAckInterval = 15 * time.Second - // DefaultHTLCExpiry is the duration after which Adds will be cancelled - // if they could not get added to an outgoing commitment. - DefaultHTLCExpiry = time.Minute + // DefaultMailboxDeliveryTimeout is the duration after which Adds will + // be cancelled if they could not get added to an outgoing commitment. + DefaultMailboxDeliveryTimeout = time.Minute ) var ( @@ -202,11 +202,11 @@ type Config struct { // Clock is a time source for the switch. Clock clock.Clock - // HTLCExpiry is the interval after which Adds will be cancelled if they - // have not been yet been delivered to a link. The computed deadline - // will expiry this long after the Adds are added to a mailbox via - // AddPacket. - HTLCExpiry time.Duration + // MailboxDeliveryTimeout is the interval after which Adds will be + // cancelled if they have not been yet been delivered to a link. The + // computed deadline will expiry this long after the Adds are added to + // a mailbox via AddPacket. + MailboxDeliveryTimeout time.Duration // DustThreshold is the threshold in milli-satoshis after which we'll // fail incoming or outgoing dust payments for a particular channel. @@ -386,7 +386,7 @@ func New(cfg Config, currentHeight uint32) (*Switch, error) { s.mailOrchestrator = newMailOrchestrator(&mailOrchConfig{ forwardPackets: s.ForwardPackets, clock: s.cfg.Clock, - expiry: s.cfg.HTLCExpiry, + expiry: s.cfg.MailboxDeliveryTimeout, failMailboxUpdate: s.failMailboxUpdate, }) diff --git a/lncfg/htlcswitch.go b/lncfg/htlcswitch.go new file mode 100644 index 000000000..4fdc85749 --- /dev/null +++ b/lncfg/htlcswitch.go @@ -0,0 +1,34 @@ +package lncfg + +import ( + "fmt" + "time" +) + +var ( + // MaxMailboxDeliveryTimeout specifies the max allowed timeout value. + // This value is derived from the itest `async_bidirectional_payments`, + // where both side send 483 payments at the same time to stress test + // lnd. + MaxMailboxDeliveryTimeout = 2 * time.Minute +) + +// nolint:lll +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."` +} + +// Validate checks the values configured for htlcswitch. +func (h *Htlcswitch) Validate() error { + if h.MailboxDeliveryTimeout <= 0 { + return fmt.Errorf("mailboxdeliverytimeout must be positive") + } + + if h.MailboxDeliveryTimeout > MaxMailboxDeliveryTimeout { + return fmt.Errorf("mailboxdeliverytimeout: %v exceeds "+ + "maximum: %v", h.MailboxDeliveryTimeout, + MaxMailboxDeliveryTimeout) + } + + return nil +} diff --git a/sample-lnd.conf b/sample-lnd.conf index 3afa98586..a06342ece 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -1423,3 +1423,10 @@ litecoin.node=ltcd ; window to allow more inputs to be added and thereby lower the fee per input. ; sweeper.batchwindowduration=30s +[htlcswitch] + +; 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. +; htlcswitch.mailboxdeliverytimeout=60s + diff --git a/server.go b/server.go index 4fc40e76a..a722a16f8 100644 --- a/server.go +++ b/server.go @@ -658,7 +658,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, AllowCircularRoute: cfg.AllowCircularRoute, RejectHTLC: cfg.RejectHTLC, Clock: clock.NewDefaultClock(), - HTLCExpiry: htlcswitch.DefaultHTLCExpiry, + MailboxDeliveryTimeout: cfg.Htlcswitch.MailboxDeliveryTimeout, DustThreshold: thresholdMSats, SignAliasUpdate: s.signAliasUpdate, IsAlias: aliasmgr.IsAlias, @@ -997,8 +997,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr, return nil, err } - srvrLog.Tracef("Sweeper batch window duration: %v", - sweep.DefaultBatchWindowDuration) + srvrLog.Debugf("Sweeper batch window duration: %v", + cfg.Sweeper.BatchWindowDuration) sweeperStore, err := sweep.NewSweeperStore( dbs.ChanStateDB, s.cfg.ActiveNetParams.GenesisHash,