Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Rotate and inactivate keysets #491

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 64 additions & 46 deletions cashu/mint/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,21 @@ class LedgerCrud(ABC):
to use their own database.
"""

@abstractmethod
async def get_keyset(
self,
*,
db: Database,
id: str = "",
derivation_path: str = "",
seed: str = "",
conn: Optional[Connection] = None,
) -> List[MintKeyset]:
...

@abstractmethod
async def get_spent_proofs(
self,
*,
db: Database,
conn: Optional[Connection] = None,
) -> List[Proof]:
...
) -> List[Proof]: ...

async def get_proof_used(
self,
*,
Y: str,
db: Database,
conn: Optional[Connection] = None,
) -> Optional[Proof]:
...
) -> Optional[Proof]: ...

@abstractmethod
async def invalidate_proof(
Expand All @@ -62,8 +48,7 @@ async def invalidate_proof(
db: Database,
proof: Proof,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def get_proofs_pending(
Expand All @@ -72,8 +57,7 @@ async def get_proofs_pending(
Ys: List[str],
db: Database,
conn: Optional[Connection] = None,
) -> List[Proof]:
...
) -> List[Proof]: ...

@abstractmethod
async def set_proof_pending(
Expand All @@ -82,14 +66,23 @@ async def set_proof_pending(
db: Database,
proof: Proof,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def unset_proof_pending(
self, *, proof: Proof, db: Database, conn: Optional[Connection] = None
) -> None:
...
) -> None: ...

@abstractmethod
async def get_keyset(
self,
*,
db: Database,
id: str = "",
derivation_path: str = "",
seed: str = "",
conn: Optional[Connection] = None,
) -> List[MintKeyset]: ...

@abstractmethod
async def store_keyset(
Expand All @@ -98,16 +91,23 @@ async def store_keyset(
db: Database,
keyset: MintKeyset,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def deactivate_keyset(
self,
*,
db: Database,
keyset: MintKeyset,
conn: Optional[Connection] = None,
) -> MintKeyset: ...

@abstractmethod
async def get_balance(
self,
db: Database,
conn: Optional[Connection] = None,
) -> int:
...
) -> int: ...

@abstractmethod
async def store_promise(
Expand All @@ -121,8 +121,7 @@ async def store_promise(
e: str = "",
s: str = "",
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def get_promise(
Expand All @@ -131,8 +130,7 @@ async def get_promise(
db: Database,
B_: str,
conn: Optional[Connection] = None,
) -> Optional[BlindedSignature]:
...
) -> Optional[BlindedSignature]: ...

@abstractmethod
async def store_mint_quote(
Expand All @@ -141,8 +139,7 @@ async def store_mint_quote(
quote: MintQuote,
db: Database,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def get_mint_quote(
Expand All @@ -151,8 +148,7 @@ async def get_mint_quote(
quote_id: str,
db: Database,
conn: Optional[Connection] = None,
) -> Optional[MintQuote]:
...
) -> Optional[MintQuote]: ...

@abstractmethod
async def get_mint_quote_by_request(
Expand All @@ -161,8 +157,7 @@ async def get_mint_quote_by_request(
request: str,
db: Database,
conn: Optional[Connection] = None,
) -> Optional[MintQuote]:
...
) -> Optional[MintQuote]: ...

@abstractmethod
async def update_mint_quote(
Expand All @@ -171,8 +166,7 @@ async def update_mint_quote(
quote: MintQuote,
db: Database,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

# @abstractmethod
# async def update_mint_quote_paid(
Expand All @@ -191,8 +185,7 @@ async def store_melt_quote(
quote: MeltQuote,
db: Database,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...

@abstractmethod
async def get_melt_quote(
Expand All @@ -202,8 +195,7 @@ async def get_melt_quote(
db: Database,
checking_id: Optional[str] = None,
conn: Optional[Connection] = None,
) -> Optional[MeltQuote]:
...
) -> Optional[MeltQuote]: ...

@abstractmethod
async def update_melt_quote(
Expand All @@ -212,8 +204,7 @@ async def update_melt_quote(
quote: MeltQuote,
db: Database,
conn: Optional[Connection] = None,
) -> None:
...
) -> None: ...


class LedgerCrudSqlite(LedgerCrud):
Expand Down Expand Up @@ -564,6 +555,33 @@ async def store_keyset(
),
)

async def deactivate_keyset(
self,
*,
db: Database,
keyset: MintKeyset,
conn: Optional[Connection] = None,
) -> MintKeyset:
await (conn or db).execute(
f"""
UPDATE {table_with_schema(db, 'keysets')}
SET active = ?
WHERE id = ?
""",
(False, keyset.id),
)

# we return the keyset from the database
row = await (conn or db).fetchone(
f"""
SELECT * from {table_with_schema(db, 'keysets')}
WHERE id = ?
""",
(keyset.id,),
)

return MintKeyset(**row)

async def get_balance(
self,
db: Database,
Expand Down
20 changes: 16 additions & 4 deletions cashu/mint/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,27 @@ async def rotate_keys(n_seconds=60):
Note: This is just a helper function for testing purposes.
"""
i = 0
new_keyset = ledger.keyset
while True:
await asyncio.sleep(n_seconds)
i += 1
logger.info("Rotating keys.")
old_keyset = new_keyset

incremented_derivation_path = (
"/".join(ledger.derivation_path.split("/")[:-1]) + f"/{i}"
)
await ledger.activate_keyset(derivation_path=incremented_derivation_path)
logger.info(f"Current keyset: {ledger.keyset.id}")
await asyncio.sleep(n_seconds)
new_keyset = await ledger.activate_keyset(
derivation_path=incremented_derivation_path
)

# deactivate old keyset and update ledger.keyset
ledger.keysets[old_keyset.id] = await ledger.crud.deactivate_keyset(
db=ledger.db, keyset=old_keyset
)

logger.info(
f"Rotate keyset and deactivated old one: {old_keyset.id} -> {new_keyset.id}."
)


async def start_mint_init():
Expand Down
Loading