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

channeldb+routing: decouple payment lifecycle flow and fix stuck payments #7503

Merged

Conversation

yyforyongyu
Copy link
Member

Depends on,

Only the last 19 commits are new.

This PR refactors the payment lifecycle to provide cleaner layers of abstractions so it’s easier to understand and reason about them. Changes included,

  • Remove duplicate logic re payment state in the payment lifecycle and treat the PaymentStatus as the single source of truth.
  • Remove shardHandler as its responsibility is too vague.
  • Decomposed launchShard so requesting route, registering, and sending HTLC are separated since they deal with different subsystems like PaymentSession, ControlTower and htlcswitch. Previously the errors returned from different systems were mixed which made it hard to distinguish a terminal error vs a temp error. By separating them we can now easily decide when to fail the lifecycle, fail or retry the payment.
  • Fail an HTLC attempt before failing a payment, if applicable. This makes sure we won’t attempt another HTLC while the payment is being marked as failed.

@yyforyongyu yyforyongyu added code health Related to code commenting, refactoring, and other non-behaviour improvements routing payments Related to invoices/payments refactoring labels Mar 10, 2023
@yyforyongyu yyforyongyu added this to the v0.16.1 milestone Mar 10, 2023
@yyforyongyu yyforyongyu self-assigned this Mar 10, 2023
@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch from 01d2f59 to 428c264 Compare March 10, 2023 09:39
@saubyk saubyk modified the milestones: v0.16.1, v0.17.0 Mar 13, 2023
@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch from 428c264 to 544cf09 Compare May 31, 2023 11:19
@saubyk saubyk linked an issue Jun 1, 2023 that may be closed by this pull request
@saubyk saubyk modified the milestones: v0.17.0, v0.17.1 Jun 20, 2023
@saubyk saubyk modified the milestones: High Priority, v0.18.0 Aug 4, 2023
@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch 3 times, most recently from 69d9036 to 16399ac Compare August 24, 2023 11:59
@lightninglabs-deploy
Copy link

@bhandras: review reminder
@joostjager: review reminder
@bitromortac: review reminder

@yyforyongyu yyforyongyu changed the base branch from master to 0-18-staging September 1, 2023 09:19
@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch from 16399ac to 13a57a5 Compare September 1, 2023 09:19
@lightninglabs-deploy
Copy link

Closing due to inactivity

1 similar comment
@lightninglabs-deploy
Copy link

Closing due to inactivity

@guggero
Copy link
Collaborator

guggero commented Sep 6, 2023

!lightninglabs-deploy mute

routing/router_test.go Show resolved Hide resolved
@@ -147,412 +187,303 @@ func (p *paymentLifecycle) resumePayment() ([32]byte, *route.Route, error) {
log.Infof("Resuming payment shard %v for payment %v",
a.AttemptID, p.identifier)

shardHandler.collectResultAsync(&a.HTLCAttemptInfo)
p.resultCollector(&a)
Copy link
Collaborator

Choose a reason for hiding this comment

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

right, after a restart of lnd 👍

channeldb/mp_payment_test.go Show resolved Hide resolved
routing/payment_lifecycle_test.go Outdated Show resolved Hide resolved
routing/payment_lifecycle_test.go Outdated Show resolved Hide resolved
This commit adds a new struct, `stateStep`, to decide the workflow
inside `resumePayment`.

It also refactors `collectResultAsync` introducing a new channel
`resultCollected`. This channel is used to signal the payment
lifecycle that an HTLC attempt result is ready to be processed.
This commit adds a new interface method `TerminalInfo` and changes its
implementation to return an `*HTLCAttempt` so it includes the route for
a successful payment. Method `GetFailureReason` is now removed as its
returned value can be found in the above method.
The old payment lifecycle is removed due to it's not "unit" -
maintaining these tests probably takes as much work as the actual
methods being tested, if not more so. Moreover, the usage of the old
mockers in current payment lifecycle test is removed as it re-implements
other interfaces and sometimes implements it uniquely just for the
tests. This is bad as, not only we need to work on the actual interface
implementations and test them , but also re-implement them again in the
test without testing them!
This commit adds more mockers to be used in coming unit tests and
simplified the mockers to be more straightforward.
Thus adding following unit tests can be a bit easier.
@bitromortac
Copy link
Collaborator

A point I wanted to highlight concerning compatibility issues with the new payment status is that an outdated lncli payinvoice will report an error because it doesn't know the status initiated, but the launched payment may be successful. This has the potential to break people's scripts if they only upgraded lnd but not lncli (which may happen in some cases).

Also, if endpoint consumers interpret the unknown status code as as a failure then this could lead to several payouts. An example would be if somebody tries to pay out funds from a custodial system (e.g. lit accounts) and operators haven't upgraded their accounting to reflect the status code (and they interpret it as a failure) this may lead to cases where the user is not debited.

@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch 2 times, most recently from 846887d to 261cc08 Compare October 26, 2023 16:13
This commit adds unit tests for `resumePayment`. In addition, the
`resumePayment` has been split into two parts so it's easier to be
tested, 1) sending the htlc, and 2) collecting results. As seen in the
new tests, this split largely reduces the complexity involved and makes
the unit test flow sequential.

This commit also makes full use of `mock.Mock` in the unit tests to
provide a more clear testing flow.
This commit makes sure a testing payment is created via
`createDummyLightningPayment` to ensure the payment hash is unique to
avoid collision of the same payment hash being used in uint tests. Since
the tests are running in parallel and accessing db, if two difference
tests are using the same payment hash, no clean test state can be
guaranteed.
@yyforyongyu yyforyongyu force-pushed the new-payment-lifecycle branch from 261cc08 to 11af820 Compare October 27, 2023 03:17
```
lnd_max_htlcs_test.go:149:
        	Error Trace:	/home/runner/work/lnd/lnd/itest/lnd_max_htlcs_test.go:149
        	            				/home/runner/work/lnd/lnd/itest/lnd_max_htlcs_test.go:40
        	            				/home/runner/work/lnd/lnd/lntest/harness.go:286
        	            				/home/runner/work/lnd/lnd/itest/lnd_test.go:136
        	Error:      	Not equal:
        	            	expected: 3
        	            	actual  : 0
        	Test:       	TestLightningNetworkDaemon/tranche01/60-of-134/btcd/max_htlc_pathfind
        	Messages:   	expected accepted
```
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 🎉🎉. I'm regarding the api compatibility issue as non-blocking for this PR as it was introduced before, but I think that it still needs to be discussed.

@Roasbeef
Copy link
Member

Landing this as is, we'll make an issue to track resolution of rolling back that breaking change. One way to handle it maybe would be: clients for the subscription call pass in a new flag that states they want the new enum value, and we only send it if so. In "compatibility mode", we just send in flight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code health Related to code commenting, refactoring, and other non-behaviour improvements payments Related to invoices/payments refactoring routing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[bug]: In flight status for payment without HTLCs
7 participants