From fe9e821af5f678a5fb08eb6c91f32404524b5312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Mon, 3 Apr 2023 14:44:17 +0200 Subject: [PATCH] BUG: proper exception for already paid internal invoices (#1593) * BUG: proper exception for paid interal invoices * test should now fail, because we pay invoice twice, and should also work in regtest * sorting * unpack check_internal * introduce another crud fn for checking internal paid payment * rename --------- Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com> --- lnbits/core/crud.py | 16 ++++++++++++++++ lnbits/core/services.py | 4 ++++ tests/core/views/test_api.py | 7 +++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 183f663a0..db6f503a2 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -604,6 +604,22 @@ async def check_internal( return row["checking_id"] +async def check_internal_pending( + payment_hash: str, conn: Optional[Connection] = None +) -> bool: + row = await (conn or db).fetchone( + """ + SELECT pending FROM apipayments + WHERE hash = ? AND amount > 0 + """, + (payment_hash,), + ) + if not row: + return False + else: + return row["pending"] + + # balance_check # ------------- diff --git a/lnbits/core/services.py b/lnbits/core/services.py index bba47e22e..3ff641311 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -27,6 +27,7 @@ from lnbits.wallets.base import PaymentResponse, PaymentStatus from . import db from .crud import ( check_internal, + check_internal_pending, create_account, create_admin_settings, create_payment, @@ -153,6 +154,9 @@ async def pay_invoice( extra=extra, ) + if not await check_internal_pending(invoice.payment_hash, conn=conn): + raise PaymentFailure("Internal invoice already paid.") + # check_internal() returns the checking_id of the invoice we're waiting for internal_checking_id = await check_internal(invoice.payment_hash, conn=conn) if internal_checking_id: diff --git a/tests/core/views/test_api.py b/tests/core/views/test_api.py index 5752b2798..8d4ca9d72 100644 --- a/tests/core/views/test_api.py +++ b/tests/core/views/test_api.py @@ -6,7 +6,7 @@ from lnbits import bolt11 from lnbits.core.views.api import api_payment from lnbits.settings import get_wallet_class -from ...helpers import get_random_invoice_data, is_fake, is_regtest +from ...helpers import get_random_invoice_data, is_fake WALLET = get_wallet_class() @@ -170,16 +170,15 @@ async def test_pay_invoice_invoicekey(client, invoice, inkey_headers_from): assert response.status_code >= 300 # should fail -# check POST /api/v1/payments: payment with admin key [should pass] +# check POST /api/v1/payments: payment with admin key, trying to pay twice [should fail] @pytest.mark.asyncio -@pytest.mark.skipif(is_regtest, reason="this only works in fakewallet") async def test_pay_invoice_adminkey(client, invoice, adminkey_headers_from): data = {"out": True, "bolt11": invoice["payment_request"]} # try payment with admin key response = await client.post( "/api/v1/payments", json=data, headers=adminkey_headers_from ) - assert response.status_code < 300 # should pass + assert response.status_code > 300 # should fail # check POST /api/v1/payments/decode