mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-21 11:04:19 +01:00
check works
This commit is contained in:
@@ -102,8 +102,6 @@ class SplitPayload(BaseModel):
|
|||||||
|
|
||||||
class CheckPayload(BaseModel):
|
class CheckPayload(BaseModel):
|
||||||
proofs: List[Proof]
|
proofs: List[Proof]
|
||||||
amount: int
|
|
||||||
output_data: MintPayloads
|
|
||||||
|
|
||||||
|
|
||||||
class MeltPayload(BaseModel):
|
class MeltPayload(BaseModel):
|
||||||
|
|||||||
15
mint/app.py
15
mint/app.py
@@ -10,7 +10,7 @@ from fastapi import FastAPI
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
import core.settings as settings
|
import core.settings as settings
|
||||||
from core.base import MintPayloads, SplitPayload, MeltPayload, Proof
|
from core.base import MintPayloads, SplitPayload, MeltPayload, CheckPayload
|
||||||
from core.settings import MINT_PRIVATE_KEY, MINT_SERVER_HOST, MINT_SERVER_PORT
|
from core.settings import MINT_PRIVATE_KEY, MINT_SERVER_HOST, MINT_SERVER_PORT
|
||||||
from lightning import WALLET
|
from lightning import WALLET
|
||||||
from mint.ledger import Ledger
|
from mint.ledger import Ledger
|
||||||
@@ -144,6 +144,11 @@ async def melt(payload: MeltPayload):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/check")
|
||||||
|
async def check_spendable(payload: CheckPayload):
|
||||||
|
return {"spendable": await ledger.check_spendable(payload.proofs)}
|
||||||
|
|
||||||
|
|
||||||
@app.post("/split")
|
@app.post("/split")
|
||||||
async def split(payload: SplitPayload):
|
async def split(payload: SplitPayload):
|
||||||
"""
|
"""
|
||||||
@@ -154,10 +159,14 @@ async def split(payload: SplitPayload):
|
|||||||
amount = payload.amount
|
amount = payload.amount
|
||||||
output_data = payload.output_data.blinded_messages
|
output_data = payload.output_data.blinded_messages
|
||||||
try:
|
try:
|
||||||
fst_promises, snd_promises = await ledger.split(proofs, amount, output_data)
|
split_return = await ledger.split(proofs, amount, output_data)
|
||||||
return {"fst": fst_promises, "snd": snd_promises}
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
return {"error": str(exc)}
|
return {"error": str(exc)}
|
||||||
|
if not split_return:
|
||||||
|
"""There was a problem with the split"""
|
||||||
|
raise Exception("could not split tokens.")
|
||||||
|
fst_promises, snd_promises = split_return
|
||||||
|
return {"fst": fst_promises, "snd": snd_promises}
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
|
|||||||
@@ -72,9 +72,13 @@ class Ledger:
|
|||||||
await store_promise(amount, B_x=B_.x, B_y=B_.y, C_x=C_.x, C_y=C_.y, db=self.db)
|
await store_promise(amount, B_x=B_.x, B_y=B_.y, C_x=C_.x, C_y=C_.y, db=self.db)
|
||||||
return BlindedSignature(amount=amount, C_=BasePoint(x=C_.x, y=C_.y))
|
return BlindedSignature(amount=amount, C_=BasePoint(x=C_.x, y=C_.y))
|
||||||
|
|
||||||
|
def _check_spendable(self, proof: Proof):
|
||||||
|
"""Checks whether the proof was already spent."""
|
||||||
|
return not proof.secret in self.proofs_used
|
||||||
|
|
||||||
def _verify_proof(self, proof: Proof):
|
def _verify_proof(self, proof: Proof):
|
||||||
"""Verifies that the proof of promise was issued by this ledger."""
|
"""Verifies that the proof of promise was issued by this ledger."""
|
||||||
if proof.secret in self.proofs_used:
|
if not self._check_spendable(proof):
|
||||||
raise Exception(f"tokens already spent. Secret: {proof.secret}")
|
raise Exception(f"tokens already spent. Secret: {proof.secret}")
|
||||||
secret_key = self.keys[proof.amount] # Get the correct key to check against
|
secret_key = self.keys[proof.amount] # Get the correct key to check against
|
||||||
C = Point(proof.C.x, proof.C.y, secp256k1)
|
C = Point(proof.C.x, proof.C.y, secp256k1)
|
||||||
@@ -202,8 +206,9 @@ class Ledger:
|
|||||||
|
|
||||||
async def check_spendable(self, proofs: List[Proof]):
|
async def check_spendable(self, proofs: List[Proof]):
|
||||||
"""Checks if all provided proofs are valid and still spendable (i.e. have not been spent)."""
|
"""Checks if all provided proofs are valid and still spendable (i.e. have not been spent)."""
|
||||||
if not all([self._verify_proof(p) for p in proofs]):
|
if not all([self._check_spendable(p) for p in proofs]):
|
||||||
return False
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
async def split(
|
async def split(
|
||||||
self, proofs: List[Proof], amount: int, output_data: List[BlindedMessage]
|
self, proofs: List[Proof], amount: int, output_data: List[BlindedMessage]
|
||||||
@@ -211,7 +216,7 @@ class Ledger:
|
|||||||
"""Consumes proofs and prepares new promises based on the amount split."""
|
"""Consumes proofs and prepares new promises based on the amount split."""
|
||||||
self._verify_split_amount(amount)
|
self._verify_split_amount(amount)
|
||||||
# Verify proofs are valid
|
# Verify proofs are valid
|
||||||
if await self.check_spendable(proofs) == False:
|
if not all([self._verify_proof(p) for p in proofs]):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
total = sum([p["amount"] for p in proofs])
|
total = sum([p["amount"] for p in proofs])
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from core.base import (
|
|||||||
Proof,
|
Proof,
|
||||||
SplitPayload,
|
SplitPayload,
|
||||||
BlindedSignature,
|
BlindedSignature,
|
||||||
|
CheckPayload,
|
||||||
)
|
)
|
||||||
from core.db import Database
|
from core.db import Database
|
||||||
from core.split import amount_split
|
from core.split import amount_split
|
||||||
@@ -112,11 +113,15 @@ class LedgerAPI:
|
|||||||
|
|
||||||
return fst_proofs, snd_proofs
|
return fst_proofs, snd_proofs
|
||||||
|
|
||||||
def check_spendable(self, proofs):
|
async def check_spendable(self, proofs: List[Proof]):
|
||||||
promises_dict = requests.post(
|
payload = CheckPayload(proofs=proofs)
|
||||||
|
return_dict = requests.post(
|
||||||
self.url + "/check",
|
self.url + "/check",
|
||||||
json=proofs.dict(),
|
json=payload.dict(),
|
||||||
).json()
|
).json()
|
||||||
|
if "spendable" in return_dict and return_dict["spendable"]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class Wallet(LedgerAPI):
|
class Wallet(LedgerAPI):
|
||||||
@@ -178,16 +183,12 @@ class Wallet(LedgerAPI):
|
|||||||
await update_proof_reserved(proof, reserved=reserved, db=self.db)
|
await update_proof_reserved(proof, reserved=reserved, db=self.db)
|
||||||
|
|
||||||
async def check_spendable(self, proofs):
|
async def check_spendable(self, proofs):
|
||||||
await super().check_spendable(proofs)
|
return await super().check_spendable(proofs)
|
||||||
|
|
||||||
async def invalidate(self, proofs):
|
async def invalidate(self, proofs):
|
||||||
# first we make sure that the server has invalidated these proofs
|
# first we make sure that the server has invalidated these proofs
|
||||||
try:
|
if await self.check_spendable(proofs):
|
||||||
await self.split(proofs, sum(p["amount"] for p in proofs))
|
raise Exception("tokens not yet spent.")
|
||||||
except Exception as exc:
|
|
||||||
assert exc.args[0].startswith("Error: tokens already spent."), Exception(
|
|
||||||
"invalidating unspent tokens"
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: check with server if they were redeemed already
|
# TODO: check with server if they were redeemed already
|
||||||
for proof in proofs:
|
for proof in proofs:
|
||||||
|
|||||||
Reference in New Issue
Block a user