mint: add trace logs (#213)

This commit is contained in:
callebtc
2023-05-14 23:06:35 +02:00
committed by GitHub
parent d1cae88062
commit 68d9020cb3
4 changed files with 47 additions and 7 deletions

View File

@@ -42,6 +42,7 @@ class CashuSettings(BaseSettings):
class EnvSettings(CashuSettings): class EnvSettings(CashuSettings):
debug: bool = Field(default=False) debug: bool = Field(default=False)
log_level: str = Field(default="INFO")
host: str = Field(default="127.0.0.1") host: str = Field(default="127.0.0.1")
port: int = Field(default=3338) port: int = Field(default=3338)
cashu_dir: str = Field(default=os.path.join(str(Path.home()), ".cashu")) cashu_dir: str = Field(default=os.path.join(str(Path.home()), ".cashu"))

View File

@@ -52,7 +52,9 @@ def create_app(config_object="core.settings") -> FastAPI:
logger.log(level, record.getMessage()) logger.log(level, record.getMessage())
logger.remove() logger.remove()
log_level: str = "DEBUG" if settings.debug else "INFO" log_level = settings.log_level
if settings.debug and log_level == "INFO":
log_level = "DEBUG"
formatter = Formatter() formatter = Formatter()
logger.add(sys.stderr, level=log_level, format=formatter.format) logger.add(sys.stderr, level=log_level, format=formatter.format)

View File

@@ -536,13 +536,15 @@ class Ledger:
Returns: Returns:
Tuple[str, str]: Bolt11 invoice and a hash (for looking it up later) Tuple[str, str]: Bolt11 invoice and a hash (for looking it up later)
""" """
logger.trace(f"called request_mint")
if settings.mint_max_peg_in and amount > settings.mint_max_peg_in: if settings.mint_max_peg_in and amount > settings.mint_max_peg_in:
raise Exception(f"Maximum mint amount is {settings.mint_max_peg_in} sats.") raise Exception(f"Maximum mint amount is {settings.mint_max_peg_in} sats.")
if settings.mint_peg_out_only: if settings.mint_peg_out_only:
raise Exception("Mint does not allow minting new tokens.") raise Exception("Mint does not allow minting new tokens.")
logger.trace(f"requesting invoice for {amount} satoshis")
payment_request, payment_hash = await self._request_lightning_invoice(amount) payment_request, payment_hash = await self._request_lightning_invoice(amount)
logger.trace(f"got invoice {payment_request} with hash {payment_hash}")
assert payment_request and payment_hash, Exception( assert payment_request and payment_hash, Exception(
"could not fetch invoice from Lightning backend" "could not fetch invoice from Lightning backend"
) )
@@ -556,6 +558,7 @@ class Ledger:
) )
await self.crud.store_lightning_invoice(invoice=invoice, db=self.db) await self.crud.store_lightning_invoice(invoice=invoice, db=self.db)
logger.trace(f"stored invoice {invoice.hash} in db")
return payment_request, invoice.hash return payment_request, invoice.hash
async def mint( async def mint(
@@ -579,6 +582,7 @@ class Ledger:
Returns: Returns:
List[BlindedSignature]: Signatures on the outputs. List[BlindedSignature]: Signatures on the outputs.
""" """
logger.trace("called mint")
amounts = [b.amount for b in B_s] amounts = [b.amount for b in B_s]
amount = sum(amounts) amount = sum(amounts)
# check if lightning invoice was paid # check if lightning invoice was paid
@@ -586,7 +590,9 @@ class Ledger:
if not hash: if not hash:
raise Exception("no hash provided.") raise Exception("no hash provided.")
try: try:
logger.trace("checking lightning invoice")
paid = await self._check_lightning_invoice(amount, hash) paid = await self._check_lightning_invoice(amount, hash)
logger.trace(f"invoice paid: {paid}")
except Exception as e: except Exception as e:
raise e raise e
@@ -597,6 +603,7 @@ class Ledger:
) )
promises = await self._generate_promises(B_s, keyset) promises = await self._generate_promises(B_s, keyset)
logger.trace("generated promises")
return promises return promises
async def melt( async def melt(
@@ -615,12 +622,15 @@ class Ledger:
Returns: Returns:
List[BlindedMessage]: Signed outputs for returning overpaid fees to wallet. List[BlindedMessage]: Signed outputs for returning overpaid fees to wallet.
""" """
logger.trace("melt called")
# validate and set proofs as pending # validate and set proofs as pending
logger.trace("setting proofs pending")
await self._set_proofs_pending(proofs) await self._set_proofs_pending(proofs)
logger.trace(f"set proofs as pending")
try: try:
await self._verify_proofs(proofs) await self._verify_proofs(proofs)
logger.trace("verified proofs")
total_provided = sum_proofs(proofs) total_provided = sum_proofs(proofs)
invoice_obj = bolt11.decode(invoice) invoice_obj = bolt11.decode(invoice)
@@ -638,15 +648,21 @@ class Ledger:
return_promises: List[BlindedSignature] = [] return_promises: List[BlindedSignature] = []
if settings.lightning: if settings.lightning:
logger.trace("paying lightning invoice")
status, preimage, fee_msat = await self._pay_lightning_invoice( status, preimage, fee_msat = await self._pay_lightning_invoice(
invoice, fees_msat invoice, fees_msat
) )
logger.trace("paid lightning invoice")
else: else:
status, preimage, fee_msat = True, "preimage", 0 status, preimage, fee_msat = True, "preimage", 0
logger.trace(
f"status: {status}, preimage: {preimage}, fee_msat: {fee_msat}"
)
if status == True: if status == True:
await self._invalidate_proofs(proofs) await self._invalidate_proofs(proofs)
logger.trace("invalidated proofs")
# prepare change to compensate wallet for overpaid fees # prepare change to compensate wallet for overpaid fees
assert fee_msat is not None, Exception("fees not valid") assert fee_msat is not None, Exception("fees not valid")
if outputs: if outputs:
@@ -657,13 +673,16 @@ class Ledger:
outputs=outputs, outputs=outputs,
) )
else: else:
logger.trace("lightning payment unsuccessful")
raise Exception("Lightning payment unsuccessful.") raise Exception("Lightning payment unsuccessful.")
except Exception as e: except Exception as e:
raise e raise e
finally: finally:
# delete proofs from pending list # delete proofs from pending list
logger.trace("unsetting proofs pending")
await self._unset_proofs_pending(proofs) await self._unset_proofs_pending(proofs)
logger.trace("unset proofs pending")
return status, preimage, return_promises return status, preimage, return_promises
@@ -729,10 +748,11 @@ class Ledger:
Returns: Returns:
Tuple[List[BlindSignature],List[BlindSignature]]: Promises on both sides of the split. Tuple[List[BlindSignature],List[BlindSignature]]: Promises on both sides of the split.
""" """
logger.trace(f"splitting {amount} from {proofs}")
# set proofs as pending # set proofs as pending
logger.trace(f"setting proofs as pending")
await self._set_proofs_pending(proofs) await self._set_proofs_pending(proofs)
logger.trace(f"set proofs as pending")
total = sum_proofs(proofs) total = sum_proofs(proofs)
try: try:
@@ -743,21 +763,25 @@ class Ledger:
raise Exception("split amount is higher than the total sum.") raise Exception("split amount is higher than the total sum.")
await self._verify_proofs(proofs) await self._verify_proofs(proofs)
logger.trace(f"verified proofs")
# verify that only unique outputs were used # verify that only unique outputs were used
if not self._verify_no_duplicate_outputs(outputs): if not self._verify_no_duplicate_outputs(outputs):
raise Exception("duplicate promises.") raise Exception("duplicate promises.")
# verify that outputs have the correct amount # verify that outputs have the correct amount
if not self._verify_outputs(total, amount, outputs): if not self._verify_outputs(total, amount, outputs):
raise Exception("split of promises is not as expected.") raise Exception("split of promises is not as expected.")
logger.trace(f"verified outputs")
except Exception as e: except Exception as e:
raise e raise e
finally: finally:
# delete proofs from pending list # delete proofs from pending list
logger.trace(f"unsetting proofs as pending")
await self._unset_proofs_pending(proofs) await self._unset_proofs_pending(proofs)
logger.trace(f"unset proofs as pending")
# Mark proofs as used and prepare new promises # Mark proofs as used and prepare new promises
await self._invalidate_proofs(proofs) await self._invalidate_proofs(proofs)
logger.trace(f"invalidated proofs")
# split outputs according to amount # split outputs according to amount
outs_fst = amount_split(total - amount) outs_fst = amount_split(total - amount)
@@ -771,4 +795,6 @@ class Ledger:
# verify amounts in produced proofs # verify amounts in produced proofs
self._verify_equation_balanced(proofs, prom_fst + prom_snd) self._verify_equation_balanced(proofs, prom_fst + prom_snd)
logger.trace(f"split successful")
return prom_fst, prom_snd return prom_fst, prom_snd

