From 2f8021d8dbaae1260ceef243907dc701a3eab98d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 30 Oct 2019 21:18:52 -0700 Subject: [PATCH] routing/result_interpretation: fix off-by-one for incoming failure Previously we would not mark a success for the first hop if the fail source index was 2. We also add a test to assert this behavior. --- routing/result_interpretation.go | 2 +- routing/result_interpretation_test.go | 31 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/routing/result_interpretation.go b/routing/result_interpretation.go index 696d930c..643d4df0 100644 --- a/routing/result_interpretation.go +++ b/routing/result_interpretation.go @@ -265,7 +265,7 @@ func (i *interpretedResult) processPaymentOutcomeIntermediate( // All nodes up to the failing pair must have forwarded // successfully. - if errorSourceIdx > 2 { + if errorSourceIdx > 1 { i.successPairRange(route, 0, errorSourceIdx-2) } } diff --git a/routing/result_interpretation_test.go b/routing/result_interpretation_test.go index 78b6088a..1bf0fa90 100644 --- a/routing/result_interpretation_test.go +++ b/routing/result_interpretation_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" + "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -47,6 +48,11 @@ func getTestPair(from, to int) DirectedNodePair { return NewDirectedNodePair(hops[from], hops[to]) } +func getPolicyFailure(from, to int) *DirectedNodePair { + pair := getTestPair(from, to) + return &pair +} + type resultTestCase struct { name string route *route.Route @@ -169,6 +175,28 @@ var resultTestCases = []resultTestCase{ }, }, }, + + // Tests that a fee insufficient failure to an intermediate hop with + // index 2 results in the first hop marked as success, and then a + // bidirectional failure for the incoming channel. It should also result + // in a policy failure for the outgoing hop. + { + name: "fail fee insufficient intermediate", + route: &routeFourHop, + failureSrcIdx: 2, + failure: lnwire.NewFeeInsufficient(0, lnwire.ChannelUpdate{}), + + expectedResult: &interpretedResult{ + pairResults: map[DirectedNodePair]pairResult{ + getTestPair(0, 1): { + success: true, + }, + getTestPair(1, 2): {}, + getTestPair(2, 1): {}, + }, + policyFailure: getPolicyFailure(2, 3), + }, + }, } // TestResultInterpretation executes a list of test cases that test the result @@ -192,7 +220,8 @@ func TestResultInterpretation(t *testing.T) { } if !reflect.DeepEqual(i, expected) { - t.Fatal("unexpected result") + t.Fatalf("unexpected result\nwant: %v\ngot: %v", + spew.Sdump(expected), spew.Sdump(i)) } }) }