mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-28 06:32:18 +02:00
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:
@@ -51,6 +51,22 @@ type BlindedPaymentPathSet struct {
|
|||||||
// moment we require that all paths for the same payment have the
|
// moment we require that all paths for the same payment have the
|
||||||
// same feature set.
|
// same feature set.
|
||||||
features *lnwire.FeatureVector
|
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
|
// NewBlindedPaymentPathSet constructs a new BlindedPaymentPathSet from a set of
|
||||||
@@ -95,19 +111,25 @@ func NewBlindedPaymentPathSet(paths []*BlindedPayment) (*BlindedPaymentPathSet,
|
|||||||
}
|
}
|
||||||
targetPub := targetPriv.PubKey()
|
targetPub := targetPriv.PubKey()
|
||||||
|
|
||||||
|
var (
|
||||||
|
pathSet = paths
|
||||||
|
finalCLTVDelta uint16
|
||||||
|
)
|
||||||
// If any provided blinded path only has a single hop (ie, the
|
// If any provided blinded path only has a single hop (ie, the
|
||||||
// destination node is also the introduction node), then we discard all
|
// destination node is also the introduction node), then we discard all
|
||||||
// other paths since we know the real pub key of the destination node.
|
// 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
|
// We also then set the final CLTV delta to the path's delta since
|
||||||
// pub key replacement, so our target pub key in this case just remains
|
// there are no other edge hints that will account for it. For a single
|
||||||
// the real introduction node ID.
|
// hop path, there is also no need for the pseudo target pub key
|
||||||
var pathSet = paths
|
// replacement, so our target pub key in this case just remains the
|
||||||
|
// real introduction node ID.
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
if len(path.BlindedPath.BlindedHops) != 1 {
|
if len(path.BlindedPath.BlindedHops) != 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pathSet = []*BlindedPayment{path}
|
pathSet = []*BlindedPayment{path}
|
||||||
|
finalCLTVDelta = path.CltvExpiryDelta
|
||||||
targetPub = path.BlindedPath.IntroductionPoint
|
targetPub = path.BlindedPath.IntroductionPoint
|
||||||
|
|
||||||
break
|
break
|
||||||
@@ -117,6 +139,7 @@ func NewBlindedPaymentPathSet(paths []*BlindedPayment) (*BlindedPaymentPathSet,
|
|||||||
paths: pathSet,
|
paths: pathSet,
|
||||||
targetPubKey: targetPub,
|
targetPubKey: targetPub,
|
||||||
features: features,
|
features: features,
|
||||||
|
finalCLTV: finalCLTVDelta,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +160,15 @@ func (s *BlindedPaymentPathSet) GetPath() *BlindedPayment {
|
|||||||
return s.paths[0]
|
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
|
// LargestLastHopPayloadPath returns the BlindedPayment in the set that has the
|
||||||
// largest last-hop payload. This is to be used for onion size estimation in
|
// largest last-hop payload. This is to be used for onion size estimation in
|
||||||
// path finding.
|
// path finding.
|
||||||
|
@@ -210,21 +210,12 @@ func newRoute(sourceVertex route.Vertex,
|
|||||||
// reporting through RPC. Set to zero for the final hop.
|
// reporting through RPC. Set to zero for the final hop.
|
||||||
fee = 0
|
fee = 0
|
||||||
|
|
||||||
// Only include the final hop CLTV delta in the total
|
if blindedPathSet == nil {
|
||||||
// time lock value if this is not a route to a blinded
|
|
||||||
// path. For blinded paths, the total time-lock from the
|
|
||||||
// whole path will be deduced from the introduction
|
|
||||||
// node's CLTV delta. The exception is for the case
|
|
||||||
// where the final hop is the blinded path introduction
|
|
||||||
// node.
|
|
||||||
if blindedPathSet == nil ||
|
|
||||||
len(blindedPathSet.GetPath().BlindedPath.
|
|
||||||
BlindedHops) == 1 {
|
|
||||||
|
|
||||||
// As this is the last hop, we'll use the
|
|
||||||
// specified final CLTV delta value instead of
|
|
||||||
// the value from the last link in the route.
|
|
||||||
totalTimeLock += uint32(finalHop.cltvDelta)
|
totalTimeLock += uint32(finalHop.cltvDelta)
|
||||||
|
} else {
|
||||||
|
totalTimeLock += uint32(
|
||||||
|
blindedPathSet.FinalCLTVDelta(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
outgoingTimeLock = totalTimeLock
|
outgoingTimeLock = totalTimeLock
|
||||||
|
|
||||||
|
@@ -524,17 +524,7 @@ func NewRouteRequest(source route.Vertex, target *route.Vertex,
|
|||||||
return nil, ErrExpiryAndBlinded
|
return nil, ErrExpiryAndBlinded
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a blinded path with 1 hop, the cltv expiry
|
requestExpiry = blindedPathSet.FinalCLTVDelta()
|
||||||
// will not be included in any hop hints (since we're just
|
|
||||||
// sending to the introduction node and need no blinded hints).
|
|
||||||
// In this case, we include it to make sure that the final
|
|
||||||
// cltv delta is accounted for (since it's part of the blinded
|
|
||||||
// delta). In the case of a multi-hop route, we set our final
|
|
||||||
// cltv to zero, since it's going to be accounted for in the
|
|
||||||
// delta for our hints.
|
|
||||||
if len(blindedPayment.BlindedPath.BlindedHops) == 1 {
|
|
||||||
requestExpiry = blindedPayment.CltvExpiryDelta
|
|
||||||
}
|
|
||||||
|
|
||||||
requestHints, err = blindedPathSet.ToRouteHints()
|
requestHints, err = blindedPathSet.ToRouteHints()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user