-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Update routing hints upon insufficient fees failure. #2151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3f982da
fdeb896
40de2ed
718a2e0
3d2cea0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import ( | |
| "bytes" | ||
| "crypto/sha256" | ||
| "fmt" | ||
| "math" | ||
| "runtime" | ||
| "sort" | ||
| "sync" | ||
|
|
@@ -1208,15 +1209,19 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error { | |
| // Now that we know this isn't a stale update, we'll apply the | ||
| // new edge policy to the proper directional edge within the | ||
| // channel graph. | ||
| if err = r.cfg.Graph.UpdateEdgePolicy(msg); err != nil { | ||
| err := errors.Errorf("unable to add channel: %v", err) | ||
| log.Error(err) | ||
| return err | ||
| } | ||
| if exists { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a fix in itself? Ideally this could be yet another separate commit, but if you find it too small for that, it's fine with me.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to add it as otherwise you would get errors on applyChannelUpdate when trying to update private channels hops.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think maybe the proper fix here is something like this: ad92e5c (feel free to cherry-pick it into this PR if needed). I believe then you wouldn't have to flip the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created #2549
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be removed now that #2549 is merged. |
||
| err = r.cfg.Graph.UpdateEdgePolicy(msg) | ||
| if err != nil { | ||
| err := errors.Errorf("unable to update "+ | ||
| "channel policy: %v", err) | ||
| log.Error(err) | ||
| return err | ||
| } | ||
|
|
||
| invalidateCache = true | ||
| log.Tracef("New channel update applied: %v", | ||
| newLogClosure(func() string { return spew.Sdump(msg) })) | ||
| invalidateCache = true | ||
| log.Tracef("New channel update applied: %v", | ||
| newLogClosure(func() string { return spew.Sdump(msg) })) | ||
| } | ||
|
|
||
| default: | ||
| return errors.Errorf("wrong routing update message type") | ||
|
|
@@ -1805,7 +1810,9 @@ func (r *ChannelRouter) processSendError(paySession *paymentSession, | |
| // update with id may not be available. | ||
| failedEdge, err := getFailedEdge(route, errVertex) | ||
| if err != nil { | ||
| return true | ||
| // If channel identification fails, ignore the error | ||
| // message and try again, until timeout. | ||
| return false | ||
| } | ||
|
|
||
| // processChannelUpdateAndRetry is a closure that | ||
|
|
@@ -1824,7 +1831,8 @@ func (r *ChannelRouter) processSendError(paySession *paymentSession, | |
| pubKey *btcec.PublicKey) { | ||
|
|
||
| // Try to apply the channel update. | ||
| updateOk := r.applyChannelUpdate(update, pubKey) | ||
| updateOk := r.applyChannelUpdate(update, | ||
| pubKey, failedEdge) | ||
|
|
||
| // If the update could not be applied, prune the | ||
| // edge. There is no reason to continue trying | ||
|
|
@@ -1837,8 +1845,13 @@ func (r *ChannelRouter) processSendError(paySession *paymentSession, | |
| paySession.ReportEdgeFailure( | ||
| failedEdge, | ||
| ) | ||
| return | ||
| } | ||
|
|
||
| // Update routing hints. | ||
| paySession.UpdateEdgePolicy(failedEdge, update) | ||
|
|
||
| // Report edge policy failure. | ||
| paySession.ReportEdgePolicyFailure( | ||
| NewVertex(errSource), failedEdge, | ||
| ) | ||
|
|
@@ -1886,7 +1899,8 @@ 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: | ||
| r.applyChannelUpdate(&onionErr.Update, errSource) | ||
| r.applyChannelUpdate(&onionErr.Update, | ||
| errSource, failedEdge) | ||
| paySession.ReportVertexFailure(errVertex) | ||
| return false | ||
|
|
||
|
|
@@ -1931,15 +1945,17 @@ func (r *ChannelRouter) processSendError(paySession *paymentSession, | |
| // forward one is currently disabled, so we'll apply | ||
| // the update and continue. | ||
| case *lnwire.FailChannelDisabled: | ||
| r.applyChannelUpdate(&onionErr.Update, errSource) | ||
| r.applyChannelUpdate(&onionErr.Update, | ||
| errSource, failedEdge) | ||
| paySession.ReportEdgeFailure(failedEdge) | ||
| return false | ||
|
|
||
| // 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: | ||
| r.applyChannelUpdate(onionErr.Update, errSource) | ||
| r.applyChannelUpdate(onionErr.Update, | ||
| errSource, failedEdge) | ||
| paySession.ReportEdgeFailure(failedEdge) | ||
| return false | ||
|
|
||
|
|
@@ -2053,27 +2069,42 @@ func getFailedEdge(route *Route, errSource Vertex) ( | |
| // applyChannelUpdate validates a channel update and if valid, applies it to the | ||
| // database. It returns a bool indicating whether the updates was successful. | ||
| func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate, | ||
| pubKey *btcec.PublicKey) bool { | ||
| pubKey *btcec.PublicKey, e *EdgeLocator) bool { | ||
| // If we get passed a nil channel update (as it's optional with some | ||
| // onion errors), then we'll exit early with a success result. | ||
| if msg == nil { | ||
| return true | ||
| } | ||
|
|
||
| // Verify update signature validates. | ||
| if err := ValidateChannelUpdateAnn(pubKey, math.MaxInt64, msg); err != nil { | ||
| log.Errorf("Failed to validate channel update: %v", err) | ||
| return false | ||
| } | ||
|
|
||
| // If channel is in database, do further checks. Else, the | ||
| // update is for an additional private edge added by hints. | ||
| ch, _, _, err := r.GetChannelByID(msg.ShortChannelID) | ||
| if err != nil { | ||
| log.Errorf("Unable to retrieve channel by id: %v", err) | ||
| return false | ||
| return true | ||
| } | ||
|
|
||
| if err := ValidateChannelUpdateAnn(pubKey, ch.Capacity, msg); err != nil { | ||
| if err := ValidateOptionalFields(ch.Capacity, msg); err != nil { | ||
| log.Errorf("Unable to validate channel update: %v", err) | ||
| return false | ||
| } | ||
|
|
||
| // Trust the direction of the edge locator, and not the one | ||
| // in the message. | ||
| if e.Direction == 1 { | ||
| msg.ChannelFlags |= lnwire.ChanUpdateDirection | ||
| } else { | ||
| msg.ChannelFlags ^= lnwire.ChanUpdateDirection | ||
| } | ||
| err = r.UpdateEdge(&channeldb.ChannelEdgePolicy{ | ||
| SigBytes: msg.Signature.ToSignatureBytes(), | ||
| ChannelID: msg.ShortChannelID.ToUint64(), | ||
| ChannelID: e.ChannelID, | ||
| LastUpdate: time.Unix(int64(msg.Timestamp), 0), | ||
| MessageFlags: msg.MessageFlags, | ||
| ChannelFlags: msg.ChannelFlags, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a rebase I guess?