Skip to content

Commit

Permalink
routing: add handling for blinded errors from final node
Browse files Browse the repository at this point in the history
We do not expect blinding errors from the final node:
1. If the introduction is the recipient, they should use regular errors.
2. Otherwise, nodes have no business sending this error when they are
   not part of a blinded route.
  • Loading branch information
carlaKC committed Nov 6, 2023
1 parent 633a06f commit e77ab31
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
15 changes: 15 additions & 0 deletions routing/result_interpretation.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,21 @@ func (i *interpretedResult) processPaymentOutcomeFinal(
// destination correctly. Continue the payment process.
i.successPairRange(route, 0, n-1)

// We do not expect to receive an invalid blinding error from the final
// node in the route. This could erroneously happen in the following
// cases:
// 1. Unblinded node: misuses the error code.
// 2. A receiving introduction node: erroneously sends the error code,
// as the spec indicates that receiving introduction nodes should
// use regular errors.
//
// Note that we expect the case where this error is sent from a node
// after the introduction node to be handled elsewhere as this is part
// of a more general class of errors where the introduction node has
// failed to convert errors for the blinded route.
case *lnwire.FailInvalidBlinding:
failNode()

// All other errors are considered terminal if coming from the
// final hop. They indicate that something is wrong at the
// recipient, so we do apply a penalty.
Expand Down
50 changes: 50 additions & 0 deletions routing/result_interpretation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ var (
{PubKeyBytes: hops[3], AmtToForward: 58},
},
}

// blindedIntroReceiver is a blinded path where the introduction node
// is the recipient.
blindedIntroReceiver = route.Route{
SourcePubKey: hops[0],
TotalAmount: 100,
Hops: []*route.Hop{
{PubKeyBytes: hops[1], AmtToForward: 95},
{
PubKeyBytes: hops[2],
AmtToForward: 90,
BlindingPoint: blindingPoint,
},
},
}
)

func getTestPair(from, to int) DirectedNodePair {
Expand Down Expand Up @@ -575,6 +590,41 @@ var resultTestCases = []resultTestCase{
nodeFailure: &hops[1],
},
},
// Non-blinded node returns a blinding related error.
{
name: "final node unexpected blinding",
route: &routeThreeHop,
failureSrcIdx: 3,
failure: &lnwire.FailInvalidBlinding{},

expectedResult: &interpretedResult{
pairResults: map[DirectedNodePair]pairResult{
getTestPair(0, 1): successPairResult(100),
getTestPair(1, 2): successPairResult(99),
getTestPair(2, 3): failPairResult(0),
getTestPair(3, 2): failPairResult(0),
},
nodeFailure: &hops[3],
finalFailureReason: &reasonError,
},
},
// Introduction node returns invalid blinding erroneously.
{
name: "final node intro blinding",
route: &blindedIntroReceiver,
failureSrcIdx: 2,
failure: &lnwire.FailInvalidBlinding{},

expectedResult: &interpretedResult{
pairResults: map[DirectedNodePair]pairResult{
getTestPair(0, 1): successPairResult(100),
getTestPair(1, 2): failPairResult(0),
getTestPair(2, 1): failPairResult(0),
},
nodeFailure: &hops[2],
finalFailureReason: &reasonError,
},
},
}

// TestResultInterpretation executes a list of test cases that test the result
Expand Down

0 comments on commit e77ab31

Please sign in to comment.