Mint: option to not duplicate keysets (#409)

* option to not duplicate keysets

* test also settings
This commit is contained in:
callebtc
2024-02-05 23:19:31 +01:00
committed by GitHub
parent 087ee957a5
commit 7574b13229
3 changed files with 86 additions and 20 deletions

View File

@@ -56,11 +56,37 @@ class MintSettings(CashuSettings):
mint_listen_port: int = Field(default=3338)
mint_lightning_backend: str = Field(default="LNbitsWallet")
mint_database: str = Field(default="data/mint")
mint_peg_out_only: bool = Field(default=False)
mint_max_peg_in: int = Field(default=None)
mint_max_peg_out: int = Field(default=None)
mint_max_request_length: int = Field(default=1000)
mint_max_balance: int = Field(default=None)
mint_peg_out_only: bool = Field(
default=False,
title="Peg-out only",
description="Mint allows no mint operations.",
)
mint_max_peg_in: int = Field(
default=None,
title="Maximum peg-in",
description="Maximum amount for a mint operation.",
)
mint_max_peg_out: int = Field(
default=None,
title="Maximum peg-out",
description="Maximum amount for a melt operation.",
)
mint_max_request_length: int = Field(
default=1000,
title="Maximum request length",
description="Maximum length of REST API request arrays.",
)
mint_max_balance: int = Field(
default=None, title="Maximum mint balance", description="Maximum mint balance."
)
mint_duplicate_keysets: bool = Field(
default=True,
title="Duplicate keysets",
description=(
"Whether to duplicate keysets for backwards compatibility before v1 API"
" (Nutshell 0.15.0)."
),
)
mint_lnbits_endpoint: str = Field(default=None)
mint_lnbits_key: str = Field(default=None)
@@ -85,7 +111,7 @@ class MintInformation(CashuSettings):
class WalletSettings(CashuSettings):
tor: bool = Field(default=True)
tor: bool = Field(default=False)
socks_host: str = Field(default=None) # deprecated
socks_port: int = Field(default=9050) # deprecated
socks_proxy: str = Field(default=None)

View File

@@ -156,14 +156,19 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
logger.debug(f"Loaded keyset {keyset.id}")
return keyset
async def init_keysets(self, autosave=True) -> None:
async def init_keysets(
self, autosave: bool = True, duplicate_keysets: Optional[bool] = None
) -> None:
"""Initializes all keysets of the mint from the db. Loads all past keysets from db
and generate their keys. Then activate the current keyset set by self.derivation_path.
Args:
autosave (bool, optional): Whether the current keyset should be saved if it is
not in the database yet. Will be passed to `self.activate_keyset` where it is
generated from `self.derivation_path`. Defaults to True.
not in the database yet. Will be passed to `self.activate_keyset` where it is
generated from `self.derivation_path`. Defaults to True.
duplicate_keysets (bool, optional): Whether to duplicate new keysets and compute
their old keyset id, and duplicate old keysets and compute their new keyset id.
Defaults to False.
"""
# load all past keysets from db, the keys will be generated at instantiation
tmp_keysets: List[MintKeyset] = await self.crud.get_keyset(db=self.db)
@@ -190,17 +195,22 @@ class Ledger(LedgerVerification, LedgerSpendingConditions):
# BEGIN BACKWARDS COMPATIBILITY < 0.15.0
# we duplicate new keysets and compute their old keyset id, and
# we duplicate old keysets and compute their new keyset id
for _, keyset in copy.copy(self.keysets).items():
keyset_copy = copy.copy(keyset)
assert keyset_copy.public_keys
if keyset.version_tuple >= (0, 15):
keyset_copy.id = derive_keyset_id_deprecated(keyset_copy.public_keys)
else:
keyset_copy.id = derive_keyset_id(keyset_copy.public_keys)
keyset_copy.duplicate_keyset_id = keyset.id
self.keysets[keyset_copy.id] = keyset_copy
# remember which keyset this keyset was duplicated from
logger.debug(f"Duplicated keyset id {keyset.id} -> {keyset_copy.id}")
if (
duplicate_keysets is None and settings.mint_duplicate_keysets
) or duplicate_keysets:
for _, keyset in copy.copy(self.keysets).items():
keyset_copy = copy.copy(keyset)
assert keyset_copy.public_keys
if keyset.version_tuple >= (0, 15):
keyset_copy.id = derive_keyset_id_deprecated(
keyset_copy.public_keys
)
else:
keyset_copy.id = derive_keyset_id(keyset_copy.public_keys)
keyset_copy.duplicate_keyset_id = keyset.id
self.keysets[keyset_copy.id] = keyset_copy
# remember which keyset this keyset was duplicated from
logger.debug(f"Duplicated keyset id {keyset.id} -> {keyset_copy.id}")
# END BACKWARDS COMPATIBILITY < 0.15.0
def get_keyset(self, keyset_id: Optional[str] = None) -> Dict[int, str]:

View File

@@ -30,6 +30,36 @@ def assert_amt(proofs: List[Proof], expected: int):
assert [p.amount for p in proofs] == expected
@pytest.mark.asyncio
async def test_init_keysets_with_duplicates(ledger: Ledger):
ledger.keysets = {}
await ledger.init_keysets(duplicate_keysets=True)
assert len(ledger.keysets) == 2
@pytest.mark.asyncio
async def test_init_keysets_with_duplicates_via_settings(ledger: Ledger):
ledger.keysets = {}
settings.mint_duplicate_keysets = True
await ledger.init_keysets()
assert len(ledger.keysets) == 2
@pytest.mark.asyncio
async def test_init_keysets_without_duplicates(ledger: Ledger):
ledger.keysets = {}
await ledger.init_keysets(duplicate_keysets=False)
assert len(ledger.keysets) == 1
@pytest.mark.asyncio
async def test_init_keysets_without_duplicates_via_settings(ledger: Ledger):
ledger.keysets = {}
settings.mint_duplicate_keysets = False
await ledger.init_keysets()
assert len(ledger.keysets) == 1
@pytest.mark.asyncio
async def test_ledger_encrypt():
aes = AESCipher(DECRYPTON_KEY)