mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 18:44:20 +01:00
Token state check with Y (#468)
* Token state check with Y * remove backwards compat for v1
This commit is contained in:
@@ -486,7 +486,7 @@ class PostSplitResponse_Very_Deprecated(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class PostCheckStateRequest(BaseModel):
|
class PostCheckStateRequest(BaseModel):
|
||||||
secrets: List[str] = Field(..., max_items=settings.mint_max_request_length)
|
Ys: List[str] = Field(..., max_items=settings.mint_max_request_length)
|
||||||
|
|
||||||
|
|
||||||
class SpentState(Enum):
|
class SpentState(Enum):
|
||||||
@@ -499,7 +499,7 @@ class SpentState(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class ProofState(BaseModel):
|
class ProofState(BaseModel):
|
||||||
secret: str
|
Y: str
|
||||||
state: SpentState
|
state: SpentState
|
||||||
witness: Optional[str] = None
|
witness: Optional[str] = None
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ class LedgerCrud(ABC):
|
|||||||
derivation_path: str = "",
|
derivation_path: str = "",
|
||||||
seed: str = "",
|
seed: str = "",
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> List[MintKeyset]: ...
|
) -> List[MintKeyset]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_spent_proofs(
|
async def get_spent_proofs(
|
||||||
@@ -42,7 +43,8 @@ class LedgerCrud(ABC):
|
|||||||
*,
|
*,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> List[Proof]: ...
|
) -> List[Proof]:
|
||||||
|
...
|
||||||
|
|
||||||
async def get_proof_used(
|
async def get_proof_used(
|
||||||
self,
|
self,
|
||||||
@@ -50,7 +52,8 @@ class LedgerCrud(ABC):
|
|||||||
Y: str,
|
Y: str,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> Optional[Proof]: ...
|
) -> Optional[Proof]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def invalidate_proof(
|
async def invalidate_proof(
|
||||||
@@ -59,16 +62,18 @@ class LedgerCrud(ABC):
|
|||||||
db: Database,
|
db: Database,
|
||||||
proof: Proof,
|
proof: Proof,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_proofs_pending(
|
async def get_proofs_pending(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
proofs: List[Proof],
|
Ys: List[str],
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> List[Proof]: ...
|
) -> List[Proof]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def set_proof_pending(
|
async def set_proof_pending(
|
||||||
@@ -77,12 +82,14 @@ class LedgerCrud(ABC):
|
|||||||
db: Database,
|
db: Database,
|
||||||
proof: Proof,
|
proof: Proof,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def unset_proof_pending(
|
async def unset_proof_pending(
|
||||||
self, *, proof: Proof, db: Database, conn: Optional[Connection] = None
|
self, *, proof: Proof, db: Database, conn: Optional[Connection] = None
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def store_keyset(
|
async def store_keyset(
|
||||||
@@ -91,14 +98,16 @@ class LedgerCrud(ABC):
|
|||||||
db: Database,
|
db: Database,
|
||||||
keyset: MintKeyset,
|
keyset: MintKeyset,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_balance(
|
async def get_balance(
|
||||||
self,
|
self,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> int: ...
|
) -> int:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def store_promise(
|
async def store_promise(
|
||||||
@@ -112,7 +121,8 @@ class LedgerCrud(ABC):
|
|||||||
e: str = "",
|
e: str = "",
|
||||||
s: str = "",
|
s: str = "",
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_promise(
|
async def get_promise(
|
||||||
@@ -121,7 +131,8 @@ class LedgerCrud(ABC):
|
|||||||
db: Database,
|
db: Database,
|
||||||
B_: str,
|
B_: str,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> Optional[BlindedSignature]: ...
|
) -> Optional[BlindedSignature]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def store_mint_quote(
|
async def store_mint_quote(
|
||||||
@@ -130,7 +141,8 @@ class LedgerCrud(ABC):
|
|||||||
quote: MintQuote,
|
quote: MintQuote,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_mint_quote(
|
async def get_mint_quote(
|
||||||
@@ -139,7 +151,8 @@ class LedgerCrud(ABC):
|
|||||||
quote_id: str,
|
quote_id: str,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> Optional[MintQuote]: ...
|
) -> Optional[MintQuote]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_mint_quote_by_checking_id(
|
async def get_mint_quote_by_checking_id(
|
||||||
@@ -148,7 +161,8 @@ class LedgerCrud(ABC):
|
|||||||
checking_id: str,
|
checking_id: str,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> Optional[MintQuote]: ...
|
) -> Optional[MintQuote]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def update_mint_quote(
|
async def update_mint_quote(
|
||||||
@@ -157,7 +171,8 @@ class LedgerCrud(ABC):
|
|||||||
quote: MintQuote,
|
quote: MintQuote,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
# @abstractmethod
|
# @abstractmethod
|
||||||
# async def update_mint_quote_paid(
|
# async def update_mint_quote_paid(
|
||||||
@@ -176,7 +191,8 @@ class LedgerCrud(ABC):
|
|||||||
quote: MeltQuote,
|
quote: MeltQuote,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_melt_quote(
|
async def get_melt_quote(
|
||||||
@@ -186,7 +202,8 @@ class LedgerCrud(ABC):
|
|||||||
db: Database,
|
db: Database,
|
||||||
checking_id: Optional[str] = None,
|
checking_id: Optional[str] = None,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> Optional[MeltQuote]: ...
|
) -> Optional[MeltQuote]:
|
||||||
|
...
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def update_melt_quote(
|
async def update_melt_quote(
|
||||||
@@ -195,7 +212,8 @@ class LedgerCrud(ABC):
|
|||||||
quote: MeltQuote,
|
quote: MeltQuote,
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> None: ...
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
class LedgerCrudSqlite(LedgerCrud):
|
class LedgerCrudSqlite(LedgerCrud):
|
||||||
@@ -256,9 +274,11 @@ class LedgerCrudSqlite(LedgerCrud):
|
|||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> List[Proof]:
|
) -> List[Proof]:
|
||||||
rows = await (conn or db).fetchall(f"""
|
rows = await (conn or db).fetchall(
|
||||||
|
f"""
|
||||||
SELECT * from {table_with_schema(db, 'proofs_used')}
|
SELECT * from {table_with_schema(db, 'proofs_used')}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
return [Proof(**r) for r in rows] if rows else []
|
return [Proof(**r) for r in rows] if rows else []
|
||||||
|
|
||||||
async def invalidate_proof(
|
async def invalidate_proof(
|
||||||
@@ -289,16 +309,16 @@ class LedgerCrudSqlite(LedgerCrud):
|
|||||||
async def get_proofs_pending(
|
async def get_proofs_pending(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
proofs: List[Proof],
|
Ys: List[str],
|
||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> List[Proof]:
|
) -> List[Proof]:
|
||||||
rows = await (conn or db).fetchall(
|
rows = await (conn or db).fetchall(
|
||||||
f"""
|
f"""
|
||||||
SELECT * from {table_with_schema(db, 'proofs_pending')}
|
SELECT * from {table_with_schema(db, 'proofs_pending')}
|
||||||
WHERE Y IN ({','.join(['?']*len(proofs))})
|
WHERE Y IN ({','.join(['?']*len(Ys))})
|
||||||
""",
|
""",
|
||||||
tuple(proof.Y for proof in proofs),
|
tuple(Ys),
|
||||||
)
|
)
|
||||||
return [Proof(**r) for r in rows]
|
return [Proof(**r) for r in rows]
|
||||||
|
|
||||||
@@ -549,9 +569,11 @@ class LedgerCrudSqlite(LedgerCrud):
|
|||||||
db: Database,
|
db: Database,
|
||||||
conn: Optional[Connection] = None,
|
conn: Optional[Connection] = None,
|
||||||
) -> int:
|
) -> int:
|
||||||
row = await (conn or db).fetchone(f"""
|
row = await (conn or db).fetchone(
|
||||||
|
f"""
|
||||||
SELECT * from {table_with_schema(db, 'balance')}
|
SELECT * from {table_with_schema(db, 'balance')}
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
assert row, "Balance not found"
|
assert row, "Balance not found"
|
||||||
return int(row[0])
|
return int(row[0])
|
||||||
|
|
||||||
|
|||||||
@@ -886,7 +886,7 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
|
|||||||
logger.debug(f"Loaded {len(spent_proofs_list)} used proofs")
|
logger.debug(f"Loaded {len(spent_proofs_list)} used proofs")
|
||||||
self.spent_proofs = {p.Y: p for p in spent_proofs_list}
|
self.spent_proofs = {p.Y: p for p in spent_proofs_list}
|
||||||
|
|
||||||
async def check_proofs_state(self, secrets: List[str]) -> List[ProofState]:
|
async def check_proofs_state(self, Ys: List[str]) -> List[ProofState]:
|
||||||
"""Checks if provided proofs are spend or are pending.
|
"""Checks if provided proofs are spend or are pending.
|
||||||
Used by wallets to check if their proofs have been redeemed by a receiver or they are still in-flight in a transaction.
|
Used by wallets to check if their proofs have been redeemed by a receiver or they are still in-flight in a transaction.
|
||||||
|
|
||||||
@@ -895,32 +895,26 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
|
|||||||
and which isn't.
|
and which isn't.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
proofs (List[Proof]): List of proofs to check.
|
Ys (List[str]): List of Y's of proofs to check
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List[bool]: List of which proof is still spendable (True if still spendable, else False)
|
List[bool]: List of which proof is still spendable (True if still spendable, else False)
|
||||||
List[bool]: List of which proof are pending (True if pending, else False)
|
List[bool]: List of which proof are pending (True if pending, else False)
|
||||||
"""
|
"""
|
||||||
states: List[ProofState] = []
|
states: List[ProofState] = []
|
||||||
proofs_spent_idx_secret = await self._get_proofs_spent_idx_secret(secrets)
|
proofs_spent = await self._get_proofs_spent(Ys)
|
||||||
proofs_pending_idx_secret = await self._get_proofs_pending_idx_secret(secrets)
|
proofs_pending = await self._get_proofs_pending(Ys)
|
||||||
for secret in secrets:
|
for Y in Ys:
|
||||||
if (
|
if Y not in proofs_spent and Y not in proofs_pending:
|
||||||
secret not in proofs_spent_idx_secret
|
states.append(ProofState(Y=Y, state=SpentState.unspent))
|
||||||
and secret not in proofs_pending_idx_secret
|
elif Y not in proofs_spent and Y in proofs_pending:
|
||||||
):
|
states.append(ProofState(Y=Y, state=SpentState.pending))
|
||||||
states.append(ProofState(secret=secret, state=SpentState.unspent))
|
|
||||||
elif (
|
|
||||||
secret not in proofs_spent_idx_secret
|
|
||||||
and secret in proofs_pending_idx_secret
|
|
||||||
):
|
|
||||||
states.append(ProofState(secret=secret, state=SpentState.pending))
|
|
||||||
else:
|
else:
|
||||||
states.append(
|
states.append(
|
||||||
ProofState(
|
ProofState(
|
||||||
secret=secret,
|
Y=Y,
|
||||||
state=SpentState.spent,
|
state=SpentState.spent,
|
||||||
witness=proofs_spent_idx_secret[secret].witness,
|
witness=proofs_spent[Y].witness,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return states
|
return states
|
||||||
@@ -971,7 +965,9 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
|
|||||||
"""
|
"""
|
||||||
assert (
|
assert (
|
||||||
len(
|
len(
|
||||||
await self.crud.get_proofs_pending(proofs=proofs, db=self.db, conn=conn)
|
await self.crud.get_proofs_pending(
|
||||||
|
Ys=[p.Y for p in proofs], db=self.db, conn=conn
|
||||||
|
)
|
||||||
)
|
)
|
||||||
== 0
|
== 0
|
||||||
), TransactionError("proofs are pending.")
|
), TransactionError("proofs are pending.")
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ async def check_state(
|
|||||||
) -> PostCheckStateResponse:
|
) -> PostCheckStateResponse:
|
||||||
"""Check whether a secret has been spent already or not."""
|
"""Check whether a secret has been spent already or not."""
|
||||||
logger.trace(f"> POST /v1/checkstate: {payload}")
|
logger.trace(f"> POST /v1/checkstate: {payload}")
|
||||||
proof_states = await ledger.check_proofs_state(payload.secrets)
|
proof_states = await ledger.check_proofs_state(payload.Ys)
|
||||||
return PostCheckStateResponse(states=proof_states)
|
return PostCheckStateResponse(states=proof_states)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ async def check_spendable_deprecated(
|
|||||||
) -> CheckSpendableResponse_deprecated:
|
) -> CheckSpendableResponse_deprecated:
|
||||||
"""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}")
|
logger.trace(f"> POST /check: {payload}")
|
||||||
proofs_state = await ledger.check_proofs_state([p.secret for p in payload.proofs])
|
proofs_state = await ledger.check_proofs_state([p.Y for p in payload.proofs])
|
||||||
spendableList: List[bool] = []
|
spendableList: List[bool] = []
|
||||||
pendingList: List[bool] = []
|
pendingList: List[bool] = []
|
||||||
for proof_state in proofs_state:
|
for proof_state in proofs_state:
|
||||||
|
|||||||
@@ -51,10 +51,7 @@ class LedgerVerification(LedgerSpendingConditions, SupportsKeysets, SupportsDb):
|
|||||||
"""
|
"""
|
||||||
# Verify inputs
|
# Verify inputs
|
||||||
# Verify proofs are spendable
|
# Verify proofs are spendable
|
||||||
if (
|
if not len(await self._get_proofs_spent([p.Y for p in proofs])) == 0:
|
||||||
not len(await self._get_proofs_spent_idx_secret([p.secret for p in proofs]))
|
|
||||||
== 0
|
|
||||||
):
|
|
||||||
raise TokenAlreadySpentError()
|
raise TokenAlreadySpentError()
|
||||||
# Verify amounts of inputs
|
# Verify amounts of inputs
|
||||||
if not all([self._verify_amount(p.amount) for p in proofs]):
|
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
|
# 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`
|
# We have previously verified that all outputs have the same keyset id in `_verify_outputs`
|
||||||
assert outputs[0].id, "output id not set"
|
assert outputs[0].id, "output id not set"
|
||||||
if not all([
|
if not all(
|
||||||
self.keysets[p.id].unit == self.keysets[outputs[0].id].unit
|
[
|
||||||
for p in proofs
|
self.keysets[p.id].unit == self.keysets[outputs[0].id].unit
|
||||||
if p.id
|
for p in proofs
|
||||||
]):
|
if p.id
|
||||||
|
]
|
||||||
|
):
|
||||||
raise TransactionError("input and output keysets have different units.")
|
raise TransactionError("input and output keysets have different units.")
|
||||||
|
|
||||||
# Verify output spending conditions
|
# Verify output spending conditions
|
||||||
@@ -143,39 +142,34 @@ class LedgerVerification(LedgerSpendingConditions, SupportsKeysets, SupportsDb):
|
|||||||
result.append(False if promise is None else True)
|
result.append(False if promise is None else True)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def _get_proofs_pending_idx_secret(
|
async def _get_proofs_pending(self, Ys: List[str]) -> Dict[str, Proof]:
|
||||||
self, secrets: List[str]
|
"""Returns a dictionary of only those proofs that are pending.
|
||||||
) -> Dict[str, Proof]:
|
The key is the Y=h2c(secret) and the value is the proof.
|
||||||
"""Returns only those proofs that are pending."""
|
"""
|
||||||
all_proofs_pending = await self.crud.get_proofs_pending(
|
proofs_pending = await self.crud.get_proofs_pending(Ys=Ys, db=self.db)
|
||||||
proofs=[Proof(secret=s) for s in secrets], db=self.db
|
proofs_pending_dict = {p.Y: p for p in proofs_pending}
|
||||||
)
|
|
||||||
proofs_pending = list(filter(lambda p: p.secret in secrets, all_proofs_pending))
|
|
||||||
proofs_pending_dict = {p.secret: p for p in proofs_pending}
|
|
||||||
return proofs_pending_dict
|
return proofs_pending_dict
|
||||||
|
|
||||||
async def _get_proofs_spent_idx_secret(
|
async def _get_proofs_spent(self, Ys: List[str]) -> Dict[str, Proof]:
|
||||||
self, secrets: List[str]
|
"""Returns a dictionary of all proofs that are spent.
|
||||||
) -> Dict[str, Proof]:
|
The key is the Y=h2c(secret) and the value is the proof.
|
||||||
"""Returns all proofs that are spent."""
|
"""
|
||||||
proofs = [Proof(secret=s) for s in secrets]
|
proofs_spent_dict: Dict[str, Proof] = {}
|
||||||
proofs_spent: List[Proof] = []
|
|
||||||
if settings.mint_cache_secrets:
|
if settings.mint_cache_secrets:
|
||||||
# check used secrets in memory
|
# check used secrets in memory
|
||||||
for proof in proofs:
|
for Y in Ys:
|
||||||
spent_proof = self.spent_proofs.get(proof.Y)
|
spent_proof = self.spent_proofs.get(Y)
|
||||||
if spent_proof:
|
if spent_proof:
|
||||||
proofs_spent.append(spent_proof)
|
proofs_spent_dict[Y] = spent_proof
|
||||||
else:
|
else:
|
||||||
# check used secrets in database
|
# check used secrets in database
|
||||||
async with self.db.connect() as conn:
|
async with self.db.connect() as conn:
|
||||||
for proof in proofs:
|
for Y in Ys:
|
||||||
spent_proof = await self.crud.get_proof_used(
|
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:
|
if spent_proof:
|
||||||
proofs_spent.append(spent_proof)
|
proofs_spent_dict[Y] = spent_proof
|
||||||
proofs_spent_dict = {p.secret: p for p in proofs_spent}
|
|
||||||
return proofs_spent_dict
|
return proofs_spent_dict
|
||||||
|
|
||||||
def _verify_secret_criteria(self, proof: Proof) -> Literal[True]:
|
def _verify_secret_criteria(self, proof: Proof) -> Literal[True]:
|
||||||
|
|||||||
@@ -654,7 +654,7 @@ class LedgerAPI(LedgerAPIDeprecated, object):
|
|||||||
"""
|
"""
|
||||||
Checks whether the secrets in proofs are already spent or not and returns a list of booleans.
|
Checks whether the secrets in proofs are already spent or not and returns a list of booleans.
|
||||||
"""
|
"""
|
||||||
payload = PostCheckStateRequest(secrets=[p.secret for p in proofs])
|
payload = PostCheckStateRequest(Ys=[p.Y for p in proofs])
|
||||||
resp = await self.httpx.post(
|
resp = await self.httpx.post(
|
||||||
join(self.url, "/v1/checkstate"),
|
join(self.url, "/v1/checkstate"),
|
||||||
json=payload.dict(),
|
json=payload.dict(),
|
||||||
@@ -667,11 +667,11 @@ class LedgerAPI(LedgerAPIDeprecated, object):
|
|||||||
states: List[ProofState] = []
|
states: List[ProofState] = []
|
||||||
for spendable, pending, p in zip(ret.spendable, ret.pending, proofs):
|
for spendable, pending, p in zip(ret.spendable, ret.pending, proofs):
|
||||||
if spendable and not pending:
|
if spendable and not pending:
|
||||||
states.append(ProofState(secret=p.secret, state=SpentState.unspent))
|
states.append(ProofState(Y=p.Y, state=SpentState.unspent))
|
||||||
elif spendable and pending:
|
elif spendable and pending:
|
||||||
states.append(ProofState(secret=p.secret, state=SpentState.pending))
|
states.append(ProofState(Y=p.Y, state=SpentState.pending))
|
||||||
else:
|
else:
|
||||||
states.append(ProofState(secret=p.secret, state=SpentState.spent))
|
states.append(ProofState(Y=p.Y, state=SpentState.spent))
|
||||||
ret = PostCheckStateResponse(states=states)
|
ret = PostCheckStateResponse(states=states)
|
||||||
return ret
|
return ret
|
||||||
# END backwards compatibility < 0.15.0
|
# END backwards compatibility < 0.15.0
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ async def test_api_keys(ledger: Ledger):
|
|||||||
"id": keyset.id,
|
"id": keyset.id,
|
||||||
"unit": keyset.unit.name,
|
"unit": keyset.unit.name,
|
||||||
"keys": {
|
"keys": {
|
||||||
str(k): v.serialize().hex() for k, v in keyset.public_keys.items() # type: ignore
|
str(k): v.serialize().hex()
|
||||||
|
for k, v in keyset.public_keys.items() # type: ignore
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for keyset in ledger.keysets.values()
|
for keyset in ledger.keysets.values()
|
||||||
@@ -378,7 +379,7 @@ async def test_melt_external(ledger: Ledger, wallet: Wallet):
|
|||||||
reason="settings.debug_mint_only_deprecated is set",
|
reason="settings.debug_mint_only_deprecated is set",
|
||||||
)
|
)
|
||||||
async def test_api_check_state(ledger: Ledger):
|
async def test_api_check_state(ledger: Ledger):
|
||||||
payload = PostCheckStateRequest(secrets=["asdasdasd", "asdasdasd1"])
|
payload = PostCheckStateRequest(Ys=["asdasdasd", "asdasdasd1"])
|
||||||
response = httpx.post(
|
response = httpx.post(
|
||||||
f"{BASE_URL}/v1/checkstate",
|
f"{BASE_URL}/v1/checkstate",
|
||||||
json=payload.dict(),
|
json=payload.dict(),
|
||||||
|
|||||||
@@ -357,7 +357,5 @@ async def test_check_proof_state(wallet1: Wallet, ledger: Ledger):
|
|||||||
|
|
||||||
keep_proofs, send_proofs = await wallet1.split_to_send(wallet1.proofs, 10)
|
keep_proofs, send_proofs = await wallet1.split_to_send(wallet1.proofs, 10)
|
||||||
|
|
||||||
proof_states = await ledger.check_proofs_state(
|
proof_states = await ledger.check_proofs_state(Ys=[p.Y for p in send_proofs])
|
||||||
secrets=[p.secret for p in send_proofs]
|
|
||||||
)
|
|
||||||
assert all([p.state.value == "UNSPENT" for p in proof_states])
|
assert all([p.state.value == "UNSPENT" for p in proof_states])
|
||||||
|
|||||||
Reference in New Issue
Block a user