Skip to content
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

routerrpc: optionally return the new payment status #8177

Merged
merged 6 commits into from
Nov 30, 2023

Conversation

yyforyongyu
Copy link
Member

Fixes #8143, this PR adds a new config value to signal whether to use the new payment status.

This commit is a pure refactoring which sorts the fields in
`SendPaymentRequest` so it's easier to see what number to use when
adding a new field.
@yyforyongyu yyforyongyu self-assigned this Nov 14, 2023
@yyforyongyu yyforyongyu added payments Related to invoices/payments compatibility labels Nov 14, 2023
@yyforyongyu yyforyongyu added this to the v0.18.0 milestone Nov 14, 2023
Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Nice fix for a tricky upgrade situation 🌷

Wondering whether this could introduce a race in the trackpayment itest?

  • The standard Alice/Bob nodes are set up to send this new status, but we assert that we get IN_FLIGHT first.
  • Since SubscribePayment just grabs whatever state we currently have, the first status we get could be initiated or in flight?

Perhaps that's okay because it hasn't happened since the PR with the new state was added, but may come back to haunt us.

lnrpc/routerrpc/router.proto Show resolved Hide resolved
//
// TODO(yy): remove this config after the new status code is fully
// deployed to the network(v0.20.0).
UseStatusInitiated bool `long:"usestatusinitiated" description:"If true, the router will send Payment_INITIATED for new payments, otherwise Payment_In_FLIGHT will be sent for compatibility concerns."`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the plan here to default this to true in 19 and then remove in 20?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah think it'd give people enough time to upgrade? The other approach is to let users specify an RPC version in SendPayment request, but that would end up being messy. My concern is, if people do not use this new flag in the coming versions, we'd still have this compatibility issue.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah think it'd give people enough time to upgrade? The other approach is to let users specify an RPC version in SendPayment request, but that would end up being messy.

Makes sense! Agree that putting it on the RPC is going to be ugly, we use the payment state in too many places (eg, would also need it in ListPayments, for example).

My concern is, if people do not use this new flag in the coming versions, we'd still have this compatibility issue.

Yah this is tough. Could force it more by making this flag DisableStatusInitiated and then people have to set it to prevent the breaking change, but there really is no easy path :(

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it should be part of every release notes (under breaking changes) until v0.20 in order for devs to check for any unwanted behavior, otherwise there won't be any real deployment process. DisableStatusInitiated would be too dangerous, I think.

sample-lnd.conf Outdated Show resolved Hide resolved
@yyforyongyu yyforyongyu force-pushed the payment-status branch 2 times, most recently from 9b41f43 to cc7948a Compare November 15, 2023 10:38
@yyforyongyu
Copy link
Member Author

Wondering whether this could introduce a race in the trackpayment itest?

Nice catch @carlaKC ! I think this is indeed a case we need to fix. Turns out we need to notify the subscribers when a new payment is made, so I updated the InitPayment to always notify it. Pushed a new version and see if the tests pass.

This commit adds a new config value to signal that the user understands
the new payment status `StatusInitiated`.
This commit fixes `InitPayment` method to make sure the subscribers get
notified when new payments are created.
This commit adds an itest case to make sure when the flag
`routerrpc.usestatusinitiated` is not set, the new status is not sent.
Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

LGTM, only one comment on strategy for getting folks upgraded (opt in vs opt out), but it's a weak opinion weakly held.

@saubyk saubyk requested a review from bitromortac November 16, 2023 15:27
@lightninglabs-deploy
Copy link

@bitromortac: review reminder

Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

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

LGTM 🎉 Concerning the transition period for the removal of the flag, it would be good to add a permanent entry in the change log under breaking changes until v0.20 saying that developers should check any unexpected behavior of their software when enabling the flag (we could link to the issue of this PR as well).

//
// TODO(yy): remove this config after the new status code is fully
// deployed to the network(v0.20.0).
UseStatusInitiated bool `long:"usestatusinitiated" description:"If true, the router will send Payment_INITIATED for new payments, otherwise Payment_In_FLIGHT will be sent for compatibility concerns."`
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it should be part of every release notes (under breaking changes) until v0.20 in order for devs to check for any unwanted behavior, otherwise there won't be any real deployment process. DisableStatusInitiated would be too dangerous, I think.

@guggero
Copy link
Collaborator

guggero commented Nov 28, 2023

Sorry to chime in a bit late. But I'm not sure I understand how this flag actually helps us with the compatibility issue?
The issue as I understand it is that in a client application (e.g. litd's custodial accounts functionality) we need to know whether lnd will serve this status or not. Or to be even more precise, we need to make sure that if an version of the client code is used that does not yet understand the new initiated code that things fail gracefully instead of with unexpected behavior.
So what I think we need is some kind of RPC flag. For example a new field in the affected RPC methods, e.g. use_initiated_status. Then we can set that to true in the updated lndclient code. And we probably have to make that lndclient change breaking so every application that uses the new lndclient version is also forced to handle the new state.

Or am I completely misunderstanding something here?

@yyforyongyu
Copy link
Member Author

@guggero so the idea here is if users don't explicit set this config then the new status won't be served so the clients should be able to understand the status field since nothing is changed.

The issue as I understand it is that in a client application (e.g. litd's custodial accounts functionality) we need to know whether lnd will serve this status or not.

yeah exactly. From client application's perspective, they set this config to know that lnd will serve it. And from lnd's view, it reads the config to be sure that the client understands it.

Or to be even more precise, we need to make sure that if an version of the client code is used that does not yet understand the new initiated code that things fail gracefully instead of with unexpected behavior.

If the client doesn't understand it, it won't be served. Things would break, however, if lnd is set to use --routerrpc.usestatusinitiated without the client being updated first, which is a misbehave at the client side.

So what I think we need is some kind of RPC flag.

There're offline discussions that rpc flag and config flag can both work(actually using RPC flag was the initial approach), while upgrading via config has several advantages:

  • it can easily be removed/deprecated(for instance we can use the hidden flag in config so we won't break users' scripts), while for RPC flags we need to first write compatible code then remove it in future versions.
  • it's a smaller change as opposed to RPC flags, as we need to visit SendPaymentRequest, TrackPaymentRequest, SendToRouteRequest and ListPaymentsRequest to add this new flag.

@guggero
Copy link
Collaborator

guggero commented Nov 29, 2023

Okay, so I guess the goal of the flag then is to be able to test the new functionality (in manual or integration tests).
But any user unaware of the flag would keep their node at the old behavior, giving them time to upgrade. Then some point in the future we'd just remove the flag and turn on the behavior by default.

I guess in terms of implementation simplicity that is easier indeed. My main worry would be that we wouldn't discover most issues in the wild as 99.9% of the users wouldn't turn on the flag, even after upgrading their whole stack. But we can turn this on in litd when running in integrated mode, where we know the whole tech stack. So we still get to run this in production for at least a portion of our user base.

@yyforyongyu
Copy link
Member Author

I guess in terms of implementation simplicity that is easier indeed. My main worry would be that we wouldn't discover most issues in the wild as 99.9% of the users wouldn't turn on the flag, even after upgrading their whole stack.

yeah i'm almost certain this would be the case😂, which is the concern mentioned here.

I think a future strategy of upgrading our RPCs could be,

  • use a config flag to let user specify they are ready for the new state
  • then after X releases, make this flag mandatory and lnd can give a detailed error message about how to proceed
  • then after Y releases, mention the flag will be removed and make this flag hidden so it won't break any shell scripts
  • then after Z releases, remove this flag

So in this case, this could be,

  • at version 0.2x.0, lnd won't start unless usestatusinitiated is set
  • at version 0.3x.0, usestatusinitiated will be hidden
  • at version 0.4x.0, usestatusinitiated will be removed

or something like that.

@guggero
Copy link
Collaborator

guggero commented Nov 29, 2023

Sounds good to me 👍 Thanks for all the explanations!

@yyforyongyu yyforyongyu merged commit 9f42459 into lightningnetwork:master Nov 30, 2023
24 of 25 checks passed
@yyforyongyu yyforyongyu deleted the payment-status branch November 30, 2023 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility payments Related to invoices/payments
Projects
None yet
Development

Successfully merging this pull request may close these issues.

payment: fix compatibility issue for the new payment status
5 participants