From 9bc284ae242f96ea0b88f2ca4061397fa6332878 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Fri, 18 Oct 2024 10:32:14 +0000 Subject: [PATCH] whitespace: cmdtest_d --- test/cmdtest_py_d/cfg.py | 369 +++++----- test/cmdtest_py_d/common.py | 69 +- test/cmdtest_py_d/ct_autosign.py | 244 +++---- test/cmdtest_py_d/ct_base.py | 36 +- test/cmdtest_py_d/ct_cfgfile.py | 126 ++-- test/cmdtest_py_d/ct_chainsplit.py | 96 +-- test/cmdtest_py_d/ct_ethdev.py | 708 +++++++++---------- test/cmdtest_py_d/ct_help.py | 64 +- test/cmdtest_py_d/ct_input.py | 210 +++--- test/cmdtest_py_d/ct_main.py | 919 ++++++++++++++----------- test/cmdtest_py_d/ct_misc.py | 119 ++-- test/cmdtest_py_d/ct_opts.py | 174 ++--- test/cmdtest_py_d/ct_ref.py | 251 +++---- test/cmdtest_py_d/ct_ref_3seed.py | 238 +++---- test/cmdtest_py_d/ct_ref_altcoin.py | 172 ++--- test/cmdtest_py_d/ct_regtest.py | 974 ++++++++++++++------------- test/cmdtest_py_d/ct_seedsplit.py | 198 +++--- test/cmdtest_py_d/ct_shared.py | 112 +-- test/cmdtest_py_d/ct_tool.py | 88 ++- test/cmdtest_py_d/ct_wallet.py | 190 +++--- test/cmdtest_py_d/ct_xmr_autosign.py | 84 +-- test/cmdtest_py_d/ct_xmrwallet.py | 333 +++++---- test/cmdtest_py_d/input.py | 24 +- 23 files changed, 2981 insertions(+), 2817 deletions(-) diff --git a/test/cmdtest_py_d/cfg.py b/test/cmdtest_py_d/cfg.py index b4433625..9526b2a4 100755 --- a/test/cmdtest_py_d/cfg.py +++ b/test/cmdtest_py_d/cfg.py @@ -12,203 +12,217 @@ test.cmdtest_py_d.cfg: configuration data for cmdtest.py """ -from .common import pwfile,hincog_fn,incog_id_fn,randbool +from .common import pwfile, hincog_fn, incog_id_fn, randbool from ..include.common import cfg -cmd_groups_altcoin = ['ref_altcoin','autosign','ethdev','xmrwallet','xmr_autosign'] +cmd_groups_altcoin = ['ref_altcoin', 'autosign', 'ethdev', 'xmrwallet', 'xmr_autosign'] cmd_groups_dfl = { - 'misc': ('CmdTestMisc',{}), - 'opts': ('CmdTestOpts',{'full_data':True}), - 'cfgfile': ('CmdTestCfgFile',{'full_data':True}), - 'help': ('CmdTestHelp',{'full_data':True}), - 'main': ('CmdTestMain',{'full_data':True}), - 'conv': ('CmdTestWalletConv',{'is3seed':True,'modname':'wallet'}), - 'ref': ('CmdTestRef',{}), - 'ref3': ('CmdTestRef3Seed',{'is3seed':True,'modname':'ref_3seed'}), - 'ref3_addr': ('CmdTestRef3Addr',{'is3seed':True,'modname':'ref_3seed'}), - 'ref3_pw': ('CmdTestRef3Passwd',{'is3seed':True,'modname':'ref_3seed'}), - 'ref_altcoin': ('CmdTestRefAltcoin',{}), - 'seedsplit': ('CmdTestSeedSplit',{}), - 'tool': ('CmdTestTool',{'full_data':True}), - 'input': ('CmdTestInput',{}), - 'output': ('CmdTestOutput',{'modname':'misc','full_data':True}), - 'autosign_clean': ('CmdTestAutosignClean', {'modname':'autosign'}), - 'autosign': ('CmdTestAutosign',{}), - 'autosign_automount': ('CmdTestAutosignAutomount', {'modname':'automount'}), - 'autosign_eth': ('CmdTestAutosignETH', {'modname':'automount_eth'}), - 'regtest': ('CmdTestRegtest',{}), -# 'chainsplit': ('CmdTestChainsplit',{}), - 'ethdev': ('CmdTestEthdev',{}), - 'xmrwallet': ('CmdTestXMRWallet',{}), - 'xmr_autosign': ('CmdTestXMRAutosign',{}), + 'misc': ('CmdTestMisc', {}), + 'opts': ('CmdTestOpts', {'full_data': True}), + 'cfgfile': ('CmdTestCfgFile', {'full_data': True}), + 'help': ('CmdTestHelp', {'full_data': True}), + 'main': ('CmdTestMain', {'full_data': True}), + 'conv': ('CmdTestWalletConv', {'is3seed': True, 'modname': 'wallet'}), + 'ref': ('CmdTestRef', {}), + 'ref3': ('CmdTestRef3Seed', {'is3seed': True, 'modname': 'ref_3seed'}), + 'ref3_addr': ('CmdTestRef3Addr', {'is3seed': True, 'modname': 'ref_3seed'}), + 'ref3_pw': ('CmdTestRef3Passwd', {'is3seed': True, 'modname': 'ref_3seed'}), + 'ref_altcoin': ('CmdTestRefAltcoin', {}), + 'seedsplit': ('CmdTestSeedSplit', {}), + 'tool': ('CmdTestTool', {'full_data': True}), + 'input': ('CmdTestInput', {}), + 'output': ('CmdTestOutput', {'modname': 'misc', 'full_data': True}), + 'autosign_clean': ('CmdTestAutosignClean', {'modname': 'autosign'}), + 'autosign': ('CmdTestAutosign', {}), + 'autosign_automount': ('CmdTestAutosignAutomount', {'modname': 'automount'}), + 'autosign_eth': ('CmdTestAutosignETH', {'modname': 'automount_eth'}), + 'regtest': ('CmdTestRegtest', {}), + # 'chainsplit': ('CmdTestChainsplit', {}), + 'ethdev': ('CmdTestEthdev', {}), + 'xmrwallet': ('CmdTestXMRWallet', {}), + 'xmr_autosign': ('CmdTestXMRAutosign', {}), } cmd_groups_extra = { - 'dev': ('CmdTestDev',{'modname':'misc'}), - 'regtest_legacy': ('CmdTestRegtestBDBWallet', {'modname':'regtest'}), - 'autosign_btc': ('CmdTestAutosignBTC',{'modname':'autosign'}), - 'autosign_live': ('CmdTestAutosignLive',{'modname':'autosign'}), - 'autosign_live_simulate': ('CmdTestAutosignLiveSimulate',{'modname':'autosign'}), - 'create_ref_tx': ('CmdTestRefTX',{'modname':'misc','full_data':True}), + 'dev': ('CmdTestDev', {'modname': 'misc'}), + 'regtest_legacy': ('CmdTestRegtestBDBWallet', {'modname': 'regtest'}), + 'autosign_btc': ('CmdTestAutosignBTC', {'modname': 'autosign'}), + 'autosign_live': ('CmdTestAutosignLive', {'modname': 'autosign'}), + 'autosign_live_simulate': ('CmdTestAutosignLiveSimulate', {'modname': 'autosign'}), + 'create_ref_tx': ('CmdTestRefTX', {'modname': 'misc', 'full_data': True}), } -cfgs = { # addr_idx_lists (except 31,32,33,34) must contain exactly 8 addresses - '1': { 'wpasswd': 'Dorian-α', - 'kapasswd': 'Grok the blockchain', - 'addr_idx_list': '12,99,5-10,5,12', - 'dep_generators': { - pwfile: 'walletgen', - 'mmdat': 'walletgen', - 'addrs': 'addrgen', - 'rawtx': 'txcreate', - 'txbump': 'txbump', - 'sigtx': 'txsign', - 'mmwords': 'export_mnemonic', - 'mmseed': 'export_seed', - 'mmhex': 'export_hex', - 'mmincog': 'export_incog', - 'mmincox': 'export_incog_hex', - hincog_fn: 'export_incog_hidden', - incog_id_fn: 'export_incog_hidden', - 'akeys.mmenc': 'keyaddrgen' - }, +cfgs = { # addr_idx_lists (except 31, 32, 33, 34) must contain exactly 8 addresses + '1': { + 'wpasswd': 'Dorian-α', + 'kapasswd': 'Grok the blockchain', + 'addr_idx_list': '12,99,5-10,5,12', + 'dep_generators': { + pwfile: 'walletgen', + 'mmdat': 'walletgen', + 'addrs': 'addrgen', + 'rawtx': 'txcreate', + 'txbump': 'txbump', + 'sigtx': 'txsign', + 'mmwords': 'export_mnemonic', + 'mmseed': 'export_seed', + 'mmhex': 'export_hex', + 'mmincog': 'export_incog', + 'mmincox': 'export_incog_hex', + hincog_fn: 'export_incog_hidden', + incog_id_fn: 'export_incog_hidden', + 'akeys.mmenc': 'keyaddrgen' + }, }, - '2': { 'wpasswd': 'Hodling away', - 'addr_idx_list': '37,45,3-6,22-23', - 'seed_len': 128, - 'dep_generators': { - 'mmdat': 'walletgen2', - 'addrs': 'addrgen2', - 'rawtx': 'txcreate2', - 'sigtx': 'txsign2', - 'mmwords': 'export_mnemonic2', - }, + '2': { + 'wpasswd': 'Hodling away', + 'addr_idx_list': '37,45,3-6,22-23', + 'seed_len': 128, + 'dep_generators': { + 'mmdat': 'walletgen2', + 'addrs': 'addrgen2', + 'rawtx': 'txcreate2', + 'sigtx': 'txsign2', + 'mmwords': 'export_mnemonic2', + }, }, - '3': { 'wpasswd': 'Major miner', - 'addr_idx_list': '73,54,1022-1023,2-5', - 'dep_generators': { - 'mmdat': 'walletgen3', - 'addrs': 'addrgen3', - 'rawtx': 'txcreate3', - 'sigtx': 'txsign3' - }, + '3': { + 'wpasswd': 'Major miner', + 'addr_idx_list': '73,54,1022-1023,2-5', + 'dep_generators': { + 'mmdat': 'walletgen3', + 'addrs': 'addrgen3', + 'rawtx': 'txcreate3', + 'sigtx': 'txsign3' + }, }, - '4': { 'wpasswd': 'Hashrate good', - 'addr_idx_list': '63,1004,542-544,7-9', - 'seed_len': 192, - 'dep_generators': { - 'mmdat': 'walletgen4', - 'mmbrain': 'walletgen4', - 'addrs': 'addrgen4', - 'rawtx': 'txcreate4', - 'sigtx': 'txsign4', - 'txdo': 'txdo4', - }, - 'bw_filename': 'brainwallet.mmbrain', - 'bw_params': '192,1', + '4': { + 'wpasswd': 'Hashrate good', + 'addr_idx_list': '63,1004,542-544,7-9', + 'seed_len': 192, + 'dep_generators': { + 'mmdat': 'walletgen4', + 'mmbrain': 'walletgen4', + 'addrs': 'addrgen4', + 'rawtx': 'txcreate4', + 'sigtx': 'txsign4', + 'txdo': 'txdo4', + }, + 'bw_filename': 'brainwallet.mmbrain', + 'bw_params': '192,1', }, - '5': { 'wpasswd': 'My changed password-α', - 'hash_preset': '2', - 'dep_generators': { - 'mmdat': 'passchg', - pwfile: 'passchg', - }, + '5': { + 'wpasswd': 'My changed password-α', + 'hash_preset': '2', + 'dep_generators': { + 'mmdat': 'passchg', + pwfile: 'passchg', + }, }, - '6': { 'seed_len': 128, - 'seed_id': 'FE3C6545', - 'ref_bw_seed_id': '33F10310', - 'wpasswd': 'reference password', - 'kapasswd': '', - 'dep_generators': { - 'mmdat': 'ref_walletgen_brain_1', - pwfile: 'ref_walletgen_brain_1', - 'addrs': 'refaddrgen_1', - 'akeys.mmenc': 'refkeyaddrgen_1' - }, + '6': { + 'seed_len': 128, + 'seed_id': 'FE3C6545', + 'ref_bw_seed_id': '33F10310', + 'wpasswd': 'reference password', + 'kapasswd': '', + 'dep_generators': { + 'mmdat': 'ref_walletgen_brain_1', + pwfile: 'ref_walletgen_brain_1', + 'addrs': 'refaddrgen_1', + 'akeys.mmenc': 'refkeyaddrgen_1' + }, }, - '7': { 'seed_len': 192, - 'seed_id': '1378FC64', - 'ref_bw_seed_id': 'CE918388', - 'wpasswd': 'reference password', - 'kapasswd': '', - 'dep_generators': { - 'mmdat': 'ref_walletgen_brain_2', - pwfile: 'ref_walletgen_brain_2', - 'addrs': 'refaddrgen_2', - 'akeys.mmenc': 'refkeyaddrgen_2' - }, + '7': { + 'seed_len': 192, + 'seed_id': '1378FC64', + 'ref_bw_seed_id': 'CE918388', + 'wpasswd': 'reference password', + 'kapasswd': '', + 'dep_generators': { + 'mmdat': 'ref_walletgen_brain_2', + pwfile: 'ref_walletgen_brain_2', + 'addrs': 'refaddrgen_2', + 'akeys.mmenc': 'refkeyaddrgen_2' + }, }, - '8': { 'seed_len': 256, - 'seed_id': '98831F3A', - 'ref_bw_seed_id': 'B48CD7FC', - 'wpasswd': 'reference password', - 'kapasswd': '', - 'dep_generators': { - 'mmdat': 'ref_walletgen_brain_3', - pwfile: 'ref_walletgen_brain_3', - 'addrs': 'refaddrgen_3', - 'akeys.mmenc': 'refkeyaddrgen_3' - }, + '8': { + 'seed_len': 256, + 'seed_id': '98831F3A', + 'ref_bw_seed_id': 'B48CD7FC', + 'wpasswd': 'reference password', + 'kapasswd': '', + 'dep_generators': { + 'mmdat': 'ref_walletgen_brain_3', + pwfile: 'ref_walletgen_brain_3', + 'addrs': 'refaddrgen_3', + 'akeys.mmenc': 'refkeyaddrgen_3' + }, }, - '9': { 'tool_enc_infn': 'tool_encrypt.in', - 'dep_generators': { - 'tool_encrypt.in': 'tool_encrypt', - 'tool_encrypt.in.mmenc': 'tool_encrypt', - }, + '9': { + 'tool_enc_infn': 'tool_encrypt.in', + 'dep_generators': { + 'tool_encrypt.in': 'tool_encrypt', + 'tool_encrypt.in.mmenc': 'tool_encrypt', + }, }, '11': {}, # wallet '12': {}, # wallet '13': {}, # wallet - '14': { 'kapasswd': 'Maxwell', - 'wpasswd': 'The Halving', - 'addr_idx_list': '61,998,502-504,7-9', - 'seed_len': 256, - 'dep_generators': { - 'mmdat': 'walletgen14', - 'addrs': 'addrgen14', - 'akeys.mmenc': 'keyaddrgen14', - }, + '14': { + 'kapasswd': 'Maxwell', + 'wpasswd': 'The Halving', + 'addr_idx_list': '61,998,502-504,7-9', + 'seed_len': 256, + 'dep_generators': { + 'mmdat': 'walletgen14', + 'addrs': 'addrgen14', + 'akeys.mmenc': 'keyaddrgen14', + }, }, - '15': { 'wpasswd': 'Dorian-α', - 'kapasswd': 'Grok the blockchain', - 'addr_idx_list': '12,99,5-10,5,12', - 'dep_generators': { - pwfile: 'walletgen_dfl_wallet', - 'addrs': 'addrgen_dfl_wallet', - 'rawtx': 'txcreate_dfl_wallet', - 'sigtx': 'txsign_dfl_wallet', - 'mmseed': 'export_seed_dfl_wallet', - 'del_dw_run': 'delete_dfl_wallet', - }, + '15': { + 'wpasswd': 'Dorian-α', + 'kapasswd': 'Grok the blockchain', + 'addr_idx_list': '12,99,5-10,5,12', + 'dep_generators': { + pwfile: 'walletgen_dfl_wallet', + 'addrs': 'addrgen_dfl_wallet', + 'rawtx': 'txcreate_dfl_wallet', + 'sigtx': 'txsign_dfl_wallet', + 'mmseed': 'export_seed_dfl_wallet', + 'del_dw_run': 'delete_dfl_wallet', + }, }, - '16': { 'wpasswd': 'My changed password', - 'hash_preset': '2', - 'dep_generators': { - pwfile: 'passchg_dfl_wallet', - }, + '16': { + 'wpasswd': 'My changed password', + 'hash_preset': '2', + 'dep_generators': { + pwfile: 'passchg_dfl_wallet', + }, }, '17': {}, # regtest '18': {}, # autosign - '19': { 'wpasswd':'abc' }, - '20': { 'wpasswd': 'Vsize it', - 'addr_idx_list': '1-8', - 'seed_len': 256, - 'dep_generators': { - 'mmdat': 'walletgen5', - 'addrs': 'addrgen5', - 'rawtx': 'txcreate5', - 'sigtx': 'txsign5', + '19': {'wpasswd': 'abc'}, + '20': { + 'wpasswd': 'Vsize it', + 'addr_idx_list': '1-8', + 'seed_len': 256, + 'dep_generators': { + 'mmdat': 'walletgen5', + 'addrs': 'addrgen5', + 'rawtx': 'txcreate5', + 'sigtx': 'txsign5', }, }, - '21': { 'wpasswd': 'Vsize it', - 'addr_idx_list': '1-8', - 'seed_len': 256, - 'dep_generators': { - 'mmdat': 'walletgen6', - 'addrs': 'addrgen6', - 'rawtx': 'txcreate6', - 'sigtx': 'txsign6', + '21': { + 'wpasswd': 'Vsize it', + 'addr_idx_list': '1-8', + 'seed_len': 256, + 'dep_generators': { + 'mmdat': 'walletgen6', + 'addrs': 'addrgen6', + 'rawtx': 'txcreate6', + 'sigtx': 'txsign6', }, }, '22': {}, # ethdev @@ -236,16 +250,15 @@ def fixup_cfgs(): for k in cfgs: cfgs[k]['tmpdir'] = os.path.join('test', 'tmp', str(k)) - for src,target in ( - ('6','11'), - ('7','12'), - ('8','13'), - ('6','26'), - ('7','27'), - ('8','28') - ): + for src, target in ( + ('6', '11'), + ('7', '12'), + ('8', '13'), + ('6', '26'), + ('7', '27'), + ('8', '28')): cfgs[target].update(cfgs[src]) - cfgs[target]['tmpdir'] = os.path.join('test','tmp',target) + cfgs[target]['tmpdir'] = os.path.join('test', 'tmp', target) for k in cfgs: cfgs[k]['segwit'] = randbool() if cfg.segwit_random else bool(cfg.segwit or cfg.bech32) diff --git a/test/cmdtest_py_d/common.py b/test/cmdtest_py_d/common.py index 79a41736..74cded17 100755 --- a/test/cmdtest_py_d/common.py +++ b/test/cmdtest_py_d/common.py @@ -20,12 +20,12 @@ test.cmdtest_py_d.common: Shared routines and data for the cmdtest.py test suite """ -import sys,os +import sys, os from mmgen.color import green, blue, gray from mmgen.util import msg -from ..include.common import cfg,getrand,text_jp,text_zh,ascii_cyr_gr,lat_cyr_gr +from ..include.common import cfg, getrand, text_jp, text_zh, ascii_cyr_gr, lat_cyr_gr rt_pw = 'abc-α' ref_wallet_brainpass = 'abc' @@ -45,11 +45,11 @@ hincog_seedlen = 256 incog_id_fn = 'incog_id' non_mmgen_fn = 'coinkey' -ref_dir = os.path.join('test','ref') -dfl_words_file = os.path.join(ref_dir,'98831F3A.mmwords') -dfl_bip39_file = os.path.join(ref_dir,'98831F3A.bip39') +ref_dir = os.path.join('test', 'ref') +dfl_words_file = os.path.join(ref_dir, '98831F3A.mmwords') +dfl_bip39_file = os.path.join(ref_dir, '98831F3A.bip39') -from mmgen.obj import MMGenTxComment,TwComment +from mmgen.obj import MMGenTxComment, TwComment tx_comment_jp = text_jp tx_comment_zh = text_zh @@ -75,8 +75,8 @@ def ok_msg(): return sys.stderr.write(green('\nOK\n') if cfg.exact_output or cfg.verbose else ' OK\n') -def skip(name,reason=None): - msg(gray('Skipping {}{}'.format( name, f' ({reason})' if reason else '' ))) +def skip(name, reason=None): + msg(gray('Skipping {}{}'.format(name, f' ({reason})' if reason else ''))) return 'skip' def confirm_continue(): @@ -85,7 +85,7 @@ def confirm_continue(): cfg, blue('Continue? (Y/n): '), default_yes = True, - complete_prompt = True ): + complete_prompt = True): if cfg.verbose or cfg.exact_output: sys.stderr.write('\n') else: @@ -101,18 +101,25 @@ def get_env_without_debug_vars(): del ret[k] return ret -def get_file_with_ext(tdir,ext,delete=True,no_dot=False,return_list=False,delete_all=False,substr=False): +def get_file_with_ext( + tdir, + ext, + delete = True, + no_dot = False, + return_list = False, + delete_all = False, + substr = False): dot = '' if no_dot else '.' def have_match(fn): return ( fn == ext - or fn.endswith( dot + ext ) - or (substr and ext in fn) ) + or fn.endswith(dot + ext) + or (substr and ext in fn)) # Don’t use os.scandir here - it returns broken paths under Windows/MSYS2 - flist = [os.path.join(tdir,name) for name in os.listdir(tdir) if have_match(name)] + flist = [os.path.join(tdir, name) for name in os.listdir(tdir) if have_match(name)] if not flist: return False @@ -135,26 +142,26 @@ def get_file_with_ext(tdir,ext,delete=True,no_dot=False,return_list=False,delete def get_comment(do_shuffle=False): labels = [ - "Automotive", - "Travel expenses", - "Healthcare", + 'Automotive', + 'Travel expenses', + 'Healthcare', tx_comment_jp[:40], tx_comment_zh[:40], - "Alice’s allowance", - "Bob’s bequest", - "House purchase", - "Real estate fund", - "Job 1", - "XYZ Corp.", - "Eddie’s endowment", - "Emergency fund", - "Real estate fund", - "Ian’s inheritance", - "", - "Rainy day", - "Fred’s funds", - "Job 2", - "Carl’s capital", + 'Alice’s allowance', + 'Bob’s bequest', + 'House purchase', + 'Real estate fund', + 'Job 1', + 'XYZ Corp.', + 'Eddie’s endowment', + 'Emergency fund', + 'Real estate fund', + 'Ian’s inheritance', + '', + 'Rainy day', + 'Fred’s funds', + 'Job 2', + 'Carl’s capital', ] from random import shuffle global label_iter diff --git a/test/cmdtest_py_d/ct_autosign.py b/test/cmdtest_py_d/ct_autosign.py index 968ae525..3d82ce9a 100755 --- a/test/cmdtest_py_d/ct_autosign.py +++ b/test/cmdtest_py_d/ct_autosign.py @@ -21,7 +21,7 @@ test.cmdtest_py_d.ct_autosign: Autosign tests for the cmdtest.py test suite """ import sys, os, time, shutil, atexit -from subprocess import run,DEVNULL +from subprocess import run, DEVNULL from pathlib import Path from mmgen.cfg import Config @@ -45,7 +45,7 @@ from ..include.common import ( end_silence, VirtBlockDevice, ) -from .common import ref_dir,dfl_words_file,dfl_bip39_file +from .common import ref_dir, dfl_words_file, dfl_bip39_file from .ct_base import CmdTestBase from .input import stealth_mnemonic_entry @@ -58,9 +58,9 @@ class CmdTestAutosignBase(CmdTestBase): threaded = False daemon_coins = [] - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + CmdTestBase.__init__(self, trunner, cfgs, spawn) if trunner is None: return @@ -89,7 +89,7 @@ class CmdTestAutosignBase(CmdTestBase): self.spawn_env['MMGEN_TEST_SUITE_AUTOSIGN_THREADED'] = '1' def __del__(self): - if hasattr(self,'have_dummy_control_files'): + if hasattr(self, 'have_dummy_control_files'): db = LEDControl.boards['dummy'] for fn in (db.status, db.trigger): run(f'sudo rm -f {fn}'.split(), check=True) @@ -102,13 +102,13 @@ class CmdTestAutosignBase(CmdTestBase): for label in (self.asi.dev_label, self.asi.ramdisk.label): self._macOS_eject_disk(label) - def _create_autosign_instances(self,create_dirs): + def _create_autosign_instances(self, create_dirs): d = {'offline': {'name':'asi'}} if self.have_online: d['online'] = {'name':'asi_online'} - for subdir,data in d.items(): + for subdir, data in d.items(): asi = Autosign( Config({ 'coins': ','.join(self.coins), @@ -164,17 +164,17 @@ class CmdTestAutosignBase(CmdTestBase): def _macOS_eject_disk(self, label): try: - run(['diskutil' ,'eject', label], stdout=DEVNULL, stderr=DEVNULL) + run(['diskutil' , 'eject', label], stdout=DEVNULL, stderr=DEVNULL) except: pass def start_daemons(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) start_test_daemons(*self.network_ids) return 'ok' def stop_daemons(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) stop_test_daemons(*self.network_ids) return 'ok' @@ -205,16 +205,16 @@ class CmdTestAutosignBase(CmdTestBase): no_passthru_opts = True) if use_dfl_wallet: - t.expect( 'Use default wallet for autosigning? (Y/n): ', 'y' ) + t.expect('Use default wallet for autosigning? (Y/n): ', 'y') t.passphrase('MMGen wallet', passwd) else: if use_dfl_wallet is not None: # None => no dfl wallet present - t.expect( 'Use default wallet for autosigning? (Y/n): ', 'n' ) - mn_file = mn_file or { 'mmgen': dfl_words_file, 'bip39': dfl_bip39_file }[mn_type] + t.expect('Use default wallet for autosigning? (Y/n): ', 'n') + mn_file = mn_file or {'mmgen': dfl_words_file, 'bip39': dfl_bip39_file}[mn_type] mn = read_from_file(mn_file).strip().split() if not seed_len: - t.expect('words: ',{ 12:'1', 18:'2', 24:'3' }[len(mn)]) - t.expect('OK? (Y/n): ','\n') + t.expect('words: ', {12:'1', 18:'2', 24:'3'}[len(mn)]) + t.expect('OK? (Y/n): ', '\n') from mmgen.mn_entry import mn_entry entry_mode = 'full' mne = mn_entry(cfg, mn_type, entry_mode) @@ -225,7 +225,7 @@ class CmdTestAutosignBase(CmdTestBase): 'Type a number.*: ', str(mne.entry_modes.index(entry_mode) + 1), regex = True) - stealth_mnemonic_entry(t,mne,mn,entry_mode) + stealth_mnemonic_entry(t, mne, mn, entry_mode) t.written_to_file('Autosign wallet') @@ -272,7 +272,7 @@ class CmdTestAutosignBase(CmdTestBase): self._macOS_eject_disk(loc.dev_label) def _mount_ops(self, loc, cmd, *args, **kwargs): - return getattr(getattr(self,loc),cmd)(*args, silent=self.silent_mount, **kwargs) + return getattr(getattr(self, loc), cmd)(*args, silent=self.silent_mount, **kwargs) def do_mount(self, *args, **kwargs): return self._mount_ops('asi', 'do_mount', *args, **kwargs) @@ -282,7 +282,7 @@ class CmdTestAutosignBase(CmdTestBase): def _gen_listing(self): for k in self.asi.dirs: - d = getattr(self.asi,k) + d = getattr(self.asi, k) if d.is_dir(): yield '{:12} {}'.format( str(Path(*d.parts[6:])) + ':', @@ -364,7 +364,7 @@ class CmdTestAutosignClean(CmdTestAutosignBase): self.asi = Autosign(Config({'_clone': self.asi.cfg, 'coins': 'xmr,btc,bch,eth'})) return self._clean('xmr,btc,bch,eth') - def _clean(self,coins): + def _clean(self, coins): self.spawn('', msg_only=True) @@ -377,7 +377,7 @@ class CmdTestAutosignClean(CmdTestAutosignBase): self.create_fake_tx_files() before = '\n'.join(self._gen_listing()) - t = self.spawn('mmgen-autosign', [f'--coins={coins}','clean'], no_msg=True) + t = self.spawn('mmgen-autosign', [f'--coins={coins}', 'clean'], no_msg=True) out = t.read() if sys.platform == 'darwin': @@ -447,18 +447,18 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase): return 'silent' def wait_loop_kill(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) pid = int(self.read_from_tmpfile('autosign_thread_pid')) self.delete_tmpfile('autosign_thread_pid') from signal import SIGTERM imsg(purple(f'Killing autosign wait loop [PID {pid}]')) try: - os.kill(pid,SIGTERM) + os.kill(pid, SIGTERM) except: imsg(yellow(f'{pid}: no such process')) return 'ok' - def _wait_signed(self,desc): + def _wait_signed(self, desc): oqmsg_r(gray(f'→ offline wallet{"s" if desc.endswith("s") else ""} waiting for {desc}')) assert not self.asi.device_inserted, f'‘{self.asi.dev_label}’ is inserted!' assert not self.asi.mountpoint.is_mount(), f'‘{self.asi.mountpoint}’ is mounted!' @@ -510,69 +510,69 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase): class CmdTestAutosign(CmdTestAutosignBase): 'autosigning transactions for all supported coins' - coins = ['btc','bch','ltc','eth'] - daemon_coins = ['btc','bch','ltc'] - txfile_coins = ['btc','bch','ltc','eth','mm1','etc'] + coins = ['btc', 'bch', 'ltc', 'eth'] + daemon_coins = ['btc', 'bch', 'ltc'] + txfile_coins = ['btc', 'bch', 'ltc', 'eth', 'mm1', 'etc'] have_online = False live = False simulate_led = True no_insert_check = True filedir_map = ( - ('btc',''), - ('bch',''), - ('ltc','litecoin'), - ('eth','ethereum'), - ('mm1','ethereum'), - ('etc','ethereum_classic'), + ('btc', ''), + ('bch', ''), + ('ltc', 'litecoin'), + ('eth', 'ethereum'), + ('mm1', 'ethereum'), + ('etc', 'ethereum_classic'), ) cmd_group = ( - ('start_daemons', 'starting daemons'), - ('copy_tx_files', 'copying transaction files'), - ('gen_key', 'generating key'), - ('create_dfl_wallet', 'creating default MMGen wallet'), - ('bad_opt1', 'running ‘mmgen-autosign’ with --seed-len in invalid context'), - ('bad_opt2', 'running ‘mmgen-autosign’ with --mnemonic-fmt in invalid context'), - ('bad_opt3', 'running ‘mmgen-autosign’ with --led in invalid context'), - ('run_setup_dfl_wallet', 'running ‘autosign setup’ (with default wallet)'), - ('sign_quiet', 'signing transactions (--quiet)'), - ('remove_signed_txfiles', 'removing signed transaction files'), - ('run_setup_bip39', 'running ‘autosign setup’ (BIP39 mnemonic)'), - ('create_bad_txfiles', 'creating bad transaction files'), - ('sign_full_summary', 'signing transactions (--full-summary)'), - ('remove_signed_txfiles_btc','removing transaction files (BTC only)'), - ('remove_bad_txfiles', 'removing bad transaction files'), - ('sign_led', 'signing transactions (--led - BTC files only)'), - ('remove_signed_txfiles', 'removing signed transaction files'), - ('sign_stealth_led', 'signing transactions (--stealth-led)'), - ('remove_signed_txfiles', 'removing signed transaction files'), - ('copy_msgfiles', 'copying message files'), - ('sign_quiet_msg', 'signing transactions and messages (--quiet)'), - ('remove_signed_txfiles', 'removing signed transaction files'), - ('create_bad_txfiles2', 'creating bad transaction files'), - ('remove_signed_msgfiles', 'removing signed message files'), - ('create_invalid_msgfile', 'creating invalid message file'), - ('sign_full_summary_msg', 'signing transactions and messages (--full-summary)'), - ('remove_invalid_msgfile', 'removing invalid message file'), - ('remove_bad_txfiles2', 'removing bad transaction files'), - ('sign_no_unsigned', 'signing transactions and messages (nothing to sign)'), - ('sign_no_unsigned_xmr', 'signing transactions and messages (nothing to sign, with XMR)'), - ('sign_no_unsigned_xmronly', 'signing transactions and messages (nothing to sign, XMR-only)'), - ('wipe_key', 'wiping the wallet encryption key'), - ('stop_daemons', 'stopping daemons'), - ('sign_bad_no_daemon', 'signing transactions (error, no daemons running)'), + ('start_daemons', 'starting daemons'), + ('copy_tx_files', 'copying transaction files'), + ('gen_key', 'generating key'), + ('create_dfl_wallet', 'creating default MMGen wallet'), + ('bad_opt1', 'running ‘mmgen-autosign’ with --seed-len in invalid context'), + ('bad_opt2', 'running ‘mmgen-autosign’ with --mnemonic-fmt in invalid context'), + ('bad_opt3', 'running ‘mmgen-autosign’ with --led in invalid context'), + ('run_setup_dfl_wallet', 'running ‘autosign setup’ (with default wallet)'), + ('sign_quiet', 'signing transactions (--quiet)'), + ('remove_signed_txfiles', 'removing signed transaction files'), + ('run_setup_bip39', 'running ‘autosign setup’ (BIP39 mnemonic)'), + ('create_bad_txfiles', 'creating bad transaction files'), + ('sign_full_summary', 'signing transactions (--full-summary)'), + ('remove_signed_txfiles_btc', 'removing transaction files (BTC only)'), + ('remove_bad_txfiles', 'removing bad transaction files'), + ('sign_led', 'signing transactions (--led - BTC files only)'), + ('remove_signed_txfiles', 'removing signed transaction files'), + ('sign_stealth_led', 'signing transactions (--stealth-led)'), + ('remove_signed_txfiles', 'removing signed transaction files'), + ('copy_msgfiles', 'copying message files'), + ('sign_quiet_msg', 'signing transactions and messages (--quiet)'), + ('remove_signed_txfiles', 'removing signed transaction files'), + ('create_bad_txfiles2', 'creating bad transaction files'), + ('remove_signed_msgfiles', 'removing signed message files'), + ('create_invalid_msgfile', 'creating invalid message file'), + ('sign_full_summary_msg', 'signing transactions and messages (--full-summary)'), + ('remove_invalid_msgfile', 'removing invalid message file'), + ('remove_bad_txfiles2', 'removing bad transaction files'), + ('sign_no_unsigned', 'signing transactions and messages (nothing to sign)'), + ('sign_no_unsigned_xmr', 'signing transactions and messages (nothing to sign, with XMR)'), + ('sign_no_unsigned_xmronly', 'signing transactions and messages (nothing to sign, XMR-only)'), + ('wipe_key', 'wiping the wallet encryption key'), + ('stop_daemons', 'stopping daemons'), + ('sign_bad_no_daemon', 'signing transactions (error, no daemons running)'), ) - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): - super().__init__(trunner,cfgs,spawn) + super().__init__(trunner, cfgs, spawn) if trunner is None: return if self.live and not cfg.exact_output: - die(1,red('autosign_live tests must be run with --exact-output enabled!')) + die(1, red('autosign_live tests must be run with --exact-output enabled!')) if self.no_insert_check: self.opts.append('--no-insert-check') @@ -585,10 +585,10 @@ class CmdTestAutosign(CmdTestAutosignBase): for coin in self.coins: if coin == 'xmr': continue - sdir = os.path.join('test','ref',fmap[coin]) + sdir = os.path.join('test', 'ref', fmap[coin]) for fn in os.listdir(sdir): if fn.endswith(f'[{coin.upper()}].rawmsg.json'): - yield os.path.join(sdir,fn) + yield os.path.join(sdir, fn) self.ref_msgfiles = tuple(gen_msg_fns()) self.good_msg_count = 0 @@ -606,20 +606,20 @@ class CmdTestAutosign(CmdTestAutosignBase): def gen_key(self): self.insert_device() - t = self.spawn( 'mmgen-autosign', self.opts + ['gen_key'] ) + t = self.spawn('mmgen-autosign', self.opts + ['gen_key']) t.expect_getend('Wrote key file ') t.read() self.remove_device() return t def create_dfl_wallet(self): - t = self.spawn( 'mmgen-walletconv', [ + t = self.spawn('mmgen-walletconv', [ f'--outdir={cfg.data_dir}', '--usr-randchars=0', '--quiet', '--hash-preset=1', '--label=foo', 'test/ref/98831F3A.hex' ] ) - t.passphrase_new('new MMGen wallet','abc') + t.passphrase_new('new MMGen wallet', 'abc') t.written_to_file('MMGen wallet') return t @@ -638,13 +638,13 @@ class CmdTestAutosign(CmdTestAutosignBase): return self._bad_opt(['--led', 'gen_key'], 'makes no sense') def run_setup_dfl_wallet(self): - return self.run_setup(mn_type='default',use_dfl_wallet=True) + return self.run_setup(mn_type='default', use_dfl_wallet=True) def run_setup_bip39(self): from mmgen.cfgfile import mmgen_cfg_file - fn = mmgen_cfg_file(cfg,'usr').fn - old_data = mmgen_cfg_file(cfg,'usr').get_data(fn) - new_data = [d.replace('bip39:fixed','bip39:full')[2:] + fn = mmgen_cfg_file(cfg, 'usr').fn + old_data = mmgen_cfg_file(cfg, 'usr').get_data(fn) + new_data = [d.replace('bip39:fixed', 'bip39:full')[2:] if d.startswith('# mnemonic_entry_modes') else d for d in old_data] with open(fn, 'w') as fh: fh.write('\n'.join(new_data) + '\n') @@ -657,7 +657,7 @@ class CmdTestAutosign(CmdTestAutosignBase): return t def copy_tx_files(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) return self.tx_file_ops('copy') def remove_signed_txfiles(self): @@ -665,24 +665,24 @@ class CmdTestAutosign(CmdTestAutosignBase): return 'skip' def remove_signed_txfiles_btc(self): - self.tx_file_ops('remove_signed',txfile_coins=['btc']) + self.tx_file_ops('remove_signed', txfile_coins=['btc']) return 'skip' - def tx_file_ops(self,op,txfile_coins=[]): + def tx_file_ops(self, op, txfile_coins=[]): - assert op in ('copy','set_count','remove_signed') + assert op in ('copy', 'set_count', 'remove_signed') from .ct_ref import CmdTestRef def gen(): d = CmdTestRef.sources['ref_tx_file'] dirmap = [e for e in self.filedir_map if e[0] in (txfile_coins or self.txfile_coins)] - for coin,coindir in dirmap: - for network in (0,1): + for coin, coindir in dirmap: + for network in (0, 1): fn = d[coin][network] if fn: - yield (coindir,fn) + yield (coindir, fn) - data = list(gen()) + [('','25EFA3[2.34].testnet.rawtx')] # TX with 2 non-MMGen outputs + data = list(gen()) + [('', '25EFA3[2.34].testnet.rawtx')] # TX with 2 non-MMGen outputs self.tx_count = len(data) if op == 'set_count': @@ -694,16 +694,16 @@ class CmdTestAutosign(CmdTestAutosignBase): self.do_mount(verbose=cfg.verbose or cfg.exact_output) end_silence() - for coindir,fn in data: - src = joinpath(ref_dir,coindir,fn) + for coindir, fn in data: + src = joinpath(ref_dir, coindir, fn) if cfg.debug_utf8: ext = '.testnet.rawtx' if fn.endswith('.testnet.rawtx') else '.rawtx' fn = fn[:-len(ext)] + '-α' + ext target = joinpath(self.asi.tx_dir, fn) if not op == 'remove_signed': - shutil.copyfile(src,target) + shutil.copyfile(src, target) try: - os.unlink(target.replace('.rawtx','.sigtx')) + os.unlink(target.replace('.rawtx', '.sigtx')) except: pass @@ -721,15 +721,15 @@ class CmdTestAutosign(CmdTestAutosignBase): create_bad_txfiles2 = create_bad_txfiles remove_bad_txfiles2 = remove_bad_txfiles - def bad_txfiles(self,op): + def bad_txfiles(self, op): self.insert_device() self.do_mount() # create or delete 2 bad tx files - self.spawn('',msg_only=True) - fns = [joinpath(self.asi.tx_dir, f'bad{n}.rawtx') for n in (1,2)] + self.spawn('', msg_only=True) + fns = [joinpath(self.asi.tx_dir, f'bad{n}.rawtx') for n in (1, 2)] if op == 'create': for fn in fns: - with open(fn,'w') as fp: + with open(fn, 'w') as fp: fp.write('bad tx data\n') self.bad_tx_count = 2 elif op == 'remove': @@ -755,16 +755,16 @@ class CmdTestAutosign(CmdTestAutosignBase): def remove_invalid_msgfile(self): return self.msgfile_ops('remove_invalid') - def msgfile_ops(self,op): - self.spawn('',msg_only=True) - destdir = joinpath(self.asi.mountpoint,'msg') + def msgfile_ops(self, op): + self.spawn('', msg_only=True) + destdir = joinpath(self.asi.mountpoint, 'msg') self.insert_device() self.do_mount() - os.makedirs(destdir,exist_ok=True) + os.makedirs(destdir, exist_ok=True) if op.endswith('_invalid'): - fn = os.path.join(destdir,'DEADBE[BTC].rawmsg.json') + fn = os.path.join(destdir, 'DEADBE[BTC].rawmsg.json') if op == 'create_invalid': - with open(fn,'w') as fp: + with open(fn, 'w') as fp: fp.write('bad data\n') self.bad_msg_count += 1 elif op == 'remove_invalid': @@ -778,9 +778,9 @@ class CmdTestAutosign(CmdTestAutosignBase): else: self.good_msg_count += 1 imsg(f'Copying: {fn} -> {destdir}') - shutil.copy2(fn,destdir) + shutil.copy2(fn, destdir) elif op == 'remove_signed': - os.unlink(os.path.join( destdir, os.path.basename(fn).replace('rawmsg','sigmsg') )) + os.unlink(os.path.join(destdir, os.path.basename(fn).replace('rawmsg', 'sigmsg'))) self.do_umount() self.remove_device() return 'ok' @@ -858,7 +858,7 @@ class CmdTestAutosign(CmdTestAutosignBase): return 'skip' return self._sign_no_unsigned( coins = 'XMR,BTC', - present = ['xmr_signables','non_xmr_signables']) + present = ['xmr_signables', 'non_xmr_signables']) def sign_no_unsigned_xmronly(self): if self.coins == ['btc']: @@ -868,17 +868,17 @@ class CmdTestAutosign(CmdTestAutosignBase): present = ['xmr_signables'], absent = ['non_xmr_signables']) - def _sign_no_unsigned(self,coins,present=[],absent=[]): + def _sign_no_unsigned(self, coins, present=[], absent=[]): self.insert_device() t = self.spawn('mmgen-autosign', ['--quiet', '--no-insert-check', f'--coins={coins}']) res = t.read() self.remove_device() for signable_list in present: - for signable_clsname in getattr(Signable,signable_list): + for signable_clsname in getattr(Signable, signable_list): desc = getattr(Signable, signable_clsname).desc assert f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ missing in output' for signable_list in absent: - for signable_clsname in getattr(Signable,signable_list): + for signable_clsname in getattr(Signable, signable_list): desc = getattr(Signable, signable_clsname).desc assert not f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ should be absent in output' return t @@ -904,33 +904,33 @@ class CmdTestAutosignLive(CmdTestAutosignBTC): no_insert_check = False cmd_group = ( - ('start_daemons', 'starting daemons'), - ('copy_tx_files', 'copying transaction files'), - ('gen_key', 'generating key'), - ('run_setup_mmgen', 'running ‘autosign setup’ (MMGen native mnemonic)'), - ('sign_live', 'signing transactions'), - ('create_bad_txfiles', 'creating bad transaction files'), - ('sign_live_led', 'signing transactions (--led)'), - ('remove_bad_txfiles', 'removing bad transaction files'), - ('sign_live_stealth_led','signing transactions (--stealth-led)'), - ('stop_daemons', 'stopping daemons'), + ('start_daemons', 'starting daemons'), + ('copy_tx_files', 'copying transaction files'), + ('gen_key', 'generating key'), + ('run_setup_mmgen', 'running ‘autosign setup’ (MMGen native mnemonic)'), + ('sign_live', 'signing transactions'), + ('create_bad_txfiles', 'creating bad transaction files'), + ('sign_live_led', 'signing transactions (--led)'), + ('remove_bad_txfiles', 'removing bad transaction files'), + ('sign_live_stealth_led', 'signing transactions (--stealth-led)'), + ('stop_daemons', 'stopping daemons'), ) - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): - super().__init__(trunner,cfgs,spawn) + super().__init__(trunner, cfgs, spawn) if trunner is None: return try: - LEDControl(enabled=True,simulate=self.simulate_led) + LEDControl(enabled=True, simulate=self.simulate_led) except Exception as e: msg(str(e)) - die(2,'LEDControl initialization failed') + die(2, 'LEDControl initialization failed') def run_setup_mmgen(self): - return self.run_setup(mn_type='mmgen',use_dfl_wallet=None) + return self.run_setup(mn_type='mmgen', use_dfl_wallet=None) def sign_live(self): return self.do_sign_live() @@ -941,7 +941,7 @@ class CmdTestAutosignLive(CmdTestAutosignBTC): def sign_live_stealth_led(self): return self.do_sign_live(['--stealth-led'], 'You should see no LED activity now') - def do_sign_live(self,led_opts=None,led_msg=None): + def do_sign_live(self, led_opts=None, led_msg=None): def prompt_remove(): omsg_r(orange('\nExtract removable device and then hit ENTER ')) diff --git a/test/cmdtest_py_d/ct_base.py b/test/cmdtest_py_d/ct_base.py index 80199913..7612cba4 100755 --- a/test/cmdtest_py_d/ct_base.py +++ b/test/cmdtest_py_d/ct_base.py @@ -20,17 +20,17 @@ test.cmdtest_py_d.ct_base: Base class for the cmdtest.py test suite """ -import sys,os +import sys, os from mmgen.util import msg from mmgen.color import gray -from ..include.common import cfg,write_to_file,read_from_file +from ..include.common import cfg, write_to_file, read_from_file from .common import get_file_with_ext class CmdTestBase: 'initializer class for the cmdtest.py test suite' - base_passthru_opts = ('data_dir','skip_cfg_file') + base_passthru_opts = ('data_dir', 'skip_cfg_file') passthru_opts = () networks = () segwit_opts_ok = False @@ -40,8 +40,8 @@ class CmdTestBase: tmpdir_nums = [] test_name = None - def __init__(self,trunner,cfgs,spawn): - if hasattr(self,'name'): # init will be called multiple times for classes with multiple inheritance + def __init__(self, trunner, cfgs, spawn): + if hasattr(self, 'name'): # init will be called multiple times for classes with multiple inheritance return self.name = type(self).__name__ self.proto = cfg._proto @@ -49,9 +49,9 @@ class CmdTestBase: self.cfgs = cfgs self.spawn = spawn self.have_dfl_wallet = False - self.usr_rand_chars = (5,30)[bool(cfg.usr_random)] + self.usr_rand_chars = (5, 30)[bool(cfg.usr_random)] self.usr_rand_arg = f'-r{self.usr_rand_chars}' - self.tn_ext = ('','.testnet')[self.proto.testnet] + self.tn_ext = ('', '.testnet')[self.proto.testnet] self.coin = self.proto.coin.lower() self.fork = 'btc' if self.coin == 'bch' and not cfg.cashaddr else self.coin self.altcoin_pfx = '' if self.fork == 'btc' else f'-{self.proto.coin}' @@ -66,19 +66,19 @@ class CmdTestBase: @property def tmpdir(self): - return os.path.join('test','tmp','{}{}'.format(self.tmpdir_num,'-α' if cfg.debug_utf8 else '')) + return os.path.join('test', 'tmp', '{}{}'.format(self.tmpdir_num, '-α' if cfg.debug_utf8 else '')) - def get_file_with_ext(self,ext,**kwargs): - return get_file_with_ext(self.tmpdir,ext,**kwargs) + def get_file_with_ext(self, ext, **kwargs): + return get_file_with_ext(self.tmpdir, ext, **kwargs) - def read_from_tmpfile(self,fn,binary=False): - return read_from_file(os.path.join(self.tmpdir,fn),binary=binary) + def read_from_tmpfile(self, fn, binary=False): + return read_from_file(os.path.join(self.tmpdir, fn), binary=binary) - def write_to_tmpfile(self,fn,data,binary=False): - return write_to_file(os.path.join(self.tmpdir,fn),data,binary=binary) + def write_to_tmpfile(self, fn, data, binary=False): + return write_to_file(os.path.join(self.tmpdir, fn), data, binary=binary) - def delete_tmpfile(self,fn): - fn = os.path.join(self.tmpdir,fn) + def delete_tmpfile(self, fn): + fn = os.path.join(self.tmpdir, fn) try: return os.unlink(fn) except: @@ -100,13 +100,13 @@ class CmdTestBase: def skip_for_win(self, extra_msg=None): return self.skip_for_platform('win32', extra_msg) - def spawn_chk(self,*args,**kwargs): + def spawn_chk(self, *args, **kwargs): """ Drop-in replacement for spawn() + t.read() for tests that spawn more than one process. Ensures that test script execution stops when a spawned process fails. """ - t = self.spawn(*args,**kwargs) + t = self.spawn(*args, **kwargs) t.read() t.ok() t.skip_ok = True diff --git a/test/cmdtest_py_d/ct_cfgfile.py b/test/cmdtest_py_d/ct_cfgfile.py index 8769e6b5..fe2c7d45 100755 --- a/test/cmdtest_py_d/ct_cfgfile.py +++ b/test/cmdtest_py_d/ct_cfgfile.py @@ -10,12 +10,12 @@ test.cmdtest_py_d.ct_cfgfile: CfgFile tests for the MMGen cmdtest.py test suite """ -import sys,os,time,shutil +import sys, os, time, shutil from mmgen.color import yellow -from mmgen.cfgfile import CfgFileSampleSys,CfgFileSampleUsr,cfg_file_sample +from mmgen.cfgfile import CfgFileSampleSys, CfgFileSampleUsr, cfg_file_sample -from ..include.common import cfg,read_from_file,write_to_file,imsg +from ..include.common import cfg, read_from_file, write_to_file, imsg from .ct_base import CmdTestBase class CmdTestCfgFile(CmdTestBase): @@ -26,25 +26,25 @@ class CmdTestCfgFile(CmdTestBase): color = True cmd_group = ( - ('sysfile', (40,'init with system cfg sample file in place', [])), - ('no_metadata_sample', (40,'init with unversioned cfg sample file', [])), - ('altered_sample', (40,'init with user-modified cfg sample file', [])), - ('old_sample', (40,'init with old v2 cfg sample file', [])), - ('old_sample_bad_var', (40,'init with old v2 cfg sample file and bad variable in mmgen.cfg', [])), - ('autoset_opts', (40,'setting autoset opts', [])), - ('autoset_opts_cmdline', (40,'setting autoset opts (override on cmdline)', [])), - ('autoset_opts_bad', (40,'setting autoset opts (bad value in cfg file)', [])), - ('autoset_opts_bad_cmdline', (40,'setting autoset opts (bad param on cmdline)', [])), - ('coin_specific_vars', (40,'setting coin-specific vars', [])), - ('chain_names', (40,'setting chain names', [])), - ('mnemonic_entry_modes', (40,'setting mnemonic entry modes', [])), + ('sysfile', (40, 'init with system cfg sample file in place', [])), + ('no_metadata_sample', (40, 'init with unversioned cfg sample file', [])), + ('altered_sample', (40, 'init with user-modified cfg sample file', [])), + ('old_sample', (40, 'init with old v2 cfg sample file', [])), + ('old_sample_bad_var', (40, 'init with old v2 cfg sample file and bad variable in mmgen.cfg', [])), + ('autoset_opts', (40, 'setting autoset opts', [])), + ('autoset_opts_cmdline', (40, 'setting autoset opts (override on cmdline)', [])), + ('autoset_opts_bad', (40, 'setting autoset opts (bad value in cfg file)', [])), + ('autoset_opts_bad_cmdline', (40, 'setting autoset opts (bad param on cmdline)', [])), + ('coin_specific_vars', (40, 'setting coin-specific vars', [])), + ('chain_names', (40, 'setting chain names', [])), + ('mnemonic_entry_modes', (40, 'setting mnemonic entry modes', [])), ) - def __init__(self,trunner,cfgs,spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + def __init__(self, trunner, cfgs, spawn): + CmdTestBase.__init__(self, trunner, cfgs, spawn) self.spawn_env['MMGEN_TEST_SUITE_CFGTEST'] = '1' - def spawn_test(self,args=[],extra_desc='',pexpect_spawn=None, exit_val=None): + def spawn_test(self, args=[], extra_desc='', pexpect_spawn=None, exit_val=None): return self.spawn( 'test/misc/cfg.py', [f'--data-dir={self.path("data_dir")}'] + args, @@ -53,19 +53,19 @@ class CmdTestCfgFile(CmdTestBase): pexpect_spawn = pexpect_spawn, exit_val = exit_val) - def path(self,id_str): + def path(self, id_str): return { 'ref': 'test/ref/mmgen.cfg', 'data_dir': '{}/data_dir'.format(self.tmpdir), - 'shared_data': '{}/data_dir/{}'.format(self.tmpdir,CfgFileSampleSys.test_fn_subdir), + 'shared_data': '{}/data_dir/{}'.format(self.tmpdir, CfgFileSampleSys.test_fn_subdir), 'usr': '{}/data_dir/mmgen.cfg'.format(self.tmpdir), - 'sys': '{}/data_dir/{}/mmgen.cfg'.format(self.tmpdir,CfgFileSampleSys.test_fn_subdir), + 'sys': '{}/data_dir/{}/mmgen.cfg'.format(self.tmpdir, CfgFileSampleSys.test_fn_subdir), 'sample': '{}/data_dir/mmgen.cfg.sample'.format(os.path.abspath(self.tmpdir)), }[id_str] def copy_sys_sample(self): - os.makedirs(self.path('shared_data'),exist_ok=True) - shutil.copy2(self.path('ref'),self.path('sys')) + os.makedirs(self.path('shared_data'), exist_ok=True) + shutil.copy2(self.path('ref'), self.path('sys')) def sysfile(self): self.copy_sys_sample() @@ -74,7 +74,7 @@ class CmdTestCfgFile(CmdTestBase): u = read_from_file(self.path('usr')) S = read_from_file(self.path('sys')) assert u[-1] == '\n', u - assert u.replace('\r\n','\n') == S, 'u != S' + assert u.replace('\r\n', '\n') == S, 'u != S' self.check_replaced_sample() return t @@ -84,8 +84,8 @@ class CmdTestCfgFile(CmdTestBase): assert s[-1] == '\n', s assert S.splitlines() == s.splitlines()[:-1], 'sys != sample[:-1]' - def bad_sample(self,s,e): - write_to_file(self.path('sample'),s) + def bad_sample(self, s, e): + write_to_file(self.path('sample'), s) t = self.spawn_test() t.expect(e) t.read() @@ -96,44 +96,44 @@ class CmdTestCfgFile(CmdTestBase): self.copy_sys_sample() s = read_from_file(self.path('sys')) e = CfgFileSampleUsr.out_of_date_fs.format(self.path('sample')) - return self.bad_sample(s,e) + return self.bad_sample(s, e) def altered_sample(self): s = '\n'.join(read_from_file(self.path('sample')).splitlines()[1:]) + '\n' e = CfgFileSampleUsr.altered_by_user_fs.format(self.path('sample')) - return self.bad_sample(s,e) + return self.bad_sample(s, e) - def old_sample_common(self,old_set=False,args=[],pexpect_spawn=False): + def old_sample_common(self, old_set=False, args=[], pexpect_spawn=False): s = read_from_file(self.path('sys')) - d = s.replace('monero_','zcash_').splitlines() - a1 = ['','# Uncomment to make foo true:','# foo true'] - a2 = ['','# Uncomment to make bar false:','# bar false'] + d = s.replace('monero_', 'zcash_').splitlines() + a1 = ['', '# Uncomment to make foo true:', '# foo true'] + a2 = ['', '# Uncomment to make bar false:', '# bar false'] d = d + a1 + a2 chk = cfg_file_sample.cls_make_metadata(d) - write_to_file(self.path('sample'),'\n'.join(d+chk) + '\n') + write_to_file(self.path('sample'), '\n'.join(d+chk) + '\n') t = self.spawn_test(args=args, pexpect_spawn=pexpect_spawn, exit_val=1 if old_set else None) t.expect('options have changed') - for s in ('have been added','monero_','have been removed','zcash_','foo','bar'): + for s in ('have been added', 'monero_', 'have been removed', 'zcash_', 'foo', 'bar'): t.expect(s) if old_set: - for s in ('must be deleted','bar','foo'): + for s in ('must be deleted', 'bar', 'foo'): t.expect(s) cp = CfgFileSampleUsr.details_confirm_prompt + ' (y/N): ' - t.expect(cp,'y') + t.expect(cp, 'y') - for s in ('CHANGES','Removed','# zcash_','# foo','# bar','Added','# monero_'): + for s in ('CHANGES', 'Removed', '# zcash_', '# foo', '# bar', 'Added', '# monero_'): t.expect(s) if t.pexpect_spawn: # view and exit pager time.sleep(1 if cfg.exact_output else t.send_delay) t.send('q') - t.expect(cp,'n') + t.expect(cp, 'n') if old_set: t.expect('unrecognized option') @@ -148,13 +148,13 @@ class CmdTestCfgFile(CmdTestBase): return t def old_sample(self): - d = ['testnet true','rpc_password passwOrd'] - write_to_file(self.path('usr'),'\n'.join(d) + '\n') + d = ['testnet true', 'rpc_password passwOrd'] + write_to_file(self.path('usr'), '\n'.join(d) + '\n') return self.old_sample_common(args=['parse_test']) def old_sample_bad_var(self): - d = ['foo true','bar false'] - write_to_file(self.path('usr'),'\n'.join(d) + '\n') + d = ['foo true', 'bar false'] + write_to_file(self.path('usr'), '\n'.join(d) + '\n') t = self.old_sample_common( old_set = True, pexpect_spawn = not sys.platform == 'win32') @@ -162,7 +162,7 @@ class CmdTestCfgFile(CmdTestBase): return t def _autoset_opts(self, args=[], text='rpc_backend aiohttp\n', exit_val=None): - write_to_file( self.path('usr'), text ) + write_to_file(self.path('usr'), text) imsg(yellow(f'Wrote cfg file:\n {text}')) return self.spawn_test(args=args, exit_val=exit_val) @@ -170,7 +170,7 @@ class CmdTestCfgFile(CmdTestBase): return self._autoset_opts(args=['autoset_opts']) def autoset_opts_cmdline(self): - return self._autoset_opts(args=['--rpc-backend=curl','autoset_opts_cmdline']) + return self._autoset_opts(args=['--rpc-backend=curl', 'autoset_opts_cmdline']) def _autoset_opts_bad(self, expect, kwargs): t = self._autoset_opts(exit_val=1, **kwargs) @@ -193,15 +193,15 @@ class CmdTestCfgFile(CmdTestBase): 'btc_ignore_daemon_version true', 'eth_ignore_daemon_version true' ] - write_to_file(self.path('usr'),'\n'.join(d) + '\n') + write_to_file(self.path('usr'), '\n'.join(d) + '\n') imsg(yellow('Wrote cfg file:\n {}'.format('\n '.join(d)))) - for coin,res1_chk,res2_chk,res2_chk_eq in ( - ('BTC','True', '1.2345',True), - ('LTC','False','1.2345',False), - ('BCH','False','1.2345',False), - ('ETH','True', '5.4321',True), - ('ETC','False','5.4321',False) + for coin, res1_chk, res2_chk, res2_chk_eq in ( + ('BTC', 'True', '1.2345', True), + ('LTC', 'False', '1.2345', False), + ('BCH', 'False', '1.2345', False), + ('ETH', 'True', '5.4321', True), + ('ETC', 'False', '5.4321', False) ): if cfg.no_altcoin and coin != 'BTC': continue @@ -212,7 +212,7 @@ class CmdTestCfgFile(CmdTestBase): 'ignore_daemon_version', 'max_tx_fee' ], - extra_desc=f'({coin})' ) + extra_desc=f'({coin})') res1 = t.expect_getend('ignore_daemon_version: ') res2 = t.expect_getend('max_tx_fee: ') assert res1 == res1_chk, f'{res1} != {res1_chk}' @@ -235,7 +235,7 @@ class CmdTestCfgFile(CmdTestBase): return t txt = 'mnemonic_entry_modes mmgen:full bip39:short' - write_to_file(self.path('usr'),txt+'\n') + write_to_file(self.path('usr'), txt+'\n') imsg(yellow(f'Wrote cfg file: {txt!r}')) t = run("{'mmgen': 'full', 'bip39': 'short'}") # check that set_dfl_entry_mode() set the mode correctly: @@ -248,11 +248,11 @@ class CmdTestCfgFile(CmdTestBase): if cfg.no_altcoin: return 'skip' - def run(chk,testnet): - for coin,chain_chk in (('ETH',chk),('ETC',None)): + def run(chk, testnet): + for coin, chain_chk in (('ETH', chk), ('ETC', None)): t = self.spawn_test( - args = [f'--coin={coin}',f'--testnet={(0,1)[testnet]}','coin_specific_vars','chain_names'], - extra_desc = f'({coin} testnet={testnet!r:5} chain_names={chain_chk})' ) + args = [f'--coin={coin}', f'--testnet={(0, 1)[testnet]}', 'coin_specific_vars', 'chain_names'], + extra_desc = f'({coin} testnet={testnet!r:5} chain_names={chain_chk})') chain = t.expect_getend('chain_names: ') if chain_chk: assert chain == chain_chk, f'{chain} != {chain_chk}' @@ -263,16 +263,16 @@ class CmdTestCfgFile(CmdTestBase): return t txt = 'eth_mainnet_chain_names istanbul constantinople' - write_to_file(self.path('usr'),txt+'\n') + write_to_file(self.path('usr'), txt+'\n') imsg(yellow(f'Wrote cfg file: {txt!r}')) - t = run("['istanbul', 'constantinople']",False) - t = run(None,True) + t = run("['istanbul', 'constantinople']", False) + t = run(None, True) txt = 'eth_testnet_chain_names rinkeby' - write_to_file(self.path('usr'),txt+'\n') + write_to_file(self.path('usr'), txt+'\n') imsg(yellow(f'Wrote cfg file: {txt!r}')) - t = run(None,False) - t = run("['rinkeby']",True) + t = run(None, False) + t = run("['rinkeby']", True) t.skip_ok = True return t diff --git a/test/cmdtest_py_d/ct_chainsplit.py b/test/cmdtest_py_d/ct_chainsplit.py index 55935c86..63f941dc 100755 --- a/test/cmdtest_py_d/ct_chainsplit.py +++ b/test/cmdtest_py_d/ct_chainsplit.py @@ -23,51 +23,51 @@ This module is unmaintained and currently non-functional from mmgen.util import die -from .common import get_file_with_ext,rt_pw +from .common import get_file_with_ext, rt_pw from .ct_regtest import CmdTestRegtest class CmdTestChainsplit(CmdTestRegtest): 'forking scenario tests for the cmdtest.py test suite' cmd_group = ( - ('split_setup', 'regtest forking scenario setup'), - ('walletgen_bob', "generating Bob's wallet"), - ('addrgen_bob', "generating Bob's addresses"), - ('addrimport_bob', "importing Bob's addresses"), - ('fund_bob', "funding Bob's wallet"), - ('split_fork', 'regtest split fork'), - ('split_start_btc', 'start regtest daemon (BTC)'), - ('split_start_b2x', 'start regtest daemon (B2X)'), - ('split_gen_btc', 'mining a block (BTC)'), - ('split_gen_b2x', 'mining 100 blocks (B2X)'), - ('split_do_split', 'creating coin splitting transactions'), - ('split_sign_b2x', 'signing B2X split transaction'), - ('split_sign_btc', 'signing BTC split transaction'), - ('split_send_b2x', 'sending B2X split transaction'), - ('split_send_btc', 'sending BTC split transaction'), - ('split_gen_btc', 'mining a block (BTC)'), - ('split_gen_b2x2', 'mining a block (B2X)'), - ('split_txdo_timelock_bad_btc', 'sending transaction with bad locktime (BTC)'), - ('split_txdo_timelock_good_btc','sending transaction with good locktime (BTC)'), - ('split_txdo_timelock_bad_b2x', 'sending transaction with bad locktime (B2X)'), - ('split_txdo_timelock_good_b2x','sending transaction with good locktime (B2X)'), + ('split_setup', 'regtest forking scenario setup'), + ('walletgen_bob', 'generating Bob’s wallet'), + ('addrgen_bob', 'generating Bob’s addresses'), + ('addrimport_bob', 'importing Bob’s addresses'), + ('fund_bob', 'funding Bob’s wallet'), + ('split_fork', 'regtest split fork'), + ('split_start_btc', 'start regtest daemon (BTC)'), + ('split_start_b2x', 'start regtest daemon (B2X)'), + ('split_gen_btc', 'mining a block (BTC)'), + ('split_gen_b2x', 'mining 100 blocks (B2X)'), + ('split_do_split', 'creating coin splitting transactions'), + ('split_sign_b2x', 'signing B2X split transaction'), + ('split_sign_btc', 'signing BTC split transaction'), + ('split_send_b2x', 'sending B2X split transaction'), + ('split_send_btc', 'sending BTC split transaction'), + ('split_gen_btc', 'mining a block (BTC)'), + ('split_gen_b2x2', 'mining a block (B2X)'), + ('split_txdo_timelock_bad_btc', 'sending transaction with bad locktime (BTC)'), + ('split_txdo_timelock_good_btc', 'sending transaction with good locktime (BTC)'), + ('split_txdo_timelock_bad_b2x', 'sending transaction with bad locktime (B2X)'), + ('split_txdo_timelock_good_b2x', 'sending transaction with good locktime (B2X)'), ) def split_setup(self): if self.proto.coin != 'BTC': - die(1,'Test valid only for coin BTC') + die(1, 'Test valid only for coin BTC') self.coin = 'BTC' return self.setup() def split_fork(self): self.coin = 'B2X' - t = self.spawn('mmgen-regtest',['fork','btc']) + t = self.spawn('mmgen-regtest', ['fork', 'btc']) t.expect('Creating fork from coin') t.expect('successfully created') t.ok() - def split_start(self,coin): + def split_start(self, coin): self.coin = coin - t = self.spawn('mmgen-regtest',['bob']) + t = self.spawn('mmgen-regtest', ['bob']) t.expect('Starting') t.expect('done') t.ok() @@ -82,7 +82,7 @@ class CmdTestChainsplit(CmdTestRegtest): self.regtest_generate(coin='BTC') def split_gen_b2x(self): - self.regtest_generate(coin='B2X',num_blocks=100) + self.regtest_generate(coin='B2X', num_blocks=100) def split_gen_b2x2(self): self.regtest_generate(coin='B2X') @@ -90,17 +90,17 @@ class CmdTestChainsplit(CmdTestRegtest): def split_do_split(self): self.coin = 'B2X' sid = self.regtest_user_sid('bob') - t = self.spawn('mmgen-split',[ + t = self.spawn('mmgen-split', [ '--bob', '--outdir='+self.tmpdir, '--tx-fees=0.0001,0.0003', - sid+':S:1',sid+':S:2']) - t.expect(r'\[q\]uit menu, .*?:.','q', regex=True) - t.expect('outputs to spend: ','1\n') + sid+':S:1', sid+':S:2']) + t.expect(r'\[q\]uit menu, .*?:.', 'q', regex=True) + t.expect('outputs to spend: ', '1\n') for _ in ('timelocked', 'split'): for _ in ('fee', 'change'): - t.expect('OK? (Y/n): ','y') + t.expect('OK? (Y/n): ', 'y') t.do_comment(False) t.view_tx('t') @@ -108,30 +108,30 @@ class CmdTestChainsplit(CmdTestRegtest): t.written_to_file('Short chain transaction') t.ok() - def split_sign(self,coin,ext): - wf = get_file_with_ext(self.regtest_user_dir('bob',coin=coin.lower()),'mmdat') - txfile = self.get_file_with_ext(ext,no_dot=True) + def split_sign(self, coin, ext): + wf = get_file_with_ext(self.regtest_user_dir('bob', coin=coin.lower()), 'mmdat') + txfile = self.get_file_with_ext(ext, no_dot=True) self.coin = coin - self.txsign(txfile,wf,extra_opts=['--bob']) + self.txsign(txfile, wf, extra_opts=['--bob']) def split_sign_b2x(self): - return self.regtest_sign(coin='B2X',ext='533].rawtx') + return self.regtest_sign(coin='B2X', ext='533].rawtx') def split_sign_btc(self): - return self.regtest_sign(coin='BTC',ext='9997].rawtx') + return self.regtest_sign(coin='BTC', ext='9997].rawtx') - def split_send(self,coin,ext): + def split_send(self, coin, ext): self.coin = coin - txfile = self.get_file_with_ext(ext,no_dot=True) - self.txsend(txfile,bogus_send=False,extra_opts=['--bob']) + txfile = self.get_file_with_ext(ext, no_dot=True) + self.txsend(txfile, bogus_send=False, extra_opts=['--bob']) def split_send_b2x(self): - return self.regtest_send(coin='B2X',ext='533].sigtx') + return self.regtest_send(coin='B2X', ext='533].sigtx') def split_send_btc(self): - return self.regtest_send(coin='BTC',ext='9997].sigtx') + return self.regtest_send(coin='BTC', ext='9997].sigtx') - def split_txdo_timelock(self,coin,locktime,bad_locktime): + def split_txdo_timelock(self, coin, locktime, bad_locktime): self.coin = coin sid = self.regtest_user_sid('bob') self.regtest_user_txdo( @@ -144,10 +144,10 @@ class CmdTestChainsplit(CmdTestRegtest): bad_locktime = bad_locktime) def split_txdo_timelock_bad_btc(self): - self.regtest_txdo_timelock('BTC',locktime=8888,bad_locktime=True) + self.regtest_txdo_timelock('BTC', locktime=8888, bad_locktime=True) def split_txdo_timelock_good_btc(self): - self.regtest_txdo_timelock('BTC',locktime=1321009871,bad_locktime=False) + self.regtest_txdo_timelock('BTC', locktime=1321009871, bad_locktime=False) def split_txdo_timelock_bad_b2x(self): - self.regtest_txdo_timelock('B2X',locktime=8888,bad_locktime=True) + self.regtest_txdo_timelock('B2X', locktime=8888, bad_locktime=True) def split_txdo_timelock_good_b2x(self): - self.regtest_txdo_timelock('B2X',locktime=1321009871,bad_locktime=False) + self.regtest_txdo_timelock('B2X', locktime=1321009871, bad_locktime=False) diff --git a/test/cmdtest_py_d/ct_ethdev.py b/test/cmdtest_py_d/ct_ethdev.py index 85cfe37e..3c071d0c 100755 --- a/test/cmdtest_py_d/ct_ethdev.py +++ b/test/cmdtest_py_d/ct_ethdev.py @@ -20,14 +20,14 @@ test.cmdtest_py_d.ct_ethdev: Ethdev tests for the cmdtest.py test suite """ -import sys,os,re,shutil,asyncio,json +import sys, os, re, shutil, asyncio, json from decimal import Decimal from collections import namedtuple -from subprocess import run,PIPE,DEVNULL +from subprocess import run, PIPE, DEVNULL from pathlib import Path -from mmgen.color import yellow,blue,cyan,set_vt100 -from mmgen.util import msg,rmsg,die +from mmgen.color import yellow, blue, cyan, set_vt100 +from mmgen.util import msg, rmsg, die from ..include.common import ( cfg, @@ -59,7 +59,7 @@ from .common import ( from .ct_base import CmdTestBase from .ct_shared import CmdTestShared -del_addrs = ('4','1') +del_addrs = ('4', '1') dfl_sid = '98831F3A' # The OpenEthereum dev address with lots of coins. Create with "ethkey -b info ''": @@ -97,72 +97,72 @@ def set_vbals(daemon_id): vbal9 = '1.226261' bals = lambda k: { - '1': [ ('98831F3A:E:1','123.456')], - '2': [ ('98831F3A:E:1','123.456'),('98831F3A:E:11','1.234')], - '3': [ ('98831F3A:E:1','123.456'),('98831F3A:E:11','1.234'),('98831F3A:E:21','2.345')], - '4': [ ('98831F3A:E:1','100'), - ('98831F3A:E:2','23.45495'), - ('98831F3A:E:11','1.234'), - ('98831F3A:E:21','2.345')], - '5': [ ('98831F3A:E:1','100'), - ('98831F3A:E:2','23.45495'), - ('98831F3A:E:11','1.234'), - ('98831F3A:E:21','2.345'), - (burn_addr + r'\s+non-MMGen',amt1)], - '8': [ ('98831F3A:E:1','0'), - ('98831F3A:E:2','23.45495'), - ('98831F3A:E:11',vbal1), - ('98831F3A:E:12','99.99895'), - ('98831F3A:E:21','2.345'), - (burn_addr + r'\s+non-MMGen',amt1)], - '9': [ ('98831F3A:E:1','0'), - ('98831F3A:E:2','23.45495'), - ('98831F3A:E:11',vbal1), - ('98831F3A:E:12',vbal2), - ('98831F3A:E:21','2.345'), - (burn_addr + r'\s+non-MMGen',amt1)], - '10': [ ('98831F3A:E:1','0'), - ('98831F3A:E:2','23.0218'), - ('98831F3A:E:3','0.4321'), - ('98831F3A:E:11',vbal1), - ('98831F3A:E:12',vbal2), - ('98831F3A:E:21','2.345'), - (burn_addr + r'\s+non-MMGen',amt1)] + '1': [ ('98831F3A:E:1', '123.456')], + '2': [ ('98831F3A:E:1', '123.456'), ('98831F3A:E:11', '1.234')], + '3': [ ('98831F3A:E:1', '123.456'), ('98831F3A:E:11', '1.234'), ('98831F3A:E:21', '2.345')], + '4': [ ('98831F3A:E:1', '100'), + ('98831F3A:E:2', '23.45495'), + ('98831F3A:E:11', '1.234'), + ('98831F3A:E:21', '2.345')], + '5': [ ('98831F3A:E:1', '100'), + ('98831F3A:E:2', '23.45495'), + ('98831F3A:E:11', '1.234'), + ('98831F3A:E:21', '2.345'), + (burn_addr + r'\s+non-MMGen', amt1)], + '8': [ ('98831F3A:E:1', '0'), + ('98831F3A:E:2', '23.45495'), + ('98831F3A:E:11', vbal1), + ('98831F3A:E:12', '99.99895'), + ('98831F3A:E:21', '2.345'), + (burn_addr + r'\s+non-MMGen', amt1)], + '9': [ ('98831F3A:E:1', '0'), + ('98831F3A:E:2', '23.45495'), + ('98831F3A:E:11', vbal1), + ('98831F3A:E:12', vbal2), + ('98831F3A:E:21', '2.345'), + (burn_addr + r'\s+non-MMGen', amt1)], + '10': [ ('98831F3A:E:1', '0'), + ('98831F3A:E:2', '23.0218'), + ('98831F3A:E:3', '0.4321'), + ('98831F3A:E:11', vbal1), + ('98831F3A:E:12', vbal2), + ('98831F3A:E:21', '2.345'), + (burn_addr + r'\s+non-MMGen', amt1)] }[k] token_bals = lambda k: { - '1': [ ('98831F3A:E:11','1000','1.234')], - '2': [ ('98831F3A:E:11','998.76544',vbal3), - ('98831F3A:E:12','1.23456','0')], - '3': [ ('98831F3A:E:11','110.654317776666555545',vbal1), - ('98831F3A:E:12','1.23456','0')], - '4': [ ('98831F3A:E:11','110.654317776666555545',vbal1), - ('98831F3A:E:12','1.23456','0'), - (burn_addr + r'\s+non-MMGen',amt2,amt1)], - '5': [ ('98831F3A:E:11','110.654317776666555545',vbal1), - ('98831F3A:E:12','1.23456','99.99895'), - (burn_addr + r'\s+non-MMGen',amt2,amt1)], - '6': [ ('98831F3A:E:11','110.654317776666555545',vbal1), - ('98831F3A:E:12','0',vbal2), - ('98831F3A:E:13','1.23456','0'), - (burn_addr + r'\s+non-MMGen',amt2,amt1)], - '7': [ ('98831F3A:E:11','67.444317776666555545',vbal9), - ('98831F3A:E:12','43.21',vbal2), - ('98831F3A:E:13','1.23456','0'), - (burn_addr + r'\s+non-MMGen',amt2,amt1)] + '1': [ ('98831F3A:E:11', '1000', '1.234')], + '2': [ ('98831F3A:E:11', '998.76544', vbal3), + ('98831F3A:E:12', '1.23456', '0')], + '3': [ ('98831F3A:E:11', '110.654317776666555545', vbal1), + ('98831F3A:E:12', '1.23456', '0')], + '4': [ ('98831F3A:E:11', '110.654317776666555545', vbal1), + ('98831F3A:E:12', '1.23456', '0'), + (burn_addr + r'\s+non-MMGen', amt2, amt1)], + '5': [ ('98831F3A:E:11', '110.654317776666555545', vbal1), + ('98831F3A:E:12', '1.23456', '99.99895'), + (burn_addr + r'\s+non-MMGen', amt2, amt1)], + '6': [ ('98831F3A:E:11', '110.654317776666555545', vbal1), + ('98831F3A:E:12', '0', vbal2), + ('98831F3A:E:13', '1.23456', '0'), + (burn_addr + r'\s+non-MMGen', amt2, amt1)], + '7': [ ('98831F3A:E:11', '67.444317776666555545', vbal9), + ('98831F3A:E:12', '43.21', vbal2), + ('98831F3A:E:13', '1.23456', '0'), + (burn_addr + r'\s+non-MMGen', amt2, amt1)] }[k] token_bals_getbalance = lambda k: { - '1': (vbal4,'999999.12345689012345678'), - '2': ('111.888877776666555545','888.111122223333444455') + '1': (vbal4, '999999.12345689012345678'), + '2': ('111.888877776666555545', '888.111122223333444455') }[k] coin = cfg.coin -class CmdTestEthdev(CmdTestBase,CmdTestShared): +class CmdTestEthdev(CmdTestBase, CmdTestShared): 'Ethereum transacting, token deployment and tracking wallet operations' - networks = ('eth','etc') - passthru_opts = ('coin','daemon_id','http_timeout','rpc_backend') + networks = ('eth', 'etc') + passthru_opts = ('coin', 'daemon_id', 'http_timeout', 'rpc_backend') tmpdir_nums = [22] color = True cmd_group_in = ( @@ -268,7 +268,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): ('token_deploy2b', 'deploying ERC20 token #2 (Owned)'), ('token_deploy2c', 'deploying ERC20 token #2 (Token)'), - ('contract_deploy', 'deploying contract (create,sign,send)'), + ('contract_deploy', 'deploying contract (create, sign, send)'), ), 'token': ( 'creating, signing, sending and bumping ERC20 token transactions', @@ -396,8 +396,8 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): ), } - def __init__(self,trunner,cfgs,spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + def __init__(self, trunner, cfgs, spawn): + CmdTestBase.__init__(self, trunner, cfgs, spawn) if trunner is None: return @@ -405,10 +405,10 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): self.eth_args_noquiet = [f'--outdir={self.tmpdir}', '--regtest=1'] from mmgen.protocol import init_proto - self.proto = init_proto( cfg, cfg.coin, network='regtest', need_amt=True ) + self.proto = init_proto( cfg, cfg.coin, network='regtest', need_amt=True) from mmgen.daemon import CoinDaemon - self.daemon = CoinDaemon( cfg, self.proto.coin+'_rt', test_suite=True ) + self.daemon = CoinDaemon( cfg, self.proto.coin+'_rt', test_suite=True) set_vbals(self.daemon.id) @@ -418,12 +418,12 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): omsg(blue(f'Coin daemon {self.daemon.id!r} selected')) - self.genesis_fn = joinpath(self.tmpdir,'genesis.json') - self.keystore_dir = os.path.relpath(joinpath(self.daemon.datadir,'keystore')) + self.genesis_fn = joinpath(self.tmpdir, 'genesis.json') + self.keystore_dir = os.path.relpath(joinpath(self.daemon.datadir, 'keystore')) write_to_file( - joinpath(self.tmpdir,parity_devkey_fn), - dfl_devkey+'\n' ) + joinpath(self.tmpdir, parity_devkey_fn), + dfl_devkey+'\n') self.message = 'attack at dawn' self.spawn_env['MMGEN_BOGUS_SEND'] = '' @@ -431,37 +431,37 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): @property async def rpc(self): from mmgen.rpc import rpc_init - return await rpc_init(cfg,self.proto) + return await rpc_init(cfg, self.proto) async def setup(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) if not self.using_solc: - srcdir = os.path.join(self.tr.repo_root,'test','ref','ethereum','bin') + srcdir = os.path.join(self.tr.repo_root, 'test', 'ref', 'ethereum', 'bin') from shutil import copytree - for d in ('mm1','mm2'): - copytree(os.path.join(srcdir,d),os.path.join(self.tmpdir,d)) + for d in ('mm1', 'mm2'): + copytree(os.path.join(srcdir, d), os.path.join(self.tmpdir, d)) d = self.daemon - if d.id in ('geth','erigon'): + if d.id in ('geth', 'erigon'): self.genesis_setup(d) set_vt100() if d.id == 'erigon': - self.write_to_tmpfile('signer_key',self.keystore_data['key']+'\n') + self.write_to_tmpfile('signer_key', self.keystore_data['key']+'\n') d.usr_coind_args = [ - '--miner.sigfile={}'.format(os.path.join(self.tmpdir,'signer_key')), - '--miner.etherbase={}'.format(self.keystore_data['address']) ] + '--miner.sigfile={}'.format(os.path.join(self.tmpdir, 'signer_key')), + '--miner.etherbase={}'.format(self.keystore_data['address'])] - if d.id in ('geth','erigon'): - imsg(' {:19} {}'.format('Cmdline:',' '.join(e for e in d.start_cmd if not 'verbosity' in e))) + if d.id in ('geth', 'erigon'): + imsg(' {:19} {}'.format('Cmdline:', ' '.join(e for e in d.start_cmd if not 'verbosity' in e))) if not cfg.no_daemon_autostart: - if not d.id in ('geth','erigon'): + if not d.id in ('geth', 'erigon'): d.stop(silent=True) d.remove_datadir() - d.start( silent = not (cfg.verbose or cfg.exact_output) ) + d.start( silent = not (cfg.verbose or cfg.exact_output)) rpc = await self.rpc imsg(f'Daemon: {rpc.daemon.coind_name} v{rpc.daemon_version_str}') @@ -469,36 +469,36 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): @property def keystore_data(self): - if not hasattr(self,'_keystore_data'): + if not hasattr(self, '_keystore_data'): - wallet_fn = os.path.join( self.keystore_dir, os.listdir(self.keystore_dir)[0] ) + wallet_fn = os.path.join( self.keystore_dir, os.listdir(self.keystore_dir)[0]) from mmgen.proto.eth.misc import decrypt_geth_keystore key = decrypt_geth_keystore( cfg = cfg, wallet_fn = wallet_fn, - passwd = b'' ) + passwd = b'') with open(wallet_fn) as fh: res = json.loads(fh.read()) - res.update( { 'key': key.hex() } ) + res.update( { 'key': key.hex()}) self._keystore_data = res return self._keystore_data - def genesis_setup(self,d): + def genesis_setup(self, d): def make_key(): - pwfile = joinpath(self.tmpdir,'account_passwd') - write_to_file(pwfile,'') - run(['rm','-rf',self.keystore_dir]) + pwfile = joinpath(self.tmpdir, 'account_passwd') + write_to_file(pwfile, '') + run(['rm', '-rf', self.keystore_dir]) cmd = f'geth account new --password={pwfile} --lightkdf --keystore {self.keystore_dir}' - cp = run(cmd.split(),stdout=PIPE,stderr=PIPE) + cp = run(cmd.split(), stdout=PIPE, stderr=PIPE) if cp.returncode: - die(1,cp.stderr.decode()) + die(1, cp.stderr.decode()) - def make_genesis(signer_addr,prealloc_addr): + def make_genesis(signer_addr, prealloc_addr): return { 'config': { 'chainId': 1337, # TODO: replace constant with var @@ -534,15 +534,15 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): 'excessBlobGas': None, 'blobGasUsed': None, 'alloc': { - prealloc_addr: { 'balance': hex(prealloc_amt.toWei()) } + prealloc_addr: { 'balance': hex(prealloc_amt.toWei())} } } def init_genesis(fn): cmd = f'{d.exec_fn} init --datadir {d.datadir} {fn}' - cp = run( cmd.split(), stdout=PIPE, stderr=PIPE ) + cp = run( cmd.split(), stdout=PIPE, stderr=PIPE) if cp.returncode: - die(1,cp.stderr.decode()) + die(1, cp.stderr.decode()) d.stop(quiet=True) d.remove_datadir() @@ -553,7 +553,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): make_key() signer_addr = self.keystore_data['address'] - self.write_to_tmpfile( 'signer_addr', signer_addr + '\n' ) + self.write_to_tmpfile( 'signer_addr', signer_addr + '\n') imsg(f' Keystore: {self.keystore_dir}') imsg(f' Signer key: {self.keystore_data["key"]}') @@ -561,8 +561,8 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): imsg(f' Faucet: {dfl_devaddr} ({prealloc_amt} ETH)') imsg(f' Genesis block data: {self.genesis_fn}') - genesis_data = make_genesis(signer_addr,dfl_devaddr) - write_to_file( self.genesis_fn, json.dumps(genesis_data,indent=' ')+'\n' ) + genesis_data = make_genesis(signer_addr, dfl_devaddr) + write_to_file( self.genesis_fn, json.dumps(genesis_data, indent=' ')+'\n') init_genesis(self.genesis_fn) def daemon_version(self): @@ -595,8 +595,8 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): async def wallet_upgrade2(self): return await self._wallet_upgrade('tracking-wallet-v2.json', 'token params field', 'network field') - def addrgen(self,addrs='1-3,11-13,21-23'): - t = self.spawn('mmgen-addrgen', self.eth_args + [dfl_words_file,addrs]) + def addrgen(self, addrs='1-3,11-13,21-23'): + t = self.spawn('mmgen-addrgen', self.eth_args + [dfl_words_file, addrs]) t.written_to_file('Addresses') return t @@ -608,7 +608,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): bad_input = False, exit_val = None): ext = ext.format('-α' if cfg.debug_utf8 else '') - fn = self.get_file_with_ext(ext,no_dot=True,delete=False) + fn = self.get_file_with_ext(ext, no_dot=True, delete=False) t = self.spawn('mmgen-addrimport', ['--regtest=1'] + add_args + [fn], exit_val=exit_val) if bad_input: return t @@ -616,7 +616,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): t.expect(expect) return t - def addrimport_one_addr(self,addr=None,extra_args=[]): + def addrimport_one_addr(self, addr=None, extra_args=[]): t = self.spawn('mmgen-addrimport', ['--regtest=1', '--quiet', f'--address={addr}'] + extra_args) t.expect('OK') return t @@ -634,61 +634,61 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): acct = '1', caller = 'txcreate', interactive_fee = '50G', - fee_info_data = ('0.00105','50'), + fee_info_data = ('0.00105', '50'), no_read = False, print_listing = True, tweaks = []): - fee_info_pat = r'\D{}\D.*{c} .*\D{}\D.*gas price in Gwei'.format( *fee_info_data, c=self.proto.coin ) + fee_info_pat = r'\D{}\D.*{c} .*\D{}\D.*gas price in Gwei'.format(*fee_info_data, c=self.proto.coin) t = self.spawn(f'mmgen-{caller}', self.eth_args + ['-B'] + args) if print_listing: - t.expect(r'add \[l\]abel, .*?:.','p', regex=True) + t.expect(r'add \[l\]abel, .*?:.', 'p', regex=True) t.written_to_file('Account balances listing') t = self.txcreate_ui_common( - t, - menu = menu, - caller = caller, - input_sels_prompt = 'to spend from', - inputs = acct, - file_desc = 'transaction', - bad_input_sels = True, - interactive_fee = interactive_fee, - fee_info_pat = fee_info_pat, - fee_desc = 'transaction fee or gas price', - add_comment = tx_comment_jp, - tweaks = tweaks) + t, + menu = menu, + caller = caller, + input_sels_prompt = 'to spend from', + inputs = acct, + file_desc = 'transaction', + bad_input_sels = True, + interactive_fee = interactive_fee, + fee_info_pat = fee_info_pat, + fee_desc = 'transaction fee or gas price', + add_comment = tx_comment_jp, + tweaks = tweaks) if not no_read: t.read() return t - def txsign(self,ni=False,ext='{}.regtest.rawtx',add_args=[],dev_send=False): + def txsign(self, ni=False, ext='{}.regtest.rawtx', add_args=[], dev_send=False): ext = ext.format('-α' if cfg.debug_utf8 else '') - keyfile = joinpath(self.tmpdir,parity_devkey_fn) - txfile = self.get_file_with_ext(ext,no_dot=True) + keyfile = joinpath(self.tmpdir, parity_devkey_fn) + txfile = self.get_file_with_ext(ext, no_dot=True) t = self.spawn( - 'mmgen-txsign', - self.eth_args - + [f'--coin={self.proto.coin}'] - + ['--rpc-host=bad_host'] # ETH signing must work without RPC - + add_args - + ([],['--yes'])[ni] - + ([f'--keys-from-file={keyfile}'] if dev_send else []) - + [txfile, dfl_words_file]) - return self.txsign_ui_common(t,ni=ni,has_label=True) + 'mmgen-txsign', + self.eth_args + + [f'--coin={self.proto.coin}'] + + ['--rpc-host=bad_host'] # ETH signing must work without RPC + + add_args + + ([], ['--yes'])[ni] + + ([f'--keys-from-file={keyfile}'] if dev_send else []) + + [txfile, dfl_words_file]) + return self.txsign_ui_common(t, ni=ni, has_label=True) - def txsend(self,ext='{}.regtest.sigtx',add_args=[]): + def txsend(self, ext='{}.regtest.sigtx', add_args=[]): ext = ext.format('-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,no_dot=True) + txfile = self.get_file_with_ext(ext, no_dot=True) t = self.spawn('mmgen-txsend', self.eth_args + add_args + [txfile]) self.txsend_ui_common( - t, - quiet = not cfg.debug, - bogus_send = False, - has_label = True) + t, + quiet = not cfg.debug, + bogus_send = False, + has_label = True) return t - def txview(self,ext_fs): + def txview(self, ext_fs): ext = ext_fs.format('-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,no_dot=True) + txfile = self.get_file_with_ext(ext, no_dot=True) return self.spawn('mmgen-tool', ['--verbose', 'txview', txfile]) def fund_dev_address(self): @@ -696,35 +696,35 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): For Erigon, fund the default (Parity) dev address from the Erigon dev address For the others, send a junk TX to keep block counts equal for all daemons """ - dt = namedtuple('data',['devkey_fn','dest','amt']) - d = dt( parity_devkey_fn, burn_addr2, '1' ) + dt = namedtuple('data', ['devkey_fn', 'dest', 'amt']) + d = dt(parity_devkey_fn, burn_addr2, '1') t = self.txcreate( args = self.eth_args_noquiet + [ - f'--keys-from-file={joinpath(self.tmpdir,d.devkey_fn)}', + f'--keys-from-file={joinpath(self.tmpdir, d.devkey_fn)}', f'{d.dest},{d.amt}', ], - menu = ['a','r'], + menu = ['a', 'r'], caller = 'txdo', acct = '1', - no_read = True ) - self._do_confirm_send(t,quiet=not cfg.debug,sure=False) + no_read = True) + self._do_confirm_send(t, quiet=not cfg.debug, sure=False) t.read() - self.get_file_with_ext('sigtx',delete_all=True) + self.get_file_with_ext('sigtx', delete_all=True) return t def txcreate1(self): # include one invalid keypress 'X' -- see EthereumTwUnspentOutputs.key_mappings - menu = ['a','d','r','M','X','e','m','m'] + menu = ['a', 'd', 'r', 'M', 'X', 'e', 'm', 'm'] args = ['98831F3A:E:1,123.456'] - return self.txcreate(args=args,menu=menu,acct='1',tweaks=['confirm_non_mmgen']) + return self.txcreate(args=args, menu=menu, acct='1', tweaks=['confirm_non_mmgen']) def txview1_raw(self): return self.txview(ext_fs='{}.regtest.rawtx') def txsign1(self): - return self.txsign(add_args=['--use-internal-keccak-module'],dev_send=True) + return self.txsign(add_args=['--use-internal-keccak-module'], dev_send=True) def tx_status0_bad(self): - return self.tx_status(ext='{}.regtest.sigtx',expect_str='neither in mempool nor blockchain',exit_val=1) + return self.tx_status(ext='{}.regtest.sigtx', expect_str='neither in mempool nor blockchain', exit_val=1) def txsign1_ni(self): - return self.txsign(ni=True,dev_send=True) + return self.txsign(ni=True, dev_send=True) def txsend1(self): return self.txsend() def txview1_sig(self): # do after send so that TxID is displayed @@ -734,9 +734,9 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def txcreate2(self): args = ['98831F3A:E:11,1.234'] - return self.txcreate(args=args,acct='10',tweaks=['confirm_non_mmgen']) + return self.txcreate(args=args, acct='10', tweaks=['confirm_non_mmgen']) def txsign2(self): - return self.txsign(ni=True,ext='1.234,50000]{}.regtest.rawtx',dev_send=True) + return self.txsign(ni=True, ext='1.234,50000]{}.regtest.rawtx', dev_send=True) def txsend2(self): return self.txsend(ext='1.234,50000]{}.regtest.sigtx') def bal2(self): @@ -744,31 +744,31 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def txcreate3(self): args = ['98831F3A:E:21,2.345'] - return self.txcreate(args=args,acct='10',tweaks=['confirm_non_mmgen']) + return self.txcreate(args=args, acct='10', tweaks=['confirm_non_mmgen']) def txsign3(self): - return self.txsign(ni=True,ext='2.345,50000]{}.regtest.rawtx',dev_send=True) + return self.txsign(ni=True, ext='2.345,50000]{}.regtest.rawtx', dev_send=True) def txsend3(self): return self.txsend(ext='2.345,50000]{}.regtest.sigtx') def bal3(self): return self.bal(n='3') - def tx_status(self,ext,expect_str,expect_str2='',add_args=[],exit_val=0): + def tx_status(self, ext, expect_str, expect_str2='', add_args=[], exit_val=0): ext = ext.format('-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,no_dot=True) + txfile = self.get_file_with_ext(ext, no_dot=True) t = self.spawn( - 'mmgen-txsend', - self.eth_args + add_args + ['--status', txfile], - exit_val = exit_val) + 'mmgen-txsend', + self.eth_args + add_args + ['--status', txfile], + exit_val = exit_val) t.expect(expect_str) if expect_str2: t.expect(expect_str2) return t def tx_status1(self): - return self.tx_status(ext='2.345,50000]{}.regtest.sigtx',expect_str='has 1 confirmation') + return self.tx_status(ext='2.345,50000]{}.regtest.sigtx', expect_str='has 1 confirmation') def tx_status1a(self): - return self.tx_status(ext='2.345,50000]{}.regtest.sigtx',expect_str='has 2 confirmations') + return self.tx_status(ext='2.345,50000]{}.regtest.sigtx', expect_str='has 2 confirmations') async def msgsign_chk(self): # NB: Geth only! @@ -776,7 +776,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): key = self.keystore_data['key'] imsg(f'Key: {key}') from mmgen.proto.eth.misc import ec_sign_message_with_privkey - return ec_sign_message_with_privkey(cfg,self.message,bytes.fromhex(key),'eth_sign') + return ec_sign_message_with_privkey(cfg, self.message, bytes.fromhex(key), 'eth_sign') async def create_signature_rpc(): addr = self.read_from_tmpfile('signer_addr').strip() @@ -785,12 +785,12 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): return await rpc.call( 'eth_sign', '0x' + addr, - '0x' + self.message.encode().hex() ) + '0x' + self.message.encode().hex()) if not self.daemon.id == 'geth': return 'skip' - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) sig = '0x' + create_signature_mmgen() sig_chk = await create_signature_rpc() @@ -798,75 +798,75 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): # Compare signatures imsg(f'Message: {self.message}') imsg(f'Signature: {sig}') - cmp_or_die(sig,sig_chk,'message signatures') + cmp_or_die(sig, sig_chk, 'message signatures') imsg('Geth and MMGen signatures match') return 'ok' - def msgcreate(self,add_args=[]): + def msgcreate(self, add_args=[]): t = self.spawn('mmgen-msg', self.eth_args_noquiet + add_args + ['create', self.message, '98831F3A:E:1']) t.written_to_file('Unsigned message data') return t def msgsign(self): - fn = get_file_with_ext(self.tmpdir,'rawmsg.json') + fn = get_file_with_ext(self.tmpdir, 'rawmsg.json') t = self.spawn('mmgen-msg', self.eth_args_noquiet + ['sign', fn, dfl_words_file]) t.written_to_file('Signed message data') return t - def msgverify(self,fn=None,msghash_type='eth_sign'): - fn = fn or get_file_with_ext(self.tmpdir,'sigmsg.json') + def msgverify(self, fn=None, msghash_type='eth_sign'): + fn = fn or get_file_with_ext(self.tmpdir, 'sigmsg.json') t = self.spawn('mmgen-msg', self.eth_args_noquiet + ['verify', fn]) t.expect(msghash_type) t.expect('1 signature verified') return t def msgexport(self): - fn = get_file_with_ext(self.tmpdir,'sigmsg.json') + fn = get_file_with_ext(self.tmpdir, 'sigmsg.json') t = self.spawn('mmgen-msg', self.eth_args_noquiet + ['export', fn]) t.written_to_file('Signature data') return t def msgverify_export(self): return self.msgverify( - fn = os.path.join(self.tmpdir,'signatures.json') ) + fn = os.path.join(self.tmpdir, 'signatures.json')) def msgcreate_raw(self): - get_file_with_ext(self.tmpdir,'rawmsg.json',delete_all=True) + get_file_with_ext(self.tmpdir, 'rawmsg.json', delete_all=True) return self.msgcreate(add_args=['--msghash-type=raw']) def msgsign_raw(self): - get_file_with_ext(self.tmpdir,'sigmsg.json',delete_all=True) + get_file_with_ext(self.tmpdir, 'sigmsg.json', delete_all=True) return self.msgsign() def msgverify_raw(self): return self.msgverify(msghash_type='raw') def msgexport_raw(self): - get_file_with_ext(self.tmpdir,'signatures.json',no_dot=True,delete_all=True) + get_file_with_ext(self.tmpdir, 'signatures.json', no_dot=True, delete_all=True) return self.msgexport() def msgverify_export_raw(self): return self.msgverify( - fn = os.path.join(self.tmpdir,'signatures.json'), - msghash_type = 'raw' ) + fn = os.path.join(self.tmpdir, 'signatures.json'), + msghash_type = 'raw') def txcreate4(self): return self.txcreate( args = ['98831F3A:E:2,23.45495'], acct = '1', interactive_fee = '40G', - fee_info_data = ('0.00084','40') ) + fee_info_data = ('0.00084', '40')) - def txbump(self,ext=',40000]{}.regtest.rawtx',fee='50G',add_args=[]): + def txbump(self, ext=',40000]{}.regtest.rawtx', fee='50G', add_args=[]): ext = ext.format('-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,no_dot=True) - t = self.spawn('mmgen-txbump', self.eth_args + add_args + ['--yes',txfile]) - t.expect('or gas price: ',fee+'\n') + txfile = self.get_file_with_ext(ext, no_dot=True) + t = self.spawn('mmgen-txbump', self.eth_args + add_args + ['--yes', txfile]) + t.expect('or gas price: ', fee+'\n') return t def txsign4(self): - return self.txsign(ni=True,ext='.45495,50000]{}.regtest.rawtx',dev_send=True) + return self.txsign(ni=True, ext='.45495,50000]{}.regtest.rawtx', dev_send=True) def txsend4(self): return self.txsend(ext='.45495,50000]{}.regtest.sigtx') def bal4(self): @@ -874,53 +874,53 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def txcreate5(self): args = [burn_addr + ','+amt1] - return self.txcreate(args=args,acct='10',tweaks=['confirm_non_mmgen']) + return self.txcreate(args=args, acct='10', tweaks=['confirm_non_mmgen']) def txsign5(self): - return self.txsign(ni=True,ext=amt1+',50000]{}.regtest.rawtx',dev_send=True) + return self.txsign(ni=True, ext=amt1+',50000]{}.regtest.rawtx', dev_send=True) def txsend5(self): return self.txsend(ext=amt1+',50000]{}.regtest.sigtx') def bal5(self): return self.bal(n='5') - def bal(self,n): - t = self.spawn('mmgen-tool', self.eth_args + ['twview','wide=1']) + def bal(self, n): + t = self.spawn('mmgen-tool', self.eth_args + ['twview', 'wide=1']) text = t.read(strip_color=True) - for addr,amt in bals(n): - pat = r'\D{}\D.*\D{}\D'.format( addr, amt.replace('.',r'\.') ) - assert re.search(pat,text), pat + for addr, amt in bals(n): + pat = r'\D{}\D.*\D{}\D'.format(addr, amt.replace('.', r'\.')) + assert re.search(pat, text), pat ss = f'Total {self.proto.coin}:' - assert re.search(ss,text),ss + assert re.search(ss, text), ss return t - def token_bal(self,n=None): - t = self.spawn('mmgen-tool', self.eth_args + ['--token=mm1','twview','wide=1']) + def token_bal(self, n=None): + t = self.spawn('mmgen-tool', self.eth_args + ['--token=mm1', 'twview', 'wide=1']) text = t.read(strip_color=True) - for addr,_amt1,_amt2 in token_bals(n): + for addr, _amt1, _amt2 in token_bals(n): pat = fr'{addr}\b.*\D{_amt1}\D.*\b{_amt2}\D' - assert re.search(pat,text), pat + assert re.search(pat, text), pat ss = 'Total MM1:' - assert re.search(ss,text),ss + assert re.search(ss, text), ss return t - def bal_getbalance(self,sid,idx,etc_adj=False,extra_args=[]): + def bal_getbalance(self, sid, idx, etc_adj=False, extra_args=[]): bal1 = token_bals_getbalance(idx)[0] bal2 = token_bals_getbalance(idx)[1] bal1 = Decimal(bal1) t = self.spawn('mmgen-tool', self.eth_args + extra_args + ['getbalance']) - t.expect(rf'{sid}:.*'+str(bal1),regex=True) - t.expect(r'Non-MMGen:.*'+bal2,regex=True) + t.expect(rf'{sid}:.*'+str(bal1), regex=True) + t.expect(r'Non-MMGen:.*'+bal2, regex=True) total = strip_ansi_escapes(t.expect_getend(rf'TOTAL {self.proto.coin}')).split()[0] assert Decimal(bal1) + Decimal(bal2) == Decimal(total) return t - def add_comment(self,comment,addr='98831F3A:E:3'): - t = self.spawn('mmgen-tool', self.eth_args + ['add_label',addr,comment]) - t.expect('Added label.*in tracking wallet',regex=True) + def add_comment(self, comment, addr='98831F3A:E:3'): + t = self.spawn('mmgen-tool', self.eth_args + ['add_label', addr, comment]) + t.expect('Added label.*in tracking wallet', regex=True) return t - def chk_comment(self,comment_pat,addr='98831F3A:E:3'): - t = self.spawn('mmgen-tool', self.eth_args + ['listaddresses','all_labels=1']) - t.expect(fr'{addr}\b.*{comment_pat}',regex=True) + def chk_comment(self, comment_pat, addr='98831F3A:E:3'): + t = self.spawn('mmgen-tool', self.eth_args + ['listaddresses', 'all_labels=1']) + t.expect(fr'{addr}\b.*{comment_pat}', regex=True) return t def add_comment1(self): @@ -932,19 +932,19 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def chk_comment2(self): return self.chk_comment(comment_pat=tw_comment_lat_cyr_gr[:3]) - def remove_comment(self,addr='98831F3A:E:3'): - t = self.spawn('mmgen-tool', self.eth_args + ['remove_label',addr]) - t.expect('Removed label.*in tracking wallet',regex=True) + def remove_comment(self, addr='98831F3A:E:3'): + t = self.spawn('mmgen-tool', self.eth_args + ['remove_label', addr]) + t.expect('Removed label.*in tracking wallet', regex=True) return t - def token_compile(self,token_data={}): - odir = joinpath(self.tmpdir,token_data['symbol'].lower()) + def token_compile(self, token_data={}): + odir = joinpath(self.tmpdir, token_data['symbol'].lower()) if not self.using_solc: imsg(f'Using precompiled contract data in {odir}') return 'skip' if os.path.exists(odir) else False - self.spawn('',msg_only=True) - cmd_args = [f'--{k}={v}' for k,v in list(token_data.items())] - imsg("Compiling solidity token contract '{}' with 'solc'".format( token_data['symbol'] )) + self.spawn('', msg_only=True) + cmd_args = [f'--{k}={v}' for k, v in list(token_data.items())] + imsg("Compiling solidity token contract '{}' with 'solc'".format(token_data['symbol'])) try: os.mkdir(odir) except: @@ -955,27 +955,27 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): '--coin=' + self.proto.coin, '--outdir=' + odir ] + cmd_args + [self.proto.checksummed_addr(dfl_devaddr)] - imsg('Executing: {}'.format( ' '.join(cmd) )) - cp = run(cmd,stdout=DEVNULL,stderr=PIPE) + imsg('Executing: {}'.format(' '.join(cmd))) + cp = run(cmd, stdout=DEVNULL, stderr=PIPE) if cp.returncode != 0: rmsg('solc failed with the following output:') - die(2,cp.stderr.decode()) - imsg('ERC20 token {!r} compiled'.format( token_data['symbol'] )) + die(2, cp.stderr.decode()) + imsg('ERC20 token {!r} compiled'.format(token_data['symbol'])) return 'ok' def token_compile1(self): - token_data = { 'name':'MMGen Token 1', 'symbol':'MM1', 'supply':10**26, 'decimals':18 } + token_data = {'name':'MMGen Token 1', 'symbol':'MM1', 'supply':10**26, 'decimals':18} return self.token_compile(token_data) def token_compile2(self): - token_data = { 'name':'MMGen Token 2', 'symbol':'MM2', 'supply':10**18, 'decimals':10 } + token_data = {'name':'MMGen Token 2', 'symbol':'MM2', 'supply':10**18, 'decimals':10} return self.token_compile(token_data) - async def get_tx_receipt(self,txid): + async def get_tx_receipt(self, txid): if self.daemon.id == 'geth': # yet another Geth bug await asyncio.sleep(0.5) from mmgen.tx import NewTX - tx = await NewTX(cfg=cfg,proto=self.proto) + tx = await NewTX(cfg=cfg, proto=self.proto) tx.rpc = await self.rpc res = await tx.get_receipt(txid) imsg(f'Gas sent: {res.gas_sent.hl():<9} {(res.gas_sent*res.gas_price).hl2(encl="()")}') @@ -985,9 +985,9 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): omsg(yellow('Warning: all gas was used!')) return res - async def token_deploy(self,num,key,gas,mmgen_cmd='txdo',tx_fee='8G'): - keyfile = joinpath(self.tmpdir,parity_devkey_fn) - fn = joinpath(self.tmpdir,'mm'+str(num),key+'.bin') + async def token_deploy(self, num, key, gas, mmgen_cmd='txdo', tx_fee='8G'): + keyfile = joinpath(self.tmpdir, parity_devkey_fn) + fn = joinpath(self.tmpdir, 'mm'+str(num), key+'.bin') args = [ '-B', f'--fee={tx_fee}', @@ -997,35 +997,35 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): '--yes', ] if mmgen_cmd == 'txdo': - args += ['-k',keyfile] - t = self.spawn( 'mmgen-'+mmgen_cmd, self.eth_args + args) + args += ['-k', keyfile] + t = self.spawn('mmgen-'+mmgen_cmd, self.eth_args + args) if mmgen_cmd == 'txcreate': t.written_to_file('transaction') ext = '[0,8000]{}.regtest.rawtx'.format('-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,no_dot=True) - t = self.spawn('mmgen-txsign', self.eth_args + ['--yes','-k',keyfile,txfile],no_msg=True) - self.txsign_ui_common(t,ni=True) - txfile = txfile.replace('.rawtx','.sigtx') - t = self.spawn('mmgen-txsend', self.eth_args + [txfile],no_msg=True) + txfile = self.get_file_with_ext(ext, no_dot=True) + t = self.spawn('mmgen-txsign', self.eth_args + ['--yes', '-k', keyfile, txfile], no_msg=True) + self.txsign_ui_common(t, ni=True) + txfile = txfile.replace('.rawtx', '.sigtx') + t = self.spawn('mmgen-txsend', self.eth_args + [txfile], no_msg=True) txid = self.txsend_ui_common(t, caller = mmgen_cmd, quiet = mmgen_cmd == 'txdo' or not cfg.debug, - bogus_send = False ) + bogus_send = False) addr = strip_ansi_escapes(t.expect_getend('Contract address: ')) if (await self.get_tx_receipt(txid)).status == 0: - die(2,f'Contract {num}:{key} failed to execute. Aborting') + die(2, f'Contract {num}:{key} failed to execute. Aborting') if key == 'Token': - self.write_to_tmpfile( f'token_addr{num}', addr+'\n' ) + self.write_to_tmpfile(f'token_addr{num}', addr+'\n') imsg(f'\nToken MM{num} deployed!') return t async def token_deploy1a(self): - return await self.token_deploy(num=1,key='SafeMath',gas=500_000) + return await self.token_deploy(num=1, key='SafeMath', gas=500_000) async def token_deploy1b(self): - return await self.token_deploy(num=1,key='Owned', gas=1_000_000) + return await self.token_deploy(num=1, key='Owned', gas=1_000_000) async def token_deploy1c(self): - return await self.token_deploy(num=1,key='Token', gas=4_000_000,tx_fee='7G') + return await self.token_deploy(num=1, key='Token', gas=4_000_000, tx_fee='7G') def tx_status2(self): return self.tx_status( @@ -1036,20 +1036,20 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): return self.bal5() async def token_deploy2a(self): - return await self.token_deploy(num=2,key='SafeMath',gas=500_000) + return await self.token_deploy(num=2, key='SafeMath', gas=500_000) async def token_deploy2b(self): - return await self.token_deploy(num=2,key='Owned', gas=1_000_000) + return await self.token_deploy(num=2, key='Owned', gas=1_000_000) async def token_deploy2c(self): - return await self.token_deploy(num=2,key='Token', gas=4_000_000) + return await self.token_deploy(num=2, key='Token', gas=4_000_000) - async def contract_deploy(self): # test create,sign,send - return await self.token_deploy(num=2,key='SafeMath',gas=500_000,mmgen_cmd='txcreate') + async def contract_deploy(self): # test create, sign, send + return await self.token_deploy(num=2, key='SafeMath', gas=500_000, mmgen_cmd='txcreate') - async def token_transfer_ops(self,op,amt=1000,num_tokens=2): - self.spawn('',msg_only=True) + async def token_transfer_ops(self, op, amt=1000, num_tokens=2): + self.spawn('', msg_only=True) sid = dfl_sid from mmgen.tool.wallet import tool_cmd - usr_mmaddrs = [f'{sid}:E:{i}' for i in (11,21)][:num_tokens] + usr_mmaddrs = [f'{sid}:E:{i}' for i in (11, 21)][:num_tokens] from mmgen.proto.eth.contract import ResolvedToken async def do_transfer(rpc): @@ -1058,9 +1058,9 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): cfg, self.proto, rpc, - self.read_from_tmpfile(f'token_addr{i+1}').strip() ) - imsg_r( '\n' + await tk.info() ) - imsg('dev token balance (pre-send): {}'.format( await tk.get_balance(dfl_devaddr) )) + self.read_from_tmpfile(f'token_addr{i+1}').strip()) + imsg_r('\n' + await tk.info()) + imsg('dev token balance (pre-send): {}'.format(await tk.get_balance(dfl_devaddr))) imsg(f'Sending {amt} {self.proto.dcoin} to address {usr_addrs[i]} ({usr_mmaddrs[i]})') txid = await tk.transfer( dfl_devaddr, @@ -1070,7 +1070,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): start_gas = self.proto.coin_amt(60000, from_unit='wei'), gasPrice = self.proto.coin_amt(8, from_unit='Gwei')) if (await self.get_tx_receipt(txid)).status == 0: - die(2,'Transfer of token funds failed. Aborting') + die(2, 'Transfer of token funds failed. Aborting') async def show_bals(rpc): for i in range(num_tokens): @@ -1078,19 +1078,19 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): cfg, self.proto, rpc, - self.read_from_tmpfile(f'token_addr{i+1}').strip() ) - imsg('Token: {}'.format( await tk.get_symbol() )) + self.read_from_tmpfile(f'token_addr{i+1}').strip()) + imsg('Token: {}'.format(await tk.get_symbol())) imsg(f'dev token balance: {await tk.get_balance(dfl_devaddr)}') imsg('usr token balance: {} ({} {})'.format( await tk.get_balance(usr_addrs[i]), usr_mmaddrs[i], - usr_addrs[i] )) + usr_addrs[i])) def gen_addr(addr): - return tool_cmd(cfg,cmdname='gen_addr',proto=self.proto).gen_addr(addr,dfl_words_file) + return tool_cmd(cfg, cmdname='gen_addr', proto=self.proto).gen_addr(addr, dfl_words_file) silence() - usr_addrs = list(map(gen_addr,usr_mmaddrs)) + usr_addrs = list(map(gen_addr, usr_mmaddrs)) if op == 'show_bals': await show_bals(await self.rpc) elif op == 'do_transfer': @@ -1104,7 +1104,7 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def token_user_bals(self): return self.token_transfer_ops(op='show_bals') - def token_addrgen(self,num_tokens=2): + def token_addrgen(self, num_tokens=2): t = self.addrgen(addrs='11-13') if num_tokens == 1: return t @@ -1129,34 +1129,34 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): t.expect('could not be resolved') return t - def token_addrimport(self,addr_file,addr_range,expect,extra_args=[]): + def token_addrimport(self, addr_file, addr_range, expect, extra_args=[]): token_addr = self.read_from_tmpfile(addr_file).strip() return self.addrimport( ext = f'[{addr_range}]{{}}.regtest.addrs', expect = expect, - add_args = ['--token-addr='+token_addr]+extra_args ) + add_args = ['--token-addr='+token_addr]+extra_args) def token_addrimport_addr1(self): - return self.token_addrimport('token_addr1','11-13',expect='3/3') + return self.token_addrimport('token_addr1', '11-13', expect='3/3') def token_addrimport_addr2(self): - return self.token_addrimport('token_addr2','21-23',expect='3/3') + return self.token_addrimport('token_addr2', '21-23', expect='3/3') def token_addrimport_batch(self): - return self.token_addrimport('token_addr1','11-13',expect='3 addresses',extra_args=['--batch']) + return self.token_addrimport('token_addr1', '11-13', expect='3 addresses', extra_args=['--batch']) def token_addrimport_sym(self): return self.addrimport( ext = '[21-23]{}.regtest.addrs', expect = '3/3', - add_args = ['--token=MM2'] ) + add_args = ['--token=MM2']) def bal7(self): return self.bal5() def token_bal1(self): return self.token_bal(n='1') - def token_txcreate(self,args=[],token='',inputs='1',fee='50G',file_desc='Unsigned transaction'): + def token_txcreate(self, args=[], token='', inputs='1', fee='50G', file_desc='Unsigned transaction'): return self.txcreate_ui_common( self.spawn('mmgen-txcreate', self.eth_args + [f'--token={token}', '-B', f'--fee={fee}'] + args), menu = [], @@ -1164,19 +1164,19 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): input_sels_prompt = 'to spend from', add_comment = tx_comment_lat_cyr_gr, file_desc = file_desc) - def token_txsign(self,ext='',token=''): - return self.txsign(ni=True,ext=ext,add_args=['--token='+token]) - def token_txsend(self,ext='',token=''): - return self.txsend(ext=ext,add_args=['--token='+token]) + def token_txsign(self, ext='', token=''): + return self.txsign(ni=True, ext=ext, add_args=['--token='+token]) + def token_txsend(self, ext='', token=''): + return self.txsend(ext=ext, add_args=['--token='+token]) def token_txcreate1(self): - return self.token_txcreate(args=['98831F3A:E:12,1.23456'],token='mm1') + return self.token_txcreate(args=['98831F3A:E:12,1.23456'], token='mm1') def token_txview1_raw(self): return self.txview(ext_fs='1.23456,50000]{}.regtest.rawtx') def token_txsign1(self): - return self.token_txsign(ext='1.23456,50000]{}.regtest.rawtx',token='mm1') + return self.token_txsign(ext='1.23456,50000]{}.regtest.rawtx', token='mm1') def token_txsend1(self): - return self.token_txsend(ext='1.23456,50000]{}.regtest.sigtx',token='mm1') + return self.token_txsend(ext='1.23456,50000]{}.regtest.sigtx', token='mm1') def token_txview1_sig(self): return self.txview(ext_fs='1.23456,50000]{}.regtest.sigtx') @@ -1185,25 +1185,25 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): ext = '1.23456,50000]{}.regtest.sigtx', add_args = ['--token=mm1'], expect_str = 'successfully executed', - expect_str2 = 'has 1 confirmation' ) + expect_str2 = 'has 1 confirmation') def token_bal2(self): return self.token_bal(n='2') - def twview(self,args=[],expect_str='',tool_args=[]): + def twview(self, args=[], expect_str='', tool_args=[]): t = self.spawn('mmgen-tool', self.eth_args + args + ['twview'] + tool_args) if expect_str: - t.expect(expect_str,regex=True) + t.expect(expect_str, regex=True) return t def token_txcreate2(self): - return self.token_txcreate(args=[burn_addr+','+amt2],token='mm1') + return self.token_txcreate(args=[burn_addr+', '+amt2], token='mm1') def token_txbump(self): - return self.txbump(ext=amt2+',50000]{}.regtest.rawtx',fee='56G',add_args=['--token=mm1']) + return self.txbump(ext=amt2+',50000]{}.regtest.rawtx', fee='56G', add_args=['--token=mm1']) def token_txsign2(self): - return self.token_txsign(ext=amt2+',50000]{}.regtest.rawtx',token='mm1') + return self.token_txsign(ext=amt2+',50000]{}.regtest.rawtx', token='mm1') def token_txsend2(self): - return self.token_txsend(ext=amt2+',50000]{}.regtest.sigtx',token='mm1') + return self.token_txsend(ext=amt2+',50000]{}.regtest.sigtx', token='mm1') def token_bal3(self): return self.token_bal(n='3') @@ -1214,16 +1214,16 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): return t def bal1_getbalance(self): - return self.bal_getbalance(dfl_sid,'1',etc_adj=True) + return self.bal_getbalance(dfl_sid, '1', etc_adj=True) def addrimport_token_burn_addr(self): - return self.addrimport_one_addr(addr=burn_addr,extra_args=['--token=mm1']) + return self.addrimport_one_addr(addr=burn_addr, extra_args=['--token=mm1']) def token_bal4(self): return self.token_bal(n='4') def token_bal_getbalance(self): - return self.bal_getbalance(dfl_sid,'2',extra_args=['--token=mm1']) + return self.bal_getbalance(dfl_sid, '2', extra_args=['--token=mm1']) def txcreate_noamt(self): return self.txcreate(args=['98831F3A:E:12']) @@ -1238,18 +1238,18 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): return self.token_bal(n='5') def token_txcreate_noamt(self): - return self.token_txcreate(args=['98831F3A:E:13'],token='mm1',inputs='2',fee='51G') + return self.token_txcreate(args=['98831F3A:E:13'], token='mm1', inputs='2', fee='51G') def token_txsign_noamt(self): - return self.token_txsign(ext='1.23456,51000]{}.regtest.rawtx',token='mm1') + return self.token_txsign(ext='1.23456,51000]{}.regtest.rawtx', token='mm1') def token_txsend_noamt(self): - return self.token_txsend(ext='1.23456,51000]{}.regtest.sigtx',token='mm1') + return self.token_txsend(ext='1.23456,51000]{}.regtest.sigtx', token='mm1') def bal9(self): return self.bal(n='9') def token_bal6(self): return self.token_bal(n='6') - def listaddresses(self,args=[],tool_args=['all_labels=1']): + def listaddresses(self, args=[], tool_args=['all_labels=1']): return self.spawn('mmgen-tool', self.eth_args + args + ['listaddresses'] + tool_args) def listaddresses1(self): @@ -1257,65 +1257,65 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def listaddresses2(self): return self.listaddresses(tool_args=['minconf=999999999']) def listaddresses3(self): - return self.listaddresses(tool_args=['sort=amt','reverse=1']) + return self.listaddresses(tool_args=['sort=amt', 'reverse=1']) def listaddresses4(self): - return self.listaddresses(tool_args=['sort=age','showempty=0']) + return self.listaddresses(tool_args=['sort=age', 'showempty=0']) def token_listaddresses1(self): return self.listaddresses(args=['--token=mm1']) def token_listaddresses2(self): - return self.listaddresses(args=['--token=mm1'],tool_args=['showempty=1']) + return self.listaddresses(args=['--token=mm1'], tool_args=['showempty=1']) def token_listaddresses3(self): - return self.listaddresses(args=['--token=mm1'],tool_args=['showempty=0']) + return self.listaddresses(args=['--token=mm1'], tool_args=['showempty=0']) def token_listaddresses4(self): - return self.listaddresses(args=['--token=mm2'],tool_args=['sort=age','reverse=1']) + return self.listaddresses(args=['--token=mm2'], tool_args=['sort=age', 'reverse=1']) def twview_cached_balances(self): return self.twview(args=['--cached-balances']) def token_twview_cached_balances(self): - return self.twview(args=['--token=mm1','--cached-balances']) + return self.twview(args=['--token=mm1', '--cached-balances']) def txcreate_cached_balances(self): - args = ['--fee=20G','--cached-balances','98831F3A:E:3,0.1276'] - return self.txcreate(args=args,acct='2') + args = ['--fee=20G', '--cached-balances', '98831F3A:E:3, 0.1276'] + return self.txcreate(args=args, acct='2') def token_txcreate_cached_balances(self): - args=['--cached-balances','--fee=12G','98831F3A:E:12,1.2789'] - return self.token_txcreate(args=args,token='mm1') + args=['--cached-balances', '--fee=12G', '98831F3A:E:12, 1.2789'] + return self.token_txcreate(args=args, token='mm1') def txdo_cached_balances( self, acct = '2', - fee_info_data = ('0.00105','50'), + fee_info_data = ('0.00105', '50'), add_args = ['98831F3A:E:3,0.4321']): t = self.txcreate( - args = ['--fee=20G','--cached-balances'] + add_args + [dfl_words_file], - acct = acct, - caller = 'txdo', - fee_info_data = fee_info_data, - no_read = True) - self._do_confirm_send(t,quiet=not cfg.debug,sure=False) + args = ['--fee=20G', '--cached-balances'] + add_args + [dfl_words_file], + acct = acct, + caller = 'txdo', + fee_info_data = fee_info_data, + no_read = True) + self._do_confirm_send(t, quiet=not cfg.debug, sure=False) return t def txcreate_refresh_balances(self): return self._txcreate_refresh_balances( - bals = ['2','3'], - args = ['-B','--cached-balances','-i'], + bals = ['2', '3'], + args = ['-B', '--cached-balances', '-i'], total = vbal5, adj_total = True, total_coin = None) - def _txcreate_refresh_balances(self,bals,args,total,adj_total,total_coin): + def _txcreate_refresh_balances(self, bals, args, total, adj_total, total_coin): if total_coin is None: total_coin = self.proto.coin t = self.spawn('mmgen-txcreate', self.eth_args + args) for n in bals: - t.expect('[R]efresh balance:\b','R') - t.expect(' main menu): ',n+'\n') - t.expect('Is this what you want? (y/N): ','y') - t.expect('[R]efresh balance:\b','q') - t.expect(rf'Total unspent:.*\D{total}\D.*{total_coin}',regex=True) + t.expect('[R]efresh balance:\b', 'R') + t.expect(' main menu): ', n+'\n') + t.expect('Is this what you want? (y/N): ', 'y') + t.expect('[R]efresh balance:\b', 'q') + t.expect(rf'Total unspent:.*\D{total}\D.*{total_coin}', regex=True) return t def bal10(self): @@ -1324,16 +1324,16 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def token_txdo_cached_balances(self): return self.txdo_cached_balances( acct = '1', - fee_info_data = ('0.0026','50'), - add_args = ['--token=mm1','98831F3A:E:12,43.21'] ) + fee_info_data = ('0.0026', '50'), + add_args = ['--token=mm1', '98831F3A:E:12,43.21']) def token_txcreate_refresh_balances(self): return self._txcreate_refresh_balances( - bals = ['1','2'], - args = ['--token=mm1','-B','--cached-balances','-i'], + bals = ['1', '2'], + args = ['--token=mm1', '-B', '--cached-balances', '-i'], total = '1000', adj_total = False, - total_coin = 'MM1' ) + total_coin = 'MM1') def token_bal7(self): return self.token_bal(n='7') @@ -1343,11 +1343,11 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def twview2(self): return self.twview(tool_args=['wide=1']) def twview3(self): - return self.twview(tool_args=['wide=1','sort=age']) + return self.twview(tool_args=['wide=1', 'sort=age']) def twview4(self): - return self.twview(tool_args=['wide=1','minconf=999999999']) + return self.twview(tool_args=['wide=1', 'minconf=999999999']) def twview5(self): - return self.twview(tool_args=['wide=1','minconf=0']) + return self.twview(tool_args=['wide=1', 'minconf=0']) def twview6(self): return self.twview(expect_str=vbal7) def twview7(self): @@ -1355,14 +1355,14 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): def twview8(self): return self.twview() def twview9(self): - return self.twview(args=['--cached-balances'],expect_str=vbal6) + return self.twview(args=['--cached-balances'], expect_str=vbal6) def token_twview1(self): return self.twview(args=['--token=mm1']) def token_twview2(self): - return self.twview(args=['--token=mm1'],tool_args=['wide=1']) + return self.twview(args=['--token=mm1'], tool_args=['wide=1']) def token_twview3(self): - return self.twview(args=['--token=mm1'],tool_args=['wide=1','sort=age']) + return self.twview(args=['--token=mm1'], tool_args=['wide=1', 'sort=age']) def edit_comment( self, @@ -1377,69 +1377,69 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): menu_prompt = 'efresh balance:\b' - t.expect(menu_prompt,'M') - t.expect(menu_prompt,action) - t.expect(r'return to main menu): ',out_num+'\n') + t.expect(menu_prompt, 'M') + t.expect(menu_prompt, action) + t.expect(r'return to main menu): ', out_num+'\n') - for p,r in ( - ('Enter label text.*: ',comment_text+'\n') if comment_text is not None else (r'\(y/N\): ','y'), - (r'\(y/N\): ','y') if comment_text == Ctrl_U else (None,None), + for p, r in ( + ('Enter label text.*: ', comment_text+'\n') if comment_text is not None else (r'\(y/N\): ', 'y'), + (r'\(y/N\): ', 'y') if comment_text == Ctrl_U else (None, None), ): if p: - t.expect(p,r,regex=True) + t.expect(p, r, regex=True) m = ( 'Label for account #{} edited' if changed else 'Account #{} removed' if action == 'D' else 'Label added to account #{}' if comment_text and comment_text != Ctrl_U else - 'Label removed from account #{}' ) + 'Label removed from account #{}') t.expect(m.format(out_num)) - t.expect(menu_prompt,'M') - t.expect(menu_prompt,'q') + t.expect(menu_prompt, 'M') + t.expect(menu_prompt, 'q') t.expect('Total unspent:') return t def edit_comment1(self): - return self.edit_comment(out_num=del_addrs[0],comment_text=tw_comment_zh[:3]) + return self.edit_comment(out_num=del_addrs[0], comment_text=tw_comment_zh[:3]) def edit_comment2(self): spawn = not sys.platform == 'win32' return self.edit_comment( - out_num = del_addrs[0], - comment_text = tw_comment_zh[3:], - changed = True, - pexpect_spawn = spawn) + out_num = del_addrs[0], + comment_text = tw_comment_zh[3:], + changed = True, + pexpect_spawn = spawn) def edit_comment3(self): - return self.edit_comment(out_num=del_addrs[1],comment_text=tw_comment_lat_cyr_gr) + return self.edit_comment(out_num=del_addrs[1], comment_text=tw_comment_lat_cyr_gr) def edit_comment4(self): if self.skip_for_win('no pexpect_spawn'): return 'skip' - return self.edit_comment(out_num=del_addrs[0],comment_text=Ctrl_U,pexpect_spawn=True) + return self.edit_comment(out_num=del_addrs[0], comment_text=Ctrl_U, pexpect_spawn=True) def token_edit_comment1(self): - return self.edit_comment(out_num='1',comment_text='Token label #1',args=['--token=mm1']) + return self.edit_comment(out_num='1', comment_text='Token label #1', args=['--token=mm1']) def remove_addr1(self): - return self.edit_comment(out_num=del_addrs[0],action='D') + return self.edit_comment(out_num=del_addrs[0], action='D') def remove_addr2(self): - return self.edit_comment(out_num=del_addrs[1],action='D') + return self.edit_comment(out_num=del_addrs[1], action='D') def token_remove_addr1(self): - return self.edit_comment(out_num=del_addrs[0],args=['--token=mm1'],action='D') + return self.edit_comment(out_num=del_addrs[0], args=['--token=mm1'], action='D') def token_remove_addr2(self): - return self.edit_comment(out_num=del_addrs[1],args=['--token=mm1'],action='D') + return self.edit_comment(out_num=del_addrs[1], args=['--token=mm1'], action='D') def twexport_noamt(self): return self.twexport(add_args=['include_amts=0']) - def twexport(self,add_args=[]): + def twexport(self, add_args=[]): t = self.spawn('mmgen-tool', self.eth_args + ['twexport'] + add_args) t.written_to_file('JSON data') return t async def twmove(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) from mmgen.tw.ctl import TwCtl twctl = await TwCtl(cfg, self.proto, no_wallet_init=True) imsg('Moving tracking wallet') @@ -1448,9 +1448,9 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): twctl.tw_path.rename(fn_bak) return 'ok' - def twimport(self,add_args=[],expect_str=None): + def twimport(self, add_args=[], expect_str=None): from mmgen.tw.json import TwJSON - fn = joinpath(self.tmpdir, TwJSON.Base(cfg,self.proto).dump_fn) + fn = joinpath(self.tmpdir, TwJSON.Base(cfg, self.proto).dump_fn) t = self.spawn('mmgen-tool', self.eth_args_noquiet + ['twimport', fn] + add_args) t.expect('(y/N): ', 'y') if expect_str: @@ -1459,39 +1459,39 @@ class CmdTestEthdev(CmdTestBase,CmdTestShared): return t def twimport_nochksum(self): - return self.twimport(add_args=['ignore_checksum=true'],expect_str='ignoring incorrect checksum') + return self.twimport(add_args=['ignore_checksum=true'], expect_str='ignoring incorrect checksum') def tw_chktotal(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) from mmgen.tw.json import TwJSON - fn = joinpath( self.tmpdir, TwJSON.Base(cfg,self.proto).dump_fn ) + fn = joinpath(self.tmpdir, TwJSON.Base(cfg, self.proto).dump_fn) res = json.loads(read_from_file(fn)) - cmp_or_die( res['data']['value'], vbal6, 'value in tracking wallet JSON dump' ) + cmp_or_die(res['data']['value'], vbal6, 'value in tracking wallet JSON dump') return 'ok' async def twcompare(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) from mmgen.tw.ctl import TwCtl twctl = await TwCtl(cfg, self.proto, no_wallet_init=True) fn = twctl.tw_path fn_bak = fn.with_suffix('.bak.json') imsg('Comparing imported tracking wallet with original') data = [json.dumps(json.loads(f.read_text()), sort_keys=True) for f in (fn, fn_bak)] - cmp_or_die(*data,'tracking wallets') + cmp_or_die(*data, 'tracking wallets') return 'ok' def edit_json_twdump(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) from mmgen.tw.json import TwJSON - fn = TwJSON.Base(cfg,self.proto).dump_fn + fn = TwJSON.Base(cfg, self.proto).dump_fn text = json.loads(self.read_from_tmpfile(fn)) token_addr = self.read_from_tmpfile('token_addr2').strip() text['data']['entries']['tokens'][token_addr][2][3] = f'edited comment [фубар] [{gr_uc}]' - self.write_to_tmpfile( fn, json.dumps(text,indent=4) ) + self.write_to_tmpfile(fn, json.dumps(text, indent=4)) return 'ok' def stop(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) if not cfg.no_daemon_stop: if not stop_test_daemons(self.proto.coin+'_rt'): return False diff --git a/test/cmdtest_py_d/ct_help.py b/test/cmdtest_py_d/ct_help.py index 2cb451e2..bff84c09 100755 --- a/test/cmdtest_py_d/ct_help.py +++ b/test/cmdtest_py_d/ct_help.py @@ -23,19 +23,19 @@ from .ct_base import CmdTestBase class CmdTestHelp(CmdTestBase): 'help, info and usage screens' networks = ('btc', 'ltc', 'bch', 'eth', 'xmr', 'doge') - passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet') + passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet') cmd_group = ( - ('usage1', (1,'usage message (via --usage)',[])), - ('usage2', (1,'usage message (via bad invocation)',[])), - ('version', (1,'version message',[])), - ('license', (1,'license message',[])), - ('helpscreens', (1,'help screens', [])), - ('longhelpscreens', (1,'help screens (--longhelp)',[])), - ('show_hash_presets', (1,'info screen (--show-hash-presets)',[])), - ('tool_help', (1,"'mmgen-tool' usage screen",[])), - ('tool_cmd_usage', (1,"'mmgen-tool' usage screen",[])), - ('test_help', (1,"'cmdtest.py' help screens",[])), - ('tooltest_help', (1,"'tooltest.py' help screens",[])), + ('usage1', (1, 'usage message (via --usage)', [])), + ('usage2', (1, 'usage message (via bad invocation)', [])), + ('version', (1, 'version message', [])), + ('license', (1, 'license message', [])), + ('helpscreens', (1, 'help screens', [])), + ('longhelpscreens', (1, 'help screens (--longhelp)', [])), + ('show_hash_presets', (1, 'info screen (--show-hash-presets)', [])), + ('tool_help', (1, '‘mmgen-tool’ usage screen', [])), + ('tool_cmd_usage', (1, '‘mmgen-tool’ usage screen', [])), + ('test_help', (1, '‘cmdtest.py’ help screens', [])), + ('tooltest_help', (1, '‘tooltest.py’ help screens', [])), ) def usage1(self): @@ -67,13 +67,13 @@ class CmdTestHelp(CmdTestBase): if cfg.pexpect_spawn: t.send('q') t.expect('to continue: ', 'c') - t.expect('data: ','beadcafe'*4 + '\n') + t.expect('data: ', 'beadcafe'*4 + '\n') t.expect('to confirm: ', 'YES\n') return t - def spawn_chk_expect(self,*args,**kwargs): + def spawn_chk_expect(self, *args, **kwargs): expect = kwargs.pop('expect') - t = self.spawn(*args,**kwargs) + t = self.spawn(*args, **kwargs) t.expect(expect) if t.pexpect_spawn: time.sleep(0.4) @@ -106,7 +106,7 @@ class CmdTestHelp(CmdTestBase): [arg], extra_desc = f'(mmgen-{cmdname})', no_passthru_opts = not gc.cmd_caps_data[cmdname].proto) - t.expect(expect,regex=True) + t.expect(expect, regex=True) if pager and t.pexpect_spawn: time.sleep(0.2) t.send('q') @@ -117,17 +117,17 @@ class CmdTestHelp(CmdTestBase): return t def longhelpscreens(self): - return self.helpscreens(arg='--longhelp',expect='USAGE:.*GLOBAL OPTIONS:') + return self.helpscreens(arg='--longhelp', expect='USAGE:.*GLOBAL OPTIONS:') def show_hash_presets(self): return self.helpscreens( arg = '--show-hash-presets', scripts = ( - 'walletgen','walletconv','walletchk','passchg','subwalletgen', - 'addrgen','keygen','passgen', - 'txsign','txdo','txbump'), + 'walletgen', 'walletconv', 'walletchk', 'passchg', 'subwalletgen', + 'addrgen', 'keygen', 'passgen', + 'txsign', 'txdo', 'txbump'), expect = 'Available parameters.*Preset', - pager = False ) + pager = False) def tool_help(self): @@ -143,7 +143,7 @@ class CmdTestHelp(CmdTestBase): 'mmgen-tool', [arg], extra_desc = f'(mmgen-tool {arg})', - expect = 'GENERAL USAGE' ) + expect = 'GENERAL USAGE') return t def tool_cmd_usage(self): @@ -156,32 +156,32 @@ class CmdTestHelp(CmdTestBase): for cmdlist in mods.values(): for cmd in cmdlist: - t = self.spawn_chk( 'mmgen-tool', ['help',cmd], extra_desc=f'({cmd})' ) + t = self.spawn_chk('mmgen-tool', ['help', cmd], extra_desc=f'({cmd})') return t def test_help(self): - for arg,expect in ( - ('--help','USAGE'), - ('--list-cmds','AVAILABLE COMMANDS'), - ('--list-cmd-groups','AVAILABLE COMMAND GROUPS') + for arg, expect in ( + ('--help', 'USAGE'), + ('--list-cmds', 'AVAILABLE COMMANDS'), + ('--list-cmd-groups', 'AVAILABLE COMMAND GROUPS') ): t = self.spawn_chk_expect( 'cmdtest.py', [arg], cmd_dir = 'test', extra_desc = f'(cmdtest.py {arg})', - expect = expect ) + expect = expect) return t def tooltest_help(self): - for arg,expect in ( - ('--list-cmds','Available commands'), - ('--testing-status','Testing status') + for arg, expect in ( + ('--list-cmds', 'Available commands'), + ('--testing-status', 'Testing status') ): t = self.spawn_chk_expect( 'tooltest.py', [arg], cmd_dir = 'test', extra_desc = f'(tooltest.py {arg})', - expect = expect ) + expect = expect) return t diff --git a/test/cmdtest_py_d/ct_input.py b/test/cmdtest_py_d/ct_input.py index c7d1c32d..fd5e8cc3 100755 --- a/test/cmdtest_py_d/ct_input.py +++ b/test/cmdtest_py_d/ct_input.py @@ -10,10 +10,10 @@ test.cmdtest_py_d.ct_input: user input tests for the MMGen cmdtest.py test suite """ -import sys,os +import sys, os from mmgen.cfg import gc -from mmgen.util import fmt,capfirst,remove_whitespace +from mmgen.util import fmt, capfirst, remove_whitespace from mmgen.wallet import get_wallet_cls from ..include.common import ( @@ -25,9 +25,9 @@ from ..include.common import ( read_from_file, strip_ansi_escapes ) -from .common import Ctrl_U,ref_dir +from .common import Ctrl_U, ref_dir from .ct_base import CmdTestBase -from .input import stealth_mnemonic_entry,user_dieroll_entry +from .input import stealth_mnemonic_entry, user_dieroll_entry hold_protect_delay = 2 if sys.platform == 'darwin' else None @@ -88,17 +88,17 @@ class CmdTestInput(CmdTestBase): ), 'mnemonic': ( 'mnemonic entry', - ('mnemonic_entry_mmgen', 'stealth mnemonic entry (mmgen)'), - ('mnemonic_entry_mmgen_minimal', 'stealth mnemonic entry (mmgen - minimal entry mode)'), - ('mnemonic_entry_bip39', 'stealth mnemonic entry (bip39)'), - ('mnemonic_entry_bip39_short', 'stealth mnemonic entry (bip39 - short entry mode)'), - ('mn2hex_interactive_mmgen', 'mn2hex_interactive (mmgen)'), - ('mn2hex_interactive_mmgen_fixed','mn2hex_interactive (mmgen - fixed (10-letter) entry mode)'), - ('mn2hex_interactive_bip39', 'mn2hex_interactive (bip39)'), - ('mn2hex_interactive_bip39_short','mn2hex_interactive (bip39 - short entry mode (+pad entry))'), - ('mn2hex_interactive_bip39_fixed','mn2hex_interactive (bip39 - fixed (4-letter) entry mode)'), - ('mn2hex_interactive_xmr', 'mn2hex_interactive (xmrseed)'), - ('mn2hex_interactive_xmr_short', 'mn2hex_interactive (xmrseed - short entry mode)'), + ('mnemonic_entry_mmgen', 'stealth mnemonic entry (mmgen)'), + ('mnemonic_entry_mmgen_minimal', 'stealth mnemonic entry (mmgen - minimal entry mode)'), + ('mnemonic_entry_bip39', 'stealth mnemonic entry (bip39)'), + ('mnemonic_entry_bip39_short', 'stealth mnemonic entry (bip39 - short entry mode)'), + ('mn2hex_interactive_mmgen', 'mn2hex_interactive (mmgen)'), + ('mn2hex_interactive_mmgen_fixed', 'mn2hex_interactive (mmgen - fixed (10-letter) entry mode)'), + ('mn2hex_interactive_bip39', 'mn2hex_interactive (bip39)'), + ('mn2hex_interactive_bip39_short', 'mn2hex_interactive (bip39 - short entry mode (+pad entry))'), + ('mn2hex_interactive_bip39_fixed', 'mn2hex_interactive (bip39 - fixed (4-letter) entry mode)'), + ('mn2hex_interactive_xmr', 'mn2hex_interactive (xmrseed)'), + ('mn2hex_interactive_xmr_short', 'mn2hex_interactive (xmrseed - short entry mode)'), ), 'dieroll': ( 'dieroll entry', @@ -108,79 +108,79 @@ class CmdTestInput(CmdTestBase): } def get_seed_from_stdin(self): - self.spawn('',msg_only=True) - from subprocess import run,PIPE - cmd = ['python3','cmds/mmgen-walletconv','--in-fmt=words','--out-fmt=words','--outdir=test/trash'] + self.spawn('', msg_only=True) + from subprocess import run, PIPE + cmd = ['python3', 'cmds/mmgen-walletconv', '--in-fmt=words', '--out-fmt=words', '--outdir=test/trash'] mn = sample_mn['mmgen']['mn'] run_env = dict(os.environ) run_env['MMGEN_TEST_SUITE'] = '' # the test can fail the first time if cfg file has changed, so run it twice if necessary: for _ in range(2): - cp = run( cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE, env=run_env ) + cp = run(cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE, env=run_env) if b'written to file' in cp.stderr: break from mmgen.color import set_vt100 set_vt100() imsg(cp.stderr.decode().strip()) - res = get_data_from_file(cfg,'test/trash/A773B05C[128].mmwords',silent=True).strip() + res = get_data_from_file(cfg, 'test/trash/A773B05C[128].mmwords', silent=True).strip() assert res == mn, f'{res} != {mn}' 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='.') + t = self.spawn('test/misc/get_passphrase.py', ['--usr-randchars=0', 'seed'], cmd_dir='.') - # 1 - new wallet, default hp,label;empty pw - t.expect('accept the default.*: ','\n',regex=True) + # 1 - new wallet, default hp, label;empty pw + t.expect('accept the default.*: ', '\n', regex=True) # bad repeat - t.expect('new MMGen wallet: ','pass1\n') - t.expect('peat passphrase: ','pass2\n') + t.expect('new MMGen wallet: ', 'pass1\n') + t.expect('peat passphrase: ', 'pass2\n') # good repeat - t.expect('new MMGen wallet: ','\n') - t.expect('peat passphrase: ','\n') + t.expect('new MMGen wallet: ', '\n') + t.expect('peat passphrase: ', '\n') t.expect('mpty pass') - t.expect('no label: ','\n') + t.expect('no label: ', '\n') t.expect('[][3][No Label]') - # 2 - new wallet, user-selected hp,pw,label + # 2 - new wallet, user-selected hp, pw, label t.expect('accept the default.*: ', '1\n', regex=True) - t.expect('new MMGen wallet: ','pass1\n') - t.expect('peat passphrase: ','pass1\n') + t.expect('new MMGen wallet: ', 'pass1\n') + t.expect('peat passphrase: ', 'pass1\n') - t.expect('no label: ','lbl1\n') + t.expect('no label: ', 'lbl1\n') t.expect('[pass1][1][lbl1]') # 3 - passchg, nothing changes t.expect('new hash preset') - t.expect('reuse the old value.*: ','\n',regex=True) + t.expect('reuse the old value.*: ', '\n', regex=True) t.expect('unchanged') - t.expect('new passphrase.*: ','pass1\n',regex=True) - t.expect('peat new passphrase: ','pass1\n') + t.expect('new passphrase.*: ', 'pass1\n', regex=True) + t.expect('peat new passphrase: ', 'pass1\n') t.expect('unchanged') - t.expect('reuse the label .*: ','\n',regex=True) + t.expect('reuse the label .*: ', '\n', regex=True) t.expect('unchanged') t.expect('[pass1][1][lbl1]') # 4 - passchg, everything changes t.expect('new hash preset') - t.expect('reuse the old value.*: ','2\n',regex=True) + t.expect('reuse the old value.*: ', '2\n', regex=True) t.expect(' changed to') - t.expect('new passphrase.*: ','pass2\n',regex=True) - t.expect('peat new passphrase: ','pass2\n') + t.expect('new passphrase.*: ', 'pass2\n', regex=True) + t.expect('peat new passphrase: ', 'pass2\n') t.expect(' changed') - t.expect('reuse the label .*: ','lbl2\n',regex=True) + t.expect('reuse the label .*: ', 'lbl2\n', regex=True) t.expect(' changed to') t.expect('[pass2][2][lbl2]') @@ -188,32 +188,32 @@ class CmdTestInput(CmdTestBase): t.expect('from file') # bad passphrase - t.expect('passphrase for MMGen wallet: ','bad\n') + t.expect('passphrase for MMGen wallet: ', 'bad\n') t.expect('Trying again') # good passphrase - t.expect('passphrase for MMGen wallet: ','reference password\n') + t.expect('passphrase for MMGen wallet: ', 'reference password\n') t.expect('[reference password][1][No Label]') return t def get_passphrase_cmdline(self): - with open('test/trash/pwfile','w') as fp: + with open('test/trash/pwfile', 'w') as fp: fp.write('reference password\n') t = self.spawn('test/misc/get_passphrase.py', [ '--usr-randchars=0', '--label=MyLabel', '--passwd-file=test/trash/pwfile', '--hash-preset=1', - 'seed' ], - cmd_dir = '.' ) + 'seed'], + cmd_dir = '.') for _ in range(4): t.expect('[reference password][1][MyLabel]') return t def get_passphrase_crypto(self): - t = self.spawn('test/misc/get_passphrase.py',['--usr-randchars=0','crypto'],cmd_dir='.') + t = self.spawn('test/misc/get_passphrase.py', ['--usr-randchars=0', 'crypto'], cmd_dir='.') # new passwd t.expect('passphrase for .*: ', 'x\n', regex=True) @@ -242,20 +242,20 @@ class CmdTestInput(CmdTestBase): def _input_func(self, func_name, arg_dfls, func_args, text, expect, term, delay=None): if term and sys.platform == 'win32': - return ('skip_warn','pexpect_spawn not supported on Windows platform') - func_args = dict(zip(arg_dfls.keys(),func_args)) + return ('skip_warn', 'pexpect_spawn not supported on Windows platform') + func_args = dict(zip(arg_dfls.keys(), func_args)) t = self.spawn( 'test/misc/input_func.py', - [func_name,repr(func_args)], + [func_name, repr(func_args)], cmd_dir='.', - pexpect_spawn=term ) + pexpect_spawn=term) imsg('Parameters:') imsg(f' pexpect_spawn: {term}') imsg(f' sending: {text!r}') imsg(f' expecting: {expect!r}') imsg('\nFunction args:') - for k,v in func_args.items(): - imsg(' {:14} {!r}'.format(k+':',v)) + for k, v in func_args.items(): + imsg(' {:14} {!r}'.format(k+':', v)) imsg_r('\nScript output: ') prompt_add = (func_args['insert_txt'] if term else '') if func_name == 'line_input' else '' prompt = func_args['prompt'] + prompt_add @@ -268,14 +268,14 @@ class CmdTestInput(CmdTestBase): assert ret == repr(expect), f'Text mismatch! {ret} != {repr(expect)}' return t - def _get_char(self,func_args,text,expect,term): + def _get_char(self, func_args, text, expect, term): arg_dfls = { 'prompt': '', 'immed_chars': '', 'prehold_protect': True, 'num_bytes': 5, } - return self._input_func('get_char',arg_dfls,func_args,text,expect,term) + return self._input_func('get_char', arg_dfls, func_args, text, expect, term) def _line_input(self, func_args, text, expect, term, delay=None): arg_dfls = { @@ -287,29 +287,29 @@ class CmdTestInput(CmdTestBase): return self._input_func('line_input', arg_dfls, func_args, text+'\n', expect, term, delay=delay) def get_char1(self): - return self._get_char(['prompt> ','',True,5],'x','x',False) + return self._get_char(['prompt> ', '', True, 5], 'x', 'x', False) def get_char2(self): expect = 'x' if sys.platform == 'win32' else 'xxxxx' - return self._get_char(['prompt> ','',True,5],'xxxxx',expect,False) + return self._get_char(['prompt> ', '', True, 5], 'xxxxx', expect, False) def get_char3(self): - return self._get_char(['','',True,5],'x','x',False) + return self._get_char(['', '', True, 5], 'x', 'x', False) def get_char4(self): - return self._get_char(['prompt> ','',True,2],'α','α',False) # UTF-8, must get 2 bytes + return self._get_char(['prompt> ', '', True, 2], 'α', 'α', False) # UTF-8, must get 2 bytes def get_char_term1(self): - return self._get_char(['prompt> ','',True,2],'β','β',True) # UTF-8, must get 2 bytes + return self._get_char(['prompt> ', '', True, 2], 'β', 'β', True) # UTF-8, must get 2 bytes def get_char_term2(self): - return self._get_char(['prompt> ','',True,5],'xxxxx','xxxxx',True) + return self._get_char(['prompt> ', '', True, 5], 'xxxxx', 'xxxxx', True) def get_char_term3(self): - return self._get_char(['','',False,5],'x','x',True) + return self._get_char(['', '', False, 5], 'x', 'x', True) def get_char_term4(self): - return self._get_char(['prompt> ','xyz',False,5],'x','x',True) + return self._get_char(['prompt> ', 'xyz', False, 5], 'x', 'x', True) def line_input(self): return self._line_input( @@ -387,13 +387,13 @@ class CmdTestInput(CmdTestBase): True, hold_protect_delay) - def _password_entry(self,prompt,opts=[],term=False): + def _password_entry(self, prompt, opts=[], term=False): if term and sys.platform == 'win32': - return ('skip_warn','pexpect_spawn not supported on Windows platform') - t = self.spawn( 'test/misc/input_func.py', opts + ['passphrase'], cmd_dir='.', pexpect_spawn=term ) + return ('skip_warn', 'pexpect_spawn not supported on Windows platform') + t = self.spawn('test/misc/input_func.py', opts + ['passphrase'], cmd_dir='.', pexpect_spawn=term) imsg(f'Terminal: {term}') pw = 'abc-α' - t.expect(prompt,pw+'\n') + t.expect(prompt, pw+'\n') ret = t.expect_getend('Entered: ') assert ret == pw, f'Password mismatch! {ret} != {pw}' return t @@ -406,35 +406,35 @@ class CmdTestInput(CmdTestBase): test/misc/input_func.py{} passphrase """ - def password_entry_noecho(self,term=False): - return self._password_entry('Enter passphrase: ',term=term) + def password_entry_noecho(self, term=False): + return self._password_entry('Enter passphrase: ', term=term) def password_entry_noecho_term(self): if self.skip_for_win('no pexpect_spawn'): - return ('skip_warn','\n' + fmt(self.winskip_msg.format(''),strip_char='\t')) + return ('skip_warn', '\n' + fmt(self.winskip_msg.format(''), strip_char='\t')) return self.password_entry_noecho(term=True) - def password_entry_echo(self,term=False): - return self._password_entry('Enter passphrase (echoed): ',['--echo-passphrase'],term=term) + def password_entry_echo(self, term=False): + return self._password_entry('Enter passphrase (echoed): ', ['--echo-passphrase'], term=term) def password_entry_echo_term(self): if self.skip_for_win('no pexpect_spawn'): - return ('skip_warn','\n' + fmt(self.winskip_msg.format(' --echo-passphrase'),strip_char='\t')) + return ('skip_warn', '\n' + fmt(self.winskip_msg.format(' --echo-passphrase'), strip_char='\t')) return self.password_entry_echo(term=True) - def _mn2hex(self,fmt,entry_mode='full',mn=None,pad_entry=False,enter_for_dfl=False): + def _mn2hex(self, fmt, entry_mode='full', mn=None, pad_entry=False, enter_for_dfl=False): mn = mn or sample_mn[fmt]['mn'].split() - t = self.spawn('mmgen-tool',['mn2hex_interactive','fmt='+fmt,'mn_len=12','print_mn=1']) + t = self.spawn('mmgen-tool', ['mn2hex_interactive', 'fmt='+fmt, 'mn_len=12', 'print_mn=1']) from mmgen.mn_entry import mn_entry - mne = mn_entry( cfg, fmt, entry_mode ) + mne = mn_entry(cfg, fmt, entry_mode) t.expect( 'Type a number.*: ', ('\n' if enter_for_dfl else str(mne.entry_modes.index(entry_mode)+1)), - regex = True ) + regex = True) t.expect(r'Using entry mode (\S+)', regex=True) mode = strip_ansi_escapes(t.p.match.group(1)).lower() assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}' - stealth_mnemonic_entry(t,mne,mn,entry_mode=entry_mode,pad_entry=pad_entry) + stealth_mnemonic_entry(t, mne, mn, entry_mode=entry_mode, pad_entry=pad_entry) t.expect(sample_mn[fmt]['hex']) return t @@ -448,52 +448,52 @@ class CmdTestInput(CmdTestBase): seedlen_opt = False): wcls = get_wallet_cls(fmt_code=fmt) - wf = os.path.join(ref_dir,f'FE3C6545.{wcls.ext}') + wf = os.path.join(ref_dir, f'FE3C6545.{wcls.ext}') if wcls.base_type == 'mnemonic': mn = mn or read_from_file(wf).strip().split() elif wcls.type == 'dieroll': mn = mn or list(remove_whitespace(read_from_file(wf))) - for idx,val in ((5,'x'),(18,'0'),(30,'7'),(44,'9')): - mn.insert(idx,val) + for idx, val in ((5, 'x'), (18, '0'), (30, '7'), (44, '9')): + mn.insert(idx, val) t = self.spawn( 'mmgen-walletconv', ['--usr-randchars=10', '--stdout'] + (['--seed-len=128'] if seedlen_opt else []) + [f'--in-fmt={fmt}', f'--out-fmt={out_fmt or fmt}'] ) - t.expect(f'{capfirst(wcls.base_type or wcls.type)} type:.*{wcls.mn_type}',regex=True) + t.expect(f'{capfirst(wcls.base_type or wcls.type)} type:.*{wcls.mn_type}', regex=True) if not seedlen_opt: - t.expect(wcls.choose_seedlen_prompt,'1') - t.expect('(Y/n): ','y') + t.expect(wcls.choose_seedlen_prompt, '1') + t.expect('(Y/n): ', 'y') if wcls.base_type == 'mnemonic': - t.expect('Type a number.*: ','6',regex=True) + t.expect('Type a number.*: ', '6', regex=True) t.expect('invalid') from mmgen.mn_entry import mn_entry - mne = mn_entry( cfg, fmt, entry_mode ) - t.expect('Type a number.*: ',str(mne.entry_modes.index(entry_mode)+1),regex=True) - t.expect(r'Using entry mode (\S+)',regex=True) + mne = mn_entry(cfg, fmt, entry_mode) + t.expect('Type a number.*: ', str(mne.entry_modes.index(entry_mode)+1), regex=True) + t.expect(r'Using entry mode (\S+)', regex=True) mode = strip_ansi_escapes(t.p.match.group(1)).lower() assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}' - stealth_mnemonic_entry(t,mne,mn,entry_mode=entry_mode) + stealth_mnemonic_entry(t, mne, mn, entry_mode=entry_mode) elif wcls.type == 'dieroll': - user_dieroll_entry(t,mn) + user_dieroll_entry(t, mn) if usr_rand: - t.expect(wcls.user_entropy_prompt,'y') + t.expect(wcls.user_entropy_prompt, 'y') t.usr_rand(10) else: - t.expect(wcls.user_entropy_prompt,'n') + t.expect(wcls.user_entropy_prompt, 'n') if not usr_rand: sid_chk = 'FE3C6545' sid = t.expect_getend(f'Valid {wcls.desc} for Seed ID') sid = strip_ansi_escapes(sid.split(',')[0]) assert sid_chk in sid, f'Seed ID mismatch! {sid_chk} not found in {sid}' - t.expect('to confirm: ','YES\n') + t.expect('to confirm: ', 'YES\n') return t def mnemonic_entry_mmgen_minimal(self): from mmgen.mn_entry import mn_entry # erase_chars: '\b\x7f' - m = mn_entry( cfg, 'mmgen', 'minimal' ) + m = mn_entry(cfg, 'mmgen', 'minimal') np = 2 mn = ( 'z', @@ -511,30 +511,30 @@ class CmdTestInput(CmdTestBase): 'app\bpl', 'wd', 'busy') - return self._user_seed_entry('words',entry_mode='minimal',mn=mn) + return self._user_seed_entry('words', entry_mode='minimal', mn=mn) def mnemonic_entry_mmgen(self): - return self._user_seed_entry('words',entry_mode='full') + return self._user_seed_entry('words', entry_mode='full') def mnemonic_entry_bip39(self): - return self._user_seed_entry('bip39',entry_mode='full') + return self._user_seed_entry('bip39', entry_mode='full') def mnemonic_entry_bip39_short(self): - return self._user_seed_entry('bip39',entry_mode='short') + return self._user_seed_entry('bip39', entry_mode='short') def mn2hex_interactive_mmgen(self): - return self._mn2hex('mmgen',entry_mode='full') + return self._mn2hex('mmgen', entry_mode='full') def mn2hex_interactive_mmgen_fixed(self): - return self._mn2hex('mmgen',entry_mode='fixed') + return self._mn2hex('mmgen', entry_mode='fixed') def mn2hex_interactive_bip39(self): - return self._mn2hex('bip39',entry_mode='full') + return self._mn2hex('bip39', entry_mode='full') def mn2hex_interactive_bip39_short(self): - return self._mn2hex('bip39',entry_mode='short',pad_entry=True) + return self._mn2hex('bip39', entry_mode='short', pad_entry=True) def mn2hex_interactive_bip39_fixed(self): - return self._mn2hex('bip39',entry_mode='fixed',enter_for_dfl=True) + return self._mn2hex('bip39', entry_mode='fixed', enter_for_dfl=True) def mn2hex_interactive_xmr(self): - return self._mn2hex('xmrseed',entry_mode='full') + return self._mn2hex('xmrseed', entry_mode='full') def mn2hex_interactive_xmr_short(self): - return self._mn2hex('xmrseed',entry_mode='short') + return self._mn2hex('xmrseed', entry_mode='short') def dieroll_entry(self): return self._user_seed_entry('dieroll', seedlen_opt=True) def dieroll_entry_usrrand(self): - return self._user_seed_entry('dieroll',usr_rand=True,out_fmt='bip39') + return self._user_seed_entry('dieroll', usr_rand=True, out_fmt='bip39') diff --git a/test/cmdtest_py_d/ct_main.py b/test/cmdtest_py_d/ct_main.py index 652dc2ee..75c93177 100755 --- a/test/cmdtest_py_d/ct_main.py +++ b/test/cmdtest_py_d/ct_main.py @@ -20,11 +20,11 @@ test.cmdtest_py_d.ct_main: Basic operations tests for the cmdtest.py test suite """ -import sys,os +import sys, os -from mmgen.util import msg,msg_r,async_run,capfirst,get_extension,die +from mmgen.util import msg, msg_r, async_run, capfirst, get_extension, die from mmgen.color import green, cyan, gray -from mmgen.fileutil import get_data_from_file,write_data_to_file +from mmgen.fileutil import get_data_from_file, write_data_to_file from mmgen.wallet import get_wallet_cls from mmgen.wallet.mmgen import wallet as MMGenWallet from mmgen.wallet.incog import wallet as IncogWallet @@ -60,20 +60,20 @@ from .ct_shared import CmdTestShared def make_brainwallet_file(fn): # Print random words with random whitespace in between wl = rwords.split() - nwords,ws_list,max_spaces = 10,' \n',5 + nwords, ws_list, max_spaces = 10, ' \n', 5 def rand_ws_seq(): nchars = getrandnum(1) % max_spaces + 1 - return ''.join([ws_list[getrandnum_range(1,200) % len(ws_list)] for i in range(nchars)]) - rand_pairs = [wl[getrandnum_range(1,200) % len(wl)] + rand_ws_seq() for i in range(nwords)] + return ''.join([ws_list[getrandnum_range(1, 200) % len(ws_list)] for i in range(nchars)]) + rand_pairs = [wl[getrandnum_range(1, 200) % len(wl)] + rand_ws_seq() for i in range(nwords)] d = ''.join(rand_pairs).rstrip() + '\n' if cfg.verbose: msg_r(f'Brainwallet password:\n{cyan(d)}') - write_data_to_file(cfg,fn,d,'brainwallet password',quiet=True,ignore_opt_outdir=True) + write_data_to_file(cfg, fn, d, 'brainwallet password', quiet=True, ignore_opt_outdir=True) -def verify_checksum_or_exit(checksum,chk): +def verify_checksum_or_exit(checksum, chk): chk = strip_ansi_escapes(chk) if checksum != chk: - die( 'TestSuiteFatalException', f'Checksum error: {chk}' ) + die('TestSuiteFatalException', f'Checksum error: {chk}') vmsg(green('Checksums match: ') + cyan(chk)) addrs_per_wallet = 8 @@ -90,180 +90,250 @@ rwords = """ сувенир сугроб суть сцена театр тираж толк удивить улыбка фирма читатель эстония эстрада юность """ -class CmdTestMain(CmdTestBase,CmdTestShared): +class CmdTestMain(CmdTestBase, CmdTestShared): 'basic operations with emulated tracking wallet' - tmpdir_nums = [1,2,3,4,5,14,15,16,20,21] - networks = ('btc','btc_tn','ltc','ltc_tn','bch','bch_tn') - passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet','rpc_backend') + tmpdir_nums = [1, 2, 3, 4, 5, 14, 15, 16, 20, 21] + networks = ('btc', 'btc_tn', 'ltc', 'ltc_tn', 'bch', 'bch_tn') + passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet', 'rpc_backend') segwit_opts_ok = True color = True need_daemon = True cmd_group = ( - ('walletgen_dfl_wallet', (15,'wallet generation (default wallet)', [[[],15]])), - ('subwalletgen_dfl_wallet', (15,'subwallet generation (default wallet)', [[[pwfile],15]])), - ('export_seed_dfl_wallet', (15,'seed export to mmseed format (default wallet)', [[[pwfile],15]])), - ('addrgen_dfl_wallet', (15,'address generation (default wallet)', [[[pwfile],15]])), - ('txcreate_dfl_wallet', (15,'transaction creation (default wallet)', [[['addrs'],15]])), - ('txsign_dfl_wallet', (15,'transaction signing (default wallet)', [[['rawtx',pwfile],15]])), - ('passchg_dfl_wallet', (16,'password, label and hash preset change (default wallet)',[[[pwfile],15]])), - ('walletchk_newpass_dfl_wallet', (16,'wallet check with new pw, label and hash preset', [[[pwfile],16]])), - ('delete_dfl_wallet', (15,'delete default wallet', [[[pwfile],15]])), - - ('walletgen', (1,'wallet generation', [[['del_dw_run'],15]])), - ('subwalletgen', (1,'subwallet generation', [[['mmdat'],1]])), - ('subwalletgen_mnemonic', (1,'subwallet generation (to mnemonic format)', [[['mmdat'],1]])), - # ('walletchk', (1,'wallet check', [[['mmdat'],1]])), - ('passchg', (5,'password, label and hash preset change', [[['mmdat',pwfile],1]])), - ('passchg_keeplabel',(5,'password, label and hash preset change (keep label)', [[['mmdat',pwfile],1]])), - ('passchg_usrlabel', ( - 5, - 'password, label and hash preset change (interactive label)', - [ - [['mmdat',pwfile],1] - ] - ) + ('walletgen_dfl_wallet', + (15, 'wallet generation (default wallet)', [[[], 15]]) + ), + ('subwalletgen_dfl_wallet', + (15, 'subwallet generation (default wallet)', [[[pwfile], 15]]) + ), + ('export_seed_dfl_wallet', + (15, 'seed export to mmseed format (default wallet)', [[[pwfile], 15]])), + ('addrgen_dfl_wallet', + (15, 'address generation (default wallet)', [[[pwfile], 15]]) + ), + ('txcreate_dfl_wallet', + (15, 'transaction creation (default wallet)', [[['addrs'], 15]]) + ), + ('txsign_dfl_wallet', + (15, 'transaction signing (default wallet)', [[['rawtx', pwfile], 15]]) + ), + ('passchg_dfl_wallet', + (16, 'password, label and hash preset change (default wallet)', [[[pwfile], 15]]) + ), + ('walletchk_newpass_dfl_wallet', + (16, 'wallet check with new pw, label and hash preset', [[[pwfile], 16]]) + ), + ('delete_dfl_wallet', + (15, 'delete default wallet', [[[pwfile], 15]]) + ), + ('walletgen', + (1, 'wallet generation', [[['del_dw_run'], 15]]) + ), + ('subwalletgen', + (1, 'subwallet generation', [[['mmdat'], 1]]) + ), + ('subwalletgen_mnemonic', + (1, 'subwallet generation (to mnemonic format)', [[['mmdat'], 1]]) + ), + # ('walletchk', (1, 'wallet check', [[['mmdat'], 1]])), + ('passchg', + (5, 'password, label and hash preset change', [[['mmdat', pwfile], 1]]) + ), + ('passchg_keeplabel', + (5, 'password, label and hash preset change (keep label)', [[['mmdat', pwfile], 1]]) + ), + ('passchg_usrlabel', + (5, 'password, label and hash preset change (interactive label)', [[['mmdat', pwfile], 1]]) + ), + ('walletchk_newpass', + (5, 'wallet check with new pw, label and hash preset', [[['mmdat', pwfile], 5]]) + ), + ('addrgen', + (1, 'address generation', [[['mmdat'], 1]]) + ), + ('txcreate', + (1, 'transaction creation', [[['addrs'], 1]]) + ), + ('txbump', + (1, 'transaction fee bumping (no send)', [[['rawtx'], 1]]) + ), + ('txsign', + (1, 'transaction signing', [[['mmdat', 'rawtx'], 1]]) + ), + ('txsend', + (1, 'transaction sending', [[['sigtx'], 1]]) ), - ('walletchk_newpass',(5,'wallet check with new pw, label and hash preset', [[['mmdat',pwfile],5]])), - ('addrgen', (1,'address generation', [[['mmdat'],1]])), - ('txcreate', (1,'transaction creation', [[['addrs'],1]])), - ('txbump', (1,'transaction fee bumping (no send)', [[['rawtx'],1]])), - ('txsign', (1,'transaction signing', [[['mmdat','rawtx'],1]])), - ('txsend', (1,'transaction sending', [[['sigtx'],1]])), # txdo must go after txsign - ('txdo', (1,'online transaction', [[['sigtx','mmdat'],1]])), - - ('export_seed', (1,'seed export to mmseed format', [[['mmdat'],1]])), - ('export_hex', (1,'seed export to hexadecimal format', [[['mmdat'],1]])), - ('export_mnemonic', (1,'seed export to mmwords format', [[['mmdat'],1]])), - ('export_bip39', (1,'seed export to bip39 format', [[['mmdat'],1]])), - ('export_incog', (1,'seed export to mmincog format', [[['mmdat'],1]])), - ('export_incog_hex',(1,'seed export to mmincog hex format', [[['mmdat'],1]])), - ('export_incog_hidden',(1,'seed export to hidden mmincog format', [[['mmdat'],1]])), - - ('addrgen_seed', (1,'address generation from mmseed file', [[['mmseed','addrs'],1]])), - ('addrgen_hex', (1,'address generation from mmhex file', [[['mmhex','addrs'],1]])), - ('addrgen_mnemonic',(1,'address generation from mmwords file', [[['mmwords','addrs'],1]])), - ('addrgen_incog', (1,'address generation from mmincog file', [[['mmincog','addrs'],1]])), - ('addrgen_incog_hex',(1,'address generation from mmincog hex file', [[['mmincox','addrs'],1]])), - ('addrgen_incog_hidden',(1,'address generation from hidden mmincog file', [[[hincog_fn,'addrs'],1]])), - - ('keyaddrgen', (1,'key-address file generation', [[['mmdat'],1]])), - ('txsign_keyaddr',(1,'transaction signing with key-address file', [[['akeys.mmenc','rawtx'],1]])), - - ('txcreate_ni', (1,'transaction creation (non-interactive)', [[['addrs'],1]])), - - ('walletgen2',(2,'wallet generation (2), 128-bit seed', [[['del_dw_run'],15]])), - ('addrgen2', (2,'address generation (2)', [[['mmdat'],2]])), - ('txcreate2', (2,'transaction creation (2)', [[['addrs'],2]])), - ('txsign2', ( - 2, - 'transaction signing, two transactions', - [ - [['mmdat','rawtx'],1], - [['mmdat','rawtx'],2] - ] - ) + ('txdo', + (1, 'online transaction', [[['sigtx', 'mmdat'], 1]]) ), - ('export_mnemonic2', ( - 2, - 'seed export to mmwords format (2)', - [ - [['mmdat'],2] - ] - ) + ('export_seed', + (1, 'seed export to mmseed format', [[['mmdat'], 1]]) ), - ('walletgen3',(3,'wallet generation (3)', [[['del_dw_run'],15]])), - ('addrgen3', (3,'address generation (3)', [[['mmdat'],3]])), - ('txcreate3', ( - 3, - 'tx creation with inputs and outputs from two wallets', - [ - [['addrs'],1], - [['addrs'],3] - ] - ) + ('export_hex', + (1, 'seed export to hexadecimal format', [[['mmdat'], 1]]) ), - ('txsign3', ( - 3, - 'tx signing with inputs and outputs from two wallets', - [ - [['mmdat'],1], - [['mmdat','rawtx'],3] - ] - ) + ('export_mnemonic', + (1, 'seed export to mmwords format', [[['mmdat'], 1]]) + ), + ('export_bip39', + (1, 'seed export to bip39 format', [[['mmdat'], 1]]) + ), + ('export_incog', + (1, 'seed export to mmincog format', [[['mmdat'], 1]]) + ), + ('export_incog_hex', + (1, 'seed export to mmincog hex format', [[['mmdat'], 1]]) + ), + ('export_incog_hidden', + (1, 'seed export to hidden mmincog format', [[['mmdat'], 1]]) + ), + ('addrgen_seed', + (1, 'address generation from mmseed file', [[['mmseed', 'addrs'], 1]]) + ), + ('addrgen_hex', + (1, 'address generation from mmhex file', [[['mmhex', 'addrs'], 1]]) + ), + ('addrgen_mnemonic', + (1, 'address generation from mmwords file', [[['mmwords', 'addrs'], 1]]) + ), + ('addrgen_incog', + (1, 'address generation from mmincog file', [[['mmincog', 'addrs'], 1]]) + ), + ('addrgen_incog_hex', + (1, 'address generation from mmincog hex file', [[['mmincox', 'addrs'], 1]]) + ), + ('addrgen_incog_hidden', + (1, 'address generation from hidden mmincog file', [[[hincog_fn, 'addrs'], 1]]) + ), + ('keyaddrgen', + (1, 'key-address file generation', [[['mmdat'], 1]]) + ), + ('txsign_keyaddr', + (1, 'transaction signing with key-address file', [[['akeys.mmenc', 'rawtx'], 1]]) + ), + ('txcreate_ni', + (1, 'transaction creation (non-interactive)', [[['addrs'], 1]]) + ), + ('walletgen2', + (2, 'wallet generation (2), 128-bit seed', [[['del_dw_run'], 15]]) + ), + ('addrgen2', + (2, 'address generation (2)', [[['mmdat'], 2]]) + ), + ('txcreate2', + (2, 'transaction creation (2)', [[['addrs'], 2]]) + ), + ('txsign2', + (2, 'transaction signing, two transactions', [[['mmdat', 'rawtx'], 1], [['mmdat', 'rawtx'], 2]]) + ), + ('export_mnemonic2', + (2, 'seed export to mmwords format (2)', [[['mmdat'], 2]]) + ), + ('walletgen3', + (3, 'wallet generation (3)', [[['del_dw_run'], 15]]) + ), + ('addrgen3', + (3, 'address generation (3)', [[['mmdat'], 3]]) + ), + ('txcreate3', + (3, 'tx creation with inputs and outputs from two wallets', [[['addrs'], 1], [['addrs'], 3]]) + ), + ('txsign3', + (3, 'tx signing with inputs and outputs from two wallets', [[['mmdat'], 1], [['mmdat', 'rawtx'], 3]]) + ), + ('walletgen14', + (14, 'wallet generation (14)', [[['del_dw_run'], 15]], 14) + ), + ('addrgen14', + (14, 'address generation (14)', [[['mmdat'], 14]]) + ), + ('keyaddrgen14', + (14, 'key-address file generation (14)', [[['mmdat'], 14]], 14) + ), + ('walletgen4', + (4, 'wallet generation (4) (brainwallet)', [[['del_dw_run'], 15]]) + ), + ('addrgen4', + (4, 'address generation (4)', [[['mmdat'], 4]]) ), - ('walletgen14', (14,'wallet generation (14)', [[['del_dw_run'],15]],14)), - ('addrgen14', (14,'address generation (14)', [[['mmdat'],14]])), - ('keyaddrgen14',(14,'key-address file generation (14)', [[['mmdat'],14]],14)), - ('walletgen4',(4,'wallet generation (4) (brainwallet)', [[['del_dw_run'],15]])), - ('addrgen4', (4,'address generation (4)', [[['mmdat'],4]])), ('txcreate4', ( - 4, - 'tx creation with inputs and outputs from four seed sources, key-address file ' - 'and non-MMGen inputs and outputs', - [ - [['addrs'],1], - [['addrs'],2], - [['addrs'],3], - [['addrs'],4], - [['addrs','akeys.mmenc'],14] - ] - ) + 4, + 'tx creation with inputs and outputs from four seed sources, key-address file ' + 'and non-MMGen inputs and outputs', + [ + [['addrs'], 1], + [['addrs'], 2], + [['addrs'], 3], + [['addrs'], 4], + [['addrs', 'akeys.mmenc'], 14] + ]) ), ('txsign4', ( - 4, - 'tx signing with inputs and outputs from incog file, mnemonic file, wallet, ' - 'brainwallet, key-address file and non-MMGen inputs and outputs', - [ - [['mmincog'],1], - [['mmwords'],2], - [['mmdat'],3], - [['mmbrain','rawtx'],4], - [['akeys.mmenc'],14] - ] - ) + 4, + 'tx signing with inputs and outputs from incog file, mnemonic file, wallet, ' + 'brainwallet, key-address file and non-MMGen inputs and outputs', + [ + [['mmincog'], 1], + [['mmwords'], 2], + [['mmdat'], 3], + [['mmbrain', 'rawtx'], 4], + [['akeys.mmenc'], 14] + ]) ), ('txdo4', ( - 4, - 'tx creation,signing and sending with inputs and outputs from four seed sources, ' - 'key-address file and non-MMGen inputs and outputs', - [ - [['addrs'],1], - [['addrs'],2], - [['addrs'],3], - [['addrs'],4], - [['addrs','akeys.mmenc'],14], - [['mmincog'],1], - [['mmwords'],2], - [['mmdat'],3], - [['mmbrain','rawtx'],4], - [['akeys.mmenc'],14] - ] - ) + 4, + 'tx creation, signing and sending with inputs and outputs from four seed sources, ' + 'key-address file and non-MMGen inputs and outputs', + [ + [['addrs'], 1], + [['addrs'], 2], + [['addrs'], 3], + [['addrs'], 4], + [['addrs', 'akeys.mmenc'], 14], + [['mmincog'], 1], + [['mmwords'], 2], + [['mmdat'], 3], + [['mmbrain', 'rawtx'], 4], + [['akeys.mmenc'], 14] + ]) ), # must go after txsign4 ('txbump4', ( - 4, - 'tx fee bump + send with inputs and outputs from four seed sources, key-address file ' - 'and non-MMGen inputs and outputs', - [ - [['akeys.mmenc'],14], - [['mmincog'],1], - [['mmwords'],2], - [['mmdat'],3], - [['akeys.mmenc'],14], - [['mmbrain','sigtx','mmdat','txdo'],4] - ] - ) + 4, + 'tx fee bump + send with inputs and outputs from four seed sources, key-address file ' + 'and non-MMGen inputs and outputs', + [ + [['akeys.mmenc'], 14], + [['mmincog'], 1], + [['mmwords'], 2], + [['mmdat'], 3], + [['akeys.mmenc'], 14], + [['mmbrain', 'sigtx', 'mmdat', 'txdo'], 4] + ]) ), # must go after txsign4 - - ('walletgen5',(20,'wallet generation (5)', [[['del_dw_run'],15]],20)), - ('addrgen5', (20,'address generation (5)', [[['mmdat'],20]])), - ('txcreate5', (20,'transaction creation with bad vsize (5)', [[['addrs'],20]])), - ('txsign5', (20,'transaction signing with bad vsize', [[['mmdat','rawtx'],20]])), - ('walletgen6',(21,'wallet generation (6)', [[['del_dw_run'],15]],21)), - ('addrgen6', (21,'address generation (6)', [[['mmdat'],21]])), - ('txcreate6', (21,'transaction creation with corrected vsize (6)', [[['addrs'],21]])), - ('txsign6', (21,'transaction signing with corrected vsize', [[['mmdat','rawtx'],21]])), + ('walletgen5', + (20, 'wallet generation (5)', [[['del_dw_run'], 15]], 20) + ), + ('addrgen5', + (20, 'address generation (5)', [[['mmdat'], 20]]) + ), + ('txcreate5', + (20, 'transaction creation with bad vsize (5)', [[['addrs'], 20]]) + ), + ('txsign5', + (20, 'transaction signing with bad vsize', [[['mmdat', 'rawtx'], 20]]) + ), + ('walletgen6', + (21, 'wallet generation (6)', [[['del_dw_run'], 15]], 21) + ), + ('addrgen6', + (21, 'address generation (6)', [[['mmdat'], 21]]) + ), + ('txcreate6', + (21, 'transaction creation with corrected vsize (6)', [[['addrs'], 21]]) + ), + ('txsign6', + (21, 'transaction signing with corrected vsize', [[['mmdat', 'rawtx'], 21]]) + ), ) segwit_do = ( 'walletgen', @@ -305,124 +375,124 @@ class CmdTestMain(CmdTestBase,CmdTestShared): 'txsign6', ) - def __init__(self,trunner,cfgs,spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + def __init__(self, trunner, cfgs, spawn): + CmdTestBase.__init__(self, trunner, cfgs, spawn) if trunner is None or self.coin not in self.networks: return - if self.coin in ('btc','bch','ltc'): - self.tx_fee = {'btc':'0.0001','bch':'0.001','ltc':'0.01'}[self.coin] - self.txbump_fee = {'btc':'123s','bch':'567s','ltc':'12345s'}[self.coin] + if self.coin in ('btc', 'bch', 'ltc'): + self.tx_fee = {'btc':'0.0001', 'bch':'0.001', 'ltc':'0.01'}[self.coin] + self.txbump_fee = {'btc':'123s', 'bch':'567s', 'ltc':'12345s'}[self.coin] - self.unspent_data_file = joinpath('test','trash','unspent.json') + self.unspent_data_file = joinpath('test', 'trash', 'unspent.json') self.spawn_env['MMGEN_BOGUS_UNSPENT_DATA'] = self.unspent_data_file @property def lbl_id(self): - if not hasattr(self,'_lbl_id'): - rpc = async_run(rpc_init(cfg,self.proto)) - self._lbl_id = ('account','label')['label_api' in rpc.caps] + if not hasattr(self, '_lbl_id'): + rpc = async_run(rpc_init(cfg, self.proto)) + self._lbl_id = ('account', 'label')['label_api' in rpc.caps] return self._lbl_id - def _get_addrfile_checksum(self,display=False): + def _get_addrfile_checksum(self, display=False): addrfile = self.get_file_with_ext('addrs') from mmgen.addrlist import AddrList silence() - chk = AddrList( cfg, self.proto, addrfile ).chksum + chk = AddrList(cfg, self.proto, addrfile).chksum end_silence() if cfg.verbose and display: msg(f'Checksum: {cyan(chk)}') return chk - def walletgen_dfl_wallet(self,seed_len=None): - return self.walletgen(seed_len=seed_len,gen_dfl_wallet=True) + def walletgen_dfl_wallet(self, seed_len=None): + return self.walletgen(seed_len=seed_len, gen_dfl_wallet=True) - def subwalletgen_dfl_wallet(self,pf): + def subwalletgen_dfl_wallet(self, pf): return self.subwalletgen(wf='default') - def export_seed_dfl_wallet(self,pf,out_fmt='seed'): - return self.export_seed(wf=None,out_fmt=out_fmt,pf=pf) + def export_seed_dfl_wallet(self, pf, out_fmt='seed'): + return self.export_seed(wf=None, out_fmt=out_fmt, pf=pf) def addrgen_dfl_wallet(self, pf): return self.addrgen(wf=None, dfl_wallet=True) - def txcreate_dfl_wallet(self,addrfile): + def txcreate_dfl_wallet(self, addrfile): return self.txcreate_common(sources=['15']) - def txsign_dfl_wallet(self,txfile,pf='',save=True,has_label=False): - return self.txsign(None,txfile,save=save,has_label=has_label,dfl_wallet=True) + def txsign_dfl_wallet(self, txfile, pf='', save=True, has_label=False): + return self.txsign(None, txfile, save=save, has_label=has_label, dfl_wallet=True) - def passchg_dfl_wallet(self,pf): - return self.passchg(wf=None,pf=pf,dfl_wallet=True) + def passchg_dfl_wallet(self, pf): + return self.passchg(wf=None, pf=pf, dfl_wallet=True) - def walletchk_newpass_dfl_wallet(self,pf): - return self.walletchk_newpass(wf=None,wcls=MMGenWallet,pf=pf,dfl_wallet=True) + def walletchk_newpass_dfl_wallet(self, pf): + return self.walletchk_newpass(wf=None, wcls=MMGenWallet, pf=pf, dfl_wallet=True) - def delete_dfl_wallet(self,pf): - self.write_to_tmpfile('del_dw_run',b'',binary=True) + def delete_dfl_wallet(self, pf): + self.write_to_tmpfile('del_dw_run', b'', binary=True) if cfg.no_dw_delete: return 'skip' for wf in [f for f in os.listdir(cfg.data_dir) if f[-6:]=='.mmdat']: - os.unlink(joinpath(cfg.data_dir,wf)) - self.spawn('',msg_only=True) + os.unlink(joinpath(cfg.data_dir, wf)) + self.spawn('', msg_only=True) self.have_dfl_wallet = False return 'ok' - def walletgen(self,del_dw_run='dummy',seed_len=None,gen_dfl_wallet=False): - self.write_to_tmpfile(pwfile,self.wpasswd+'\n') + def walletgen(self, del_dw_run='dummy', seed_len=None, gen_dfl_wallet=False): + self.write_to_tmpfile(pwfile, self.wpasswd+'\n') args = ['-p1'] if not gen_dfl_wallet: - args += ['-d',self.tmpdir] + args += ['-d', self.tmpdir] if seed_len: - args += ['-l',str(seed_len)] + args += ['-l', str(seed_len)] t = self.spawn('mmgen-walletgen', self.testnet_opt + args + [self.usr_rand_arg], no_passthru_opts=True) t.license() t.usr_rand(self.usr_rand_chars) wcls = MMGenWallet - t.passphrase_new('new '+wcls.desc,self.wpasswd) + t.passphrase_new('new '+wcls.desc, self.wpasswd) t.label() if not self.have_dfl_wallet and gen_dfl_wallet: - t.expect('move it to the data directory? (Y/n): ','y') + t.expect('move it to the data directory? (Y/n): ', 'y') self.have_dfl_wallet = True t.written_to_file(capfirst(wcls.desc)) return t - def subwalletgen(self,wf): - args = [self.usr_rand_arg,'-p1','-d',self.tr.trash_dir,'-L','Label'] + def subwalletgen(self, wf): + args = [self.usr_rand_arg, '-p1', '-d', self.tr.trash_dir, '-L', 'Label'] if wf != 'default': args += [wf] t = self.spawn('mmgen-subwalletgen', self.testnet_opt + args + ['10s'], no_passthru_opts=True) t.license() wcls = MMGenWallet - t.passphrase(wcls.desc,self.cfgs['1']['wpasswd']) - t.expect(r'Generating subseed.*\D10S',regex=True) - t.passphrase_new('new '+wcls.desc,'foo') + t.passphrase(wcls.desc, self.cfgs['1']['wpasswd']) + t.expect(r'Generating subseed.*\D10S', regex=True) + t.passphrase_new('new '+wcls.desc, 'foo') t.usr_rand(self.usr_rand_chars) fn = t.written_to_file(capfirst(wcls.desc)) ext = get_extension(fn) - assert ext,f'incorrect file extension: {ext}' + assert ext, f'incorrect file extension: {ext}' return t - def subwalletgen_mnemonic(self,wf): + def subwalletgen_mnemonic(self, wf): icls = get_wallet_cls(ext=get_extension(wf)) ocls = get_wallet_cls('words') - args = [self.usr_rand_arg,'-p1','-d',self.tr.trash_dir,'-o',ocls.fmt_codes[0],wf,'3L'] + args = [self.usr_rand_arg, '-p1', '-d', self.tr.trash_dir, '-o', ocls.fmt_codes[0], wf, '3L'] t = self.spawn('mmgen-subwalletgen', self.testnet_opt + args, no_passthru_opts=True) t.license() - t.passphrase(icls.desc,self.cfgs['1']['wpasswd']) - t.expect(r'Generating subseed.*\D3L',regex=True) + t.passphrase(icls.desc, self.cfgs['1']['wpasswd']) + t.expect(r'Generating subseed.*\D3L', regex=True) fn = t.written_to_file(capfirst(ocls.desc)) ext = get_extension(fn) - assert ext == ocls.ext,f'incorrect file extension: {ext}' + assert ext == ocls.ext, f'incorrect file extension: {ext}' return t - def passchg(self,wf,pf,label_action='cmdline',dfl_wallet=False,delete=False): + def passchg(self, wf, pf, label_action='cmdline', dfl_wallet=False, delete=False): silence() - self.write_to_tmpfile( pwfile, get_data_from_file(cfg,pf) ) + self.write_to_tmpfile(pwfile, get_data_from_file(cfg, pf)) end_silence() add_args = { - 'cmdline': ['-d',self.tmpdir,'-L','Changed label (UTF-8) α'], - 'keep': ['-d',self.tr.trash_dir,'--keep-label'], - 'user': ['-d',self.tr.trash_dir] + 'cmdline': ['-d', self.tmpdir, '-L', 'Changed label (UTF-8) α'], + 'keep': ['-d', self.tr.trash_dir, '--keep-label'], + 'user': ['-d', self.tr.trash_dir] }[label_action] t = self.spawn( 'mmgen-passchg', @@ -430,44 +500,51 @@ class CmdTestMain(CmdTestBase,CmdTestShared): no_passthru_opts = True) t.license() wcls = MMGenWallet - t.passphrase(wcls.desc,self.cfgs['1']['wpasswd'],pwtype='old') + t.passphrase(wcls.desc, self.cfgs['1']['wpasswd'], pwtype='old') t.expect_getend('Hash preset changed to ') - t.passphrase(wcls.desc,self.wpasswd,pwtype='new') # reuse passphrase? - t.expect('Repeat new passphrase: ',self.wpasswd+'\n') + t.passphrase(wcls.desc, self.wpasswd, pwtype='new') # reuse passphrase? + t.expect('Repeat new passphrase: ', self.wpasswd+'\n') t.usr_rand(self.usr_rand_chars) if label_action == 'user': - t.expect('Enter a wallet label.*: ','Interactive Label (UTF-8) α\n',regex=True) - t.expect_getend(('Label changed to ','Reusing label ')[label_action=='keep']) + t.expect('Enter a wallet label.*: ', 'Interactive Label (UTF-8) α\n', regex=True) + t.expect_getend(('Label changed to ', 'Reusing label ')[label_action=='keep']) # t.expect_getend('Key ID changed: ') if dfl_wallet: - t.expect("Type uppercase 'YES' to confirm: ",'YES\n') + t.expect("Type uppercase 'YES' to confirm: ", 'YES\n') t.written_to_file('New wallet') t.expect('Securely deleting old wallet') -# t.expect('Okay to WIPE 1 regular file ? (Yes/No)','Yes\n') +# t.expect('Okay to WIPE 1 regular file ? (Yes/No)', 'Yes\n') t.expect('Wallet passphrase has changed') t.expect_getend('has been changed to ') else: t.written_to_file(capfirst(wcls.desc)) - t.expect( 'Securely delete .*: ', ('y' if delete else 'n' ), regex=True ) + t.expect('Securely delete .*: ', ('y' if delete else 'n'), regex=True) if delete: - t.expect( 'Securely deleting' ) + t.expect('Securely deleting') return t - def passchg_keeplabel(self,wf,pf): - return self.passchg(wf,pf,label_action='keep',delete=True) + def passchg_keeplabel(self, wf, pf): + return self.passchg(wf, pf, label_action='keep', delete=True) - def passchg_usrlabel(self,wf,pf): - return self.passchg(wf,pf,label_action='user') + def passchg_usrlabel(self, wf, pf): + return self.passchg(wf, pf, label_action='user') - def walletchk_newpass(self,wf,pf,wcls=None,dfl_wallet=False): - return self.walletchk(wf,wcls=wcls,dfl_wallet=dfl_wallet) + def walletchk_newpass(self, wf, pf, wcls=None, dfl_wallet=False): + return self.walletchk(wf, wcls=wcls, dfl_wallet=dfl_wallet) - def _write_fake_data_to_file(self,d): - write_data_to_file(cfg,self.unspent_data_file,d,'Unspent outputs',quiet=True,ignore_opt_outdir=True) + def _write_fake_data_to_file(self, d): + write_data_to_file(cfg, self.unspent_data_file, d, 'Unspent outputs', quiet=True, ignore_opt_outdir=True) if cfg.verbose or cfg.exact_output: sys.stderr.write(f'Fake transaction wallet data written to file {self.unspent_data_file!r}\n') - def _create_fake_unspent_entry(self,coinaddr,al_id=None,idx=None,comment=None,non_mmgen=False,segwit=False): + def _create_fake_unspent_entry( + self, + coinaddr, + al_id = None, + idx = None, + comment = None, + non_mmgen = False, + segwit = False): if 'S' not in self.proto.mmtypes: segwit = False if comment: @@ -475,19 +552,25 @@ class CmdTestMain(CmdTestBase,CmdTestShared): k = coinaddr.addr_fmt if not segwit and k == 'p2sh': k = 'p2pkh' - s_beg,s_end = { 'p2pkh': ('76a914','88ac'), - 'p2sh': ('a914','87'), - 'bech32': (self.proto.witness_vernum_hex + '14','') }[k] - amt1,amt2 = {'btc':(10,40),'bch':(10,40),'ltc':(1000,4000)}[self.coin] + s_beg, s_end = { + 'p2pkh': ('76a914', '88ac'), + 'p2sh': ('a914', '87'), + 'bech32': (self.proto.witness_vernum_hex + '14', '') + }[k] + amt1, amt2 = { + 'btc': (10, 40), + 'bch': (10, 40), + 'ltc': (1000, 4000) + }[self.coin] ret = { self.lbl_id: ( f'{self.proto.base_coin.lower()}:{coinaddr}' if non_mmgen - else f'{al_id}:{idx}{comment}' ), + else f'{al_id}:{idx}{comment}'), 'vout': int(getrandnum(4) % 8), 'txid': getrandhex(32), 'amount': self.proto.coin_amt('{}.{}'.format( amt1 + getrandnum(4) % amt2, - getrandnum(4) % 100000000 )), + getrandnum(4) % 100000000)), 'address': coinaddr, 'spendable': False, 'scriptPubKey': f'{s_beg}{coinaddr.bytes.hex()}{s_end}', @@ -495,16 +578,23 @@ class CmdTestMain(CmdTestBase,CmdTestShared): } return ret - def _create_fake_unspent_data(self,adata,tx_data,non_mmgen_input='',non_mmgen_input_compressed=True): + def _create_fake_unspent_data( + self, + adata, + tx_data, + non_mmgen_input = '', + non_mmgen_input_compressed = True): out = [] for d in tx_data.values(): al = adata.addrlist(al_id=d['al_id']) - for n,(idx,coinaddr) in enumerate(al.addrpairs()): + for n, (idx, coinaddr) in enumerate(al.addrpairs()): comment = get_comment(do_shuffle=not cfg.test_suite_deterministic) - out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,comment,segwit=d['segwit'])) + out.append(self._create_fake_unspent_entry( + coinaddr, d['al_id'], idx, comment, segwit=d['segwit'])) if n == 0: # create a duplicate address. This means addrs_per_wallet += 1 - out.append(self._create_fake_unspent_entry(coinaddr,d['al_id'],idx,comment,segwit=d['segwit'])) + out.append(self._create_fake_unspent_entry( + coinaddr, d['al_id'], idx, comment, segwit=d['segwit'])) if non_mmgen_input: from mmgen.key import PrivKey @@ -512,36 +602,36 @@ class CmdTestMain(CmdTestBase,CmdTestShared): self.proto, getrand(32), compressed = non_mmgen_input_compressed, - pubkey_type = 'std' ) - from mmgen.addrgen import KeyGenerator,AddrGenerator + pubkey_type = 'std') + from mmgen.addrgen import KeyGenerator, AddrGenerator rand_coinaddr = AddrGenerator( cfg, self.proto, - ('legacy','compressed')[non_mmgen_input_compressed] - ).to_addr(KeyGenerator( cfg, self.proto, 'std' ).gen_data(privkey)) - of = joinpath(self.cfgs[non_mmgen_input]['tmpdir'],non_mmgen_fn) + ('legacy', 'compressed')[non_mmgen_input_compressed] + ).to_addr(KeyGenerator(cfg, self.proto, 'std').gen_data(privkey)) + of = joinpath(self.cfgs[non_mmgen_input]['tmpdir'], non_mmgen_fn) write_data_to_file( cfg = cfg, outfile = of, data = privkey.wif + '\n', desc = f'compressed {self.proto.name} key', quiet = True, - ignore_opt_outdir = True ) - out.append(self._create_fake_unspent_entry(rand_coinaddr,non_mmgen=True,segwit=False)) + ignore_opt_outdir = True) + out.append(self._create_fake_unspent_entry(rand_coinaddr, non_mmgen=True, segwit=False)) return out - def _create_tx_data(self,sources,addrs_per_wallet=addrs_per_wallet): - from mmgen.addrlist import AddrList,AddrIdxList + def _create_tx_data(self, sources, addrs_per_wallet=addrs_per_wallet): + from mmgen.addrlist import AddrList, AddrIdxList from mmgen.addrdata import AddrData - tx_data,ad = {},AddrData(self.proto) + tx_data, ad = {}, AddrData(self.proto) for s in sources: - addrfile = get_file_with_ext(self.cfgs[s]['tmpdir'],'addrs') - al = AddrList( cfg, self.proto, addrfile ) + addrfile = get_file_with_ext(self.cfgs[s]['tmpdir'], 'addrs') + al = AddrList(cfg, self.proto, addrfile) ad.add(al) aix = AddrIdxList(fmt_str=self.cfgs[s]['addr_idx_list']) if len(aix) != addrs_per_wallet: - die( 'TestSuiteFatalException', f'Address index list length != {addrs_per_wallet}: {repr(aix)}' ) + die('TestSuiteFatalException', f'Address index list length != {addrs_per_wallet}: {repr(aix)}') tx_data[s] = { 'addrfile': addrfile, 'chk': al.chksum, @@ -549,25 +639,29 @@ class CmdTestMain(CmdTestBase,CmdTestShared): 'addr_idxs': aix[-2:], 'segwit': self.cfgs[s]['segwit'] } - return ad,tx_data + return ad, tx_data - def _make_txcreate_cmdline(self,tx_data): + def _make_txcreate_cmdline(self, tx_data): from mmgen.key import PrivKey - privkey = PrivKey(self.proto,getrand(32),compressed=True,pubkey_type='std') - t = ('compressed','segwit')['S' in self.proto.mmtypes] - from mmgen.addrgen import KeyGenerator,AddrGenerator - rand_coinaddr = AddrGenerator( cfg, self.proto, t ).to_addr( - KeyGenerator( cfg, self.proto, 'std' ).gen_data(privkey) + privkey = PrivKey(self.proto, getrand(32), compressed=True, pubkey_type='std') + t = ('compressed', 'segwit')['S' in self.proto.mmtypes] + from mmgen.addrgen import KeyGenerator, AddrGenerator + rand_coinaddr = AddrGenerator(cfg, self.proto, t).to_addr( + KeyGenerator(cfg, self.proto, 'std').gen_data(privkey) ) # total of two outputs must be < 10 BTC (<1000 LTC) - mods = {'btc':(6,4),'bch':(6,4),'ltc':(600,400)}[self.coin] + mods = { + 'btc': (6, 4), + 'bch': (6, 4), + 'ltc': (600, 400) + }[self.coin] for k in self.cfgs: - self.cfgs[k]['amts'] = [None,None] - for idx,mod in enumerate(mods): + self.cfgs[k]['amts'] = [None, None] + for idx, mod in enumerate(mods): self.cfgs[k]['amts'][idx] = '{}.{}'.format( getrandnum(4) % mod, - str(getrandnum(4))[:5] ) + str(getrandnum(4))[:5]) cmd_args = ['--outdir='+self.tmpdir] for num in tx_data: @@ -576,17 +670,17 @@ class CmdTestMain(CmdTestBase,CmdTestShared): '{}:{},{}'.format( s['al_id'], s['addr_idxs'][0], - self.cfgs[num]['amts'][0] )] + self.cfgs[num]['amts'][0])] # + one change address and one BTC address if num is list(tx_data.keys())[-1]: cmd_args += [ '{}:{}'.format( s['al_id'], - s['addr_idxs'][1] )] + s['addr_idxs'][1])] cmd_args += [ '{},{}'.format( rand_coinaddr, - self.cfgs[num]['amts'][1] )] + self.cfgs[num]['amts'][1])] return cmd_args + [tx_data[num]['addrfile'] for num in tx_data] @@ -607,20 +701,20 @@ class CmdTestMain(CmdTestBase,CmdTestShared): sys.stderr.write(green('Generating fake tracking wallet info\n')) silence() - ad,tx_data = self._create_tx_data(sources,addrs_per_wallet) - dfake = self._create_fake_unspent_data(ad,tx_data,non_mmgen_input,non_mmgen_input_compressed) + ad, tx_data = self._create_tx_data(sources, addrs_per_wallet) + dfake = self._create_fake_unspent_data(ad, tx_data, non_mmgen_input, non_mmgen_input_compressed) import json from mmgen.rpc import json_encoder - self._write_fake_data_to_file(json.dumps(dfake,cls=json_encoder)) + self._write_fake_data_to_file(json.dumps(dfake, cls=json_encoder)) cmd_args = self._make_txcreate_cmdline(tx_data) if cmdline_inputs: from mmgen.tw.shared import TwLabel cmd_args = [ '--inputs={},{},{},{},{},{}'.format( - TwLabel(self.proto,dfake[0][self.lbl_id]).mmid, dfake[1]['address'], - TwLabel(self.proto,dfake[2][self.lbl_id]).mmid, dfake[3]['address'], - TwLabel(self.proto,dfake[4][self.lbl_id]).mmid, dfake[5]['address'] + TwLabel(self.proto, dfake[0][self.lbl_id]).mmid, dfake[1]['address'], + TwLabel(self.proto, dfake[2][self.lbl_id]).mmid, dfake[3]['address'], + TwLabel(self.proto, dfake[4][self.lbl_id]).mmid, dfake[5]['address'] ), f'--outdir={self.tr.trash_dir}' ] + cmd_args[1:] @@ -631,12 +725,12 @@ class CmdTestMain(CmdTestBase,CmdTestShared): sys.stderr.write('\n') t = self.spawn( - 'mmgen-'+('txcreate','txdo')[bool(txdo_args)], - (['--no-rbf'],[])[self.proto.cap('rbf')] + - ['-f',self.tx_fee,'-B'] + add_args + cmd_args + txdo_args) + 'mmgen-'+('txcreate', 'txdo')[bool(txdo_args)], + (['--no-rbf'], [])[self.proto.cap('rbf')] + + ['-f', self.tx_fee, '-B'] + add_args + cmd_args + txdo_args) - if t.expect([('Get','Unsigned transac')[cmdline_inputs],r'Unable to connect to \S+'],regex=True) == 1: - die( 'TestSuiteException', '\n'+t.p.after ) + if t.expect([('Get', 'Unsigned transac')[cmdline_inputs], r'Unable to connect to \S+'], regex=True) == 1: + die('TestSuiteException', '\n'+t.p.after) if cmdline_inputs: t.written_to_file('tion') @@ -646,86 +740,86 @@ class CmdTestMain(CmdTestBase,CmdTestShared): for num in tx_data: t.expect_getend('ting address data from file ') - chk=t.expect_getend(r'Checksum for address data .*?: ',regex=True) - verify_checksum_or_exit(tx_data[num]['chk'],chk) + chk=t.expect_getend(r'Checksum for address data .*?: ', regex=True) + verify_checksum_or_exit(tx_data[num]['chk'], chk) # not in tracking wallet warning, (1 + num sources) times for num in range(len(tx_data) + 1): - t.expect('Continue anyway? (y/N): ','y') + t.expect('Continue anyway? (y/N): ', 'y') outputs_list = [(addrs_per_wallet+1)*i + 1 for i in range(len(tx_data))] if non_mmgen_input: outputs_list.append(len(tx_data)*(addrs_per_wallet+1) + 1) self.txcreate_ui_common(t, - menu = (['M'],['M','D','D','D','D','m','o'])[self.test_name=='txcreate'], - inputs = ' '.join(map(str,outputs_list)), - add_comment = ('',tx_comment_lat_cyr_gr)[do_label], + menu = (['M'], ['M', 'D', 'D', 'D', 'D', 'm', 'o'])[self.test_name=='txcreate'], + inputs = ' '.join(map(str, outputs_list)), + add_comment = ('', tx_comment_lat_cyr_gr)[do_label], view = view, - tweaks = tweaks ) + tweaks = tweaks) if txdo_args and add_args: # txdo4 t.do_decrypt_ka_data(pw=self.cfgs['14']['kapasswd']) return t - def txcreate(self,addrfile): - return self.txcreate_common(sources=['1'],add_args=['--vsize-adj=1.01']) + def txcreate(self, addrfile): + return self.txcreate_common(sources=['1'], add_args=['--vsize-adj=1.01']) - def txbump(self,txfile,prepend_args=[],seed_args=[]): + def txbump(self, txfile, prepend_args=[], seed_args=[]): if not self.proto.cap('rbf'): msg(gray('Skipping RBF')) return 'skip' - args = prepend_args + ['--quiet','--outdir='+self.tmpdir,txfile] + seed_args - t = self.spawn('mmgen-txbump',args) + args = prepend_args + ['--quiet', '--outdir='+self.tmpdir, txfile] + seed_args + t = self.spawn('mmgen-txbump', args) if seed_args: t.do_decrypt_ka_data(pw=self.cfgs['14']['kapasswd']) - t.expect('deduct the fee from (Hit ENTER for the change output): ','1\n') + t.expect('deduct the fee from (Hit ENTER for the change output): ', '1\n') # Fee must be > tx_fee + network relay fee (currently 0.00001) - t.expect('OK? (Y/n): ','\n') - t.expect('Enter transaction fee: ',self.txbump_fee+'\n') - t.expect('OK? (Y/n): ','\n') + t.expect('OK? (Y/n): ', '\n') + t.expect('Enter transaction fee: ', self.txbump_fee+'\n') + t.expect('OK? (Y/n): ', '\n') if seed_args: # sign and send - t.do_comment(False,has_label=True) - for cnum,wcls in (('1',IncogWallet),('3',MMGenWallet),('4',MMGenWallet)): - t.passphrase(wcls.desc,self.cfgs[cnum]['wpasswd']) - self._do_confirm_send(t,quiet=not cfg.debug,confirm_send=True) + t.do_comment(False, has_label=True) + for cnum, wcls in (('1', IncogWallet), ('3', MMGenWallet), ('4', MMGenWallet)): + t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) + self._do_confirm_send(t, quiet=not cfg.debug, confirm_send=True) if cfg.debug: t.written_to_file('Transaction') else: t.do_comment(False) - t.expect('Save fee-bumped transaction? (y/N): ','y') + t.expect('Save fee-bumped transaction? (y/N): ', 'y') t.written_to_file('Fee-bumped transaction') os.unlink(txfile) # our tx file replaces the original - cmd = 'touch ' + joinpath(self.tmpdir,'txbump') + cmd = 'touch ' + joinpath(self.tmpdir, 'txbump') os.system(cmd) return t - def txsend(self,sigfile,extra_opts=[]): - t = self.spawn('mmgen-txsend', extra_opts + ['-d',self.tmpdir,sigfile]) - self.txsend_ui_common(t,view='t',add_comment='') + def txsend(self, sigfile, extra_opts=[]): + t = self.spawn('mmgen-txsend', extra_opts + ['-d', self.tmpdir, sigfile]) + self.txsend_ui_common(t, view='t', add_comment='') return t - def txdo(self,addrfile,wallet): - t = self.txcreate_common(sources=['1'],txdo_args=[wallet]) - self.txsign_ui_common(t,view='n',do_passwd=True) + def txdo(self, addrfile, wallet): + t = self.txcreate_common(sources=['1'], txdo_args=[wallet]) + self.txsign_ui_common(t, view='n', do_passwd=True) self.txsend_ui_common(t) return t - def _walletconv_export(self,wf,uargs=[],out_fmt='w',pf=None): - opts = ['-d',self.tmpdir,'-o',out_fmt] + uargs + \ - ([],[wf])[bool(wf)] + ([],['-P',pf])[bool(pf)] + def _walletconv_export(self, wf, uargs=[], out_fmt='w', pf=None): + opts = ['-d', self.tmpdir, '-o', out_fmt] + uargs + \ + ([], [wf])[bool(wf)] + ([], ['-P', pf])[bool(pf)] t = self.spawn('mmgen-walletconv', self.testnet_opt + opts, no_passthru_opts=True) t.license() if not pf: icls = get_wallet_cls(ext=get_extension(wf)) - t.passphrase(icls.desc,self.wpasswd) + t.passphrase(icls.desc, self.wpasswd) ocls = get_wallet_cls(fmt_code=out_fmt) if ocls.enc and ocls.type != 'brain': - t.passphrase_new('new '+ocls.desc,self.wpasswd) + t.passphrase_new('new '+ocls.desc, self.wpasswd) t.usr_rand(self.usr_rand_chars) if ocls.type.startswith('incog'): @@ -736,48 +830,48 @@ class CmdTestMain(CmdTestBase,CmdTestShared): t.expect(m) if ocls.type == 'incog_hidden': - self.write_to_tmpfile(incog_id_fn,incog_id) + self.write_to_tmpfile(incog_id_fn, incog_id) t.hincog_create(hincog_bytes) elif ocls.type == 'mmgen': t.label() return t.written_to_file(capfirst(ocls.desc)), t - def export_seed(self,wf,out_fmt='seed',pf=None): - f,t = self._walletconv_export(wf,out_fmt=out_fmt,pf=pf) + def export_seed(self, wf, out_fmt='seed', pf=None): + f, t = self._walletconv_export(wf, out_fmt=out_fmt, pf=pf) silence() wcls = get_wallet_cls(fmt_code=out_fmt) msg('==> {}: {}'.format( wcls.desc, - cyan(get_data_from_file( cfg, f, wcls.desc )) + cyan(get_data_from_file(cfg, f, wcls.desc)) )) end_silence() return t - def export_hex(self,wf,out_fmt='mmhex',pf=None): - return self.export_seed(wf,out_fmt=out_fmt,pf=pf) + def export_hex(self, wf, out_fmt='mmhex', pf=None): + return self.export_seed(wf, out_fmt=out_fmt, pf=pf) - def export_mnemonic(self,wf): - return self.export_seed(wf,out_fmt='words') + def export_mnemonic(self, wf): + return self.export_seed(wf, out_fmt='words') - def export_bip39(self,wf): - return self.export_seed(wf,out_fmt='bip39') + def export_bip39(self, wf): + return self.export_seed(wf, out_fmt='bip39') - def export_incog(self,wf,out_fmt='i',add_args=[]): - uargs = ['-p1',self.usr_rand_arg] + add_args - _,t = self._walletconv_export(wf,out_fmt=out_fmt,uargs=uargs) + def export_incog(self, wf, out_fmt='i', add_args=[]): + uargs = ['-p1', self.usr_rand_arg] + add_args + _, t = self._walletconv_export(wf, out_fmt=out_fmt, uargs=uargs) return t - def export_incog_hex(self,wf): - return self.export_incog(wf,out_fmt='xi') + def export_incog_hex(self, wf): + return self.export_incog(wf, out_fmt='xi') # TODO: make outdir and hidden incog compatible (ignore --outdir and warn user?) - def export_incog_hidden(self,wf): - rf = joinpath(self.tmpdir,hincog_fn) - add_args = ['-J',f'{rf},{hincog_offset}'] - return self.export_incog(wf,out_fmt='hi',add_args=add_args) + def export_incog_hidden(self, wf): + rf = joinpath(self.tmpdir, hincog_fn) + add_args = ['-J', f'{rf},{hincog_offset}'] + return self.export_incog(wf, out_fmt='hi', add_args=add_args) - def addrgen_seed(self,wf,_,in_fmt='seed'): + def addrgen_seed(self, wf, _, in_fmt='seed'): wcls = get_wallet_cls(fmt_code=in_fmt) stdout = wcls.type == 'seed' # capture output to screen once t = self.spawn( @@ -791,18 +885,18 @@ class CmdTestMain(CmdTestBase,CmdTestShared): vmsg('Comparing generated checksum with checksum from previous address file') verify_checksum_or_exit( self._get_addrfile_checksum(), - t.expect_getend(r'Checksum for address data .*?: ',regex=True) ) + t.expect_getend(r'Checksum for address data .*?: ', regex=True)) if not stdout: t.no_overwrite() return t - def addrgen_hex(self,wf,_,in_fmt='mmhex'): - return self.addrgen_seed(wf,_,in_fmt=in_fmt) + def addrgen_hex(self, wf, _, in_fmt='mmhex'): + return self.addrgen_seed(wf, _, in_fmt=in_fmt) - def addrgen_mnemonic(self,wf,_): - return self.addrgen_seed(wf,_,in_fmt='words') + def addrgen_mnemonic(self, wf, _): + return self.addrgen_seed(wf, _, in_fmt='words') - def addrgen_incog(self,wf=[],_='',in_fmt='i',args=[]): + def addrgen_incog(self, wf=[], _='', in_fmt='i', args=[]): t = self.spawn( 'mmgen-addrgen', args @@ -814,71 +908,71 @@ class CmdTestMain(CmdTestBase,CmdTestShared): t.license() t.expect_getend('Incog Wallet ID: ') wcls = get_wallet_cls(fmt_code=in_fmt) - t.hash_preset(wcls.desc,'1') - t.passphrase(rf'{wcls.desc} \w{{8}}',self.wpasswd) + t.hash_preset(wcls.desc, '1') + t.passphrase(rf'{wcls.desc} \w{{8}}', self.wpasswd) vmsg('Comparing generated checksum with checksum from address file') - chk = t.expect_getend(r'Checksum for address data .*?: ',regex=True) - verify_checksum_or_exit(self._get_addrfile_checksum(),chk) + chk = t.expect_getend(r'Checksum for address data .*?: ', regex=True) + verify_checksum_or_exit(self._get_addrfile_checksum(), chk) t.no_overwrite() return t - def addrgen_incog_hex(self,wf,_): - return self.addrgen_incog(wf,'',in_fmt='xi') + def addrgen_incog_hex(self, wf, _): + return self.addrgen_incog(wf, '', in_fmt='xi') - def addrgen_incog_hidden(self,wf,_): - rf = joinpath(self.tmpdir,hincog_fn) - return self.addrgen_incog([],'',in_fmt='hi', - args=['-H',f'{rf},{hincog_offset}','-l',str(hincog_seedlen)]) + def addrgen_incog_hidden(self, wf, _): + rf = joinpath(self.tmpdir, hincog_fn) + return self.addrgen_incog([], '', in_fmt='hi', + args=['-H', f'{rf},{hincog_offset}', '-l', str(hincog_seedlen)]) - def txsign_keyaddr(self,keyaddr_file,txfile): - t = self.spawn('mmgen-txsign', ['-d',self.tmpdir,'-p1','-M',keyaddr_file,txfile]) + def txsign_keyaddr(self, keyaddr_file, txfile): + t = self.spawn('mmgen-txsign', ['-d', self.tmpdir, '-p1', '-M', keyaddr_file, txfile]) t.license() t.view_tx('n') t.do_decrypt_ka_data(pw=self.kapasswd) self.txsign_end(t) return t - def txcreate_ni(self,addrfile): - return self.txcreate_common(sources=['1'],cmdline_inputs=True,add_args=['--yes']) + def txcreate_ni(self, addrfile): + return self.txcreate_common(sources=['1'], cmdline_inputs=True, add_args=['--yes']) - def walletgen2(self,del_dw_run='dummy'): + def walletgen2(self, del_dw_run='dummy'): return self.walletgen(seed_len=128) - def addrgen2(self,wf): + def addrgen2(self, wf): return self.addrgen(wf) - def txcreate2(self,addrfile): + def txcreate2(self, addrfile): return self.txcreate_common(sources=['2']) - def txsign2(self,wf1,txf1,wf2,txf2): - t = self.spawn('mmgen-txsign', ['-d',self.tmpdir,txf1,wf1,txf2,wf2]) + def txsign2(self, wf1, txf1, wf2, txf2): + t = self.spawn('mmgen-txsign', ['-d', self.tmpdir, txf1, wf1, txf2, wf2]) t.license() - for cnum,wf in (('1',wf1),('2',wf2)): + for cnum, wf in (('1', wf1), ('2', wf2)): wcls = get_wallet_cls(ext=get_extension(wf)) t.view_tx('n') - t.passphrase(wcls.desc,self.cfgs[cnum]['wpasswd']) - self.txsign_end(t,cnum) + t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) + self.txsign_end(t, cnum) return t - def export_mnemonic2(self,wf): + def export_mnemonic2(self, wf): return self.export_mnemonic(wf) - def walletgen3(self,del_dw_run='dummy'): + def walletgen3(self, del_dw_run='dummy'): return self.walletgen() - def addrgen3(self,wf): + def addrgen3(self, wf): return self.addrgen(wf) - def txcreate3(self,addrfile1,addrfile2): - return self.txcreate_common(sources=['1','3']) + def txcreate3(self, addrfile1, addrfile2): + return self.txcreate_common(sources=['1', '3']) - def txsign3(self,wf1,wf2,txf2): - t = self.spawn('mmgen-txsign', ['-d',self.tmpdir,wf1,wf2,txf2]) + def txsign3(self, wf1, wf2, txf2): + t = self.spawn('mmgen-txsign', ['-d', self.tmpdir, wf1, wf2, txf2]) t.license() t.view_tx('n') - for cnum,wf in (('1',wf1),('3',wf2)): + for cnum, wf in (('1', wf1), ('3', wf2)): wcls = get_wallet_cls(ext=get_extension(wf)) - t.passphrase(wcls.desc,self.cfgs[cnum]['wpasswd']) + t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) self.txsign_end(t) return t @@ -886,33 +980,33 @@ class CmdTestMain(CmdTestBase,CmdTestShared): addrgen14 = CmdTestShared.addrgen keyaddrgen14 = CmdTestShared.keyaddrgen - def walletgen4(self,del_dw_run='dummy'): - bwf = joinpath(self.tmpdir,self.bw_filename) + def walletgen4(self, del_dw_run='dummy'): + bwf = joinpath(self.tmpdir, self.bw_filename) make_brainwallet_file(bwf) seed_len = str(self.seed_len) - args = ['-d',self.tmpdir,'-p1',self.usr_rand_arg,'-l'+seed_len,'-ibw'] + args = ['-d', self.tmpdir, '-p1', self.usr_rand_arg, '-l'+seed_len, '-ibw'] t = self.spawn('mmgen-walletconv', self.testnet_opt + args + [bwf], no_passthru_opts=True) t.license() wcls = MMGenWallet - t.passphrase_new('new ' +wcls.desc,self.wpasswd) + t.passphrase_new('new ' +wcls.desc, self.wpasswd) t.usr_rand(self.usr_rand_chars) t.label() t.written_to_file(capfirst(wcls.desc)) return t - def addrgen4(self,wf): + def addrgen4(self, wf): return self.addrgen(wf) - def txcreate4(self,f1,f2,f3,f4,f5,f6): + def txcreate4(self, f1, f2, f3, f4, f5, f6): return self.txcreate_common( sources = ['1', '2', '3', '4', '14'], non_mmgen_input = '4', do_label = True, view = 'y', - tweaks = ['confirm_non_mmgen'] ) + tweaks = ['confirm_non_mmgen']) - def txsign4(self,f1,f2,f3,f4,f5,f6): - non_mm_file = joinpath(self.tmpdir,non_mmgen_fn) + def txsign4(self, f1, f2, f3, f4, f5, f6): + non_mm_file = joinpath(self.tmpdir, non_mmgen_fn) add_args = [ '-d', self.tmpdir, '-i', 'brain', @@ -920,60 +1014,67 @@ class CmdTestMain(CmdTestBase,CmdTestShared): '-p1', '--keys-from-file=' + non_mm_file, '--mmgen-keys-from-file=' + f6, - f1, f2, f3, f4, f5 ] - t = self.spawn('mmgen-txsign',add_args) + f1, f2, f3, f4, f5] + t = self.spawn('mmgen-txsign', add_args) t.license() t.view_tx('t') t.do_decrypt_ka_data(pw=self.cfgs['14']['kapasswd']) - for cnum,wcls in (('1',IncogWallet),('3',MMGenWallet)): - t.passphrase(wcls.desc,self.cfgs[cnum]['wpasswd']) + for cnum, wcls in (('1', IncogWallet), ('3', MMGenWallet)): + t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) - self.txsign_end(t,has_label=True) + self.txsign_end(t, has_label=True) return t - def txdo4(self,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12): - non_mm_file = joinpath(self.tmpdir,non_mmgen_fn) + def txdo4(self, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12): + non_mm_file = joinpath(self.tmpdir, non_mmgen_fn) add_args = [ '-d', self.tmpdir, '-i', 'brain', '-b'+self.bw_params, '-p1', '--keys-from-file=' + non_mm_file, - '--mmgen-keys-from-file=' + f12 ] - self.get_file_with_ext('sigtx',delete_all=True) # delete tx signed by txsign4 - t = self.txcreate_common(sources=['1','2','3','4','14'], - non_mmgen_input='4',do_label=True,txdo_args=[f7,f8,f9,f10],add_args=add_args) + '--mmgen-keys-from-file=' + f12] + self.get_file_with_ext('sigtx', delete_all=True) # delete tx signed by txsign4 + t = self.txcreate_common( + sources = ['1', '2', '3', '4', '14'], + non_mmgen_input = '4', + do_label = True, + txdo_args = [f7, f8, f9, f10], + add_args = add_args) - for cnum,wcls in (('1',IncogWallet),('3',MMGenWallet)): - t.passphrase(wcls.desc,self.cfgs[cnum]['wpasswd']) + for cnum, wcls in (('1', IncogWallet), ('3', MMGenWallet)): + t.passphrase(wcls.desc, self.cfgs[cnum]['wpasswd']) self.txsign_ui_common(t) self.txsend_ui_common(t) - cmd = 'touch ' + joinpath(self.tmpdir,'txdo') + cmd = 'touch ' + joinpath(self.tmpdir, 'txdo') os.system(cmd) return t - def txbump4(self,f1,f2,f3,f4,f5,f6,f7,f8,f9): # f7:txfile,f9:'txdo' - non_mm_file = joinpath(self.tmpdir,non_mmgen_fn) - return self.txbump(f7,prepend_args=['-p1','-k',non_mm_file,'-M',f1],seed_args=[f2,f3,f4,f5,f6,f8]) + def txbump4(self, f1, f2, f3, f4, f5, f6, f7, f8, f9): # f7:txfile, f9:'txdo' + non_mm_file = joinpath(self.tmpdir, non_mmgen_fn) + return self.txbump( + f7, + prepend_args = ['-p1', '-k', non_mm_file, '-M', f1], + seed_args = [f2, f3, f4, f5, f6, f8]) - def walletgen5(self,del_dw_run='dummy'): + def walletgen5(self, del_dw_run='dummy'): return self.walletgen() - def addrgen5(self,wf): + def addrgen5(self, wf): return self.addrgen(wf) - def txcreate5(self,addrfile): + def txcreate5(self, addrfile): return self.txcreate_common( sources = ['20'], non_mmgen_input = '20', non_mmgen_input_compressed = False, - tweaks = ['confirm_non_mmgen'] ) + tweaks = ['confirm_non_mmgen']) - def txsign5(self,wf,txf,bad_vsize=True,add_args=[]): - non_mm_file = joinpath(self.tmpdir,non_mmgen_fn) + def txsign5(self, wf, txf, bad_vsize=True, add_args=[]): + non_mm_file = joinpath(self.tmpdir, non_mmgen_fn) t = self.spawn( 'mmgen-txsign', add_args + ['-d', self.tmpdir, '-k', non_mm_file, txf, wf], @@ -981,28 +1082,28 @@ class CmdTestMain(CmdTestBase,CmdTestShared): t.license() t.view_tx('n') wcls = get_wallet_cls(ext=get_extension(wf)) - t.passphrase(wcls.desc,self.cfgs['20']['wpasswd']) + t.passphrase(wcls.desc, self.cfgs['20']['wpasswd']) if bad_vsize: t.expect('Estimated transaction vsize') t.expect('1 transaction could not be signed') else: t.do_comment(False) - t.expect('Save signed transaction? (Y/n): ','y') + t.expect('Save signed transaction? (Y/n): ', 'y') return t - def walletgen6(self,del_dw_run='dummy'): + def walletgen6(self, del_dw_run='dummy'): return self.walletgen() - def addrgen6(self,wf): + def addrgen6(self, wf): return self.addrgen(wf) - def txcreate6(self,addrfile): + def txcreate6(self, addrfile): return self.txcreate_common( sources = ['21'], non_mmgen_input = '21', non_mmgen_input_compressed = False, add_args = ['--vsize-adj=1.08'], - tweaks = ['confirm_non_mmgen'] ) + tweaks = ['confirm_non_mmgen']) - def txsign6(self,wf,txf): - return self.txsign5(wf,txf,bad_vsize=False,add_args=['--vsize-adj=1.08']) + def txsign6(self, wf, txf): + return self.txsign5(wf, txf, bad_vsize=False, add_args=['--vsize-adj=1.08']) diff --git a/test/cmdtest_py_d/ct_misc.py b/test/cmdtest_py_d/ct_misc.py index 1a82ae89..d33a955c 100755 --- a/test/cmdtest_py_d/ct_misc.py +++ b/test/cmdtest_py_d/ct_misc.py @@ -39,8 +39,8 @@ class CmdTestDev(CmdTestBase): tmpdir_nums = [99] color = True - def _spawn(self,script,args): - return self.spawn(script,args,cmd_dir='.',no_exec_wrapper=True) + def _spawn(self, script, args): + return self.spawn(script, args, cmd_dir='.', no_exec_wrapper=True) def compute_file_chksum(self): t = self._spawn('scripts/compute-file-chksum.py', ['test/ref/25EFA3[2.34].testnet.rawtx']) @@ -50,28 +50,29 @@ class CmdTestDev(CmdTestBase): def create_bip_hd_chain_params(self): t = self._spawn('scripts/create-bip-hd-chain-params.py', ['test/ref/altcoin/slip44-mini.json']) t.expect('[defaults]') - t.expect(r"secp.*0488ade4.*0488b21e.*0'\/0\/0",regex=True) + t.expect(r"secp.*0488ade4.*0488b21e.*0'\/0\/0", regex=True) t.expect('[bip-44]') t.expect('[bip-49]') - t.match_expect_list(['0','BTC','x','m','P2SH','049d7878','049d7cb2','80','05','x','Bitcoin','1']) + t.match_expect_list( + ['0', 'BTC', 'x', 'm', 'P2SH', '049d7878', '049d7cb2', '80', '05', 'x', 'Bitcoin', '1']) return t class CmdTestMisc(CmdTestBase): 'miscellaneous tests (RPC backends, xmrwallet_txview, term)' networks = ('btc',) tmpdir_nums = [99] - passthru_opts = ('daemon_data_dir','rpc_port') + passthru_opts = ('daemon_data_dir', 'rpc_port') cmd_group = ( ('rpc_backends', 'RPC backends'), - ('bch_txview_legacy1', "'mmgen-tool --coin=bch --cashaddr=0 txview terse=0'"), - ('bch_txview_legacy2', "'mmgen-tool --coin=bch --cashaddr=0 txview terse=1'"), - ('bch_txview_cashaddr1', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=0'"), - ('bch_txview_cashaddr2', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=1'"), - ('xmrwallet_txview', "'mmgen-xmrwallet' txview"), - ('xmrwallet_txlist', "'mmgen-xmrwallet' txlist"), - ('coin_daemon_info', "'examples/coin-daemon-info.py'"), - ('examples_bip_hd', "'examples/bip_hd.py'"), - ('term_echo', "term.set('echo')"), + ('bch_txview_legacy1', '‘mmgen-tool --coin=bch --cashaddr=0 txview terse=0’'), + ('bch_txview_legacy2', '‘mmgen-tool --coin=bch --cashaddr=0 txview terse=1’'), + ('bch_txview_cashaddr1', '‘mmgen-tool --coin=bch --cashaddr=1 txview terse=0’'), + ('bch_txview_cashaddr2', '‘mmgen-tool --coin=bch --cashaddr=1 txview terse=1’'), + ('xmrwallet_txview', '‘mmgen-xmrwallet txview’'), + ('xmrwallet_txlist', '‘mmgen-xmrwallet txlist’'), + ('coin_daemon_info', '‘examples/coin-daemon-info.py’'), + ('examples_bip_hd', '‘examples/bip_hd.py’'), + ('term_echo', 'term.set("echo")'), ('term_cleanup', 'term.register_cleanup()'), ) need_daemon = True @@ -80,7 +81,7 @@ class CmdTestMisc(CmdTestBase): def rpc_backends(self): backends = cfg._autoset_opts['rpc_backend'][1] for b in backends: - t = self.spawn_chk('mmgen-tool',[f'--rpc-backend={b}','daemon_version'],extra_desc=f'({b})') + t = self.spawn_chk('mmgen-tool', [f'--rpc-backend={b}', 'daemon_version'], extra_desc=f'({b})') return t def _bch_txview(self, view_pref, terse, expect): @@ -104,11 +105,11 @@ class CmdTestMisc(CmdTestBase): def bch_txview_cashaddr2(self): return self._bch_txview(1, 1, '[1HpynST7vkLn8yNtdrqPfeghexZk4sdB3W]') - def xmrwallet_txview(self,op='txview'): + def xmrwallet_txview(self, op='txview'): if cfg.no_altcoin: return 'skip' - files = get_file_with_ext('test/ref/monero','tx',no_dot=True,delete=False,return_list=True) - t = self.spawn( 'mmgen-xmrwallet', [op] + files ) + files = get_file_with_ext('test/ref/monero', 'tx', no_dot=True, delete=False, return_list=True) + t = self.spawn('mmgen-xmrwallet', [op] + files) res = t.read(strip_color=True) if op == 'txview': for s in ( @@ -117,7 +118,7 @@ class CmdTestMisc(CmdTestBase): ): assert s in res, f'{s} not in {res}' elif op == 'txlist': - assert re.search( '3EBD06-.*D94583-.*8BFA29-', res, re.DOTALL ) + assert re.search('3EBD06-.*D94583-.*8BFA29-', res, re.DOTALL) return t def xmrwallet_txlist(self): @@ -126,31 +127,31 @@ class CmdTestMisc(CmdTestBase): def examples_bip_hd(self): if cfg.no_altcoin: return 'skip' - return self.spawn('examples/bip_hd.py',cmd_dir='.') + return self.spawn('examples/bip_hd.py', cmd_dir='.') def coin_daemon_info(self): if cfg.no_altcoin: coins = ['btc'] else: - coins = ['btc','ltc','eth'] - start_test_daemons('ltc','eth') - t = self.spawn('examples/coin-daemon-info.py',coins,cmd_dir='.') + coins = ['btc', 'ltc', 'eth'] + start_test_daemons('ltc', 'eth') + t = self.spawn('examples/coin-daemon-info.py', coins, cmd_dir='.') for coin in coins: - t.expect(coin.upper() + r'\s+mainnet\s+Up',regex=True) + t.expect(coin.upper() + r'\s+mainnet\s+Up', regex=True) if cfg.pexpect_spawn: t.send('q') if not cfg.no_altcoin: - stop_test_daemons('ltc','eth') + stop_test_daemons('ltc', 'eth') return t def term_echo(self): def test_echo(): - t.expect('echo> ','foo\n') + t.expect('echo> ', 'foo\n') t.expect('foo') def test_noecho(): - t.expect('noecho> ','foo\n') + t.expect('noecho> ', 'foo\n') import pexpect try: t.expect('foo') @@ -163,7 +164,7 @@ class CmdTestMisc(CmdTestBase): if self.skip_for_win('no termios support') or self.skip_for_mac('termios.ECHO issues'): return 'skip' - t = self.spawn('test/misc/term_ni.py',['echo'],cmd_dir='.',pexpect_spawn=True,timeout=1) + t = self.spawn('test/misc/term_ni.py', ['echo'], cmd_dir='.', pexpect_spawn=True, timeout=1) t.p.logfile = None t.p.logfile_read = sys.stdout if cfg.verbose or cfg.exact_output else None t.p.logfile_send = None @@ -177,23 +178,23 @@ class CmdTestMisc(CmdTestBase): def term_cleanup(self): if self.skip_for_win('no termios support'): return 'skip' - return self.spawn('test/misc/term_ni.py',['cleanup'],cmd_dir='.',pexpect_spawn=True) + return self.spawn('test/misc/term_ni.py', ['cleanup'], cmd_dir='.', pexpect_spawn=True) class CmdTestOutput(CmdTestBase): 'screen output' networks = ('btc',) cmd_group = ( - ('output_gr', (1,"Greek text", [])), - ('output_ru', (1,"Russian text", [])), - ('output_zh', (1,"Chinese text", [])), - ('output_jp', (1,"Japanese text", [])), - ('oneshot_warning', (1,"Oneshot warnings", [])), - ('oneshot_warning_term', (1,"Oneshot warnings (pexpect_spawn)", [])) + ('output_gr', (1, 'Greek text', [])), + ('output_ru', (1, 'Russian text', [])), + ('output_zh', (1, 'Chinese text', [])), + ('output_jp', (1, 'Japanese text', [])), + ('oneshot_warning', (1, 'Oneshot warnings', [])), + ('oneshot_warning_term', (1, 'Oneshot warnings (pexpect_spawn)', [])) ) color = True - def screen_output(self,lang): - return self.spawn('test/misc/utf8_output.py',[lang],cmd_dir='.') + def screen_output(self, lang): + return self.spawn('test/misc/utf8_output.py', [lang], cmd_dir='.') def output_gr(self): return self.screen_output('gr') @@ -204,8 +205,8 @@ class CmdTestOutput(CmdTestBase): def output_jp(self): return self.screen_output('jp') - def oneshot_warning(self,pexpect_spawn=None): - t = self.spawn('test/misc/oneshot_warning.py',cmd_dir='.',pexpect_spawn=pexpect_spawn) + def oneshot_warning(self, pexpect_spawn=None): + t = self.spawn('test/misc/oneshot_warning.py', cmd_dir='.', pexpect_spawn=pexpect_spawn) nl = '\r\n' if sys.platform == 'win32' or t.pexpect_spawn else '\n' for s in ( f'pw{nl}wg1', @@ -234,33 +235,37 @@ class CmdTestOutput(CmdTestBase): return 'skip' return self.oneshot_warning(pexpect_spawn=True) -class CmdTestRefTX(CmdTestMain,CmdTestBase): +class CmdTestRefTX(CmdTestMain, CmdTestBase): 'create a reference transaction file (administrative command)' segwit_opts_ok = False - passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet') - tmpdir_nums = [31,32,33,34] + passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet') + tmpdir_nums = [31, 32, 33, 34] need_daemon = True cmd_group = ( - ('ref_tx_addrgen1', (31,'address generation (legacy)', [[[],1]])), - ('ref_tx_addrgen2', (32,'address generation (compressed)', [[[],1]])), - ('ref_tx_addrgen3', (33,'address generation (segwit)', [[[],1]])), - ('ref_tx_addrgen4', (34,'address generation (bech32)', [[[],1]])), - ('ref_tx_txcreate', (31,'transaction creation', - ([['addrs'],31],[['addrs'],32],[['addrs'],33],[['addrs'],34]))), + ('ref_tx_addrgen1', (31, 'address generation (legacy)', [[[], 1]])), + ('ref_tx_addrgen2', (32, 'address generation (compressed)', [[[], 1]])), + ('ref_tx_addrgen3', (33, 'address generation (segwit)', [[[], 1]])), + ('ref_tx_addrgen4', (34, 'address generation (bech32)', [[[], 1]])), + ('ref_tx_txcreate', + (31, 'transaction creation', + ([['addrs'], 31], [['addrs'], 32], [['addrs'], 33], [['addrs'], 34])) + ), ) - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): if cfgs: for n in self.tmpdir_nums: - cfgs[str(n)].update({ 'addr_idx_list': '1-2', - 'segwit': n in (33,34), - 'dep_generators': { 'addrs':'ref_tx_addrgen'+str(n)[-1] }}) - CmdTestMain.__init__(self,trunner,cfgs,spawn) + cfgs[str(n)].update({ + 'addr_idx_list': '1-2', + 'segwit': n in (33, 34), + 'dep_generators': {'addrs':'ref_tx_addrgen'+str(n)[-1]} + }) + CmdTestMain.__init__(self, trunner, cfgs, spawn) - def ref_tx_addrgen(self,atype): + def ref_tx_addrgen(self, atype): if atype not in self.proto.mmtypes: return - return self.spawn('mmgen-addrgen',['--outdir='+self.tmpdir,'--type='+atype,dfl_words_file,'1-2']) + return self.spawn('mmgen-addrgen', ['--outdir='+self.tmpdir, '--type='+atype, dfl_words_file, '1-2']) def ref_tx_addrgen1(self): return self.ref_tx_addrgen(atype='L') @@ -271,8 +276,8 @@ class CmdTestRefTX(CmdTestMain,CmdTestBase): def ref_tx_addrgen4(self): return self.ref_tx_addrgen(atype='B') - def ref_tx_txcreate(self,f1,f2,f3,f4): - sources = ['31','32'] + def ref_tx_txcreate(self, f1, f2, f3, f4): + sources = ['31', '32'] if 'S' in self.proto.mmtypes: sources += ['33'] if 'B' in self.proto.mmtypes: diff --git a/test/cmdtest_py_d/ct_opts.py b/test/cmdtest_py_d/ct_opts.py index 66540ca1..56d7701b 100755 --- a/test/cmdtest_py_d/ct_opts.py +++ b/test/cmdtest_py_d/ct_opts.py @@ -10,7 +10,7 @@ test.cmdtest_py_d.ct_opts: options processing tests for the MMGen cmdtest.py test suite """ -import os,time +import os, time from ..include.common import cfg from .ct_base import CmdTestBase @@ -46,41 +46,41 @@ class CmdTestOpts(CmdTestBase): ('opt_bad_outdir', (41, 'bad outdir parameter', [])), ('opt_bad_incompatible', (41, 'incompatible opts', [])), ('opt_bad_autoset', (41, 'invalid autoset value', [])), - ('opt_invalid_1', (41, 'invalid cmdline opt ‘--x’', [])), - ('opt_invalid_2', (41, 'invalid cmdline opt ‘---’', [])), - ('opt_invalid_5', (41, 'invalid cmdline opt (missing parameter)', [])), - ('opt_invalid_6', (41, 'invalid cmdline opt (missing parameter)', [])), - ('opt_invalid_7', (41, 'invalid cmdline opt (parameter not required)', [])), - ('opt_invalid_8', (41, 'invalid cmdline opt (non-existent option)', [])), - ('opt_invalid_9', (41, 'invalid cmdline opt (non-existent option)', [])), - ('opt_invalid_10', (41, 'invalid cmdline opt (missing parameter)', [])), - ('opt_invalid_11', (41, 'invalid cmdline opt (missing parameter)', [])), - ('opt_invalid_12', (41, 'invalid cmdline opt (non-existent option)', [])), - ('opt_invalid_13', (41, 'invalid cmdline opt (ambiguous long opt substring)', [])), - ('opt_invalid_14', (41, 'invalid cmdline opt (long opt substring too short)', [])), - ('opt_invalid_15', (41, 'invalid cmdline (too many args)', [])), - ('opt_invalid_16', (41, 'invalid cmdline (overlong arg)', [])), + ('opt_invalid_1', (41, 'invalid cmdline opt ‘--x’', [])), + ('opt_invalid_2', (41, 'invalid cmdline opt ‘---’', [])), + ('opt_invalid_5', (41, 'invalid cmdline opt (missing parameter)', [])), + ('opt_invalid_6', (41, 'invalid cmdline opt (missing parameter)', [])), + ('opt_invalid_7', (41, 'invalid cmdline opt (parameter not required)', [])), + ('opt_invalid_8', (41, 'invalid cmdline opt (non-existent option)', [])), + ('opt_invalid_9', (41, 'invalid cmdline opt (non-existent option)', [])), + ('opt_invalid_10', (41, 'invalid cmdline opt (missing parameter)', [])), + ('opt_invalid_11', (41, 'invalid cmdline opt (missing parameter)', [])), + ('opt_invalid_12', (41, 'invalid cmdline opt (non-existent option)', [])), + ('opt_invalid_13', (41, 'invalid cmdline opt (ambiguous long opt substring)', [])), + ('opt_invalid_14', (41, 'invalid cmdline opt (long opt substring too short)', [])), + ('opt_invalid_15', (41, 'invalid cmdline (too many args)', [])), + ('opt_invalid_16', (41, 'invalid cmdline (overlong arg)', [])), ) def spawn_prog(self, args, exit_val=None): return self.spawn('test/misc/opts.py', args, cmd_dir='.', exit_val=exit_val) - def check_vals(self,args,vals): + def check_vals(self, args, vals): t = self.spawn_prog(args) - for k,v in vals: - t.expect(rf'{k}:\s+{v}',regex=True) + for k, v in vals: + t.expect(rf'{k}:\s+{v}', regex=True) return t - def do_run(self,args,expect,exit_val,regex=False): + def do_run(self, args, expect, exit_val, regex=False): t = self.spawn_prog(args, exit_val=exit_val or None) - t.expect(expect,regex=regex) + t.expect(expect, regex=regex) return t def opt_helpscreen(self): expect = r'OPTS.PY: Opts test.*USAGE:\s+opts.py' if not cfg.pexpect_spawn: expect += r'.*--minconf.*NOTES FOR THIS.*a note' - t = self.do_run( ['--help'], expect, 0, regex=True ) + t = self.do_run(['--help'], expect, 0, regex=True) if t.pexpect_spawn: time.sleep(0.4) t.send('q') @@ -88,74 +88,74 @@ class CmdTestOpts(CmdTestBase): def opt_noargs(self): return self.check_vals( - [], - ( - ('cfg.foo', 'None'), # added opt - ('cfg.print_checksum', 'None'), # sets 'quiet' - ('cfg.quiet', 'False'), # _incompatible_opts - ('cfg.verbose', 'False'), # _incompatible_opts - ('cfg.passwd_file', ''), # _infile_opts - check_infile() - ('cfg.outdir', ''), # check_outdir() - ('cfg.cached_balances', 'False'), - ('cfg.minconf', '1'), - ('cfg.coin', 'BTC'), - ('cfg.pager', 'False'), - ('cfg.fee_estimate_mode', 'conservative'), # _autoset_opts - )) + [], + ( + ('cfg.foo', 'None'), # added opt + ('cfg.print_checksum', 'None'), # sets 'quiet' + ('cfg.quiet', 'False'), # _incompatible_opts + ('cfg.verbose', 'False'), # _incompatible_opts + ('cfg.passwd_file', ''), # _infile_opts - check_infile() + ('cfg.outdir', ''), # check_outdir() + ('cfg.cached_balances', 'False'), + ('cfg.minconf', '1'), + ('cfg.coin', 'BTC'), + ('cfg.pager', 'False'), + ('cfg.fee_estimate_mode', 'conservative'), # _autoset_opts + )) def opt_good1(self): pf_base = 'testfile' - pf = os.path.join(self.tmpdir,pf_base) - self.write_to_tmpfile(pf_base,'') + pf = os.path.join(self.tmpdir, pf_base) + self.write_to_tmpfile(pf_base, '') return self.check_vals( - [ - '--print-checksum', - '--fee-estimate-mode=E', - '--passwd-file='+pf, - '--outdir='+self.tmpdir, - '--cached-balances', - f'--hidden-incog-input-params={pf},123', - ], ( - ('cfg.print_checksum', 'True'), - ('cfg.quiet', 'True'), # set by print_checksum - ('cfg.passwd_file', pf), - ('cfg.outdir', self.tmpdir), - ('cfg.cached_balances', 'True'), - ('cfg.hidden_incog_input_params', pf+',123'), - ('cfg.fee_estimate_mode', 'economical'), - )) + [ + '--print-checksum', + '--fee-estimate-mode=E', + '--passwd-file='+pf, + '--outdir='+self.tmpdir, + '--cached-balances', + f'--hidden-incog-input-params={pf},123', + ], ( + ('cfg.print_checksum', 'True'), + ('cfg.quiet', 'True'), # set by print_checksum + ('cfg.passwd_file', pf), + ('cfg.outdir', self.tmpdir), + ('cfg.cached_balances', 'True'), + ('cfg.hidden_incog_input_params', pf+',123'), + ('cfg.fee_estimate_mode', 'economical'), + )) def opt_good2(self): return self.check_vals( - [ - '--print-checksum', - '-qX', - f'--outdir={self.tmpdir}', - '-p5', - '-m', '0', - '--seed-len=256', - '-L--my-label', - '--seed-len', '128', - '--min-temp=-30', - '-T-10', - '--', - 'x', 'y', '12345' - ], ( - ('cfg.print_checksum', 'True'), - ('cfg.quiet', 'True'), - ('cfg.outdir', self.tmpdir), - ('cfg.cached_balances', 'True'), - ('cfg.minconf', '0'), - ('cfg.keep_label', 'None'), - ('cfg.seed_len', '128'), - ('cfg.hash_preset', '5'), - ('cfg.label', '--my-label'), - ('cfg.min_temp', '-30'), - ('cfg.max_temp', '-10'), - ('arg1', 'x'), - ('arg2', 'y'), - ('arg3', '12345'), - )) + [ + '--print-checksum', + '-qX', + f'--outdir={self.tmpdir}', + '-p5', + '-m', '0', + '--seed-len=256', + '-L--my-label', + '--seed-len', '128', + '--min-temp=-30', + '-T-10', + '--', + 'x', 'y', '12345' + ], ( + ('cfg.print_checksum', 'True'), + ('cfg.quiet', 'True'), + ('cfg.outdir', self.tmpdir), + ('cfg.cached_balances', 'True'), + ('cfg.minconf', '0'), + ('cfg.keep_label', 'None'), + ('cfg.seed_len', '128'), + ('cfg.hash_preset', '5'), + ('cfg.label', '--my-label'), + ('cfg.min_temp', '-30'), + ('cfg.max_temp', '-10'), + ('arg1', 'x'), + ('arg2', 'y'), + ('arg3', '12345'), + )) def opt_good3(self): return self.check_vals(['m'] * 256, (('arg256', 'm'),)) @@ -212,18 +212,18 @@ class CmdTestOpts(CmdTestBase): return self.do_run(['--pager=1'], 'no parameter', 1) def opt_bad_infile(self): - pf = os.path.join(self.tmpdir,'fubar') - return self.do_run(['--passwd-file='+pf],'not found',1) + pf = os.path.join(self.tmpdir, 'fubar') + return self.do_run(['--passwd-file='+pf], 'not found', 1) def opt_bad_outdir(self): bo = self.tmpdir+'_fubar' - return self.do_run(['--outdir='+bo],'not found',1) + return self.do_run(['--outdir='+bo], 'not found', 1) def opt_bad_incompatible(self): - return self.do_run(['--label=Label','--keep-label'],'Conflicting options',1) + return self.do_run(['--label=Label', '--keep-label'], 'Conflicting options', 1) def opt_bad_autoset(self): - return self.do_run(['--fee-estimate-mode=Fubar'],'not unique substring',1) + return self.do_run(['--fee-estimate-mode=Fubar'], 'not unique substring', 1) def opt_invalid(self, args, expect, exit_val): t = self.spawn_prog(args, exit_val=exit_val) diff --git a/test/cmdtest_py_d/ct_ref.py b/test/cmdtest_py_d/ct_ref.py index a4b988e3..84b0009c 100755 --- a/test/cmdtest_py_d/ct_ref.py +++ b/test/cmdtest_py_d/ct_ref.py @@ -51,11 +51,11 @@ from .ct_shared import CmdTestShared wpasswd = 'reference password' -class CmdTestRef(CmdTestBase,CmdTestShared): +class CmdTestRef(CmdTestBase, CmdTestShared): 'saved reference address, password and transaction files' tmpdir_nums = [8] - networks = ('btc','btc_tn','ltc','ltc_tn') - passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet') + networks = ('btc', 'btc_tn', 'ltc', 'ltc_tn') + passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet') need_daemon = True sources = { 'ref_addrfile': '98831F3A{}[1,31-33,500-501,1010-1011]{}.addrs', @@ -77,17 +77,30 @@ class CmdTestRef(CmdTestBase,CmdTestShared): 'ref_passwdfile_xmrseed_25': '98831F3A-фубар@crypto.org-xmrseed-25[1,4,1100].pws', 'ref_passwdfile_hex2bip39_12': '98831F3A-фубар@crypto.org-hex2bip39-12[1,4,1100].pws', 'ref_tx_file': { # data shared with ref_altcoin, autosign - 'btc': ('0B8D5A[15.31789,14,tl=1320969600].rawtx', - '0C7115[15.86255,14,tl=1320969600].testnet.rawtx'), - 'ltc': ('AF3CDF-LTC[620.76194,1453,tl=1320969600].rawtx', - 'A5A1E0-LTC[1454.64322,1453,tl=1320969600].testnet.rawtx'), - 'bch': ('460D4D-BCH[10.19764,tl=1320969600].rawtx', - '359FD5-BCH[6.68868,tl=1320969600].testnet.rawtx'), - 'eth': ('88FEFD-ETH[23.45495,40000].rawtx', - 'B472BD-ETH[23.45495,40000].testnet.rawtx'), - 'mm1': ('5881D2-MM1[1.23456,50000].rawtx', - '6BDB25-MM1[1.23456,50000].testnet.rawtx'), - 'etc': ('ED3848-ETC[1.2345,40000].rawtx','') + 'btc': ( + '0B8D5A[15.31789,14,tl=1320969600].rawtx', + '0C7115[15.86255,14,tl=1320969600].testnet.rawtx' + ), + 'ltc': ( + 'AF3CDF-LTC[620.76194,1453,tl=1320969600].rawtx', + 'A5A1E0-LTC[1454.64322,1453,tl=1320969600].testnet.rawtx' + ), + 'bch': ( + '460D4D-BCH[10.19764,tl=1320969600].rawtx', + '359FD5-BCH[6.68868,tl=1320969600].testnet.rawtx' + ), + 'eth': ( + '88FEFD-ETH[23.45495,40000].rawtx', + 'B472BD-ETH[23.45495,40000].testnet.rawtx' + ), + 'mm1': ( + '5881D2-MM1[1.23456,50000].rawtx', + '6BDB25-MM1[1.23456,50000].testnet.rawtx' + ), + 'etc': ( + 'ED3848-ETC[1.2345,40000].rawtx', + '' + ) }, } chk_data = { @@ -96,82 +109,84 @@ class CmdTestRef(CmdTestBase,CmdTestShared): '98831F3A:1S':'20D95B09', }, 'ref_addrfile_chksum': { - 'btc': ('6FEF 6FB9 7B13 5D91','424E 4326 CFFE 5F51'), - 'ltc': ('AD52 C3FE 8924 AAF0','4EBE 2E85 E969 1B30'), + 'btc': ('6FEF 6FB9 7B13 5D91', '424E 4326 CFFE 5F51'), + 'ltc': ('AD52 C3FE 8924 AAF0', '4EBE 2E85 E969 1B30'), }, 'ref_segwitaddrfile_chksum': { - 'btc': ('06C1 9C87 F25C 4EE6','072C 8B07 2730 CB7A'), - 'ltc': ('63DF E42A 0827 21C3','5DD1 D186 DBE1 59F2'), + 'btc': ('06C1 9C87 F25C 4EE6', '072C 8B07 2730 CB7A'), + 'ltc': ('63DF E42A 0827 21C3', '5DD1 D186 DBE1 59F2'), }, 'ref_bech32addrfile_chksum': { - 'btc': ('9D2A D4B6 5117 F02E','0527 9C39 6C1B E39A'), - 'ltc': ('FF1C 7939 5967 AB82','ED3D 8AA4 BED4 0B40'), + 'btc': ('9D2A D4B6 5117 F02E', '0527 9C39 6C1B E39A'), + 'ltc': ('FF1C 7939 5967 AB82', 'ED3D 8AA4 BED4 0B40'), }, 'ref_keyaddrfile_chksum': { - 'btc': ('9F2D D781 1812 8BAD','88CC 5120 9A91 22C2'), - 'ltc': ('B804 978A 8796 3ED4','98B5 AC35 F334 0398'), + 'btc': ('9F2D D781 1812 8BAD', '88CC 5120 9A91 22C2'), + 'ltc': ('B804 978A 8796 3ED4', '98B5 AC35 F334 0398'), }, - 'ref_passwdfile_b32_12_chksum': '7252 CD8D EF0D 3DB1', - 'ref_passwdfile_b32_24_chksum': '8D56 3845 A072 A5B9', - 'ref_passwdfile_b58_10_chksum': '534F CC1A 6701 9FED', - 'ref_passwdfile_b58_20_chksum': 'DDD9 44B0 CA28 183F', - 'ref_passwdfile_hex_32_chksum': '05C7 3678 E25E BC32', - 'ref_passwdfile_hex_48_chksum': '7DBB FFD0 633E DE6F', - 'ref_passwdfile_hex_64_chksum': 'F11D CB0A 8AE3 4D21', - 'ref_passwdfile_bip39_12_chksum': 'BF57 02A3 5229 CF18', - 'ref_passwdfile_bip39_18_chksum': '31D3 1656 B7DC 27CF', - 'ref_passwdfile_bip39_24_chksum': 'E565 3A59 7D91 4671', - 'ref_passwdfile_xmrseed_25_chksum': 'B488 21D3 4539 968D', + 'ref_passwdfile_b32_12_chksum': '7252 CD8D EF0D 3DB1', + 'ref_passwdfile_b32_24_chksum': '8D56 3845 A072 A5B9', + 'ref_passwdfile_b58_10_chksum': '534F CC1A 6701 9FED', + 'ref_passwdfile_b58_20_chksum': 'DDD9 44B0 CA28 183F', + 'ref_passwdfile_hex_32_chksum': '05C7 3678 E25E BC32', + 'ref_passwdfile_hex_48_chksum': '7DBB FFD0 633E DE6F', + 'ref_passwdfile_hex_64_chksum': 'F11D CB0A 8AE3 4D21', + 'ref_passwdfile_bip39_12_chksum': 'BF57 02A3 5229 CF18', + 'ref_passwdfile_bip39_18_chksum': '31D3 1656 B7DC 27CF', + 'ref_passwdfile_bip39_24_chksum': 'E565 3A59 7D91 4671', + 'ref_passwdfile_xmrseed_25_chksum': 'B488 21D3 4539 968D', 'ref_passwdfile_hex2bip39_12_chksum': '93AD 4AE2 03D1 8A0A', } cmd_group = ( # TODO: move to tooltest2 - ('ref_words_to_subwallet_chk1','subwallet generation from reference words file (long subseed)'), - ('ref_words_to_subwallet_chk2','subwallet generation from reference words file (short subseed)'), - ('ref_subwallet_addrgen1','subwallet address file generation (long subseed)'), - ('ref_subwallet_addrgen2','subwallet address file generation (short subseed)'), - ('ref_subwallet_keygen1','subwallet key-address file generation (long subseed)'), - ('ref_subwallet_keygen2','subwallet key-address file generation (short subseed)'), - ('ref_addrfile_chk', 'saved reference address file'), - ('ref_segwitaddrfile_chk','saved reference address file (segwit)'), - ('ref_bech32addrfile_chk','saved reference address file (bech32)'), - ('ref_keyaddrfile_chk','saved reference key-address file'), + ('ref_words_to_subwallet_chk1', 'subwallet generation from reference words file (long subseed)'), + ('ref_words_to_subwallet_chk2', 'subwallet generation from reference words file (short subseed)'), + ('ref_subwallet_addrgen1', 'subwallet address file generation (long subseed)'), + ('ref_subwallet_addrgen2', 'subwallet address file generation (short subseed)'), + ('ref_subwallet_keygen1', 'subwallet key-address file generation (long subseed)'), + ('ref_subwallet_keygen2', 'subwallet key-address file generation (short subseed)'), + ('ref_addrfile_chk', 'saved reference address file'), + ('ref_segwitaddrfile_chk', 'saved reference address file (segwit)'), + ('ref_bech32addrfile_chk', 'saved reference address file (bech32)'), + ('ref_keyaddrfile_chk', 'saved reference key-address file'), - ('ref_passwdfile_chk_b58_20','saved reference password file (base58, 20 chars)'), - ('ref_passwdfile_chk_b58_10','saved reference password file (base58, 10 chars)'), - ('ref_passwdfile_chk_b32_24','saved reference password file (base32, 24 chars)'), - ('ref_passwdfile_chk_b32_12','saved reference password file (base32, 12 chars)'), - ('ref_passwdfile_chk_hex_32','saved reference password file (hexadecimal, 32 chars)'), - ('ref_passwdfile_chk_hex_48','saved reference password file (hexadecimal, 48 chars)'), - ('ref_passwdfile_chk_hex_64','saved reference password file (hexadecimal, 64 chars)'), - ('ref_passwdfile_chk_bip39_12','saved reference password file (BIP39, 12 words)'), - ('ref_passwdfile_chk_bip39_18','saved reference password file (BIP39, 18 words)'), - ('ref_passwdfile_chk_bip39_24','saved reference password file (BIP39, 24 words)'), - ('ref_passwdfile_chk_xmrseed_25','saved reference password file (Monero new-style mnemonic, 25 words)'), - ('ref_passwdfile_chk_hex2bip39_12','saved reference password file (hex-to-BIP39, 12 words)'), + ('ref_passwdfile_chk_b58_20', 'saved reference password file (base58, 20 chars)'), + ('ref_passwdfile_chk_b58_10', 'saved reference password file (base58, 10 chars)'), + ('ref_passwdfile_chk_b32_24', 'saved reference password file (base32, 24 chars)'), + ('ref_passwdfile_chk_b32_12', 'saved reference password file (base32, 12 chars)'), + ('ref_passwdfile_chk_hex_32', 'saved reference password file (hexadecimal, 32 chars)'), + ('ref_passwdfile_chk_hex_48', 'saved reference password file (hexadecimal, 48 chars)'), + ('ref_passwdfile_chk_hex_64', 'saved reference password file (hexadecimal, 64 chars)'), + ('ref_passwdfile_chk_bip39_12', 'saved reference password file (BIP39, 12 words)'), + ('ref_passwdfile_chk_bip39_18', 'saved reference password file (BIP39, 18 words)'), + ('ref_passwdfile_chk_bip39_24', 'saved reference password file (BIP39, 24 words)'), + ('ref_passwdfile_chk_xmrseed_25', 'saved reference password file (Monero new-style mnemonic, 25 words)'), + ('ref_passwdfile_chk_hex2bip39_12', 'saved reference password file (hex-to-BIP39, 12 words)'), # Create the fake inputs: # ('txcreate8', 'transaction creation (8)'), - ('ref_tx_chk', 'signing saved reference tx file'), - ('ref_brain_chk_spc3', 'saved brainwallet (non-standard spacing)'), - ('ref_dieroll_chk_seedtruncate','saved dieroll wallet with extra entropy bits'), - ('ref_tool_decrypt', 'decryption of saved MMGen-encrypted file'), + ('ref_tx_chk', 'signing saved reference tx file'), + ('ref_brain_chk_spc3', 'saved brainwallet (non-standard spacing)'), + ('ref_dieroll_chk_seedtruncate', 'saved dieroll wallet with extra entropy bits'), + ('ref_tool_decrypt', 'decryption of saved MMGen-encrypted file'), ) @property def nw_desc(self): return '{} {}'.format( self.proto.coin, - ('Mainnet','Testnet')[self.proto.testnet] ) + ('Mainnet','Testnet')[self.proto.testnet]) def _get_ref_subdir_by_coin(self,coin): - return {'btc': '', - 'bch': '', - 'ltc': 'litecoin', - 'eth': 'ethereum', - 'etc': 'ethereum_classic', - 'xmr': 'monero', - 'zec': 'zcash', - 'dash': 'dash' }[coin.lower()] + return { + 'btc': '', + 'bch': '', + 'ltc': 'litecoin', + 'eth': 'ethereum', + 'etc': 'ethereum_classic', + 'xmr': 'monero', + 'zec': 'zcash', + 'dash': 'dash' + }[coin.lower()] @property def ref_subdir(self): @@ -183,10 +198,10 @@ class CmdTestRef(CmdTestBase,CmdTestShared): def ref_words_to_subwallet_chk2(self): return self.ref_words_to_subwallet_chk('1S') - def ref_words_to_subwallet_chk(self,ss_idx): + def ref_words_to_subwallet_chk(self, ss_idx): wf = dfl_words_file ocls = get_wallet_cls('words') - args = ['-d',self.tr.trash_dir,'-o',ocls.fmt_codes[-1],wf,ss_idx] + args = ['-d', self.tr.trash_dir, '-o', ocls.fmt_codes[-1], wf, ss_idx] t = self.spawn( 'mmgen-subwalletgen', @@ -196,7 +211,7 @@ class CmdTestRef(CmdTestBase,CmdTestShared): t.expect(f'Generating subseed {ss_idx}') chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}'] fn = t.written_to_file(capfirst(ocls.desc)) - assert chk_sid in fn,f'incorrect filename: {fn} (does not contain {chk_sid})' + assert chk_sid in fn, f'incorrect filename: {fn} (does not contain {chk_sid})' ok() t = self.spawn( @@ -204,22 +219,22 @@ class CmdTestRef(CmdTestBase,CmdTestShared): self.testnet_opt + [fn], extra_desc = '(check subwallet)', no_passthru_opts = True) - t.expect(r'Valid MMGen native mnemonic data for Seed ID ([0-9A-F]*)\b',regex=True) + t.expect(r'Valid MMGen native mnemonic data for Seed ID ([0-9A-F]*)\b', regex=True) sid = t.p.match.group(1) - assert sid == chk_sid,f'subseed ID {sid} does not match expected value {chk_sid}' + assert sid == chk_sid, f'subseed ID {sid} does not match expected value {chk_sid}' return t - def ref_subwallet_addrgen(self,ss_idx,target='addr'): + def ref_subwallet_addrgen(self, ss_idx, target='addr'): wf = dfl_words_file - args = ['-d',self.tr.trash_dir,'--subwallet='+ss_idx,wf,'1-10'] - t = self.spawn(f'mmgen-{target}gen',args) + args = ['-d', self.tr.trash_dir, '--subwallet='+ss_idx, wf, '1-10'] + t = self.spawn(f'mmgen-{target}gen', args) t.expect(f'Generating subseed {ss_idx}') chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}'] - assert chk_sid == t.expect_getend('Checksum for .* data ',regex=True)[:8] + assert chk_sid == t.expect_getend('Checksum for .* data ', regex=True)[:8] if target == 'key': - t.expect('Encrypt key list? (y/N): ','n') - fn = t.written_to_file(('Addresses','Secret keys')[target=='key']) - assert chk_sid in fn,f'incorrect filename: {fn} (does not contain {chk_sid})' + t.expect('Encrypt key list? (y/N): ', 'n') + fn = t.written_to_file(('Addresses', 'Secret keys')[target=='key']) + assert chk_sid in fn, f'incorrect filename: {fn} (does not contain {chk_sid})' return t def ref_subwallet_addrgen1(self): @@ -229,10 +244,10 @@ class CmdTestRef(CmdTestBase,CmdTestShared): return self.ref_subwallet_addrgen('1S') def ref_subwallet_keygen1(self): - return self.ref_subwallet_addrgen('32L',target='key') + return self.ref_subwallet_addrgen('32L', target='key') def ref_subwallet_keygen2(self): - return self.ref_subwallet_addrgen('1S',target='key') + return self.ref_subwallet_addrgen('1S', target='key') def ref_addrfile_chk( self, @@ -246,90 +261,90 @@ class CmdTestRef(CmdTestBase,CmdTestShared): pat = pat or f'{self.nw_desc}.*Legacy' af_key = f'ref_{ftype}file' + ('_' + id_key if id_key else '') - af_fn = CmdTestRef.sources[af_key].format(pfx or self.altcoin_pfx,'' if coin else self.tn_ext) - af = joinpath(ref_dir,(subdir or self.ref_subdir,'')[ftype=='passwd'],af_fn) + af_fn = CmdTestRef.sources[af_key].format(pfx or self.altcoin_pfx, '' if coin else self.tn_ext) + af = joinpath(ref_dir, (subdir or self.ref_subdir, '')[ftype=='passwd'], af_fn) coin_arg = [] if coin is None else ['--coin='+coin] - tool_cmd = ftype.replace('segwit','').replace('bech32','')+'file_chksum' - t = self.spawn( 'mmgen-tool', coin_arg + ['--verbose','-p1',tool_cmd,af] ) + tool_cmd = ftype.replace('segwit', '').replace('bech32', '')+'file_chksum' + t = self.spawn('mmgen-tool', coin_arg + ['--verbose', '-p1', tool_cmd, af]) if ftype == 'keyaddr': - t.do_decrypt_ka_data(pw=ref_kafile_pass,have_yes_opt=True) - chksum_key = '_'.join([af_key,'chksum'] + ([coin.lower()] if coin else []) + ([mmtype] if mmtype else [])) + t.do_decrypt_ka_data(pw=ref_kafile_pass, have_yes_opt=True) + chksum_key = '_'.join([af_key, 'chksum'] + ([coin.lower()] if coin else []) + ([mmtype] if mmtype else [])) rc = self.chk_data[chksum_key] ref_chksum = rc if (ftype == 'passwd' or coin) else rc[self.proto.base_coin.lower()][self.proto.testnet] if pat: - t.expect(pat,regex=True) - t.expect(chksum_pat,regex=True) + t.expect(pat, regex=True) + t.expect(chksum_pat, regex=True) m = t.p.match.group(0) - cmp_or_die(ref_chksum,m) + cmp_or_die(ref_chksum, m) return t def ref_segwitaddrfile_chk(self): if not 'S' in self.proto.mmtypes: return skip(f'not supported by {self.proto.cls_name} protocol') - return self.ref_addrfile_chk(ftype='segwitaddr',pat=f'{self.nw_desc}.*Segwit') + return self.ref_addrfile_chk(ftype='segwitaddr', pat=f'{self.nw_desc}.*Segwit') def ref_bech32addrfile_chk(self): if not 'B' in self.proto.mmtypes: return skip(f'not supported by {self.proto.cls_name} protocol') - return self.ref_addrfile_chk(ftype='bech32addr',pat=f'{self.nw_desc}.*Bech32') + return self.ref_addrfile_chk(ftype='bech32addr', pat=f'{self.nw_desc}.*Bech32') def ref_keyaddrfile_chk(self): return self.ref_addrfile_chk(ftype='keyaddr') - def ref_passwdfile_chk(self,key,pat): - return self.ref_addrfile_chk(ftype='passwd',id_key=key,pat=pat) + def ref_passwdfile_chk(self, key, pat): + return self.ref_addrfile_chk(ftype='passwd', id_key=key, pat=pat) def ref_passwdfile_chk_b58_20(self): - return self.ref_passwdfile_chk(key='b58_20',pat=r'Base58.*len.* 20\b') + return self.ref_passwdfile_chk(key='b58_20', pat=r'Base58.*len.* 20\b') def ref_passwdfile_chk_b58_10(self): - return self.ref_passwdfile_chk(key='b58_10',pat=r'Base58.*len.* 10\b') + return self.ref_passwdfile_chk(key='b58_10', pat=r'Base58.*len.* 10\b') def ref_passwdfile_chk_b32_24(self): - return self.ref_passwdfile_chk(key='b32_24',pat=r'Base32.*len.* 24\b') + return self.ref_passwdfile_chk(key='b32_24', pat=r'Base32.*len.* 24\b') def ref_passwdfile_chk_b32_12(self): - return self.ref_passwdfile_chk(key='b32_12',pat=r'Base32.*len.* 12\b') + return self.ref_passwdfile_chk(key='b32_12', pat=r'Base32.*len.* 12\b') def ref_passwdfile_chk_hex_32(self): - return self.ref_passwdfile_chk(key='hex_32',pat=r'Hexadec.*len.* 32\b') + return self.ref_passwdfile_chk(key='hex_32', pat=r'Hexadec.*len.* 32\b') def ref_passwdfile_chk_hex_48(self): - return self.ref_passwdfile_chk(key='hex_48',pat=r'Hexadec.*len.* 48\b') + return self.ref_passwdfile_chk(key='hex_48', pat=r'Hexadec.*len.* 48\b') def ref_passwdfile_chk_hex_64(self): - return self.ref_passwdfile_chk(key='hex_64',pat=r'Hexadec.*len.* 64\b') + return self.ref_passwdfile_chk(key='hex_64', pat=r'Hexadec.*len.* 64\b') def ref_passwdfile_chk_bip39_12(self): - return self.ref_passwdfile_chk(key='bip39_12',pat=r'BIP39.*len.* 12\b') + return self.ref_passwdfile_chk(key='bip39_12', pat=r'BIP39.*len.* 12\b') def ref_passwdfile_chk_bip39_18(self): - return self.ref_passwdfile_chk(key='bip39_18',pat=r'BIP39.*len.* 18\b') + return self.ref_passwdfile_chk(key='bip39_18', pat=r'BIP39.*len.* 18\b') def ref_passwdfile_chk_bip39_24(self): - return self.ref_passwdfile_chk(key='bip39_24',pat=r'BIP39.*len.* 24\b') + return self.ref_passwdfile_chk(key='bip39_24', pat=r'BIP39.*len.* 24\b') def ref_passwdfile_chk_xmrseed_25(self): - return self.ref_passwdfile_chk(key='xmrseed_25',pat=r'Mon.*len.* 25\b') + return self.ref_passwdfile_chk(key='xmrseed_25', pat=r'Mon.*len.* 25\b') def ref_passwdfile_chk_hex2bip39_12(self): - return self.ref_passwdfile_chk(key='hex2bip39_12',pat=r'BIP39.*len.* 12\b') + return self.ref_passwdfile_chk(key='hex2bip39_12', pat=r'BIP39.*len.* 12\b') def ref_tx_chk(self): fn = self.sources['ref_tx_file'][self.coin][bool(self.tn_ext)] if not fn: return - tf = joinpath(ref_dir,self.ref_subdir,fn) + tf = joinpath(ref_dir, self.ref_subdir, fn) wf = dfl_words_file - self.write_to_tmpfile(pwfile,wpasswd) - return self.txsign(wf,tf,save=False,has_label=True,view='y') + self.write_to_tmpfile(pwfile, wpasswd) + return self.txsign(wf, tf, save=False, has_label=True, view='y') def ref_brain_chk_spc3(self): return self.ref_brain_chk(bw_file=ref_bw_file_spc) def ref_dieroll_chk_seedtruncate(self): - wf = joinpath(ref_dir,'overflow128.b6d') - return self.walletchk(wf,sid='8EC6D4A2') + wf = joinpath(ref_dir, 'overflow128.b6d') + return self.walletchk(wf, sid='8EC6D4A2') def ref_tool_decrypt(self): - f = joinpath(ref_dir,ref_enc_fn) - dec_file = joinpath(self.tmpdir,'famous.txt') + f = joinpath(ref_dir, ref_enc_fn) + dec_file = joinpath(self.tmpdir, 'famous.txt') t = self.spawn( 'mmgen-tool', - ['-q','decrypt',f,'outfile='+dec_file,'hash_preset=1'], - env = os.environ if cfg.debug_utf8 else get_env_without_debug_vars() ) - t.passphrase('data',tool_enc_passwd) + ['-q', 'decrypt', f, 'outfile='+dec_file, 'hash_preset=1'], + env = os.environ if cfg.debug_utf8 else get_env_without_debug_vars()) + t.passphrase('data', tool_enc_passwd) t.written_to_file('Decrypted data') dec_txt = read_from_file(dec_file) imsg_r(dec_txt) - cmp_or_die(sample_text+'\n',dec_txt) # file adds a newline to sample_text + cmp_or_die(sample_text+'\n', dec_txt) # file adds a newline to sample_text return t diff --git a/test/cmdtest_py_d/ct_ref_3seed.py b/test/cmdtest_py_d/ct_ref_3seed.py index 57542935..752d2665 100755 --- a/test/cmdtest_py_d/ct_ref_3seed.py +++ b/test/cmdtest_py_d/ct_ref_3seed.py @@ -23,10 +23,10 @@ test.cmdtest_py_d.ct_ref_3seed: Saved and generated reference file tests for 128 import os -from mmgen.util import msg,capfirst +from mmgen.util import msg, capfirst from mmgen.wallet import get_wallet_cls -from ..include.common import cfg,cmp_or_die,joinpath +from ..include.common import cfg, cmp_or_die, joinpath from .common import ( pwfile, ref_wallet_hash_preset, @@ -39,66 +39,66 @@ from .ct_base import CmdTestBase from .ct_shared import CmdTestShared from .ct_wallet import CmdTestWalletConv -class CmdTestRef3Seed(CmdTestBase,CmdTestShared): +class CmdTestRef3Seed(CmdTestBase, CmdTestShared): 'saved wallet files for 128-, 192- and 256-bit seeds + generated filename checks' networks = ('btc',) mmtypes = (None,) - tmpdir_nums = [6,7,8] + tmpdir_nums = [6, 7, 8] addr_idx_list_in = '1010,500-501,31-33,1,33,500,1011' pass_idx_list_in = '1,4,9-11,1100' chk_data = { 'lens': (128, 192, 256), 'sids': ('FE3C6545', '1378FC64', '98831F3A'), } - shared_deps = ['mmdat',pwfile] + shared_deps = ['mmdat', pwfile] skip_cmds = ( 'ref_xmrseed_25_passwdgen_1', 'ref_xmrseed_25_passwdgen_2', ) cmd_group = ( # reading saved reference wallets - ('ref_wallet_chk', ([],'saved reference wallet')), - ('ref_seed_chk', ([],'saved seed file')), - ('ref_hex_chk', ([],'saved mmhex file')), - ('ref_plainhex_chk',([],'saved hex file')), - ('ref_dieroll_chk', ([],'saved dieroll (b6d) file')), - ('ref_mn_chk', ([],'saved native MMGen mnemonic file')), - ('ref_bip39_chk', ([],'saved BIP39 mnemonic file')), - ('ref_hincog_chk', ([],'saved hidden incog reference wallet')), - ('ref_brain_chk', ([],'saved brainwallet')), # in ct_shared + ('ref_wallet_chk', ([], 'saved reference wallet')), + ('ref_seed_chk', ([], 'saved seed file')), + ('ref_hex_chk', ([], 'saved mmhex file')), + ('ref_plainhex_chk', ([], 'saved hex file')), + ('ref_dieroll_chk', ([], 'saved dieroll (b6d) file')), + ('ref_mn_chk', ([], 'saved native MMGen mnemonic file')), + ('ref_bip39_chk', ([], 'saved BIP39 mnemonic file')), + ('ref_hincog_chk', ([], 'saved hidden incog reference wallet')), + ('ref_brain_chk', ([], 'saved brainwallet')), # in ct_shared # generating new reference ('abc' brainwallet) wallets for filename checks: - ('ref_walletgen_brain', ([],'generating new reference wallet + filename check (brain)')), - ('ref_walletconv_words', ([],'wallet filename (native mnemonic)')), - ('ref_walletconv_bip39', ([],'wallet filename (bip39)')), - ('ref_walletconv_seed', ([],'wallet filename (seed)')), - ('ref_walletconv_hexseed', ([],'wallet filename (hex seed)')), - ('ref_walletconv_plainhexseed',([],'wallet filename (plain hex seed)')), - ('ref_walletconv_dieroll', ([],'wallet filename (dieroll (b6d) seed)')), - ('ref_walletconv_incog', ([],'wallet filename (incog)')), - ('ref_walletconv_hexincog', ([],'wallet filename (hex incog)')), + ('ref_walletgen_brain', ([], 'generating new reference wallet + filename check (brain)')), + ('ref_walletconv_words', ([], 'wallet filename (native mnemonic)')), + ('ref_walletconv_bip39', ([], 'wallet filename (bip39)')), + ('ref_walletconv_seed', ([], 'wallet filename (seed)')), + ('ref_walletconv_hexseed', ([], 'wallet filename (hex seed)')), + ('ref_walletconv_plainhexseed', ([], 'wallet filename (plain hex seed)')), + ('ref_walletconv_dieroll', ([], 'wallet filename (dieroll (b6d) seed)')), + ('ref_walletconv_incog', ([], 'wallet filename (incog)')), + ('ref_walletconv_hexincog', ([], 'wallet filename (hex incog)')), ) - def __init__(self,trunner,cfgs,spawn): - for k,_ in self.cmd_group: - for n in (1,2,3): # 128,192,256 bits - setattr(self,f'{k}_{n}',getattr(self,k)) + def __init__(self, trunner, cfgs, spawn): + for k, _ in self.cmd_group: + for n in (1, 2, 3): # 128, 192, 256 bits + setattr(self, f'{k}_{n}', getattr(self, k)) if cfgs: for n in self.tmpdir_nums: cfgs[str(n)]['addr_idx_list'] = self.addr_idx_list_in cfgs[str(n)]['pass_idx_list'] = self.pass_idx_list_in - CmdTestBase.__init__(self,trunner,cfgs,spawn) + CmdTestBase.__init__(self, trunner, cfgs, spawn) def ref_wallet_chk(self): - wf = joinpath(ref_dir,CmdTestWalletConv.sources[str(self.seed_len)]['ref_wallet']) - return self.walletchk(wf,sid=self.seed_id) + wf = joinpath(ref_dir, CmdTestWalletConv.sources[str(self.seed_len)]['ref_wallet']) + return self.walletchk(wf, sid=self.seed_id) - def ref_ss_chk(self,ss_type): + def ref_ss_chk(self, ss_type): ss = get_wallet_cls(ss_type) return self.walletchk( - wf = joinpath(ref_dir,f'{self.seed_id}.{ss.ext}'), + wf = joinpath(ref_dir, f'{self.seed_id}.{ss.ext}'), wcls = ss, - sid = self.seed_id ) + sid = self.seed_id) def ref_seed_chk(self): return self.ref_ss_chk('seed') @@ -118,14 +118,14 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): def ref_bip39_chk(self): return self.ref_ss_chk('bip39') - def ref_hincog_chk(self,desc='hidden incognito data'): + def ref_hincog_chk(self, desc='hidden incognito data'): source = CmdTestWalletConv.sources[str(self.seed_len)] - for wtype,edesc,of_arg in ( - ('hic_wallet', '', []), - ('hic_wallet_old','(old format)',['-O']) ): + for wtype, edesc, of_arg in ( + ('hic_wallet', '', []), + ('hic_wallet_old', '(old format)', ['-O'])): ic_arg = ['-H{},{}'.format( - joinpath(ref_dir,source[wtype]), - ref_wallet_incog_offset ) + joinpath(ref_dir, source[wtype]), + ref_wallet_incog_offset) ] slarg = [f'-l{self.seed_len} '] hparg = ['-p1'] @@ -134,11 +134,11 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): t = self.spawn('mmgen-walletchk', slarg + hparg + of_arg + ic_arg, extra_desc=edesc) - t.passphrase(desc,self.wpasswd+'\n') + t.passphrase(desc, self.wpasswd+'\n') if wtype == 'hic_wallet_old': - t.expect('Is the Seed ID correct? (Y/n): ','\n') + t.expect('Is the Seed ID correct? (Y/n): ', '\n') chk = t.expect_getend('Seed ID: ') - cmp_or_die(self.seed_id,chk) + cmp_or_die(self.seed_id, chk) ok_msg() t.skip_ok = True return t @@ -148,14 +148,14 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): hp_arg = f'-p{ref_wallet_hash_preset}' label = f'ref. wallet (pw {ref_wallet_brainpass!r}, seed len {self.seed_len}) α' bf = 'ref.mmbrain' - args = ['-d',self.tmpdir,hp_arg,sl_arg,'-ibw','-L',label] - self.write_to_tmpfile(bf,ref_wallet_brainpass) - self.write_to_tmpfile(pwfile,self.wpasswd) + args = ['-d', self.tmpdir, hp_arg, sl_arg, '-ibw', '-L', label] + self.write_to_tmpfile(bf, ref_wallet_brainpass) + self.write_to_tmpfile(pwfile, self.wpasswd) t = self.spawn('mmgen-walletconv', self.testnet_opt + args + [self.usr_rand_arg], no_passthru_opts=True) t.license() t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n') ocls = get_wallet_cls('mmgen') - t.passphrase_new('new '+ocls.desc,self.wpasswd) + t.passphrase_new('new '+ocls.desc, self.wpasswd) t.usr_rand(self.usr_rand_chars) fn = os.path.split(t.written_to_file(capfirst(ocls.desc)))[-1] import re @@ -164,15 +164,15 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): self.chk_data['sids'][idx], self.chk_data['lens'][idx], '-α' if cfg.debug_utf8 else '') - assert re.match(pat,fn), f'{pat} != {fn}' + assert re.match(pat, fn), f'{pat} != {fn}' sid = os.path.basename(fn.split('-')[0]) - cmp_or_die(sid,self.seed_id,desc='Seed ID') + cmp_or_die(sid, self.seed_id, desc='Seed ID') return t - def ref_walletconv(self,ofmt,extra_args=[],re_pat=None): + def ref_walletconv(self, ofmt, extra_args=[], re_pat=None): wf = self.get_file_with_ext('mmdat') - pf = joinpath(self.tmpdir,pwfile) - t = self.spawn('mmgen-walletconv',extra_args+['-d','test/trash','-o',ofmt,'-P'+pf,wf]) + pf = joinpath(self.tmpdir, pwfile) + t = self.spawn('mmgen-walletconv', extra_args+['-d', 'test/trash', '-o', ofmt, '-P'+pf, wf]) wcls = get_wallet_cls(fmt_code=ofmt) fn = os.path.split(t.written_to_file(capfirst(wcls.desc)))[-1] idx = int(self.test_name[-1]) - 1 @@ -180,15 +180,15 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): slen = self.chk_data['lens'][idx] if re_pat: import re - pat = re_pat.format(sid,slen) - assert re.match(pat,fn), f'{pat} != {fn}' + pat = re_pat.format(sid, slen) + assert re.match(pat, fn), f'{pat} != {fn}' else: cmp_or_die('{}[{}]{}.{}'.format( sid, slen, '-α' if cfg.debug_utf8 else '', wcls.ext), - fn ) + fn) return t def ref_walletconv_words(self): @@ -204,13 +204,13 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared): def ref_walletconv_dieroll(self): return self.ref_walletconv(ofmt='dieroll') - def ref_walletconv_incog(self,ofmt='incog',ext='mmincog'): - args = ['-r0','-p1'] + def ref_walletconv_incog(self, ofmt='incog', ext='mmincog'): + args = ['-r0', '-p1'] pat = r'{}-[0-9A-F]{{8}}-[0-9A-F]{{8}}\[{},1\]' + ('-α' if cfg.debug_utf8 else '') + '.' + ext - return self.ref_walletconv(ofmt=ofmt,extra_args=args,re_pat=pat) + return self.ref_walletconv(ofmt=ofmt, extra_args=args, re_pat=pat) def ref_walletconv_hexincog(self): - return self.ref_walletconv_incog(ofmt='incog_hex',ext='mmincox') + return self.ref_walletconv_incog(ofmt='incog_hex', ext='mmincox') class CmdTestRef3Addr(CmdTestRef3Seed): 'generated reference address and key-address files for 128-, 192- and 256-bit seeds' @@ -223,112 +223,112 @@ class CmdTestRef3Addr(CmdTestRef3Seed): 'lens': (128, 192, 256), 'sids': ('FE3C6545', '1378FC64', '98831F3A'), 'refaddrgen_legacy_1': { - 'btc': ('B230 7526 638F 38CB','A9DC 5A13 12CB 1317'), - 'bch': ('026D AFE0 8C60 6CFF','B406 4937 D884 6E48'), - 'ltc': ('2B23 5E97 848A B961','AEC3 E774 0B21 0202'), + 'btc': ('B230 7526 638F 38CB', 'A9DC 5A13 12CB 1317'), + 'bch': ('026D AFE0 8C60 6CFF', 'B406 4937 D884 6E48'), + 'ltc': ('2B23 5E97 848A B961', 'AEC3 E774 0B21 0202'), }, 'refaddrgen_segwit_1': { - 'btc': ('9914 6D10 2307 F348','83C8 A6B6 ADA8 25B2'), - 'ltc': ('CC09 A190 B7DF B7CD','0425 7893 C6F1 ECA3'), + 'btc': ('9914 6D10 2307 F348', '83C8 A6B6 ADA8 25B2'), + 'ltc': ('CC09 A190 B7DF B7CD', '0425 7893 C6F1 ECA3'), }, 'refaddrgen_bech32_1': { - 'btc': ('C529 D686 31AA ACD4','21D0 26AD 3A22 5465'), - 'ltc': ('3DFB CFCC E180 DC9D','8C72 D5C2 07E0 5F7B'), + 'btc': ('C529 D686 31AA ACD4', '21D0 26AD 3A22 5465'), + 'ltc': ('3DFB CFCC E180 DC9D', '8C72 D5C2 07E0 5F7B'), }, 'refaddrgen_compressed_1': { - 'btc': ('95EB 8CC0 7B3B 7856','16E6 6170 154D 2202'), - 'bch': ('C560 A343 CEAB 118E','3F56 8DC5 0383 CD78'), - 'ltc': ('35D5 8ECA 9A42 46C3','15B3 5492 D3D3 6854'), + 'btc': ('95EB 8CC0 7B3B 7856', '16E6 6170 154D 2202'), + 'bch': ('C560 A343 CEAB 118E', '3F56 8DC5 0383 CD78'), + 'ltc': ('35D5 8ECA 9A42 46C3', '15B3 5492 D3D3 6854'), }, 'refkeyaddrgen_legacy_1': { - 'btc': ('CF83 32FB 8A8B 08E2','1F67 B73A FF8C 5D15'), - 'bch': ('6909 4C64 119A 7681','7E48 5071 5E41 D1AE'), - 'ltc': ('1896 A26C 7F14 2D01','FA0E CD4E ADAF DBF4'), + 'btc': ('CF83 32FB 8A8B 08E2', '1F67 B73A FF8C 5D15'), + 'bch': ('6909 4C64 119A 7681', '7E48 5071 5E41 D1AE'), + 'ltc': ('1896 A26C 7F14 2D01', 'FA0E CD4E ADAF DBF4'), }, 'refkeyaddrgen_compressed_1': { - 'btc': ('E43A FA46 5751 720A','FDEE 8E45 1C0A 02AD'), - 'bch': ('7068 9B37 8ABF 3E31','C688 29A5 BA4C 21B2'), - 'ltc': ('7603 2FE3 2145 FFAD','3FE0 5A8E 5FBE FF3E'), + 'btc': ('E43A FA46 5751 720A', 'FDEE 8E45 1C0A 02AD'), + 'bch': ('7068 9B37 8ABF 3E31', 'C688 29A5 BA4C 21B2'), + 'ltc': ('7603 2FE3 2145 FFAD', '3FE0 5A8E 5FBE FF3E'), }, 'refkeyaddrgen_segwit_1': { - 'btc': ('C13B F717 D4E8 CF59','BB71 175C 5416 19D8'), - 'ltc': ('054B 9794 55B4 5D82','DE85 3CF3 9636 FE2E'), + 'btc': ('C13B F717 D4E8 CF59', 'BB71 175C 5416 19D8'), + 'ltc': ('054B 9794 55B4 5D82', 'DE85 3CF3 9636 FE2E'), }, 'refkeyaddrgen_bech32_1': { - 'btc': ('934F 1C33 6C06 B18C','A283 5BAB 7AF3 3EA4'), - 'ltc': ('A6AD DF53 5968 7B6A','9572 43E0 A4DC 0B2E'), + 'btc': ('934F 1C33 6C06 B18C', 'A283 5BAB 7AF3 3EA4'), + 'ltc': ('A6AD DF53 5968 7B6A', '9572 43E0 A4DC 0B2E'), }, 'refaddrgen_legacy_2': { - 'btc': ('8C17 A5FA 0470 6E89','764C 66F9 7502 AAEA'), - 'bch': ('8117 24B6 3FDA 6B40','E58C A8A4 C371 66AE'), - 'ltc': ('2B77 A009 D5D0 22AD','51D1 979D 0A35 F24B'), + 'btc': ('8C17 A5FA 0470 6E89', '764C 66F9 7502 AAEA'), + 'bch': ('8117 24B6 3FDA 6B40', 'E58C A8A4 C371 66AE'), + 'ltc': ('2B77 A009 D5D0 22AD', '51D1 979D 0A35 F24B'), }, 'refaddrgen_compressed_2': { - 'btc': ('2615 8401 2E98 7ECA','A386 EE07 A356 906D'), - 'bch': ('3364 0F9D 8355 2A53','3451 F741 0A8A FA56'), - 'ltc': ('197C C48C 3C37 AB0F','8DDC 5FE3 BFF9 1226'), + 'btc': ('2615 8401 2E98 7ECA', 'A386 EE07 A356 906D'), + 'bch': ('3364 0F9D 8355 2A53', '3451 F741 0A8A FA56'), + 'ltc': ('197C C48C 3C37 AB0F', '8DDC 5FE3 BFF9 1226'), }, 'refaddrgen_segwit_2': { - 'btc': ('91C4 0414 89E4 2089','BF9F C67F ED22 A47B'), - 'ltc': ('8F12 FA7B 9F12 594C','2609 8494 A23C F836'), + 'btc': ('91C4 0414 89E4 2089', 'BF9F C67F ED22 A47B'), + 'ltc': ('8F12 FA7B 9F12 594C', '2609 8494 A23C F836'), }, 'refaddrgen_bech32_2': { - 'btc': ('2AA3 78DF B965 82EB','027B 1C1F 7FB2 D859'), - 'ltc': ('951C 8FB2 FCA5 87D1','4A5D 67E0 8210 FEF2'), + 'btc': ('2AA3 78DF B965 82EB', '027B 1C1F 7FB2 D859'), + 'ltc': ('951C 8FB2 FCA5 87D1', '4A5D 67E0 8210 FEF2'), }, 'refkeyaddrgen_legacy_2': { - 'btc': ('9648 5132 B98E 3AD9','1BD3 5A36 D51C 256D'), - 'bch': ('C4D8 7C36 DC77 F8C2','953D 245C 8CFF AC72'), - 'ltc': ('DBD4 FAB6 7E46 CD07','8822 3FDF FEC0 6A8C'), + 'btc': ('9648 5132 B98E 3AD9', '1BD3 5A36 D51C 256D'), + 'bch': ('C4D8 7C36 DC77 F8C2', '953D 245C 8CFF AC72'), + 'ltc': ('DBD4 FAB6 7E46 CD07', '8822 3FDF FEC0 6A8C'), }, 'refkeyaddrgen_compressed_2': { - 'btc': ('6D6D 3D35 04FD B9C3','94BF 4BCF 10B2 394B'), - 'bch': ('3E7F C369 2AB9 BD58','0C99 14CD 5ADE 6782'), - 'ltc': ('F5DA 9D60 6798 C4E9','7918 88DE 9096 DD7A'), + 'btc': ('6D6D 3D35 04FD B9C3', '94BF 4BCF 10B2 394B'), + 'bch': ('3E7F C369 2AB9 BD58', '0C99 14CD 5ADE 6782'), + 'ltc': ('F5DA 9D60 6798 C4E9', '7918 88DE 9096 DD7A'), }, 'refkeyaddrgen_segwit_2': { - 'btc': ('C98B DF08 A3D5 204B','7E7F DF50 FE04 6F68'), - 'ltc': ('1829 7FE7 2567 CB91','BE92 D19C 7589 EF30'), + 'btc': ('C98B DF08 A3D5 204B', '7E7F DF50 FE04 6F68'), + 'ltc': ('1829 7FE7 2567 CB91', 'BE92 D19C 7589 EF30'), }, 'refkeyaddrgen_bech32_2': { - 'btc': ('4A6B 3762 DF30 9368','12DD 1888 36BA 85F7'), - 'ltc': ('5C12 FDD4 17AB F179','E195 B28C 59C4 C5EC'), + 'btc': ('4A6B 3762 DF30 9368', '12DD 1888 36BA 85F7'), + 'ltc': ('5C12 FDD4 17AB F179', 'E195 B28C 59C4 C5EC'), }, 'refaddrgen_legacy_3': { - 'btc': ('6FEF 6FB9 7B13 5D91','424E 4326 CFFE 5F51'), - 'bch': ('E580 43BB 0F96 AA93','630E 174A 8DDE 1BCE'), - 'ltc': ('AD52 C3FE 8924 AAF0','4EBE 2E85 E969 1B30'), + 'btc': ('6FEF 6FB9 7B13 5D91', '424E 4326 CFFE 5F51'), + 'bch': ('E580 43BB 0F96 AA93', '630E 174A 8DDE 1BCE'), + 'ltc': ('AD52 C3FE 8924 AAF0', '4EBE 2E85 E969 1B30'), }, 'refaddrgen_compressed_3': { - 'btc': ('A33C 4FDE F515 F5BC','6C48 AA57 2056 C8C8'), - 'bch': ('E37B AF41 7997 A28C','0D5D 9A58 D6E9 92EE'), - 'ltc': ('3FC0 8F03 C2D6 BD19','4C0A 49B6 2DD1 1BE0'), + 'btc': ('A33C 4FDE F515 F5BC', '6C48 AA57 2056 C8C8'), + 'bch': ('E37B AF41 7997 A28C', '0D5D 9A58 D6E9 92EE'), + 'ltc': ('3FC0 8F03 C2D6 BD19', '4C0A 49B6 2DD1 1BE0'), }, 'refaddrgen_segwit_3': { - 'btc': ('06C1 9C87 F25C 4EE6','072C 8B07 2730 CB7A'), - 'ltc': ('63DF E42A 0827 21C3','5DD1 D186 DBE1 59F2'), + 'btc': ('06C1 9C87 F25C 4EE6', '072C 8B07 2730 CB7A'), + 'ltc': ('63DF E42A 0827 21C3', '5DD1 D186 DBE1 59F2'), }, 'refaddrgen_bech32_3': { - 'btc': ('9D2A D4B6 5117 F02E','0527 9C39 6C1B E39A'), - 'ltc': ('FF1C 7939 5967 AB82','ED3D 8AA4 BED4 0B40'), + 'btc': ('9D2A D4B6 5117 F02E', '0527 9C39 6C1B E39A'), + 'ltc': ('FF1C 7939 5967 AB82', 'ED3D 8AA4 BED4 0B40'), }, 'refkeyaddrgen_legacy_3': { - 'btc': ('9F2D D781 1812 8BAD','88CC 5120 9A91 22C2'), - 'bch': ('A0EE B039 48F4 24AE','B014 E0AB 5F87 EC64'), - 'ltc': ('B804 978A 8796 3ED4','98B5 AC35 F334 0398'), + 'btc': ('9F2D D781 1812 8BAD', '88CC 5120 9A91 22C2'), + 'bch': ('A0EE B039 48F4 24AE', 'B014 E0AB 5F87 EC64'), + 'ltc': ('B804 978A 8796 3ED4', '98B5 AC35 F334 0398'), }, 'refkeyaddrgen_compressed_3': { - 'btc': ('420A 8EB5 A9E2 7814','F43A CB4A 81F3 F735'), - 'bch': ('33E7 5C06 88CF 2792','6E09 FF73 B7C8 00D4'), - 'ltc': ('8D1C 781F EB7F 44BC','05F3 5C68 FD31 FCEF'), + 'btc': ('420A 8EB5 A9E2 7814', 'F43A CB4A 81F3 F735'), + 'bch': ('33E7 5C06 88CF 2792', '6E09 FF73 B7C8 00D4'), + 'ltc': ('8D1C 781F EB7F 44BC', '05F3 5C68 FD31 FCEF'), }, 'refkeyaddrgen_segwit_3': { - 'btc': ('A447 12C2 DD14 5A9B','C770 7391 C415 21F9'), - 'ltc': ('E8A3 9F6E E164 A521','D3D5 BFDD F5D5 20BD'), + 'btc': ('A447 12C2 DD14 5A9B', 'C770 7391 C415 21F9'), + 'ltc': ('E8A3 9F6E E164 A521', 'D3D5 BFDD F5D5 20BD'), }, 'refkeyaddrgen_bech32_3': { - 'btc': ('D0DD BDE3 87BE 15AE','7552 D70C AAB8 DEAA'), - 'ltc': ('74A0 7DD5 963B 6326','2CDA A007 4B9F E9A5'), + 'btc': ('D0DD BDE3 87BE 15AE', '7552 D70C AAB8 DEAA'), + 'ltc': ('74A0 7DD5 963B 6326', '2CDA A007 4B9F E9A5'), }, } @@ -446,7 +446,7 @@ class CmdTestRef3Passwd(CmdTestRef3Seed): no_passthru_opts = True) def refpasswdgen(self): - return self.pwgen('pass','alice@crypto.org') + return self.pwgen('pass', 'alice@crypto.org') def refpasswdgen_half(self): return self.pwgen('pass', 'alice@crypto.org', pwlen='h') diff --git a/test/cmdtest_py_d/ct_ref_altcoin.py b/test/cmdtest_py_d/ct_ref_altcoin.py index 97d85709..f2795ea7 100755 --- a/test/cmdtest_py_d/ct_ref_altcoin.py +++ b/test/cmdtest_py_d/ct_ref_altcoin.py @@ -22,62 +22,60 @@ test.cmdtest_py_d.ct_ref_altcoin: Altcoin reference file tests for the cmdtest.p from mmgen.color import set_vt100 -from .common import pwfile,dfl_wpasswd,ref_dir,dfl_words_file,dfl_addr_idx_list -from ..include.common import cfg,joinpath,start_test_daemons,stop_test_daemons,cmp_or_die +from .common import pwfile, dfl_wpasswd, ref_dir, dfl_words_file, dfl_addr_idx_list +from ..include.common import cfg, joinpath, start_test_daemons, stop_test_daemons, cmp_or_die from .ct_ref import CmdTestRef from .ct_base import CmdTestBase -class CmdTestRefAltcoin(CmdTestRef,CmdTestBase): +class CmdTestRefAltcoin(CmdTestRef, CmdTestBase): 'saved and generated altcoin reference files' tmpdir_nums = [8] networks = ('btc',) chk_data = { - 'ref_addrfile_chksum_zec': '903E 7225 DD86 6E01', - 'ref_addrfile_chksum_zec_z': '9C7A 72DC 3D4A B3AF', - 'ref_addrfile_chksum_xmr': '4369 0253 AC2C 0E38', - 'ref_addrfile_chksum_dash':'FBC1 6B6A 0988 4403', - 'ref_addrfile_chksum_eth': 'E554 076E 7AF6 66A3', - 'ref_addrfile_chksum_etc': 'E97A D796 B495 E8BC', - 'ref_keyaddrfile_chksum_zec': 'F05A 5A5C 0C8E 2617', - 'ref_keyaddrfile_chksum_zec_z': '6B87 9B2D 0D8D 8D1E', - 'ref_keyaddrfile_chksum_xmr': 'E0D7 9612 3D67 404A', + 'ref_addrfile_chksum_zec': '903E 7225 DD86 6E01', + 'ref_addrfile_chksum_zec_z': '9C7A 72DC 3D4A B3AF', + 'ref_addrfile_chksum_xmr': '4369 0253 AC2C 0E38', + 'ref_addrfile_chksum_dash': 'FBC1 6B6A 0988 4403', + 'ref_addrfile_chksum_eth': 'E554 076E 7AF6 66A3', + 'ref_addrfile_chksum_etc': 'E97A D796 B495 E8BC', + 'ref_keyaddrfile_chksum_zec': 'F05A 5A5C 0C8E 2617', + 'ref_keyaddrfile_chksum_zec_z': '6B87 9B2D 0D8D 8D1E', + 'ref_keyaddrfile_chksum_xmr': 'E0D7 9612 3D67 404A', 'ref_viewkeyaddrfile_chksum_xmr': '40C9 0E61 B743 229C', - 'ref_keyaddrfile_chksum_dash': 'E83D 2C63 FEA2 4142', - 'ref_keyaddrfile_chksum_eth': 'E400 70D9 0AE3 C7C2', - 'ref_keyaddrfile_chksum_etc': 'EF49 967D BD6C FE45', + 'ref_keyaddrfile_chksum_dash': 'E83D 2C63 FEA2 4142', + 'ref_keyaddrfile_chksum_eth': 'E400 70D9 0AE3 C7C2', + 'ref_keyaddrfile_chksum_etc': 'EF49 967D BD6C FE45', } cmd_group = ( - ('ref_altcoin_tx_chk', 'signing saved reference tx files'), - ('ref_addrfile_gen_eth', 'generate address file (ETH)'), - ('ref_addrfile_gen_etc', 'generate address file (ETC)'), - ('ref_addrfile_gen_dash', 'generate address file (DASH)'), - ('ref_addrfile_gen_zec', 'generate address file (ZEC-T)'), - ('ref_addrfile_gen_zec_z','generate address file (ZEC-Z)'), - ('ref_addrfile_gen_xmr', 'generate address file (XMR)'), - # we test the unoptimized ed25519 mod in unit_tests.py, so skip this -# ('ref_addrfile_gen_xmr_slow','generate address file (XMR - unoptimized ed25519 module)'), + ('ref_altcoin_tx_chk', 'signing saved reference tx files'), + ('ref_addrfile_gen_eth', 'generate address file (ETH)'), + ('ref_addrfile_gen_etc', 'generate address file (ETC)'), + ('ref_addrfile_gen_dash', 'generate address file (DASH)'), + ('ref_addrfile_gen_zec', 'generate address file (ZEC-T)'), + ('ref_addrfile_gen_zec_z', 'generate address file (ZEC-Z)'), + ('ref_addrfile_gen_xmr', 'generate address file (XMR)'), - ('ref_keyaddrfile_gen_eth', 'generate key-address file (ETH)'), - ('ref_keyaddrfile_gen_etc', 'generate key-address file (ETC)'), - ('ref_keyaddrfile_gen_dash', 'generate key-address file (DASH)'), - ('ref_keyaddrfile_gen_zec', 'generate key-address file (ZEC-T)'), - ('ref_keyaddrfile_gen_zec_z','generate key-address file (ZEC-Z)'), - ('ref_keyaddrfile_gen_xmr', 'generate key-address file (XMR)'), - ('ref_viewkeyaddrfile_gen_xmr','generate viewkey-address file (XMR)'), + ('ref_keyaddrfile_gen_eth', 'generate key-address file (ETH)'), + ('ref_keyaddrfile_gen_etc', 'generate key-address file (ETC)'), + ('ref_keyaddrfile_gen_dash', 'generate key-address file (DASH)'), + ('ref_keyaddrfile_gen_zec', 'generate key-address file (ZEC-T)'), + ('ref_keyaddrfile_gen_zec_z', 'generate key-address file (ZEC-Z)'), + ('ref_keyaddrfile_gen_xmr', 'generate key-address file (XMR)'), + ('ref_viewkeyaddrfile_gen_xmr', 'generate viewkey-address file (XMR)'), - ('ref_addrfile_chk_eth', 'reference address file (ETH)'), - ('ref_addrfile_chk_etc', 'reference address file (ETC)'), - ('ref_addrfile_chk_dash','reference address file (DASH)'), - ('ref_addrfile_chk_zec', 'reference address file (ZEC-T)'), - ('ref_addrfile_chk_zec_z','reference address file (ZEC-Z)'), - ('ref_addrfile_chk_xmr', 'reference address file (XMR)'), + ('ref_addrfile_chk_eth', 'reference address file (ETH)'), + ('ref_addrfile_chk_etc', 'reference address file (ETC)'), + ('ref_addrfile_chk_dash', 'reference address file (DASH)'), + ('ref_addrfile_chk_zec', 'reference address file (ZEC-T)'), + ('ref_addrfile_chk_zec_z', 'reference address file (ZEC-Z)'), + ('ref_addrfile_chk_xmr', 'reference address file (XMR)'), - ('ref_keyaddrfile_chk_eth', 'reference key-address file (ETH)'), - ('ref_keyaddrfile_chk_etc', 'reference key-address file (ETC)'), - ('ref_keyaddrfile_chk_dash','reference key-address file (DASH)'), - ('ref_keyaddrfile_chk_zec', 'reference key-address file (ZEC-T)'), - ('ref_keyaddrfile_chk_zec_z','reference key-address file (ZEC-Z)'), - ('ref_keyaddrfile_chk_xmr', 'reference key-address file (XMR)'), + ('ref_keyaddrfile_chk_eth', 'reference key-address file (ETH)'), + ('ref_keyaddrfile_chk_etc', 'reference key-address file (ETC)'), + ('ref_keyaddrfile_chk_dash', 'reference key-address file (DASH)'), + ('ref_keyaddrfile_chk_zec', 'reference key-address file (ZEC-T)'), + ('ref_keyaddrfile_chk_zec_z', 'reference key-address file (ZEC-Z)'), + ('ref_keyaddrfile_chk_xmr', 'reference key-address file (XMR)'), ('ref_viewkeyaddrfile_chk_xmr', 'reference viewkey-address file (XMR)'), ) @@ -87,11 +85,11 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase): Though this basically duplicates the autosign test, here we do everything via the command line, so it's worth doing """ - self.write_to_tmpfile(pwfile,dfl_wpasswd) - passfile = joinpath(self.tmpdir,pwfile) + self.write_to_tmpfile(pwfile, dfl_wpasswd) + passfile = joinpath(self.tmpdir, pwfile) from mmgen.tx.file import MMGenTxFile src = CmdTestRef.sources['ref_tx_file'] - for coin,files in src.items(): + for coin, files in src.items(): if coin == 'mm1': coin = 'eth' token_desc = ':MM1' @@ -103,14 +101,14 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase): txfile = joinpath( ref_dir, self._get_ref_subdir_by_coin(coin), - fn ) - proto = MMGenTxFile.get_proto(cfg,txfile,quiet_open=True) + fn) + proto = MMGenTxFile.get_proto(cfg, txfile, quiet_open=True) if proto.sign_mode == 'daemon': start_test_daemons(proto.network_id) set_vt100() t = self.spawn( 'mmgen-txsign', - ['--outdir=test/trash','--yes', f'--passwd-file={passfile}', dfl_words_file, txfile], + ['--outdir=test/trash', '--yes', f'--passwd-file={passfile}', dfl_words_file, txfile], extra_desc = f'{proto.coin}{token_desc} {proto.network}') t.read() t.ok() @@ -118,64 +116,71 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase): stop_test_daemons(proto.network_id) return 'ok' - def ref_altcoin_addrgen(self,coin,mmtype,gen_what='addr',coin_suf='',add_args=[],addr_idx_list=None): + def ref_altcoin_addrgen( + self, + coin, + mmtype, + gen_what = 'addr', + coin_suf = '', + add_args = [], + addr_idx_list = None): wf = dfl_words_file t = self.spawn( 'mmgen-keygen' if 'key' in gen_what else 'mmgen-addrgen', - ['-Sq','--coin='+coin] + + ['-Sq', '--coin='+coin] + (['--type='+mmtype] if mmtype else []) + add_args + - [wf,addr_idx_list or dfl_addr_idx_list]) + [wf, addr_idx_list or dfl_addr_idx_list]) if 'key' in gen_what: - t.expect('Encrypt key list? (y/N): ','N') - chk = t.expect_getend(r'.* data checksum for \S*: ',regex=True) + t.expect('Encrypt key list? (y/N): ', 'N') + chk = t.expect_getend(r'.* data checksum for \S*: ', regex=True) chk_ref = self.chk_data[ 'ref_{}addrfile_chksum_{}{}'.format( (gen_what if 'key' in gen_what else ''), coin.lower(), - coin_suf ) + coin_suf) ] - cmp_or_die(chk,chk_ref,desc=f'{gen_what}list data checksum') + cmp_or_die(chk, chk_ref, desc=f'{gen_what}list data checksum') return t def ref_addrfile_gen_eth(self): - return self.ref_altcoin_addrgen(coin='ETH',mmtype='ethereum') + return self.ref_altcoin_addrgen(coin='ETH', mmtype='ethereum') def ref_addrfile_gen_etc(self): - return self.ref_altcoin_addrgen(coin='ETC',mmtype='ethereum') + return self.ref_altcoin_addrgen(coin='ETC', mmtype='ethereum') def ref_addrfile_gen_dash(self): - return self.ref_altcoin_addrgen(coin='DASH',mmtype='compressed') + return self.ref_altcoin_addrgen(coin='DASH', mmtype='compressed') def ref_addrfile_gen_zec(self): - return self.ref_altcoin_addrgen(coin='ZEC',mmtype='compressed') + return self.ref_altcoin_addrgen(coin='ZEC', mmtype='compressed') def ref_addrfile_gen_zec_z(self): - return self.ref_altcoin_addrgen(coin='ZEC',mmtype='zcash_z',coin_suf='_z') + return self.ref_altcoin_addrgen(coin='ZEC', mmtype='zcash_z', coin_suf='_z') def ref_addrfile_gen_xmr(self): - return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero') + return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero') def ref_addrfile_gen_xmr_slow(self): - return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero',add_args=['--keygen-backend=2']) + return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero', add_args=['--keygen-backend=2']) def ref_keyaddrfile_gen_eth(self): - return self.ref_altcoin_addrgen(coin='ETH',mmtype='ethereum',gen_what='key') + return self.ref_altcoin_addrgen(coin='ETH', mmtype='ethereum', gen_what='key') def ref_keyaddrfile_gen_etc(self): - return self.ref_altcoin_addrgen(coin='ETC',mmtype='ethereum',gen_what='key') + return self.ref_altcoin_addrgen(coin='ETC', mmtype='ethereum', gen_what='key') def ref_keyaddrfile_gen_dash(self): - return self.ref_altcoin_addrgen(coin='DASH',mmtype='compressed',gen_what='key') + return self.ref_altcoin_addrgen(coin='DASH', mmtype='compressed', gen_what='key') def ref_keyaddrfile_gen_zec(self): - return self.ref_altcoin_addrgen(coin='ZEC',mmtype='compressed',gen_what='key') + return self.ref_altcoin_addrgen(coin='ZEC', mmtype='compressed', gen_what='key') def ref_keyaddrfile_gen_zec_z(self): - return self.ref_altcoin_addrgen(coin='ZEC',mmtype='zcash_z',coin_suf='_z',gen_what='key') + return self.ref_altcoin_addrgen(coin='ZEC', mmtype='zcash_z', coin_suf='_z', gen_what='key') def ref_keyaddrfile_gen_xmr(self): - return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero',gen_what='key') + return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero', gen_what='key') def ref_viewkeyaddrfile_gen_xmr(self): return self.ref_altcoin_addrgen( @@ -183,57 +188,56 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase): mmtype = 'monero', gen_what = 'viewkey', add_args = ['--viewkeys'], - addr_idx_list = '1-3' ) + addr_idx_list = '1-3') def ref_addrfile_chk_eth(self): - return self.ref_addrfile_chk(ftype='addr',coin='ETH',subdir='ethereum',pfx='-ETH', + return self.ref_addrfile_chk(ftype='addr', coin='ETH', subdir='ethereum', pfx='-ETH', pat='ETH Mainnet.*Ethereum') def ref_addrfile_chk_etc(self): - return self.ref_addrfile_chk(ftype='addr',coin='ETC',subdir='ethereum_classic',pfx='-ETC', + return self.ref_addrfile_chk(ftype='addr', coin='ETC', subdir='ethereum_classic', pfx='-ETC', pat='ETH Mainnet.*Ethereum') def ref_addrfile_chk_dash(self): - return self.ref_addrfile_chk(ftype='addr',coin='DASH',subdir='dash',pfx='-DASH-C', + return self.ref_addrfile_chk(ftype='addr', coin='DASH', subdir='dash', pfx='-DASH-C', pat='DASH Mainnet.*Compressed') def ref_addrfile_chk_zec(self): - return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-C', + return self.ref_addrfile_chk(ftype='addr', coin='ZEC', subdir='zcash', pfx='-ZEC-C', pat='ZEC Mainnet.*Compressed') def ref_addrfile_chk_zec_z(self): - return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z', + return self.ref_addrfile_chk(ftype='addr', coin='ZEC', subdir='zcash', pfx='-ZEC-Z', mmtype='z', pat='ZEC Mainnet.*Zcash_z') def ref_addrfile_chk_xmr(self): - return self.ref_addrfile_chk(ftype='addr',coin='XMR',subdir='monero',pfx='-XMR-M', + return self.ref_addrfile_chk(ftype='addr', coin='XMR', subdir='monero', pfx='-XMR-M', pat='XMR Mainnet.*Monero') - def ref_keyaddrfile_chk_eth(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='ETH',subdir='ethereum',pfx='-ETH', + return self.ref_addrfile_chk(ftype='keyaddr', coin='ETH', subdir='ethereum', pfx='-ETH', pat='ETH Mainnet.*Ethereum') def ref_keyaddrfile_chk_etc(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='ETC',subdir='ethereum_classic',pfx='-ETC', + return self.ref_addrfile_chk(ftype='keyaddr', coin='ETC', subdir='ethereum_classic', pfx='-ETC', pat='ETH Mainnet.*Ethereum') def ref_keyaddrfile_chk_dash(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='DASH',subdir='dash',pfx='-DASH-C', + return self.ref_addrfile_chk(ftype='keyaddr', coin='DASH', subdir='dash', pfx='-DASH-C', pat='DASH Mainnet.*Compressed') def ref_keyaddrfile_chk_zec(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-C', + return self.ref_addrfile_chk(ftype='keyaddr', coin='ZEC', subdir='zcash', pfx='-ZEC-C', pat='ZEC Mainnet.*Compressed') def ref_keyaddrfile_chk_zec_z(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z', + return self.ref_addrfile_chk(ftype='keyaddr', coin='ZEC', subdir='zcash', pfx='-ZEC-Z', mmtype='z', pat='ZEC Mainnet.*Zcash_z') def ref_keyaddrfile_chk_xmr(self): - return self.ref_addrfile_chk(ftype='keyaddr',coin='XMR',subdir='monero',pfx='-XMR-M', + return self.ref_addrfile_chk(ftype='keyaddr', coin='XMR', subdir='monero', pfx='-XMR-M', pat='XMR Mainnet.*Monero') def ref_viewkeyaddrfile_chk_xmr(self): - return self.ref_addrfile_chk(ftype='viewkeyaddr',coin='XMR',subdir='monero',pfx='-XMR-M', + return self.ref_addrfile_chk(ftype='viewkeyaddr', coin='XMR', subdir='monero', pfx='-XMR-M', pat='XMR Mainnet.*Monero') diff --git a/test/cmdtest_py_d/ct_regtest.py b/test/cmdtest_py_d/ct_regtest.py index 5552ffbf..aab87908 100755 --- a/test/cmdtest_py_d/ct_regtest.py +++ b/test/cmdtest_py_d/ct_regtest.py @@ -27,10 +27,10 @@ from mmgen.proto.btc.regtest import MMGenRegtest from mmgen.proto.bch.cashaddr import b32a from mmgen.proto.btc.common import b58a from mmgen.color import yellow -from mmgen.util import msg_r,die,gmsg,capfirst,fmt_list +from mmgen.util import msg_r, die, gmsg, capfirst, fmt_list from mmgen.protocol import init_proto from mmgen.addrlist import AddrList -from mmgen.wallet import Wallet,get_wallet_cls +from mmgen.wallet import Wallet, get_wallet_cls from ..include.common import ( cfg, @@ -66,97 +66,97 @@ dfl_wcls = get_wallet_cls('mmgen') tx_fee = rtFundAmt = rtFee = rtBals = rtBals_gb = rtBobOp3 = rtAmts = {} # pylint rt_pw = 'abc-α' rt_data = { - 'tx_fee': {'btc':'0.0001','bch':'0.001','ltc':'0.01'}, - 'rtFundAmt': {'btc':'500','bch':'500','ltc':'5500'}, + 'tx_fee': {'btc':'0.0001', 'bch':'0.001', 'ltc':'0.01'}, + 'rtFundAmt': {'btc':'500', 'bch':'500', 'ltc':'5500'}, 'rtFee': { - 'btc': ('20s','10s','60s','31s','10s','20s'), - 'bch': ('20s','10s','60s','0.0001','10s','20s'), - 'ltc': ('1000s','500s','1500s','0.05','400s','1000s') + 'btc': ('20s', '10s', '60s', '31s', '10s', '20s'), + 'bch': ('20s', '10s', '60s', '0.0001', '10s', '20s'), + 'ltc': ('1000s', '500s', '1500s', '0.05', '400s', '1000s') }, 'rtBals': { - 'btc': ('499.9999488','399.9998282','399.9998147','399.9996877', - '52.99980410','946.99933647','999.99914057','52.9999', - '946.99933647','0.4169328','6.24987417'), - 'bch': ('499.9999484','399.9999194','399.9998972','399.9997692', - '46.78890380','953.20966920','999.99857300','46.789', - '953.2096692','0.4169328','39.58187387'), - 'ltc': ('5499.99744','5399.994425','5399.993885','5399.987535', - '52.98520500','10946.93753500','10999.92274000','52.99', - '10946.937535','0.41364','6.24846787'), + 'btc': ('499.9999488', '399.9998282', '399.9998147', '399.9996877', + '52.99980410', '946.99933647', '999.99914057', '52.9999', + '946.99933647', '0.4169328', '6.24987417'), + 'bch': ('499.9999484', '399.9999194', '399.9998972', '399.9997692', + '46.78890380', '953.20966920', '999.99857300', '46.789', + '953.2096692', '0.4169328', '39.58187387'), + 'ltc': ('5499.99744', '5399.994425', '5399.993885', '5399.987535', + '52.98520500', '10946.93753500', '10999.92274000', '52.99', + '10946.937535', '0.41364', '6.24846787'), }, 'rtBals_gb': { 'btc': { '0conf0': { - 'mmgen': ('283.22339537','283.22339537'), - 'nonmm': ('16.77647763','116.77629233'), - 'total': ('299.999873','399.9996877'), + 'mmgen': ('283.22339537', '283.22339537'), + 'nonmm': ('16.77647763', '116.77629233'), + 'total': ('299.999873', '399.9996877'), }, '0conf1': { - 'mmgen': ('283.22339537','0'), - 'nonmm': ('16.77647763','99.9998147'), - 'total': ('299.999873','99.9998147'), + 'mmgen': ('283.22339537', '0'), + 'nonmm': ('16.77647763', '99.9998147'), + 'total': ('299.999873', '99.9998147'), }, '1conf1': { - 'mmgen': ('0','283.22339537'), - 'nonmm': ('0','116.77629233'), - 'total': ('0','399.9996877'), + 'mmgen': ('0', '283.22339537'), + 'nonmm': ('0', '116.77629233'), + 'total': ('0', '399.9996877'), }, '1conf2': { - 'mmgen': ('0','283.22339537','0'), - 'nonmm': ('0','16.77647763','99.9998147'), - 'total': ('0','299.999873','99.9998147'), + 'mmgen': ('0', '283.22339537', '0'), + 'nonmm': ('0', '16.77647763', '99.9998147'), + 'total': ('0', '299.999873', '99.9998147'), }, }, 'bch': { '0conf0': { - 'mmgen': ('283.22339437','283.22339437'), - 'nonmm': ('16.77647763','116.77637483'), - 'total': ('299.999872','399.9997692'), + 'mmgen': ('283.22339437', '283.22339437'), + 'nonmm': ('16.77647763', '116.77637483'), + 'total': ('299.999872', '399.9997692'), }, '0conf1': { - 'mmgen': ('283.22339437','0'), - 'nonmm': ('16.77647763','99.9998972'), - 'total': ('299.999872','99.9998972'), + 'mmgen': ('283.22339437', '0'), + 'nonmm': ('16.77647763', '99.9998972'), + 'total': ('299.999872', '99.9998972'), }, '1conf1': { - 'mmgen': ('0','283.22339437'), - 'nonmm': ('0','116.77637483'), - 'total': ('0','399.9997692'), + 'mmgen': ('0', '283.22339437'), + 'nonmm': ('0', '116.77637483'), + 'total': ('0', '399.9997692'), }, '1conf2': { - 'mmgen': ('0','283.22339437','0'), - 'nonmm': ('0','16.77647763','99.9998972'), - 'total': ('0','299.999872','99.9998972'), + 'mmgen': ('0', '283.22339437', '0'), + 'nonmm': ('0', '16.77647763', '99.9998972'), + 'total': ('0', '299.999872', '99.9998972'), }, }, 'ltc': { '0conf0': { - 'mmgen': ('283.21717237','283.21717237'), - 'nonmm': ('16.77647763','5116.77036263'), - 'total': ('299.99365','5399.987535'), + 'mmgen': ('283.21717237', '283.21717237'), + 'nonmm': ('16.77647763', '5116.77036263'), + 'total': ('299.99365', '5399.987535'), }, '0conf1': { - 'mmgen': ('283.21717237','0'), - 'nonmm': ('16.77647763','5099.993885'), - 'total': ('299.99365','5099.993885'), + 'mmgen': ('283.21717237', '0'), + 'nonmm': ('16.77647763', '5099.993885'), + 'total': ('299.99365', '5099.993885'), }, '1conf1': { - 'mmgen': ('0','283.21717237'), - 'nonmm': ('0','5116.77036263'), - 'total': ('0','5399.987535'), + 'mmgen': ('0', '283.21717237'), + 'nonmm': ('0', '5116.77036263'), + 'total': ('0', '5399.987535'), }, '1conf2': { - 'mmgen': ('0','283.21717237','0'), - 'nonmm': ('0','16.77647763','5099.993885'), - 'total': ('0','299.99365','5099.993885'), + 'mmgen': ('0', '283.21717237', '0'), + 'nonmm': ('0', '16.77647763', '5099.993885'), + 'total': ('0', '299.99365', '5099.993885'), }, } }, - 'rtBobOp3': {'btc':'S:2','bch':'L:3','ltc':'S:2'}, + 'rtBobOp3': {'btc':'S:2', 'bch':'L:3', 'ltc':'S:2'}, 'rtAmts': { - 'btc': ('500','500'), - 'bch': ('500','560'), - 'ltc': ('5500','5500') + 'btc': ('500', '500'), + 'bch': ('500', '560'), + 'ltc': ('5500', '5500') } } @@ -168,10 +168,10 @@ def make_burn_addr(proto): proto = proto, mmtype = 'compressed').pubhash2addr('00'*20) -class CmdTestRegtest(CmdTestBase,CmdTestShared): +class CmdTestRegtest(CmdTestBase, CmdTestShared): 'transacting and tracking wallet operations via regtest mode' - networks = ('btc','ltc','bch') - passthru_opts = ('coin','rpc_backend') + networks = ('btc', 'ltc', 'bch') + passthru_opts = ('coin', 'rpc_backend') tmpdir_nums = [17] color = True deterministic = False @@ -184,7 +184,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('subgroup.misc', []), ('subgroup.init_bob', []), ('subgroup.init_alice', []), - ('subgroup.fund_users', ['init_bob','init_alice']), + ('subgroup.fund_users', ['init_bob', 'init_alice']), ('subgroup.msg', ['init_bob']), ('subgroup.twexport', ['fund_users']), ('subgroup.rescan', ['fund_users']), @@ -194,7 +194,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('subgroup.txhist', ['main']), ('subgroup.label', ['main']), ('subgroup.view', ['label']), - ('subgroup._auto_chg_deps', ['twexport','label']), + ('subgroup._auto_chg_deps', ['twexport', 'label']), ('subgroup.auto_chg', ['_auto_chg_deps']), ('stop', 'stopping regtest daemon'), ) @@ -210,7 +210,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('bob_listaddrs_noaddrs', 'viewing Bob’s addresses (error, no addrs)'), ('walletgen_bob', 'wallet generation (Bob)'), ('addrgen_bob', 'address generation (Bob)'), - ('addrimport_bob', "importing Bob's addresses"), + ('addrimport_bob', 'importing Bob’s addresses'), ('bob_twview_nobal', 'viewing Bob’s unspent outputs (error, no balance)'), ('bob_listaddrs_nobal', 'viewing Bob’s addresses (OK, no balance)'), ), @@ -218,20 +218,20 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): 'creating Alice’s MMGen wallet and tracking wallet', ('walletgen_alice', 'wallet generation (Alice)'), ('addrgen_alice', 'address generation (Alice)'), - ('addrimport_alice', "importing Alice's addresses"), + ('addrimport_alice', 'importing Alice’s addresses'), ), 'fund_users': ( 'funding Bob and Alice’s wallets', - ('bob_import_miner_addr', "importing miner’s coinbase addr into Bob’s wallet"), - ('fund_bob_deterministic', "funding Bob’s first MMGen address (deterministic method)"), - ('fund_alice_deterministic', "funding Alice’s first MMGen address (deterministic method)"), + ('bob_import_miner_addr', 'importing miner’s coinbase addr into Bob’s wallet'), + ('fund_bob_deterministic', 'funding Bob’s first MMGen address (deterministic method)'), + ('fund_alice_deterministic', 'funding Alice’s first MMGen address (deterministic method)'), ('bob_recreate_tracking_wallet', 'creation of new tracking wallet (Bob)'), - ('addrimport_bob2', "reimporting Bob's addresses"), - ('fund_bob', "funding Bob's wallet"), - ('fund_alice', "funding Alice's wallet"), + ('addrimport_bob2', 'reimporting Bob’s addresses'), + ('fund_bob', 'funding Bob’s wallet'), + ('fund_alice', 'funding Alice’s wallet'), ('generate', 'mining a block'), - ('bob_bal1', "Bob's balance"), - ('generate_extra_deterministic', "generate extra blocks for deterministic run"), + ('bob_bal1', 'Bob’s balance'), + ('generate_extra_deterministic', 'generate extra blocks for deterministic run'), ), 'msg': ( 'message signing', @@ -282,19 +282,19 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ), 'main': ( 'creating, signing, sending and bumping transactions', - ('bob_add_comment1', "adding an 80-screen-width label (lat+cyr+gr)"), - ('bob_twview1', "viewing Bob's tracking wallet"), - ('bob_split1', "splitting Bob's funds"), + ('bob_add_comment1', 'adding an 80-screen-width label (lat+cyr+gr)'), + ('bob_twview1', 'viewing Bob’s tracking wallet'), + ('bob_split1', 'splitting Bob’s funds'), ('generate', 'mining a block'), - ('bob_bal2', "Bob's balance"), + ('bob_bal2', 'Bob’s balance'), ('bob_rbf_1output_create', 'creating RBF tx with one output'), ('bob_rbf_1output_bump', 'bumping RBF tx with one output'), - ('bob_bal2a', "Bob's balance (age_fmt=confs)"), - ('bob_bal2b', "Bob's balance (showempty=1)"), - ('bob_bal2c', "Bob's balance (showempty=1 minconf=2 age_fmt=days)"), - ('bob_bal2d', "Bob's balance (minconf=2)"), - ('bob_bal2e', "Bob's balance (showempty=1 sort=age)"), - ('bob_bal2f', "Bob's balance (showempty=1 sort=age,reverse)"), + ('bob_bal2a', 'Bob’s balance (age_fmt=confs)'), + ('bob_bal2b', 'Bob’s balance (showempty=1)'), + ('bob_bal2c', 'Bob’s balance (showempty=1 minconf=2 age_fmt=days)'), + ('bob_bal2d', 'Bob’s balance (minconf=2)'), + ('bob_bal2e', 'Bob’s balance (showempty=1 sort=age)'), + ('bob_bal2f', 'Bob’s balance (showempty=1 sort=age,reverse)'), ('bob_send_maybe_rbf', 'sending funds to Alice (RBF, if supported)'), ('get_mempool1', 'mempool (before RBF bump)'), ('bob_rbf_status1', 'getting status of transaction'), @@ -307,43 +307,43 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('bob_rbf_status5', 'getting status of replacement transaction (confirmed)'), ('generate', 'mining a block'), ('bob_rbf_status6', 'getting status of transaction after confirmed (2) replacement'), - ('bob_bal3', "Bob's balance"), + ('bob_bal3', 'Bob’s balance'), ('bob_pre_import', 'sending to non-imported address'), ('generate', 'mining a block'), ('bob_import_addr', 'importing non-MMGen address'), - ('bob_bal4', "Bob's balance (after import)"), + ('bob_bal4', 'Bob’s balance (after import)'), ('bob_import_list', 'importing flat address list'), ('bob_import_list_rescan', 'importing flat address list with --rescan'), ('bob_import_list_rescan_aio', 'importing flat address list with --rescan (aiohttp backend)'), - ('bob_split2', "splitting Bob's funds"), - ('bob_0conf0_getbalance', "Bob's balance (unconfirmed, minconf=0)"), - ('bob_0conf1_getbalance', "Bob's balance (unconfirmed, minconf=1)"), + ('bob_split2', 'splitting Bob’s funds'), + ('bob_0conf0_getbalance', 'Bob’s balance (unconfirmed, minconf=0)'), + ('bob_0conf1_getbalance', 'Bob’s balance (unconfirmed, minconf=1)'), ('generate', 'mining a block'), - ('bob_1conf1_getbalance', "Bob's balance (confirmed, minconf=1)"), - ('bob_1conf2_getbalance', "Bob's balance (confirmed, minconf=2)"), - ('bob_bal5', "Bob's balance"), + ('bob_1conf1_getbalance', 'Bob’s balance (confirmed, minconf=1)'), + ('bob_1conf2_getbalance', 'Bob’s balance (confirmed, minconf=2)'), + ('bob_bal5', 'Bob’s balance'), ('bob_send_non_mmgen', 'sending funds to Alice (from non-MMGen addrs)'), ('generate', 'mining a block'), ('alice_send_estimatefee', 'tx creation with no fee on command line'), ('generate', 'mining a block'), - ('bob_bal6', "Bob's balance"), + ('bob_bal6', 'Bob’s balance'), - ('bob_subwallet_addrgen1', "generating Bob's addrs from subwallet 29L"), - ('bob_subwallet_addrgen2', "generating Bob's addrs from subwallet 127S"), - ('bob_subwallet_addrimport1', "importing Bob's addrs from subwallet 29L"), - ('bob_subwallet_addrimport2', "importing Bob's addrs from subwallet 127S"), - ('bob_subwallet_fund', "funding Bob's subwallet addrs"), + ('bob_subwallet_addrgen1', 'generating Bob’s addrs from subwallet 29L'), + ('bob_subwallet_addrgen2', 'generating Bob’s addrs from subwallet 127S'), + ('bob_subwallet_addrimport1', 'importing Bob’s addrs from subwallet 29L'), + ('bob_subwallet_addrimport2', 'importing Bob’s addrs from subwallet 127S'), + ('bob_subwallet_fund', 'funding Bob’s subwallet addrs'), ('generate', 'mining a block'), - ('bob_twview2', "viewing Bob's tracking wallet"), - ('bob_twview3', "viewing Bob's tracking wallet"), + ('bob_twview2', 'viewing Bob’s tracking wallet'), + ('bob_twview3', 'viewing Bob’s tracking wallet'), ('bob_subwallet_txcreate', 'creating a transaction with subwallet inputs'), ('bob_subwallet_txsign', 'signing a transaction with subwallet inputs'), - ('bob_subwallet_txdo', "sending from Bob's subwallet addrs"), + ('bob_subwallet_txdo', 'sending from Bob’s subwallet addrs'), ('generate', 'mining a block'), - ('bob_twview4', "viewing Bob's tracking wallet"), + ('bob_twview4', 'viewing Bob’s tracking wallet'), - ('bob_alice_bal', "Bob and Alice's balances"), + ('bob_alice_bal', 'Bob and Alice’s balances'), ('bob_nochg_burn', 'zero-change transaction to burn address'), ('generate', 'mining a block'), @@ -366,16 +366,16 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ), 'txhist': ( 'viewing transaction history', - ('bob_txhist1', "viewing Bob's transaction history (sort=age)"), - ('bob_txhist2', "viewing Bob's transaction history (sort=blockheight reverse=1)"), - ('bob_txhist3', "viewing Bob's transaction history (sort=blockheight sinceblock=-7)"), - ('bob_txhist4', "viewing Bob's transaction history (detail=1)"), - ('bob_txhist5', "viewing Bob's transaction history (sinceblock=399 detail=1)"), - ('bob_txhist_interactive', "viewing Bob's transaction history (age_fmt=date_time interactive=true)"), + ('bob_txhist1', 'viewing Bob’s transaction history (sort=age)'), + ('bob_txhist2', 'viewing Bob’s transaction history (sort=blockheight reverse=1)'), + ('bob_txhist3', 'viewing Bob’s transaction history (sort=blockheight sinceblock=-7)'), + ('bob_txhist4', 'viewing Bob’s transaction history (detail=1)'), + ('bob_txhist5', 'viewing Bob’s transaction history (sinceblock=399 detail=1)'), + ('bob_txhist_interactive', 'viewing Bob’s transaction history (age_fmt=date_time interactive=true)'), ), 'label': ( 'adding, removing and editing labels', - ('alice_bal2', "Alice's balance"), + ('alice_bal2', 'Alice’s balance'), ('alice_add_comment1', 'adding a label'), ('alice_chk_comment1', 'the label'), ('alice_add_comment2', 'adding a label'), @@ -421,10 +421,10 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ), 'auto_chg': ( 'automatic change address selection', - ('bob_auto_chg1', 'creating an automatic change address transaction (C)'), - ('bob_auto_chg2', 'creating an automatic change address transaction (B)'), - ('bob_auto_chg3', 'creating an automatic change address transaction (S)'), - ('bob_auto_chg4', 'creating an automatic change address transaction (single address)'), + ('bob_auto_chg1', 'creating an automatic change address transaction (C)'), + ('bob_auto_chg2', 'creating an automatic change address transaction (B)'), + ('bob_auto_chg3', 'creating an automatic change address transaction (S)'), + ('bob_auto_chg4', 'creating an automatic change address transaction (single address)'), ('bob_auto_chg_addrtype1', 'creating an automatic change address transaction by addrtype (C)'), ('bob_auto_chg_addrtype2', 'creating an automatic change address transaction by addrtype (B)'), ('bob_auto_chg_addrtype3', 'creating an automatic change address transaction by addrtype (S)'), @@ -464,15 +464,15 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ), } - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + CmdTestBase.__init__(self, trunner, cfgs, spawn) if trunner is None: return if self.proto.testnet: - die(2,'--testnet and --regtest options incompatible with regtest test suite') + die(2, '--testnet and --regtest options incompatible with regtest test suite') coin = self.coin @@ -492,22 +492,22 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): self.deterministic = True self.spawn_env['MMGEN_BOGUS_SEND'] = '' - self.write_to_tmpfile('wallet_password',rt_pw) + self.write_to_tmpfile('wallet_password', rt_pw) self.dfl_mmtype = 'C' if coin == 'bch' else 'B' self.burn_addr = make_burn_addr(self.proto) self.user_sids = {} - def _add_comments_to_addr_file(self,addrfile,outfile,use_comments=False): + def _add_comments_to_addr_file(self, addrfile, outfile, use_comments=False): silence() gmsg(f'Adding comments to address file {addrfile!r}') - a = AddrList( cfg, self.proto, addrfile ) - for n,idx in enumerate(a.idxs(),1): + a = AddrList(cfg, self.proto, addrfile) + for n, idx in enumerate(a.idxs(), 1): if use_comments: - a.set_comment(idx,get_comment()) + a.set_comment(idx, get_comment()) else: if n % 2: - a.set_comment(idx,f'Test address {n}') + a.set_comment(idx, f'Test address {n}') a.file.format(add_comments=True) from mmgen.fileutil import write_data_to_file write_data_to_file( @@ -515,15 +515,15 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): outfile = outfile, data = a.file.fmt_data, quiet = True, - ignore_opt_outdir = True ) + ignore_opt_outdir = True) end_silence() def setup(self): - stop_test_daemons(self.proto.network_id,force=True,remove_datadir=True) + stop_test_daemons(self.proto.network_id, force=True, remove_datadir=True) from shutil import rmtree try: - rmtree(joinpath(self.tr.data_dir,'regtest')) + rmtree(joinpath(self.tr.data_dir, 'regtest')) except: pass t = self.spawn( @@ -537,16 +537,16 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return t def daemon_version(self): - t = self.spawn('mmgen-tool', ['--bob','daemon_version']) + t = self.spawn('mmgen-tool', ['--bob', 'daemon_version']) t.expect('version') return t def halving_calculator_bob(self): - t = self.spawn('halving-calculator.py',['--bob'],cmd_dir='examples') + t = self.spawn('halving-calculator.py', ['--bob'], cmd_dir='examples') t.expect('time until halving') return t - def walletgen(self,user): + def walletgen(self, user): t = self.spawn('mmgen-walletgen', ['-q', '-r0', '-p1', f'--{user}'], no_passthru_opts=True) t.passphrase_new(f'new {dfl_wcls.desc}', rt_pw) t.label() @@ -562,17 +562,17 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def _user_dir(self, user, coin=None): return joinpath(self.tr.data_dir, 'regtest', user) - def _user_sid(self,user): + def _user_sid(self, user): if user in self.user_sids: return self.user_sids[user] else: - self.user_sids[user] = os.path.basename(get_file_with_ext(self._user_dir(user),'mmdat'))[:8] + self.user_sids[user] = os.path.basename(get_file_with_ext(self._user_dir(user), 'mmdat'))[:8] return self.user_sids[user] - def _get_user_subsid(self,user,subseed_idx): - fn = get_file_with_ext(self._user_dir(user),dfl_wcls.ext) + def _get_user_subsid(self, user, subseed_idx): + fn = get_file_with_ext(self._user_dir(user), dfl_wcls.ext) silence() - w = Wallet( cfg, fn=fn, passwd_file=os.path.join(self.tmpdir,'wallet_password') ) + w = Wallet(cfg, fn=fn, passwd_file=os.path.join(self.tmpdir, 'wallet_password')) end_silence() return w.seed.subseed(subseed_idx).sid @@ -592,7 +592,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): + ([f'--subwallet={subseed_idx}'] if subseed_idx else []) + [addr_range], extra_desc = '({})'.format(MMGenAddrType.mmtypes[mmtype].name)) - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.written_to_file('Addresses') ok_msg() t.skip_ok = True @@ -612,7 +612,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): mmtypes = [], batch = True, quiet = True): - id_strs = { 'legacy':'', 'compressed':'-C', 'segwit':'-S', 'bech32':'-B' } + id_strs = {'legacy':'', 'compressed':'-C', 'segwit':'-S', 'bech32':'-B'} if not sid: sid = self._user_sid(user) from mmgen.addr import MMGenAddrType @@ -620,20 +620,20 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): desc = MMGenAddrType.mmtypes[mmtype].name addrfile = joinpath(self._user_dir(user), '{}{}{}[{}]{x}.regtest.addrs'.format( - sid,self.altcoin_pfx,id_strs[desc],addr_range, + sid, self.altcoin_pfx, id_strs[desc], addr_range, x='-α' if cfg.debug_utf8 else '')) if mmtype == self.proto.mmtypes[0] and user == 'bob': - self._add_comments_to_addr_file(addrfile,addrfile,use_comments=True) + self._add_comments_to_addr_file(addrfile, addrfile, use_comments=True) t = self.spawn( 'mmgen-addrimport', args = ( (['--quiet'] if quiet else []) + ['--'+user] + (['--batch'] if batch else []) + - [addrfile] ), - extra_desc = f'({desc})' ) + [addrfile]), + extra_desc = f'({desc})') if cfg.debug: - t.expect("Type uppercase 'YES' to confirm: ",'YES\n') + t.expect("Type uppercase 'YES' to confirm: ", 'YES\n') t.expect('Importing') if batch: t.expect(f'{num_addrs} addresses imported') @@ -647,14 +647,14 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def addrimport_bob(self): return self.addrimport('bob') def addrimport_alice(self): - return self.addrimport('alice',batch=False,quiet=False) + return self.addrimport('alice', batch=False, quiet=False) async def bob_import_miner_addr(self): if not self.deterministic: return 'skip' return self.spawn( 'mmgen-addrimport', - [ '--bob', '--rescan', '--quiet', f'--address={await self.rt.miner_addr}' ] ) + ['--bob', '--rescan', '--quiet', f'--address={await self.rt.miner_addr}']) async def fund_wallet_deterministic(self, addr, utxo_nums, skip_passphrase=False): """ @@ -662,24 +662,24 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): """ if not self.deterministic: return 'skip' - self.write_to_tmpfile('miner.key',f'{await self.rt.miner_wif}\n') - keyfile = joinpath(self.tmpdir,'miner.key') + self.write_to_tmpfile('miner.key', f'{await self.rt.miner_wif}\n') + keyfile = joinpath(self.tmpdir, 'miner.key') return self.user_txdo( 'bob', '40s', - [ f'{addr},{rtFundAmt}', self.burn_addr ], + [f'{addr}, {rtFundAmt}', self.burn_addr], utxo_nums, extra_args = [f'--keys-from-file={keyfile}'], - skip_passphrase = skip_passphrase ) + skip_passphrase = skip_passphrase) def fund_bob_deterministic(self): - return self.fund_wallet_deterministic( f'{self._user_sid("bob")}:C:1', '1-11' ) + return self.fund_wallet_deterministic(f'{self._user_sid("bob")}:C:1', '1-11') def fund_alice_deterministic(self): sid = self._user_sid('alice') - mmtype = ('L','S')[self.proto.cap('segwit')] - addr = self.get_addr_from_addrlist('alice',sid,mmtype,0,addr_range='1-5') - return self.fund_wallet_deterministic( addr, '1-11', skip_passphrase=True ) + mmtype = ('L', 'S')[self.proto.cap('segwit')] + addr = self.get_addr_from_addrlist('alice', sid, mmtype, 0, addr_range='1-5') + return self.fund_wallet_deterministic(addr, '1-11', skip_passphrase=True) def generate_extra_deterministic(self): if not self.deterministic: @@ -689,7 +689,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): async def bob_recreate_tracking_wallet(self): if not self.deterministic: return 'skip' - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) await self.rt.stop() from shutil import rmtree imsg('Deleting Bob’s old tracking wallet') @@ -707,22 +707,22 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return 'skip' return self.addrimport('bob') - def fund_wallet(self,user,mmtype,amt,sid=None,addr_range='1-5'): + def fund_wallet(self, user, mmtype, amt, sid=None, addr_range='1-5'): if self.deterministic: return 'skip' if not sid: sid = self._user_sid(user) - addr = self.get_addr_from_addrlist(user,sid,mmtype,0,addr_range=addr_range) - t = self.spawn('mmgen-regtest', ['send',str(addr),str(amt)]) + addr = self.get_addr_from_addrlist(user, sid, mmtype, 0, addr_range=addr_range) + t = self.spawn('mmgen-regtest', ['send', str(addr), str(amt)]) t.expect(f'Sending {amt} miner {self.proto.coin}') t.expect('Mined 1 block') return t def fund_bob(self): - return self.fund_wallet('bob','C',rtFundAmt) + return self.fund_wallet('bob', 'C', rtFundAmt) def fund_alice(self): - return self.fund_wallet('alice',('L','S')[self.proto.cap('segwit')],rtFundAmt) + return self.fund_wallet('alice', ('L', 'S')[self.proto.cap('segwit')], rtFundAmt) def user_twview( self, @@ -735,7 +735,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): exit_val = None): t = self.spawn('mmgen-tool', [f'--{user}'] + opts + [cmd] + [f'sort={sort}'], exit_val=exit_val) if chk: - t.expect(r'{}\b.*\D{}\b'.format(*chk),regex=True) + t.expect(r'{}\b.*\D{}\b'.format(*chk), regex=True) if expect: t.expect(expect, regex=True) return t @@ -758,14 +758,14 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def user_bal(self, user, bal, opts=[], args=['showempty=1'], skip_check=False): t = self.spawn('mmgen-tool', opts + [f'--{user}', 'listaddresses'] + args) if not skip_check: - cmp_or_die(f'{bal} {self.proto.coin}',strip_ansi_escapes(t.expect_getend('TOTAL: '))) + cmp_or_die(f'{bal} {self.proto.coin}', strip_ansi_escapes(t.expect_getend('TOTAL: '))) return t def alice_bal1(self): - return self.user_bal('alice',rtFundAmt) + return self.user_bal('alice', rtFundAmt) def alice_bal2(self): - return self.user_bal('alice',rtBals[8]) + return self.user_bal('alice', rtBals[8]) def bob_bal1(self): return self.user_bal('bob', rtFundAmt, self._cashaddr_opt(0)) @@ -774,64 +774,64 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return self.user_bal('bob', rtBals[0], self._cashaddr_opt(1)) def bob_bal2a(self): - return self.user_bal('bob',rtBals[0],args=['showempty=1','age_fmt=confs']) + return self.user_bal('bob', rtBals[0], args=['showempty=1', 'age_fmt=confs']) def bob_bal2b(self): - return self.user_bal('bob',rtBals[0],args=['showempty=1']) + return self.user_bal('bob', rtBals[0], args=['showempty=1']) def bob_bal2c(self): - return self.user_bal('bob',rtBals[0],args=['showempty=1','minconf=2','age_fmt=days'],skip_check=True) + return self.user_bal('bob', rtBals[0], args=['showempty=1', 'minconf=2', 'age_fmt=days'], skip_check=True) def bob_bal2d(self): - return self.user_bal('bob',rtBals[0],args=['minconf=2'],skip_check=True) + return self.user_bal('bob', rtBals[0], args=['minconf=2'], skip_check=True) def bob_bal2e(self): - return self.user_bal('bob',rtBals[0],args=['showempty=1','sort=amt']) + return self.user_bal('bob', rtBals[0], args=['showempty=1', 'sort=amt']) def bob_bal2f(self): - return self.user_bal('bob',rtBals[0],args=['showempty=0','sort=twmmid','reverse=1']) + return self.user_bal('bob', rtBals[0], args=['showempty=0', 'sort=twmmid', 'reverse=1']) def bob_bal3(self): - return self.user_bal('bob',rtBals[1]) + return self.user_bal('bob', rtBals[1]) def bob_bal4(self): - return self.user_bal('bob',rtBals[2]) + return self.user_bal('bob', rtBals[2]) def bob_bal5(self): - return self.user_bal('bob',rtBals[3]) + return self.user_bal('bob', rtBals[3]) def bob_bal6(self): - return self.user_bal('bob',rtBals[7]) + return self.user_bal('bob', rtBals[7]) def bob_subwallet_addrgen1(self): - return self.addrgen('bob',subseed_idx='29L',mmtypes=['C']) # 29L: 2FA7BBA8 + return self.addrgen('bob', subseed_idx='29L', mmtypes=['C']) # 29L: 2FA7BBA8 def bob_subwallet_addrgen2(self): - return self.addrgen('bob',subseed_idx='127S',mmtypes=['C']) # 127S: '09E8E286' + return self.addrgen('bob', subseed_idx='127S', mmtypes=['C']) # 127S: '09E8E286' - def subwallet_addrimport(self,user,subseed_idx): - sid = self._get_user_subsid(user,subseed_idx) - return self.addrimport(user,sid=sid,mmtypes=['C']) + def subwallet_addrimport(self, user, subseed_idx): + sid = self._get_user_subsid(user, subseed_idx) + return self.addrimport(user, sid=sid, mmtypes=['C']) def bob_subwallet_addrimport1(self): - return self.subwallet_addrimport('bob','29L') + return self.subwallet_addrimport('bob', '29L') def bob_subwallet_addrimport2(self): - return self.subwallet_addrimport('bob','127S') + return self.subwallet_addrimport('bob', '127S') def bob_subwallet_fund(self): - sid1 = self._get_user_subsid('bob','29L') - sid2 = self._get_user_subsid('bob','127S') - chg_addr = self._user_sid('bob') + (':B:1',':L:1')[self.proto.coin=='BCH'] + sid1 = self._get_user_subsid('bob', '29L') + sid2 = self._get_user_subsid('bob', '127S') + chg_addr = self._user_sid('bob') + (':B:1', ':L:1')[self.proto.coin=='BCH'] return self.user_txdo( user = 'bob', fee = rtFee[1], - outputs_cl = [sid1+':C:2,0.29',sid2+':C:3,0.127',chg_addr], - outputs_list = ('3','1')[self.proto.coin=='BCH'], + outputs_cl = [sid1+':C:2,0.29', sid2+':C:3,0.127', chg_addr], + outputs_list = ('3', '1')[self.proto.coin=='BCH'], extra_args = ['--subseeds=127'], - used_chg_addr_resp = (None,'y')[self.proto.coin=='BCH'] ) + used_chg_addr_resp = (None, 'y')[self.proto.coin=='BCH']) def bob_twview2(self): - sid1 = self._get_user_subsid('bob','29L') + sid1 = self._get_user_subsid('bob', '29L') return self.user_twview( 'bob', opts = self._cashaddr_opt(0), @@ -840,7 +840,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): expect = rf'[{b58a}]{{8}}' if self.proto.coin == 'BCH' else None) def bob_twview3(self): - sid2 = self._get_user_subsid('bob','127S') + sid2 = self._get_user_subsid('bob', '127S') return self.user_twview( 'bob', opts = self._cashaddr_opt(1), @@ -849,33 +849,39 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): expect = rf'[{b32a}]{{8}}' if self.proto.coin == 'BCH' else None) def bob_subwallet_txcreate(self): - sid1 = self._get_user_subsid('bob','29L') - sid2 = self._get_user_subsid('bob','127S') - outputs_cl = [sid1+':C:5,0.0159',sid2+':C:5'] - t = self.spawn('mmgen-txcreate',['-d',self.tmpdir,'-B','--bob'] + outputs_cl) + sid1 = self._get_user_subsid('bob', '29L') + sid2 = self._get_user_subsid('bob', '127S') + outputs_cl = [sid1+':C:5,0.0159', sid2+':C:5'] + t = self.spawn('mmgen-txcreate', ['-d', self.tmpdir, '-B', '--bob'] + outputs_cl) return self.txcreate_ui_common(t, menu = ['a'], - inputs = ('1,2','2,3')[self.proto.coin=='BCH'], + inputs = ('1,2', '2,3')[self.proto.coin=='BCH'], interactive_fee = '0.00001') def bob_subwallet_txsign(self): - fn = get_file_with_ext(self.tmpdir,'rawtx') - t = self.spawn('mmgen-txsign',['-d',self.tmpdir,'--bob','--subseeds=127',fn]) + fn = get_file_with_ext(self.tmpdir, 'rawtx') + t = self.spawn('mmgen-txsign', ['-d', self.tmpdir, '--bob', '--subseeds=127', fn]) t.view_tx('t') - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.do_comment(None) - t.expect('(Y/n): ','y') + t.expect('(Y/n): ', 'y') t.written_to_file('Signed transaction') return t def bob_subwallet_txdo(self): outputs_cl = [self._user_sid('bob')+':L:5'] - inputs = ('1,2','2,3')[self.proto.coin=='BCH'] - return self.user_txdo('bob',rtFee[5],outputs_cl,inputs,menu=['a'],extra_args=['--subseeds=127']) # sort: amt + inputs = ('1,2', '2,3')[self.proto.coin=='BCH'] + return self.user_txdo( + 'bob', + rtFee[5], + outputs_cl, + inputs, + menu = ['a'], + extra_args = ['--subseeds=127']) # sort: amt def bob_twview4(self): sid = self._user_sid('bob') - return self.user_twview('bob',chk=(sid+':L:5',rtBals[9]),sort='twmmid') + return self.user_twview('bob', chk=(sid+':L:5', rtBals[9]), sort='twmmid') def user_txhist(self, user, args, expect, opts=[], expect2=None): t = self.spawn('mmgen-tool', opts + [f'--{user}', 'txhist'] + args) @@ -896,32 +902,32 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_txhist2(self): return self.user_txhist('bob', opts = self._cashaddr_opt(0), - args = ['sort=blockheight','reverse=1','age_fmt=block'], + args = ['sort=blockheight', 'reverse=1', 'age_fmt=block'], expect = fr'\s1\).*:{self.dfl_mmtype}:1\s', expect2 = rf'[{b58a}]{{8}}' if self.proto.coin == 'BCH' else None) def bob_txhist3(self): return self.user_txhist('bob', - args = ['sort=blockheight','sinceblock=-7','age_fmt=block'], + args = ['sort=blockheight', 'sinceblock=-7', 'age_fmt=block'], expect = fr'Displaying transactions since block 399.*\s6\)\s+405\s.*\s{rtBals[9]}\s.*:L:5.*\s7\)' ) def bob_txhist4(self): return self.user_txhist('bob', - args = ['sort=blockheight','age_fmt=block','detail=1'], + args = ['sort=blockheight', 'age_fmt=block', 'detail=1'], expect = fr'Block:.*406.*Value:.*{rtBals[10]}' ) def bob_txhist5(self): return self.user_txhist('bob', - args = ['sort=blockheight','sinceblock=399','age_fmt=block','detail=1'], + args = ['sort=blockheight', 'sinceblock=399', 'age_fmt=block', 'detail=1'], expect = fr'Displaying transactions since block 399.*\s7\).*Block:.*406.*Value:.*{rtBals[10]}' ) def bob_txhist_interactive(self): - self.get_file_with_ext('out',delete_all=True) + self.get_file_with_ext('out', delete_all=True) t = self.spawn('mmgen-tool', - ['--bob',f'--outdir={self.tmpdir}','txhist','age_fmt=date_time','interactive=true'] ) + ['--bob', f'--outdir={self.tmpdir}', 'txhist', 'age_fmt=date_time', 'interactive=true']) if self.proto.coin == 'BCH': for expect, resp in ( (rf'[{b32a}]{{8}}', 'h'), @@ -929,30 +935,30 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ): t.expect(expect, regex=True) t.expect('draw:\b', resp, regex=True) - for resp in ('u','i','t','a','m','T','A','r','r','D','D','D','D','p','P','n','V'): - t.expect('draw:\b',resp,regex=True) + for resp in ('u', 'i', 't', 'a', 'm', 'T', 'A', 'r', 'r', 'D', 'D', 'D', 'D', 'p', 'P', 'n', 'V'): + t.expect('draw:\b', resp, regex=True) if t.pexpect_spawn: - t.expect(r'Block:.*394',regex=True) + t.expect(r'Block:.*394', regex=True) time.sleep(1) t.send('q') time.sleep(0.2) t.send('n') - t.expect('draw:\b','q',regex=True) + t.expect('draw:\b', 'q', regex=True) else: - txnum,idx = (8,1) if self.proto.coin == 'BCH' else (9,3) - t.expect(rf'\s{txnum}\).*Inputs:.*:L:{idx}.*Outputs \(3\):.*:C:2.*\s10\)','q',regex=True) + txnum, idx = (8, 1) if self.proto.coin == 'BCH' else (9, 3) + t.expect(rf'\s{txnum}\).*Inputs:.*:L:{idx}.*Outputs \(3\):.*:C:2.*\s10\)', 'q', regex=True) return t - def bob_getbalance(self,bals,confs=1): + def bob_getbalance(self, bals, confs=1): for i in range(len(bals['mmgen'])): assert Decimal(bals['mmgen'][i]) + Decimal(bals['nonmm'][i]) == Decimal(bals['total'][i]) sid = self._user_sid('bob') - t = self.spawn('mmgen-tool',['--bob','getbalance',f'minconf={confs}']) + t = self.spawn('mmgen-tool', ['--bob', 'getbalance', f'minconf={confs}']) t.expect('Wallet') - for k,lbl in ( - ('mmgen',f'{sid}:'), - ('nonmm','Non-MMGen:'), - ('total',f'TOTAL {self.proto.coin}') + for k, lbl in ( + ('mmgen', f'{sid}:'), + ('nonmm', 'Non-MMGen:'), + ('total', f'TOTAL {self.proto.coin}') ): ret = strip_ansi_escapes(t.expect_getend(lbl + ' ')) cmp_or_die( @@ -963,28 +969,28 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return t def bob_0conf0_getbalance(self): - return self.bob_getbalance(rtBals_gb['0conf0'],confs=0) + return self.bob_getbalance(rtBals_gb['0conf0'], confs=0) def bob_0conf1_getbalance(self): - return self.bob_getbalance(rtBals_gb['0conf1'],confs=1) + return self.bob_getbalance(rtBals_gb['0conf1'], confs=1) def bob_1conf1_getbalance(self): - return self.bob_getbalance(rtBals_gb['1conf1'],confs=1) + return self.bob_getbalance(rtBals_gb['1conf1'], confs=1) def bob_1conf2_getbalance(self): - return self.bob_getbalance(rtBals_gb['1conf2'],confs=2) + return self.bob_getbalance(rtBals_gb['1conf2'], confs=2) def bob_nochg_burn(self): return self.user_txdo('bob', fee = '0.00009713', outputs_cl = [self.burn_addr], - outputs_list = '1' ) + outputs_list = '1') def bob_alice_bal(self): - t = self.spawn('mmgen-regtest',['balances']) + t = self.spawn('mmgen-regtest', ['balances']) ret = t.expect_getend("Bob's balance:").strip() - cmp_or_die(rtBals[4],ret) + cmp_or_die(rtBals[4], ret) ret = t.expect_getend("Alice's balance:").strip() - cmp_or_die(rtBals[5],ret) - ret = t.expect_getend("Total balance:").strip() - cmp_or_die(rtBals[6],ret) + cmp_or_die(rtBals[5], ret) + ret = t.expect_getend('Total balance:').strip() + cmp_or_die(rtBals[6], ret) return t def user_txsend_status( @@ -1000,9 +1006,9 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ['-d', self.tmpdir, '--'+user, '--status'] + extra_args + [tx_file], exit_val = exit_val) if exp1: - t.expect(exp1,regex=True) + t.expect(exp1, regex=True) if exp2: - t.expect(exp2,regex=True) + t.expect(exp2, regex=True) if self.deterministic: imsg( 'DETERMINISTIC TESTING NOTE:\n ' @@ -1028,10 +1034,10 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): t = self.spawn( 'mmgen-txdo', - ['-d',self.tmpdir,'-B','--'+user] + ['-d', self.tmpdir, '-B', '--'+user] + (['--fee='+fee] if fee else []) + extra_args - + ([],[wf])[bool(wf)] + + ([], [wf])[bool(wf)] + outputs_cl, exit_val = exit_val) @@ -1041,7 +1047,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): menu = menu, inputs = outputs_list, file_desc = 'Signed transaction', - interactive_fee = (tx_fee,'')[bool(fee)], + interactive_fee = (tx_fee, '')[bool(fee)], add_comment = add_comment, return_early = return_early, view = 't', @@ -1052,7 +1058,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return t if not skip_passphrase: - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.written_to_file('Signed transaction') self._do_confirm_send(t) @@ -1063,45 +1069,45 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_split1(self): sid = self._user_sid('bob') - outputs_cl = [sid+':C:1,100', sid+':L:2,200',sid+':'+rtBobOp3] - return self.user_txdo('bob',rtFee[0],outputs_cl,'1',extra_args=['--locktime=500000001']) + outputs_cl = [sid+':C:1,100', sid+':L:2,200', sid+':'+rtBobOp3] + return self.user_txdo('bob', rtFee[0], outputs_cl, '1', extra_args=['--locktime=500000001']) - def get_addr_from_addrlist(self,user,sid,mmtype,idx,addr_range='1-5'): - id_str = { 'L':'', 'S':'-S', 'C':'-C', 'B':'-B' }[mmtype] + def get_addr_from_addrlist(self, user, sid, mmtype, idx, addr_range='1-5'): + id_str = {'L':'', 'S':'-S', 'C':'-C', 'B':'-B'}[mmtype] ext = '{}{}{}[{}]{x}.regtest.addrs'.format( - sid,self.altcoin_pfx,id_str,addr_range,x='-α' if cfg.debug_utf8 else '') - addrfile = get_file_with_ext(self._user_dir(user),ext,no_dot=True) + sid, self.altcoin_pfx, id_str, addr_range, x='-α' if cfg.debug_utf8 else '') + addrfile = get_file_with_ext(self._user_dir(user), ext, no_dot=True) silence() - addr = AddrList( cfg, self.proto, addrfile ).data[idx].addr + addr = AddrList(cfg, self.proto, addrfile).data[idx].addr end_silence() return addr - def _create_tx_outputs(self,user,data): + def _create_tx_outputs(self, user, data): sid = self._user_sid(user) - return [self.get_addr_from_addrlist(user,sid,mmtype,idx-1)+amt_str for mmtype,idx,amt_str in data] + return [self.get_addr_from_addrlist(user, sid, mmtype, idx-1)+amt_str for mmtype, idx, amt_str in data] def bob_rbf_1output_create(self): if not self.test_rbf: return 'skip' - out_addr = self._create_tx_outputs('alice',(('B',5,''),)) - t = self.spawn('mmgen-txcreate',['-d',self.tr.trash_dir,'-B','--bob'] + out_addr) - return self.txcreate_ui_common(t,menu=[],inputs='3',interactive_fee='3s') # out amt: 199.99999343 + out_addr = self._create_tx_outputs('alice', (('B', 5, ''),)) + t = self.spawn('mmgen-txcreate', ['-d', self.tr.trash_dir, '-B', '--bob'] + out_addr) + return self.txcreate_ui_common(t, menu=[], inputs='3', interactive_fee='3s') # out amt: 199.99999343 def bob_rbf_1output_bump(self): if not self.test_rbf: return 'skip' ext = '9343,3]{x}.regtest.rawtx'.format(x='-α' if cfg.debug_utf8 else '') - txfile = get_file_with_ext(self.tr.trash_dir,ext,delete=False,no_dot=True) + txfile = get_file_with_ext(self.tr.trash_dir, ext, delete=False, no_dot=True) return self.user_txbump('bob', self.tr.trash_dir, txfile, '8s', has_label = False, signed_tx = False, - one_output = True ) + one_output = True) def bob_send_maybe_rbf(self): - outputs_cl = self._create_tx_outputs('alice',(('L',1,',60'),('C',1,',40'))) + outputs_cl = self._create_tx_outputs('alice', (('L', 1, ', 60'), ('C', 1, ', 40'))) outputs_cl += [self._user_sid('bob')+':'+rtBobOp3] return self.user_txdo( user = 'bob', @@ -1112,9 +1118,9 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): used_chg_addr_resp = 'y') def bob_send_non_mmgen(self): - keyfile = joinpath(self.tmpdir,'non-mmgen.keys') + keyfile = joinpath(self.tmpdir, 'non-mmgen.keys') atype = 'S' if self.proto.cap('segwit') else 'L' - outputs_cl = self._create_tx_outputs('alice',((atype, 2, ', 10'), (atype, 3, ''))) + outputs_cl = self._create_tx_outputs('alice', ((atype, 2, ', 10'), (atype, 3, ''))) return self.user_txdo( user = 'bob', fee = rtFee[3], @@ -1123,7 +1129,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): extra_args = [f'--keys-from-file={keyfile}', '--vsize-adj=1.02']) def alice_send_estimatefee(self): - outputs_cl = self._create_tx_outputs('bob',(('L',1,''),)) # bob_sid:L:1 + outputs_cl = self._create_tx_outputs('bob', (('L', 1, ''),)) # bob_sid:L:1 return self.user_txdo('alice', None, outputs_cl, '1', extra_args=['--verbose']) # fee=None def user_txbump( @@ -1139,28 +1145,28 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): if not self.proto.cap('rbf'): return 'skip' t = self.spawn('mmgen-txbump', - ['-d',outdir,'--'+user,'--fee='+fee,'--output-to-reduce=c'] + add_args + [txfile]) + ['-d', outdir, '--'+user, '--fee='+fee, '--output-to-reduce=c'] + add_args + [txfile]) if not one_output: - t.expect('OK? (Y/n): ','y') # output OK? - t.expect('OK? (Y/n): ','y') # fee OK? - t.do_comment(False,has_label=has_label) + t.expect('OK? (Y/n): ', 'y') # output OK? + t.expect('OK? (Y/n): ', 'y') # fee OK? + t.do_comment(False, has_label=has_label) if signed_tx: - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.written_to_file('Signed transaction') - self.txsend_ui_common(t,caller='txdo',bogus_send=False,file_desc='Signed transaction') + self.txsend_ui_common(t, caller='txdo', bogus_send=False, file_desc='Signed transaction') else: - t.expect('Save fee-bumped transaction? (y/N): ','y') + t.expect('Save fee-bumped transaction? (y/N): ', 'y') t.written_to_file('Fee-bumped transaction') return t def bob_rbf_bump(self): - ext = ',{}]{x}.regtest.sigtx'.format(rtFee[1][:-1],x='-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,delete=False,no_dot=True) - return self.user_txbump('bob',self.tmpdir,txfile,rtFee[2],add_args=['--send']) + ext = ',{}]{x}.regtest.sigtx'.format(rtFee[1][:-1], x='-α' if cfg.debug_utf8 else '') + txfile = self.get_file_with_ext(ext, delete=False, no_dot=True) + return self.user_txbump('bob', self.tmpdir, txfile, rtFee[2], add_args=['--send']) - def generate(self,num_blocks=1): + def generate(self, num_blocks=1): int(num_blocks) - t = self.spawn('mmgen-regtest',['generate',str(num_blocks)]) + t = self.spawn('mmgen-regtest', ['generate', str(num_blocks)]) t.expect(f'Mined {num_blocks} block') return t @@ -1170,38 +1176,38 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ['mempool'], env = os.environ if cfg.debug_utf8 else get_env_without_debug_vars(), ).read() - m = re.search(r'(\[\s*"[a-f0-9]{64}"\s*])',ret) # allow for extra output by handler at end + m = re.search(r'(\[\s*"[a-f0-9]{64}"\s*])', ret) # allow for extra output by handler at end return json.loads(m.group(1)) def get_mempool1(self): mp = self._get_mempool() if len(mp) != 1: - die(4,'Mempool has more or less than one TX!') - self.write_to_tmpfile('rbf_txid',mp[0]+'\n') + die(4, 'Mempool has more or less than one TX!') + self.write_to_tmpfile('rbf_txid', mp[0]+'\n') return 'ok' def bob_rbf_status(self, fee, exp1, exp2='', exit_val=None): if not self.proto.cap('rbf'): return 'skip' - ext = ',{}]{x}.regtest.sigtx'.format(fee[:-1],x='-α' if cfg.debug_utf8 else '') - txfile = self.get_file_with_ext(ext,delete=False,no_dot=True) + ext = ',{}]{x}.regtest.sigtx'.format(fee[:-1], x='-α' if cfg.debug_utf8 else '') + txfile = self.get_file_with_ext(ext, delete=False, no_dot=True) return self.user_txsend_status('bob', txfile, exp1, exp2, exit_val=exit_val) def bob_rbf_status1(self): if not self.proto.cap('rbf'): return 'skip' - return self.bob_rbf_status(rtFee[1],'in mempool, replaceable') + return self.bob_rbf_status(rtFee[1], 'in mempool, replaceable') def get_mempool2(self): if not self.proto.cap('rbf'): return 'skip' mp = self._get_mempool() if len(mp) != 1: - die(4,'Mempool has more or less than one TX!') + die(4, 'Mempool has more or less than one TX!') chk = self.read_from_tmpfile('rbf_txid') if chk.strip() == mp[0]: - die(4,'TX in mempool has not changed! RBF bump failed') - self.write_to_tmpfile('rbf_txid2',mp[0]+'\n') + die(4, 'TX in mempool has not changed! RBF bump failed') + self.write_to_tmpfile('rbf_txid2', mp[0]+'\n') return 'ok' def bob_rbf_status2(self): @@ -1217,7 +1223,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_rbf_status3(self): if not self.proto.cap('rbf'): return 'skip' - return self.bob_rbf_status(rtFee[2],'status: in mempool, replaceable') + return self.bob_rbf_status(rtFee[2], 'status: in mempool, replaceable') def bob_rbf_status4(self): if not self.proto.cap('rbf'): @@ -1225,12 +1231,12 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): new_txid = self.read_from_tmpfile('rbf_txid2').strip() return self.bob_rbf_status(rtFee[1], 'Replacement transaction has 1 confirmation', - rf'Replacing transactions:\s+{new_txid}' ) + rf'Replacing transactions:\s+{new_txid}') def bob_rbf_status5(self): if not self.proto.cap('rbf'): return 'skip' - return self.bob_rbf_status(rtFee[2],'Transaction has 1 confirmation') + return self.bob_rbf_status(rtFee[2], 'Transaction has 1 confirmation') def bob_rbf_status6(self): if not self.proto.cap('rbf'): @@ -1238,90 +1244,90 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): new_txid = self.read_from_tmpfile('rbf_txid2').strip() return self.bob_rbf_status(rtFee[1], 'Replacement transaction has 2 confirmations', - rf'Replacing transactions:\s+{new_txid}' ) + rf'Replacing transactions:\s+{new_txid}') - def _gen_pairs(self,n): + def _gen_pairs(self, n): from mmgen.tool.api import tool_api t = tool_api(cfg) - t.init_coin(self.proto.coin,self.proto.network) + t.init_coin(self.proto.coin, self.proto.network) def gen_addr(Type): t.addrtype = Type wif = t.hex2wif(getrandhex(32)) - return ( wif, t.wif2addr(wif) ) + return (wif, t.wif2addr(wif)) return [gen_addr('legacy')] + [gen_addr('compressed') for i in range(n-1)] def bob_pre_import(self): pairs = self._gen_pairs(5) - self.write_to_tmpfile('non-mmgen.keys','\n'.join([a[0] for a in pairs])+'\n') - self.write_to_tmpfile('non-mmgen.addrs','\n'.join([a[1] for a in pairs])+'\n') - return self.user_txdo('bob',rtFee[4],[pairs[0][1]],'3') + self.write_to_tmpfile('non-mmgen.keys', '\n'.join([a[0] for a in pairs])+'\n') + self.write_to_tmpfile('non-mmgen.addrs', '\n'.join([a[1] for a in pairs])+'\n') + return self.user_txdo('bob', rtFee[4], [pairs[0][1]], '3') - def user_import(self,user,args,nAddr): - t = self.spawn('mmgen-addrimport',['--'+user]+args) + def user_import(self, user, args, nAddr): + t = self.spawn('mmgen-addrimport', ['--'+user] + args) if cfg.debug: - t.expect("Type uppercase 'YES' to confirm: ",'YES\n') + t.expect("Type uppercase 'YES' to confirm: ", 'YES\n') t.expect(f'Importing {nAddr} address') if '--rescan' in args: if not '--quiet' in args: - t.expect('Continue? (Y/n): ','y') + t.expect('Continue? (Y/n): ', 'y') t.expect('Rescanning block') return t def bob_import_addr(self): addr = self.read_from_tmpfile('non-mmgen.addrs').split()[0] - return self.user_import('bob',['--quiet','--address='+addr],nAddr=1) + return self.user_import('bob', ['--quiet', '--address='+addr], nAddr=1) def bob_import_list_rescan_aio(self): - addrfile = joinpath(self.tmpdir,'non-mmgen.addrs') - return self.user_import('bob',['--rescan','--rpc-backend=aio','--addrlist',addrfile],nAddr=5) + addrfile = joinpath(self.tmpdir, 'non-mmgen.addrs') + return self.user_import('bob', ['--rescan', '--rpc-backend=aio', '--addrlist', addrfile], nAddr=5) def bob_resolve_addr(self): mmaddr = '{}:C:1'.format(self._user_sid('bob')) - t = self.spawn('mmgen-tool',['--bob','resolve_address',mmaddr]) + t = self.spawn('mmgen-tool', ['--bob', 'resolve_address', mmaddr]) coinaddr = re.search(r'[0-9A-Za-z]{30,}', t.read())[0] - t = self.spawn('mmgen-tool',['--bob','resolve_address',coinaddr],no_msg=True) + t = self.spawn('mmgen-tool', ['--bob', 'resolve_address', coinaddr], no_msg=True) mmaddr_res = re.search(r'[0-9A-F]{8}:C:1', t.read())[0] assert mmaddr == mmaddr_res, f'{mmaddr} != {mmaddr_res}' return t def bob_import_list(self): - addrfile = joinpath(self.tmpdir,'non-mmgen.addrs') - return self.user_import('bob',['--quiet','--addrlist',addrfile],nAddr=5) + addrfile = joinpath(self.tmpdir, 'non-mmgen.addrs') + return self.user_import('bob', ['--quiet', '--addrlist', addrfile], nAddr=5) def bob_import_list_rescan(self): - addrfile = joinpath(self.tmpdir,'non-mmgen.addrs') - return self.user_import('bob',['--quiet','--rescan','--addrlist',addrfile],nAddr=5) + addrfile = joinpath(self.tmpdir, 'non-mmgen.addrs') + return self.user_import('bob', ['--quiet', '--rescan', '--addrlist', addrfile], nAddr=5) def bob_rescan_addr(self): sid = self._user_sid('bob') - t = self.spawn('mmgen-tool',['--bob','rescan_address',f'{sid}:C:1']) + t = self.spawn('mmgen-tool', ['--bob', 'rescan_address', f'{sid}:C:1']) t.expect('Found 1 unspent output') t.expect('updated successfully') return t - def _usr_rescan_blockchain(self,user,add_args,expect=None): - t = self.spawn('mmgen-tool',[f'--{user}','rescan_blockchain'] + add_args) + def _usr_rescan_blockchain(self, user, add_args, expect=None): + t = self.spawn('mmgen-tool', [f'--{user}', 'rescan_blockchain'] + add_args) if expect: t.expect(f'Scanning blocks {expect}') t.expect('Done') return t def bob_rescan_blockchain_all(self): - return self._usr_rescan_blockchain('bob',[],'300-396') + return self._usr_rescan_blockchain('bob', [], '300-396') def bob_rescan_blockchain_gb(self): - return self._usr_rescan_blockchain('bob',['start_block=0','stop_block=0'],'0-0') + return self._usr_rescan_blockchain('bob', ['start_block=0', 'stop_block=0'], '0-0') def bob_rescan_blockchain_one(self): - return self._usr_rescan_blockchain('bob',['start_block=300','stop_block=300'],'300-300') + return self._usr_rescan_blockchain('bob', ['start_block=300', 'stop_block=300'], '300-300') def bob_rescan_blockchain_ss(self): - return self._usr_rescan_blockchain('bob',['start_block=300','stop_block=302'],'300-302') + return self._usr_rescan_blockchain('bob', ['start_block=300', 'stop_block=302'], '300-302') - def bob_twexport(self,add_args=[]): - t = self.spawn('mmgen-tool',['--bob',f'--outdir={self.tmpdir}','twexport'] + add_args) + def bob_twexport(self, add_args=[]): + t = self.spawn('mmgen-tool', ['--bob', f'--outdir={self.tmpdir}', 'twexport'] + add_args) t.written_to_file('JSON data') return t @@ -1346,22 +1352,22 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): t = self.spawn( 'mmgen-tool', - ['--bob',f'--outdir={self.tr.trash_dir}','twexport','prune=1'] - + (['warn_used=1'] if warn_used else []) ) + ['--bob', f'--outdir={self.tr.trash_dir}', 'twexport', 'prune=1'] + + (['warn_used=1'] if warn_used else [])) for s in expect_menu: - t.expect('prune list:\b',s) + t.expect('prune list:\b', s) - t.expect('prune list:\b','p') - t.expect('addresses to prune: ',f'{prune_spec}\n') + t.expect('prune list:\b', 'p') + t.expect('addresses to prune: ', f'{prune_spec}\n') - for p,s in expect: - t.expect(p,s,regex=True) + for p, s in expect: + t.expect(p, s, regex=True) - t.expect('prune list:\b','q') + t.expect('prune list:\b', 'q') - for p,s in expect2: - t.expect(p,s,regex=True) + for p, s in expect2: + t.expect(p, s, regex=True) if npruned: t.expect(f'Pruned {npruned} addresses') @@ -1375,49 +1381,49 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return self._bob_twprune( expect_menu = 'a', # sort by amt to make address order deterministic prune_spec = '35,12,18,3-5', - npruned = 6 ) + npruned = 6) def bob_twprune_all(self): taddr = 35 if self.proto.cap('segwit') else 25 return self._bob_twprune( prune_spec = f'1-{taddr}', npruned = taddr, - expect = [('all with balance: ','P')], - non_segwit_ok = True ) + expect = [('all with balance: ', 'P')], + non_segwit_ok = True) def bob_twprune_skip(self): return self._bob_twprune( prune_spec = '', npruned = 0, - non_segwit_ok = True ) + non_segwit_ok = True) def bob_twprune_skipamt(self): return self._bob_twprune( prune_spec = '1-35', npruned = 32, - expect = [('all with balance: ','S')] ) + expect = [('all with balance: ', 'S')]) def bob_twprune_skipused(self): return self._bob_twprune( prune_spec = '1-35', npruned = 18, - expect = [('all used: ','S')], - warn_used = True ) + expect = [('all used: ', 'S')], + warn_used = True) def bob_twprune_allamt(self): return self._bob_twprune( prune_spec = '1-35', npruned = 35, - expect = [('all with balance: ','P')], - expect2 = [('Warning: pruned address .* has a balance',None)] ) + expect = [('all with balance: ', 'P')], + expect2 = [('Warning: pruned address .* has a balance', None)]) def bob_twprune_allused(self): return self._bob_twprune( prune_spec = '1-35', npruned = 32, - expect = [('all used: ','P'),('all with balance: ','S')], - expect2 = [('Warning: pruned address .* used',None)], - warn_used = True ) + expect = [('all used: ', 'P'), ('all with balance: ', 'S')], + expect2 = [('Warning: pruned address .* used', None)], + warn_used = True) @property def _b_start(self): @@ -1425,17 +1431,17 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): SIDs sort non-deterministically, so we must search for start of main (not subseeds) group, i.e. ':B:1' """ assert self.proto.cap('segwit') - if not hasattr(self,'_b_start_'): - t = self.spawn( 'mmgen-tool', ['--color=0','--bob','listaddresses'], no_msg=True ) + if not hasattr(self, '_b_start_'): + t = self.spawn('mmgen-tool', ['--color=0', '--bob', 'listaddresses'], no_msg=True) self._b_start_ = int([e for e in t.read().split('\n') if ':B:1' in e][0].split()[0].rstrip(')')) t.close() return self._b_start_ - def _bob_twprune_selected(self,resp,npruned): + def _bob_twprune_selected(self, resp, npruned): if not self.proto.cap('segwit'): return 'skip' B = self._b_start - a,b,c,d,e,f = resp + a, b, c, d, e, f = resp return self._bob_twprune( expect_menu = 'a', # sort by amt to make address order deterministic prune_spec = f'31-32,{B+14},{B+9},{B}-{B+4}', @@ -1448,33 +1454,33 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ('all used: ', e), ('all used: ', f), ], - warn_used = True ) + warn_used = True) def bob_twprune1(self): - return self._bob_twprune_selected(resp='sssssS',npruned=3) + return self._bob_twprune_selected(resp='sssssS', npruned=3) def bob_twprune2(self): - return self._bob_twprune_selected(resp='sppPsS',npruned=3) + return self._bob_twprune_selected(resp='sppPsS', npruned=3) def bob_twprune3(self): - return self._bob_twprune_selected(resp='sssPpS',npruned=3) + return self._bob_twprune_selected(resp='sssPpS', npruned=3) def bob_twprune4(self): - return self._bob_twprune_selected(resp='sssPpP',npruned=9) + return self._bob_twprune_selected(resp='sssPpP', npruned=9) def bob_twprune5(self): - return self._bob_twprune_selected(resp='pppPpP',npruned=9) + return self._bob_twprune_selected(resp='pppPpP', npruned=9) def bob_twprune6(self): - return self._bob_twprune_selected(resp='sssSpP',npruned=7) + return self._bob_twprune_selected(resp='sssSpP', npruned=7) def bob_edit_json_twdump(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) from mmgen.tw.json import TwJSON - fn = TwJSON.Base(cfg,self.proto).dump_fn + fn = TwJSON.Base(cfg, self.proto).dump_fn text = json.loads(self.read_from_tmpfile(fn)) text['data']['entries'][3][3] = f'edited comment [фубар] [{gr_uc}]' - self.write_to_tmpfile( fn, json.dumps(text,indent=4) ) + self.write_to_tmpfile(fn, json.dumps(text, indent=4)) return 'ok' def carol_twimport( @@ -1484,13 +1490,13 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): expect_str = None, expect_str2 = 'Found 1 unspent output'): from mmgen.tw.json import TwJSON - fn = joinpath( self.tmpdir, TwJSON.Base(cfg,self.proto).dump_fn ) + fn = joinpath(self.tmpdir, TwJSON.Base(cfg, self.proto).dump_fn) t = self.spawn( 'mmgen-tool', ([f'--rpc-backend={rpc_backend}'] if rpc_backend else []) - + ['--carol','twimport',fn] - + add_parms ) - t.expect('(y/N): ','y') + + ['--carol', 'twimport', fn] + + add_parms) + t.expect('(y/N): ', 'y') if expect_str: t.expect(expect_str) elif 'batch=true' in add_parms: @@ -1501,22 +1507,22 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return t def carol_twimport_nochksum(self): - return self.carol_twimport(rpc_backend=None,add_parms=['ignore_checksum=true']) + return self.carol_twimport(rpc_backend=None, add_parms=['ignore_checksum=true']) def carol_twimport_batch(self): return self.carol_twimport(add_parms=['batch=true']) def carol_twimport_pretty(self): - return self.carol_twimport(add_parms=['ignore_checksum=true'],expect_str='ignoring incorrect checksum') + return self.carol_twimport(add_parms=['ignore_checksum=true'], expect_str='ignoring incorrect checksum') def carol_listaddresses(self): - return self.spawn('mmgen-tool',['--carol','listaddresses','showempty=1']) + return self.spawn('mmgen-tool', ['--carol', 'listaddresses', 'showempty=1']) async def carol_delete_wallet(self): imsg('Unloading Carol’s tracking wallet') if self.proto.coin == 'BCH': time.sleep(0.2) - t = self.spawn('mmgen-regtest',['cli','unloadwallet','carol']) + t = self.spawn('mmgen-regtest', ['cli', 'unloadwallet', 'carol']) t.ok() wdir = joinpath((await self.rt.rpc).daemon.network_datadir, 'wallets', 'carol') from shutil import rmtree @@ -1526,24 +1532,24 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_split2(self): addrs = self.read_from_tmpfile('non-mmgen.addrs').split() - amts = (1.12345678,2.87654321,3.33443344,4.00990099,5.43214321) - outputs1 = list(map('{},{}'.format,addrs,amts)) + amts = (1.12345678, 2.87654321, 3.33443344, 4.00990099, 5.43214321) + outputs1 = list(map('{},{}'.format, addrs, amts)) sid = self._user_sid('bob') - l1,l2 = ( - (':S',':B') if 'B' in self.proto.mmtypes else - (':S',':S') if self.proto.cap('segwit') else - (':L',':L') ) - outputs2 = [sid+':C:2,6.333', sid+':L:3,6.667',sid+l1+':4,0.123',sid+l2+':5'] - return self.user_txdo('bob',rtFee[5],outputs1+outputs2,'1-2') + l1, l2 = ( + (':S', ':B') if 'B' in self.proto.mmtypes else + (':S', ':S') if self.proto.cap('segwit') else + (':L', ':L')) + outputs2 = [sid+':C:2,6.333', sid+':L:3,6.667', sid+l1+':4,0.123', sid+l2+':5'] + return self.user_txdo('bob', rtFee[5], outputs1+outputs2, '1-2') - def user_add_comment(self,user,addr,comment): - t = self.spawn('mmgen-tool',['--'+user,'add_label',addr,comment]) - t.expect('Added label.*in tracking wallet',regex=True) + def user_add_comment(self, user, addr, comment): + t = self.spawn('mmgen-tool', ['--'+user, 'add_label', addr, comment]) + t.expect('Added label.*in tracking wallet', regex=True) return t - def user_remove_comment(self,user,addr): - t = self.spawn('mmgen-tool',['--'+user,'remove_label',addr]) - t.expect('Removed label.*in tracking wallet',regex=True) + def user_remove_comment(self, user, addr): + t = self.spawn('mmgen-tool', ['--'+user, 'remove_label', addr]) + t.expect('Removed label.*in tracking wallet', regex=True) return t def bob_bad_locktime1(self): @@ -1555,12 +1561,12 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_bad_locktime3(self): return self._bob_bad_locktime(0xffffffff, 'non-final', 2, return_early=False) # > cur time - def _bob_bad_locktime(self,locktime,expect,exit_val,return_early=False): + def _bob_bad_locktime(self, locktime, expect, exit_val, return_early=False): sid = self._user_sid('bob') t = self.user_txdo( user = 'bob', fee = '20s', - outputs_cl = [self.burn_addr+',0.1', sid+':C:5'], + outputs_cl = [self.burn_addr+', 0.1', sid+':C:5'], outputs_list = '1', extra_args = [f'--locktime={locktime}'], return_early = return_early, @@ -1573,96 +1579,96 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_add_comment1(self): sid = self._user_sid('bob') - return self.user_add_comment('bob',sid+':C:1',tw_comment_lat_cyr_gr) + return self.user_add_comment('bob', sid+':C:1', tw_comment_lat_cyr_gr) def alice_add_comment1(self): sid = self._user_sid('alice') - return self.user_add_comment('alice',sid+':C:1','Original Label - 月へ') + return self.user_add_comment('alice', sid+':C:1', 'Original Label - 月へ') def alice_add_comment2(self): sid = self._user_sid('alice') - return self.user_add_comment('alice',sid+':C:1','Replacement Label') + return self.user_add_comment('alice', sid+':C:1', 'Replacement Label') - def _user_chk_comment(self,user,addr,comment,extra_args=[]): - t = self.spawn('mmgen-tool',['--'+user,'listaddresses','all_labels=1']+extra_args) - ret = strip_ansi_escapes(t.expect_getend(addr)).strip().split(None,2)[2] + def _user_chk_comment(self, user, addr, comment, extra_args=[]): + t = self.spawn('mmgen-tool', ['--'+user, 'listaddresses', 'all_labels=1']+extra_args) + ret = strip_ansi_escapes(t.expect_getend(addr)).strip().split(None, 2)[2] cmp_or_die( # squeezed display, double-width chars, so truncate to min field width ret[:3].strip(), comment[:3].strip()) return t def alice_add_comment_coinaddr(self): - mmid = self._user_sid('alice') + (':S:1',':L:1')[self.proto.coin=='BCH'] - t = self.spawn('mmgen-tool',['--alice','listaddress',mmid,'wide=true'],no_msg=True) - addr = [i for i in strip_ansi_escapes(t.read()).splitlines() if re.search(rf'\b{mmid}\b',i)][0].split()[3] - return self.user_add_comment('alice',addr,'Label added using coin address of MMGen address') + mmid = self._user_sid('alice') + (':S:1', ':L:1')[self.proto.coin=='BCH'] + t = self.spawn('mmgen-tool', ['--alice', 'listaddress', mmid, 'wide=true'], no_msg=True) + addr = [i for i in strip_ansi_escapes(t.read()).splitlines() if re.search(rf'\b{mmid}\b', i)][0].split()[3] + return self.user_add_comment('alice', addr, 'Label added using coin address of MMGen address') def alice_chk_comment_coinaddr(self): - mmid = self._user_sid('alice') + (':S:1',':L:1')[self.proto.coin=='BCH'] - return self._user_chk_comment('alice',mmid,'Label added using coin address of MMGen address') + mmid = self._user_sid('alice') + (':S:1', ':L:1')[self.proto.coin=='BCH'] + return self._user_chk_comment('alice', mmid, 'Label added using coin address of MMGen address') - def alice_add_comment_badaddr(self,addr,reply,exit_val): + def alice_add_comment_badaddr(self, addr, reply, exit_val): if os.getenv('PYTHONOPTIMIZE'): omsg(yellow(f'PYTHONOPTIMIZE set, skipping test {self.test_name!r}')) return 'skip' t = self.spawn( 'mmgen-tool', - ['--alice','add_label',addr,'(none)'], + ['--alice', 'add_label', addr, '(none)'], exit_val = exit_val) - t.expect(reply,regex=True) + t.expect(reply, regex=True) return t def alice_add_comment_badaddr1(self): - return self.alice_add_comment_badaddr( rt_pw, 'invalid address', 2 ) + return self.alice_add_comment_badaddr(rt_pw, 'invalid address', 2) def alice_add_comment_badaddr2(self): # mainnet zero address: addr = init_proto(cfg, self.proto.coin, network='mainnet').pubhash2addr(bytes(20), 'p2pkh') - return self.alice_add_comment_badaddr( addr, 'invalid address', 2 ) + return self.alice_add_comment_badaddr(addr, 'invalid address', 2) def alice_add_comment_badaddr3(self): addr = self._user_sid('alice') + ':C:123' - return self.alice_add_comment_badaddr( addr, f'MMGen address {addr!r} not found in tracking wallet', 2 ) + return self.alice_add_comment_badaddr(addr, f'MMGen address {addr!r} not found in tracking wallet', 2) def alice_add_comment_badaddr4(self): addr = self.proto.pubhash2addr(bytes(20), 'p2pkh') # regtest (testnet) zero address - return self.alice_add_comment_badaddr( addr, f'Coin address {addr!r} not found in tracking wallet', 2 ) + return self.alice_add_comment_badaddr(addr, f'Coin address {addr!r} not found in tracking wallet', 2) def alice_remove_comment1(self): sid = self._user_sid('alice') - mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH'] - return self.user_remove_comment('alice',mmid) + mmid = sid + (':S:3', ':L:3')[self.proto.coin=='BCH'] + return self.user_remove_comment('alice', mmid) def alice_chk_comment1(self): sid = self._user_sid('alice') - return self._user_chk_comment('alice',sid+':C:1','Original Label - 月へ') + return self._user_chk_comment('alice', sid+':C:1', 'Original Label - 月へ') def alice_chk_comment2(self): sid = self._user_sid('alice') - return self._user_chk_comment('alice',sid+':C:1','Replacement Label',extra_args=['age_fmt=block']) + return self._user_chk_comment('alice', sid+':C:1', 'Replacement Label', extra_args=['age_fmt=block']) def alice_edit_comment1(self): - return self.user_edit_comment('alice','4',tw_comment_lat_cyr_gr) + return self.user_edit_comment('alice', '4', tw_comment_lat_cyr_gr) def alice_edit_comment2(self): - return self.user_edit_comment('alice','3',tw_comment_zh) + return self.user_edit_comment('alice', '3', tw_comment_zh) def alice_chk_comment3(self): sid = self._user_sid('alice') - mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH'] - return self._user_chk_comment('alice',mmid,tw_comment_lat_cyr_gr,extra_args=['age_fmt=date']) + mmid = sid + (':S:3', ':L:3')[self.proto.coin=='BCH'] + return self._user_chk_comment('alice', mmid, tw_comment_lat_cyr_gr, extra_args=['age_fmt=date']) def alice_chk_comment4(self): sid = self._user_sid('alice') - mmid = sid + (':S:3',':L:3')[self.proto.coin=='BCH'] - return self._user_chk_comment('alice',mmid,'-',extra_args=['age_fmt=date_time']) + mmid = sid + (':S:3', ':L:3')[self.proto.coin=='BCH'] + return self._user_chk_comment('alice', mmid, '-', extra_args=['age_fmt=date_time']) - def user_edit_comment(self,user,output,comment): - t = self.spawn('mmgen-txcreate',['-B','--'+user,'-i']) - t.expect(r'add \[l\]abel:.','M',regex=True) - t.expect(r'add \[l\]abel:.','l',regex=True) - t.expect(r"Enter unspent.*return to main menu\):.",output+'\n',regex=True) - t.expect(r"Enter label text.*:.",comment+'\n',regex=True) - t.expect(r'\[q\]uit menu, .*?:.','q',regex=True) + def user_edit_comment(self, user, output, comment): + t = self.spawn('mmgen-txcreate', ['-B', '--'+user, '-i']) + t.expect(r'add \[l\]abel:.', 'M', regex=True) + t.expect(r'add \[l\]abel:.', 'l', regex=True) + t.expect(r'Enter unspent.*return to main menu\):.', output+'\n', regex=True) + t.expect(r'Enter label text.*:.', comment+'\n', regex=True) + t.expect(r'\[q\]uit menu, .*?:.', 'q', regex=True) return t def alice_listaddresses_scroll(self): @@ -1684,14 +1690,14 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): t.send('l') t.expect( 'main menu): ', - '{}\n'.format(2 if self.proto.coin == 'BCH' else 1) ) - t.expect('for address.*: ','\n',regex=True) + '{}\n'.format(2 if self.proto.coin == 'BCH' else 1)) + t.expect('for address.*: ', '\n', regex=True) t.expect('unchanged') t.expect(prompt, 'q') return t - def _alice_listaddresses_interactive(self,expect=(),expect_menu=()): - t = self.spawn('mmgen-tool',['--alice','listaddresses','interactive=1']) + def _alice_listaddresses_interactive(self, expect=(), expect_menu=()): + t = self.spawn('mmgen-tool', ['--alice', 'listaddresses', 'interactive=1']) prompt = 'abel:\b' for e in expect: t.expect(*e, regex=True) @@ -1717,57 +1723,57 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def alice_listaddresses_menu(self): return self._alice_listaddresses_interactive(expect_menu='aAMrDDDDLeq') - def alice_listaddresses(self,args,expect): - t = self.spawn('mmgen-tool',['--alice','listaddresses','showempty=1'] + args) + def alice_listaddresses(self, args, expect): + t = self.spawn('mmgen-tool', ['--alice', 'listaddresses', 'showempty=1'] + args) expect_str = r'\D{}\D.*\b{}'.format(*expect) - t.expect(expect_str,regex=True) + t.expect(expect_str, regex=True) return t def alice_listaddresses1(self): return self.alice_listaddresses( args = [], - expect = (rtAmts[1],r'\d+') ) + expect = (rtAmts[1], r'\d+')) def alice_listaddresses_days(self): return self.alice_listaddresses( args = ['age_fmt=days'], - expect = (rtAmts[1],r'\d+') ) + expect = (rtAmts[1], r'\d+')) def alice_listaddresses_date(self): return self.alice_listaddresses( args = ['age_fmt=date'], - expect = (rtAmts[1],pat_date) ) + expect = (rtAmts[1], pat_date)) def alice_listaddresses_date_time(self): return self.alice_listaddresses( args = ['age_fmt=date_time'], - expect = (rtAmts[1],pat_date_time) ) + expect = (rtAmts[1], pat_date_time)) - def alice_twview(self,args,expect): - t = self.spawn('mmgen-tool',['--alice','twview'] + args) + def alice_twview(self, args, expect): + t = self.spawn('mmgen-tool', ['--alice', 'twview'] + args) expect_str = r'\D{}\D.*\b{}'.format(*expect) - t.expect(expect_str,regex=True) + t.expect(expect_str, regex=True) return t def alice_twview1(self): return self.alice_twview( args = [], - expect = (rtAmts[0],r'\d+') ) + expect = (rtAmts[0], r'\d+')) def alice_twview_days(self): return self.alice_twview( args = ['age_fmt=days'], - expect = (rtAmts[0],r'\d+') ) + expect = (rtAmts[0], r'\d+')) def alice_twview_date(self): return self.alice_twview( args = ['age_fmt=date'], - expect = (rtAmts[0],pat_date) ) + expect = (rtAmts[0], pat_date)) def alice_twview_date_time(self): return self.alice_twview( args = ['age_fmt=date_time'], - expect = (rtAmts[0],pat_date_time) ) + expect = (rtAmts[0], pat_date_time)) def alice_twview_interactive_cashaddr(self): if self.proto.coin != 'BCH': @@ -1780,22 +1786,21 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): t.expect(prompt, 'q') return t - def alice_txcreate_info(self,pexpect_spawn=False): - t = self.spawn('mmgen-txcreate',['--alice','-Bi'],pexpect_spawn=pexpect_spawn) + def alice_txcreate_info(self, pexpect_spawn=False): + t = self.spawn('mmgen-txcreate', ['--alice', '-Bi'], pexpect_spawn=pexpect_spawn) pats = ( - ( r'\d+', 'w'), - ( r'\d+', 'D'), - ( r'\d+', 'D'), - ( r'\d+', 'D'), - ( pat_date, 'q'), - ) - for d,s in pats: + (r'\d+', 'w'), + (r'\d+', 'D'), + (r'\d+', 'D'), + (r'\d+', 'D'), + (pat_date, 'q')) + for d, s in pats: t.expect( - r'\D{}\D.*\b{}\b'.format( rtAmts[0], d ), + r'\D{}\D.*\b{}\b'.format(rtAmts[0], d), s, - regex=True ) + regex=True) if t.pexpect_spawn and s == 'w': - t.expect(r'Total.*','q',regex=True,delay=1 if cfg.exact_output else t.send_delay) + t.expect(r'Total.*', 'q', regex=True, delay=1 if cfg.exact_output else t.send_delay) time.sleep(t.send_delay) t.send('e') return t @@ -1807,25 +1812,24 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): # send one TX to 2 addrs in Alice’s wallet - required for alice_twview_grouped() (group by TxID) def bob_send_to_alice_2addr(self): - outputs_cl = self._create_tx_outputs('alice',[('C',1,',0.02'),('C',2,',0.2')]) + outputs_cl = self._create_tx_outputs('alice', [('C', 1, ',0.02'), ('C', 2, ',0.2')]) outputs_cl += [self._user_sid('bob')+':C:5'] - return self.user_txdo('bob','25s',outputs_cl,'1') + return self.user_txdo('bob', '25s', outputs_cl, '1') # send to a used addr in Alice’s wallet - required for alice_twview_grouped() (group by address) def bob_send_to_alice_reuse(self): - outputs_cl = self._create_tx_outputs('alice',[('C',1,',0.0111')]) + outputs_cl = self._create_tx_outputs('alice', [('C', 1, ',0.0111')]) outputs_cl += [self._user_sid('bob')+':C:5'] - return self.user_txdo('bob','25s',outputs_cl,'1') + return self.user_txdo('bob', '25s', outputs_cl, '1') def alice_twview_grouped(self): - t = self.spawn('mmgen-tool',['--alice','twview','interactive=1']) + t = self.spawn('mmgen-tool', ['--alice', 'twview', 'interactive=1']) prompt = 'abel:\b' for grouped, send in ( (False, 'o'), # 'o' = group display (False, 'M'), # grouped address (True, 't'), # grouped TxID - (True, 'q'), - ): + (True, 'q')): if grouped: t.expect('........') t.expect(prompt, send) @@ -1833,7 +1837,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_msgcreate(self): sid1 = self._user_sid('bob') - sid2 = self._get_user_subsid('bob','29L') + sid2 = self._get_user_subsid('bob', '29L') return self.spawn( 'mmgen-msg', [ '--bob', @@ -1844,17 +1848,17 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): f'{sid2}:C:3-7,87,98' ]) - def bob_msgsign(self,wallets=[]): - fn = get_file_with_ext(self.tmpdir,'rawmsg.json') + def bob_msgsign(self, wallets=[]): + fn = get_file_with_ext(self.tmpdir, 'rawmsg.json') t = self.spawn( 'mmgen-msg', [ '--bob', f'--outdir={self.tmpdir}', 'sign', fn - ] + wallets ) + ] + wallets) if not wallets: - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) return t def bob_walletconv_words(self): @@ -1862,7 +1866,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): 'mmgen-walletconv', ['--bob', f'--outdir={self.tmpdir}', '--out-fmt=words'], no_passthru_opts = True) - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.written_to_file('data') return t @@ -1871,18 +1875,18 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): 'mmgen-subwalletgen', ['--bob', f'--outdir={self.tmpdir}', '--out-fmt=bip39', '29L'], no_passthru_opts = True) - t.passphrase(dfl_wcls.desc,rt_pw) + t.passphrase(dfl_wcls.desc, rt_pw) t.written_to_file('data') return t def bob_msgsign_userwallet(self): - fn1 = get_file_with_ext(self.tmpdir,'mmwords') + fn1 = get_file_with_ext(self.tmpdir, 'mmwords') return self.bob_msgsign([fn1]) def bob_msgsign_userwallets(self): - fn1 = get_file_with_ext(self.tmpdir,'mmwords') - fn2 = get_file_with_ext(self.tmpdir,'bip39') - return self.bob_msgsign([fn2,fn1]) + fn1 = get_file_with_ext(self.tmpdir, 'mmwords') + fn2 = get_file_with_ext(self.tmpdir, 'bip39') + return self.bob_msgsign([fn2, fn1]) def bob_msgverify( self, @@ -1896,7 +1900,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): '--bob', f'--outdir={self.tmpdir}', cmd, - msgfile or get_file_with_ext(self.tmpdir,ext), + msgfile or get_file_with_ext(self.tmpdir, ext), ] + ([addr] if addr else []), exit_val = exit_val) @@ -1910,8 +1914,8 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): sid = self._user_sid('bob') return self.bob_msgverify(addr=f'{sid}:{self.dfl_mmtype}:1') - def bob_msgexport(self,addr=None): - t = self.bob_msgverify( addr=addr, cmd='export' ) + def bob_msgexport(self, addr=None): + t = self.bob_msgverify(addr=addr, cmd='export') t.written_to_file('data') return t @@ -1921,20 +1925,20 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): def bob_msgverify_export(self): return self.bob_msgverify( - msgfile = os.path.join(self.tmpdir,'signatures.json') + msgfile = os.path.join(self.tmpdir, 'signatures.json') ) def bob_msgverify_export_single(self): sid = self._user_sid('bob') mmid = f'{sid}:{self.dfl_mmtype}:1' - args = [ '--bob', '--color=0', 'listaddress', mmid, 'wide=true' ] + args = ['--bob', '--color=0', 'listaddress', mmid, 'wide=true'] imsg(f'Running mmgen-tool {fmt_list(args,fmt="bare")}') t = self.spawn('mmgen-tool', args, no_msg=True) addr = t.expect_getend(mmid).split()[1] t.close() return self.bob_msgverify( addr = addr, - msgfile = os.path.join(self.tmpdir,'signatures.json') + msgfile = os.path.join(self.tmpdir, 'signatures.json') ) def bob_auto_chg_split(self): @@ -1945,7 +1949,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): user = 'bob', fee = '23s', outputs_cl = [sid+':C:5,0.0135', sid+':L:4'], - outputs_list = '1' ) + outputs_list = '1') def bob_auto_chg_generate(self): if not self.proto.cap('segwit'): @@ -1962,7 +1966,7 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): ignore_labels = False, add_args = []): - if mmtype in ('S','B') and not self.proto.cap('segwit'): + if mmtype in ('S', 'B') and not self.proto.cap('segwit'): return 'skip' sid = self._user_sid('bob') t = self.spawn( @@ -1980,55 +1984,55 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): auto_chg_addr = f'{sid}:{mmtype}:{idx}') def bob_auto_chg1(self): - return self._usr_auto_chg( 'bob', 'C', '3' ) + return self._usr_auto_chg('bob', 'C', '3') def bob_auto_chg2(self): - return self._usr_auto_chg( 'bob', 'B', '2' ) + return self._usr_auto_chg('bob', 'B', '2') def bob_auto_chg3(self): - return self._usr_auto_chg( 'bob', 'S', '1' ) + return self._usr_auto_chg('bob', 'S', '1') def bob_auto_chg4(self): - return self._usr_auto_chg( 'bob', 'C', '3', include_dest=False ) + return self._usr_auto_chg('bob', 'C', '3', include_dest=False) def bob_auto_chg_addrtype1(self): - return self._usr_auto_chg( 'bob', 'C', '3', True ) + return self._usr_auto_chg('bob', 'C', '3', True) def bob_auto_chg_addrtype2(self): - return self._usr_auto_chg( 'bob', 'B', '2', True ) + return self._usr_auto_chg('bob', 'B', '2', True) def bob_auto_chg_addrtype3(self): - return self._usr_auto_chg( 'bob', 'S', '1', True ) + return self._usr_auto_chg('bob', 'S', '1', True) def bob_auto_chg_addrtype4(self): - return self._usr_auto_chg( 'bob', 'C', '3', True, include_dest=False ) + return self._usr_auto_chg('bob', 'C', '3', True, include_dest=False) - def _bob_add_comment_uua(self,addrspec,comment): + def _bob_add_comment_uua(self, addrspec, comment): sid = self._user_sid('bob') - return self.user_add_comment('bob',sid+addrspec,comment) + return self.user_add_comment('bob', sid+addrspec, comment) def bob_add_comment_uua1(self): - return self._bob_add_comment_uua(':C:3','comment for unused address') + return self._bob_add_comment_uua(':C:3', 'comment for unused address') def bob_auto_chg5(self): - return self._usr_auto_chg( 'bob', 'C', '4' ) + return self._usr_auto_chg('bob', 'C', '4') def bob_auto_chg_addrtype5(self): - return self._usr_auto_chg( 'bob', 'C', '4', True ) + return self._usr_auto_chg('bob', 'C', '4', True) def bob_auto_chg6(self): - return self._usr_auto_chg( 'bob', 'C', '3', ignore_labels=True ) + return self._usr_auto_chg('bob', 'C', '3', ignore_labels=True) def bob_auto_chg7(self): sid = self._user_sid('bob') - return self._usr_auto_chg( 'bob', 'S', '3', add_args=[f'{sid}:S:1,0.00345'] ) + return self._usr_auto_chg('bob', 'S', '3', add_args=[f'{sid}:S:1,0.00345']) def bob_auto_chg_addrtype6(self): - return self._usr_auto_chg( 'bob', 'C', '3', True, ignore_labels=True ) + return self._usr_auto_chg('bob', 'C', '3', True, ignore_labels=True) - def _bob_remove_comment_uua(self,addrspec): + def _bob_remove_comment_uua(self, addrspec): sid = self._user_sid('bob') - return self.user_remove_comment('bob',sid+addrspec) + return self.user_remove_comment('bob', sid+addrspec) def bob_remove_comment_uua1(self): return self._bob_remove_comment_uua(':C:3') @@ -2048,25 +2052,25 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return self._usr_auto_chg_bad( 'bob', 'FFFFFFFF:C', - 'contains no addresses' ) + 'contains no addresses') def bob_auto_chg_bad2(self): return self._usr_auto_chg_bad( 'bob', '00000000:C', - 'contains no addresses' ) + 'contains no addresses') def bob_auto_chg_bad3(self): return self._usr_auto_chg_bad( 'bob', self._user_sid('bob') + ':L', - 'contains no unused addresses from address list' ) + 'contains no unused addresses from address list') def bob_auto_chg_bad4(self): return self._usr_auto_chg_bad( 'bob', 'L', - 'contains no unused addresses of address type' ) + 'contains no unused addresses of address type') def bob_auto_chg_bad5(self): sid = self._user_sid('bob') @@ -2092,32 +2096,32 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): add_args = ['B' if self.proto.cap('segwit') else 'C']) def carol_twimport2(self): - u,b = (4,3) if self.proto.cap('segwit') else (3,2) + u, b = (4, 3) if self.proto.cap('segwit') else (3, 2) return self.carol_twimport( rpc_backend = None, add_parms = ['ignore_checksum=true'], - expect_str2 = f'Found {u} unspent outputs in {b} blocks' ) + expect_str2 = f'Found {u} unspent outputs in {b} blocks') def carol_rescan_blockchain(self): - return self._usr_rescan_blockchain('carol',[]) + return self._usr_rescan_blockchain('carol', []) def carol_auto_chg1(self): - return self._usr_auto_chg( 'carol', 'C', '3' ) + return self._usr_auto_chg('carol', 'C', '3') def carol_auto_chg2(self): - return self._usr_auto_chg( 'carol', 'B', '2' ) + return self._usr_auto_chg('carol', 'B', '2') def carol_auto_chg3(self): - return self._usr_auto_chg( 'carol', 'S', '1' ) + return self._usr_auto_chg('carol', 'S', '1') def carol_auto_chg_addrtype1(self): - return self._usr_auto_chg( 'carol', 'C', '3', True ) + return self._usr_auto_chg('carol', 'C', '3', True) def carol_auto_chg_addrtype2(self): - return self._usr_auto_chg( 'carol', 'B', '2', True ) + return self._usr_auto_chg('carol', 'B', '2', True) def carol_auto_chg_addrtype3(self): - return self._usr_auto_chg( 'carol', 'S', '1', True ) + return self._usr_auto_chg('carol', 'S', '1', True) def carol_auto_chg_addrtype4(self): sid = self._user_sid('bob') @@ -2127,13 +2131,13 @@ class CmdTestRegtest(CmdTestBase,CmdTestShared): return self._usr_auto_chg_bad( 'carol', self._user_sid('bob') + ':L', - 'contains no unused addresses from address list' ) + 'contains no unused addresses from address list') def carol_auto_chg_bad2(self): return self._usr_auto_chg_bad( 'carol', 'L', - 'contains no unused addresses of address type' ) + 'contains no unused addresses of address type') def stop(self): self.spawn('', msg_only=True) diff --git a/test/cmdtest_py_d/ct_seedsplit.py b/test/cmdtest_py_d/ct_seedsplit.py index 05a3a005..1a636ebc 100755 --- a/test/cmdtest_py_d/ct_seedsplit.py +++ b/test/cmdtest_py_d/ct_seedsplit.py @@ -25,7 +25,7 @@ import os from mmgen.wallet import get_wallet_cls from mmgen.util import capfirst -from ..include.common import strip_ansi_escapes,cmp_or_die +from ..include.common import strip_ansi_escapes, cmp_or_die from .common import get_file_with_ext from .ct_base import CmdTestBase @@ -41,85 +41,85 @@ class CmdTestSeedSplit(CmdTestBase): tmpdir_nums = [23] color = True cmd_group = ( - ('ss_walletgen', 'wallet generation'), - ('ss_2way_A_dfl1', '2-way seed split (share A)'), - ('ss_2way_B_dfl1', '2-way seed split (share B)'), - ('ss_2way_join_dfl1', '2-way seed join'), - ('ss_2way_A_dfl2', "2-way seed split 'default' (share A)"), - ('ss_2way_B_dfl2', "2-way seed split 'default' (share B)"), - ('ss_2way_join_dfl2', "2-way seed join 'default'"), - ('ss_2way_A_alice', "2-way seed split 'alice' (share A)"), - ('ss_2way_B_alice', "2-way seed split 'alice' (share B)"), - ('ss_2way_join_alice', "2-way seed join 'alice'"), - ('ss_2way_join_alice_mix', "2-way seed join 'alice' (out of order)"), - ('ss_2way_A_dfl_master3', '2-way seed split with master share #3 (share A)'), - ('ss_2way_B_dfl_master3', '2-way seed split with master share #3 (share B)'), - ('ss_2way_join_dfl_master3', '2-way seed join with master share #3'), - ('ss_2way_A_dfl_usw', '2-way seed split of user-specified wallet (share A)'), - ('ss_2way_B_dfl_usw', '2-way seed split of user-specified wallet (share B)'), - ('ss_2way_join_dfl_usw', '2-way seed join of user-specified wallet'), - ('ss_3way_A_dfl', '3-way seed split (share A)'), - ('ss_3way_B_dfl', '3-way seed split (share B)'), - ('ss_3way_C_dfl', '3-way seed split (share C)'), - ('ss_3way_join_dfl', '3-way seed join'), - ('ss_3way_join_dfl_mix', '3-way seed join (out of order)'), - ('ss_3way_A_foobar_master7', "3-way seed split 'φυβαρ' with master share #7 (share A)"), - ('ss_3way_B_foobar_master7', "3-way seed split 'φυβαρ' with master share #7 (share B)"), - ('ss_3way_C_foobar_master7', "3-way seed split 'φυβαρ' with master share #7 (share C)"), - ('ss_3way_join_foobar_master7', "3-way seed join 'φυβαρ' with master share #7"), - ('ss_3way_join_foobar_master7_mix',"3-way seed join 'φυβαρ' with master share #7 (out of order)"), + ('ss_walletgen', 'wallet generation'), + ('ss_2way_A_dfl1', '2-way seed split (share A)'), + ('ss_2way_B_dfl1', '2-way seed split (share B)'), + ('ss_2way_join_dfl1', '2-way seed join'), + ('ss_2way_A_dfl2', '2-way seed split ‘default’ (share A)'), + ('ss_2way_B_dfl2', '2-way seed split ‘default’ (share B)'), + ('ss_2way_join_dfl2', '2-way seed join ‘default’'), + ('ss_2way_A_alice', '2-way seed split ‘alice’ (share A)'), + ('ss_2way_B_alice', '2-way seed split ‘alice’ (share B)'), + ('ss_2way_join_alice', '2-way seed join ‘alice’'), + ('ss_2way_join_alice_mix', '2-way seed join ‘alice’ (out of order)'), + ('ss_2way_A_dfl_master3', '2-way seed split with master share #3 (share A)'), + ('ss_2way_B_dfl_master3', '2-way seed split with master share #3 (share B)'), + ('ss_2way_join_dfl_master3', '2-way seed join with master share #3'), + ('ss_2way_A_dfl_usw', '2-way seed split of user-specified wallet (share A)'), + ('ss_2way_B_dfl_usw', '2-way seed split of user-specified wallet (share B)'), + ('ss_2way_join_dfl_usw', '2-way seed join of user-specified wallet'), + ('ss_3way_A_dfl', '3-way seed split (share A)'), + ('ss_3way_B_dfl', '3-way seed split (share B)'), + ('ss_3way_C_dfl', '3-way seed split (share C)'), + ('ss_3way_join_dfl', '3-way seed join'), + ('ss_3way_join_dfl_mix', '3-way seed join (out of order)'), + ('ss_3way_A_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share A)'), + ('ss_3way_B_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share B)'), + ('ss_3way_C_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share C)'), + ('ss_3way_join_foobar_master7', '3-way seed join ‘φυβαρ’ with master share #7'), + ('ss_3way_join_foobar_master7_mix', '3-way seed join ‘φυβαρ’ with master share #7 (out of order)'), - ('ss_3way_join_dfl_bad_invocation',"bad invocation of 'mmgen-seedjoin' - --id-str with non-master join"), - ('ss_bad_invocation1', "bad invocation of 'mmgen-seedsplit' - no arguments"), - ('ss_bad_invocation2', "bad invocation of 'mmgen-seedsplit' - master share with split specifier"), - ('ss_bad_invocation3', "bad invocation of 'mmgen-seedsplit' - nonexistent file"), - ('ss_bad_invocation4', "bad invocation of 'mmgen-seedsplit' - invalid file extension"), - ('ss_bad_invocation5', "bad invocation of 'mmgen-seedjoin' - no arguments"), - ('ss_bad_invocation6', "bad invocation of 'mmgen-seedjoin' - one file argument"), - ('ss_bad_invocation7', "bad invocation of 'mmgen-seedjoin' - invalid file extension"), - ('ss_bad_invocation8', "bad invocation of 'mmgen-seedjoin' - nonexistent file"), - ('ss_bad_invocation9', "bad invocation of 'mmgen-seedsplit' - bad specifier"), - ('ss_bad_invocation10', "bad invocation of 'mmgen-seedsplit' - nonexistent file"), - ('ss_bad_invocation11', "bad invocation of 'mmgen-seedsplit' - invalid file extension"), + ('ss_3way_join_dfl_bad_invocation', 'bad invocation of ‘mmgen-seedjoin’ - --id-str with non-master join'), + ('ss_bad_invocation1', 'bad invocation of ‘mmgen-seedsplit’ - no arguments'), + ('ss_bad_invocation2', 'bad invocation of ‘mmgen-seedsplit’ - master share with split specifier'), + ('ss_bad_invocation3', 'bad invocation of ‘mmgen-seedsplit’ - nonexistent file'), + ('ss_bad_invocation4', 'bad invocation of ‘mmgen-seedsplit’ - invalid file extension'), + ('ss_bad_invocation5', 'bad invocation of ‘mmgen-seedjoin’ - no arguments'), + ('ss_bad_invocation6', 'bad invocation of ‘mmgen-seedjoin’ - one file argument'), + ('ss_bad_invocation7', 'bad invocation of ‘mmgen-seedjoin’ - invalid file extension'), + ('ss_bad_invocation8', 'bad invocation of ‘mmgen-seedjoin’ - nonexistent file'), + ('ss_bad_invocation9', 'bad invocation of ‘mmgen-seedsplit’ - bad specifier'), + ('ss_bad_invocation10', 'bad invocation of ‘mmgen-seedsplit’ - nonexistent file'), + ('ss_bad_invocation11', 'bad invocation of ‘mmgen-seedsplit’ - invalid file extension'), ) - def get_tmp_subdir(self,subdir): - return os.path.join(self.tmpdir,subdir) + def get_tmp_subdir(self, subdir): + return os.path.join(self.tmpdir, subdir) def ss_walletgen(self): - t = self.spawn('mmgen-walletgen', ['-r0','-p1']) - t.passphrase_new('new '+dfl_wcls.desc,wpasswd) + t = self.spawn('mmgen-walletgen', ['-r0', '-p1']) + t.passphrase_new('new '+dfl_wcls.desc, wpasswd) t.label() - self.write_to_tmpfile('dfl.sid',strip_ansi_escapes(t.expect_getend('Seed ID: '))) - t.expect('move it to the data directory? (Y/n): ','y') + self.write_to_tmpfile('dfl.sid', strip_ansi_escapes(t.expect_getend('Seed ID: '))) + t.expect('move it to the data directory? (Y/n): ', 'y') t.written_to_file(capfirst(dfl_wcls.desc)) return t - def ss_splt(self,tdir,ofmt,spec,add_args=[],wf=None,master=None): + def ss_splt(self, tdir, ofmt, spec, add_args=[], wf=None, master=None): try: os.mkdir(self.get_tmp_subdir(tdir)) except: pass t = self.spawn('mmgen-seedsplit', - ['-q','-d',self.get_tmp_subdir(tdir),'-r0','-o',ofmt] - + (['-L',(spec or 'label')] if ofmt == 'w' else []) + ['-q', '-d', self.get_tmp_subdir(tdir), '-r0', '-o', ofmt] + + (['-L', (spec or 'label')] if ofmt == 'w' else []) + add_args + ([f'--master-share={master}'] if master else []) + ([wf] if wf else []) + ([spec] if spec else [])) if not wf: - t.passphrase(dfl_wcls.desc,wpasswd) + t.passphrase(dfl_wcls.desc, wpasswd) if spec: from mmgen.seedsplit import SeedSplitSpecifier sss = SeedSplitSpecifier(spec) pat = rf'Processing .*\b{sss.idx}\b of \b{sss.count}\b of .* id .*‘{sss.id}’' else: pat = f'master share #{master}' - t.expect(pat,regex=True) + t.expect(pat, regex=True) ocls = get_wallet_cls(fmt_code=ofmt) if ocls.enc: - t.hash_preset('new '+ocls.desc,'1') - t.passphrase_new('new '+ocls.desc,sh1_passwd) + t.hash_preset('new '+ocls.desc, '1') + t.passphrase_new('new '+ocls.desc, sh1_passwd) if ocls.type == 'incog_hidden': t.hincog_create(1234) t.written_to_file(capfirst(ocls.desc)) @@ -136,119 +136,119 @@ class CmdTestSeedSplit(CmdTestBase): master = None, id_str = None): td = self.get_tmp_subdir(tdir) - shares = [get_file_with_ext(td,f) for f in in_exts] + shares = [get_file_with_ext(td, f) for f in in_exts] if not sid: sid = self.read_from_tmpfile('dfl.sid') t = self.spawn('mmgen-seedjoin', add_args + ([f'--master-share={master}'] if master else []) + ([f'--id-str={id_str}'] if id_str else []) - + ['-d',td,'-o',ofmt] - + (['--label','Joined Wallet Label','-r0'] if ofmt == 'w' else []) + + ['-d', td, '-o', ofmt] + + (['--label', 'Joined Wallet Label', '-r0'] if ofmt == 'w' else []) + shares, exit_val = exit_val) if exit_val: return t - icls = ( dfl_wcls if 'mmdat' in in_exts + icls = (dfl_wcls if 'mmdat' in in_exts else get_wallet_cls('incog') if 'mmincog' in in_exts else get_wallet_cls('incog_hex') if 'mmincox' in in_exts else get_wallet_cls('incog_hidden') if '-H' in add_args - else None ) + else None) if icls.type.startswith('incog'): - t.hash_preset(icls.desc,'1') + t.hash_preset(icls.desc, '1') if icls: - t.passphrase(icls.desc,sh1_passwd) + t.passphrase(icls.desc, sh1_passwd) if master: fs = "master share #{}, split id.*‘{}’.*, share count {}" pat = fs.format( master, id_str or 'default', - len(shares) + (icls.type=='incog_hidden') ) - t.expect(pat,regex=True) + len(shares) + (icls.type=='incog_hidden')) + t.expect(pat, regex=True) sid_cmp = strip_ansi_escapes(t.expect_getend('Joined Seed ID: ')) - cmp_or_die(sid,sid_cmp) + cmp_or_die(sid, sid_cmp) ocls = get_wallet_cls(fmt_code=ofmt) if ocls.type == 'mmgen': - t.hash_preset('new '+ocls.desc,'1') - t.passphrase_new('new '+ocls.desc,wpasswd) + t.hash_preset('new '+ocls.desc, '1') + t.passphrase_new('new '+ocls.desc, wpasswd) t.written_to_file(capfirst(ocls.desc)) return t - def get_hincog_arg(self,tdir,suf='-default-2of2'): + def get_hincog_arg(self, tdir, suf='-default-2of2'): sid = self.read_from_tmpfile('dfl.sid') - return os.path.join(self.tmpdir,tdir,sid+suf+'.hincog') + ',123' + return os.path.join(self.tmpdir, tdir, sid+suf+'.hincog') + ',123' def ss_2way_A_dfl1(self): - return self.ss_splt('2way_dfl1','w','1:2') + return self.ss_splt('2way_dfl1', 'w', '1:2') def ss_2way_B_dfl1(self): - return self.ss_splt('2way_dfl1','bip39','2:2') + return self.ss_splt('2way_dfl1', 'bip39', '2:2') def ss_2way_join_dfl1(self): - return self.ss_join('2way_dfl1','w',['mmdat','bip39']) + return self.ss_join('2way_dfl1', 'w', ['mmdat', 'bip39']) def ss_2way_A_dfl2(self): - return self.ss_splt('2way_dfl2','seed','default:1:2') + return self.ss_splt('2way_dfl2', 'seed', 'default:1:2') def ss_2way_B_dfl2(self): - return self.ss_splt('2way_dfl2','hincog','default:2:2',['-J',self.get_hincog_arg('2way_dfl2')]) + return self.ss_splt('2way_dfl2', 'hincog', 'default:2:2', ['-J', self.get_hincog_arg('2way_dfl2')]) def ss_2way_join_dfl2(self): - return self.ss_join('2way_dfl2','mmhex',['mmseed'],['-H',self.get_hincog_arg('2way_dfl2')]) + return self.ss_join('2way_dfl2', 'mmhex', ['mmseed'], ['-H', self.get_hincog_arg('2way_dfl2')]) def ss_2way_A_alice(self): - return self.ss_splt('2way_alice','w','alice:1:2') + return self.ss_splt('2way_alice', 'w', 'alice:1:2') def ss_2way_B_alice(self): - return self.ss_splt('2way_alice','mmhex','alice:2:2') + return self.ss_splt('2way_alice', 'mmhex', 'alice:2:2') def ss_2way_join_alice(self): - return self.ss_join('2way_alice','seed',['mmdat','mmhex']) + return self.ss_join('2way_alice', 'seed', ['mmdat', 'mmhex']) def ss_2way_join_alice_mix(self): - return self.ss_join('2way_alice','seed',['mmhex','mmdat']) + return self.ss_join('2way_alice', 'seed', ['mmhex', 'mmdat']) def ss_2way_A_dfl_usw(self): - return self.ss_splt('2way_dfl_usw','words','1:2',[],wf=ref_wf) + return self.ss_splt('2way_dfl_usw', 'words', '1:2', [], wf=ref_wf) def ss_2way_B_dfl_usw(self): - return self.ss_splt('2way_dfl_usw','incog','2:2',[],wf=ref_wf) + return self.ss_splt('2way_dfl_usw', 'incog', '2:2', [], wf=ref_wf) def ss_2way_join_dfl_usw(self): - return self.ss_join('2way_dfl_usw','mmhex',['mmwords','mmincog'],sid=ref_sid) + return self.ss_join('2way_dfl_usw', 'mmhex', ['mmwords', 'mmincog'], sid=ref_sid) def ss_3way_A_dfl(self): - return self.ss_splt('3way_dfl','words','1:3') + return self.ss_splt('3way_dfl', 'words', '1:3') def ss_3way_B_dfl(self): - return self.ss_splt('3way_dfl','incog_hex','2:3') + return self.ss_splt('3way_dfl', 'incog_hex', '2:3') def ss_3way_C_dfl(self): - return self.ss_splt('3way_dfl','bip39','3:3') + return self.ss_splt('3way_dfl', 'bip39', '3:3') def ss_3way_join_dfl(self): - return self.ss_join('3way_dfl','mmhex',['mmwords','mmincox','bip39']) + return self.ss_join('3way_dfl', 'mmhex', ['mmwords', 'mmincox', 'bip39']) def ss_3way_join_dfl_mix(self): - return self.ss_join('3way_dfl','mmhex',['bip39','mmwords','mmincox']) + return self.ss_join('3way_dfl', 'mmhex', ['bip39', 'mmwords', 'mmincox']) def ss_2way_A_dfl_master3(self): - return self.ss_splt('2way_dfl_master3','w','',master=3) + return self.ss_splt('2way_dfl_master3', 'w', '', master=3) def ss_2way_B_dfl_master3(self): - return self.ss_splt('2way_dfl_master3','bip39','2:2',master=3) + return self.ss_splt('2way_dfl_master3', 'bip39', '2:2', master=3) def ss_2way_join_dfl_master3(self): - return self.ss_join('2way_dfl_master3','mmhex',['mmdat','bip39'],master=3) + return self.ss_join('2way_dfl_master3', 'mmhex', ['mmdat', 'bip39'], master=3) tdir2 = '3way_foobar_master7' def ss_3way_C_foobar_master7(self): - return self.ss_splt(self.tdir2,'hincog','', - ['-J',self.get_hincog_arg(self.tdir2,'-master7')],master=7) + return self.ss_splt(self.tdir2, 'hincog', '', + ['-J', self.get_hincog_arg(self.tdir2, '-master7')], master=7) def ss_3way_B_foobar_master7(self): - return self.ss_splt(self.tdir2,'bip39','φυβαρ:2:3',master=7) + return self.ss_splt(self.tdir2, 'bip39', 'φυβαρ:2:3', master=7) def ss_3way_A_foobar_master7(self): - return self.ss_splt(self.tdir2,'mmhex','φυβαρ:3:3',master=7) + return self.ss_splt(self.tdir2, 'mmhex', 'φυβαρ:3:3', master=7) def ss_3way_join_foobar_master7(self): - return self.ss_join(self.tdir2,'seed', ['bip39','mmhex'], - ['-H',self.get_hincog_arg(self.tdir2,'-master7')],master=7,id_str='φυβαρ') + return self.ss_join(self.tdir2, 'seed', ['bip39', 'mmhex'], + ['-H', self.get_hincog_arg(self.tdir2, '-master7')], master=7, id_str='φυβαρ') def ss_3way_join_foobar_master7_mix(self): - return self.ss_join(self.tdir2,'seed', ['mmhex','bip39'], - ['-H',self.get_hincog_arg(self.tdir2,'-master7')],master=7,id_str='φυβαρ') + return self.ss_join(self.tdir2, 'seed', ['mmhex', 'bip39'], + ['-H', self.get_hincog_arg(self.tdir2, '-master7')], master=7, id_str='φυβαρ') - def ss_bad_invocation(self,cmd,args,exit_val,errmsg): + def ss_bad_invocation(self, cmd, args, exit_val, errmsg): t = self.spawn(cmd, args, exit_val=exit_val) t.expect(errmsg, regex=True) return t def ss_3way_join_dfl_bad_invocation(self): - t = self.ss_join('3way_dfl','mmhex', - ['mmwords','mmincox','bip39'], + t = self.ss_join('3way_dfl', 'mmhex', + ['mmwords', 'mmincox', 'bip39'], id_str = 'foo', exit_val = 1) t.expect('option meaningless') diff --git a/test/cmdtest_py_d/ct_shared.py b/test/cmdtest_py_d/ct_shared.py index 0220bb8b..a8524345 100755 --- a/test/cmdtest_py_d/ct_shared.py +++ b/test/cmdtest_py_d/ct_shared.py @@ -26,14 +26,14 @@ from mmgen.addrlist import AddrList from mmgen.passwdlist import PasswordList from ..include.common import cfg, cmp_or_die, strip_ansi_escapes, joinpath, silence, end_silence -from .common import ref_bw_file,ref_bw_hash_preset,ref_dir +from .common import ref_bw_file, ref_bw_hash_preset, ref_dir class CmdTestShared: 'shared methods for the cmdtest.py test suite' @property def segwit_mmtype(self): - return ('segwit','bech32')[bool(cfg.bech32)] if self.segwit else None + return ('segwit', 'bech32')[bool(cfg.bech32)] if self.segwit else None @property def segwit_arg(self): @@ -66,48 +66,48 @@ class CmdTestShared: confirm_pat = r'Is this what you want.*:.' if used_chg_addr_resp is not None: - t.expect('reuse harms your privacy.*:.*',used_chg_addr_resp,regex=True) + t.expect('reuse harms your privacy.*:.*', used_chg_addr_resp, regex=True) if auto_chg_addr is not None: e1 = 'Choose a change address:.*Enter a number> ' e2 = fr'Using .*{auto_chg_addr}.* as.*address' - res = t.expect([e1,e2],regex=True) + res = t.expect([e1, e2], regex=True) if res == 0: choice = [s.split(')')[0].lstrip() for s in t.p.match[0].split('\n') if auto_chg_addr in s][0] t.send(f'{choice}\n') - t.expect(e2,regex=True) + t.expect(e2, regex=True) t.send('y') pat = expect_pat for choice in menu + ['q']: - t.expect(pat,choice,regex=True) + t.expect(pat, choice, regex=True) if self.proto.base_proto == 'Ethereum': pat = confirm_pat if pat == delete_pat else delete_pat if choice == 'D' else expect_pat if bad_input_sels: - for r in ('x','3-1','9999'): - t.expect(input_sels_prompt+': ',r+'\n') + for r in ('x', '3-1', '9999'): + t.expect(input_sels_prompt+': ', r+'\n') - t.expect(input_sels_prompt+': ',inputs+'\n') + t.expect(input_sels_prompt+': ', inputs+'\n') - have_est_fee = t.expect([f'{fee_desc}: ','OK? (Y/n): ']) == 1 + have_est_fee = t.expect([f'{fee_desc}: ', 'OK? (Y/n): ']) == 1 if have_est_fee and not interactive_fee: t.send('y') else: if have_est_fee: t.send('n') - t.expect(f'{fee_desc}: ',interactive_fee+'\n') + t.expect(f'{fee_desc}: ', interactive_fee+'\n') else: t.send(interactive_fee+'\n') if fee_info_pat: - t.expect(fee_info_pat,regex=True) - t.expect('OK? (Y/n): ','y') + t.expect(fee_info_pat, regex=True) + t.expect('OK? (Y/n): ', 'y') - t.expect('(Y/n): ','\n') # chg amt OK prompt + t.expect('(Y/n): ', '\n') # chg amt OK prompt if 'confirm_non_mmgen' in tweaks: - t.expect('Continue? (Y/n)','\n') + t.expect('Continue? (Y/n)', '\n') t.do_comment(add_comment) @@ -116,7 +116,7 @@ class CmdTestShared: t.view_tx(view) if not txdo: - t.expect('(y/N): ',('n','y')[save]) + t.expect('(y/N): ', ('n', 'y')[save]) t.written_to_file(file_desc) return t @@ -136,12 +136,12 @@ class CmdTestShared: txdo = (caller or self.test_name)[:4] == 'txdo' if do_passwd: - t.passphrase('MMGen wallet',self.wpasswd) + t.passphrase('MMGen wallet', self.wpasswd) if not ni and not txdo: t.view_tx(view) - t.do_comment(add_comment,has_label=has_label) - t.expect('(Y/n): ',('n','y')[save]) + t.do_comment(add_comment, has_label=has_label) + t.expect('(Y/n): ', ('n', 'y')[save]) t.written_to_file(file_desc) @@ -164,9 +164,9 @@ class CmdTestShared: if not txdo: t.license() # MMGEN_NO_LICENSE is set, so does nothing t.view_tx(view) - t.do_comment(add_comment,has_label=has_label) + t.do_comment(add_comment, has_label=has_label) - self._do_confirm_send(t,quiet=quiet,confirm_send=confirm_send) + self._do_confirm_send(t, quiet=quiet, confirm_send=confirm_send) if bogus_send: txid = '' @@ -179,10 +179,10 @@ class CmdTestShared: return txid - def txsign_end(self,t,tnum=None,has_label=False): + def txsign_end(self, t, tnum=None, has_label=False): t.expect('Signing transaction') - t.do_comment(False,has_label=has_label) - t.expect(r'Save signed transaction.*?\? \(Y/n\): ','y',regex=True) + t.do_comment(False, has_label=has_label) + t.expect(r'Save signed transaction.*?\? \(Y/n\): ', 'y', regex=True) t.written_to_file('Signed transaction' + (' #' + tnum if tnum else '')) return t @@ -196,7 +196,7 @@ class CmdTestShared: extra_desc = '', view = 'n', dfl_wallet = False): - opts = extra_opts + ['-d',self.tmpdir,txfile] + ([wf] if wf else []) + opts = extra_opts + ['-d', self.tmpdir, txfile] + ([wf] if wf else []) wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf)) t = self.spawn( 'mmgen-txsign', @@ -206,19 +206,19 @@ class CmdTestShared: t.license() t.view_tx(view) if wcls.enc and wcls.type != 'brain': - t.passphrase(wcls.desc,self.wpasswd) + t.passphrase(wcls.desc, self.wpasswd) if save: - self.txsign_end(t,has_label=has_label) + self.txsign_end(t, has_label=has_label) else: - t.do_comment(False,has_label=has_label) - t.expect('Save signed transaction? (Y/n): ','n') + t.do_comment(False, has_label=has_label) + t.expect('Save signed transaction? (Y/n): ', 'n') t.expect('not saved') return t - def ref_brain_chk(self,bw_file=ref_bw_file): - wf = joinpath(ref_dir,bw_file) + def ref_brain_chk(self, bw_file=ref_bw_file): + wf = joinpath(ref_dir, bw_file) add_args = [f'-l{self.seed_len}', f'-p{ref_bw_hash_preset}'] - return self.walletchk(wf,add_args=add_args,sid=self.ref_bw_seed_id) + return self.walletchk(wf, add_args=add_args, sid=self.ref_bw_seed_id) def walletchk( self, @@ -228,21 +228,21 @@ class CmdTestShared: sid = None, extra_desc = '', dfl_wallet = False): - hp = self.hash_preset if hasattr(self,'hash_preset') else '1' + hp = self.hash_preset if hasattr(self, 'hash_preset') else '1' wcls = wcls or get_wallet_cls(ext=get_extension(wf)) t = self.spawn( 'mmgen-walletchk', - ([] if dfl_wallet else ['-i',wcls.fmt_codes[0]]) + ([] if dfl_wallet else ['-i', wcls.fmt_codes[0]]) + self.testnet_opt - + add_args + ['-p',hp] + + add_args + ['-p', hp] + ([wf] if wf else []), extra_desc = extra_desc, no_passthru_opts = True) if wcls.type != 'incog_hidden': t.expect(f"Getting {wcls.desc} from file ‘") if wcls.enc and wcls.type != 'brain': - t.passphrase(wcls.desc,self.wpasswd) - t.expect(['Passphrase is OK', 'Passphrase.* are correct'],regex=True) + t.passphrase(wcls.desc, self.wpasswd) + t.expect(['Passphrase is OK', 'Passphrase.* are correct'], regex=True) chksum = t.expect_getend(f'Valid {wcls.desc} for Seed ID ')[:8] if sid: cmp_or_die(chksum, sid) @@ -265,19 +265,19 @@ class CmdTestShared: mmtype = self.segwit_mmtype t = self.spawn( f'mmgen-{list_type}gen', - ['-d',self.tmpdir] + extra_opts + - ([],['--type='+str(mmtype)])[bool(mmtype)] + - ([],['--stdout'])[stdout] + - ([],[wf])[bool(wf)] + - ([],[id_str])[bool(id_str)] + - [getattr(self,f'{list_type}_idx_list')], - extra_desc = f'({mmtype})' if mmtype in ('segwit','bech32') else '', + ['-d', self.tmpdir] + extra_opts + + ([], ['--type='+str(mmtype)])[bool(mmtype)] + + ([], ['--stdout'])[stdout] + + ([], [wf])[bool(wf)] + + ([], [id_str])[bool(id_str)] + + [getattr(self, f'{list_type}_idx_list')], + extra_desc = f'({mmtype})' if mmtype in ('segwit', 'bech32') else '', no_passthru_opts = no_passthru_opts) t.license() - wcls = get_wallet_cls( ext = 'mmdat' if dfl_wallet else get_extension(wf) ) - t.passphrase(wcls.desc,self.wpasswd) + wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf)) + t.passphrase(wcls.desc, self.wpasswd) t.expect('Passphrase is OK') - desc = ('address','password')[passgen] + desc = ('address', 'password')[passgen] chksum = strip_ansi_escapes(t.expect_getend(rf'Checksum for {desc} data .*?: ', regex=True)) if check_ref: chksum_chk = ( @@ -285,7 +285,7 @@ class CmdTestShared: self.chk_data[self.test_name][self.fork][self.proto.testnet]) cmp_or_die(chksum, chksum_chk, desc=f'{ftype}list data checksum') if passgen: - t.expect('Encrypt password list? (y/N): ','N') + t.expect('Encrypt password list? (y/N): ', 'N') if stdout: t.read() else: @@ -306,20 +306,20 @@ class CmdTestShared: extra_desc = f'({mmtype})' if mmtype in ('segwit', 'bech32') else '') t.license() wcls = get_wallet_cls(ext=get_extension(wf)) - t.passphrase(wcls.desc,self.wpasswd) - chksum = t.expect_getend(r'Checksum for key-address data .*?: ',regex=True) + t.passphrase(wcls.desc, self.wpasswd) + chksum = t.expect_getend(r'Checksum for key-address data .*?: ', regex=True) if check_ref: chksum_chk = self.chk_data[self.test_name][self.fork][self.proto.testnet] cmp_or_die(chksum, chksum_chk, desc='key-address list data checksum') - t.expect('Encrypt key list? (y/N): ','y') + t.expect('Encrypt key list? (y/N): ', 'y') t.usr_rand(self.usr_rand_chars) - t.hash_preset('new key-address list','1') - t.passphrase_new('new key-address list',self.kapasswd) + t.hash_preset('new key-address list', '1') + t.passphrase_new('new key-address list', self.kapasswd) t.written_to_file('Encrypted secret keys') return t - def _do_confirm_send(self,t,quiet=False,confirm_send=True,sure=True): + def _do_confirm_send(self, t, quiet=False, confirm_send=True, sure=True): if sure: t.expect('Are you sure you want to broadcast this') - m = ('YES, I REALLY WANT TO DO THIS','YES')[quiet] - t.expect(f'{m!r} to confirm: ',('',m)[confirm_send]+'\n') + m = ('YES, I REALLY WANT TO DO THIS', 'YES')[quiet] + t.expect(f'{m!r} to confirm: ', ('', m)[confirm_send]+'\n') diff --git a/test/cmdtest_py_d/ct_tool.py b/test/cmdtest_py_d/ct_tool.py index 8563fa88..a2f04248 100755 --- a/test/cmdtest_py_d/ct_tool.py +++ b/test/cmdtest_py_d/ct_tool.py @@ -10,7 +10,7 @@ test.cmdtest_py_d.ct_tool: tool tests for the MMGen cmdtest.py test suite """ -import sys,os +import sys, os from mmgen.util import suf from mmgen.color import cyan @@ -24,35 +24,51 @@ from ..include.common import ( joinpath, getrand ) -from .common import hincog_fn,incog_id_fn,hincog_offset,tool_enc_passwd,ref_dir +from .common import hincog_fn, incog_id_fn, hincog_offset, tool_enc_passwd, ref_dir from .ct_base import CmdTestBase from .ct_main import CmdTestMain -class CmdTestTool(CmdTestMain,CmdTestBase): +class CmdTestTool(CmdTestMain, CmdTestBase): "interactive 'mmgen-tool' commands" networks = ('btc',) segwit_opts_ok = False tmpdir_nums = [9] enc_infn = 'tool_encrypt.in' cmd_group = ( - ('tool_find_incog_data', (9,"'mmgen-tool find_incog_data'", [[[hincog_fn],1],[[incog_id_fn],1]])), - ('tool_rand2file', (9,"'mmgen-tool rand2file'", [])), - ('tool_encrypt', (9,"'mmgen-tool encrypt' (random data)", [])), - ('tool_decrypt', (9,"'mmgen-tool decrypt' (random data)", [[[enc_infn+'.mmenc'],9]])), - ('tool_twview_bad_comment',(9,"'mmgen-tool twview' (with bad comment)", [])), - ('tool_decrypt_keystore',(9,"'mmgen-tool decrypt_keystore'", [])), - ('tool_decrypt_geth_keystore',(9,"'mmgen-tool decrypt_geth_keystore'", [])), - ('tool_api', (9,'tool API (initialization, config methods, wif2addr)',[])), - # ('tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])), + ('tool_find_incog_data', + (9, '‘mmgen-tool find_incog_data’', [[[hincog_fn], 1], [[incog_id_fn], 1]]) + ), + ('tool_rand2file', + (9, '‘mmgen-tool rand2file’', []) + ), + ('tool_encrypt', + (9, '‘mmgen-tool encrypt’ (random data)', []) + ), + ('tool_decrypt', + (9, '‘mmgen-tool decrypt’ (random data)', [[[enc_infn+'.mmenc'], 9]]) + ), + ('tool_twview_bad_comment', + (9, '‘mmgen-tool twview’ (with bad comment)', []) + ), + ('tool_decrypt_keystore', + (9, '‘mmgen-tool decrypt_keystore’', []) + ), + ('tool_decrypt_geth_keystore', + (9, '‘mmgen-tool decrypt_geth_keystore’', []) + ), + ('tool_api', + (9, 'tool API (initialization, config methods, wif2addr)', []) + ), + # ('tool_encrypt_ref', (9, '‘mmgen-tool encrypt’ (reference text)', [])), ) def tool_rand2file(self): from mmgen.util2 import parse_bytespec - for nbytes in ('1','1023','1K','1048575','1M','1048577','123M'): + for nbytes in ('1', '1023', '1K', '1048575', '1M', '1048577', '123M'): t = self.spawn( 'mmgen-tool', - ['-d',self.tmpdir,'-r0','rand2file','rand2file.out',nbytes], - extra_desc='({} byte{})'.format( nbytes, suf(parse_bytespec(nbytes)) ) + ['-d', self.tmpdir, '-r0', 'rand2file', 'rand2file.out', nbytes], + extra_desc='({} byte{})'.format(nbytes, suf(parse_bytespec(nbytes))) ) t.expect('random data written to file') t.read() @@ -62,49 +78,49 @@ class CmdTestTool(CmdTestMain,CmdTestBase): return t def tool_encrypt(self): - infile = joinpath(self.tmpdir,self.enc_infn) - write_to_file(infile,getrand(1033),binary=True) - t = self.spawn('mmgen-tool',['-d',self.tmpdir,self.usr_rand_arg,'encrypt',infile]) + infile = joinpath(self.tmpdir, self.enc_infn) + write_to_file(infile, getrand(1033), binary=True) + t = self.spawn('mmgen-tool', ['-d', self.tmpdir, self.usr_rand_arg, 'encrypt', infile]) t.usr_rand(self.usr_rand_chars) - t.hash_preset('data','1') - t.passphrase_new('data',tool_enc_passwd) + t.hash_preset('data', '1') + t.passphrase_new('data', tool_enc_passwd) t.written_to_file('Encrypted data') return t - def tool_decrypt(self,f1): + def tool_decrypt(self, f1): out_fn = 'tool_encrypt.out' - t = self.spawn('mmgen-tool',['-d',self.tmpdir,'decrypt',f1,'outfile='+out_fn,'hash_preset=1']) - t.passphrase('data',tool_enc_passwd) + t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'decrypt', f1, 'outfile='+out_fn, 'hash_preset=1']) + t.passphrase('data', tool_enc_passwd) t.written_to_file('Decrypted data') - d1 = self.read_from_tmpfile(self.enc_infn,binary=True) - d2 = self.read_from_tmpfile(out_fn,binary=True) - cmp_or_die(d1,d2) + d1 = self.read_from_tmpfile(self.enc_infn, binary=True) + d2 = self.read_from_tmpfile(out_fn, binary=True) + cmp_or_die(d1, d2) return t - def tool_find_incog_data(self,f1,f2): + def tool_find_incog_data(self, f1, f2): i_id = read_from_file(f2).rstrip() vmsg(f'Incog ID: {cyan(i_id)}') - t = self.spawn('mmgen-tool',['-d',self.tmpdir,'find_incog_data',f1,i_id]) + t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'find_incog_data', f1, i_id]) o = t.expect_getend(f'Incog data for ID {i_id} found at offset ') if not sys.platform == 'win32': os.unlink(f1) # causes problems with MSYS2 - cmp_or_die(hincog_offset,int(o)) + cmp_or_die(hincog_offset, int(o)) return t def tool_twview_bad_comment(self): # test correct operation of get_tw_label() t = self.spawn( 'mmgen-tool', ['twview'], - env = { 'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir,'bad-comment-unspent.json') }, + env = {'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir, 'bad-comment-unspent.json')}, exit_val = 2) t.expect('cannot be converted to TwComment') return t - def _decrypt_keystore(self,cmd,fn,pw,chk): + def _decrypt_keystore(self, cmd, fn, pw, chk): if cfg.no_altcoin: return 'skip' - t = self.spawn('mmgen-tool',['-d',self.tmpdir,cmd,fn]) - t.expect('Enter passphrase: ',pw+'\n') + t = self.spawn('mmgen-tool', ['-d', self.tmpdir, cmd, fn]) + t.expect('Enter passphrase: ', pw+'\n') t.expect(chk) return t @@ -113,7 +129,7 @@ class CmdTestTool(CmdTestMain,CmdTestBase): cmd = 'decrypt_keystore', fn = 'test/ref/altcoin/98831F3A-keystore-wallet.json', pw = 'abc', - chk = read_from_file('test/ref/98831F3A.bip39').strip() ) + chk = read_from_file('test/ref/98831F3A.bip39').strip()) def tool_decrypt_geth_keystore(self): return self._decrypt_keystore( @@ -126,6 +142,6 @@ class CmdTestTool(CmdTestMain,CmdTestBase): t = self.spawn( 'tool_api_test.py', (['no_altcoin'] if cfg.no_altcoin else []), - cmd_dir = 'test/misc' ) - t.expect('legacy.*compressed.*segwit.*bech32',regex=True) + cmd_dir = 'test/misc') + t.expect('legacy.*compressed.*segwit.*bech32', regex=True) return t diff --git a/test/cmdtest_py_d/ct_wallet.py b/test/cmdtest_py_d/ct_wallet.py index bb9cc923..98aa5c70 100755 --- a/test/cmdtest_py_d/ct_wallet.py +++ b/test/cmdtest_py_d/ct_wallet.py @@ -22,84 +22,85 @@ test.cmdtest_py_d.ct_wallet: Wallet conversion tests for the cmdtest.py test sui import sys, os -from mmgen.util import msg,capfirst,get_extension +from mmgen.util import msg, capfirst, get_extension from mmgen.wallet import get_wallet_cls from ..include.common import cfg, joinpath, VirtBlockDevice -from .common import ref_dir,ref_wallet_brainpass,ref_wallet_incog_offset,hincog_fn,hincog_bytes +from .common import ref_dir, ref_wallet_brainpass, ref_wallet_incog_offset, hincog_fn, hincog_bytes from .ct_base import CmdTestBase from .ct_shared import CmdTestShared -class CmdTestWalletConv(CmdTestBase,CmdTestShared): +class CmdTestWalletConv(CmdTestBase, CmdTestShared): 'wallet conversion to and from reference data' networks = ('btc',) - tmpdir_nums = [11,12,13] - sources = { '128': { - 'ref_wallet': 'FE3C6545-D782B529[128,1].mmdat', - 'ic_wallet': 'FE3C6545-E29303EA-5E229E30[128,1].mmincog', - 'ic_wallet_hex': 'FE3C6545-BC4BE3F2-32586837[128,1].mmincox', + tmpdir_nums = [11, 12, 13] + sources = { + '128': { + 'ref_wallet': 'FE3C6545-D782B529[128,1].mmdat', + 'ic_wallet': 'FE3C6545-E29303EA-5E229E30[128,1].mmincog', + 'ic_wallet_hex': 'FE3C6545-BC4BE3F2-32586837[128,1].mmincox', - 'hic_wallet': 'FE3C6545-161E495F-BEB7548E[128,1].incog-offset123', - 'hic_wallet_old': 'FE3C6545-161E495F-9860A85B[128,1].incog-old.offset123', - }, - '192': { - 'ref_wallet': '1378FC64-6F0F9BB4[192,1].mmdat', - 'ic_wallet': '1378FC64-2907DE97-F980D21F[192,1].mmincog', - 'ic_wallet_hex': '1378FC64-4DCB5174-872806A7[192,1].mmincox', + 'hic_wallet': 'FE3C6545-161E495F-BEB7548E[128,1].incog-offset123', + 'hic_wallet_old': 'FE3C6545-161E495F-9860A85B[128,1].incog-old.offset123', + }, + '192': { + 'ref_wallet': '1378FC64-6F0F9BB4[192,1].mmdat', + 'ic_wallet': '1378FC64-2907DE97-F980D21F[192,1].mmincog', + 'ic_wallet_hex': '1378FC64-4DCB5174-872806A7[192,1].mmincox', - 'hic_wallet': '1378FC64-B55E9958-77256FC1[192,1].incog.offset123', - 'hic_wallet_old': '1378FC64-B55E9958-D85FF20C[192,1].incog-old.offset123', - }, - '256': { - 'ref_wallet': '98831F3A-27F2BF93[256,1].mmdat', - 'ic_wallet': '98831F3A-5482381C-18460FB1[256,1].mmincog', - 'ic_wallet_hex': '98831F3A-1630A9F2-870376A9[256,1].mmincox', + 'hic_wallet': '1378FC64-B55E9958-77256FC1[192,1].incog.offset123', + 'hic_wallet_old': '1378FC64-B55E9958-D85FF20C[192,1].incog-old.offset123', + }, + '256': { + 'ref_wallet': '98831F3A-27F2BF93[256,1].mmdat', + 'ic_wallet': '98831F3A-5482381C-18460FB1[256,1].mmincog', + 'ic_wallet_hex': '98831F3A-1630A9F2-870376A9[256,1].mmincox', - 'hic_wallet': '98831F3A-F59B07A0-559CEF19[256,1].incog.offset123', - 'hic_wallet_old': '98831F3A-F59B07A0-848535F3[256,1].incog-old.offset123', + 'hic_wallet': '98831F3A-F59B07A0-559CEF19[256,1].incog.offset123', + 'hic_wallet_old': '98831F3A-F59B07A0-848535F3[256,1].incog-old.offset123', - }, - } + }, + } cmd_group = ( # reading - ('ref_wallet_conv', 'conversion of saved reference wallet'), - ('ref_mn_conv', 'conversion of saved MMGen native mnemonic'), - ('ref_bip39_conv', 'conversion of saved BIP39 mnemonic'), - ('ref_seed_conv', 'conversion of saved seed file'), - ('ref_hex_conv', 'conversion of saved MMGen hexadecimal seed file'), - ('ref_plainhex_conv', 'conversion of saved plain hexadecimal seed file'), - ('ref_dieroll_conv', 'conversion of saved dieroll (b6d) seed file'), - ('ref_brain_conv', 'conversion of ref brainwallet'), - ('ref_incog_conv', 'conversion of saved incog wallet'), - ('ref_incox_conv', 'conversion of saved hex incog wallet'), - ('ref_hincog_conv', 'conversion of saved hidden incog wallet'), - ('ref_hincog_conv_old','conversion of saved hidden incog wallet (old format)'), + ('ref_wallet_conv', 'conversion of saved reference wallet'), + ('ref_mn_conv', 'conversion of saved MMGen native mnemonic'), + ('ref_bip39_conv', 'conversion of saved BIP39 mnemonic'), + ('ref_seed_conv', 'conversion of saved seed file'), + ('ref_hex_conv', 'conversion of saved MMGen hexadecimal seed file'), + ('ref_plainhex_conv', 'conversion of saved plain hexadecimal seed file'), + ('ref_dieroll_conv', 'conversion of saved dieroll (b6d) seed file'), + ('ref_brain_conv', 'conversion of ref brainwallet'), + ('ref_incog_conv', 'conversion of saved incog wallet'), + ('ref_incox_conv', 'conversion of saved hex incog wallet'), + ('ref_hincog_conv', 'conversion of saved hidden incog wallet'), + ('ref_hincog_conv_old', 'conversion of saved hidden incog wallet (old format)'), # writing - ('ref_wallet_conv_out', 'ref seed conversion to wallet'), - ('ref_mn_conv_out', 'ref seed conversion to MMGen native mnemonic'), - ('ref_bip39_conv_out', 'ref seed conversion to BIP39 mnemonic'), - ('ref_hex_conv_out', 'ref seed conversion to MMGen hex seed'), - ('ref_plainhex_conv_out','ref seed conversion to plain hex seed'), - ('ref_dieroll_conv_out','ref seed conversion to dieroll (b6d) seed'), - ('ref_seed_conv_out', 'ref seed conversion to seed'), - ('ref_incog_conv_out', 'ref seed conversion to incog data'), - ('ref_incox_conv_out', 'ref seed conversion to hex incog data'), - ('ref_hincog_conv_out', 'ref seed conversion to hidden incog data'), + ('ref_wallet_conv_out', 'ref seed conversion to wallet'), + ('ref_mn_conv_out', 'ref seed conversion to MMGen native mnemonic'), + ('ref_bip39_conv_out', 'ref seed conversion to BIP39 mnemonic'), + ('ref_hex_conv_out', 'ref seed conversion to MMGen hex seed'), + ('ref_plainhex_conv_out', 'ref seed conversion to plain hex seed'), + ('ref_dieroll_conv_out', 'ref seed conversion to dieroll (b6d) seed'), + ('ref_seed_conv_out', 'ref seed conversion to seed'), + ('ref_incog_conv_out', 'ref seed conversion to incog data'), + ('ref_incox_conv_out', 'ref seed conversion to hex incog data'), + ('ref_hincog_conv_out', 'ref seed conversion to hidden incog data'), ('ref_hincog_blkdev_conv_out', 'ref seed conversion to hidden incog data on block device') ) - def __init__(self,trunner,cfgs,spawn): - for k,_ in self.cmd_group: - for n in (1,2,3): - setattr(self,f'{k}_{n}',getattr(self,k)) - CmdTestBase.__init__(self,trunner,cfgs,spawn) + def __init__(self, trunner, cfgs, spawn): + for k, _ in self.cmd_group: + for n in (1, 2, 3): + setattr(self, f'{k}_{n}', getattr(self, k)) + CmdTestBase.__init__(self, trunner, cfgs, spawn) def ref_wallet_conv(self): - wf = joinpath(ref_dir,self.sources[str(self.seed_len)]['ref_wallet']) + wf = joinpath(ref_dir, self.sources[str(self.seed_len)]['ref_wallet']) return self.walletconv_in(wf) - def ref_mn_conv(self,ext='mmwords'): - wf = joinpath(ref_dir,self.seed_id+'.'+ext) + def ref_mn_conv(self, ext='mmwords'): + wf = joinpath(ref_dir, self.seed_id+'.'+ext) return self.walletconv_in(wf) def ref_bip39_conv(self): @@ -114,28 +115,28 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared): return self.ref_mn_conv(ext='b6d') def ref_brain_conv(self): - uopts = ['-i','bw','-p','1','-l',str(self.seed_len)] - return self.walletconv_in(None,uopts,icls=get_wallet_cls('brain')) + uopts = ['-i', 'bw', '-p', '1', '-l', str(self.seed_len)] + return self.walletconv_in(None, uopts, icls=get_wallet_cls('brain')) - def ref_incog_conv(self,wfk='ic_wallet',in_fmt='i'): - uopts = ['-i',in_fmt,'-p','1','-l',str(self.seed_len)] - wf = joinpath(ref_dir,self.sources[str(self.seed_len)][wfk]) - return self.walletconv_in(wf,uopts) + def ref_incog_conv(self, wfk='ic_wallet', in_fmt='i'): + uopts = ['-i', in_fmt, '-p', '1', '-l', str(self.seed_len)] + wf = joinpath(ref_dir, self.sources[str(self.seed_len)][wfk]) + return self.walletconv_in(wf, uopts) def ref_incox_conv(self): - return self.ref_incog_conv(in_fmt='xi',wfk='ic_wallet_hex') + return self.ref_incog_conv(in_fmt='xi', wfk='ic_wallet_hex') - def ref_hincog_conv(self,wfk='hic_wallet',add_uopts=[]): - ic_f = joinpath(ref_dir,self.sources[str(self.seed_len)][wfk]) - uopts = ['-i','hi','-p','1','-l',str(self.seed_len)] + add_uopts - hi_opt = ['-H',f'{ic_f},{ref_wallet_incog_offset}'] + def ref_hincog_conv(self, wfk='hic_wallet', add_uopts=[]): + ic_f = joinpath(ref_dir, self.sources[str(self.seed_len)][wfk]) + uopts = ['-i', 'hi', '-p', '1', '-l', str(self.seed_len)] + add_uopts + hi_opt = ['-H', f'{ic_f},{ref_wallet_incog_offset}'] return self.walletconv_in( None, uopts + hi_opt, - icls = get_wallet_cls('incog_hidden') ) + icls = get_wallet_cls('incog_hidden')) def ref_hincog_conv_old(self): - return self.ref_hincog_conv(wfk='hic_wallet_old',add_uopts=['-O']) + return self.ref_hincog_conv(wfk='hic_wallet_old', add_uopts=['-O']) def ref_wallet_conv_out(self): return self.walletconv_out('w') @@ -156,14 +157,15 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared): def ref_incox_conv_out(self): return self.walletconv_out('xi') - def ref_hincog_conv_out(self,ic_f=None): + def ref_hincog_conv_out(self, ic_f=None): if not ic_f: - ic_f = joinpath(self.tmpdir,hincog_fn) + ic_f = joinpath(self.tmpdir, hincog_fn) hi_parms = f'{ic_f},{ref_wallet_incog_offset}' sl_parm = '-l' + str(self.seed_len) - return self.walletconv_out('hi', - uopts = ['-J',hi_parms,sl_parm], - uopts_chk = ['-H',hi_parms,sl_parm] ) + return self.walletconv_out( + 'hi', + uopts = ['-J', hi_parms, sl_parm], + uopts_chk = ['-H', hi_parms, sl_parm]) def ref_hincog_blkdev_conv_out(self): @@ -179,41 +181,41 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared): return 'ok' # wallet conversion tests - def walletconv_in(self,infile,uopts=[],icls=None): + def walletconv_in(self, infile, uopts=[], icls=None): ocls = get_wallet_cls('words') - opts = ['-d',self.tmpdir,'-o',ocls.fmt_codes[0],self.usr_rand_arg] + opts = ['-d', self.tmpdir, '-o', ocls.fmt_codes[0], self.usr_rand_arg] if_arg = [infile] if infile else [] d = '(convert)' - t = self.spawn('mmgen-walletconv',opts+uopts+if_arg,extra_desc=d) + t = self.spawn('mmgen-walletconv', opts+uopts+if_arg, extra_desc=d) t.license() icls = icls or get_wallet_cls(ext=get_extension(infile)) if icls.type == 'brain': - t.expect('Enter brainwallet: ',ref_wallet_brainpass+'\n') + t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n') if icls.enc and icls.type != 'brain': - t.passphrase(icls.desc,self.wpasswd) + t.passphrase(icls.desc, self.wpasswd) if self.test_name[:19] == 'ref_hincog_conv_old': - t.expect('Is the Seed ID correct? (Y/n): ','\n') + t.expect('Is the Seed ID correct? (Y/n): ', '\n') else: - t.expect(['Passphrase is OK',' are correct']) + t.expect(['Passphrase is OK', ' are correct']) wf = t.written_to_file(capfirst(ocls.desc)) t.p.wait() # back check of result msg('' if cfg.profile else ' OK') return self.walletchk( - wf, - extra_desc = '(check)', - sid = self.seed_id) + wf, + extra_desc = '(check)', + sid = self.seed_id) - def walletconv_out(self,out_fmt='w',uopts=[],uopts_chk=[]): + def walletconv_out(self, out_fmt='w', uopts=[], uopts_chk=[]): wcls = get_wallet_cls(fmt_code=out_fmt) - opts = ['-d',self.tmpdir,'-p1','-o',out_fmt] + uopts - infile = joinpath(ref_dir,self.seed_id+'.mmwords') - t = self.spawn('mmgen-walletconv',[self.usr_rand_arg]+opts+[infile],extra_desc='(convert)') + opts = ['-d', self.tmpdir, '-p1', '-o', out_fmt] + uopts + infile = joinpath(ref_dir, self.seed_id+'.mmwords') + t = self.spawn('mmgen-walletconv', [self.usr_rand_arg]+opts+[infile], extra_desc='(convert)') add_args = [f'-l{self.seed_len}'] t.license() if wcls.enc and wcls.type != 'brain': - t.passphrase_new('new '+wcls.desc,self.wpasswd) + t.passphrase_new('new '+wcls.desc, self.wpasswd) t.usr_rand(self.usr_rand_chars) if wcls.type.startswith('incog'): for _ in range(3): @@ -229,8 +231,8 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared): wf = None msg('' if cfg.profile else ' OK') return self.walletchk( - wf, - wcls = wcls, - extra_desc = '(check)', - sid = self.seed_id, - add_args = add_args) + wf, + wcls = wcls, + extra_desc = '(check)', + sid = self.seed_id, + add_args = add_args) diff --git a/test/cmdtest_py_d/ct_xmr_autosign.py b/test/cmdtest_py_d/ct_xmr_autosign.py index c4b6f1d5..61fde97f 100755 --- a/test/cmdtest_py_d/ct_xmr_autosign.py +++ b/test/cmdtest_py_d/ct_xmr_autosign.py @@ -30,9 +30,9 @@ def make_burn_addr(): cfg = cfg, cmdname = 'privhex2addr', proto = cfg._proto, - mmtype = 'monero' ).privhex2addr('beadcafe'*8) + mmtype = 'monero').privhex2addr('beadcafe'*8) -class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): +class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): """ Monero autosigning operations """ @@ -99,10 +99,10 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): ('check_tx_dirs', 'cleaning and checking signable file directories'), ) - def __init__(self,trunner,cfgs,spawn): + def __init__(self, trunner, cfgs, spawn): - CmdTestAutosignThreaded.__init__(self,trunner,cfgs,spawn) - CmdTestXMRWallet.__init__(self,trunner,cfgs,spawn) + CmdTestAutosignThreaded.__init__(self, trunner, cfgs, spawn) + CmdTestXMRWallet.__init__(self, trunner, cfgs, spawn) if trunner is None: return @@ -123,7 +123,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): self.spawn_env['MMGEN_TEST_SUITE_XMR_AUTOSIGN'] = '1' def create_tmp_wallets(self): - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) data = self.users['alice'] from mmgen.wallet import Wallet from mmgen.xmrwallet import op @@ -133,22 +133,22 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): cfg = self.cfg, proto = self.proto, addr_idxs = '1-2', - seed = Wallet(cfg,data.mmwords).seed, + seed = Wallet(cfg, data.mmwords).seed, skip_chksum_msg = True, - key_address_validity_check = False ) + key_address_validity_check = False) kal.file.write(ask_overwrite=False) - fn = get_file_with_ext(data.udir,'akeys') + fn = get_file_with_ext(data.udir, 'akeys') m = op('create', self.cfg, fn, '1-2') async_run(m.main()) async_run(m.stop_wallet_daemon()) end_silence() return 'ok' - def _new_addr_alice(self,*args): + def _new_addr_alice(self, *args): data = self.users['alice'] return self.new_addr_alice( *args, - kafile = get_file_with_ext(data.udir,'akeys') ) + kafile = get_file_with_ext(data.udir, 'akeys')) def new_account_alice(self): return self._new_addr_alice( @@ -174,7 +174,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def dump_wallets(self): return self._dump_wallets(autosign=True) - def _dump_wallets(self,autosign): + def _dump_wallets(self, autosign): data = self.users['alice'] self.insert_device_online() t = self.spawn( @@ -183,27 +183,27 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): + [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}'] + (self.autosign_opts if autosign else []) + ['dump'] - + ([] if autosign else [get_file_with_ext(data.udir,'akeys')]) ) + + ([] if autosign else [get_file_with_ext(data.udir, 'akeys')])) t.expect('2 wallets dumped') t.read() self.remove_device_online() return t - def _delete_files(self,*ext_list): + def _delete_files(self, *ext_list): data = self.users['alice'] - self.spawn('',msg_only=True) + self.spawn('', msg_only=True) for ext in ext_list: - get_file_with_ext(data.udir,ext,no_dot=True,delete_all=True) + get_file_with_ext(data.udir, ext, no_dot=True, delete_all=True) return 'ok' def delete_tmp_wallets(self): - return self._delete_files( 'MoneroWallet', 'MoneroWallet.keys', '.akeys' ) + return self._delete_files('MoneroWallet', 'MoneroWallet.keys', '.akeys') def delete_wallets(self): - return self._delete_files( 'MoneroWatchOnlyWallet', '.keys', '.address.txt' ) + return self._delete_files('MoneroWatchOnlyWallet', '.keys', '.address.txt') def delete_tmp_dump_files(self): - return self._delete_files( '.dump' ) + return self._delete_files('.dump') def gen_kafile_miner(self): return self.gen_kafiles(['miner']) @@ -212,7 +212,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): return self.create_wallets_miner() def delete_dump_files(self): - return self._delete_files( '.dump' ) + return self._delete_files('.dump') def fund_alice1(self): return self.fund_alice(wallet=1) @@ -279,7 +279,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): create_transfer_tx2a = create_transfer_tx2 - def _abort_tx(self,expect,send=None,exit_val=None): + def _abort_tx(self, expect, send=None, exit_val=None): self.insert_device_online() t = self.spawn('mmgen-xmrwallet', ['--autosign', 'abort'], exit_val=exit_val) t.expect(expect) @@ -312,40 +312,40 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): + self.autosign_opts + [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}'] + add_opts - + [ op ] - + ([get_file_with_ext(self.asi.xmr_tx_dir,ext)] if ext else []) + + [op] + + ([get_file_with_ext(self.asi.xmr_tx_dir, ext)] if ext else []) + ([wallet_arg] if wallet_arg else []) ) desc_pfx = f'{desc}, ' if desc else '' self.insert_device_online() # device must be removed by calling method - return self.spawn( 'mmgen-xmrwallet', args, extra_desc=f'({desc_pfx}Alice)' ) + return self.spawn('mmgen-xmrwallet', args, extra_desc=f'({desc_pfx}Alice)') - def _sync_chkbal(self,wallet_arg,bal_chk_func): + def _sync_chkbal(self, wallet_arg, bal_chk_func): return self.sync_wallets( 'alice', op = 'sync', wallets = wallet_arg, - bal_chk_func = bal_chk_func ) + bal_chk_func = bal_chk_func) def sync_chkbal1(self): - return self._sync_chkbal( '1', lambda n,b,ub: b == ub and 1 < b < 1.12 ) + return self._sync_chkbal('1', lambda n, b, ub: b == ub and 1 < b < 1.12) # 1.234567891234 - 0.124 = 1.110567891234 (minus fees) def sync_chkbal2(self): - return self._sync_chkbal( '1', lambda n,b,ub: b == ub and 0.8 < b < 0.86 ) + return self._sync_chkbal('1', lambda n, b, ub: b == ub and 0.8 < b < 0.86) # 1.234567891234 - 0.124 - 0.257 = 0.853567891234 (minus fees) def sync_chkbal3(self): return self._sync_chkbal( '1-2', - lambda n,b,ub: b == ub and ((n == 1 and 0.8 < b < 0.86) or (n == 2 and b > 1.23)) ) + lambda n, b, ub: b == ub and ((n == 1 and 0.8 < b < 0.86) or (n == 2 and b > 1.23))) - def _mine_chk(self,desc): - bal_type = {'locked':'b','unlocked':'ub'}[desc] + def _mine_chk(self, desc): + bal_type = {'locked':'b', 'unlocked':'ub'}[desc] return self.mine_chk( 'alice', 1, 0, - lambda x: 0 < getattr(x,bal_type) < 1.234567891234, - f'{desc} balance 0 < 1.234567891234' ) + lambda x: 0 < getattr(x, bal_type) < 1.234567891234, + f'{desc} balance 0 < 1.234567891234') def submit_transfer_tx1(self): return self._submit_transfer_tx() @@ -357,16 +357,16 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): check_bal = False) def submit_transfer_tx2(self): - return self._submit_transfer_tx( relay_parm=self.tx_relay_daemon_parm ) + return self._submit_transfer_tx(relay_parm=self.tx_relay_daemon_parm) - def _submit_transfer_tx(self,relay_parm=None,ext=None,op='submit',check_bal=True): + def _submit_transfer_tx(self, relay_parm=None, ext=None, op='submit', check_bal=True): t = self._xmr_autosign_op( op = op, add_opts = [f'--tx-relay-daemon={relay_parm}'] if relay_parm else [], ext = ext, signable_desc = 'transaction', wait_signed = op == 'submit') - t.expect( f'{op.capitalize()} transaction? (y/N): ', 'y' ) + t.expect(f'{op.capitalize()} transaction? (y/N): ', 'y') t.written_to_file('Submitted transaction') t.read() self.remove_device_online() # device was inserted by _xmr_autosign_op() @@ -395,7 +395,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def export_outputs3(self): return self._export_outputs('1-2', op='export-outputs-sign') - def _import_key_images(self,wallet_arg): + def _import_key_images(self, wallet_arg): t = self._xmr_autosign_op( op = 'import-key-images', wallet_arg = wallet_arg, @@ -413,12 +413,12 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): def txlist(self): self.insert_device_online() - t = self.spawn( 'mmgen-xmrwallet', self.autosign_opts + ['txlist'] ) + t = self.spawn('mmgen-xmrwallet', self.autosign_opts + ['txlist']) t.match_expect_list([ 'SUBMITTED', - 'Network','Submitted', - 'transfer 1:0','-> ext', - 'transfer 1:0','-> ext' + 'Network', 'Submitted', + 'transfer 1:0', '-> ext', + 'transfer 1:0', '-> ext' ]) t.read() self.remove_device_online() @@ -466,7 +466,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded): imsg(f'\nBefore cleaning:\n{before}') imsg(f'\nAfter cleaning:\n{after}') pat = r'xmr/tx: \s*\S+\.subtx \S+\.subtx\s+xmr/outputs:\s*$' - assert re.search( pat, after, re.DOTALL ), f'regex search for {pat} failed' + assert re.search(pat, after, re.DOTALL), f'regex search for {pat} failed' return t def view(self): diff --git a/test/cmdtest_py_d/ct_xmrwallet.py b/test/cmdtest_py_d/ct_xmrwallet.py index e791a1dc..3c2d5d55 100755 --- a/test/cmdtest_py_d/ct_xmrwallet.py +++ b/test/cmdtest_py_d/ct_xmrwallet.py @@ -20,14 +20,14 @@ test.cmdtest_py_d.ct_xmrwallet: xmrwallet tests for the cmdtest.py test suite """ -import sys,os,time,re,atexit,asyncio,shutil -from subprocess import run,PIPE +import sys, os, time, re, atexit, asyncio, shutil +from subprocess import run, PIPE from collections import namedtuple -from mmgen.util import msg,fmt,async_run,capfirst,is_int,die,list_gen +from mmgen.util import msg, fmt, async_run, capfirst, is_int, die, list_gen from mmgen.obj import MMGenRange from mmgen.amt import XMRAmt -from mmgen.addrlist import ViewKeyAddrList,KeyAddrList,AddrIdxList +from mmgen.addrlist import ViewKeyAddrList, KeyAddrList, AddrIdxList from ..include.common import ( cfg, @@ -56,10 +56,10 @@ def stop_daemons(self): def stop_miner_wallet_daemon(self): async_run(self.users['miner'].wd_rpc.stop_daemon()) -def kill_proxy(cls,args): +def kill_proxy(cls, args): if sys.platform in ('linux', 'darwin'): omsg(f'Killing SSH SOCKS server at localhost:{cls.socks_port}') - cmd = [ 'pkill', '-f', ' '.join(args) ] + cmd = ['pkill', '-f', ' '.join(args)] run(cmd) class CmdTestXMRWallet(CmdTestBase): @@ -81,66 +81,66 @@ class CmdTestXMRWallet(CmdTestBase): ('bob', '1378FC64', False, 140, None, ['--restricted-rpc']), ) tx_relay_user = 'bob' - datadir_base = os.path.join('test','daemons','xmrtest') + datadir_base = os.path.join('test', 'daemons', 'xmrtest') cmd_group = ( - ('daemon_version', 'checking daemon version'), - ('gen_kafiles_miner_alice', 'generating key-address files for Miner and Alice'), - ('create_wallets_miner', 'creating Monero wallets (Miner)'), - ('set_label_miner', 'setting an address label (Miner, primary account)'), - ('mine_initial_coins', 'mining initial coins'), - ('create_wallets_alice', 'creating Monero wallets (Alice)'), - ('fund_alice', 'sending funds'), - ('check_bal_alice', 'mining, checking balance'), + ('daemon_version', 'checking daemon version'), + ('gen_kafiles_miner_alice', 'generating key-address files for Miner and Alice'), + ('create_wallets_miner', 'creating Monero wallets (Miner)'), + ('set_label_miner', 'setting an address label (Miner, primary account)'), + ('mine_initial_coins', 'mining initial coins'), + ('create_wallets_alice', 'creating Monero wallets (Alice)'), + ('fund_alice', 'sending funds'), + ('check_bal_alice', 'mining, checking balance'), - ('sync_wallets_all', 'syncing all wallets'), - ('new_account_alice', 'creating a new account (Alice)'), - ('new_account_alice_label', 'creating a new account (Alice, with label)'), - ('new_address_alice', 'creating a new address (Alice)'), - ('new_address_alice_label', 'creating a new address (Alice, with label)'), - ('remove_label_alice', 'removing an address label (Alice, subaddress)'), - ('set_label_alice', 'setting an address label (Alice, subaddress)'), - ('sync_wallets_selected', 'syncing selected wallets'), + ('sync_wallets_all', 'syncing all wallets'), + ('new_account_alice', 'creating a new account (Alice)'), + ('new_account_alice_label', 'creating a new account (Alice, with label)'), + ('new_address_alice', 'creating a new address (Alice)'), + ('new_address_alice_label', 'creating a new address (Alice, with label)'), + ('remove_label_alice', 'removing an address label (Alice, subaddress)'), + ('set_label_alice', 'setting an address label (Alice, subaddress)'), + ('sync_wallets_selected', 'syncing selected wallets'), - ('sweep_to_wallet', 'sweeping to new account in another wallet'), - ('sweep_to_account', 'sweeping to specific account in same wallet'), - ('sweep_to_wallet_account', 'sweeping to specific account in another wallet'), + ('sweep_to_wallet', 'sweeping to new account in another wallet'), + ('sweep_to_account', 'sweeping to specific account in same wallet'), + ('sweep_to_wallet_account', 'sweeping to specific account in another wallet'), ('sweep_to_wallet_account_proxy', 'sweeping to specific account in another wallet (via TX relay + proxy)'), ('sweep_to_same_account_noproxy', 'sweeping to same account (via TX relay, no proxy)'), - ('transfer_to_miner_proxy', 'transferring funds to Miner (via TX relay + proxy)'), - ('transfer_to_miner_noproxy', 'transferring funds to Miner (via TX relay, no proxy)'), + ('transfer_to_miner_proxy', 'transferring funds to Miner (via TX relay + proxy)'), + ('transfer_to_miner_noproxy', 'transferring funds to Miner (via TX relay, no proxy)'), - ('transfer_to_miner_create1', 'transferring funds to Miner (create TX)'), - ('transfer_to_miner_send1', 'transferring funds to Miner (send TX via proxy)'), - ('transfer_to_miner_create2', 'transferring funds to Miner (create TX)'), - ('transfer_to_miner_send2', 'transferring funds to Miner (send TX, no proxy)'), + ('transfer_to_miner_create1', 'transferring funds to Miner (create TX)'), + ('transfer_to_miner_send1', 'transferring funds to Miner (send TX via proxy)'), + ('transfer_to_miner_create2', 'transferring funds to Miner (create TX)'), + ('transfer_to_miner_send2', 'transferring funds to Miner (send TX, no proxy)'), - ('sweep_create_and_send', 'sweeping to new account (create TX + send TX, in stages)'), - ('list_wallets_all', 'listing wallets'), - ('stop_daemons', 'stopping all wallet and coin daemons'), + ('sweep_create_and_send', 'sweeping to new account (create TX + send TX, in stages)'), + ('list_wallets_all', 'listing wallets'), + ('stop_daemons', 'stopping all wallet and coin daemons'), ) - def __init__(self,trunner,cfgs,spawn): - CmdTestBase.__init__(self,trunner,cfgs,spawn) + def __init__(self, trunner, cfgs, spawn): + CmdTestBase.__init__(self, trunner, cfgs, spawn) if trunner is None: return from mmgen.protocol import init_proto - self.proto = init_proto( cfg, 'XMR', network='mainnet' ) + self.proto = init_proto(cfg, 'XMR', network='mainnet') self.extra_opts = ['--wallet-rpc-password=passw0rd'] self.init_users() self.init_daemon_args() for v in self.users.values(): - run(['mkdir','-p',v.udir]) + run(['mkdir', '-p', v.udir]) - self.tx_relay_daemon_parm = 'localhost:{}'.format( self.users[self.tx_relay_user].md.rpc_port ) + self.tx_relay_daemon_parm = 'localhost:{}'.format(self.users[self.tx_relay_user].md.rpc_port) self.tx_relay_daemon_proxy_parm = ( - self.tx_relay_daemon_parm + f':127.0.0.1:{self.socks_port}' ) # must be IP, not 'localhost' + self.tx_relay_daemon_parm + f':127.0.0.1:{self.socks_port}') # must be IP, not 'localhost' if not cfg.no_daemon_stop: - atexit.register(stop_daemons,self) - atexit.register(stop_miner_wallet_daemon,self) + atexit.register(stop_daemons, self) + atexit.register(stop_miner_wallet_daemon, self) if not cfg.no_daemon_autostart: stop_daemons(self) @@ -156,12 +156,12 @@ class CmdTestXMRWallet(CmdTestBase): # init methods @classmethod - def init_proxy(cls,external_call=False): + def init_proxy(cls, external_call=False): def port_in_use(port): import socket try: - socket.create_connection(('localhost',port)).close() + socket.create_connection(('localhost', port)).close() except: return False else: @@ -172,16 +172,16 @@ class CmdTestXMRWallet(CmdTestBase): run(a+b2) omsg(f'SSH SOCKS server started, listening at localhost:{cls.socks_port}') - debug_file = os.path.join('' if external_call else cls.datadir_base,'txrelay-proxy.debug') - a = ['ssh','-x','-o','ExitOnForwardFailure=True','-D',f'localhost:{cls.socks_port}'] - b0 = ['-o','PasswordAuthentication=False'] - b1 = ['localhost','true'] - b2 = ['-fN','-E', debug_file, 'localhost'] + debug_file = os.path.join('' if external_call else cls.datadir_base, 'txrelay-proxy.debug') + a = ['ssh', '-x', '-o', 'ExitOnForwardFailure=True', '-D', f'localhost:{cls.socks_port}'] + b0 = ['-o', 'PasswordAuthentication=False'] + b1 = ['localhost', 'true'] + b2 = ['-fN', '-E', debug_file, 'localhost'] if port_in_use(cls.socks_port): omsg(f'Port {cls.socks_port} already in use. Assuming SSH SOCKS server is running') else: - cp = run(a+b0+b1,stdout=PIPE,stderr=PIPE) + cp = run(a+b0+b1, stdout=PIPE, stderr=PIPE) err = cp.stderr.decode() if err: omsg(err) @@ -189,12 +189,12 @@ class CmdTestXMRWallet(CmdTestBase): if cp.returncode == 0: start_proxy() elif 'onnection refused' in err: - die(2,fmt(""" + die(2, fmt(""" The SSH daemon must be running and listening on localhost in order to test XMR TX relaying via SOCKS proxy. If sshd is not running, please start it. Otherwise, add the line 'ListenAddress 127.0.0.1' to your sshd_config, and then restart the daemon. - """,indent=' ')) + """, indent=' ')) elif 'ermission denied' in err: msg(fmt(f""" In order to test XMR TX relaying via SOCKS proxy, it’s desirable to enable @@ -211,21 +211,21 @@ class CmdTestXMRWallet(CmdTestBase): following command, and restart the test: {' '.join(a+b2)} - """,indent=' ',strip_char='\t')) + """, indent=' ', strip_char='\t')) from mmgen.ui import keypress_confirm - if keypress_confirm(cfg,'Continue?'): + if keypress_confirm(cfg, 'Continue?'): start_proxy() else: - die(1,'Exiting at user request') + die(1, 'Exiting at user request') else: - die(2,fmt(f""" + die(2, fmt(f""" Please start the SSH SOCKS proxy by entering the following command: {' '.join(a+b2)} Then restart the test. - """,indent=' ')) + """, indent=' ')) if not (external_call or cfg.no_daemon_stop): atexit.unregister(kill_proxy) @@ -236,10 +236,10 @@ class CmdTestXMRWallet(CmdTestBase): def init_users(self): from mmgen.daemon import CoinDaemon from mmgen.proto.xmr.daemon import MoneroWalletDaemon - from mmgen.proto.xmr.rpc import MoneroRPCClient,MoneroWalletRPCClient + from mmgen.proto.xmr.rpc import MoneroRPCClient, MoneroWalletRPCClient self.users = {} tmpdir_num = self.tmpdir_nums[0] - ud = namedtuple('user_data',[ + ud = namedtuple('user_data', [ 'sid', 'mmwords', 'autosign', @@ -256,15 +256,16 @@ class CmdTestXMRWallet(CmdTestBase): 'add_coind_args', ]) # kal_range must be None, a single digit, or a single hyphenated range - for ( user, + for ( + user, sid, autosign, shift, kal_range, - add_coind_args ) in self.user_data: - tmpdir = os.path.join('test','tmp',str(tmpdir_num)) - udir = os.path.join(tmpdir,user) - datadir = os.path.join(self.datadir_base,user) + add_coind_args) in self.user_data: + tmpdir = os.path.join('test', 'tmp', str(tmpdir_num)) + udir = os.path.join(tmpdir, user) + datadir = os.path.join(self.datadir_base, user) md = CoinDaemon( cfg = cfg, proto = self.proto, @@ -284,13 +285,13 @@ class CmdTestXMRWallet(CmdTestBase): daemon = md, ) wd = MoneroWalletDaemon( - cfg = cfg, - proto = self.proto, - test_suite = True, - wallet_dir = udir, - user = 'foo', - passwd = 'bar', - port_shift = shift, + cfg = cfg, + proto = self.proto, + test_suite = True, + wallet_dir = udir, + user = 'foo', + passwd = 'bar', + port_shift = shift, monerod_addr = f'127.0.0.1:{md.rpc_port}', ) wd_rpc = MoneroWalletRPCClient( @@ -307,53 +308,53 @@ class CmdTestXMRWallet(CmdTestBase): fn_stem = 'MoneroWallet' kafile_dir = udir self.users[user] = ud( - sid = sid, - mmwords = f'test/ref/{sid}.mmwords', - autosign = autosign, - udir = udir, - datadir = datadir, - kal_range = kal_range, - kafile = f'{kafile_dir}/{sid}-XMR-M[{kal_range}].{kafile_suf}', - walletfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}', - addrfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}.address.txt', - md = md, - md_rpc = md_rpc, - wd = wd, - wd_rpc = wd_rpc, + sid = sid, + mmwords = f'test/ref/{sid}.mmwords', + autosign = autosign, + udir = udir, + datadir = datadir, + kal_range = kal_range, + kafile = f'{kafile_dir}/{sid}-XMR-M[{kal_range}].{kafile_suf}', + walletfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}', + addrfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}.address.txt', + md = md, + md_rpc = md_rpc, + wd = wd, + wd_rpc = wd_rpc, add_coind_args = add_coind_args, ) def init_daemon_args(self): - common_args = ['--p2p-bind-ip=127.0.0.1','--fixed-difficulty=1','--regtest'] # ,'--rpc-ssl-allow-any-cert'] + common_args = ['--p2p-bind-ip=127.0.0.1', '--fixed-difficulty=1', '--regtest'] # --rpc-ssl-allow-any-cert for u in self.users: other_ports = [self.users[u2].md.p2p_port for u2 in self.users if u2 != u] node_args = [f'--add-exclusive-node=127.0.0.1:{p}' for p in other_ports] self.users[u].md.usr_coind_args = ( - common_args + - node_args + - self.users[u].add_coind_args ) + common_args + + node_args + + self.users[u].add_coind_args) # cmd_group methods def daemon_version(self): rpc_port = self.users['miner'].md.rpc_port - return self.spawn( 'mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version'] ) + return self.spawn('mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version']) def gen_kafiles_miner_alice(self): return self.gen_kafiles(['miner', 'alice']) def gen_kafiles(self, users): - for user,data in self.users.items(): + for user, data in self.users.items(): if not user in users: continue - run(['mkdir','-p',data.udir]) - run(f'rm -f {data.kafile}',shell=True) + run(['mkdir', '-p', data.udir]) + run(f'rm -f {data.kafile}', shell=True) t = self.spawn( 'mmgen-keygen', [ '-q', '--accept-defaults', '--coin=xmr', f'--outdir={data.udir}', data.mmwords, data.kal_range ], - extra_desc = f'({capfirst(user)})' ) + extra_desc = f'({capfirst(user)})') t.read() t.ok() t.skip_ok = True @@ -365,15 +366,15 @@ class CmdTestXMRWallet(CmdTestBase): def create_wallets_alice(self): return self.create_wallets('alice') - def create_wallets(self,user,wallet=None,add_opts=[],op='create'): + def create_wallets(self, user, wallet=None, add_opts=[], op='create'): assert wallet is None or is_int(wallet), 'wallet arg' data = self.users[user] stem_glob = data.walletfile_fs.format(wallet or '*') for glob in ( stem_glob, stem_glob + '.keys', - stem_glob + '.address.txt' ): - run( f'rm -f {glob}', shell=True ) + stem_glob + '.address.txt'): + run(f'rm -f {glob}', shell=True) t = self.spawn( 'mmgen-xmrwallet', [f'--wallet-dir={data.udir}'] @@ -393,15 +394,15 @@ class CmdTestXMRWallet(CmdTestBase): ) return t - def new_addr_alice(self,spec,cfg,expect,kafile=None): + def new_addr_alice(self, spec, cfg, expect, kafile=None): data = self.users['alice'] t = self.spawn( 'mmgen-xmrwallet', self.extra_opts + [f'--wallet-dir={data.udir}'] + [f'--daemon=localhost:{data.md.rpc_port}'] - + (['--no-start-wallet-daemon'] if cfg in ('continue','stop') else []) - + (['--no-stop-wallet-daemon'] if cfg in ('start','continue') else []) + + (['--no-start-wallet-daemon'] if cfg in ('continue', 'stop') else []) + + (['--no-stop-wallet-daemon'] if cfg in ('start', 'continue') else []) + ['new', (kafile or data.kafile), spec]) t.expect(expect, 'y', regex=True) return t @@ -434,10 +435,10 @@ class CmdTestXMRWallet(CmdTestBase): async def mine_initial_coins(self): self.spawn('', msg_only=True, extra_desc='(opening wallet)') - await self.open_wallet_user('miner',1) + await self.open_wallet_user('miner', 1) ok() # NB: a large balance is required to avoid ‘insufficient outputs’ error - return await self.mine_chk('miner',1,0,lambda x: x.ub > 2000,'unlocked balance > 2000') + return await self.mine_chk('miner', 1, 0, lambda x: x.ub > 2000, 'unlocked balance > 2000') async def fund_alice(self, wallet=1, amt=1234567891234): self.spawn('', msg_only=True, extra_desc='(transferring funds from Miner wallet)') @@ -451,7 +452,7 @@ class CmdTestXMRWallet(CmdTestBase): async def check_bal_alice(self, wallet=1, bal='1.234567891234'): return await self.mine_chk( 'alice', wallet, 0, - lambda x: str(x.ub) == bal,f'unlocked balance == {bal}', + lambda x: str(x.ub) == bal, f'unlocked balance == {bal}', random_txs = self.dfl_random_txs ) @@ -474,7 +475,7 @@ class CmdTestXMRWallet(CmdTestBase): + cmd_opts + ['label', data.kafile, label_spec] ) - t.expect('(y/N): ','y') + t.expect('(y/N): ', 'y') t.expect(f'Label successfully {expect}') return t @@ -496,7 +497,7 @@ class CmdTestXMRWallet(CmdTestBase): def sync_wallets_miner(self): return self.sync_wallets('miner') - def sync_wallets(self,user,op='sync',wallets=None,add_opts=[],bal_chk_func=None): + def sync_wallets(self, user, op='sync', wallets=None, add_opts=[], bal_chk_func=None): data = self.users[user] if data.autosign: self.insert_device_online() @@ -515,22 +516,22 @@ class CmdTestXMRWallet(CmdTestBase): + ([wallets] if wallets else []) ) wlist = AddrIdxList(wallets) if wallets else MMGenRange(data.kal_range).items - for n,wnum in enumerate(wlist,1): + for n, wnum in enumerate(wlist, 1): t.expect('ing wallet {}/{} ({})'.format( n, len(wlist), os.path.basename(data.walletfile_fs.format(wnum)), )) - if op in ('view','listview'): + if op in ('view', 'listview'): t.expect('Wallet height: ') else: t.expect('Chain height: ') t.expect('Wallet height: ') res = strip_ansi_escapes(t.expect_getend('Balance: ')) if bal_chk_func: - m = re.match( r'(\S+) Unlocked balance: (\S+)', res, re.DOTALL ) + m = re.match(r'(\S+) Unlocked balance: (\S+)', res, re.DOTALL) amts = [XMRAmt(amt) for amt in m.groups()] - assert bal_chk_func(n,*amts), f'balance check for wallet {n} failed!' + assert bal_chk_func(n, *amts), f'balance check for wallet {n} failed!' if data.autosign: t.read() self.remove_device_online() @@ -567,27 +568,24 @@ class CmdTestXMRWallet(CmdTestBase): + [op] + ([] if data.autosign else [data.kafile]) + [arg2], - extra_desc = f'({capfirst(user)}{add_desc})' ) + extra_desc = f'({capfirst(user)}{add_desc})') if op == 'sign': return t if op in ('sweep', 'sweep_all'): desc = 'address' if re.match(r'.*:\d+$', arg2) else 'account' - t.expect( - rf'Create new {desc} .* \(y/N\): ', - ('y','n')[use_existing], - regex=True ) + t.expect(rf'Create new {desc} .* \(y/N\): ', ('y', 'n')[use_existing], regex=True) if use_existing: t.expect(rf'to last existing {desc} .* \(y/N\): ', 'y', regex=True) dtype = 'unsigned' if data.autosign else 'signed' - t.expect(f'Save {dtype} transaction? (y/N): ','y') + t.expect(f'Save {dtype} transaction? (y/N): ', 'y') t.written_to_file(f'{dtype.capitalize()} transaction') if not no_relay: - t.expect(f'Relay {op} transaction? (y/N): ','y') - get_file_with_ext(self.users[user].udir,'sigtx',delete_all=True) + t.expect(f'Relay {op} transaction? (y/N): ', 'y') + get_file_with_ext(self.users[user].udir, 'sigtx', delete_all=True) t.read() @@ -616,22 +614,22 @@ class CmdTestXMRWallet(CmdTestBase): async def transfer_to_miner_proxy(self): addr = read_from_file(self.users['miner'].addrfile_fs.format(2)) amt = '0.135' - self.do_op('transfer','alice',f'2:1:{addr},{amt}',self.tx_relay_daemon_proxy_parm) + self.do_op('transfer', 'alice', f'2:1:{addr},{amt}', self.tx_relay_daemon_proxy_parm) await self.stop_wallet_user('miner') - await self.open_wallet_user('miner',2) - await self.mine_chk('miner',2,0,lambda x: str(x.ub) == amt,f'unlocked balance == {amt}') + await self.open_wallet_user('miner', 2) + await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == amt, f'unlocked balance == {amt}') ok() - return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9') + return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9') async def transfer_to_miner_noproxy(self): addr = read_from_file(self.users['miner'].addrfile_fs.format(2)) self.do_op('transfer', 'alice', f'2:1:{addr},0.0995', self.tx_relay_daemon_parm, add_opts=['--full-address']) - await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2345','unlocked balance == 0.2345') + await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2345', 'unlocked balance == 0.2345') ok() - return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9') + return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9') - def transfer_to_miner_create(self,amt): - get_file_with_ext(self.users['alice'].udir,'sigtx',delete_all=True) + def transfer_to_miner_create(self, amt): + get_file_with_ext(self.users['alice'].udir, 'sigtx', delete_all=True) addr = read_from_file(self.users['miner'].addrfile_fs.format(2)) return self.do_op('transfer', 'alice', f'2:1:{addr},{amt}', no_relay=True, do_ret=True, add_opts=['-Ee']) @@ -641,31 +639,31 @@ class CmdTestXMRWallet(CmdTestBase): def transfer_to_miner_create2(self): return self.transfer_to_miner_create('0.0012') - def relay_tx(self,relay_opt,add_desc=None): + def relay_tx(self, relay_opt, add_desc=None): user = 'alice' data = self.users[user] add_desc = (', ' + add_desc) if add_desc else '' t = self.spawn( 'mmgen-xmrwallet', self.extra_opts - + [ relay_opt, 'relay', get_file_with_ext(data.udir,'sigtx') ], - extra_desc = f'(relaying TX, {capfirst(user)}{add_desc})' ) - t.expect('Relay transaction? ','y') + + [relay_opt, 'relay', get_file_with_ext(data.udir, 'sigtx')], + extra_desc = f'(relaying TX, {capfirst(user)}{add_desc})') + t.expect('Relay transaction? ', 'y') t.read() t.ok() return t async def transfer_to_miner_send1(self): - self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_proxy_parm}',add_desc='via proxy') - await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2456','unlocked balance == 0.2456') + self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_proxy_parm}', add_desc='via proxy') + await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2456', 'unlocked balance == 0.2456') ok() - return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9') + return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9') async def transfer_to_miner_send2(self): - self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_parm}',add_desc='no proxy') - await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2468','unlocked balance == 0.2468') + self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_parm}', add_desc='no proxy') + await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2468', 'unlocked balance == 0.2468') ok() - return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9') + return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9') async def sweep_create_and_send(self): get_file_with_ext(self.users['alice'].udir, 'sigtx', delete_all=True) @@ -680,7 +678,7 @@ class CmdTestXMRWallet(CmdTestBase): # wallet methods - async def open_wallet_user(self,user,wnum): + async def open_wallet_user(self, user, wnum): data = self.users[user] if data.autosign: self.insert_device_online() @@ -691,7 +689,7 @@ class CmdTestXMRWallet(CmdTestBase): proto = self.proto, addrfile = data.kafile, skip_chksum_msg = True, - key_address_validity_check = False ) + key_address_validity_check = False) end_silence() if data.autosign: self.do_umount_online() @@ -700,9 +698,9 @@ class CmdTestXMRWallet(CmdTestBase): return data.wd_rpc.call( 'open_wallet', filename = os.path.basename(data.walletfile_fs.format(wnum)), - password = kal.entry(wnum).wallet_passwd ) + password = kal.entry(wnum).wallet_passwd) - async def stop_wallet_user(self,user): + async def stop_wallet_user(self, user): await self.users[user].wd_rpc.stop_daemon(silent=not (cfg.exact_output or cfg.verbose)) return 'ok' @@ -725,7 +723,7 @@ class CmdTestXMRWallet(CmdTestBase): await self.start_mining() else: raise - die(2,'Restart attempt limit exceeded') + die(2, 'Restart attempt limit exceeded') async def mine10(self): return await self.mine(10) @@ -736,7 +734,7 @@ class CmdTestXMRWallet(CmdTestBase): async def mine100(self): return await self.mine(100) - async def mine(self,nblks): + async def mine(self, nblks): start_height = height = await self._get_height() imsg(f'Height: {height}') imsg_r(f'Mining {nblks} blocks...') @@ -761,7 +759,7 @@ class CmdTestXMRWallet(CmdTestBase): do_background_mining = False, # run mining in background or foreground ignore_battery = True, # ignore battery state (on laptop) miner_address = addr, # account address to mine to - threads_count = 1 ) # number of mining threads to run + threads_count = 1) # number of mining threads to run status = self.get_status(ret) if status == 'OK': return True @@ -769,8 +767,8 @@ class CmdTestXMRWallet(CmdTestBase): await asyncio.sleep(5) omsg('Daemon busy. Attempting to start mining...') else: - die(2,f'Monerod returned status {status}') - die(2,'Max retries exceeded') + die(2, f'Monerod returned status {status}') + die(2, 'Max retries exceeded') async def stop_mining(self): ret = self.users['miner'].md_rpc.call_raw('stop_mining') @@ -786,7 +784,7 @@ class CmdTestXMRWallet(CmdTestBase): test2 = None, test2_desc = None, random_txs = None, - return_bal = False ): + return_bal = False): """ - open destination wallet @@ -800,7 +798,7 @@ class CmdTestXMRWallet(CmdTestBase): async def send_random_txs(): from mmgen.tool.api import tool_api t = tool_api(cfg) - t.init_coin('XMR','mainnet') + t.init_coin('XMR', 'mainnet') t.usr_randchars = 0 imsg_r('Sending random transactions: ') for i in range(random_txs): @@ -814,7 +812,7 @@ class CmdTestXMRWallet(CmdTestBase): await asyncio.sleep(0.5) imsg('') - def print_balance(dest,bal_info): + def print_balance(dest, bal_info): imsg('Total balances in {}’s wallet {}, account #{}: {} (total), {} (unlocked)'.format( capfirst(dest.user), dest.wnum, @@ -823,32 +821,31 @@ class CmdTestXMRWallet(CmdTestBase): bal_info.ub.hl(), )) - async def get_balance(dest,count): + async def get_balance(dest, count): data = self.users[dest.user] data.wd_rpc.call('refresh') if count and not count % 20: data.wd_rpc.call('rescan_blockchain') ret = data.wd_rpc.call('get_accounts')['subaddress_accounts'][dest.account] - d_tup = namedtuple('bal_info',['b','ub']) + d_tup = namedtuple('bal_info', ['b', 'ub']) return d_tup( - b = XMRAmt(ret['balance'],from_unit='atomic'), - ub = XMRAmt(ret['unlocked_balance'],from_unit='atomic') - ) + b = XMRAmt(ret['balance'], from_unit='atomic'), + ub = XMRAmt(ret['unlocked_balance'], from_unit='atomic')) # start execution: self.do_msg(extra_desc = (f'sending {random_txs} random TXs, ' if random_txs else '') + - f'mining, checking wallet {user}:{wnum}:{account}' ) + f'mining, checking wallet {user}:{wnum}:{account}') dest = namedtuple( - 'dest_info',['user','wnum','account','test','test_desc','test2','test2_desc'])( - user,wnum,account,test,test_desc,test2,test2_desc) + 'dest_info', ['user', 'wnum', 'account', 'test', 'test_desc', 'test2', 'test2_desc'])( + user, wnum, account, test, test_desc, test2, test2_desc) if dest.user != 'miner': - await self.open_wallet_user(dest.user,dest.wnum) + await self.open_wallet_user(dest.user, dest.wnum) - bal_info_start = await get_balance(dest,0) + bal_info_start = await get_balance(dest, 0) chk_bal_chg = dest.test(bal_info_start) == 'chk_bal_chg' if random_txs: @@ -859,16 +856,16 @@ class CmdTestXMRWallet(CmdTestBase): h = await self._get_height() imsg_r(f'Chain height: {h} ') - max_iterations,min_height = (300,64) if sys.platform == 'win32' else (50,300) + max_iterations, min_height = (300, 64) if sys.platform == 'win32' else (50, 300) verbose = False for count in range(max_iterations): - bal_info = await get_balance(dest,count) + bal_info = await get_balance(dest, count) if h > min_height: if dest.test(bal_info) is True or (chk_bal_chg and bal_info.ub != bal_info_start.ub): imsg('') oqmsg_r('+') - print_balance(dest,bal_info) + print_balance(dest, bal_info) if dest.test2: assert dest.test2(bal_info) is True, f'test failed: {dest.test2_desc} ({bal_info})' break @@ -878,13 +875,13 @@ class CmdTestXMRWallet(CmdTestBase): if not verbose: imsg('') imsg_r(f'Height: {h}, ') - print_balance(dest,bal_info) + print_balance(dest, bal_info) verbose = True else: imsg_r(f'{h} ') oqmsg_r('+') else: - die(2,f'Timeout exceeded, balance {bal_info.ub!r}') + die(2, f'Timeout exceeded, balance {bal_info.ub!r}') await self.stop_mining() @@ -895,26 +892,26 @@ class CmdTestXMRWallet(CmdTestBase): # util methods - def get_status(self,ret): + def get_status(self, ret): if ret['status'] != 'OK': - imsg( 'RPC status: {}'.format( ret['status'] )) + imsg('RPC status: {}'.format(ret['status'])) return ret['status'] - def do_msg(self,extra_desc=None): + def do_msg(self, extra_desc=None): self.spawn( '', msg_only = True, extra_desc = f'({extra_desc})' if extra_desc else None ) - async def transfer(self,user,amt,addr): - return self.users[user].wd_rpc.call('transfer',destinations=[{'amount':amt,'address':addr}]) + async def transfer(self, user, amt, addr): + return self.users[user].wd_rpc.call('transfer', destinations=[{'amount':amt, 'address':addr}]) # daemon start/stop methods def start_daemons(self): for v in self.users.values(): - run(['mkdir','-p',v.datadir]) + run(['mkdir', '-p', v.datadir]) v.md.start() def stop_daemons(self): diff --git a/test/cmdtest_py_d/input.py b/test/cmdtest_py_d/input.py index 200f47b9..48b49018 100755 --- a/test/cmdtest_py_d/input.py +++ b/test/cmdtest_py_d/input.py @@ -14,13 +14,13 @@ import time from .common import randbool from ..include.common import getrand -def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False): +def stealth_mnemonic_entry(t, mne, mn, entry_mode, pad_entry=False): - def pad_mnemonic(mn,ss_len): + def pad_mnemonic(mn, ss_len): def get_pad_chars(n): ret = '' for _ in range(n): - m = int.from_bytes(getrand(1),'big') % 32 + m = int.from_bytes(getrand(1), 'big') % 32 ret += r'123579!@#$%^&*()_+-=[]{}"?/,.<>|'[m] return ret ret = [] @@ -36,13 +36,13 @@ def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False): w += '\n' else: w = get_pad_chars(1) + w[0] + get_pad_chars(1) + w[1:] - elif len(w) > (3,5)[ss_len==12]: + elif len(w) > (3, 5)[ss_len==12]: w = w + '\n' else: w = ( get_pad_chars(2 if randbool() and entry_mode != 'short' else 0) + w[0] + get_pad_chars(2) + w[1:] - + get_pad_chars(9) ) + + get_pad_chars(9)) w = w[:ss_len+1] ret.append(w) return ret @@ -57,22 +57,22 @@ def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False): else: yield w[0] + 'z\b' + '#' * (ssl-len(w)) + w[1:] mn = list(gen_mn()) - elif entry_mode in ('full','short'): - mn = ['fzr'] + mn[:5] + ['grd','grdbxm'] + mn[5:] - mn = pad_mnemonic(mn,mne.em.ss_len) + elif entry_mode in ('full', 'short'): + mn = ['fzr'] + mn[:5] + ['grd', 'grdbxm'] + mn[5:] + mn = pad_mnemonic(mn, mne.em.ss_len) mn[10] = '@#$%*##' + mn[10] wnum = 1 - p_ok,p_err = mne.word_prompt + p_ok, p_err = mne.word_prompt for w in mn: - ret = t.expect((p_ok.format(wnum),p_err.format(wnum-1))) + ret = t.expect((p_ok.format(wnum), p_err.format(wnum-1))) if ret == 0: wnum += 1 for char in w: t.send(char) time.sleep(0.005) -def user_dieroll_entry(t,data): +def user_dieroll_entry(t, data): for s in data: - t.expect(r'Enter die roll #.+: ',s,regex=True) + t.expect(r'Enter die roll #.+: ', s, regex=True) time.sleep(0.005)