From 4447a487240bb65679ec7e5bbb0b53ffdcd73ec4 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 2 Sep 2020 00:58:21 -0300 Subject: [PATCH] deleting expired invoices based on their actual expiry date. also fixes a possible bug that could have caused pending outgoing payments to be deleted and affecting the balance. probably never happened. --- lnbits/core/crud.py | 33 ++++++++++++++++++++++++++------- lnbits/core/models.py | 5 ----- lnbits/core/views/api.py | 3 ++- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 2c3ae7a5..50fe1586 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -1,7 +1,9 @@ -from typing import List, Optional, Dict +import datetime from uuid import uuid4 +from typing import List, Optional, Dict from lnbits.db import open_db +from lnbits import bolt11 from lnbits.settings import DEFAULT_WALLET_NAME from .models import User, Wallet, Payment @@ -190,15 +192,32 @@ def get_wallet_payments( return [Payment.from_row(row) for row in rows] -def delete_wallet_payments_expired(wallet_id: str, *, seconds: int = 86400) -> None: +def delete_expired_invoices() -> None: with open_db() as db: - db.execute( + rows = db.fetchall( """ - DELETE - FROM apipayments WHERE wallet = ? AND pending = 1 AND time < strftime('%s', 'now') - ? - """, - (wallet_id, seconds), + SELECT bolt11 + FROM apipayments + WHERE pending = 1 AND amount > 0 AND time < strftime('%s', 'now') - 86400 + """ ) + for (payment_request,) in rows: + try: + invoice = bolt11.decode(payment_request) + except: + continue + + expiration_date = datetime.datetime.fromtimestamp(invoice.date + invoice.expiry) + if expiration_date > datetime.datetime.utcnow(): + continue + + db.execute( + """ + DELETE FROM apipayments + WHERE pending = 1 AND payment_hash = ? + """, + (invoice.payment_hash,), + ) # payments diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 175c5fe4..ed4ed43d 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -43,11 +43,6 @@ class Wallet(NamedTuple): return get_wallet_payments(self.id, complete=complete, pending=pending, outgoing=outgoing, incoming=incoming) - def delete_expired_payments(self, seconds: int = 86400) -> None: - from .crud import delete_wallet_payments_expired - - delete_wallet_payments_expired(self.id, seconds=seconds) - class Payment(NamedTuple): checking_id: str diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 52c67cd6..9a587ee6 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -5,6 +5,7 @@ from binascii import unhexlify from lnbits import bolt11 from lnbits.core import core_app from lnbits.core.services import create_invoice, pay_invoice +from lnbits.core.crud import delete_expired_invoices from lnbits.decorators import api_check_wallet_key, api_validate_post_request from lnbits.settings import WALLET @@ -13,7 +14,7 @@ from lnbits.settings import WALLET @api_check_wallet_key("invoice") def api_payments(): if "check_pending" in request.args: - g.wallet.delete_expired_payments() + delete_expired_invoices() for payment in g.wallet.get_payments(complete=False, pending=True): if payment.is_uncheckable: