From 8055bcf2e0496b3edbc9b0601108911f8a61f03f Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Wed, 26 Jun 2019 08:52:49 +0200 Subject: [PATCH] routing: report failures to mission control directly As there is no more state kept in the payment session, failure reporting can go straight to mission control. --- routing/payment_lifecycle.go | 2 +- routing/payment_session.go | 67 ------------------------------------ routing/router.go | 34 +++++++++--------- 3 files changed, 18 insertions(+), 85 deletions(-) diff --git a/routing/payment_lifecycle.go b/routing/payment_lifecycle.go index 32f6883ea..4de85b5dc 100644 --- a/routing/payment_lifecycle.go +++ b/routing/payment_lifecycle.go @@ -343,7 +343,7 @@ func (p *paymentLifecycle) sendPaymentAttempt(firstHop lnwire.ShortChannelID, func (p *paymentLifecycle) handleSendError(sendErr error) error { final, reason := p.router.processSendError( - p.paySession, &p.attempt.Route, sendErr, + &p.attempt.Route, sendErr, ) if !final { // Save the forwarding error so it can be returned if diff --git a/routing/payment_session.go b/routing/payment_session.go index f138ae315..44abeae9f 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -16,27 +16,6 @@ type PaymentSession interface { // specified HTLC payment to the target node. RequestRoute(payment *LightningPayment, height uint32, finalCltvDelta uint16) (*route.Route, error) - - // ReportVertexFailure reports to the PaymentSession that the passsed - // vertex failed to route the previous payment attempt. The - // PaymentSession will use this information to produce a better next - // route. - ReportVertexFailure(v route.Vertex) - - // ReportEdgeFailure reports to the PaymentSession that the passed edge - // failed to route the previous payment attempt. A minimum penalization - // amount is included to attenuate the failure. This is set to a - // non-zero value for channel balance failures. The PaymentSession will - // use this information to produce a better next route. - ReportEdgeFailure(failedEdge edge, minPenalizeAmt lnwire.MilliSatoshi) - - // ReportEdgePolicyFailure reports to the PaymentSession that we - // received a failure message that relates to a channel policy. For - // these types of failures, the PaymentSession can decide whether to to - // keep the edge included in the next attempted route. The - // PaymentSession will use this information to produce a better next - // route. - ReportEdgePolicyFailure(failedEdge edge) } // paymentSession is used during an HTLC routings session to prune the local @@ -60,52 +39,6 @@ type paymentSession struct { pathFinder pathFinder } -// A compile time assertion to ensure paymentSession meets the PaymentSession -// interface. -var _ PaymentSession = (*paymentSession)(nil) - -// ReportVertexFailure adds a vertex to the graph prune view after a client -// reports a routing failure localized to the vertex. The time the vertex was -// added is noted, as it'll be pruned from the shared view after a period of -// vertexDecay. However, the vertex will remain pruned for the *local* session. -// This ensures we don't retry this vertex during the payment attempt. -// -// NOTE: Part of the PaymentSession interface. -func (p *paymentSession) ReportVertexFailure(v route.Vertex) { - p.sessionSource.MissionControl.ReportVertexFailure(v) -} - -// ReportEdgeFailure adds a channel to the graph prune view. The time the -// channel was added is noted, as it'll be pruned from the global view after a -// period of edgeDecay. However, the edge will remain pruned for the duration -// of the *local* session. This ensures that we don't flap by continually -// retrying an edge after its pruning has expired. -// -// TODO(roasbeef): also add value attempted to send and capacity of channel -// -// NOTE: Part of the PaymentSession interface. -func (p *paymentSession) ReportEdgeFailure(failedEdge edge, - minPenalizeAmt lnwire.MilliSatoshi) { - - p.sessionSource.MissionControl.ReportEdgeFailure( - failedEdge, minPenalizeAmt, - ) -} - -// ReportEdgePolicyFailure handles a failure message that relates to a -// channel policy. For these types of failures, the policy is updated and we -// want to keep it included during path finding. This function does mark the -// edge as 'policy failed once'. The next time it fails, the whole node will be -// pruned. This is to prevent nodes from keeping us busy by continuously sending -// new channel updates. -// -// NOTE: Part of the PaymentSession interface. -// -// TODO(joostjager): Move this logic into global mission control. -func (p *paymentSession) ReportEdgePolicyFailure(failedEdge edge) { - p.sessionSource.MissionControl.ReportEdgePolicyFailure(failedEdge) -} - // RequestRoute returns a route which is likely to be capable for successfully // routing the specified HTLC payment to the target node. Initially the first // set of paths returned from this method may encounter routing failure along diff --git a/routing/router.go b/routing/router.go index 0fd1caf99..4df236d55 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1875,8 +1875,8 @@ func (r *ChannelRouter) tryApplyChannelUpdate(rt *route.Route, // error type, this error is either the final outcome of the payment or we need // to continue with an alternative route. This is indicated by the boolean // return value. -func (r *ChannelRouter) processSendError(paySession PaymentSession, - rt *route.Route, sendErr error) (bool, channeldb.FailureReason) { +func (r *ChannelRouter) processSendError(rt *route.Route, sendErr error) ( + bool, channeldb.FailureReason) { // If the failure message could not be decrypted, attribute the failure // to our own outgoing channel. @@ -1981,7 +1981,7 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession, // that sent us this error, as it doesn't now what the // correct block height is. case *lnwire.FailExpiryTooSoon: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 // If we hit an instance of onion payload corruption or an invalid @@ -2001,49 +2001,49 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession, // amount, we'll apply the new minimum amount and retry // routing. case *lnwire.FailAmountBelowMinimum: - paySession.ReportEdgePolicyFailure(failedEdge) + r.cfg.MissionControl.ReportEdgePolicyFailure(failedEdge) return false, 0 // If we get a failure due to a fee, we'll apply the // new fee update, and retry our attempt using the // newly updated fees. case *lnwire.FailFeeInsufficient: - paySession.ReportEdgePolicyFailure(failedEdge) + r.cfg.MissionControl.ReportEdgePolicyFailure(failedEdge) return false, 0 // If we get the failure for an intermediate node that // disagrees with our time lock values, then we'll // apply the new delta value and try it once more. case *lnwire.FailIncorrectCltvExpiry: - paySession.ReportEdgePolicyFailure(failedEdge) + r.cfg.MissionControl.ReportEdgePolicyFailure(failedEdge) return false, 0 // The outgoing channel that this node was meant to // forward one is currently disabled, so we'll apply // the update and continue. case *lnwire.FailChannelDisabled: - paySession.ReportEdgeFailure(failedEdge, 0) + r.cfg.MissionControl.ReportEdgeFailure(failedEdge, 0) return false, 0 // It's likely that the outgoing channel didn't have // sufficient capacity, so we'll prune this edge for // now, and continue onwards with our path finding. case *lnwire.FailTemporaryChannelFailure: - paySession.ReportEdgeFailure(failedEdge, failedAmt) + r.cfg.MissionControl.ReportEdgeFailure(failedEdge, failedAmt) return false, 0 // If the send fail due to a node not having the // required features, then we'll note this error and // continue. case *lnwire.FailRequiredNodeFeatureMissing: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 // If the send fail due to a node not having the // required features, then we'll note this error and // continue. case *lnwire.FailRequiredChannelFeatureMissing: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 // If the next hop in the route wasn't known or @@ -2054,18 +2054,18 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession, // returning errors in order to attempt to black list // another node. case *lnwire.FailUnknownNextPeer: - paySession.ReportEdgeFailure(failedEdge, 0) + r.cfg.MissionControl.ReportEdgeFailure(failedEdge, 0) return false, 0 // If the node wasn't able to forward for which ever // reason, then we'll note this and continue with the // routes. case *lnwire.FailTemporaryNodeFailure: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 case *lnwire.FailPermanentNodeFailure: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 // If we crafted a route that contains a too long time @@ -2078,15 +2078,15 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession, // that as a hint during future path finding through // that node. case *lnwire.FailExpiryTooFar: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 // If we get a permanent channel or node failure, then // we'll prune the channel in both directions and // continue with the rest of the routes. case *lnwire.FailPermanentChannelFailure: - paySession.ReportEdgeFailure(failedEdge, 0) - paySession.ReportEdgeFailure(edge{ + r.cfg.MissionControl.ReportEdgeFailure(failedEdge, 0) + r.cfg.MissionControl.ReportEdgeFailure(edge{ from: failedEdge.to, to: failedEdge.from, channel: failedEdge.channel, @@ -2095,7 +2095,7 @@ func (r *ChannelRouter) processSendError(paySession PaymentSession, // Any other failure or an empty failure will get the node pruned. default: - paySession.ReportVertexFailure(failureVertex) + r.cfg.MissionControl.ReportVertexFailure(failureVertex) return false, 0 } }