From e112258c392d1a375a71d9b888001c3dc4afe701 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 28 Mar 2021 00:11:41 -0300 Subject: [PATCH] improve checking routine. check pending invoices only once on startup, then check outgoing payments every 30 minutes, and delete outgoing payments that return False (meaning they have failed). also fix a bug on sparko. --- lnbits/core/models.py | 15 +++++++++++---- lnbits/tasks.py | 15 +++++++++++---- lnbits/wallets/base.py | 14 ++++++++++++++ lnbits/wallets/spark.py | 2 +- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 8ab58e67b..5803a5158 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -58,7 +58,7 @@ class Wallet(NamedTuple): pending: bool = False, outgoing: bool = True, incoming: bool = True, - exclude_uncheckable: bool = False + exclude_uncheckable: bool = False, ) -> List["Payment"]: from .crud import get_payments @@ -141,11 +141,18 @@ class Payment(NamedTuple): return if self.is_out: - pending = await WALLET.get_payment_status(self.checking_id) + status = await WALLET.get_payment_status(self.checking_id) else: - pending = await WALLET.get_invoice_status(self.checking_id) + status = await WALLET.get_invoice_status(self.checking_id) - await self.set_pending(pending.pending) + print( + f" - checking '{'in' if self.is_in else 'out'}' {self.checking_id}: {status.paid}" + ) + + if self.is_out and status.failed: + await self.delete() + elif not status.pending: + await self.set_pending(status.pending) async def delete(self) -> None: from .crud import delete_payment diff --git a/lnbits/tasks.py b/lnbits/tasks.py index cfd025cb1..d8f26a757 100644 --- a/lnbits/tasks.py +++ b/lnbits/tasks.py @@ -71,19 +71,26 @@ async def invoice_listener(nursery): async def check_pending_payments(): await delete_expired_invoices() + + outgoing = True + incoming = True + while True: for payment in await get_payments( since=(int(time.time()) - 60 * 60 * 24 * 15), # 15 days ago complete=False, pending=True, + outgoing=outgoing, + incoming=incoming, exclude_uncheckable=True, ): - print( - f" - checking {'in' if payment.is_in else 'out'} pending: {payment.checking_id}" - ) await payment.check_pending() - await trio.sleep(60 * 120) + # after the first check we will only check outgoing, not incoming + # that will be handled by the global invoice listeners, hopefully + incoming = False + + await trio.sleep(60 * 30) # every 30 minutes async def invoice_callback_dispatcher(checking_id: str): diff --git a/lnbits/wallets/base.py b/lnbits/wallets/base.py index 3f131c1e8..973c18085 100644 --- a/lnbits/wallets/base.py +++ b/lnbits/wallets/base.py @@ -30,6 +30,20 @@ class PaymentStatus(NamedTuple): def pending(self) -> bool: return self.paid is not True + @property + def failed(self) -> bool: + return self.paid == False + + def __str__(self) -> str: + if self.paid == True: + return "settled" + elif self.paid == False: + return "failed" + elif self.paid == None: + return "still pending" + else: + return "unknown (should never happen)" + class Wallet(ABC): @abstractmethod diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index 2ecc6fabc..d80e3cc9d 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -130,7 +130,7 @@ class SparkWallet(Wallet): if pay["status"] == "failed": return PaymentResponse(False, None, 0, None, str(exc)) elif pay["status"] == "pending": - return PaymentResponse(None, listpays["pays"], 0, None, None) + return PaymentResponse(None, payment_hash, 0, None, None) elif pay["status"] == "complete": r = pay r["payment_preimage"] = pay["preimage"]