From e99c63c804cafae97ffc247ef85472d1842e6ea9 Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Mon, 16 May 2022 07:02:34 +0800 Subject: [PATCH] routing: add `SendToRouteSkipTempErr` to skip temp error failure This commit adds a new method `SendToRouteSkipTempErr` that skips failing the payment unless a terminal error occurred. This is accomplished by demoting the original `SendToRoute` to a private method and creating two new methods on top of it to minimize code change. --- routing/router.go | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/routing/router.go b/routing/router.go index 1c90eba6d..348914db7 100644 --- a/routing/router.go +++ b/routing/router.go @@ -2155,13 +2155,30 @@ func (r *ChannelRouter) preparePayment(payment *LightningPayment) ( return paySession, shardTracker, nil } -// SendToRoute attempts to send a payment with the given hash through the +// SendToRoute sends a payment using the provided route and fails the payment +// when an error is returned from the attempt. +func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, + rt *route.Route) (*channeldb.HTLCAttempt, error) { + + return r.sendToRoute(htlcHash, rt, false) +} + +// SendToRouteSkipTempErr sends a payment using the provided route and fails +// the payment ONLY when a terminal error is returned from the attempt. +func (r *ChannelRouter) SendToRouteSkipTempErr(htlcHash lntypes.Hash, + rt *route.Route) (*channeldb.HTLCAttempt, error) { + + return r.sendToRoute(htlcHash, rt, true) +} + +// sendToRoute attempts to send a payment with the given hash through the // provided route. This function is blocking and will return the attempt // information as it is stored in the database. For a successful htlc, this // information will contain the preimage. If an error occurs after the attempt -// was initiated, both return values will be non-nil. -func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, rt *route.Route) ( - *channeldb.HTLCAttempt, error) { +// was initiated, both return values will be non-nil. If skipTempErr is true, +// the payment won't be failed unless a terminal error has occurred. +func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route, + skipTempErr bool) (*channeldb.HTLCAttempt, error) { // Calculate amount paid to receiver. amt := rt.ReceiverAmt() @@ -2281,10 +2298,9 @@ func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, rt *route.Route) ( err = sh.handleSendError(attempt, shardError) switch { - // If we weren't able to extract a proper failure reason (which can - // happen if the second chance logic is triggered), then we'll use the - // normal no route error. - case err == nil: + // If a non-terminal error is returned and `skipTempErr` is false, then + // we'll use the normal no route error. + case err == nil && !skipTempErr: err = r.cfg.Control.Fail( paymentIdentifier, channeldb.FailureReasonNoRoute, )