routing: let BlindedPaymentPathSet handle FinalCLTV logic

Instead of needing to remember how to handle the FinalCLTV value of a
blinded payment path at various points in the code base, we hide the
logic behind a unified FinalCLTVDelta method on the blinded path.
This commit is contained in:
Elle Mouton committed 2024-07-31 09:15:24 +02:00
1 parent 8df03de3e9
commit daaa24b69c
3 files changed
+42 -29

No files matched your search

+36 -4
View File
@@ -51,6 +51,22 @@ type BlindedPaymentPathSet struct {
// moment we require that all paths for the same payment have the
// same feature set.
features *lnwire.FeatureVector
// finalCLTV is the final hop's expiry delta of _any_ path in the set.
// For any multi-hop path, the final CLTV delta should be seen as zero
// since the final hop's final CLTV delta is accounted for in the
// accumulated path policy values. The only edge case is for when the
// final hop in the path is also the introduction node in which case
// that path's FinalCLTV must be the non-zero min CLTV of the final hop
// so that it is accounted for in path finding. For this reason, if
// we have any single path in the set with only one hop, then we throw
// away all the other paths. This should be fine to do since if there is
// a path where the intro node is also the destination node, then there
// isn't any need to try any other longer blinded path. In other words,
// if this value is non-zero, then there is only one path in this
// blinded path set and that path only has a single hop: the
// introduction node.
finalCLTV uint16
}
// NewBlindedPaymentPathSet constructs a new BlindedPaymentPathSet from a set of
@@ -95,19 +111,25 @@ func NewBlindedPaymentPathSet(paths []*BlindedPayment) (*BlindedPaymentPathSet,
}
targetPub := targetPriv.PubKey()
var (
pathSet = paths
finalCLTVDelta uint16
)
// If any provided blinded path only has a single hop (ie, the
// destination node is also the introduction node), then we discard all
// other paths since we know the real pub key of the destination node.
// For a single hop path, there is also no need for the pseudo target
// pub key replacement, so our target pub key in this case just remains
// the real introduction node ID.
var pathSet = paths
// We also then set the final CLTV delta to the path's delta since
// there are no other edge hints that will account for it. For a single
// hop path, there is also no need for the pseudo target pub key
// replacement, so our target pub key in this case just remains the
// real introduction node ID.
for _, path := range paths {
if len(path.BlindedPath.BlindedHops) != 1 {
continue
}
pathSet = []*BlindedPayment{path}
finalCLTVDelta = path.CltvExpiryDelta
targetPub = path.BlindedPath.IntroductionPoint
break
@@ -117,6 +139,7 @@ func NewBlindedPaymentPathSet(paths []*BlindedPayment) (*BlindedPaymentPathSet,
paths: pathSet,
targetPubKey: targetPub,
features: features,
finalCLTV: finalCLTVDelta,
}, nil
}
@@ -137,6 +160,15 @@ func (s *BlindedPaymentPathSet) GetPath() *BlindedPayment {
return s.paths[0]
}
// FinalCLTVDelta is the minimum CLTV delta to use for the final hop on the
// route. In most cases this will return zero since the value is accounted for
// in the path's accumulated CLTVExpiryDelta. Only in the edge case of the path
// set only including a single path which only includes an introduction node
// will this return a non-zero value.
func (s *BlindedPaymentPathSet) FinalCLTVDelta() uint16 {
return s.finalCLTV
}
// LargestLastHopPayloadPath returns the BlindedPayment in the set that has the
// largest last-hop payload. This is to be used for onion size estimation in
// path finding.