Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ledger.py #517

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 51 additions & 50 deletions cashu/mint/ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def __init__(

# ------- STARTUP -------

class QuoteProcessor:
async def startup_ledger(self):
await self._startup_ledger()
await self._check_pending_proofs_and_melt_quotes()
Expand All @@ -106,68 +107,68 @@ async def _startup_ledger(self):
for derivation_path in settings.mint_derivation_path_list:
await self.activate_keyset(derivation_path=derivation_path)

await self.log_backend_info()

logger.info(f"Data dir: {settings.cashu_dir}")

async def _check_pending_proofs_and_melt_quotes(self):
"""Startup routine that checks all pending proofs for their melt state and either invalidates
them for a successful melt or deletes them if the melt failed.
"""
melt_quotes = await self.get_pending_melt_quotes()
if not melt_quotes:
return
for quote in melt_quotes:
pending_proofs = await self.get_pending_proofs(quote)
await self.process_quote_payment(quote, pending_proofs)

async def log_backend_info(self):
for method in self.backends:
for unit in self.backends[method]:
backend_name = self.backends[method][unit].__class__.__name__
logger.info(
f"Using {self.backends[method][unit].__class__.__name__} backend for"
f" method: '{method.name}' and unit: '{unit.name}'"
f"Using {backend_name} backend for method: '{method.name}' and unit: '{unit.name}'"
)
status = await self.backends[method][unit].status()
if status.error_message:
logger.warning(
"The backend for"
f" {self.backends[method][unit].__class__.__name__} isn't"
f" working properly: '{status.error_message}'",
f"The backend for {backend_name} isn't working properly: '{status.error_message}'",
RuntimeWarning,
)
logger.info(f"Backend balance: {status.balance} {unit.name}")

logger.info(f"Data dir: {settings.cashu_dir}")
async def get_pending_melt_quotes(self):
return await self.crud.get_all_melt_quotes_from_pending_proofs(db=self.db)

async def get_pending_proofs(self, quote):
return await self.crud.get_pending_proofs_for_quote(quote_id=quote.quote, db=self.db)

async def process_quote_payment(self, quote, pending_proofs):
payment = await self.get_payment_status(quote)
if payment.paid:
logger.info(f"Melt quote {quote.quote} state: paid")
await self.set_melt_quote_paid(quote, payment, pending_proofs)
elif payment.failed:
logger.info(f"Melt quote {quote.quote} state: failed")
await self._unset_proofs_pending(pending_proofs)
elif payment.pending:
logger.info(f"Melt quote {quote.quote} state: pending")
else:
logger.error("Melt quote state unknown")

async def set_melt_quote_paid(self, quote, payment, pending_proofs):
quote.paid_time = int(time.time())
quote.paid = True
if payment.fee:
quote.fee_paid = payment.fee.to(Unit[quote.unit]).amount
quote.proof = payment.preimage or ""
await self.crud.update_melt_quote(quote=quote, db=self.db)
await self._invalidate_proofs(proofs=pending_proofs, quote_id=quote.quote)
await self._unset_proofs_pending(pending_proofs)

async def get_payment_status(self, quote):
return await self.backends[Method[quote.method]][Unit[quote.unit]].get_payment_status(quote.checking_id)

async def _check_pending_proofs_and_melt_quotes(self):
"""Startup routine that checks all pending proofs for their melt state and either invalidates
them for a successful melt or deletes them if the melt failed.
"""
# get all pending melt quotes
melt_quotes = await self.crud.get_all_melt_quotes_from_pending_proofs(
db=self.db
)
if not melt_quotes:
return
for quote in melt_quotes:
# get pending proofs for quote
pending_proofs = await self.crud.get_pending_proofs_for_quote(
quote_id=quote.quote, db=self.db
)
# check with the backend whether the quote has been paid during downtime
payment = await self.backends[Method[quote.method]][
Unit[quote.unit]
].get_payment_status(quote.checking_id)
if payment.paid:
logger.info(f"Melt quote {quote.quote} state: paid")
quote.paid_time = int(time.time())
quote.paid = True
if payment.fee:
quote.fee_paid = payment.fee.to(Unit[quote.unit]).amount
quote.proof = payment.preimage or ""
await self.crud.update_melt_quote(quote=quote, db=self.db)
# invalidate proofs
await self._invalidate_proofs(
proofs=pending_proofs, quote_id=quote.quote
)
# unset pending
await self._unset_proofs_pending(pending_proofs)
elif payment.failed:
logger.info(f"Melt quote {quote.quote} state: failed")

# unset pending
await self._unset_proofs_pending(pending_proofs)
elif payment.pending:
logger.info(f"Melt quote {quote.quote} state: pending")
pass
else:
logger.error("Melt quote state unknown")
pass

# ------- KEYS -------

Expand Down
Loading