From 6b3f4d985674e04ffeff06088c21f2f50b27de69 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Wed, 20 May 2026 21:48:32 +0200 Subject: [PATCH] instantout: treat closed payment streams as errors Closed payment channels yielded zero values or nil errors in failure paths. Return explicit errors so the observer cannot report a failed swap as success. --- instantout/actions.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/instantout/actions.go b/instantout/actions.go index d1c405fd..18c31d28 100644 --- a/instantout/actions.go +++ b/instantout/actions.go @@ -244,7 +244,13 @@ func (f *FSM) PollPaymentAcceptedAction(ctx context.Context, timer := time.NewTimer(time.Second) for { select { - case payRes := <-payChan: + case payRes, ok := <-payChan: + if !ok { + return f.handleErrorAndUnlockReservations( + ctx, errors.New("payment status channel closed"), + ) + } + f.Debugf("payment result: %v", payRes) if payRes.State == lnrpc.Payment_FAILED { return f.handleErrorAndUnlockReservations( @@ -252,12 +258,18 @@ func (f *FSM) PollPaymentAcceptedAction(ctx context.Context, payRes.FailureReason), ) } - case err := <-paymentErrChan: + case err, ok := <-paymentErrChan: + if !ok { + err = errors.New("payment error channel closed") + } else if err == nil { + err = errors.New("payment error channel returned nil") + } + f.Errorf("error sending payment: %v", err) return f.handleErrorAndUnlockReservations(ctx, err) case <-ctx.Done(): - return f.handleErrorAndUnlockReservations(ctx, nil) + return f.handleErrorAndUnlockReservations(ctx, ctx.Err()) case <-timer.C: res, err := f.cfg.InstantOutClient.PollPaymentAccepted(