From 563b0ca7d09d9eddeedb1d3259f1f7b0f56aff0d Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 27 Mar 2023 10:48:20 +0000 Subject: [PATCH] daemon.py, opts.py, globalvars.py, tool/wallet.py: minor cleanups --- mmgen/daemon.py | 4 ++-- mmgen/data/mmgen.cfg | 2 +- mmgen/globalvars.py | 12 ++++++------ mmgen/opts.py | 31 ++++++++++++++----------------- mmgen/tool/wallet.py | 20 +++++++++----------- test/test.py | 4 +++- test/test_py_d/ts_input.py | 11 ++++++++--- test/unit_tests_d/ut_lockable.py | 2 +- 8 files changed, 44 insertions(+), 42 deletions(-) diff --git a/mmgen/daemon.py b/mmgen/daemon.py index 05fc5cb3..d55b7996 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -285,8 +285,8 @@ class CoinDaemon(Daemon): ret = cls.coins[coin].daemon_ids if 'erigon' in ret and not g.enable_erigon: ret.remove('erigon') - if g.blacklist_daemons: - blacklist = g.blacklist_daemons.split() + if g.blacklisted_daemons: + blacklist = g.blacklisted_daemons.split() def gen(): for daemon_id in ret: if daemon_id in blacklist: diff --git a/mmgen/data/mmgen.cfg b/mmgen/data/mmgen.cfg index 0312e8c4..d30c09bb 100644 --- a/mmgen/data/mmgen.cfg +++ b/mmgen/data/mmgen.cfg @@ -20,7 +20,7 @@ # Uncomment to force 256-color output when 'color' is true: # force_256_color true -# Uncomment to use regtest mode (this also sets testnet to true): +# Uncomment to use regtest mode: # regtest true # Uncomment to use testnet instead of mainnet: diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index 0357b700..54cc4832 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -29,7 +29,7 @@ def die(exit_val,s=''): sys.stderr.write(s+'\n') sys.exit(exit_val) -class GlobalContext(Lockable): +class GlobalConfig(Lockable): """ Set global vars to default values Globals are overridden in this order: @@ -117,6 +117,7 @@ class GlobalContext(Lockable): debug_utf8 = False exec_wrapper = False test_suite = False + test_suite_autosign_led_simulate = False test_suite_cfgtest = False test_suite_deterministic = False test_suite_pexpect = False @@ -147,10 +148,10 @@ class GlobalContext(Lockable): else: die(2,'$HOME is not set! Unable to determine home directory') - data_dir_root,data_dir,cfg_file = (None,None,None) + data_dir_root,data_dir = (None,None) daemon_data_dir = '' # set by user daemon_id = '' - blacklist_daemons = '' + blacklisted_daemons = '' # must match CoinProtocol.coins core_coins = ('btc','bch','ltc','eth','etc','zec','xmr') @@ -250,6 +251,7 @@ class GlobalContext(Lockable): 'MMGEN_COLUMNS', 'MMGEN_TEST_SUITE', + 'MMGEN_TEST_SUITE_AUTOSIGN_LED_SIMULATE', 'MMGEN_TEST_SUITE_CFGTEST', 'MMGEN_TEST_SUITE_DETERMINISTIC', 'MMGEN_TEST_SUITE_PEXPECT', @@ -279,9 +281,7 @@ class GlobalContext(Lockable): 'MMGEN_IGNORE_DAEMON_VERSION', 'MMGEN_USE_STANDALONE_SCRYPT_MODULE', 'MMGEN_ENABLE_ERIGON', - 'MMGEN_DISABLE_COLOR', - 'MMGEN_DISABLE_MSWIN_PW_WARNING', ) infile_opts = ( 'keys_from_file', @@ -360,4 +360,4 @@ class GlobalContext(Lockable): def release_date(self): return self.get_mmgen_data_file(filename='release_date').strip() -g = GlobalContext() +g = GlobalConfig() diff --git a/mmgen/opts.py b/mmgen/opts.py index 09b59bf3..8cc1e4ea 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -19,7 +19,7 @@ """ opts: MMGen-specific options processing after generic processing by share.Opts """ -import sys,os,stat +import sys,os from .globalvars import g from .base_obj import Lockable @@ -193,7 +193,7 @@ def override_globals_from_cfg_file(ucfg,autoset_opts,env_globals,need_proto): from .util import die die( 'CfgFileParseError', f'{d.name!r}: unrecognized option in {ucfg.fn!r}, line {d.lineno}' ) -def override_globals_and_set_opts_from_env(opt): +def override_globals_from_env(): for name,val in ((k,v) for k,v in os.environ.items() if k.startswith('MMGEN_')): if name == 'MMGEN_DEBUG_ALL': continue @@ -204,11 +204,8 @@ def override_globals_and_set_opts_from_env(opt): if hasattr(g,gname): setattr(g,gname,set_for_type(val,getattr(g,gname),name,disable)) yield gname - elif hasattr(opt,gname): - if getattr(opt,gname) is None: # env must not override cmdline! - setattr(opt,gname,val) else: - raise ValueError(f'Name {gname!r} not present in globals or opts') + raise ValueError(f'Name {gname!r} not present in globals') else: raise ValueError(f'{name!r} is not a valid MMGen environment variable') @@ -333,9 +330,18 @@ def init( if opt.version: version() # exits + if opt.show_hash_presets: + _show_hash_presets() # exits + + from .term import init_term + init_term() + + from .util import wrap_ripemd160 + wrap_ripemd160() # ripemd160 used by mmgen_cfg_file() + # === begin global var initialization === # - env_globals = tuple(override_globals_and_set_opts_from_env(opt)) + env_globals = tuple(override_globals_from_env()) """ NB: user opt --data-dir is actually data_dir_root @@ -359,12 +365,6 @@ def init( from .fileutil import check_or_create_dir check_or_create_dir(g.data_dir_root) - from .term import init_term - init_term() - - from .util import wrap_ripemd160 - wrap_ripemd160() # ripemd160 used by mmgen_cfg_file() - cfgfile_autoset_opts = {} if not (opt.skip_cfg_file or opt.bob or opt.alice or g.prog_name == 'mmgen-regtest'): @@ -408,9 +408,6 @@ def init( else: setattr(opt,k,getattr(g,k)) - if opt.show_hash_presets: # exits - _show_hash_presets() - g.coin = g.coin.upper() or 'BTC' g.token = g.token.upper() or None @@ -431,7 +428,7 @@ def init( die_on_incompatible_opts(g.incompatible_opts) - check_or_create_dir(g.data_dir) # g.data_dir is finalized, so we can create it + check_or_create_dir(g.data_dir) # Check user-set opts without modifying them check_usr_opts(po.user_opts) diff --git a/mmgen/tool/wallet.py b/mmgen/tool/wallet.py index 240d0206..02902745 100755 --- a/mmgen/tool/wallet.py +++ b/mmgen/tool/wallet.py @@ -23,7 +23,6 @@ tool.wallet: Wallet routines for the 'mmgen-tool' utility from .common import tool_cmd_base from ..opts import opt -from ..fileutil import get_seed_file from ..subseed import SubSeedList from ..seedsplit import MasterShareIdx from ..wallet import Wallet @@ -36,25 +35,26 @@ class tool_cmd(tool_cmd_base): self.need_proto = True super().__init__(cmdname=cmdname,proto=proto,mmtype=mmtype) + def _get_seed_file(self,wallet): + from ..fileutil import get_seed_file + return get_seed_file([wallet] if wallet else [],1) + def get_subseed(self,subseed_idx:str,wallet=''): "get the Seed ID of a single subseed by Subseed Index for default or specified wallet" opt.quiet = True - sf = get_seed_file([wallet] if wallet else [],1) - return Wallet(sf).seed.subseed(subseed_idx).sid + return Wallet(self._get_seed_file(wallet)).seed.subseed(subseed_idx).sid def get_subseed_by_seed_id(self,seed_id:str,wallet='',last_idx=SubSeedList.dfl_len): "get the Subseed Index of a single subseed by Seed ID for default or specified wallet" opt.quiet = True - sf = get_seed_file([wallet] if wallet else [],1) - ret = Wallet(sf).seed.subseed_by_seed_id( seed_id, last_idx ) + ret = Wallet(self._get_seed_file(wallet)).seed.subseed_by_seed_id( seed_id, last_idx ) return ret.ss_idx if ret else None def list_subseeds(self,subseed_idx_range:str,wallet=''): "list a range of subseed Seed IDs for default or specified wallet" opt.quiet = True - sf = get_seed_file([wallet] if wallet else [],1) from ..subseed import SubSeedIdxRange - return Wallet(sf).seed.subseeds.format( *SubSeedIdxRange(subseed_idx_range) ) + return Wallet(self._get_seed_file(wallet)).seed.subseeds.format( *SubSeedIdxRange(subseed_idx_range) ) def list_shares(self, share_count: int, @@ -63,8 +63,7 @@ class tool_cmd(tool_cmd_base): wallet = '' ): "list the Seed IDs of the shares resulting from a split of default or specified wallet" opt.quiet = True - sf = get_seed_file([wallet] if wallet else [],1) - return Wallet(sf).seed.split( share_count, id_str, master_share ).format() + return Wallet(self._get_seed_file(wallet)).seed.split( share_count, id_str, master_share ).format() def gen_key(self,mmgen_addr:str,wallet=''): "generate a single WIF key for specified MMGen address from default or specified wallet" @@ -80,8 +79,7 @@ class tool_cmd(tool_cmd_base): addr = MMGenID( self.proto, mmgen_addr ) opt.quiet = True - sf = get_seed_file([wallet] if wallet else [],1) - ss = Wallet(sf) + ss = Wallet(self._get_seed_file(wallet)) if ss.seed.sid != addr.sid: from ..util import die diff --git a/test/test.py b/test/test.py index 37f2119e..b326da19 100755 --- a/test/test.py +++ b/test/test.py @@ -198,7 +198,7 @@ usr_args = parsed_opts.cmd_args if opt.pexpect_spawn and g.platform == 'win': die(1,'--pexpect-spawn option not supported on Windows platform, exiting') -if opt.daemon_id and opt.daemon_id in g.blacklist_daemons.split(): +if opt.daemon_id and opt.daemon_id in g.blacklisted_daemons.split(): die(1,f'test.py: daemon {opt.daemon_id!r} blacklisted, exiting') network_id = g.coin.lower() + ('_tn' if opt.testnet else '') @@ -907,6 +907,8 @@ class TestSuiteRunner(object): elif ret == 'ok': ok() self.cmd_total += 1 + elif ret == 'error': + die(2,red(f'\nTest {self.ts.test_name!r} failed')) elif ret in ('skip','silent'): pass elif type(ret) == tuple and ret[0] == 'skip_warn': diff --git a/test/test_py_d/ts_input.py b/test/test_py_d/ts_input.py index f5703650..fef8d024 100755 --- a/test/test_py_d/ts_input.py +++ b/test/test_py_d/ts_input.py @@ -98,13 +98,18 @@ class TestSuiteInput(TestSuiteBase): cmd = ['python3','cmds/mmgen-walletconv','--in-fmt=words','--out-fmt=bip39','--outdir=test/trash'] mn = sample_mn['mmgen']['mn'] os.environ['MMGEN_TEST_SUITE'] = '' - cp = run( cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE ) + + # the test can fail the first time if cfg file has changed, so run it twice if necessary: + for i in range(2): + cp = run( cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE ) + if b'written to file' in cp.stderr: + break + from mmgen.color import set_vt100 set_vt100() os.environ['MMGEN_TEST_SUITE'] = '1' - assert b'written to file' in cp.stderr, "test 'get_seed_from_stdin' failed" imsg(cp.stderr.decode().strip()) - return 'ok' + return 'ok' if b'written to file' in cp.stderr else 'error' def get_passphrase_ui(self): t = self.spawn('test/misc/get_passphrase.py',['--usr-randchars=0','seed'],cmd_dir='.') diff --git a/test/unit_tests_d/ut_lockable.py b/test/unit_tests_d/ut_lockable.py index 04a172ee..52f1afcf 100755 --- a/test/unit_tests_d/ut_lockable.py +++ b/test/unit_tests_d/ut_lockable.py @@ -81,7 +81,7 @@ class unit_test(object): lc.epsilon = [0] - class MyLockableClsCheck(Lockable): # class has attrs, like GlobalContext + class MyLockableClsCheck(Lockable): # class has attrs, like GlobalConfig _autolock = False _use_class_attr = True _set_ok = ('foo','baz')