From 508abfb350c5df4058fd0e4b484a3d75bbd08463 Mon Sep 17 00:00:00 2001 From: MMGen Date: Thu, 17 Oct 2019 11:30:29 +0000 Subject: [PATCH] MMGenAddrType.mmtypes: implement values as namedtuples --- mmgen/main_addrgen.py | 4 +- mmgen/obj.py | 95 ++++++++++++------------------------ test/test_py_d/ts_regtest.py | 4 +- 3 files changed, 35 insertions(+), 68 deletions(-) diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 5543563d..4261f088 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -104,7 +104,7 @@ FMT CODES: 'code': { 'options': lambda s: s.format( seed_lens=', '.join(map(str,g.seed_lens)), - dmat="'{}' or '{}'".format(g.proto.dfl_mmtype,MMGenAddrType.mmtypes[g.proto.dfl_mmtype]['name']), + dmat="'{}' or '{}'".format(g.proto.dfl_mmtype,MMGenAddrType.mmtypes[g.proto.dfl_mmtype].name), kgs=' '.join(['{}:{}'.format(n,k) for n,k in enumerate(g.key_generators,1)]), kg=g.key_generator, pnm=g.proj_name, @@ -118,7 +118,7 @@ FMT CODES: n_bw=help_notes('brainwallet'), n_fmt='\n '.join(SeedSource.format_fmt_codes().splitlines()), n_at='\n '.join(["'{}','{:<12} - {}".format( - k,v['name']+"'",v['desc']) for k,v in list(MMGenAddrType.mmtypes.items())]) + k,v.name+"'",v.desc) for k,v in MMGenAddrType.mmtypes.items()]) ) } } diff --git a/mmgen/obj.py b/mmgen/obj.py index 343dea0e..86510f9b 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -844,58 +844,32 @@ class SeedSplitSpecifier(str,Hilite,InitErrors,MMGenObject): class SeedSplitIDString(MMGenPWIDString): desc = 'seed split ID string' +from collections import namedtuple +ati = namedtuple('addrtype_info', + ['name','pubkey_type','compressed','gen_method','addr_fmt','wif_label','extra_attrs','desc']) + class MMGenAddrType(str,Hilite,InitErrors,MMGenObject): width = 1 trunc_ok = False color = 'blue' - mmtypes = { # 'name' is used to cook the seed, so it must never change! - 'L': { 'name':'legacy', - 'pubkey_type':'std', - 'compressed':False, - 'gen_method':'p2pkh', - 'addr_fmt':'p2pkh', - 'desc':'Legacy uncompressed address'}, - 'C': { 'name':'compressed', - 'pubkey_type':'std', - 'compressed':True, - 'gen_method':'p2pkh', - 'addr_fmt':'p2pkh', - 'desc':'Compressed P2PKH address'}, - 'S': { 'name':'segwit', - 'pubkey_type':'std', - 'compressed':True, - 'gen_method':'segwit', - 'addr_fmt':'p2sh', - 'desc':'Segwit P2SH-P2WPKH address' }, - 'B': { 'name':'bech32', - 'pubkey_type':'std', - 'compressed':True, - 'gen_method':'bech32', - 'addr_fmt':'bech32', - 'desc':'Native Segwit (Bech32) address' }, - 'E': { 'name':'ethereum', - 'pubkey_type':'std', - 'compressed':False, - 'gen_method':'ethereum', - 'addr_fmt':'ethereum', - 'wif_label':'privkey', - 'extra_attrs': ('wallet_passwd',), - 'desc':'Ethereum address' }, - 'Z': { 'name':'zcash_z', - 'pubkey_type':'zcash_z', - 'compressed':False, - 'gen_method':'zcash_z', - 'addr_fmt':'zcash_z', - 'extra_attrs': ('viewkey',), - 'desc':'Zcash z-address' }, - 'M': { 'name':'monero', - 'pubkey_type':'monero', - 'compressed':False, - 'gen_method':'monero', - 'addr_fmt':'monero', - 'wif_label':'spendkey', - 'extra_attrs': ('viewkey','wallet_passwd'), - 'desc':'Monero address'} + + name = MMGenImmutableAttr('name',str) + pubkey_type = MMGenImmutableAttr('pubkey_type',str) + compressed = MMGenImmutableAttr('compressed',bool) + gen_method = MMGenImmutableAttr('gen_method',str) + addr_fmt = MMGenImmutableAttr('addr_fmt',str) + wif_label = MMGenImmutableAttr('wif_label',str) + extra_attrs = MMGenImmutableAttr('extra_attrs',tuple) + desc = MMGenImmutableAttr('desc',str) + + mmtypes = { + 'L': ati('legacy', 'std', False,'p2pkh', 'p2pkh', 'wif', (), 'Legacy uncompressed address'), + 'C': ati('compressed','std', True, 'p2pkh', 'p2pkh', 'wif', (), 'Compressed P2PKH address'), + 'S': ati('segwit', 'std', True, 'segwit', 'p2sh', 'wif', (), 'Segwit P2SH-P2WPKH address'), + 'B': ati('bech32', 'std', True, 'bech32', 'bech32', 'wif', (), 'Native Segwit (Bech32) address'), + 'E': ati('ethereum', 'std', False,'ethereum','ethereum','privkey', ('wallet_passwd',),'Ethereum address'), + 'Z': ati('zcash_z','zcash_z',False,'zcash_z', 'zcash_z', 'wif', ('viewkey',), 'Zcash z-address'), + 'M': ati('monero', 'monero', False,'monero', 'monero', 'spendkey',('viewkey','wallet_passwd'),'Monero address'), } def __new__(cls,s,on_fail='die',errmsg=None): if type(s) == cls: return s @@ -903,32 +877,25 @@ class MMGenAddrType(str,Hilite,InitErrors,MMGenObject): from mmgen.globalvars import g try: for k,v in list(cls.mmtypes.items()): - if s in (k,v['name']): - if s == v['name']: s = k + if s in (k,v.name): + if s == v.name: s = k me = str.__new__(cls,s) - for k in ('name','pubkey_type','compressed','gen_method','addr_fmt','desc'): - setattr(me,k,v[k]) + for k in v._fields: + setattr(me,k,getattr(v,k)) assert me in g.proto.mmtypes + ('P',), ( "'{}': invalid address type for {}".format(me.name,g.proto.__name__)) - me.extra_attrs = v['extra_attrs'] if 'extra_attrs' in v else () - me.wif_label = v['wif_label'] if 'wif_label' in v else 'wif' return me - raise ValueError('not found') + raise ValueError('unrecognized address type') except Exception as e: - m = '{}{!r}: invalid value for {} ({})'.format( - ('{!r}\n'.format(errmsg) if errmsg else ''),s,cls.__name__,e.args[0]) + emsg = '{!r}\n'.format(errmsg) if errmsg else '' + m = '{}{!r}: invalid value for {} ({})'.format(emsg,s,cls.__name__,e.args[0]) return cls.init_fail(e,m,preformat=True) @classmethod def get_names(cls): - return [v['name'] for v in cls.mmtypes.values()] + return [v.name for v in cls.mmtypes.values()] class MMGenPasswordType(MMGenAddrType): mmtypes = { - 'P': { 'name':'password', - 'pubkey_type':'password', - 'compressed':False, - 'gen_method':None, - 'addr_fmt':None, - 'desc':'Password generated from MMGen seed'} + 'P': ati('password', 'password', False, None, None, None, (), 'Password generated from MMGen seed') } diff --git a/test/test_py_d/ts_regtest.py b/test/test_py_d/ts_regtest.py index 93243575..89f3ae58 100755 --- a/test/test_py_d/ts_regtest.py +++ b/test/test_py_d/ts_regtest.py @@ -297,7 +297,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): ([wf] if wf else []) + (['--subwallet='+subseed_idx] if subseed_idx else []) + [addr_range], - extra_desc='({})'.format(MMGenAddrType.mmtypes[mmtype]['name'])) + extra_desc='({})'.format(MMGenAddrType.mmtypes[mmtype].name)) t.passphrase('MMGen wallet',rt_pw) t.written_to_file('Addresses') ok_msg() @@ -312,7 +312,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): if not sid: sid = self._user_sid(user) from mmgen.addr import MMGenAddrType for mmtype in mmtypes or g.proto.mmtypes: - desc = MMGenAddrType.mmtypes[mmtype]['name'] + desc = MMGenAddrType.mmtypes[mmtype].name addrfile = joinpath(self._user_dir(user), '{}{}{}[{}]{x}.testnet.addrs'.format( sid,self.altcoin_pfx,id_strs[desc],addr_range,