Browse Source

autosign,xmrwallet: various fixes and cleanups

The MMGen Project 2 years ago
parent
commit
1682bd16d3
5 changed files with 92 additions and 40 deletions
  1. 8 8
      mmgen/autosign.py
  2. 1 0
      mmgen/exception.py
  3. 40 8
      mmgen/xmrwallet.py
  4. 23 20
      test/test_py_d/ts_autosign.py
  5. 20 4
      test/test_py_d/ts_xmrwallet.py

+ 8 - 8
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)

+ 1 - 0
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

+ 40 - 8
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):

+ 23 - 20
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
 

+ 20 - 4
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':