From df8525a4f05b1c6a259134e4c8bd1ad05923d783 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 28 Feb 2025 11:04:45 +0200 Subject: [PATCH] refactor: move logic to `update_pending_payments` --- lnbits/core/services/__init__.py | 4 +-- lnbits/core/services/payments.py | 39 +++++++++++++++++++++++++- lnbits/core/views/payment_api.py | 8 +++--- lnbits/tasks.py | 47 +++++++++++++------------------- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/lnbits/core/services/__init__.py b/lnbits/core/services/__init__.py index 36a23691c..cec9a406c 100644 --- a/lnbits/core/services/__init__.py +++ b/lnbits/core/services/__init__.py @@ -13,8 +13,8 @@ from .payments import ( fee_reserve_total, pay_invoice, service_fee, - update_pending_payments, update_wallet_balance, + update_wallet_pending_payments, ) from .settings import ( check_webpush_settings, @@ -49,7 +49,7 @@ __all__ = [ "fee_reserve_total", "pay_invoice", "service_fee", - "update_pending_payments", + "update_wallet_pending_payments", "update_wallet_balance", # settings "check_webpush_settings", diff --git a/lnbits/core/services/payments.py b/lnbits/core/services/payments.py index 5187cd66c..1c058b868 100644 --- a/lnbits/core/services/payments.py +++ b/lnbits/core/services/payments.py @@ -171,7 +171,7 @@ async def create_invoice( return payment -async def update_pending_payments(wallet_id: str): +async def update_wallet_pending_payments(wallet_id: str): pending_payments = await get_payments( wallet_id=wallet_id, pending=True, @@ -187,6 +187,43 @@ async def update_pending_payments(wallet_id: str): await update_payment(payment) +async def update_pending_payments( + offset: Optional[int] = 0, + limit: Optional[int] = 100, + since: Optional[int] = None, + delay: Optional[int] = 0, +) -> list[Payment]: + """ + Updates the status of the pending payments based on the funding source state. + """ + pending_payments = await get_payments( + since=since, + complete=False, + pending=True, + exclude_uncheckable=True, + offset=offset, + limit=limit, + ) + for i, payment in enumerate(pending_payments): + status = await payment.check_status() + prefix = f"payment [{(offset or 0) +i +1}]" + if status.failed: + payment.status = PaymentState.FAILED + await update_payment(payment) + logger.debug(f"{prefix} failed {payment.checking_id}") + elif status.success: + payment.fee = status.fee_msat or 0 + payment.preimage = status.preimage + payment.status = PaymentState.SUCCESS + await update_payment(payment) + logger.debug(f"{prefix} success {payment.checking_id}") + else: + logger.debug(f"{prefix} pending {payment.checking_id}") + await asyncio.sleep(delay or 0.01) # to avoid complete blocking + + return pending_payments + + def fee_reserve_total(amount_msat: int, internal: bool = False) -> int: return fee_reserve(amount_msat, internal) + service_fee(amount_msat, internal) diff --git a/lnbits/core/views/payment_api.py b/lnbits/core/views/payment_api.py index 6cfcc511c..92a1e0bad 100644 --- a/lnbits/core/views/payment_api.py +++ b/lnbits/core/views/payment_api.py @@ -68,7 +68,7 @@ from ..services import ( create_invoice, fee_reserve_total, pay_invoice, - update_pending_payments, + update_wallet_pending_payments, ) payment_router = APIRouter(prefix="/api/v1/payments", tags=["Payments"]) @@ -86,7 +86,7 @@ async def api_payments( key_info: WalletTypeInfo = Depends(require_invoice_key), filters: Filters = Depends(parse_filters(PaymentFilters)), ): - await update_pending_payments(key_info.wallet.id) + await update_wallet_pending_payments(key_info.wallet.id) return await get_payments( wallet_id=key_info.wallet.id, pending=True, @@ -106,7 +106,7 @@ async def api_payments_history( group: DateTrunc = Query("day"), filters: Filters[PaymentFilters] = Depends(parse_filters(PaymentFilters)), ): - await update_pending_payments(key_info.wallet.id) + await update_wallet_pending_payments(key_info.wallet.id) return await get_payments_history(key_info.wallet.id, group, filters) @@ -180,7 +180,7 @@ async def api_payments_paginated( key_info: WalletTypeInfo = Depends(require_invoice_key), filters: Filters = Depends(parse_filters(PaymentFilters)), ): - await update_pending_payments(key_info.wallet.id) + await update_wallet_pending_payments(key_info.wallet.id) page = await get_payments_paginated( wallet_id=key_info.wallet.id, filters=filters, diff --git a/lnbits/tasks.py b/lnbits/tasks.py index 4d84cae11..ed7bc5cff 100644 --- a/lnbits/tasks.py +++ b/lnbits/tasks.py @@ -13,11 +13,11 @@ from typing import ( from loguru import logger from lnbits.core.crud import ( - get_payments, get_standalone_payment, update_payment, ) from lnbits.core.models import Payment, PaymentState +from lnbits.core.services.payments import update_pending_payments from lnbits.settings import settings from lnbits.wallets import get_funding_source @@ -162,35 +162,26 @@ async def check_pending_payments(): await asyncio.sleep(sleep_time) continue start_time = time.time() - pending_payments = await get_payments( - since=(int(time.time()) - 60 * 60 * 24 * 15), # 15 days ago - complete=False, - pending=True, - exclude_uncheckable=True, - ) - count = len(pending_payments) - if count > 0: - logger.info(f"Task: checking {count} pending payments of last 15 days...") - for i, payment in enumerate(pending_payments): - status = await payment.check_status() - prefix = f"payment ({i+1} / {count})" - if status.failed: - payment.status = PaymentState.FAILED - await update_payment(payment) - logger.debug(f"{prefix} failed {payment.checking_id}") - elif status.success: - payment.fee = status.fee_msat or 0 - payment.preimage = status.preimage - payment.status = PaymentState.SUCCESS - await update_payment(payment) - logger.debug(f"{prefix} success {payment.checking_id}") - else: - logger.debug(f"{prefix} pending {payment.checking_id}") - await asyncio.sleep(0.01) # to avoid complete blocking + + since = int(time.time()) - 60 * 60 * 24 * 31 # 31 days ago + offset = 0 + limit = 100 + count = -1 + while count != 0: logger.info( - f"Task: pending check finished for {count} payments" - f" (took {time.time() - start_time:0.3f} s)" + f"Task [{offset, offset+limit}]: " + "checking pending payments of last 31 days..." ) + pending_payments = await update_pending_payments( + offset=offset, limit=limit, since=since + ) + count = len(pending_payments) + offset += limit + logger.info( + f"Task: pending check finished for {count} payments " + f"(took {time.time() - start_time:0.3f} s)" + ) + await asyncio.sleep(0.1) await asyncio.sleep(sleep_time)