Files
nutshell/cashu/mint/tasks.py
callebtc d8d3037cc5 WIP: New melt flow (#622)
* `PaymentResult`

* ledger: rely on PaymentResult instead of paid flag. Double check for payments marked pending.

* `None` is `PENDING`

* make format

* reflected changes API tests where `PaymentStatus` is used + reflected changes in lnbits

* reflect changes in blink backend and tests

* fix lnbits get_payment_status

* remove paid flag

* fix mypy

* remove more paid flags

* fix strike mypy

* green

* shorten all state checks

* fix

* fix some tests

* gimme 

* fix............

* fix lnbits

* fix error

* lightning refactor

* add more regtest tests

* add tests for pending state and failure

* shorten checks

* use match case for startup check - and remember modified checking_id from pay_invoice

* fix strike pending return

* new tests?

* refactor startup routine into get_melt_quote

* test with purge

* refactor blink

* cleanup responses

* blink: return checking_id on failure

* fix lndgrpc try except

* add more testing for melt branches

* speed things up a bit

* remove comments

* remove comments

* block pending melt quotes

* remove comments

---------

Co-authored-by: lollerfirst <lollerfirst@gmail.com>
2024-09-24 14:55:35 +02:00

67 lines
2.6 KiB
Python

import asyncio
from typing import List, Mapping
from loguru import logger
from ..core.base import Method, MintQuoteState, Unit
from ..core.db import Database
from ..lightning.base import LightningBackend
from ..mint.crud import LedgerCrud
from .events.events import LedgerEventManager
from .protocols import SupportsBackends, SupportsDb, SupportsEvents
class LedgerTasks(SupportsDb, SupportsBackends, SupportsEvents):
backends: Mapping[Method, Mapping[Unit, LightningBackend]] = {}
db: Database
crud: LedgerCrud
events: LedgerEventManager
async def dispatch_listeners(self) -> List[asyncio.Task]:
tasks = []
for method, unitbackends in self.backends.items():
for unit, backend in unitbackends.items():
logger.debug(
f"Dispatching backend invoice listener for {method} {unit} {backend.__class__.__name__}"
)
tasks.append(asyncio.create_task(self.invoice_listener(backend)))
return tasks
async def invoice_listener(self, backend: LightningBackend) -> None:
if backend.supports_incoming_payment_stream:
while True:
try:
async for checking_id in backend.paid_invoices_stream():
await self.invoice_callback_dispatcher(checking_id)
except Exception as e:
logger.error(f"Error in invoice listener: {e}")
logger.info("Restarting invoice listener...")
await asyncio.sleep(1)
async def invoice_callback_dispatcher(self, checking_id: str) -> None:
logger.debug(f"Invoice callback dispatcher: {checking_id}")
async with self.db.get_connection(
lock_table="mint_quotes",
lock_select_statement=f"checking_id='{checking_id}'",
lock_timeout=5,
) as conn:
quote = await self.crud.get_mint_quote(
checking_id=checking_id, db=self.db, conn=conn
)
if not quote:
logger.error(f"Quote not found for {checking_id}")
return
logger.trace(
f"Invoice callback dispatcher: quote {quote} trying to set as {MintQuoteState.paid}"
)
# set the quote as paid
if quote.unpaid:
quote.state = MintQuoteState.paid
await self.crud.update_mint_quote(quote=quote, db=self.db, conn=conn)
logger.trace(
f"Quote {quote.quote} with {MintQuoteState.unpaid} set as {quote.state.value}"
)
await self.events.submit(quote)