Browse Source

MMGEN_DEBUG_ALL env var; tw display and other fixes

MMGen 7 years ago
parent
commit
b230b43d4b
9 changed files with 78 additions and 44 deletions
  1. 2 2
      mmgen/addr.py
  2. 7 1
      mmgen/common.py
  3. 2 2
      mmgen/crypto.py
  4. 1 0
      mmgen/globalvars.py
  5. 13 9
      mmgen/main_wallet.py
  6. 6 1
      mmgen/opts.py
  7. 12 10
      mmgen/tw.py
  8. 1 1
      test/mmgen_pexpect.py
  9. 34 18
      test/test.py

+ 2 - 2
mmgen/addr.py

@@ -28,7 +28,7 @@ from mmgen.obj import *
 pnm = g.proj_name
 
 def dmsg_sc(desc,data):
-	if g.debug_addrlist: Msg('sc_debug_{}: {}'.format(desc,data))
+	if g.debug_addrlist: Msg(u'sc_debug_{}: {}'.format(desc,data))
 
 class AddrGenerator(MMGenObject):
 	def __new__(cls,addr_type):
@@ -446,7 +446,7 @@ Removed {{}} duplicate WIF key{{}} from keylist (also in {pnm} key-address file
 				dmsg('Key {:>03}: {}'.format(pos,e.passwd))
 
 			out.append(e)
-			if g.debug: Msg('generate():\n{}'.format(e.pformat()))
+			if g.debug_addrlist: Msg('generate():\n{}'.format(e.pformat()))
 
 		qmsg('\r{}: {} {}{} generated{}'.format(
 				self.al_id.hl(),t_addrs,self.gen_desc,suf(t_addrs,self.gen_desc_pl),' '*15))

+ 7 - 1
mmgen/common.py

@@ -20,12 +20,18 @@
 common.py:  Common imports for all MMGen scripts
 """
 
-import sys
+import sys,os
 from mmgen.globalvars import g
 import mmgen.opts as opts
 from mmgen.opts import opt
 from mmgen.util import *
 
+def set_debug_all():
+	if os.getenv('MMGEN_DEBUG_ALL'):
+		for name in g.env_opts:
+			if name[:11] == 'MMGEN_DEBUG':
+				os.environ[name] = '1'
+
 def help_notes(k):
 	from mmgen.seed import SeedSource
 	return {

+ 2 - 2
mmgen/crypto.py

@@ -45,8 +45,8 @@ def sha256_rounds(s,n):
 def scramble_seed(seed,scramble_key,hash_rounds):
 	import hmac
 	scr_seed = hmac.new(seed,scramble_key,sha256).digest()
-	fs = 'Seed:  {}\nScramble key: {}\nScrambled seed: {}'
-	dmsg(fs.format(hexlify(seed),scramble_key,hexlify(scr_seed)))
+	fs = u'Seed:  {}\nScramble key: {}\nScrambled seed: {}'
+	dmsg(fs.format(hexlify(seed),scramble_key.decode('utf8'),hexlify(scr_seed)))
 	return sha256_rounds(scr_seed,hash_rounds)
 
 def encrypt_seed(seed,key):

+ 1 - 0
mmgen/globalvars.py

@@ -138,6 +138,7 @@ class g(object):
 	)
 	env_opts = (
 		'MMGEN_BOGUS_WALLET_DATA',
+		'MMGEN_DEBUG_ALL',
 		'MMGEN_DEBUG',
 		'MMGEN_DEBUG_OPTS',
 		'MMGEN_DEBUG_RPC',

+ 13 - 9
mmgen/main_wallet.py

@@ -142,11 +142,9 @@ if invoked_as == 'passchg':
 		if getattr(ss_out.ssdata,k) != getattr(ss_in.ssdata,k)]):
 		die(1,'Password, hash preset and label are unchanged.  Taking no action')
 
-m1 = yellow('Confirmation of default wallet update')
-m2 = 'update the default wallet'
-m3 = 'Make this wallet your default and move it to the data directory?'
-
 if invoked_as == 'passchg' and ss_in.infile.dirname == g.data_dir:
+	m1 = yellow('Confirmation of default wallet update')
+	m2 = 'update the default wallet'
 	confirm_or_exit(m1,m2,exit_msg='Password not changed')
 	ss_out.write_to_file(desc='New wallet',outdir=g.data_dir)
 	msg('Securely deleting old wallet')
@@ -156,13 +154,19 @@ if invoked_as == 'passchg' and ss_in.infile.dirname == g.data_dir:
 		check_output(sd_cmd + [ss_in.infile.name])
 	except:
 		ymsg("WARNING: '{}' command failed, using regular file delete instead".format(sd_cmd[0]))
-#		msg('Command output: {}\nReturn value {}'.format(e.output,e.returncode))
 		os.unlink(ss_in.infile.name)
-elif invoked_as == 'gen' and not find_file_in_dir(Wallet,g.data_dir) \
-	and not opt.stdout and keypress_confirm(m3,default_yes=True):
-	ss_out.write_to_file(outdir=g.data_dir)
 else:
-	ss_out.write_to_file()
+	try:
+		assert invoked_as == 'gen','dw'
+		assert not opt.stdout,'dw'
+		assert not find_file_in_dir(Wallet,g.data_dir),'dw'
+		m = 'Make this wallet your default and move it to the data directory?'
+		assert keypress_confirm(m,default_yes=True),'dw'
+	except Exception as e:
+		if e[0] != 'dw': raise
+		ss_out.write_to_file()
+	else:
+		ss_out.write_to_file(outdir=g.data_dir)
 
 if invoked_as == 'passchg':
 	if ss_out.ssdata.passwd == ss_in.ssdata.passwd:

+ 6 - 1
mmgen/opts.py

@@ -58,7 +58,6 @@ def opt_preproc_debug(short_opts,long_opts,skipped_opts,uopts,args):
 	for e in d: Msg('    {:<20}: {}'.format(*e))
 
 def opt_postproc_debug():
-	opt.verbose,opt.quiet = True,None
 	a = [k for k in dir(opt) if k[:2] != '__' and getattr(opt,k) != None]
 	b = [k for k in dir(opt) if k[:2] != '__' and getattr(opt,k) == None]
 	Msg('    Opts after processing:')
@@ -164,6 +163,7 @@ def override_from_cfg_file(cfg_data):
 def override_from_env():
 	from mmgen.util import set_for_type
 	for name in g.env_opts:
+		if name == 'MMGEN_DEBUG_ALL': continue
 		idx,invert_bool = ((6,False),(14,True))[name[:14]=='MMGEN_DISABLE_']
 		val = os.getenv(name) # os.getenv() returns None if env var is unset
 		if val: # exclude empty string values too
@@ -237,6 +237,9 @@ def init(opts_f,add_opts=[],opt_filter=None):
 
 	if opt.version: Die(0,version_info)
 
+	from mmgen.common import set_debug_all
+	set_debug_all()
+
 	# === Interaction with global vars begins here ===
 
 	# NB: user opt --data-dir is actually g.data_dir_root
@@ -313,6 +316,8 @@ def init(opts_f,add_opts=[],opt_filter=None):
 		ymsg("Warning: config file options have changed! See '{}' for details".format(g.cfg_file+'.sample'))
 		my_raw_input('Hit ENTER to continue: ')
 
+	if g.debug and g.prog_name != 'test.py':
+		opt.verbose,opt.quiet = True,None
 	if g.debug_opts: opt_postproc_debug()
 
 	# We don't need this data anymore

+ 12 - 10
mmgen/tw.py

@@ -104,7 +104,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
 			'age':   lambda i: 0 - i.confs,
 			'amt':   lambda i: i.amt,
 			'txid':  lambda i: '{} {:04}'.format(i.txid,i.vout),
-			'mmid':  lambda i: i.twmmid.sort_key
+			'twmmid':  lambda i: i.twmmid.sort_key
 		}
 		key = key or self.sort_key
 		if key not in sort_funcs:
@@ -142,12 +142,14 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
 		col1_w = max(3,len(str(len(unsp)))+1) # num + ')'
 		mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in unsp) or 12 # DEADBEEF:S:1
 		max_acct_w = max(len(i.label) for i in unsp) + mmid_w + 1
-		addr_w = min(max(len(i.addr) for i in unsp)+(0,1+max_acct_w)[self.show_mmid],self.cols-45)
-		acct_w = min(max_acct_w, max(24,int(addr_w-10)))
+		max_btcaddr_w = max(len(i.addr) for i in unsp)
+		min_addr_w = self.cols - 38
+		addr_w = min(max_btcaddr_w + (0,1+max_acct_w)[self.show_mmid],min_addr_w)
+		acct_w = min(max_acct_w, max(24,addr_w-10))
 		btaddr_w = addr_w - acct_w - 1
 		label_w = acct_w - mmid_w - 1
-		tx_w = max(11,min(64, self.cols-addr_w-28-col1_w))
-		txdots = ('','...')[tx_w < 64]
+		tx_w = min(64,self.cols-addr_w-28-col1_w) # min=7
+		txdots = ('','..')[tx_w < 64]
 
 		for i in unsp: i.skip = None
 		if self.group and (self.sort_key in ('addr','txid','twmmid')):
@@ -162,13 +164,13 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
 			out += [green('Chain: {}'.format(g.chain.upper()))]
 		fs = ' {:%s} {:%s} {:2} {} {} {:<}' % (col1_w,tx_w)
 		out += [fs.format('Num',
-				'TX id'.ljust(tx_w - 5) + ' Vout', '',
-				'Address'.ljust(addr_w+3),
-				'Amt({})'.format(g.coin).ljust(10),
+				'TXid'.ljust(tx_w - 5) + ' Vout', '',
+				'Address'.ljust(addr_w),
+				'Amt({})'.format(g.coin).ljust(12),
 				('Confs','Age(d)')[self.show_days])]
 
 		for n,i in enumerate(unsp):
-			addr_dots = '|' + '.'*33
+			addr_dots = '|' + '.'*(addr_w-1)
 			mmid_disp = MMGenID.fmtc('.'*mmid_w if i.skip=='addr'
 				else i.twmmid if i.twmmid.type=='mmgen'
 					else 'Non-{}'.format(g.proj_name),width=mmid_w,color=True)
@@ -284,7 +286,7 @@ Display options: show [D]ays, [g]roup, show [m]mgen addr, r[e]draw screen
 						msg('{}\n{}\n{}'.format(self.fmt_display,prompt,p))
 					else:
 						msg('Label could not be added\n{}\n{}'.format(prompt,p))
-			elif reply == 'M': self.do_sort('mmid'); self.show_mmid = True
+			elif reply == 'M': self.do_sort('twmmid'); self.show_mmid = True
 			elif reply == 'm': self.show_mmid = not self.show_mmid
 			elif reply == 'p':
 				msg('')

+ 1 - 1
test/mmgen_pexpect.py

@@ -67,7 +67,7 @@ def my_expect(p,s,t='',delay=send_delay,regex=False,nonl=False,silent=False):
 		sys.exit(1)
 	debug_pexpect_msg(p)
 
-	if opt.debug or (opt.verbose and type(s) != str):
+	if opt.verbose and type(s) != str:
 		msg_r(' ==> {} '.format(ret))
 
 	if ret == -1:

+ 34 - 18
test/test.py

@@ -31,6 +31,8 @@ from mmgen.common import *
 from mmgen.test import *
 from mmgen.protocol import CoinProtocol
 
+set_debug_all()
+
 g.quiet = False # if 'quiet' was set in config file, disable here
 os.environ['MMGEN_QUIET'] = '0' # and for the spawned scripts
 
@@ -115,7 +117,6 @@ opts_data = lambda: {
 -b, --buf-keypress  Use buffered keypresses as with real human input
 -c, --print-cmdline Print the command line of each spawned command
 -C, --coverage      Produce code coverage info using trace module
--d, --debug-scripts Turn on debugging output in executed scripts
 -x, --debug-pexpect Produce debugging output for pexpect calls
 -D, --direct-exec   Bypass pexpect and execute a command directly (for
                     debugging only)
@@ -182,12 +183,17 @@ def randbool():
 	return hexlify(os.urandom(1))[1] in '12345678'
 def get_segwit_bool():
 	return randbool() if opt.segwit_random else True if opt.segwit or opt.bech32 else False
+
 def disable_debug():
-	ds = os.getenv('MMGEN_DEBUG')
-	if ds is not None: os.environ['MMGEN_DEBUG'] = ''
-	return ds
-def restore_debug(ds):
-	if ds is not None: os.environ['MMGEN_DEBUG'] = ds
+	global save_debug
+	save_debug = {}
+	for k in g.env_opts:
+		if k[:11] == 'MMGEN_DEBUG':
+			save_debug[k] = os.getenv(k)
+			os.environ[k] = ''
+def restore_debug():
+	for k in save_debug:
+		os.environ[k] = save_debug[k] or ''
 
 cfgs = {
 	'15': {
@@ -957,8 +963,6 @@ def get_segwit_arg(cfg):
 # Tell spawned programs they're running in the test suite
 os.environ['MMGEN_TEST_SUITE'] = '1'
 
-if opt.debug_scripts: os.environ['MMGEN_DEBUG'] = '1'
-
 if opt.exact_output:
 	def msg(s): pass
 	vmsg = vmsg_r = msg_r = msg
@@ -1099,7 +1103,7 @@ def create_fake_unspent_entry(coinaddr,al_id=None,idx=None,lbl=None,non_mmgen=Fa
 		'address': coinaddr,
 		'spendable': False,
 		'scriptPubKey': '{}{}{}'.format(spk_beg,coinaddr.hex,spk_end),
-		'confirmations': getrandnum(4) % 50000
+		'confirmations': getrandnum(3) / 2 # max: 8388608 (7 digits)
 	}
 
 labels = [
@@ -1479,7 +1483,7 @@ class MMGenTestSuite(object):
 	def walletchk(self,name,wf,pf,desc='MMGen wallet',add_args=[],sid=None,pw=False,extra_desc=''):
 		args = []
 		hp = cfg['hash_preset'] if 'hash_preset' in cfg else '1'
-		wf_arg = ([],[wf])[bool(wf)]
+		wf_arg = [wf] if wf else []
 		t = MMGenExpect(name,'mmgen-walletchk',
 				add_args+args+['-p',hp]+wf_arg,
 				extra_desc=extra_desc)
@@ -1520,7 +1524,7 @@ class MMGenTestSuite(object):
 				extra_args +
 				([],['--type='+str(mmtype)])[bool(mmtype)] +
 				([],[wf])[bool(wf)] +
-				([],[id_str])[bool(id_str)] +
+				([id_str] if id_str else []) +
 				[cfg['{}_idx_list'.format(cmd_pfx)]],
 				extra_desc='({})'.format(mmtype) if mmtype in ('segwit','bech32') else '')
 		t.license()
@@ -1563,7 +1567,7 @@ class MMGenTestSuite(object):
 		vmsg('This is a simulation, so no addresses were actually imported into the tracking\nwallet')
 		t.ok(exit_val=1)
 
-	def txcreate_common(self, name,
+	def txcreate_common(self,name,
 						sources=['1'],
 						non_mmgen_input='',
 						do_label=False,
@@ -1610,6 +1614,10 @@ class MMGenTestSuite(object):
 		for num in tx_data:
 			t.expect('Continue anyway? (y/N): ','y')
 		t.expect(r"'q'=quit view, .*?:.",'M', regex=True)
+		if name == 'txcreate':
+			t.expect(r"'q'=quit view, .*?:.",'D', regex=True)
+			t.expect(r"'q'=quit view, .*?:.",'m', regex=True)
+			t.expect(r"'q'=quit view, .*?:.",'g', regex=True)
 		t.expect(r"'q'=quit view, .*?:.",'q', regex=True)
 		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)
@@ -1649,7 +1657,10 @@ class MMGenTestSuite(object):
 			t.expect('Edit transaction comment? (y/N): ','\n')
 			for cnum,desc in (('1','incognito data'),('3','MMGen wallet'),('4','MMGen wallet')):
 				t.passphrase(desc,cfgs[cnum]['wpasswd'])
-			t.expect("Type uppercase 'YES' to confirm: ",'YES\n')
+			m = ('YES','YES, I REALLY WANT TO DO THIS')[g.debug]
+			t.expect("'{}' to confirm: ".format(m),m+'\n')
+			if g.debug:
+				t.written_to_file('Transaction')
 		else:
 			t.expect('Add a comment to transaction? (y/N): ','\n')
 			t.expect('Save transaction? (y/N): ','y')
@@ -2277,9 +2288,10 @@ class MMGenTestSuite(object):
 
 	def ref_tool_decrypt(self,name):
 		f = os.path.join(ref_dir,ref_enc_fn)
+		disable_debug()
 		t = MMGenExpect(name,'mmgen-tool', ['-q','decrypt',f,'outfile=-','hash_preset=1'])
+		restore_debug()
 		t.passphrase('user data',tool_enc_passwd)
-#		t.expect("Type uppercase 'YES' to confirm: ",'YES\n') # comment out with popen_spawn
 		t.expect(NL,nonl=True)
 		import re
 		o = re.sub('\r\n','\n',t.read())
@@ -2399,6 +2411,8 @@ class MMGenTestSuite(object):
 			fn = os.path.join(self.regtest_user_dir(user),
 				'{}{}{}[{}].addrs'.format(sid,altcoin_pfx,id_strs[desc],addr_range))
 			t = MMGenExpect(name,'mmgen-addrimport', ['--quiet','--'+user,'--batch',fn],extra_desc='('+desc+')')
+			if g.debug:
+				t.expect("Type uppercase 'YES' to confirm: ",'YES\n')
 			t.expect('Importing')
 			t.expect('{} addresses imported'.format(num_addrs))
 			t.ok()
@@ -2564,9 +2578,9 @@ class MMGenTestSuite(object):
 		t.ok()
 
 	def regtest_get_mempool(self,name):
-		ds = disable_debug()
+		disable_debug()
 		ret = MMGenExpect(name,'mmgen-regtest',['show_mempool']).read()
-		restore_debug(ds)
+		restore_debug()
 		from ast import literal_eval
 		return literal_eval(ret)
 
@@ -2590,13 +2604,13 @@ class MMGenTestSuite(object):
 
 	@staticmethod
 	def gen_pairs(n):
-		ds = disable_debug()
+		disable_debug()
 		ret = [subprocess.check_output(
 						['python',os.path.join('cmds','mmgen-tool'),'--testnet=1'] +
 						(['--type=compressed'],[])[i==0] +
 						['-r0','randpair']
 					).split() for i in range(n)]
-		restore_debug(ds)
+		restore_debug()
 		return ret
 
 	def regtest_bob_pre_import(self,name):
@@ -2607,6 +2621,8 @@ class MMGenTestSuite(object):
 
 	def regtest_user_import(self,name,user,args):
 		t = MMGenExpect(name,'mmgen-addrimport',['--quiet','--'+user]+args)
+		if g.debug:
+			t.expect("Type uppercase 'YES' to confirm: ",'YES\n')
 		t.expect('Importing')
 		t.expect('OK')
 		t.ok()