loopin: fix dead error variable and silent invoice cancel in setStateAbandoned

The err variable is always nil when the final fmt.Errorf is reached
(a non-nil err exits earlier), producing a trailing ', <nil>' in the
error string visible to callers and in logs.

Additionally, CancelInvoice errors were silently swallowed with a
bare '_' assignment. The timeout path in the same file correctly
checks for ErrInvoiceAlreadySettled; this commit makes the abandon
path consistent: ignore already-settled invoices and log any other
unexpected error so operators can diagnose issues without failing
the abandon itself.

Co-authored-by: Chanda Chewe <chandachewe10@users.noreply.github.com>
This commit is contained in:
Chanda Chewe 2026-07-17 11:57:28 +00:00
parent 39c97e60d2
commit 89f2dcff8b
No known key found for this signature in database

View file

@ -1174,13 +1174,17 @@ func (s *loopInSwap) setStateAbandoned(ctx context.Context) error {
return err return err
} }
// If the invoice is already settled or canceled, this is a nop. // Cancel the invoice so the server can no longer settle it. If the
_ = s.lnd.Invoices.CancelInvoice(ctx, s.hash) // invoice is already settled we ignore the error, matching the
// behaviour of the timeout path. Any other unexpected error is logged
// but does not prevent the abandon from completing.
err = s.lnd.Invoices.CancelInvoice(ctx, s.hash)
if err != nil && err != invpkg.ErrInvoiceAlreadySettled {
s.log.Warnf("Failed to cancel invoice for abandoned swap: %v",
err)
}
return fmt.Errorf("swap hash "+ return fmt.Errorf("swap hash abandoned by client, swap ID: %v", s.hash)
"abandoned by client, "+
"swap ID: %v, %v",
s.hash, err)
} }
// persistAndAnnounceState updates the swap state on disk and sends out an // persistAndAnnounceState updates the swap state on disk and sends out an