From 523a8cc5c3c839530e3a822eecc0698817e6146b Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 19 Jan 2022 11:43:53 +0000 Subject: [PATCH] replace global variable 'subseeds' with SubSeedList.dfl_len --- mmgen/data/version | 2 +- mmgen/globalvars.py | 4 ++-- mmgen/help.py | 4 ++++ mmgen/main_txdo.py | 2 +- mmgen/main_txsign.py | 2 +- mmgen/opts.py | 6 ++++++ mmgen/seed.py | 8 ++++++-- mmgen/seedsplit.py | 3 +++ mmgen/subseed.py | 10 ++++++---- mmgen/tool.py | 3 ++- test/objtest_py_d/ot_btc_mainnet.py | 2 +- test/unit_tests_d/ut_subseed.py | 27 ++++++++++++++++++--------- 12 files changed, 51 insertions(+), 22 deletions(-) diff --git a/mmgen/data/version b/mmgen/data/version index 666e09b5..6c72c7e1 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -13.1.dev004 +13.1.dev005 diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index ac40de71..680eedb2 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -158,7 +158,7 @@ class GlobalContext(Lockable): 'minconf','usr_randchars','debug','quiet','tx_confs','tx_fee_adj' ) # user opt sets global var: - opt_sets_global = ( 'subseeds','cached_balances' ) + opt_sets_global = ( 'cached_balances', ) # 'long' opts - opt sets global var common_opts = ( @@ -249,6 +249,7 @@ class GlobalContext(Lockable): auto_typeset_opts = { 'seed_len': int, + 'subseeds': int, } min_screen_width = 80 @@ -262,7 +263,6 @@ class GlobalContext(Lockable): min_urandchars = 10 scramble_hash_rounds = 10 - subseeds = 100 salt_len = 16 aesctr_iv_len = 16 diff --git a/mmgen/help.py b/mmgen/help.py index adecf471..137840e8 100755 --- a/mmgen/help.py +++ b/mmgen/help.py @@ -39,6 +39,10 @@ def help_notes_func(proto,po,k): class help_notes: + def dfl_subseeds(): + from .subseed import SubSeedList + return str(SubSeedList.dfl_len) + def dfl_seed_len(): from .seed import Seed return str(Seed.dfl_len) diff --git a/mmgen/main_txdo.py b/mmgen/main_txdo.py index baa9498a..178674e7 100755 --- a/mmgen/main_txdo.py +++ b/mmgen/main_txdo.py @@ -100,7 +100,7 @@ FMT CODES: coin_id=help_notes('coin_id'), fu=help_notes('rel_fee_desc'), fl=help_notes('fee_spec_letters'), - ss=g.subseeds, + ss=help_notes('dfl_subseeds'), ss_max=SubSeedIdxRange.max_idx, fe_all=fmt_list(g.autoset_opts['fee_estimate_mode'].choices,fmt='no_spc'), fe_dfl=g.autoset_opts['fee_estimate_mode'].choices[0], diff --git a/mmgen/main_txsign.py b/mmgen/main_txsign.py index af6b2106..2a72242a 100755 --- a/mmgen/main_txsign.py +++ b/mmgen/main_txsign.py @@ -86,7 +86,7 @@ FMT CODES: kgs=help_notes('keygen_backends'), coin_id=help_notes('coin_id'), dsl=help_notes('dfl_seed_len'), - ss=g.subseeds, + ss=help_notes('dfl_subseeds'), ss_max=SubSeedIdxRange.max_idx, cu=proto.coin), 'notes': lambda help_notes,s: s.format( diff --git a/mmgen/opts.py b/mmgen/opts.py index 04a9ecc9..9322884b 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -509,6 +509,12 @@ def check_usr_opts(usr_opts): # Raises an exception if any check fails chk_hidden_incog_output_params = chk_hidden_incog_input_params + def chk_subseeds(key,val,desc): + from .subseed import SubSeedIdxRange + opt_is_int(val,desc) + opt_compares(int(val),'>=',SubSeedIdxRange.min_idx,desc) + opt_compares(int(val),'<=',SubSeedIdxRange.max_idx,desc) + def chk_seed_len(key,val,desc): from .seed import Seed opt_is_int(val,desc) diff --git a/mmgen/seed.py b/mmgen/seed.py index 279b8dad..513a9cf9 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -56,7 +56,7 @@ class SeedBase(MMGenObject): data = ImmutableAttr(bytes,typeconv=False) sid = ImmutableAttr(SeedID,typeconv=False) - def __init__(self,seed_bin=None): + def __init__(self,seed_bin=None,nSubseeds=None): if not seed_bin: from .opts import opt from .crypto import get_random @@ -68,6 +68,7 @@ class SeedBase(MMGenObject): self.data = seed_bin self.sid = SeedID(seed=self) + self.nSubseeds = nSubseeds # will override opt.subseeds @property def bitlen(self): @@ -91,7 +92,10 @@ class Seed(SeedBase): def subseeds(self): if not hasattr(self,'_subseeds'): from .subseed import SubSeedList - self._subseeds = SubSeedList(self) + from .opts import opt + self._subseeds = SubSeedList( + self, + length = self.nSubseeds or getattr(opt,'subseeds',None) ) return self._subseeds def subseed(self,*args,**kwargs): diff --git a/mmgen/seedsplit.py b/mmgen/seedsplit.py index 51c54c29..099f1c4b 100755 --- a/mmgen/seedsplit.py +++ b/mmgen/seedsplit.py @@ -20,6 +20,8 @@ seedsplit.py: Seed split classes and methods for the MMGen suite """ +from .globalvars import g +from .color import yellow from .exception import RangeError from .obj import MMGenPWIDString,MMGenIdx from .subseed import * @@ -69,6 +71,7 @@ class SeedShareList(SubSeedList): self.parent_seed = parent_seed self.id_str = id_str or 'default' self.count = count + self.len = 2 # placeholder, always overridden def make_master_share(): for nonce in range(SeedShare.max_nonce+1): diff --git a/mmgen/subseed.py b/mmgen/subseed.py index f53304c3..82a899a1 100755 --- a/mmgen/subseed.py +++ b/mmgen/subseed.py @@ -20,7 +20,6 @@ subseed.py: Subseed classes and methods for the MMGen suite """ -from .common import * from .color import green from .util import msg_r,msg,qmsg from .exception import SubSeedNonceRangeExceeded @@ -81,11 +80,13 @@ class SubSeedList(MMGenObject): have_short = True nonce_start = 0 debug_last_share_sid_len = 3 + dfl_len = 100 - def __init__(self,parent_seed): + def __init__(self,parent_seed,length=None): self.member_type = SubSeed self.parent_seed = parent_seed self.data = { 'long': IndexedDict(), 'short': IndexedDict() } + self.len = length or self.dfl_len def __len__(self): return len(self.data['long']) @@ -135,7 +136,7 @@ class SubSeedList(MMGenObject): )) if last_idx == None: - last_idx = g.subseeds + last_idx = self.len subseed = get_existing_subseed_by_seed_id(sid) if subseed: @@ -170,7 +171,7 @@ class SubSeedList(MMGenObject): def _generate(self,last_idx=None,last_sid=None): if last_idx == None: - last_idx = g.subseeds + last_idx = self.len first_idx = len(self) + 1 @@ -184,6 +185,7 @@ class SubSeedList(MMGenObject): for nonce in range(self.nonce_start,self.member_type.max_nonce+1): # handle SeedID collisions sid = make_chksum_8(self.member_type.make_subseed_bin(self,idx,nonce,length)) if sid in self.data['long'] or sid in self.data['short'] or sid == self.parent_seed.sid: + from .globalvars import g if g.debug_subseed: # should get ≈450 collisions for first 1,000,000 subseeds self._collision_debug_msg(sid,idx,nonce) else: diff --git a/mmgen/tool.py b/mmgen/tool.py index a8a651e3..d8062895 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -24,6 +24,7 @@ from .protocol import hash160 from .common import * from .crypto import get_random from .key import PrivKey +from .subseed import SubSeedList from .seedsplit import MasterShareIdx from .addr import * from .addrlist import AddrList,KeyAddrList @@ -851,7 +852,7 @@ class MMGenToolCmdWallet(MMGenToolCmds): from .wallet import Wallet return Wallet(sf).seed.subseed(subseed_idx).sid - def get_subseed_by_seed_id(self,seed_id:str,wallet='',last_idx=g.subseeds): + 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) diff --git a/test/objtest_py_d/ot_btc_mainnet.py b/test/objtest_py_d/ot_btc_mainnet.py index 4e8c9dc1..0b77c1d4 100755 --- a/test/objtest_py_d/ot_btc_mainnet.py +++ b/test/objtest_py_d/ot_btc_mainnet.py @@ -67,7 +67,7 @@ tests = { ('3',(3,3)), ((3,5),(3,5)), ('1-2',(1,2)), - (str(g.subseeds),(g.subseeds,g.subseeds)), + (str(SubSeedList.dfl_len),(SubSeedList.dfl_len,SubSeedList.dfl_len)), (str(SubSeedIdxRange.max_idx),(SubSeedIdxRange.max_idx,SubSeedIdxRange.max_idx)), ) }, diff --git a/test/unit_tests_d/ut_subseed.py b/test/unit_tests_d/ut_subseed.py index af8b88ba..3f787cfc 100755 --- a/test/unit_tests_d/ut_subseed.py +++ b/test/unit_tests_d/ut_subseed.py @@ -9,7 +9,9 @@ class unit_test(object): def run_test(self,name,ut): from mmgen.seed import Seed - from mmgen.subseed import SubSeedIdxRange + from mmgen.subseed import SubSeedList,SubSeedIdxRange + + nSubseeds = SubSeedList.dfl_len def basic_ops(): msg_r('Testing basic ops...') @@ -55,9 +57,9 @@ class unit_test(object): assert seed.pfmt() == seed2.pfmt() - s = seed.subseeds.format(1,g.subseeds) + s = seed.subseeds.format(1,nSubseeds) s_lines = s.strip().split('\n') - assert len(s_lines) == g.subseeds + 4, s + assert len(s_lines) == nSubseeds + 4, s a = seed.subseed('2L').sid b = [e for e in s_lines if ' 2L:' in e][0].strip().split()[1] @@ -70,11 +72,11 @@ class unit_test(object): b = [e for e in s_lines if ' 5S:' in e][0].strip().split()[3] assert a == b, b - s = seed.subseeds.format(g.subseeds+1,g.subseeds+2) + s = seed.subseeds.format(nSubseeds+1,nSubseeds+2) s_lines = s.strip().split('\n') assert len(s_lines) == 6, s - ss_idx = str(g.subseeds+2) + 'S' + ss_idx = str(nSubseeds+2) + 'S' a = seed.subseed(ss_idx).sid b = [e for e in s_lines if f' {ss_idx}:' in e][0].strip().split()[3] assert a == b, b @@ -91,17 +93,24 @@ class unit_test(object): msg_r('Testing defaults and limits...') seed_bin = bytes.fromhex('deadbeef' * 8) + + seed = Seed(seed_bin,nSubseeds=11) + seed.subseeds._generate() + ss = seed.subseeds + assert len(ss.data['long']) == len(ss.data['short']), len(ss.data['short']) + assert len(ss) == 11, len(ss) + seed = Seed(seed_bin) seed.subseeds._generate() ss = seed.subseeds assert len(ss.data['long']) == len(ss.data['short']), len(ss.data['short']) - assert len(ss) == g.subseeds, len(ss) + assert len(ss) == nSubseeds, len(ss) seed = Seed(seed_bin) seed.subseed_by_seed_id('EEEEEEEE') ss = seed.subseeds assert len(ss.data['long']) == len(ss.data['short']), len(ss.data['short']) - assert len(ss) == g.subseeds, len(ss) + assert len(ss) == nSubseeds, len(ss) seed = Seed(seed_bin) subseed = seed.subseed_by_seed_id('803B165C') @@ -135,8 +144,8 @@ class unit_test(object): r = SubSeedIdxRange('3-3') assert r.items == [3], r.items - r = SubSeedIdxRange(f'{g.subseeds-1}-{g.subseeds}') - assert r.items == [g.subseeds-1,g.subseeds], r.items + r = SubSeedIdxRange(f'{nSubseeds-1}-{nSubseeds}') + assert r.items == [nSubseeds-1,nSubseeds], r.items for n,e in enumerate(SubSeedIdxRange('1-5').iterate(),1): assert n == e, e