diff --git a/cashu/mint/crud.py b/cashu/mint/crud.py index 75f4471c..75fb818e 100644 --- a/cashu/mint/crud.py +++ b/cashu/mint/crud.py @@ -25,26 +25,13 @@ 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, @@ -52,8 +39,7 @@ async def get_proof_used( Y: str, db: Database, conn: Optional[Connection] = None, - ) -> Optional[Proof]: - ... + ) -> Optional[Proof]: ... @abstractmethod async def invalidate_proof( @@ -62,8 +48,7 @@ async def invalidate_proof( db: Database, proof: Proof, conn: Optional[Connection] = None, - ) -> None: - ... + ) -> None: ... @abstractmethod async def get_proofs_pending( @@ -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( @@ -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( @@ -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( @@ -121,8 +121,7 @@ async def store_promise( e: str = "", s: str = "", conn: Optional[Connection] = None, - ) -> None: - ... + ) -> None: ... @abstractmethod async def get_promise( @@ -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( @@ -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( @@ -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( @@ -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( @@ -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( @@ -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( @@ -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( @@ -212,8 +204,7 @@ async def update_melt_quote( quote: MeltQuote, db: Database, conn: Optional[Connection] = None, - ) -> None: - ... + ) -> None: ... class LedgerCrudSqlite(LedgerCrud): @@ -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, diff --git a/cashu/mint/startup.py b/cashu/mint/startup.py index 94d16e61..7e8ae740 100644 --- a/cashu/mint/startup.py +++ b/cashu/mint/startup.py @@ -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():