This commit is contained in:
callebtc
2022-10-09 17:51:37 +02:00
parent b7361145e0
commit e4747910c9
5 changed files with 28 additions and 24 deletions

View File

@@ -1,9 +1,15 @@
import asyncio
from functools import partial, wraps
from typing import List
from cashu.core.base import Proof
from cashu.core.settings import LIGHTNING_FEE_PERCENT, LIGHTNING_RESERVE_FEE_MIN
def sum_proofs(proofs: List[Proof]):
return sum([p.amount for p in proofs])
def async_wrap(func):
@wraps(func)
async def run(*args, loop=None, executor=None, **kwargs):

View File

@@ -19,7 +19,7 @@ from cashu.core.base import (
)
from cashu.core.crypto import derive_keys, derive_keyset_id, derive_pubkeys
from cashu.core.db import Database
from cashu.core.helpers import fee_reserve
from cashu.core.helpers import fee_reserve, sum_proofs
from cashu.core.script import verify_script
from cashu.core.secp import PublicKey
from cashu.core.settings import LIGHTNING, MAX_ORDER
@@ -45,6 +45,7 @@ class Ledger:
self.db: Database = Database("mint", db)
async def load_used_proofs(self):
"""Load all used proofs from database."""
self.proofs_used = set(await get_proofs_used(db=self.db))
async def init_keysets(self):
@@ -93,12 +94,8 @@ class Ledger:
"""Checks whether the proof was already spent."""
return not proof.secret in self.proofs_used
def _verify_secret_or_script(self, proof: Proof):
if proof.secret and proof.script:
raise Exception("secret and script present at the same time.")
return True
def _verify_secret_criteria(self, proof: Proof):
"""Verifies that a secret is present"""
if proof.secret is None or proof.secret == "":
raise Exception("no secret in proof.")
return True
@@ -213,7 +210,7 @@ class Ledger:
invoice: Invoice = await get_lightning_invoice(payment_hash, db=self.db)
if invoice.issued:
raise Exception("tokens already issued for this invoice.")
total_requested = sum([amount for amount in amounts])
total_requested = sum(amounts)
if total_requested > invoice.amount:
raise Exception(
f"Requested amount too high: {total_requested}. Invoice amount: {invoice.amount}"
@@ -287,7 +284,7 @@ class Ledger:
if not all([self._verify_proof(p) for p in proofs]):
raise Exception("could not verify proofs.")
total_provided = sum([p["amount"] for p in proofs])
total_provided = sum_proofs(proofs)
invoice_obj = bolt11.decode(invoice)
amount = math.ceil(invoice_obj.amount_msat / 1000)
fees_msat = await self.check_fees(invoice)
@@ -319,7 +316,7 @@ class Ledger:
self, proofs: List[Proof], amount: int, outputs: List[BlindedMessage]
):
"""Consumes proofs and prepares new promises based on the amount split."""
total = sum([p.amount for p in proofs])
total = sum_proofs(proofs)
# verify that amount is kosher
self._verify_split_amount(amount)

View File

@@ -81,11 +81,17 @@ async def melt(payload: MeltRequest):
@router.post("/check")
async def check_spendable(payload: CheckRequest):
"""Check whether a secret has been spent already or not."""
return await ledger.check_spendable(payload.proofs)
@router.post("/checkfees")
async def check_fees(payload: CheckFeesRequest):
"""
Responds with the fees necessary to pay a Lightning invoice.
Used by wallets for figuring out the fees they need to supply.
This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu).
"""
fees_msat = await ledger.check_fees(payload.pr)
return CheckFeesResponse(fee=fees_msat / 1000)

View File

@@ -18,7 +18,7 @@ from loguru import logger
import cashu.core.bolt11 as bolt11
from cashu.core.base import Proof
from cashu.core.bolt11 import Invoice, decode
from cashu.core.helpers import fee_reserve
from cashu.core.helpers import fee_reserve, sum_proofs
from cashu.core.migrations import migrate_databases
from cashu.core.settings import CASHU_DIR, DEBUG, ENV_FILE, LIGHTNING, MINT_URL, VERSION
from cashu.wallet import migrations
@@ -267,7 +267,7 @@ async def pending(ctx):
int(grouped_proofs[0].time_reserved)
).strftime("%Y-%m-%d %H:%M:%S")
print(
f"#{i} Amount: {sum([p['amount'] for p in grouped_proofs])} sat Time: {reserved_date} ID: {key}\n"
f"#{i} Amount: {sum_proofs(grouped_proofs)} sat Time: {reserved_date} ID: {key}\n"
)
print(f"With secret: {coin}\n\nSecretless: {coin_hidden_secret}\n")
print(f"--------------------------\n")

View File

@@ -22,6 +22,7 @@ from cashu.core.base import (
WalletKeyset,
)
from cashu.core.db import Database
from cashu.core.helpers import sum_proofs
from cashu.core.script import (
step0_carol_checksig_redeemscrip,
step0_carol_privkey,
@@ -190,7 +191,7 @@ class LedgerAPI:
If scnd_secret is provided, the wallet will create blinded secrets with those to attach a
predefined spending condition to the tokens they want to send."""
total = sum([p["amount"] for p in proofs])
total = sum_proofs(proofs)
frst_amt, scnd_amt = total - amount, amount
frst_outputs = amount_split(frst_amt)
scnd_outputs = amount_split(scnd_amt)
@@ -312,12 +313,6 @@ class Wallet(LedgerAPI):
for proof in proofs:
await store_proof(proof, db=self.db)
@staticmethod
def _sum_proofs(proofs: List[Proof], available_only=False):
if available_only:
return sum([p.amount for p in proofs if not p.reserved])
return sum([p.amount for p in proofs])
@staticmethod
def _get_proofs_per_keyset(proofs: List[Proof]):
return {key: list(group) for key, group in groupby(proofs, lambda p: p.id)}
@@ -345,7 +340,7 @@ class Wallet(LedgerAPI):
# attach unlock scripts to proofs
for p in proofs:
p.script = P2SHScript(script=scnd_script, signature=scnd_siganture)
return await self.split(proofs, sum(p["amount"] for p in proofs))
return await self.split(proofs, sum_proofs(proofs))
async def split(
self,
@@ -405,7 +400,7 @@ class Wallet(LedgerAPI):
if scnd_secret:
logger.debug(f"Spending conditions: {scnd_secret}")
spendable_proofs = await self._get_spendable_proofs(proofs)
if sum([p.amount for p in spendable_proofs]) < amount:
if sum_proofs(spendable_proofs) < amount:
raise Exception("balance too low.")
return await self.split(
[p for p in spendable_proofs if not p.reserved], amount, scnd_secret
@@ -453,11 +448,11 @@ class Wallet(LedgerAPI):
@property
def balance(self):
return sum(p["amount"] for p in self.proofs)
return sum_proofs(self.proofs)
@property
def available_balance(self):
return sum(p["amount"] for p in self.proofs if not p.reserved)
return sum_proofs([p for p in self.proofs if not p.reserved])
def status(self):
print(
@@ -467,8 +462,8 @@ class Wallet(LedgerAPI):
def balance_per_keyset(self):
return {
key: {
"balance": self._sum_proofs(proofs),
"available": self._sum_proofs(proofs, available_only=True),
"balance": sum_proofs(proofs),
"available": sum_proofs([p for p in proofs if not p.reserved]),
}
for key, proofs in self._get_proofs_per_keyset(self.proofs).items()
}