-
Notifications
You must be signed in to change notification settings - Fork 2.2k
payment lifecycle small fix #9626
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
payment lifecycle small fix #9626
Conversation
603ecfb
to
208e181
Compare
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
208e181
to
a5a3772
Compare
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.
I think we need an itest to show what's been fixed. In addition I think we should catch this error earlier in the rpc layer.
routing/payment_lifecycle.go
Outdated
// because otherwise the payment might be resolved when | ||
// resuming. | ||
_, failure := payment.TerminalInfo() | ||
if failure == nil && |
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.
I don't think we should make it this complicated - if we really want to fail the payment, I think the only safe case to fail is when the status is in StatusInitiated
, which is the case from using keysend
+ max_shard_size_sat
, the payment was never attempted.
routing/payment_lifecycle.go
Outdated
exitWithErr := func(exitErr error) ([32]byte, *route.Route, error) { | ||
// We fetch the latest payment status here to get the latest | ||
// state of the payment. | ||
payment, err := p.router.cfg.Control.FetchPayment(p.identifier) |
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.
we don't need to fetch the payment again - it's already been rewritten in the loop below.
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.
hmm, acutally I think we need because we reload it at the beginning and then we might fail it down the road so we will not have the current payment status available.
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.
As long as we check for StatusInitiated
we can be sure it's not modified, which can only happen when the async result collector is fired, which implicitly means there are inflight HTLCs, and we don't want to fail it in that case.
routing/payment_lifecycle.go
Outdated
exitWithErr := func(err error) ([32]byte, *route.Route, error) { | ||
// Log an error with the latest payment status. | ||
// | ||
// NOTE: this `status` variable is reassigned in the loop |
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.
Keep this note?
routing/payment_lifecycle.go
Outdated
@@ -332,6 +350,13 @@ lifecycle: | |||
return htlc.Settle.Preimage, &htlc.Route, nil | |||
} | |||
|
|||
// At this point the payment should have a failure reason and therefore | |||
// this should never happen. | |||
if failure == nil { |
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.
Have you encountered this case before?
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.
No I haven't it just caught my eye so I added this robustness check.
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.
yeah i had that concern too - tho I think it's not possible to have this being nil
. A better way is to Defining errors out of existence so we don't need to even worry about it, maybe a new PR to change the pointer to be a concrete struct.
a5a3772
to
fc67963
Compare
routing/payment_lifecycle.go
Outdated
// the payment fetching to return an error. | ||
log.Errorf("Payment %v with status=%v failed: %v", p.identifier, | ||
status, err) | ||
exitWithErr := func(exitErr error) ([32]byte, *route.Route, error) { |
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.
if we really wanna do this let's make these into a new method so we don't grow the resumePayment
fc67963
to
0356f0e
Compare
0356f0e
to
0eca55f
Compare
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.
LGTM 🚀
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.
Looking good
While working on the payment lifecycle I came across this case. When trying to send a keysend with a max shard restriction we would not fail the payment properly and it would hang indefinitely being marked as
INFLIGHT
in the db although no payment was attempted.Just try sending a payment via this cmd:
lncli sendpayment --dest XXX --amt 100 --keysend --max_shard_size_sat 10
The payment lifecycle will fail here because keysend payments are not MPP payments but we try to shard them:
lnd/channeldb/payment_control.go
Lines 419 to 422 in 5d92172