Merge pull request #1121 from Roasbeef/mission-control-less-vertex-pruning

routing: stop pruning edges in response to FailUnknownNextPeer
This commit is contained in:
Olaoluwa Osuntokun 2018-04-24 18:43:15 -07:00 committed by GitHub
commit 91edf5ea07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 14 deletions

@ -1819,12 +1819,14 @@ func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte, *Route
continue continue
// If the next hop in the route wasn't known or // If the next hop in the route wasn't known or
// offline, we'll prune the _next_ hop from the set of // offline, we'll only the channel which we attempted
// routes and retry. // to route over. This is conservative, and it can
// handle faulty channels between nodes properly.
// Additionally, this guards against routing nodes
// returning errors in order to attempt to black list
// another node.
case *lnwire.FailUnknownNextPeer: case *lnwire.FailUnknownNextPeer:
pruneVertexFailure( pruneEdgeFailure(paySession, route, errSource)
paySession, route, errSource, true,
)
continue continue
// If the node wasn't able to forward for which ever // If the node wasn't able to forward for which ever

@ -607,20 +607,34 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
return preImage, nil return preImage, nil
} }
// The final error returned should also indicate that the peer wasn't // This shouldn't return an error, as we'll make a payment attempt via
// online (the last error we returned). // the satoshi channel based on the assumption that there might be an
_, _, err = ctx.router.SendPayment(&payment) // intermittent issue with the roasbeef <-> lioji channel.
if err == nil { paymentPreImage, route, err := ctx.router.SendPayment(&payment)
t.Fatalf("payment didn't return error") if err != nil {
t.Fatalf("unable send payment: %v", err)
} }
if !strings.Contains(err.Error(), "UnknownNextPeer") {
t.Fatalf("expected UnknownNextPeer instead got: %v", err) // This path should go: roasbeef -> satoshi -> luoji
if len(route.Hops) != 2 {
t.Fatalf("incorrect route length: expected %v got %v", 2,
len(route.Hops))
}
if !bytes.Equal(paymentPreImage[:], preImage[:]) {
t.Fatalf("incorrect preimage used: expected %x got %x",
preImage[:], paymentPreImage[:])
}
if route.Hops[0].Channel.Node.Alias != "satoshi" {
t.Fatalf("route should go through satoshi as first hop, "+
"instead passes through: %v",
route.Hops[0].Channel.Node.Alias)
} }
ctx.router.missionControl.ResetHistory() ctx.router.missionControl.ResetHistory()
// Finally, we'll modify the SendToSwitch function to indicate that the // Finally, we'll modify the SendToSwitch function to indicate that the
// roasbeef -> luoji channel has insufficient capacity. // roasbeef -> luoji channel has insufficient capacity. This should
// again cause us to instead go via the satoshi route.
ctx.router.cfg.SendToSwitch = func(n [33]byte, ctx.router.cfg.SendToSwitch = func(n [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) { if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) {
@ -635,7 +649,7 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
return preImage, nil return preImage, nil
} }
paymentPreImage, route, err := ctx.router.SendPayment(&payment) paymentPreImage, route, err = ctx.router.SendPayment(&payment)
if err != nil { if err != nil {
t.Fatalf("unable to send payment: %v", err) t.Fatalf("unable to send payment: %v", err)
} }