From 1682bd16d3ef064e261316b0794eca6f32e8acb9 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Tue, 18 Apr 2023 18:35:56 +0000 Subject: [PATCH] autosign,xmrwallet: various fixes and cleanups --- mmgen/autosign.py | 16 ++++++------ mmgen/exception.py | 1 + mmgen/xmrwallet.py | 48 ++++++++++++++++++++++++++++------ test/test_py_d/ts_autosign.py | 43 ++++++++++++++++-------------- test/test_py_d/ts_xmrwallet.py | 24 ++++++++++++++--- 5 files changed, 92 insertions(+), 40 deletions(-) diff --git a/mmgen/autosign.py b/mmgen/autosign.py index 984824e9..871a0457 100755 --- a/mmgen/autosign.py +++ b/mmgen/autosign.py @@ -70,19 +70,18 @@ class Autosign: cfg.outdir = self.tx_dir cfg.passwd_file = self.keyfile - async def check_daemons_running(self): - - if 'coin' in self.cfg._uopts: + if 'coin' in cfg._uopts: die(1,'--coin option not supported with this command. Use --coins instead') - if self.cfg.coins: - coins = self.cfg.coins.upper().split(',') + if cfg.coins: + self.coins = cfg.coins.upper().split(',') else: ymsg('Warning: no coins specified, defaulting to BTC') - coins = ['BTC'] + self.coins = ['BTC'] + async def check_daemons_running(self): from .protocol import init_proto - for coin in coins: + for coin in self.coins: proto = init_proto( self.cfg, coin, testnet=self.cfg.network=='testnet', need_amt=True ) if proto.sign_mode == 'daemon': self.cfg._util.vmsg(f'Checking {coin} daemon') @@ -92,6 +91,7 @@ class Autosign: await rpc_init( self.cfg, proto ) except SocketError as e: die(2,f'{coin} daemon not running or not listening on port {proto.rpc_port}') + @property def wallet_files(self): @@ -126,7 +126,7 @@ class Autosign: self.have_msg_dir = os.path.isdir(self.msg_dir) - from stat import S_ISDIR,S_IWUSR,S_IRUSR + from stat import S_ISDIR,S_IWUSR,S_IRUSR for cdir in [self.tx_dir] + ([self.msg_dir] if self.have_msg_dir else []): try: ds = os.stat(cdir) diff --git a/mmgen/exception.py b/mmgen/exception.py index 132bb3b5..8e5db8a3 100755 --- a/mmgen/exception.py +++ b/mmgen/exception.py @@ -65,6 +65,7 @@ class TransactionChainMismatch(Exception):mmcode = 2 class ObjectInitError(Exception): mmcode = 2 class ClassFlagsError(Exception): mmcode = 2 class ExtensionModuleError(Exception): mmcode = 2 +class MoneroMMGenTXFileParseError(Exception): mmcode = 2 # 3: yellow hl, 'MMGen Error' + exception + message class RPCFailure(Exception): mmcode = 3 diff --git a/mmgen/xmrwallet.py b/mmgen/xmrwallet.py index 50d623a9..e373eb6f 100755 --- a/mmgen/xmrwallet.py +++ b/mmgen/xmrwallet.py @@ -102,6 +102,15 @@ class XMRWalletAddrSpec(str,Hilite,InitErrors,MMGenObject): except Exception as e: return cls.init_fail(e,me) +def is_xmr_tx_file(cfg,fn): + try: + MoneroMMGenTX.Completed(cfg,fn) + return True + except Exception as e: + if not 'MoneroMMGenTXFileParseError' in type(e).__name__: + ymsg(f'\n{type(e).__name__}: {e}') + return False + class MoneroMMGenTX: class Base: @@ -250,15 +259,25 @@ class MoneroMMGenTX: metadata = d.metadata, ) - class Signed(Base): + class Completed(Base): + name = 'completed' def __init__(self,cfg,fn): - from .fileutil import get_data_from_file + self.cfg = cfg self.fn = fn - d_wrap = json.loads(get_data_from_file( cfg, fn ))['MoneroMMGenTX'] + + from .fileutil import get_data_from_file + + try: + d_wrap = json.loads(get_data_from_file( cfg, fn ))['MoneroMMGenTX'] + except Exception as e: + die( 'MoneroMMGenTXFileParseError', f'{type(e).__name__}: {e}\nCould not load transaction file' ) + d = self.xmrwallet_tx_data(**d_wrap['data']) + proto = init_proto( cfg, 'xmr', network=d.network, need_amt=True ) + self.data = self.xmrwallet_tx_data( op = d.op, create_time = d.create_time, @@ -279,9 +298,22 @@ class MoneroMMGenTX: b = d_wrap[k] assert a == b, f'{k} mismatch: {a} != {b}' + class Signed(Completed): + name = 'signed' + class MoneroWalletOps: - ops = ('create','sync','list','new','transfer','sweep','relay','txview','label') + ops = ( + 'create', + 'sync', + 'list', + 'new', + 'transfer', + 'sweep', + 'relay', + 'txview', + 'label' ) + opts = ( 'wallet_dir', 'daemon', @@ -291,8 +323,8 @@ class MoneroWalletOps: 'restore_height', 'no_start_wallet_daemon', 'no_stop_wallet_daemon', - 'no_relay', - ) + 'no_relay' ) + pat_opts = ('daemon','tx_relay_daemon') class base(MMGenObject): @@ -441,11 +473,11 @@ class MoneroWalletOps: if not self.cfg.no_stop_wallet_daemon: await self.c.stop_daemon() - def get_wallet_fn(self,d): + def get_wallet_fn(self,data): return os.path.join( self.cfg.wallet_dir or '.','{a}-{b}-MoneroWallet{c}'.format( a = self.kal.al_id.sid, - b = d.idx, + b = data.idx, c = f'.{self.cfg.network}' if self.cfg.network != 'mainnet' else '')) async def main(self): diff --git a/test/test_py_d/ts_autosign.py b/test/test_py_d/ts_autosign.py index fafcf712..854032b5 100755 --- a/test/test_py_d/ts_autosign.py +++ b/test/test_py_d/ts_autosign.py @@ -53,16 +53,16 @@ def init_led(simulate): if fn: run(['sudo','chmod','0666',fn],check=True) -def check_mountpoint(mountpoint,txdir): - if not os.path.ismount(mountpoint): +def check_mountpoint(asi): + if not os.path.ismount(asi.mountpoint): try: - run(['mount',mountpoint],check=True) - imsg(f'Mounted {mountpoint}') + run(['mount',asi.mountpoint],check=True) + imsg(f'Mounted {asi.mountpoint}') except: - die(2,f'Could not mount {mountpoint}! Exiting') + die(2,f'Could not mount {asi.mountpoint}! Exiting') - if not os.path.isdir(txdir): - die(2,f'Directory {txdir} does not exist! Exiting') + if not os.path.isdir(asi.tx_dir): + die(2,f'Directory {asi.tx_dir} does not exist! Exiting') def do_mount(mountpoint): if not os.path.ismount(mountpoint): @@ -78,6 +78,7 @@ class TestSuiteAutosignBase(TestSuiteBase): networks = ('btc',) tmpdir_nums = [18] color = True + mountpoint_basename = 'mmgen_autosign' def __init__(self,trunner,cfgs,spawn): @@ -92,8 +93,14 @@ class TestSuiteAutosignBase(TestSuiteBase): self.network_ids = [c+'_tn' for c in self.daemon_coins] + self.daemon_coins self.asi = Autosign( - AutosignConfig() + AutosignConfig({ + 'mountpoint': ( + None if self.live else + os.path.join(self.tmpdir,self.mountpoint_basename) + ) + }) ) + self.mountpoint = self.asi.mountpoint if self.simulate and not cfg.exact_output: die(1,red('This command must be run with --exact-output enabled!')) @@ -102,21 +109,17 @@ class TestSuiteAutosignBase(TestSuiteBase): os.environ['MMGEN_TEST_SUITE_AUTOSIGN_LED_SIMULATE'] = '1' LEDControl.create_dummy_control_files() + self.opts = ['--coins='+','.join(self.coins)] + if self.live: - self.mountpoint = self.asi.mountpoint - self.opts = ['--coins='+','.join(self.coins)] - check_mountpoint( self.mountpoint, self.asi.tx_dir ) + check_mountpoint(self.asi) init_led(self.simulate) else: - self.mountpoint = self.tmpdir - try: - os.mkdir(joinpath(self.mountpoint,'tx')) - except: - pass - self.opts = [ - '--coins='+','.join(self.coins), - '--mountpoint='+self.mountpoint, - '--no-insert-check' ] + os.makedirs(self.asi.tx_dir,exist_ok=True) # creates mountpoint + self.opts.extend([ + '--mountpoint=' + self.mountpoint, + '--no-insert-check', + ]) self.tx_file_ops('set_count') # initialize tx_count here so we can resume anywhere diff --git a/test/test_py_d/ts_xmrwallet.py b/test/test_py_d/ts_xmrwallet.py index 05e9ffc3..83f24872 100755 --- a/test/test_py_d/ts_xmrwallet.py +++ b/test/test_py_d/ts_xmrwallet.py @@ -218,7 +218,7 @@ class TestSuiteXMRWallet(TestSuiteBase): 'add_coind_args', ]) # kal_range must be None, a single digit, or a single hyphenated range - for ( user, + for ( user, sid, shift, kal_range, @@ -322,7 +322,13 @@ class TestSuiteXMRWallet(TestSuiteBase): dir_opt = [f'--wallet-dir={data.udir}'] t = self.spawn( 'mmgen-xmrwallet', - self.extra_opts + add_opts + dir_opt + [ 'create', data.kafile, (wallet or data.kal_range) ] ) + self.extra_opts + + add_opts + + dir_opt + + ['create'] + + [data.kafile] + + [wallet or data.kal_range] + ) for i in MMGenRange(wallet or data.kal_range).items: write_data_to_file( cfg, @@ -427,7 +433,13 @@ class TestSuiteXMRWallet(TestSuiteBase): ) t = self.spawn( 'mmgen-xmrwallet', - self.extra_opts + cmd_opts + add_opts + [ op, data.kafile ] + ([wallets] if wallets else []) ) + self.extra_opts + + cmd_opts + + add_opts + + [op] + + [data.kafile] + + ([wallets] if wallets else []) + ) wlist = AddrIdxList(wallets) if wallets else MMGenRange(data.kal_range).items for n,wnum in enumerate(wlist): t.expect('Syncing wallet {}/{} ({})'.format( @@ -460,7 +472,11 @@ class TestSuiteXMRWallet(TestSuiteBase): t = self.spawn( 'mmgen-xmrwallet', - self.extra_opts + cmd_opts + [ op, data.kafile, arg2 ], + self.extra_opts + + cmd_opts + + [op] + + [data.kafile] + + [arg2], extra_desc = f'({capfirst(user)}{add_desc})' ) if op == 'sweep':