From 5d7113ac1d0b704ad5e7f469ebe0c10e4c4ff983 Mon Sep 17 00:00:00 2001 From: ziggie Date: Thu, 22 Aug 2024 17:45:45 +0200 Subject: [PATCH 1/4] blindedpath: remove blockexpiry check. Removes a check where we would NOT allow to create a blinded invoice with an expiry (invoice expiry in seconds considered as block time) lower than the min_final_ctlv_delta. --- routing/blindedpath/blinded_path.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/routing/blindedpath/blinded_path.go b/routing/blindedpath/blinded_path.go index 19a6edcaa..c03ae833c 100644 --- a/routing/blindedpath/blinded_path.go +++ b/routing/blindedpath/blinded_path.go @@ -82,7 +82,16 @@ type BuildBlindedPathCfg struct { MinFinalCLTVExpiryDelta uint32 // BlocksUntilExpiry is the number of blocks that this blinded path - // should remain valid for. + // should remain valid for. This is a relative number of blocks. This + // number in addition with a potential minimum cltv delta for the last + // hop and some block padding will be the payment constraint which is + // part of the blinded hop info. Every htlc using the provided blinded + // hops cannot have a higher cltv delta otherwise it will get rejected + // by the forwarding nodes or the final node. + // + // This number should at least be greater than the invoice expiry time + // so that the blinded route is always valid as long as the invoice is + // valid. BlocksUntilExpiry uint32 // MinNumHops is the minimum number of hops that each blinded path @@ -105,13 +114,6 @@ type BuildBlindedPathCfg struct { func BuildBlindedPaymentPaths(cfg *BuildBlindedPathCfg) ( []*zpay32.BlindedPaymentPath, error) { - if cfg.MinFinalCLTVExpiryDelta >= cfg.BlocksUntilExpiry { - return nil, fmt.Errorf("blinded path CLTV expiry delta (%d) "+ - "must be greater than the minimum final CLTV expiry "+ - "delta (%d)", cfg.BlocksUntilExpiry, - cfg.MinFinalCLTVExpiryDelta) - } - // Find some appropriate routes for the value to be routed. This will // return a set of routes made up of real nodes. routes, err := cfg.FindRoutes(cfg.ValueMsat) From 73984964a8e44baf8ef66ff0334e076566bb21e0 Mon Sep 17 00:00:00 2001 From: ziggie Date: Thu, 22 Aug 2024 17:48:27 +0200 Subject: [PATCH 2/4] blindedpath: fix log output. --- routing/blindedpath/blinded_path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing/blindedpath/blinded_path.go b/routing/blindedpath/blinded_path.go index c03ae833c..e47114baf 100644 --- a/routing/blindedpath/blinded_path.go +++ b/routing/blindedpath/blinded_path.go @@ -150,7 +150,7 @@ func BuildBlindedPaymentPaths(cfg *BuildBlindedPathCfg) ( continue } else if err != nil { log.Errorf("Not using route (%s) as a blinded path: %v", - err) + route, err) continue } From 25f7b1c362227daa4f4b15d5693c6256910c9366 Mon Sep 17 00:00:00 2001 From: ziggie Date: Thu, 22 Aug 2024 17:49:16 +0200 Subject: [PATCH 3/4] blindedpath: minHTLC for blinded path change. We will not add a buffer to the chan policy for blinded paths in case the sender amount violates the minHTLC restriction in the first place. Moreover we disgard a route fast if the payment amount is smaller than the minHTLC along the route. --- routing/blindedpath/blinded_path.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/routing/blindedpath/blinded_path.go b/routing/blindedpath/blinded_path.go index e47114baf..bc14daa40 100644 --- a/routing/blindedpath/blinded_path.go +++ b/routing/blindedpath/blinded_path.go @@ -437,11 +437,27 @@ func collectRelayInfo(cfg *BuildBlindedPathCfg, path *candidatePath) ( } } - policy, err = cfg.AddPolicyBuffer(policy) + if policy.MinHTLCMsat > cfg.ValueMsat { + return nil, 0, 0, fmt.Errorf("%w: minHTLC of hop "+ + "policy larger than payment amt: sentAmt(%v), "+ + "minHTLC(%v)", errInvalidBlindedPath, + cfg.ValueMsat, policy.MinHTLCMsat) + } + + bufferPolicy, err := cfg.AddPolicyBuffer(policy) if err != nil { return nil, 0, 0, err } + // We only use the new buffered policy if the new minHTLC value + // does not violate the sender amount. + // + // NOTE: We don't check this for maxHTLC, because the payment + // amount can always be splitted using MPP. + if bufferPolicy.MinHTLCMsat <= cfg.ValueMsat { + policy = bufferPolicy + } + // If this is the first policy we are collecting, then use this // policy to set the base values for min/max htlc. if len(hops) == 0 { From 816b25e2bac45480eb78974774eda165289d88f8 Mon Sep 17 00:00:00 2001 From: ziggie Date: Thu, 22 Aug 2024 17:53:38 +0200 Subject: [PATCH 4/4] docs: add release-notes. --- docs/release-notes/release-notes-0.18.3.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/release-notes/release-notes-0.18.3.md b/docs/release-notes/release-notes-0.18.3.md index 372be529c..3b72ec42d 100644 --- a/docs/release-notes/release-notes-0.18.3.md +++ b/docs/release-notes/release-notes-0.18.3.md @@ -68,6 +68,11 @@ commitment when the channel was force closed. in the `ReplyChannelRange` msg and introduced a check that ChanUpdates with a timestamp too far into the future will be discarded. +* [Fixed](https://github.com/lightningnetwork/lnd/pull/9026) a bug where we +would create a blinded route with a minHTLC greater than the actual payment +amount. Moreover remove strict correlation between min_cltv_delta and the +blinded path expiry. + # New Features ## Functional Enhancements ## RPC Additions