mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 18:44:20 +01:00
[Mint] Fix key rotation (#177)
* rotate keys every 5 seconds * every 10 seconds * do not regenerate all past keys for each epoch cycle * remove automatic rotation * make format * print to logger * rephrase print
This commit is contained in:
@@ -14,6 +14,8 @@ from .base import (
|
|||||||
Wallet,
|
Wallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BRR = True
|
||||||
|
|
||||||
|
|
||||||
class FakeWallet(Wallet):
|
class FakeWallet(Wallet):
|
||||||
"""https://github.com/lnbits/lnbits"""
|
"""https://github.com/lnbits/lnbits"""
|
||||||
@@ -77,7 +79,7 @@ class FakeWallet(Wallet):
|
|||||||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||||
invoice = decode(bolt11)
|
invoice = decode(bolt11)
|
||||||
|
|
||||||
if invoice.payment_hash[:6] == self.privkey[:6]:
|
if invoice.payment_hash[:6] == self.privkey[:6] or BRR:
|
||||||
await self.queue.put(invoice)
|
await self.queue.put(invoice)
|
||||||
self.paid_invoices.add(invoice.payment_hash)
|
self.paid_invoices.add(invoice.payment_hash)
|
||||||
return PaymentResponse(True, invoice.payment_hash, 0)
|
return PaymentResponse(True, invoice.payment_hash, 0)
|
||||||
@@ -87,8 +89,7 @@ class FakeWallet(Wallet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||||
|
paid = checking_id in self.paid_invoices or BRR
|
||||||
paid = checking_id in self.paid_invoices
|
|
||||||
return PaymentStatus(paid or None)
|
return PaymentStatus(paid or None)
|
||||||
|
|
||||||
async def get_payment_status(self, _: str) -> PaymentStatus:
|
async def get_payment_status(self, _: str) -> PaymentStatus:
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class Ledger:
|
|||||||
self.crud = crud
|
self.crud = crud
|
||||||
self.lightning = lightning
|
self.lightning = lightning
|
||||||
self.pubkey = derive_pubkey(self.master_key)
|
self.pubkey = derive_pubkey(self.master_key)
|
||||||
|
self.keysets = MintKeysets([])
|
||||||
|
|
||||||
async def load_used_proofs(self):
|
async def load_used_proofs(self):
|
||||||
"""Load all used proofs from database."""
|
"""Load all used proofs from database."""
|
||||||
@@ -86,11 +87,21 @@ class Ledger:
|
|||||||
"""
|
"""
|
||||||
# load all past keysets from db
|
# load all past keysets from db
|
||||||
tmp_keysets: List[MintKeyset] = await self.crud.get_keyset(db=self.db)
|
tmp_keysets: List[MintKeyset] = await self.crud.get_keyset(db=self.db)
|
||||||
self.keysets = MintKeysets(tmp_keysets)
|
# add keysets from db to current keysets
|
||||||
logger.trace(f"Loading {len(self.keysets.keysets)} keysets form db.")
|
for k in tmp_keysets:
|
||||||
# generate all derived keys from stored derivation paths of past keysets
|
if k.id and k.id not in self.keysets.keysets:
|
||||||
|
self.keysets.keysets[k.id] = k
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
f"Currently, there are {len(self.keysets.keysets)} active keysets."
|
||||||
|
)
|
||||||
|
|
||||||
|
# generate all private keys, public keys, and keyset id from the derivation path for all keysets that are not yet generated
|
||||||
for _, v in self.keysets.keysets.items():
|
for _, v in self.keysets.keysets.items():
|
||||||
logger.trace(f"Generating keys for keyset {v.id}")
|
# we already generated the keys for this keyset
|
||||||
|
if v.id and v.public_keys and len(v.public_keys):
|
||||||
|
continue
|
||||||
|
logger.debug(f"Generating keys for keyset {v.id}")
|
||||||
v.generate_keys(self.master_key)
|
v.generate_keys(self.master_key)
|
||||||
# load the current keyset
|
# load the current keyset
|
||||||
self.keyset = await self.load_keyset(self.derivation_path, autosave)
|
self.keyset = await self.load_keyset(self.derivation_path, autosave)
|
||||||
@@ -128,6 +139,7 @@ class Ledger:
|
|||||||
BlindedSignature: Generated promise.
|
BlindedSignature: Generated promise.
|
||||||
"""
|
"""
|
||||||
keyset = keyset if keyset else self.keyset
|
keyset = keyset if keyset else self.keyset
|
||||||
|
logger.trace(f"Generating promise with keyset {keyset.id}.")
|
||||||
private_key_amount = keyset.private_keys[amount]
|
private_key_amount = keyset.private_keys[amount]
|
||||||
C_ = b_dhke.step2_bob(B_, private_key_amount)
|
C_ = b_dhke.step2_bob(B_, private_key_amount)
|
||||||
await self.crud.store_promise(
|
await self.crud.store_promise(
|
||||||
@@ -155,6 +167,9 @@ class Ledger:
|
|||||||
if not proof.id:
|
if not proof.id:
|
||||||
private_key_amount = self.keyset.private_keys[proof.amount]
|
private_key_amount = self.keyset.private_keys[proof.amount]
|
||||||
else:
|
else:
|
||||||
|
logger.trace(
|
||||||
|
f"Validating proof with keyset {self.keysets.keysets[proof.id].id}."
|
||||||
|
)
|
||||||
# use the appropriate active keyset for this proof.id
|
# use the appropriate active keyset for this proof.id
|
||||||
private_key_amount = self.keysets.keysets[proof.id].private_keys[
|
private_key_amount = self.keysets.keysets[proof.id].private_keys[
|
||||||
proof.amount
|
proof.amount
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# startup routine of the standalone app. These are the steps that need
|
# startup routine of the standalone app. These are the steps that need
|
||||||
# to be taken by external apps importing the cashu mint.
|
# to be taken by external apps importing the cashu mint.
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -28,6 +29,20 @@ ledger = Ledger(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def rotate_keys(n_seconds=10):
|
||||||
|
"""Rotate keyset epoch every n_seconds.
|
||||||
|
Note: This is just a helper function for testing purposes.
|
||||||
|
"""
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
i += 1
|
||||||
|
logger.info("Rotating keys.")
|
||||||
|
ledger.derivation_path = f"0/0/0/{i}"
|
||||||
|
await ledger.init_keysets()
|
||||||
|
logger.info(f"Current keyset: {ledger.keyset.id}")
|
||||||
|
await asyncio.sleep(n_seconds)
|
||||||
|
|
||||||
|
|
||||||
async def start_mint_init():
|
async def start_mint_init():
|
||||||
await migrate_databases(ledger.db, migrations)
|
await migrate_databases(ledger.db, migrations)
|
||||||
await ledger.load_used_proofs()
|
await ledger.load_used_proofs()
|
||||||
@@ -45,3 +60,4 @@ async def start_mint_init():
|
|||||||
|
|
||||||
logger.info(f"Data dir: {settings.cashu_dir}")
|
logger.info(f"Data dir: {settings.cashu_dir}")
|
||||||
logger.info("Mint started.")
|
logger.info("Mint started.")
|
||||||
|
# asyncio.create_task(rotate_keys())
|
||||||
|
|||||||
Reference in New Issue
Block a user