Skip to content

Commit

Permalink
multi: fix payment failure overwrite
Browse files Browse the repository at this point in the history
We now make sure we do not overwrite the payment failure status
if it is already set and return an error. When using sendtoroute
we might fail a payment twice hence we do not error out if we
fail a payment twice.
  • Loading branch information
ziggie1984 committed Feb 22, 2025
1 parent 5fe900d commit 4eca3b9
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
12 changes: 11 additions & 1 deletion channeldb/payment_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,14 +582,24 @@ func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
// lets the last attempt to fail with a terminal write its
// failure to the PaymentControl without synchronizing with
// other attempts.
_, err = fetchPaymentStatus(bucket)
status, err := fetchPaymentStatus(bucket)
if errors.Is(err, ErrPaymentNotInitiated) {
updateErr = ErrPaymentNotInitiated
return nil
} else if err != nil {
return err
}

// We make sure that if the payment is already failed we do not
// overwrite the failure reason and remain consistent. We do
// not return the error in the batch function to avoid retrying
// the transaction.
if status == StatusFailed {
updateErr = ErrPaymentAlreadyFailed

return nil
}

// Put the failure reason in the bucket for record keeping.
v := []byte{byte(reason)}
err = bucket.Put(paymentFailInfoKey, v)
Expand Down
7 changes: 6 additions & 1 deletion routing/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,12 @@ func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route,
// as failed if we don't skip temp error.
if !skipTempErr {
err := r.cfg.Control.FailPayment(paymentIdentifier, reason)
if err != nil {

// We might attempt to fail the payment twice here because the
// payment might already be failed when handling the switch
// error in the result collector.
if err != nil &&
!errors.Is(err, channeldb.ErrPaymentAlreadyFailed) {

Check failure on line 1208 in routing/router.go

View workflow job for this annotation

GitHub Actions / lint code

multi-line statement should be followed by a newline (whitespace)
return nil, err
}
}
Expand Down

0 comments on commit 4eca3b9

Please sign in to comment.