Token state check with Y (#468)

* Token state check with Y

* remove backwards compat for v1
This commit is contained in:
callebtc
2024-03-12 15:53:18 +01:00
committed by GitHub
parent 4f52973908
commit 150195d66a
9 changed files with 99 additions and 88 deletions

View File

@@ -51,10 +51,7 @@ class LedgerVerification(LedgerSpendingConditions, SupportsKeysets, SupportsDb):
"""
# Verify inputs
# Verify proofs are spendable
if (
not len(await self._get_proofs_spent_idx_secret([p.secret for p in proofs]))
== 0
):
if not len(await self._get_proofs_spent([p.Y for p in proofs])) == 0:
raise TokenAlreadySpentError()
# Verify amounts of inputs
if not all([self._verify_amount(p.amount) for p in proofs]):
@@ -87,11 +84,13 @@ class LedgerVerification(LedgerSpendingConditions, SupportsKeysets, SupportsDb):
# Verify that input keyset units are the same as output keyset unit
# We have previously verified that all outputs have the same keyset id in `_verify_outputs`
assert outputs[0].id, "output id not set"
if not all([
self.keysets[p.id].unit == self.keysets[outputs[0].id].unit
for p in proofs
if p.id
]):
if not all(
[
self.keysets[p.id].unit == self.keysets[outputs[0].id].unit
for p in proofs
if p.id
]
):
raise TransactionError("input and output keysets have different units.")
# Verify output spending conditions
@@ -143,39 +142,34 @@ class LedgerVerification(LedgerSpendingConditions, SupportsKeysets, SupportsDb):
result.append(False if promise is None else True)
return result
async def _get_proofs_pending_idx_secret(
self, secrets: List[str]
) -> Dict[str, Proof]:
"""Returns only those proofs that are pending."""
all_proofs_pending = await self.crud.get_proofs_pending(
proofs=[Proof(secret=s) for s in secrets], db=self.db
)
proofs_pending = list(filter(lambda p: p.secret in secrets, all_proofs_pending))
proofs_pending_dict = {p.secret: p for p in proofs_pending}
async def _get_proofs_pending(self, Ys: List[str]) -> Dict[str, Proof]:
"""Returns a dictionary of only those proofs that are pending.
The key is the Y=h2c(secret) and the value is the proof.
"""
proofs_pending = await self.crud.get_proofs_pending(Ys=Ys, db=self.db)
proofs_pending_dict = {p.Y: p for p in proofs_pending}
return proofs_pending_dict
async def _get_proofs_spent_idx_secret(
self, secrets: List[str]
) -> Dict[str, Proof]:
"""Returns all proofs that are spent."""
proofs = [Proof(secret=s) for s in secrets]
proofs_spent: List[Proof] = []
async def _get_proofs_spent(self, Ys: List[str]) -> Dict[str, Proof]:
"""Returns a dictionary of all proofs that are spent.
The key is the Y=h2c(secret) and the value is the proof.
"""
proofs_spent_dict: Dict[str, Proof] = {}
if settings.mint_cache_secrets:
# check used secrets in memory
for proof in proofs:
spent_proof = self.spent_proofs.get(proof.Y)
for Y in Ys:
spent_proof = self.spent_proofs.get(Y)
if spent_proof:
proofs_spent.append(spent_proof)
proofs_spent_dict[Y] = spent_proof
else:
# check used secrets in database
async with self.db.connect() as conn:
for proof in proofs:
for Y in Ys:
spent_proof = await self.crud.get_proof_used(
db=self.db, Y=proof.Y, conn=conn
db=self.db, Y=Y, conn=conn
)
if spent_proof:
proofs_spent.append(spent_proof)
proofs_spent_dict = {p.secret: p for p in proofs_spent}
proofs_spent_dict[Y] = spent_proof
return proofs_spent_dict
def _verify_secret_criteria(self, proof: Proof) -> Literal[True]: