This commit is contained in:
callebtc
2022-10-13 22:11:00 +02:00
parent 3437af041e
commit a84b04605e
4 changed files with 49 additions and 38 deletions

View File

@@ -262,6 +262,7 @@ class MintKeyset:
self.generate_keys(seed)
def generate_keys(self, seed):
"""Generates keys of a keyset from a seed."""
self.private_keys = derive_keys(seed, self.derivation_path)
self.public_keys = derive_pubkeys(self.private_keys)
self.id = derive_keyset_id(self.public_keys)

View File

@@ -6,6 +6,15 @@ from cashu.core.secp import PrivateKey, PublicKey
from cashu.core.settings import MAX_ORDER
# entropy = bytes([random.getrandbits(8) for i in range(16)])
# mnemonic = bip39.mnemonic_from_bytes(entropy)
# seed = bip39.mnemonic_to_seed(mnemonic)
# root = bip32.HDKey.from_seed(seed, version=NETWORKS["main"]["xprv"])
# bip44_xprv = root.derive("m/44h/1h/0h")
# bip44_xpub = bip44_xprv.to_public()
def derive_keys(master_key: str, derivation_path: str = ""):
"""
Deterministic derivation of keys for 2^n values.

View File

@@ -29,9 +29,6 @@ from cashu.core.split import amount_split
from cashu.mint.crud import LedgerCrud
from cashu.lightning.lnbits import LNbitsWallet
class Ledger:
def __init__(
self,
@@ -39,11 +36,12 @@ class Ledger:
seed: str,
derivation_path="",
crud=LedgerCrud,
lightning=LNbitsWallet(),
lightning=None,
):
self.proofs_used: Set[str] = set()
self.master_key = seed
self.derivation_path = derivation_path
self.db = db
self.crud = crud
self.lightning = lightning
@@ -53,33 +51,34 @@ class Ledger:
proofs_used = await self.crud.get_proofs_used(db=self.db)
self.proofs_used = set(proofs_used)
async def init_keysets(self):
"""Loads all past keysets and stores the active one if not already in db"""
# generate current keyset from seed and current derivation path
self.keyset = MintKeyset(
seed=self.master_key, derivation_path=self.derivation_path, version=VERSION
async def load_keyset(self, derivation_path):
"""Load current keyset keyset or generate new one."""
keyset = MintKeyset(
seed=self.master_key, derivation_path=derivation_path, version=VERSION
)
# check if current keyset is stored in db and store if not
logger.debug(f"Loading keyset {self.keyset.id} from db.")
current_keyset_local: List[MintKeyset] = await self.crud.get_keyset(
id=self.keyset.id, db=self.db
logger.debug(f"Loading keyset {keyset.id} from db.")
tmp_keyset_local: List[MintKeyset] = await self.crud.get_keyset(
id=keyset.id, db=self.db
)
if not len(current_keyset_local):
logger.debug(f"Storing keyset {self.keyset.id}.")
await self.crud.store_keyset(keyset=self.keyset, db=self.db)
if not len(tmp_keyset_local):
logger.debug(f"Storing keyset {keyset.id}.")
await self.crud.store_keyset(keyset=keyset, db=self.db)
return keyset
async def init_keysets(self):
"""Loads all keysets from db."""
self.keyset = await self.load_keyset(self.derivation_path)
# load all past keysets from db
# this needs two steps because the types of tmp_keysets and the argument of MintKeysets() are different
tmp_keysets: List[MintKeyset] = await self.crud.get_keyset(db=self.db)
self.keysets = MintKeysets(tmp_keysets)
logger.debug(f"Keysets {self.keysets.keysets}")
logger.debug(f"Loading {len(self.keysets.keysets)} keysets form db.")
# generate all derived keys from stored derivation paths of past keysets
for _, v in self.keysets.keysets.items():
logger.debug(f"Generating keys for keyset {v.id}")
v.generate_keys(self.master_key)
if len(self.keysets.keysets):
logger.debug(f"Loaded {len(self.keysets.keysets)} keysets from db.")
async def _generate_promises(
self, B_s: List[BlindedMessage], keyset: MintKeyset = None
):
@@ -276,13 +275,10 @@ class Ledger:
for p in proofs:
await self.crud.invalidate_proof(proof=p, db=self.db)
def _serialize_pubkeys(self):
"""Returns public keys for possible amounts."""
return {a: p.serialize().hex() for a, p in self.keyset.public_keys.items()}
# Public methods
def get_keyset(self):
return self._serialize_pubkeys()
def get_keyset(self, keyset_id: str = None):
keyset = self.keysets[keyset_id] if keyset_id else self.keyset
return {a: p.serialize().hex() for a, p in keyset.public_keys.items()}
async def request_mint(self, amount):
"""Returns Lightning invoice and stores it in the db."""
@@ -391,13 +387,16 @@ class Ledger:
# Mark proofs as used and prepare new promises
await self._invalidate_proofs(proofs)
# split outputs according to amount
outs_fst = amount_split(total - amount)
outs_snd = amount_split(amount)
B_fst = [od.B_ for od in outputs[: len(outs_fst)]]
B_snd = [od.B_ for od in outputs[len(outs_fst) :]]
B_fst = [od for od in outputs[: len(outs_fst)]]
B_snd = [od for od in outputs[len(outs_fst) :]]
# generate promises
prom_fst, prom_snd = await self._generate_promises(
outs_fst, B_fst, keyset
), await self._generate_promises(outs_snd, B_snd, keyset)
B_fst, keyset
), await self._generate_promises(B_snd, keyset)
# verify amounts in produced proofs
self._verify_equation_balanced(proofs, prom_fst + prom_snd)
return prom_fst, prom_snd

View File

@@ -14,12 +14,14 @@ from cashu.mint import migrations
from cashu.mint.ledger import Ledger
from cashu.core.settings import MINT_PRIVATE_KEY
from cashu.core.db import Database
from cashu.lightning.lnbits import LNbitsWallet
ledger = Ledger(
db=Database("mint", "data/mint"),
seed=MINT_PRIVATE_KEY,
# seed="asd",
derivation_path="0/0/0/0",
lightning=LNbitsWallet() if LIGHTNING else None,
)
@@ -29,14 +31,14 @@ async def start_mint_init():
await ledger.load_used_proofs()
await ledger.init_keysets()
# if LIGHTNING:
# error_message, balance = await WALLET.status()
# if error_message:
# logger.warning(
# f"The backend for {WALLET.__class__.__name__} isn't working properly: '{error_message}'",
# RuntimeWarning,
# )
# logger.info(f"Lightning balance: {balance} sat")
if LIGHTNING:
error_message, balance = await ledger.lightning.status()
if error_message:
logger.warning(
f"The backend for {ledger.lightning.__class__.__name__} isn't working properly: '{error_message}'",
RuntimeWarning,
)
logger.info(f"Lightning balance: {balance} sat")
logger.info(f"Data dir: {CASHU_DIR}")
logger.info("Mint started.")