Skip to content

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

Merged

Conversation

ziggie1984
Copy link
Collaborator

@ziggie1984 ziggie1984 commented Mar 21, 2025

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:

amt := attempt.Route.ReceiverAmt()
if !isBlinded && mpp == nil && amt != payment.Info.Value {
return ErrValueMismatch
}

@ziggie1984 ziggie1984 force-pushed the payment-lifecycle-small-fix branch from 603ecfb to 208e181 Compare March 21, 2025 04:08
@ziggie1984 ziggie1984 marked this pull request as ready for review March 21, 2025 04:08
Copy link
Contributor

coderabbitai bot commented Mar 21, 2025

Important

Review skipped

Auto reviews are limited to specific labels.

🏷️ Labels to auto review (1)
  • llm-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ziggie1984 ziggie1984 force-pushed the payment-lifecycle-small-fix branch from 208e181 to a5a3772 Compare March 21, 2025 04:51
Copy link
Member

@yyforyongyu yyforyongyu left a 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.

// because otherwise the payment might be resolved when
// resuming.
_, failure := payment.TerminalInfo()
if failure == nil &&
Copy link
Member

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.

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)
Copy link
Member

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.

Copy link
Collaborator Author

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.

Copy link
Member

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.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep this note?

@@ -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 {
Copy link
Member

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?

Copy link
Collaborator Author

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.

Copy link
Member

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.

@ziggie1984 ziggie1984 force-pushed the payment-lifecycle-small-fix branch from a5a3772 to fc67963 Compare March 25, 2025 04:54
// 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) {
Copy link
Member

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

@ziggie1984 ziggie1984 force-pushed the payment-lifecycle-small-fix branch from fc67963 to 0356f0e Compare March 25, 2025 06:25
@ziggie1984 ziggie1984 force-pushed the payment-lifecycle-small-fix branch from 0356f0e to 0eca55f Compare March 25, 2025 09:42
@ziggie1984 ziggie1984 requested a review from yyforyongyu March 25, 2025 09:42
@ziggie1984 ziggie1984 added this to the v0.19 overflow milestone Mar 25, 2025
Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

Copy link
Member

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good

@guggero guggero merged commit cf35be8 into lightningnetwork:master Mar 25, 2025
31 of 35 checks passed
@saubyk saubyk modified the milestones: v0.19 overflow, v0.19.0 May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants