diff --git a/lib/swap/PaymentHandler.ts b/lib/swap/PaymentHandler.ts index 00b3194e..a56919af 100644 --- a/lib/swap/PaymentHandler.ts +++ b/lib/swap/PaymentHandler.ts @@ -249,9 +249,8 @@ class PaymentHandler { }); } else if (payment.status === Payment.PaymentStatus.IN_FLIGHT) { this.logger.info(`Invoice of Swap ${swap.id} is still pending`); + return undefined; } - - return undefined; } catch (e) { /* empty */ } @@ -269,6 +268,8 @@ class PaymentHandler { } if ( + errorMessage === PaymentHandler.errCltvTooSmall || + LightningNursery.errIsInvoicePaid(error) || LightningNursery.errIsPaymentInTransition(error) || LightningNursery.errIsCltvLimitExceeded(error) ) { diff --git a/test/unit/swap/PaymentHandler.spec.ts b/test/unit/swap/PaymentHandler.spec.ts index f4723116..adfc6b5f 100644 --- a/test/unit/swap/PaymentHandler.spec.ts +++ b/test/unit/swap/PaymentHandler.spec.ts @@ -80,7 +80,8 @@ describe('PaymentHandler', () => { preimageHash: '8bc944ac6563a0dc50c2666ffc1f6cc6295d5f093859f869c8d065fcb965443a', status: SwapUpdateEvent.InvoicePending, - } as Swap; + update: jest.fn().mockImplementation(async () => swap), + } as any as Swap; const handler = new PaymentHandler( Logger.disabledLogger, @@ -118,7 +119,6 @@ describe('PaymentHandler', () => { ${PaymentHandler['errCltvTooSmall']} ${{ details: 'invoice is already paid' }} ${{ details: 'cltv limit 123 should be greater than 232' }} - ${{ details: 'invoice expired' }} `('should check payment for pay error "$error"', async ({ error }) => { cltvLimit = 100; sendPaymentError = error; @@ -138,6 +138,27 @@ describe('PaymentHandler', () => { ); }); + test('should abandon swap when invoice expired', async () => { + cltvLimit = 100; + sendPaymentError = { details: 'invoice expired' }; + trackPaymentResponse = { + status: Payment.PaymentStatus.FAILED, + }; + + expect(mockedEmit).toHaveBeenCalledTimes(0); + expect(btcCurrency.lndClient!.resetMissionControl).toHaveBeenCalledTimes(0); + expect(btcCurrency.lndClient!.trackPayment).toHaveBeenCalledTimes(0); + + await expect(handler.payInvoice(swap, null, undefined)).resolves.toEqual( + undefined, + ); + expect(swap.update).toHaveBeenCalledTimes(1); + expect(swap.update).toHaveBeenCalledWith({ + failureReason: 'invoice could not be paid', + status: SwapUpdateEvent.InvoiceFailedToPay, + }); + }); + test('should reset LND mission control only on interval', async () => { cltvLimit = 100; sendPaymentError = 'their node is offline';