From 89f2dcff8b2293a8e8bee83f3164cbabee483fee Mon Sep 17 00:00:00 2001 From: Chanda Chewe <82529756+chandachewe10@users.noreply.github.com> Date: Fri, 17 Jul 2026 11:57:28 +0000 Subject: [PATCH] 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 ', ' 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 --- loopin.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/loopin.go b/loopin.go index ae6802c8..06d63629 100644 --- a/loopin.go +++ b/loopin.go @@ -1174,13 +1174,17 @@ func (s *loopInSwap) setStateAbandoned(ctx context.Context) error { return err } - // If the invoice is already settled or canceled, this is a nop. - _ = s.lnd.Invoices.CancelInvoice(ctx, s.hash) + // Cancel the invoice so the server can no longer settle it. If the + // 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 "+ - "abandoned by client, "+ - "swap ID: %v, %v", - s.hash, err) + return fmt.Errorf("swap hash abandoned by client, swap ID: %v", s.hash) } // persistAndAnnounceState updates the swap state on disk and sends out an