routing: add result interpretation for intermediate invalid blinding
This commit adds handling for route blinding errors that are reported by the introduction node in a multi-hop blinded route. As the introduction node is always responsible for handling blinded errors, it is not penalized - only the final hop is penalized to discourage the blinded route without filling up mission control with ephemeral results. If this error code is reported by a node that is not an introduction node, we penalize the node because it is returning an error code that it should not be using.
This commit is contained in:
2 files changed
+187
No files matched your search
@@ -75,6 +75,22 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
// blindedSingleHop is a blinded path with a single blinded hop after
|
||||
// the introduction node.
|
||||
blindedSingleHop = route.Route{
|
||||
SourcePubKey: hops[0],
|
||||
TotalAmount: 100,
|
||||
Hops: []*route.Hop{
|
||||
{PubKeyBytes: hops[1], AmtToForward: 99},
|
||||
{
|
||||
PubKeyBytes: hops[2],
|
||||
AmtToForward: 95,
|
||||
BlindingPoint: blindingPoint,
|
||||
},
|
||||
{PubKeyBytes: hops[3], AmtToForward: 88},
|
||||
},
|
||||
}
|
||||
|
||||
// blindedMultiToIntroduction is a blinded path which goes directly
|
||||
// to the introduction node, with multiple blinded hops after it.
|
||||
blindedMultiToIntroduction = route.Route{
|
||||
@@ -451,6 +467,113 @@ var resultTestCases = []resultTestCase{
|
||||
finalFailureReason: &reasonError,
|
||||
},
|
||||
},
|
||||
// Test a multi-hop blinded route where the failure occurs at the
|
||||
// introduction point.
|
||||
{
|
||||
name: "blinded multi-hop introduction",
|
||||
route: &blindedMultiHop,
|
||||
failureSrcIdx: 2,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
getTestPair(0, 1): successPairResult(100),
|
||||
getTestPair(1, 2): successPairResult(99),
|
||||
getTestPair(3, 4): failPairResult(88),
|
||||
},
|
||||
},
|
||||
},
|
||||
// Test a multi-hop blinded route where the failure occurs at the
|
||||
// introduction point, which is a direct peer.
|
||||
{
|
||||
name: "blinded multi-hop introduction peer",
|
||||
route: &blindedMultiToIntroduction,
|
||||
failureSrcIdx: 1,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
getTestPair(0, 1): successPairResult(100),
|
||||
getTestPair(2, 3): failPairResult(75),
|
||||
},
|
||||
},
|
||||
},
|
||||
// Test a single-hop blinded route where the recipient is directly
|
||||
// connected to the introduction node.
|
||||
{
|
||||
name: "blinded single hop introduction failure",
|
||||
route: &blindedSingleHop,
|
||||
failureSrcIdx: 2,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
getTestPair(0, 1): successPairResult(100),
|
||||
getTestPair(1, 2): successPairResult(99),
|
||||
},
|
||||
finalFailureReason: &reasonError,
|
||||
},
|
||||
},
|
||||
// Test the case where a node before the introduction node returns a
|
||||
// blinding error and is penalized for returning the wrong error.
|
||||
{
|
||||
name: "error before introduction",
|
||||
route: &blindedMultiHop,
|
||||
failureSrcIdx: 1,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
// Failures from failing hops[1].
|
||||
getTestPair(0, 1): failPairResult(0),
|
||||
getTestPair(1, 0): failPairResult(0),
|
||||
getTestPair(1, 2): failPairResult(0),
|
||||
getTestPair(2, 1): failPairResult(0),
|
||||
},
|
||||
nodeFailure: &hops[1],
|
||||
},
|
||||
},
|
||||
// Test the case where an intermediate node that is not in a blinded
|
||||
// route returns an invalid blinding error and there was one
|
||||
// successful hop before the incorrect error.
|
||||
{
|
||||
name: "intermediate unexpected blinding",
|
||||
route: &routeThreeHop,
|
||||
failureSrcIdx: 2,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
getTestPair(0, 1): successPairResult(100),
|
||||
// Failures from failing hops[2].
|
||||
getTestPair(1, 2): failPairResult(0),
|
||||
getTestPair(2, 1): failPairResult(0),
|
||||
getTestPair(2, 3): failPairResult(0),
|
||||
getTestPair(3, 2): failPairResult(0),
|
||||
},
|
||||
nodeFailure: &hops[2],
|
||||
},
|
||||
},
|
||||
// Test the case where an intermediate node that is not in a blinded
|
||||
// route returns an invalid blinding error and there were no successful
|
||||
// hops before the erring incoming link (the erring node if our peer).
|
||||
{
|
||||
name: "peer unexpected blinding",
|
||||
route: &routeThreeHop,
|
||||
failureSrcIdx: 1,
|
||||
failure: &lnwire.FailInvalidBlinding{},
|
||||
|
||||
expectedResult: &interpretedResult{
|
||||
pairResults: map[DirectedNodePair]pairResult{
|
||||
// Failures from failing hops[1].
|
||||
getTestPair(0, 1): failPairResult(0),
|
||||
getTestPair(1, 0): failPairResult(0),
|
||||
getTestPair(1, 2): failPairResult(0),
|
||||
getTestPair(2, 1): failPairResult(0),
|
||||
},
|
||||
nodeFailure: &hops[1],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// TestResultInterpretation executes a list of test cases that test the result
|
||||
|
||||
Reference in new issue
Block a user