eth: listaddresses, twview display fixes; add tests
- remove confirmations and days columns in address lists for eth
This commit is contained in:
parent
d4eb8f6ac0
commit
d9b344d1f5
4 changed files with 152 additions and 56 deletions
|
|
@ -224,7 +224,7 @@ class EthereumTwAddrList(TwAddrList):
|
|||
|
||||
from mmgen.obj import CoinAddr
|
||||
for mmid,d in tw.items():
|
||||
# if d['confirmations'] < minconf: continue
|
||||
# if d['confirmations'] < minconf: continue # cannot get confirmations for eth account
|
||||
label = TwLabel(mmid+' '+d['comment'],on_fail='raise')
|
||||
if usr_addr_list and (label.mmid not in usr_addr_list): continue
|
||||
bal = self.get_addr_balance(d['addr'])
|
||||
|
|
@ -234,7 +234,7 @@ class EthereumTwAddrList(TwAddrList):
|
|||
self[label.mmid] = {'amt': g.proto.coin_amt('0'), 'lbl': label }
|
||||
if showbtcaddrs:
|
||||
self[label.mmid]['addr'] = CoinAddr(d['addr'])
|
||||
self[label.mmid]['lbl'].mmid.confs = 9999 # TODO
|
||||
self[label.mmid]['lbl'].mmid.confs = None
|
||||
self[label.mmid]['amt'] += bal
|
||||
self.total += bal
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ def help_notes(k):
|
|||
'rel_fee_desc': MMGenTX().rel_fee_desc,
|
||||
'fee_spec_letters': fee_spec_letters(),
|
||||
'passwd': """
|
||||
For passphrases all combinations of whitespace are equal and leading and
|
||||
trailing space is ignored. This permits reading passphrase or brainwallet
|
||||
For passphrases all combinations of whitespace are equal, and leading and
|
||||
trailing space are ignored. This permits reading passphrase or brainwallet
|
||||
data from a multi-line file with free spacing and indentation.
|
||||
""".strip(),
|
||||
'brainwallet': """
|
||||
|
|
|
|||
13
mmgen/tw.py
13
mmgen/tw.py
|
|
@ -232,8 +232,8 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
|
|||
mmid_w = max(len(('',i.twmmid)[i.twmmid.type=='mmgen']) for i in self.unspent) or 12 # DEADBEEF:S:1
|
||||
amt_w = g.proto.coin_amt.max_prec + 4
|
||||
fs = { 'btc': u' {n:4} {t:%s} {a} {m} {A:%s} {c:<8} {g:<6} {l}' % (self.txid_w+3,amt_w),
|
||||
'eth': u' {n:4} {a} {m} {A:%s} {c:<8} {g:<6} {l}' % amt_w,
|
||||
'token': u' {n:4} {a} {m} {A:%s} {A2:%s} {c:<8} {g:<6} {l}' % (amt_w,amt_w)
|
||||
'eth': u' {n:4} {a} {m} {A:%s} {l}' % amt_w,
|
||||
'token': u' {n:4} {a} {m} {A:%s} {A2:%s} {l}' % (amt_w,amt_w)
|
||||
}[self.disp_type]
|
||||
out = [fs.format( n='Num',
|
||||
t='Tx ID,Vout',
|
||||
|
|
@ -241,8 +241,8 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
|
|||
m='MMGen ID'.ljust(mmid_w+1),
|
||||
A='Amount({})'.format(g.dcoin).ljust(amt_w+1),
|
||||
A2='Amount({})'.format(g.coin),
|
||||
c='Confs',
|
||||
g='Age(d)',
|
||||
c='Confs', # skipped for eth
|
||||
g='Age(d)', # skipped for eth
|
||||
l='Label')]
|
||||
|
||||
max_lbl_len = max([len(i.label) for i in self.unspent if i.label] or [2])
|
||||
|
|
@ -445,7 +445,8 @@ class TwAddrList(MMGenDict):
|
|||
if sort and 'age' in sort:
|
||||
return '{}_{:>012}_{}'.format(
|
||||
j.obj.rsplit(':',1)[0],
|
||||
(1000000000-j.confs if hasattr(j,'confs') else 0), # Hack, but OK for the foreseeable future
|
||||
# Hack, but OK for the foreseeable future:
|
||||
(1000000000-j.confs if hasattr(j,'confs') and j.confs != None else 0),
|
||||
j.sort_key)
|
||||
else:
|
||||
return j.sort_key
|
||||
|
|
@ -469,7 +470,7 @@ class TwAddrList(MMGenDict):
|
|||
addr=(e['addr'].fmt(color=True,width=addr_width) if showbtcaddrs else None),
|
||||
cmt=e['lbl'].comment.fmt(width=max_cmt_len,color=True,nullrepl='-'),
|
||||
amt=e['amt'].fmt('4.{}'.format(max(max_fp_len,3)),color=True),
|
||||
age=mmid.confs / (1,confs_per_day)[show_days] if hasattr(mmid,'confs') else '-'
|
||||
age=mmid.confs / (1,confs_per_day)[show_days] if hasattr(mmid,'confs') and mmid.confs != None else '-'
|
||||
))
|
||||
|
||||
return '\n'.join(out + ['\nTOTAL: {} {}'.format(self.total.hl(color=True),g.dcoin)])
|
||||
|
|
|
|||
187
test/test.py
187
test/test.py
|
|
@ -121,34 +121,35 @@ opts_data = lambda: {
|
|||
'desc': 'Test suite for the MMGen suite',
|
||||
'usage':'[options] [command(s) or metacommand(s)]',
|
||||
'options': """
|
||||
-h, --help Print this help message
|
||||
--, --longhelp Print help message for long options (common options)
|
||||
-B, --bech32 Generate and use Bech32 addresses
|
||||
-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
|
||||
-x, --debug-pexpect Produce debugging output for pexpect calls
|
||||
-D, --direct-exec Bypass pexpect and execute a command directly (for
|
||||
debugging only)
|
||||
-e, --exact-output Show the exact output of the MMGen script(s) being run
|
||||
-g, --segwit Generate and use Segwit addresses
|
||||
-G, --segwit-random Generate and use a random mix of Segwit and Legacy addrs
|
||||
-l, --list-cmds List and describe the commands in the test suite
|
||||
-L, --log Log commands to file {lf}
|
||||
-n, --names Display command names instead of descriptions
|
||||
-O, --popen-spawn Use pexpect's popen_spawn instead of popen (always true, so ignored)
|
||||
-p, --pause Pause between tests, resuming on keypress
|
||||
-P, --profile Record the execution time of each script
|
||||
-q, --quiet Produce minimal output. Suppress dependency info
|
||||
-r, --resume=c Resume at command 'c' after interrupted run
|
||||
-s, --system Test scripts and modules installed on system rather
|
||||
than those in the repo root
|
||||
-S, --skip-deps Skip dependency checking for command
|
||||
-u, --usr-random Get random data interactively from user
|
||||
-t, --traceback Run the command inside the '{tbc}' script
|
||||
-v, --verbose Produce more verbose output
|
||||
-W, --no-dw-delete Don't remove default wallet from data dir after dw tests are done
|
||||
-X, --exit-after=C Exit after command 'C'
|
||||
-h, --help Print this help message
|
||||
--, --longhelp Print help message for long options (common options)
|
||||
-B, --bech32 Generate and use Bech32 addresses
|
||||
-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
|
||||
-x, --debug-pexpect Produce debugging output for pexpect calls
|
||||
-D, --no-daemon-stop Don't stop auto-started daemons after running tests
|
||||
-E, --direct-exec Bypass pexpect and execute a command directly (for
|
||||
debugging only)
|
||||
-e, --exact-output Show the exact output of the MMGen script(s) being run
|
||||
-g, --segwit Generate and use Segwit addresses
|
||||
-G, --segwit-random Generate and use a random mix of Segwit and Legacy addrs
|
||||
-l, --list-cmds List and describe the commands in the test suite
|
||||
-L, --log Log commands to file {lf}
|
||||
-n, --names Display command names instead of descriptions
|
||||
-O, --popen-spawn Use pexpect's popen_spawn instead of popen (always true, so ignored)
|
||||
-p, --pause Pause between tests, resuming on keypress
|
||||
-P, --profile Record the execution time of each script
|
||||
-q, --quiet Produce minimal output. Suppress dependency info
|
||||
-r, --resume=c Resume at command 'c' after interrupted run
|
||||
-s, --system Test scripts and modules installed on system rather
|
||||
than those in the repo root
|
||||
-S, --skip-deps Skip dependency checking for command
|
||||
-u, --usr-random Get random data interactively from user
|
||||
-t, --traceback Run the command inside the '{tbc}' script
|
||||
-v, --verbose Produce more verbose output
|
||||
-W, --no-dw-delete Don't remove default wallet from data dir after dw tests are done
|
||||
-X, --exit-after=C Exit after command 'C'
|
||||
""".format(tbc=g.traceback_cmd,lf=log_file),
|
||||
'notes': """
|
||||
|
||||
|
|
@ -807,6 +808,12 @@ cmd_group['regtest'] = (
|
|||
('regtest_bob_split1', "splitting Bob's funds"),
|
||||
('regtest_generate', 'mining a block'),
|
||||
('regtest_bob_bal2', "Bob's balance"),
|
||||
('regtest_bob_bal2a', "Bob's balance (show_days=1)"),
|
||||
('regtest_bob_bal2b', "Bob's balance (show_age=1)"),
|
||||
('regtest_bob_bal2c', "Bob's balance (showempty=1 show_age=1 minconf=2)"),
|
||||
('regtest_bob_bal2d', "Bob's balance (show_age=1 minconf=2)"),
|
||||
('regtest_bob_bal2e', "Bob's balance (showempty=1 show_age=1 sort=age)"),
|
||||
('regtest_bob_bal2f', "Bob's balance (showempty=1 show_age=1 sort=age,reverse)"),
|
||||
('regtest_bob_rbf_send', 'sending funds to Alice (RBF)'),
|
||||
('regtest_get_mempool1', 'mempool (before RBF bump)'),
|
||||
('regtest_bob_rbf_bump', 'bumping RBF transaction'),
|
||||
|
|
@ -841,7 +848,7 @@ cmd_group['regtest'] = (
|
|||
('regtest_alice_add_label_rpcfail','RPC failure code'),
|
||||
('regtest_alice_send_estimatefee','tx creation with no fee on command line'),
|
||||
('regtest_generate', 'mining a block'),
|
||||
('regtest_bob_bal6', "Bob's balance"),
|
||||
('regtest_bob_bal6', "Bob's balance"),
|
||||
('regtest_bob_alice_bal', "Bob and Alice's balances"),
|
||||
('regtest_alice_bal2', "Alice's balance"),
|
||||
('regtest_stop', 'stopping regtest daemon'),
|
||||
|
|
@ -934,7 +941,7 @@ cmd_group['ethdev'] = (
|
|||
('ethdev_token_txsign1', 'signing the transaction'),
|
||||
('ethdev_token_txsend1', 'sending the transaction'),
|
||||
|
||||
('ethdev_token_twview1', 'viewing token tracking wallet'),
|
||||
('ethdev_token_twview1_chk', 'viewing token tracking wallet'),
|
||||
|
||||
('ethdev_token_txcreate2', 'creating a token transaction (to burn address)'),
|
||||
('ethdev_token_txbump', 'bumping the transaction fee'),
|
||||
|
|
@ -965,7 +972,26 @@ cmd_group['ethdev'] = (
|
|||
|
||||
('ethdev_token_bal3', 'the token balance'),
|
||||
|
||||
# ('ethdev_stop', 'stopping parity'),
|
||||
('ethdev_listaddresses1', 'listaddresses'),
|
||||
('ethdev_listaddresses2', 'listaddresses minconf=999999999 (ignored)'),
|
||||
('ethdev_listaddresses3', 'listaddresses sort=age (ignored)'),
|
||||
('ethdev_listaddresses4', 'listaddresses showempty=1 sort=age (ignored)'),
|
||||
|
||||
('ethdev_token_listaddresses1','listaddresses --token=mm1'),
|
||||
('ethdev_token_listaddresses2','listaddresses --token=mm1 showempty=1'),
|
||||
|
||||
('ethdev_twview1','twview'),
|
||||
('ethdev_twview2','twview wide=1'),
|
||||
('ethdev_twview3','twview wide=1 sort=age (ignored)'),
|
||||
('ethdev_twview4','twview wide=1 minconf=999999999 (ignored)'),
|
||||
('ethdev_twview5','twview wide=1 minconf=0 (ignored)'),
|
||||
('ethdev_twview6','twview show_days=0 (ignored)'),
|
||||
|
||||
('ethdev_token_twview1','twview --token=mm1'),
|
||||
('ethdev_token_twview2','twview --token=mm1 wide=1'),
|
||||
('ethdev_token_twview3','twview --token=mm1 wide=1 sort=age (ignored)'),
|
||||
|
||||
('ethdev_stop', 'stopping parity'),
|
||||
)
|
||||
|
||||
cmd_group['autosign'] = (
|
||||
|
|
@ -2765,10 +2791,14 @@ class MMGenTestSuite(object):
|
|||
def regtest_fund_bob(self,name): self.regtest_fund_wallet(name,'bob','C',rtFundAmt)
|
||||
def regtest_fund_alice(self,name): self.regtest_fund_wallet(name,'alice',('L','S')[g.proto.cap('segwit')],rtFundAmt)
|
||||
|
||||
def regtest_user_bal(self,name,user,bal):
|
||||
t = MMGenExpect(name,'mmgen-tool',['--'+user,'listaddresses','showempty=1'])
|
||||
total = t.expect_getend('TOTAL: ')
|
||||
cmp_or_die('{} {}'.format(bal,g.coin),total)
|
||||
def regtest_user_bal(self,name,user,bal,args=['showempty=1'],skip_check=False,exit_val=0):
|
||||
t = MMGenExpect(name,'mmgen-tool',['--'+user,'listaddresses'] + args)
|
||||
if skip_check:
|
||||
t.read()
|
||||
t.ok(exit_val=exit_val)
|
||||
else:
|
||||
total = t.expect_getend('TOTAL: ')
|
||||
cmp_or_die('{} {}'.format(bal,g.coin),total)
|
||||
|
||||
def regtest_alice_bal1(self,name):
|
||||
return self.regtest_user_bal(name,'alice',rtFundAmt)
|
||||
|
|
@ -2782,6 +2812,24 @@ class MMGenTestSuite(object):
|
|||
def regtest_bob_bal2(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0])
|
||||
|
||||
def regtest_bob_bal2a(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['showempty=1','show_days=1'])
|
||||
|
||||
def regtest_bob_bal2b(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['showempty=1','show_age=1'])
|
||||
|
||||
def regtest_bob_bal2c(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['showempty=1','show_age=1','minconf=2'],skip_check=True)
|
||||
|
||||
def regtest_bob_bal2d(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['show_age=1','minconf=2'],skip_check=True)
|
||||
|
||||
def regtest_bob_bal2e(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['showempty=1','show_age=1','sort=age'])
|
||||
|
||||
def regtest_bob_bal2f(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[0],args=['showempty=1','show_age=1','sort=age,reverse'])
|
||||
|
||||
def regtest_bob_bal3(self,name):
|
||||
return self.regtest_user_bal(name,'bob',rtBals[1])
|
||||
|
||||
|
|
@ -3086,8 +3134,13 @@ class MMGenTestSuite(object):
|
|||
t.ok()
|
||||
|
||||
def regtest_stop(self,name):
|
||||
t = MMGenExpect(name,'mmgen-regtest',['stop'])
|
||||
t.ok()
|
||||
if opt.no_daemon_stop:
|
||||
MMGenExpect(name,'',msg_only=True)
|
||||
msg_r('(leaving daemon running by user request)')
|
||||
ok()
|
||||
else:
|
||||
t = MMGenExpect(name,'mmgen-regtest',['stop'])
|
||||
t.ok()
|
||||
|
||||
def regtest_split_setup(self,name):
|
||||
if g.coin != 'BTC': die(1,'Test valid only for coin BTC')
|
||||
|
|
@ -3453,14 +3506,15 @@ class MMGenTestSuite(object):
|
|||
def ethdev_token_txsend1(self,name):
|
||||
self.ethdev_token_txsend(name,ext='1.23456,50000].sigtx',token='mm1')
|
||||
|
||||
def ethdev_twview(self,name,args,expect_str):
|
||||
t = MMGenExpect(name,'mmgen-tool', eth_args() + args + ['twview'])
|
||||
t.expect(expect_str,regex=True)
|
||||
def ethdev_twview(self,name,args=[],expect_str='',tool_args=[],exit_val=0):
|
||||
t = MMGenExpect(name,'mmgen-tool', eth_args() + args + ['twview'] + tool_args)
|
||||
if expect_str:
|
||||
t.expect(expect_str,regex=True)
|
||||
t.read()
|
||||
t.ok()
|
||||
t.ok(exit_val=exit_val)
|
||||
|
||||
bal_corr = Decimal('0.0000032') # gas use varies for token sends!
|
||||
def ethdev_token_twview1(self,name):
|
||||
bal_corr = Decimal('0.0000032') # gas use for token sends varies between ETH and ETC!
|
||||
def ethdev_token_twview1_chk(self,name):
|
||||
ebal = Decimal('1.2314236')
|
||||
if g.coin == 'ETC': ebal += self.bal_corr
|
||||
s = '98831F3A:E:11\s+998.76544\s+' + str(ebal)
|
||||
|
|
@ -3529,11 +3583,52 @@ class MMGenTestSuite(object):
|
|||
def ethdev_token_bal3(self,name):
|
||||
self.ethdev_token_bal(name,expect_str=r'98831F3A:E:13\s+1.23456\s')
|
||||
|
||||
def ethdev_listaddresses(self,name,args=[],tool_args=['all_labels=1'],exit_val=0):
|
||||
t = MMGenExpect(name,'mmgen-tool', eth_args() + args + ['listaddresses'] + tool_args)
|
||||
t.read()
|
||||
t.ok(exit_val=exit_val)
|
||||
|
||||
def ethdev_listaddresses1(self,name):
|
||||
return self.ethdev_listaddresses(name)
|
||||
def ethdev_listaddresses2(self,name):
|
||||
return self.ethdev_listaddresses(name,tool_args=['minconf=999999999'])
|
||||
def ethdev_listaddresses3(self,name):
|
||||
return self.ethdev_listaddresses(name,tool_args=['sort=age'])
|
||||
def ethdev_listaddresses4(self,name):
|
||||
return self.ethdev_listaddresses(name,tool_args=['sort=age','showempty=1'])
|
||||
|
||||
def ethdev_token_listaddresses1(self,name):
|
||||
return self.ethdev_listaddresses(name,args=['--token=mm1'])
|
||||
def ethdev_token_listaddresses2(self,name):
|
||||
return self.ethdev_listaddresses(name,args=['--token=mm1'],tool_args=['showempty=1'])
|
||||
|
||||
def ethdev_twview1(self,name):
|
||||
return self.ethdev_twview(name)
|
||||
def ethdev_twview2(self,name):
|
||||
return self.ethdev_twview(name,tool_args=['wide=1'])
|
||||
def ethdev_twview3(self,name):
|
||||
return self.ethdev_twview(name,tool_args=['wide=1','sort=age'])
|
||||
def ethdev_twview4(self,name):
|
||||
return self.ethdev_twview(name,tool_args=['wide=1','minconf=999999999'])
|
||||
def ethdev_twview5(self,name):
|
||||
return self.ethdev_twview(name,tool_args=['wide=1','minconf=0'])
|
||||
def ethdev_twview6(self,name):
|
||||
return self.ethdev_twview(name,tool_args=['show_days=0'])
|
||||
|
||||
def ethdev_token_twview1(self,name):
|
||||
return self.ethdev_twview(name,args=['--token=mm1'])
|
||||
def ethdev_token_twview2(self,name):
|
||||
return self.ethdev_twview(name,args=['--token=mm1'],tool_args=['wide=1'])
|
||||
def ethdev_token_twview3(self,name):
|
||||
return self.ethdev_twview(name,args=['--token=mm1'],tool_args=['wide=1','sort=age'])
|
||||
|
||||
def ethdev_stop(self,name):
|
||||
MMGenExpect(name,'',msg_only=True)
|
||||
pid = read_from_tmpfile(cfg,cfg['parity_pidfile'])
|
||||
assert pid,'No parity pid file!'
|
||||
subprocess.check_call(['kill',pid])
|
||||
pid = read_from_tmpfile(cfg,cfg['parity_pidfile']) # exits if file not found
|
||||
if opt.no_daemon_stop:
|
||||
msg_r('(leaving daemon running by user request)')
|
||||
else:
|
||||
subprocess.check_call(['kill',pid])
|
||||
ok()
|
||||
|
||||
# undocumented admin commands
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue