routing: final changes to BlindedPaymentPathSet

Continue adding some complexity behind the BlindedPaymentPathSet. What
we do here is add a new IntroNodeOnlyPath method. The assumption we
make here is: If multiple blinded paths are provided to us in an invoice
but one of those paths only includes an intro node, then there is no
point in looking at any other path since we know that the intro node is
the destination node. So in such a case, we would have discarded any
other path in the `NewBlindedPaymentPathSet` constructor. So then we
would only have a single blinded path made up of an introduction node
only. In this specific case, in the `newRoute` function, no edge passed
to the function would have a blindedPayment associated with it (since
there are no blinded hops in this case). So we will have a case where
`blindedPathSet` passed to `newRoute` is not nil but `blindedPayment` is
nil since nonce was extacted from any edge. If this happens then we can
assume that this is the Intro-Node-Only situation described above. And
so we grabe the associated payment from the path set.
This commit is contained in:
Elle Mouton 2024-05-16 10:33:00 +02:00
parent daaa24b69c
commit e87110317b
No known key found for this signature in database
GPG Key ID: D7D916376026F177
4 changed files with 51 additions and 15 deletions

View File

@ -154,10 +154,36 @@ func (s *BlindedPaymentPathSet) Features() *lnwire.FeatureVector {
return s.features
}
// GetPath is a temporary getter for the single path that the set holds.
// This will be removed later on in this PR.
func (s *BlindedPaymentPathSet) GetPath() *BlindedPayment {
return s.paths[0]
// IntroNodeOnlyPath can be called if it is expected that the path set only
// contains a single payment path which itself only has one hop. It errors if
// this is not the case.
func (s *BlindedPaymentPathSet) IntroNodeOnlyPath() (*BlindedPayment, error) {
if len(s.paths) != 1 {
return nil, fmt.Errorf("expected only a single path in the "+
"blinded payment set, got %d", len(s.paths))
}
if len(s.paths[0].BlindedPath.BlindedHops) > 1 {
return nil, fmt.Errorf("an intro node only path cannot have " +
"more than one hop")
}
return s.paths[0], nil
}
// IsIntroNode returns true if the given vertex is an introduction node for one
// of the paths in the blinded payment path set.
func (s *BlindedPaymentPathSet) IsIntroNode(source route.Vertex) bool {
for _, path := range s.paths {
introVertex := route.NewVertex(
path.BlindedPath.IntroductionPoint,
)
if source == introVertex {
return true
}
}
return false
}
// FinalCLTVDelta is the minimum CLTV delta to use for the final hop on the

View File

@ -309,7 +309,11 @@ func newRoute(sourceVertex route.Vertex,
// we can assume the relevant payment is the only one in the
// payment set.
if blindedPayment == nil {
blindedPayment = blindedPathSet.GetPath()
var err error
blindedPayment, err = blindedPathSet.IntroNodeOnlyPath()
if err != nil {
return nil, err
}
}
var (

View File

@ -3296,10 +3296,21 @@ func TestBlindedRouteConstruction(t *testing.T) {
daveEveEdge := blindedEdges[daveBlindedVertex][0]
edges := []*unifiedEdge{
{policy: aliceBobEdge},
{policy: bobCarolEdge},
{policy: carolDaveEdge.EdgePolicy()},
{policy: daveEveEdge.EdgePolicy()},
{
policy: aliceBobEdge,
},
{
policy: bobCarolEdge,
blindedPayment: blindedPayment,
},
{
policy: carolDaveEdge.EdgePolicy(),
blindedPayment: blindedPayment,
},
{
policy: daveEveEdge.EdgePolicy(),
blindedPayment: blindedPayment,
},
}
// Total timelock for the route should include:

View File

@ -505,12 +505,7 @@ func NewRouteRequest(source route.Vertex, target *route.Vertex,
)
if blindedPathSet != nil {
blindedPayment := blindedPathSet.GetPath()
introVertex := route.NewVertex(
blindedPayment.BlindedPath.IntroductionPoint,
)
if source == introVertex {
if blindedPathSet.IsIntroNode(source) {
return nil, ErrSelfIntro
}