diff --git a/docs/release-notes/release-notes-0.14.0.md b/docs/release-notes/release-notes-0.14.0.md index 5c9721f98..3051ea2da 100644 --- a/docs/release-notes/release-notes-0.14.0.md +++ b/docs/release-notes/release-notes-0.14.0.md @@ -479,6 +479,12 @@ messages directly. There is no routing/path finding involved. * [Save compressed log files from logrorate during itest](https://github.com/lightningnetwork/lnd/pull/5354). +## Mission control + +* [Interpretation of channel disabled errors was changed to only penalize t + he destination node to consider mobile wallets with hub + nodes.](https://github.com/lightningnetwork/lnd/pull/5598) + ## Bug Fixes * A bug has been fixed that would cause `lnd` to [try to bootstrap using the diff --git a/routing/result_interpretation.go b/routing/result_interpretation.go index 70cc08f6a..19c43e4a1 100644 --- a/routing/result_interpretation.go +++ b/routing/result_interpretation.go @@ -335,6 +335,23 @@ func (i *interpretedResult) processPaymentOutcomeIntermediate( case *lnwire.FailUnknownNextPeer: reportOutgoing() + // Some implementations use this error when the next hop is offline, so we + // do the same as FailUnknownNextPeer and also process the channel update. + case *lnwire.FailChannelDisabled: + + // Set the node pair for which a channel update may be out of + // date. The second chance logic uses the policyFailure field. + i.policyFailure = &DirectedNodePair{ + From: route.Hops[errorSourceIdx-1].PubKeyBytes, + To: route.Hops[errorSourceIdx].PubKeyBytes, + } + + reportOutgoing() + + // All nodes up to the failing pair must have forwarded + // successfully. + i.successPairRange(route, 0, errorSourceIdx-1) + // If we get a permanent channel, we'll prune the channel set in both // directions and continue with the rest of the routes. case *lnwire.FailPermanentChannelFailure: @@ -349,8 +366,7 @@ func (i *interpretedResult) processPaymentOutcomeIntermediate( // control. case *lnwire.FailAmountBelowMinimum, *lnwire.FailFeeInsufficient, - *lnwire.FailIncorrectCltvExpiry, - *lnwire.FailChannelDisabled: + *lnwire.FailIncorrectCltvExpiry: // Set the node pair for which a channel update may be out of // date. The second chance logic uses the policyFailure field. diff --git a/routing/result_interpretation_test.go b/routing/result_interpretation_test.go index 2fc0a7d90..954f07981 100644 --- a/routing/result_interpretation_test.go +++ b/routing/result_interpretation_test.go @@ -349,6 +349,24 @@ var resultTestCases = []resultTestCase{ nodeFailure: nil, }, }, + + // Test a channel disabled failure from the final hop in two hops. Only the + // disabled channel should be penalized for any amount. + { + name: "two hop channel disabled", + route: &routeTwoHop, + failureSrcIdx: 1, + failure: &lnwire.FailChannelDisabled{}, + + expectedResult: &interpretedResult{ + pairResults: map[DirectedNodePair]pairResult{ + getTestPair(1, 2): failPairResult(0), + getTestPair(2, 1): failPairResult(0), + getTestPair(0, 1): successPairResult(100), + }, + policyFailure: getPolicyFailure(1, 2), + }, + }, } // TestResultInterpretation executes a list of test cases that test the result