From 9eab15dc6eda98bade2f2b5c3da618e9f5c07ad5 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 27 Mar 2023 10:50:37 +0000 Subject: [PATCH] mn_entry.py: check configured mnemonic entry modes at runtime --- mmgen/mn_entry.py | 54 +++++++++++++++++++----------------- test/misc/cfg.py | 6 +++- test/test_py_d/ts_cfgfile.py | 6 +++- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/mmgen/mn_entry.py b/mmgen/mn_entry.py index 21a23d9f..d7d6bb8f 100755 --- a/mmgen/mn_entry.py +++ b/mmgen/mn_entry.py @@ -213,19 +213,6 @@ class MnEntryModeMinimal(MnEntryMode): if pad > self.pad_max: return mne.idx(s,'full',lo_idx=lo,hi_idx=hi) -def mn_entry(wl_id,entry_mode=None): - if wl_id == 'words': - wl_id = 'mmgen' - me = MnemonicEntry.get_cls_by_wordlist(wl_id) - import importlib - me.bconv = getattr(importlib.import_module(f'mmgen.{me.modname}'),me.modname)(wl_id) - me.wl = me.bconv.digits - obj = me() - if entry_mode: - import mmgen.mn_entry - obj.em = getattr( mmgen.mn_entry, 'MnEntryMode'+capfirst(entry_mode) )(obj) - return obj - class MnemonicEntry(object): prompt_info = { @@ -245,6 +232,9 @@ class MnemonicEntry(object): _sw = None _usl = None + def __init__(self): + self.set_dfl_entry_mode() + @property def longest_word(self): if not self._lw: @@ -394,15 +384,22 @@ class MnemonicEntry(object): raise ValueError(f'wordlist {wl!r} not recognized (valid choices: {fmt_list(list(d))})') return d[wl] - @classmethod - def get_cfg_vars(cls): + def set_dfl_entry_mode(self): + """ + In addition to setting the default entry mode for the current wordlist, checks validity + of all user-configured entry modes + """ for k,v in g.mnemonic_entry_modes.items(): - tcls = cls.get_cls_by_wordlist(k) - if v not in tcls.entry_modes: - raise ValueError( - f'entry mode {v!r} not recognized for wordlist {k!r}:' + - f'\n (valid choices: {fmt_list(tcls.entry_modes)})' ) - tcls.usr_dfl_entry_mode = v + cls = self.get_cls_by_wordlist(k) + if v not in cls.entry_modes: + errmsg = """ + Error in cfg file option 'mnemonic_entry_modes': + Entry mode {!r} not recognized for wordlist {!r}: + Valid choices: {} + """.format( v, k, fmt_list(cls.entry_modes) ) + die(2, '\n' + fmt(errmsg,indent=' ')) + if cls == type(self): + self.usr_dfl_entry_mode = v class MnemonicEntryMMGen(MnemonicEntry): wl_id = 'mmgen' @@ -425,7 +422,14 @@ class MnemonicEntryMonero(MnemonicEntry): dfl_entry_mode = 'short' has_chksum = True -try: - MnemonicEntry.get_cfg_vars() -except Exception as e: - die(2, f"Error in cfg file option 'mnemonic_entry_modes':\n {e.args[0]}") +def mn_entry(wl_id,entry_mode=None): + if wl_id == 'words': + wl_id = 'mmgen' + me = MnemonicEntry.get_cls_by_wordlist(wl_id)() + import importlib + me.bconv = getattr(importlib.import_module(f'mmgen.{me.modname}'),me.modname)(wl_id) + me.wl = me.bconv.digits + if entry_mode: + import mmgen.mn_entry + me.em = getattr( mmgen.mn_entry, 'MnEntryMode'+capfirst(entry_mode) )(me) + return me diff --git a/test/misc/cfg.py b/test/misc/cfg.py index 1756808b..d1c2e302 100755 --- a/test/misc/cfg.py +++ b/test/misc/cfg.py @@ -34,4 +34,8 @@ if cmd_args: elif cmd_args[0] == 'autoset_opts_cmdline': assert opt.rpc_backend == 'curl', "opt.rpc_backend != 'curl'" elif cmd_args[0] == 'mnemonic_entry_modes': - msg( 'mnemonic_entry_modes: {}'.format(g.mnemonic_entry_modes) ) + from mmgen.mn_entry import mn_entry + msg('mnemonic_entry_modes: {}\nmmgen: {}\nbip39: {}'.format( + g.mnemonic_entry_modes, + mn_entry('mmgen').usr_dfl_entry_mode, + mn_entry('bip39').usr_dfl_entry_mode )) diff --git a/test/test_py_d/ts_cfgfile.py b/test/test_py_d/ts_cfgfile.py index 91186d4a..a030598d 100755 --- a/test/test_py_d/ts_cfgfile.py +++ b/test/test_py_d/ts_cfgfile.py @@ -236,7 +236,11 @@ class TestSuiteCfgFile(TestSuiteBase): txt = 'mnemonic_entry_modes mmgen:full bip39:short' write_to_file(self.path('usr'),txt+'\n') imsg(yellow(f'Wrote cfg file: {txt!r}')) - return run("{'mmgen': 'full', 'bip39': 'short'}") + t = run("{'mmgen': 'full', 'bip39': 'short'}") + # check that set_dfl_entry_mode() set the mode correctly: + t.expect('mmgen: full') + t.expect('bip39: short') + return t def chain_names(self):