routing: move unreadable failure handling into mission control
This commit is contained in:
parent
934ea8e78d
commit
334b6a3bfe
@ -390,29 +390,40 @@ func (m *MissionControl) GetHistorySnapshot() *MissionControlSnapshot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReportPaymentFail reports a failed payment to mission control as input for
|
// ReportPaymentFail reports a failed payment to mission control as input for
|
||||||
// future probability estimates. It returns a bool indicating whether this error
|
// future probability estimates. The failureSourceIdx argument indicates the
|
||||||
// is a final error and no further payment attempts need to be made.
|
// failure source. If it is nil, the failure source is unknown. This function
|
||||||
|
// returns a bool indicating whether this error is a final error. If it is
|
||||||
|
// final, a failure reason is returned and no further payment attempts need to
|
||||||
|
// be made.
|
||||||
func (m *MissionControl) ReportPaymentFail(rt *route.Route,
|
func (m *MissionControl) ReportPaymentFail(rt *route.Route,
|
||||||
failureSourceIdx int, failure lnwire.FailureMessage) (bool,
|
failureSourceIdx *int, failure lnwire.FailureMessage) (bool,
|
||||||
channeldb.FailureReason) {
|
channeldb.FailureReason) {
|
||||||
|
|
||||||
var (
|
var failureSourceIdxInt int
|
||||||
failureVertex route.Vertex
|
if failureSourceIdx == nil {
|
||||||
)
|
// If the failure message could not be decrypted, attribute the
|
||||||
|
// failure to our own outgoing channel.
|
||||||
|
//
|
||||||
|
// TODO(joostager): Penalize all channels in the route.
|
||||||
|
failureSourceIdxInt = 0
|
||||||
|
failure = lnwire.NewTemporaryChannelFailure(nil)
|
||||||
|
} else {
|
||||||
|
failureSourceIdxInt = *failureSourceIdx
|
||||||
|
}
|
||||||
|
|
||||||
// For any non-self failure, look up the source pub key in the hops
|
var failureVertex route.Vertex
|
||||||
// slice. Otherwise return the self node pubkey.
|
|
||||||
if failureSourceIdx > 0 {
|
if failureSourceIdxInt > 0 {
|
||||||
failureVertex = rt.Hops[failureSourceIdx-1].PubKeyBytes
|
failureVertex = rt.Hops[failureSourceIdxInt-1].PubKeyBytes
|
||||||
} else {
|
} else {
|
||||||
failureVertex = rt.SourcePubKey
|
failureVertex = rt.SourcePubKey
|
||||||
}
|
}
|
||||||
log.Tracef("Node %x (index %v) reported failure when sending htlc",
|
log.Tracef("Node %x (index %v) reported failure when sending htlc",
|
||||||
failureVertex, failureSourceIdx)
|
failureVertex, failureSourceIdx)
|
||||||
|
|
||||||
// Always determine chan id ourselves, because a channel
|
// Always determine chan id ourselves, because a channel update with id
|
||||||
// update with id may not be available.
|
// may not be available.
|
||||||
failedEdge, failedAmt := getFailedEdge(rt, failureSourceIdx)
|
failedEdge, failedAmt := getFailedEdge(rt, failureSourceIdxInt)
|
||||||
|
|
||||||
switch failure.(type) {
|
switch failure.(type) {
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ func (ctx *mcTestContext) reportFailure(t time.Time,
|
|||||||
|
|
||||||
errorSourceIdx := 1
|
errorSourceIdx := 1
|
||||||
ctx.mc.ReportPaymentFail(
|
ctx.mc.ReportPaymentFail(
|
||||||
mcTestRoute, errorSourceIdx, failure,
|
mcTestRoute, &errorSourceIdx, failure,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ type mockMissionControl struct {
|
|||||||
var _ MissionController = (*mockMissionControl)(nil)
|
var _ MissionController = (*mockMissionControl)(nil)
|
||||||
|
|
||||||
func (m *mockMissionControl) ReportPaymentFail(rt *route.Route,
|
func (m *mockMissionControl) ReportPaymentFail(rt *route.Route,
|
||||||
failureSourceIdx int, failure lnwire.FailureMessage) (bool,
|
failureSourceIdx *int, failure lnwire.FailureMessage) (bool,
|
||||||
channeldb.FailureReason) {
|
channeldb.FailureReason) {
|
||||||
|
|
||||||
return false, 0
|
return false, 0
|
||||||
|
@ -179,7 +179,7 @@ type MissionController interface {
|
|||||||
// whether this error is a final error and no further payment attempts
|
// whether this error is a final error and no further payment attempts
|
||||||
// need to be made.
|
// need to be made.
|
||||||
ReportPaymentFail(rt *route.Route,
|
ReportPaymentFail(rt *route.Route,
|
||||||
failureSourceIdx int, failure lnwire.FailureMessage) (bool,
|
failureSourceIdx *int, failure lnwire.FailureMessage) (bool,
|
||||||
channeldb.FailureReason)
|
channeldb.FailureReason)
|
||||||
|
|
||||||
// GetEdgeProbability is expected to return the success probability of a
|
// GetEdgeProbability is expected to return the success probability of a
|
||||||
@ -1893,21 +1893,16 @@ func (r *ChannelRouter) tryApplyChannelUpdate(rt *route.Route,
|
|||||||
// error type, this error is either the final outcome of the payment or we need
|
// 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
|
// to continue with an alternative route. This is indicated by the boolean
|
||||||
// return value.
|
// return value.
|
||||||
func (r *ChannelRouter) processSendError(rt *route.Route, sendErr error) (
|
func (r *ChannelRouter) processSendError(rt *route.Route, sendErr error) (bool,
|
||||||
bool, channeldb.FailureReason) {
|
channeldb.FailureReason) {
|
||||||
|
|
||||||
// If the failure message could not be decrypted, attribute the failure
|
|
||||||
// to our own outgoing channel.
|
|
||||||
//
|
|
||||||
// TODO(joostager): Penalize all channels in the route.
|
|
||||||
if sendErr == htlcswitch.ErrUnreadableFailureMessage {
|
if sendErr == htlcswitch.ErrUnreadableFailureMessage {
|
||||||
sendErr = &htlcswitch.ForwardingError{
|
log.Tracef("Unreadable failure when sending htlc")
|
||||||
FailureSourceIdx: 0,
|
|
||||||
FailureMessage: lnwire.NewTemporaryChannelFailure(nil),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an internal, non-forwarding error occurred, we can stop trying.
|
return r.cfg.MissionControl.ReportPaymentFail(rt, nil, nil)
|
||||||
|
}
|
||||||
|
// If an internal, non-forwarding error occurred, we can stop
|
||||||
|
// trying.
|
||||||
fErr, ok := sendErr.(*htlcswitch.ForwardingError)
|
fErr, ok := sendErr.(*htlcswitch.ForwardingError)
|
||||||
if !ok {
|
if !ok {
|
||||||
return true, channeldb.FailureReasonError
|
return true, channeldb.FailureReasonError
|
||||||
@ -1927,8 +1922,11 @@ func (r *ChannelRouter) processSendError(rt *route.Route, sendErr error) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Tracef("Node=%v reported failure when sending htlc",
|
||||||
|
failureSourceIdx)
|
||||||
|
|
||||||
return r.cfg.MissionControl.ReportPaymentFail(
|
return r.cfg.MissionControl.ReportPaymentFail(
|
||||||
rt, failureSourceIdx, failureMessage,
|
rt, &failureSourceIdx, failureMessage,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user