View File

@@ -1,6 +1,7 @@
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
from fastapi import APIRouter from fastapi import APIRouter
from loguru import logger
from secp256k1 import PublicKey from secp256k1 import PublicKey
from ..core.base import ( from ..core.base import (
@@ -36,6 +37,7 @@ router: APIRouter = APIRouter()
response_model_exclude_none=True, response_model_exclude_none=True,
) )
async def info(): async def info():
logger.trace(f"> GET /info")
return GetInfoResponse( return GetInfoResponse(
name=settings.mint_info_name, name=settings.mint_info_name,
pubkey=ledger.pubkey.serialize().hex() if ledger.pubkey else None, pubkey=ledger.pubkey.serialize().hex() if ledger.pubkey else None,
@@ -60,6 +62,7 @@ async def info():
) )
async def keys() -> KeysResponse: async def keys() -> KeysResponse:
"""This endpoint returns a dictionary of all supported token values of the mint and their associated public key.""" """This endpoint returns a dictionary of all supported token values of the mint and their associated public key."""
logger.trace(f"> GET /keys")
keyset = ledger.get_keyset() keyset = ledger.get_keyset()
keys = KeysResponse.parse_obj(keyset) keys = KeysResponse.parse_obj(keyset)
return keys return keys
@@ -76,6 +79,7 @@ async def keyset_keys(idBase64Urlsafe: str) -> Union[KeysResponse, CashuError]:
The id is encoded in idBase64Urlsafe (by a wallet) and is converted back to The id is encoded in idBase64Urlsafe (by a wallet) and is converted back to
normal base64 before it can be processed (by the mint). normal base64 before it can be processed (by the mint).
""" """
logger.trace(f"> GET /keys/{idBase64Urlsafe}")
try: try:
id = idBase64Urlsafe.replace("-", "+").replace("_", "/") id = idBase64Urlsafe.replace("-", "+").replace("_", "/")
keyset = ledger.get_keyset(keyset_id=id) keyset = ledger.get_keyset(keyset_id=id)
@@ -90,6 +94,7 @@ async def keyset_keys(idBase64Urlsafe: str) -> Union[KeysResponse, CashuError]:
) )
async def keysets() -> KeysetsResponse: async def keysets() -> KeysetsResponse:
"""This endpoint returns a list of keysets that the mint currently supports and will accept tokens from.""" """This endpoint returns a list of keysets that the mint currently supports and will accept tokens from."""
logger.trace(f"> GET /keysets")
keysets = KeysetsResponse(keysets=ledger.keysets.get_ids()) keysets = KeysetsResponse(keysets=ledger.keysets.get_ids())
return keysets return keysets
@@ -102,6 +107,7 @@ async def request_mint(amount: int = 0) -> Union[GetMintResponse, CashuError]:
Call `POST /mint` after paying the invoice. Call `POST /mint` after paying the invoice.
""" """
logger.trace(f"> GET /mint: amount={amount}")
if settings.mint_peg_out_only: if settings.mint_peg_out_only:
return CashuError(code=0, error="Mint does not allow minting new tokens.") return CashuError(code=0, error="Mint does not allow minting new tokens.")
try: try:
@@ -128,6 +134,7 @@ async def mint(
Call this endpoint after `GET /mint`. Call this endpoint after `GET /mint`.
""" """
logger.trace(f"> POST /mint: {payload}")
try: try:
# BEGIN: backwards compatibility < 0.12 where we used to lookup payments with payment_hash # BEGIN: backwards compatibility < 0.12 where we used to lookup payments with payment_hash
# We use the payment_hash to lookup the hash from the database and pass that one along. # We use the payment_hash to lookup the hash from the database and pass that one along.
@@ -149,6 +156,7 @@ async def melt(payload: PostMeltRequest) -> Union[CashuError, GetMeltResponse]:
""" """
Requests tokens to be destroyed and sent out via Lightning. Requests tokens to be destroyed and sent out via Lightning.
""" """
logger.trace(f"> POST /melt: {payload}")
try: try:
ok, preimage, change_promises = await ledger.melt( ok, preimage, change_promises = await ledger.melt(
payload.proofs, payload.pr, payload.outputs payload.proofs, payload.pr, payload.outputs
@@ -168,6 +176,7 @@ async def check_spendable(
payload: CheckSpendableRequest, payload: CheckSpendableRequest,
) -> CheckSpendableResponse: ) -> CheckSpendableResponse:
"""Check whether a secret has been spent already or not.""" """Check whether a secret has been spent already or not."""
logger.trace(f"> POST /check: {payload}")
spendableList = await ledger.check_spendable(payload.proofs) spendableList = await ledger.check_spendable(payload.proofs)
return CheckSpendableResponse(spendable=spendableList) return CheckSpendableResponse(spendable=spendableList)
@@ -183,6 +192,7 @@ async def check_fees(payload: CheckFeesRequest) -> CheckFeesResponse:
Used by wallets for figuring out the fees they need to supply together with the payment amount. Used by wallets for figuring out the fees they need to supply together with the payment amount.
This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu). This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu).
""" """
logger.trace(f"> POST /checkfees: {payload}")
fees_sat = await ledger.check_fees(payload.pr) fees_sat = await ledger.check_fees(payload.pr)
return CheckFeesResponse(fee=fees_sat) return CheckFeesResponse(fee=fees_sat)
@@ -198,6 +208,7 @@ async def split(
This endpoint is used by Alice to split a set of proofs before making a payment to Carol. This endpoint is used by Alice to split a set of proofs before making a payment to Carol.
It is then used by Carol (by setting split=total) to redeem the tokens. It is then used by Carol (by setting split=total) to redeem the tokens.
""" """
logger.trace(f"> POST /split: {payload}")
assert payload.outputs, Exception("no outputs provided.") assert payload.outputs, Exception("no outputs provided.")
try: try:
split_return = await ledger.split( split_return = await ledger.split(