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 ab5cd5f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
11 changes: 10 additions & 1 deletion channeldb/payment_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,14 +582,23 @@ 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 to 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) {
return nil, err
}
}
Expand Down

0 comments on commit ab5cd5f

Please sign in to comment.