mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-27 22:21:18 +02:00
Merge pull request #10141 from ziggie1984/fix-stuck-payment
fix stuck payment
This commit is contained in:
@@ -42,6 +42,10 @@
|
|||||||
situations where the sending amount would violate the channel policy
|
situations where the sending amount would violate the channel policy
|
||||||
restriction (min,max HTLC).
|
restriction (min,max HTLC).
|
||||||
|
|
||||||
|
- [Fixed](https://github.com/lightningnetwork/lnd/pull/10141) a case where we
|
||||||
|
would not resolve all outstanding payment attempts after the overall payment
|
||||||
|
lifecycle was canceled due to a timeout.
|
||||||
|
|
||||||
# New Features
|
# New Features
|
||||||
|
|
||||||
## Functional Enhancements
|
## Functional Enhancements
|
||||||
|
@@ -226,6 +226,19 @@ func (p *paymentLifecycle) resumePayment(ctx context.Context) ([32]byte,
|
|||||||
// critical error during path finding.
|
// critical error during path finding.
|
||||||
lifecycle:
|
lifecycle:
|
||||||
for {
|
for {
|
||||||
|
// Before we attempt any new shard, we'll check to see if we've
|
||||||
|
// gone past the payment attempt timeout or if the context was
|
||||||
|
// canceled. If the context is done, the payment is marked as
|
||||||
|
// failed and we reload the latest payment state to reflect
|
||||||
|
// this.
|
||||||
|
//
|
||||||
|
// NOTE: This can be called several times if there are more
|
||||||
|
// attempts to be resolved after the timeout or context is
|
||||||
|
// cancelled.
|
||||||
|
if err := p.checkContext(ctx); err != nil {
|
||||||
|
return exitWithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
// We update the payment state on every iteration.
|
// We update the payment state on every iteration.
|
||||||
currentPayment, ps, err := p.reloadPayment()
|
currentPayment, ps, err := p.reloadPayment()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -241,19 +254,11 @@ lifecycle:
|
|||||||
|
|
||||||
// We now proceed our lifecycle with the following tasks in
|
// We now proceed our lifecycle with the following tasks in
|
||||||
// order,
|
// order,
|
||||||
// 1. check context.
|
// 1. request route.
|
||||||
// 2. request route.
|
// 2. create HTLC attempt.
|
||||||
// 3. create HTLC attempt.
|
// 3. send HTLC attempt.
|
||||||
// 4. send HTLC attempt.
|
// 4. collect HTLC attempt result.
|
||||||
// 5. collect HTLC attempt result.
|
|
||||||
//
|
//
|
||||||
// Before we attempt any new shard, we'll check to see if we've
|
|
||||||
// gone past the payment attempt timeout, or if the context was
|
|
||||||
// cancelled, or the router is exiting. In any of these cases,
|
|
||||||
// we'll stop this payment attempt short.
|
|
||||||
if err := p.checkContext(ctx); err != nil {
|
|
||||||
return exitWithErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now decide the next step of the current lifecycle.
|
// Now decide the next step of the current lifecycle.
|
||||||
step, err := p.decideNextStep(payment)
|
step, err := p.decideNextStep(payment)
|
||||||
|
@@ -868,25 +868,16 @@ func TestResumePaymentFailOnTimeoutErr(t *testing.T) {
|
|||||||
// Create a test paymentLifecycle with the initial two calls mocked.
|
// Create a test paymentLifecycle with the initial two calls mocked.
|
||||||
p, m := setupTestPaymentLifecycle(t)
|
p, m := setupTestPaymentLifecycle(t)
|
||||||
|
|
||||||
paymentAmt := lnwire.MilliSatoshi(10000)
|
// We now enter the payment lifecycle loop, we will check the router
|
||||||
|
// quit channel in the beginning and quit immediately without reloading
|
||||||
// We now enter the payment lifecycle loop.
|
// the payment.
|
||||||
//
|
|
||||||
// 1. calls `FetchPayment` and return the payment.
|
|
||||||
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
|
|
||||||
|
|
||||||
// 2. calls `GetState` and return the state.
|
|
||||||
ps := &channeldb.MPPaymentState{
|
|
||||||
RemainingAmt: paymentAmt,
|
|
||||||
}
|
|
||||||
m.payment.On("GetState").Return(ps).Once()
|
|
||||||
|
|
||||||
// NOTE: GetStatus is only used to populate the logs which is
|
// NOTE: GetStatus is only used to populate the logs which is
|
||||||
// not critical so we loosen the checks on how many times it's
|
// not critical so we loosen the checks on how many times it's
|
||||||
// been called.
|
// been called.
|
||||||
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
|
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
|
||||||
|
|
||||||
// 3. quit the router to return an error.
|
// Quit the router to return an error.
|
||||||
close(p.router.quit)
|
close(p.router.quit)
|
||||||
|
|
||||||
// Send the payment and assert it failed when router is shutting down.
|
// Send the payment and assert it failed when router is shutting down.
|
||||||
|
Reference in New Issue
Block a user