burn all spent tokens with cashu burn -a

This commit is contained in:
callebtc
2022-09-17 23:26:51 +03:00
parent fac578b956
commit f02ac8d3ee
5 changed files with 57 additions and 25 deletions

View File

@@ -144,7 +144,7 @@ async def melt(payload: MeltPayload):
@app.post("/check")
async def check_spendable(payload: CheckPayload):
return {"spendable": await ledger.check_spendable(payload.proofs)}
return await ledger.check_spendable(payload.proofs)
@app.post("/split")

View File

@@ -13,9 +13,14 @@ from core.secp import PrivateKey, PublicKey
from core.settings import LIGHTNING, MAX_ORDER
from core.split import amount_split
from lightning import WALLET
from mint.crud import (get_lightning_invoice, get_proofs_used,
invalidate_proof, store_lightning_invoice,
store_promise, update_lightning_invoice)
from mint.crud import (
get_lightning_invoice,
get_proofs_used,
invalidate_proof,
store_lightning_invoice,
store_promise,
update_lightning_invoice,
)
class Ledger:
@@ -219,9 +224,7 @@ class Ledger:
async def check_spendable(self, proofs: List[Proof]):
"""Checks if all provided proofs are valid and still spendable (i.e. have not been spent)."""
if not all([self._check_spendable(p) for p in proofs]):
return False
return True
return {i: self._check_spendable(p) for i, p in enumerate(proofs)}
async def split(
self, proofs: List[Proof], amount: int, output_data: List[BlindedMessage]

View File

@@ -16,6 +16,7 @@ from core.helpers import fee_reserve
from core.migrations import migrate_databases
from core.settings import LIGHTNING, MINT_URL
from wallet import migrations
from wallet.crud import get_reserved_proofs
from wallet.wallet import Wallet as Wallet
@@ -121,14 +122,23 @@ async def receive(ctx, token: str):
@cli.command("burn", help="Burn spent tokens.")
@click.argument("token", type=str)
@click.argument("token", required=False, type=str)
@click.option("--all", "-a", default=False, is_flag=True, help="Burn all spent tokens.")
@click.pass_context
@coro
async def burn(ctx, token: str):
async def burn(ctx, token: str, all: bool):
wallet: Wallet = ctx.obj["WALLET"]
await init_wallet(wallet)
if not (all or token) or (token and all):
print("Error: enter a token or use --all to burn all pending tokens.")
return
if all:
proofs = await get_reserved_proofs(wallet.db)
else:
proofs = [
Proof.from_dict(p) for p in json.loads(base64.urlsafe_b64decode(token))
]
wallet.status()
proofs = [Proof.from_dict(p) for p in json.loads(base64.urlsafe_b64decode(token))]
await wallet.invalidate(proofs)
wallet.status()

View File

@@ -38,6 +38,20 @@ async def get_proofs(
return [Proof.from_row(r) for r in rows]
async def get_reserved_proofs(
db: Database,
conn: Optional[Connection] = None,
):
rows = await (conn or db).fetchall(
"""
SELECT * from proofs
WHERE reserved
"""
)
return [Proof.from_row(r) for r in rows]
async def invalidate_proof(
proof: Proof,
db: Database,

View File

@@ -4,13 +4,19 @@ from typing import List
import requests
import core.b_dhke as b_dhke
from core.base import (BlindedMessage, BlindedSignature, CheckPayload,
MeltPayload, MintPayloads, Proof, SplitPayload)
from core.base import (
BlindedMessage,
BlindedSignature,
CheckPayload,
MeltPayload,
MintPayloads,
Proof,
SplitPayload,
)
from core.db import Database
from core.secp import PublicKey
from core.split import amount_split
from wallet.crud import (get_proofs, invalidate_proof, store_proof,
update_proof_reserved)
from wallet.crud import get_proofs, invalidate_proof, store_proof, update_proof_reserved
class LedgerAPI:
@@ -113,9 +119,8 @@ class LedgerAPI:
self.url + "/check",
json=payload.dict(),
).json()
if "spendable" in return_dict and return_dict["spendable"]:
return True
return False
return return_dict
async def pay_lightning(self, proofs: List[Proof], amount: int, invoice: str):
payload = MeltPayload(proofs=proofs, amount=amount, invoice=invoice)
@@ -197,14 +202,14 @@ class Wallet(LedgerAPI):
return await super().check_spendable(proofs)
async def invalidate(self, proofs):
# first we make sure that the server has invalidated these proofs
if await self.check_spendable(proofs):
raise Exception("tokens not yet spent.")
# TODO: check with server if they were redeemed already
for proof in proofs:
await invalidate_proof(proof, db=self.db)
invalidate_secrets = [p["secret"] for p in proofs]
"""Invalidates all spendable tokens supplied in proofs."""
spendables = await self.check_spendable(proofs)
invalidated_proofs = []
for idx, spendable in spendables.items():
if not spendable:
invalidated_proofs.append(proofs[int(idx)])
await invalidate_proof(proofs[int(idx)], db=self.db)
invalidate_secrets = [p["secret"] for p in invalidated_proofs]
self.proofs = list(
filter(lambda p: p["secret"] not in invalidate_secrets, self.proofs)
)