mmgen-regtest: test suite support, mswin bugfixes

tx.view(): refactor, bugfixes
new script: test-release.sh
This commit is contained in:
The MMGen Project 2017-09-19 22:14:00 +03:00
commit 50f55b9790
Signed by: mmgen
GPG key ID: 62DBE9E5212F05BE
16 changed files with 652 additions and 162 deletions

View file

@ -47,6 +47,7 @@ opts_data = lambda: {
generate - mine a block
test_daemon - test whether daemon is running
get_balances - get balances of Bob and Alice
show_mempool - show transaction IDs in mempool
"""
}
@ -56,7 +57,7 @@ if len(cmd_args) != 1:
opts.usage()
cmds = ('setup','stop','generate','test_daemon','create_data_dir','bob','alice','user',
'wait_for_daemon','wait_for_exit','get_current_user','get_balances')
'wait_for_daemon','wait_for_exit','get_current_user','get_balances','show_mempool')
if cmd_args[0] not in cmds:
opts.usage()

View file

@ -661,9 +661,21 @@ class MMGenAddrType(str,Hilite,InitErrors,MMGenObject):
trunc_ok = False
color = 'blue'
mmtypes = { # since 'name' is used to cook the seed, it must never change!
'L': {'name':'legacy','comp':False,'gen':'p2pkh', 'fmt':'p2pkh','desc':'Legacy uncompressed Bitcoin address'},
'S': {'name':'segwit','comp':True, 'gen':'segwit','fmt':'p2sh', 'desc':'Bitcoin Segwit P2SH-P2WPK address' },
'C': {'name':'compressed','comp':True,'gen':'p2pkh','fmt':'p2pkh','desc':'Compressed Bitcoin P2PKH address'}
'L': { 'name':'legacy',
'comp':False,
'gen':'p2pkh',
'fmt':'p2pkh',
'desc':'Legacy uncompressed Bitcoin address'},
'S': { 'name':'segwit',
'comp':True,
'gen':'segwit',
'fmt':'p2sh',
'desc':'Bitcoin Segwit P2SH-P2WPK address' },
'C': { 'name':'compressed',
'comp':True,
'gen':'p2pkh',
'fmt':'p2pkh',
'desc':'Compressed Bitcoin P2PKH address'}
# 'l': 'litecoin',
# 'e': 'ethereum',
# 'E': 'ethereum_classic',

View file

@ -227,10 +227,6 @@ def init(opts_f,add_opts=[],opt_filter=None):
else:
setattr(opt,k,g.__dict__[k])
# Check user-set opts without modifying them
if not check_opts(uopts):
sys.exit(1)
if opt.show_hash_presets:
_show_hash_presets()
sys.exit(0)
@ -246,24 +242,27 @@ def init(opts_f,add_opts=[],opt_filter=None):
opts_data['long_options'] = common_opts_data
mmgen.share.Opts.parse_opts(sys.argv,opts_data,opt_filter=opt_filter)
# We don't need this data anymore
del mmgen.share.Opts
del opts_f
for k in ('prog_name','desc','usage','options','notes'):
if k in opts_data: del opts_data[k]
if g.bob or g.alice:
g.data_dir = os.path.join(g.data_dir_root,'regtest')
import regtest as rt
rt.user(('alice','bob')[g.bob],quiet=True)
g.testnet = True
g.rpc_host = 'localhost'
g.rpc_port = rt.rpc_port
g.rpc_user = rt.rpc_user
g.rpc_password = rt.rpc_password
g.data_dir = os.path.join(g.home_dir,'.'+g.proj_name.lower(),'regtest')
# Check user-set opts without modifying them
if not check_opts(uopts):
sys.exit(1)
if g.debug: opt_postproc_debug()
# We don't need this data anymore
del mmgen.share.Opts
del opts_f
for k in ('prog_name','desc','usage','options','notes'):
if k in opts_data: del opts_data[k]
return args
def check_opts(usr_opts): # Returns false if any check fails
@ -414,6 +413,11 @@ def check_opts(usr_opts): # Returns false if any check fails
if not opt_compares(val,'>',0,desc): return False
elif key == 'coin':
if not opt_is_in_list(val.upper(),g.coins,'coin'): return False
elif key in ('bob','alice'):
from mmgen.regtest import regtest_dir
m = "{}'s wallet doesn't exist yet. Run '{}-regtest setup' to initialize."
try: os.stat(regtest_dir)
except: die(1,m.format(key.capitalize(),g.proj_name.lower()))
else:
if g.debug: Msg("check_opts(): No test for opt '%s'" % key)

View file

@ -22,26 +22,20 @@ regtest: Bitcoind regression test mode setup and operations for the MMGen suite
import os,subprocess,time,shutil
from mmgen.common import *
PIPE = subprocess.PIPE
data_dir = os.path.join(g.data_dir,'regtest')
regtest_dir = os.path.join(data_dir,'regtest')
rpc_port = 8552
rpc_user = 'bobandalice'
data_dir = os.path.join(g.data_dir_root,'regtest')
regtest_dir = os.path.join(data_dir,'regtest')
rpc_port = 8552
rpc_user = 'bobandalice'
rpc_password = 'hodltothemoon'
init_amt = 500
tr_wallet = {
'orig': os.path.join(regtest_dir,'wallet.dat.orig'),
'bob': os.path.join(regtest_dir,'wallet.dat.bob'),
'alice': os.path.join(regtest_dir,'wallet.dat.alice')
}
mmwords = {
'bob': os.path.join(data_dir,'1163DDF1[128].mmwords'),
'alice': os.path.join(data_dir,'9304C211[128].mmwords')
}
mmaddrs = {
'bob': os.path.join(data_dir,'1163DDF1{}[1-10].addrs'),
'alice': os.path.join(data_dir,'9304C211{}[1-10].addrs')
}
init_amt = 500
sids = { 'bob':'1163DDF1', 'alice':'9304C211' }
tr_wallet = lambda user: os.path.join(regtest_dir,'wallet.dat.'+user)
mmwallet = lambda user: os.path.join(data_dir,'{}[128].mmwords'.format(sids[user]))
mmaddrs = lambda user: os.path.join(data_dir,'{}{{}}[1-5].addrs'.format(sids[user]))
mnemonic = {
'bob': 'ignore bubble ignore crash stay long stay patient await glorious destination moon',
'alice': 'stay long guard secret await price rise destination moon enjoy rich future'
@ -54,6 +48,7 @@ send_addr = {
common_args = (
'-rpcuser={}'.format(rpc_user),
'-rpcpassword={}'.format(rpc_password),
'-rpcport={}'.format(rpc_port),
'-regtest',
'-datadir={}'.format(data_dir))
@ -61,13 +56,11 @@ def start_daemon(user,quiet=False,daemon=True):
cmd = (
'bitcoind',
'-keypool=1',
'-rpcbind=localhost:{}'.format(rpc_port),
'-rpcallowip=::1',
'-wallet={}'.format(os.path.basename(tr_wallet[user]))
'-wallet={}'.format(os.path.basename(tr_wallet(user)))
) + common_args
if daemon: cmd += ('-daemon',)
if not g.debug or quiet: vmsg('{}'.format(' '.join(cmd)))
p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p = subprocess.Popen(cmd,stdout=PIPE,stderr=PIPE)
err = process_output(p,silent=False)[1]
if err:
rdie(1,'Error starting the Bitcoin daemon:\n{}'.format(err))
@ -82,10 +75,11 @@ def start_daemon_mswin(user,quiet=False):
def start_cmd(*args,**kwargs):
cmd = args
if args[0] == 'cli':
cmd = ('bitcoin-cli','-rpcconnect=localhost','-rpcport={}'.format(rpc_port)) + common_args + args[1:]
cmd = ('bitcoin-cli',) + common_args + args[1:]
if g.debug or not 'quiet' in kwargs:
vmsg('{}'.format(' '.join(cmd)))
return subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
io=(PIPE,None)['no_pipe' in kwargs and kwargs['no_pipe']]
return subprocess.Popen(cmd,stdin=io,stdout=io,stderr=io)
def test_daemon():
p = start_cmd('cli','getblockcount',quiet=True)
@ -113,7 +107,9 @@ def get_balances():
tbal = 0
from mmgen.obj import BTCAmt
for user in (user1,user2):
p = start_cmd('python','mmgen-tool','--{}'.format(user),'getbalance','quiet=1')
p = start_cmd('python','mmgen-tool',
'--{}'.format(user),'--data-dir='+g.data_dir,
'getbalance','quiet=1')
bal = BTCAmt(p.stdout.read())
ustr = "{}'s balance:".format(user.capitalize())
msg('{:<16} {:12}'.format(ustr,bal))
@ -122,7 +118,6 @@ def get_balances():
msg('{:<16} {:12}'.format('Miner fees:',1000-tbal))
def create_data_dir():
#def keypress_confirm(prompt,default_yes=False,verbose=False,no_nl=False):
try: os.stat(regtest_dir)
except: pass
else:
@ -136,6 +131,7 @@ def create_data_dir():
def process_output(p,silent=False):
out = p.stdout.read()
if not opt.verbose: Msg_r(' \b')
err = p.stderr.read()
if g.debug or not silent:
vmsg('stdout: [{}]'.format(out.strip()))
@ -155,9 +151,11 @@ def create_mmgen_wallet(user):
def create_mmgen_addrs(user,addr_type):
gmsg('Creating MMGen addresses for user {} (type: {})'.format(user.capitalize(),addr_type))
suf = ('-'+addr_type,'')[addr_type=='L']
try: os.unlink(mmaddrs[user].format(suf))
try: os.unlink(mmaddrs(user).format(suf))
except: pass
p = start_cmd('python','mmgen-addrgen','--{}'.format(user),'-d',data_dir,'--type',addr_type,mmwords[user],'1-10')
p = start_cmd('python','mmgen-addrgen',
'--{}'.format(user),'--data-dir='+g.data_dir,
'-d',data_dir,'--type',addr_type,mmwallet(user),'1-5')
p.stdin.write(mnemonic[user]+'\n')
p.stdin.close()
err = process_output(p)[1]
@ -168,9 +166,9 @@ def create_mmgen_addrs(user,addr_type):
def import_mmgen_addrs(user,addr_type):
gmsg_r('Importing MMGen addresses for user {} (type: {})'.format(user.capitalize(),addr_type))
suf = ('-'+addr_type,'')[addr_type=='L']
p = start_cmd('python','mmgen-addrimport','--{}'.format(user),'-q','--batch',mmaddrs[user].format(suf))
p.stdin.write(mnemonic[user]+'\n')
p.stdin.close()
p = start_cmd('python','mmgen-addrimport',
'--{}'.format(user),'--data-dir='+g.data_dir,
'-q','--batch',mmaddrs(user).format(suf))
err = process_output(p)[1]
if not 'addresses imported' in err:
rdie(1,'Error importing MMGen addresses')
@ -211,6 +209,11 @@ def fund_wallet(user,amt):
process_output(p)
p.wait()
def show_mempool():
p = start_cmd('cli','getrawmempool')
msg_r(p.stdout.read())
p.wait()
def setup():
try: os.mkdir(data_dir)
except: pass
@ -245,7 +248,7 @@ def setup():
def get_current_user_win(quiet=False):
if test_daemon() == 'stopped': return None
p = start_cmd('grep','Using wallet',os.path.join(regtest_dir,'debug.log'))
p = start_cmd('grep','Using wallet',os.path.join(regtest_dir,'debug.log'),quiet=True)
try: wallet_fn = p.stdout.readlines()[-1].split()[-1]
except: return None
for k in ('orig','bob','alice'):

View file

@ -75,7 +75,9 @@ class BitcoinRPCConnection(object):
if cf['on_fail'] in ('return','silent'):
return 'rpcfail',args
else:
die(args[1],yellow(args[2]))
try: s = u'{}'.format(args[2])
except: s = repr(args[2])
die(args[1],yellow(s))
dmsg('=== request() debug ===')
dmsg(' RPC POST data ==> %s\n' % p)
@ -91,7 +93,8 @@ class BitcoinRPCConnection(object):
# dump = json.dumps(p,cls=MyJSONEncoder,ensure_ascii=False)
# print(dump)
dmsg(' RPC AUTHORIZATION data ==> [Basic {}]\n'.format(base64.b64encode(self.auth_str)))
dmsg(' RPC AUTHORIZATION data ==> raw: [{}]\n{}enc: [Basic {}]\n'.format(
self.auth_str,' '*31,base64.b64encode(self.auth_str)))
try:
hc.request('POST', '/', json.dumps(p,cls=MyJSONEncoder), {
'Host': self.host,

View file

@ -49,7 +49,7 @@ def mk_tmpdir(d):
except OSError as e:
if e.errno != 17: raise
else:
qmsg("Created directory '%s'" % d)
vmsg("Created directory '%s'" % d)
def mk_tmpdir_path(path,cfg):
try:

View file

@ -78,7 +78,7 @@ cmd_data = OrderedDict([
('Mn_printlist', ["wordlist [str='electrum']"]),
('Listaddress',['<{} address> [str]'.format(pnm),'minconf [int=1]','pager [bool=False]','showempty [bool=True]''showbtcaddr [bool=True]']),
('Listaddresses',["addrs [str='']",'minconf [int=1]','showempty [bool=False]','pager [bool=False]','showbtcaddrs [bool=False]','all_labels [bool=False]']),
('Listaddresses',["addrs [str='']",'minconf [int=1]','showempty [bool=False]','pager [bool=False]','showbtcaddrs [bool=True]','all_labels [bool=False]']),
('Getbalance', ['minconf [int=1]','quiet [bool=False]']),
('Txview', ['<{} TX file(s)> [str]'.format(pnm),'pager [bool=False]','terse [bool=False]',"sort [str='mtime'] (options: 'ctime','atime')",'MARGS']),
('Twview', ["sort [str='age']",'reverse [bool=False]','show_days [bool=True]','show_mmid [bool=True]','minconf [int=1]','wide [bool=False]','pager [bool=False]']),
@ -354,7 +354,7 @@ def Listaddress(addr,minconf=1,pager=False,showempty=True,showbtcaddr=True):
return Listaddresses(addrs=addr,minconf=minconf,pager=pager,showempty=showempty,showbtcaddrs=showbtcaddr)
# List MMGen addresses and their balances. TODO: move this code to AddrList
def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=False,all_labels=False):
def Listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=True,all_labels=False):
c = rpc_connection()

View file

@ -134,7 +134,7 @@ class MMGenTX(MMGenObject):
class MMGenTxInput(MMGenListItem):
for k in txio_attrs: locals()[k] = txio_attrs[k] # in lieu of inheritance
scriptPubKey = MMGenListItemAttr('scriptPubKey','HexStr')
sequence = MMGenListItemAttr('sequence',int,typeconv=False)
sequence = MMGenListItemAttr('sequence',(int,long)[g.platform=='win'],typeconv=False)
class MMGenTxOutput(MMGenListItem):
for k in txio_attrs: locals()[k] = txio_attrs[k]
@ -632,7 +632,7 @@ class MMGenTX(MMGenObject):
o = self.format_view(terse=terse).encode('utf8')
if pager: do_pager(o)
else:
Msg_r(o)
msg_r(o)
from mmgen.term import get_char
if pause:
get_char('Press any key to continue: ')
@ -663,76 +663,65 @@ class MMGenTX(MMGenObject):
'TRANSACTION DATA\n\n[ID:{}] [{} {}] [{} UTC] [RBF:{}] [Signed:{}]\n',
'Transaction {} {} {} ({} UTC) RBF={} Signed={}\n'
)[bool(terse)]
nonmm_str = '(non-{pnm} address)'.format(pnm=g.proj_name)
def get_max_mmwid(io):
if io == self.inputs:
sel_f = lambda o: len(o.mmid) + 2 # len('()')
else:
sel_f = lambda o: len(o.mmid) + (2,8)[bool(o.is_chg)] # + len(' (chg)')
return max(max([sel_f(o) for o in io if o.mmid] or [0]),len(nonmm_str))
max_mmwid = max(get_max_mmwid(self.inputs),get_max_mmwid(self.outputs))
def format_io(io):
ip = io == self.inputs
io_out = ''
for n,e in enumerate(sorted(io,key=lambda o: o.mmid.sort_key if o.mmid else o.addr)):
if ip and blockcount:
confs = e.confs + blockcount - self.blockcount
days = int(confs * g.mins_per_block / (60*24))
if e.mmid:
app=('',' (chg)')[bool(not ip and e.is_chg and terse)]
mmid_fmt = e.mmid.fmt(width=max_mmwid,encl='()',color=True,app=app,appcolor='green')
else:
mmid_fmt = MMGenID.fmtc(nonmm_str,width=max_mmwid)
if terse:
io_out += '{:3} {} {} {} {}\n'.format(n+1,e.addr.fmt(color=True),mmid_fmt,e.amt.hl(),g.coin)
else:
icommon = [
((n+1,'')[ip], 'address:', e.addr.fmt(color=True) + ' ' + mmid_fmt),
('', 'comment:', e.label.hl() if e.label else ''),
('', 'amount:', '{} {}'.format(e.amt.hl(),g.coin))]
items = [(n+1, 'tx,vout:', '%s,%s' % (e.txid, e.vout))] + icommon + [
('', 'confirmations:', '%s (around %s days)' % (confs,days) if blockcount else '')
] if ip else icommon + [
('', 'change:', green('True') if e.is_chg else '')]
io_out += '\n'.join([('%3s %-8s %s' % d) for d in items if d[2]]) + '\n\n'
return io_out
out = hdr_fs.format(self.txid.hl(),self.send_amt.hl(),g.coin,self.timestamp,
self.is_rbf(color=True),self.marked_signed(color=True))
if self.chain in ('testnet','regtest'):
out += green('Chain: {}\n'.format(self.chain.upper()))
if self.btc_txid:
out += '{} TxID: {}\n'.format(g.coin,self.btc_txid.hl())
enl = ('\n','')[bool(terse)]
if self.chain in ('testnet','regtest'): out += green('Chain: {}\n'.format(self.chain.upper()))
if self.btc_txid: out += '{} TxID: {}\n'.format(g.coin,self.btc_txid.hl())
out += enl
if self.label:
out += 'Comment: %s\n%s' % (self.label.hl(),enl)
out += 'Inputs:\n' + enl
nonmm_str = '(non-{pnm} address)'.format(pnm=g.proj_name)
max_mmwid = max(max([len(i.mmid) for i in self.inputs if i.mmid] or [0])+len('()'),len(nonmm_str))
for n,e in enumerate(sorted(self.inputs,key=lambda o: o.mmid.sort_key if o.mmid else o.addr)):
if blockcount:
confs = e.confs + blockcount - self.blockcount
days = int(confs * g.mins_per_block / (60*24))
mmid_fmt = e.mmid.fmt(width=max_mmwid,encl='()',color=True) if e.mmid else MMGenID.hlc(nonmm_str)
if terse:
out += '{:3} {} {} {} {}'.format(n+1,e.addr.fmt(color=True),mmid_fmt,e.amt.hl(),g.coin)
else:
for d in (
(n+1, 'tx,vout:', '%s,%s' % (e.txid, e.vout)),
('', 'address:', e.addr.fmt(color=True) + ' ' + mmid_fmt),
('', 'comment:', e.label.hl() if e.label else ''),
('', 'amount:', '{} {}'.format(e.amt.hl(),g.coin)),
('', 'confirmations:', '%s (around %s days)' % (confs,days) if blockcount else '')
):
if d[2]: out += ('%3s %-8s %s\n' % d)
out += '\n'
out += 'Outputs:\n' + enl
sel_f = lambda o: (len(o.mmid),len(o.mmid)+len(' (chg)'))[bool(o.is_chg)]
max_mmwid = max([sel_f(o) for o in self.outputs if o.mmid] or [0])
max_mmwid = max(max_mmwid+len('()'),len(nonmm_str))
for n,e in enumerate(sorted(self.outputs,key=lambda o: o.mmid.sort_key if o.mmid else o.addr)):
if e.mmid:
app=('',' (chg)')[bool(e.is_chg and terse)]
mmid_fmt = e.mmid.fmt(width=max_mmwid,encl='()',color=True,
app=app,appcolor='green')
else:
mmid_fmt = MMGenID.hlc(nonmm_str)
if terse:
out += '{:3} {} {} {} {}'.format(n+1,e.addr.fmt(color=True),mmid_fmt,e.amt.hl(),g.coin)
else:
for d in (
(n+1, 'address:', e.addr.fmt(color=True) + ' ' + mmid_fmt),
('', 'comment:', e.label.hl() if e.label else ''),
('', 'amount:', '{} {}'.format(e.amt.hl(),g.coin)),
('', 'change:', green('True') if e.is_chg else '')
):
if d[2]: out += ('%3s %-8s %s\n' % d)
out += '\n'
out += 'Inputs:\n' + enl + format_io(self.inputs)
out += 'Outputs:\n' + enl + format_io(self.outputs)
fs = (
'Total input: {} {c}\nTotal output: {} {c}\nTX fee: {} {c} ({} satoshis per byte)\n',
'In {} {c} - Out {} {c} - Fee {} {c} ({} satoshis/byte)\n'
)[bool(terse)]
total_in = self.sum_inputs()
total_out = self.sum_outputs()
out += fs.format(
total_in.hl(),
total_out.hl(),
(total_in-total_out).hl(),
pink(str(self.btc2spb(total_in-total_out))),
c=g.coin
)
t_in,t_out = self.sum_inputs(),self.sum_outputs()
fee = t_in-t_out
out += fs.format(t_in.hl(),t_out.hl(),fee.hl(),pink(str(self.btc2spb(fee))),c=g.coin)
if opt.verbose:
ts = len(self.hex)/2 if self.hex else 'unknown'
out += 'Transaction size: Vsize={} Actual={}'.format(self.estimate_size(),ts)
@ -741,8 +730,7 @@ class MMGenTX(MMGenObject):
out += ' Base={} Witness={}'.format(ts-ws,ws)
out += '\n'
# TX label might contain non-ascii chars
return out
return out # TX label might contain non-ascii chars
def parse_tx_file(self,infile):

View file

@ -141,7 +141,7 @@ def get_seed_files(opt,args):
from mmgen.filename import find_file_in_dir,find_files_in_dir
if g.bob or g.alice:
import regtest as rt
wf = rt.mmwords[('alice','bob')[g.bob]]
wf = rt.mmwallet(('alice','bob')[g.bob])
else:
wf = find_file_in_dir(Wallet,g.data_dir) # Make this the first encrypted ss in the list
if wf: ret.append(wf)

View file

@ -470,7 +470,7 @@ def get_seed_file(cmd_args,nargs,invoked_as=None):
from mmgen.seed import Wallet
if g.bob or g.alice:
import regtest as rt
wf = rt.mmwords[('alice','bob')[g.bob]]
wf = rt.mmwallet(('alice','bob')[g.bob])
else:
wf = find_file_in_dir(Wallet,g.data_dir)
@ -610,7 +610,6 @@ def write_data_to_file(
else:
do_file(outfile,ask_write_prompt)
def get_words_from_user(prompt):
# split() also strips
words = my_raw_input(prompt, echo=opt.echo_passphrase).split()
@ -797,13 +796,8 @@ def get_bitcoind_cfg_options(cfg_keys):
return cfg
def get_bitcoind_auth_cookie():
f = os.path.join(g.bitcoin_data_dir,('',g.testnet_name)[g.testnet],'.cookie')
if file_is_readable(f):
return get_lines_from_file(f,'')[0]
else:
return ''
return get_lines_from_file(f,'')[0] if file_is_readable(f) else ''
def rpc_connection():
@ -840,6 +834,9 @@ def rpc_connection():
auth_cookie=get_bitcoind_auth_cookie())
if not g.bitcoind_version: # First call
if g.bob or g.alice:
import regtest as rt
rt.user(('alice','bob')[g.bob],quiet=True)
g.bitcoind_version = int(c.getnetworkinfo()['version'])
g.chain = c.getblockchaininfo()['chain']
if g.chain != 'regtest':

68
scripts/test-release.sh Executable file
View file

@ -0,0 +1,68 @@
#!/bin/bash
# Tested on Linux, MinGW-64
set -e
GREEN="\e[32;1m" YELLOW="\e[33;1m" RESET="\e[0m" BRANCH=$1
REFDIR=test/ref
if uname -a | grep -qi mingw; then SUDO='' MINGW=1; else SUDO='sudo' MINGW=''; fi
function check {
[ "$BRANCH" ] || { echo 'No branch specified. Exiting'; exit; }
[ "$(git diff $BRANCH)" == "" ] || {
echo "Unmerged changes from branch '$BRANCH'. Exiting"
exit
}
git diff $BRANCH >/dev/null 2>&1 || exit
}
function install {
set -x
eval "$SUDO rm -rf .test-release"
git clone --branch $BRANCH --single-branch . .test-release
cd .test-release
./setup.py sdist
mkdir pydist && cd pydist
if [ "$MINGW" ]; then unzip ../dist/mmgen-*.zip; else tar zxvf ../dist/mmgen-*gz; fi
cd mmgen-*
scripts/deinstall.sh
[ "$MINGW" ] && ./setup.py build --compiler=mingw32
eval "$SUDO ./setup.py install"
}
function do_test {
set +x
for i in "${CMDS[@]}"; do
echo -e "\n${GREEN}Running:$RESET $YELLOW$i$RESET"
eval "$i"
done
}
check
(install)
eval "cd .test-release/pydist/mmgen-*"
CMDS=(
'test/test.py -On'
'test/test.py -On --segwit dfl_wallet main ref ref_other'
'test/test.py -On --segwit-random dfl_wallet main'
)
do_test
CMDS=('test/test.py -On regtest')
do_test
# tooltest tests both segwit and non-segwit
CMDS=(
'test/tooltest.py'
"test/gentest.py -q 2 $REFDIR/btcwallet.dump"
"test/gentest.py -q --testnet=1 2 $REFDIR/btcwallet-testnet.dump"
'test/gentest.py -q 1:2 10'
'test/gentest.py -q --segwit 1:2 10'
# "scripts/tx-old2new.py -S $REFDIR/tx_*raw >/dev/null 2>&1"
"scripts/compute-file-chksum.py $REFDIR/*testnet.rawtx >/dev/null 2>&1"
)
do_test
echo -e "\n${GREEN}All OK$RESET"

View file

@ -10,7 +10,8 @@ try:
sys.argv.pop(0)
execfile(sys.argv[0])
except SystemExit:
sys.exit(int(str(sys.exc_info()[1])))
e = sys.exc_info()
sys.exit(int(str(e[1])))
except:
l = traceback.format_exception(*sys.exc_info())
exc = l.pop()
@ -18,3 +19,4 @@ except:
def yellow(s): return '{e}[33;1m{}{e}[0m'.format(s,e='\033')
sys.stdout.write('{}{}'.format(yellow(''.join(l)),red(exc)))
traceback.print_exc(file=f)

View file

@ -35,6 +35,10 @@ else:
send_delay = 0
os.environ['MMGEN_DISABLE_HOLD_PROTECT'] = '1'
stderr_save = sys.stderr
def errmsg(s): stderr_save.write(s+'\n')
def errmsg_r(s): stderr_save.write(s)
def my_send(p,t,delay=send_delay,s=False):
if delay: time.sleep(delay)
ret = p.send(t) # returns num bytes written
@ -45,11 +49,12 @@ def my_send(p,t,delay=send_delay,s=False):
msg('%sSEND %s%s' % (ls,es,yellow("'%s'"%t.replace('\n',r'\n'))))
return ret
def my_expect(p,s,t='',delay=send_delay,regex=False,nonl=False):
def my_expect(p,s,t='',delay=send_delay,regex=False,nonl=False,silent=False):
quo = ('',"'")[type(s) == str]
if opt.verbose: msg_r('EXPECT %s' % yellow(quo+str(s)+quo))
else: msg_r('+')
if not silent:
if opt.verbose: msg_r('EXPECT %s' % yellow(quo+str(s)+quo))
elif not opt.exact_output: msg_r('+')
try:
if s == '': ret = 0
@ -69,7 +74,7 @@ def my_expect(p,s,t='',delay=send_delay,regex=False,nonl=False):
sys.exit(1)
else:
if t == '':
if not nonl: vmsg('')
if not nonl and not silent: vmsg('')
else:
my_send(p,t,delay,s)
return ret
@ -233,14 +238,14 @@ class MMGenPexpect(object):
debug_pexpect_msg(self.p)
# end = self.readline().strip()
# readline() of partial lines doesn't work with PopenSpawn, so do this instead:
self.expect(self.NL,nonl=True)
self.expect(self.NL,nonl=True,silent=True)
debug_pexpect_msg(self.p)
end = self.p.before
vmsg(' ==> %s' % cyan(end))
return end
def interactive(self):
return self.p.interact()
return self.p.interact() # interact() not available with popen_spawn
def logfile(self,arg):
self.p.logfile = arg

View file

@ -0,0 +1,109 @@
# Wallet dump created by Bitcoin v0.15.0
# * Created on 2017-09-18T19:13:26Z
# * Best block at time of backup was 0 (000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943),
# mined on 2011-02-02T23:16:42Z
# extended private masterkey: tprv8ZgxMBicQKsPdiu5xpPn3bx1GCYK7sMSgcF8WGUoZgFxkXvQiX1nowCK4FqcRqVGKNrPGqdGUvQaWGvhoBQGZTXARyNSVaa1ZN4hPizUCK8
cUEusQd9JM1yAs2PfZ6g5SMdjSxWnmr1MwGA2JhUxtiSTypkqH4Y 2017-09-18T19:12:26Z reserve=1 # addr=mfX7cEamwkYkRbUJrrXXvoatWbAoGZj199 hdkeypath=m/0'/1'/30'
cPRnb6khn1kgQjsQDqsqUUoqcsfMhYBRstXyAL1GbXv4mCJ6i7qn 2017-09-18T19:12:26Z reserve=1 # addr=mfXTxzK38HGtyFYXQfLkUxPCqHyJQvPGZL hdkeypath=m/0'/0'/845'
cTcfhngLaH21pbhBNGoBBAZ9VUMtnidg2soESoTRUtcs1gPRDCLZ 2017-09-18T19:12:26Z reserve=1 # addr=mfY2NMWSumDYrS9qUAHWd6yVpX58P7cYqy hdkeypath=m/0'/0'/725'
cQv25Qu3CdbMv8WBNwcNWAmzgeRHkyuvhkhxjVwoyYkL8wFDdK8K 2017-09-18T19:12:26Z reserve=1 # addr=mfYXm11FhF4BrxBMLzBXoviA4dmA6s4ao2 hdkeypath=m/0'/0'/195'
cRuFFcZ7Bh9RKJFjVYsRnFfPeoHmU1g9po2jiAFV4b99oSQawXo3 2017-09-18T19:12:26Z reserve=1 # addr=mfaNEGCWTUSTjV74csgU48M28XeHxuKVMZ hdkeypath=m/0'/1'/60'
cTDgAs627gcpYGmDqTFgdMCZFqHHgdx4uvGMBQvo4bLJdLGV7apk 2017-09-18T19:12:26Z reserve=1 # addr=mfafQVAcuDD7zrek7V2hXH9tpQVkRyWreG hdkeypath=m/0'/0'/460'
cVVuidrFg911sww3f8JaAqGacQQUyq3LcqTbpAo6rzR3hmKkmdZV 2017-09-18T19:12:26Z reserve=1 # addr=mfcY5a9q2TX2K8QgjS1uerraSp28JAJqDo hdkeypath=m/0'/1'/116'
cMoZ8voCBxkWTKSLJV5NoN1gcJ7SA9sh3RbMnLPmtMcUY4B5ZCaL 2017-09-18T19:12:26Z reserve=1 # addr=mfdJh6gnZin9iWA8wwZWcJhwPgdEoAEHdG hdkeypath=m/0'/0'/635'
cRwQpvfsgHL1YfP32QCLZp1rZiJCDg7tTwYy14xoPttNJ8W4mjJo 2017-09-18T19:12:26Z reserve=1 # addr=mfeCBSvj9oAmdGMG2phoXNfHSg4dVavk1h hdkeypath=m/0'/0'/325'
cNHFKMBXzbKp65ytTJBiF9E4cu4qpScDotNQL6r9yG4Uw6ipadim 2017-09-18T19:12:26Z reserve=1 # addr=mfftEQuszis2f7yKcCJuRC2JkF7jPQR4Wq hdkeypath=m/0'/0'/783'
cPVbgWezdXVijdzjAMayFtQWepzVrYTVX3Wk949gk7vZDaNpNMvj 2017-09-18T19:12:26Z reserve=1 # addr=mfgmonsaJzLFS1rPZRvAF1UNCEURsqGhut hdkeypath=m/0'/0'/870'
cVjHGeShf8qGH5yu1vMu357hCjz6ToHmgHUbdKkTTxLucZzW3s6Q 2017-09-18T19:12:26Z reserve=1 # addr=mfja4BQr7tBoJRhVFzFLTPEPkhwWuTk2Ma hdkeypath=m/0'/1'/5'
cPd4rtRPXBFPorMa395Jaz43kYkWdKBEL14qEgZnnKTqsd9uCGSK 2017-09-18T19:12:26Z reserve=1 # addr=mfmcBLvT4btK41jF4q78FhHqJuXVEPvCpB hdkeypath=m/0'/0'/20'
cUy7KrF3ngkHWcs3h5DPVRKJw74HzUG5H4mUHHDfp5NKqYftb9ob 2017-09-18T19:12:26Z reserve=1 # addr=mfo2braQsYCHiv9TSZDTMpRGo5jUNGV6tF hdkeypath=m/0'/1'/128'
cUDfnjK92pvR4GW5sALwkJr8Do9qJ3hPUWTtsLQrbZG4UGQF8Kzp 2017-09-18T19:12:26Z reserve=1 # addr=mfoWT5kXtHNo9NxKoCCjRJf2tfJ3iRju7s hdkeypath=m/0'/0'/788'
cVAcUB3FKDH8qRmu26S1Xn3dHPbVSWbE5u48QmQzNxYnkZBFgSv6 2017-09-18T19:12:26Z reserve=1 # addr=mfomDSHg7Dkvxr4DkELRFVd9jjGeLhBGFj hdkeypath=m/0'/0'/750'
cSMp98cCCdkpNF8Xvnqg4XCT77a1RhPLZZ6fSMMSLRMWkyFo4Mrf 2017-09-18T19:12:26Z reserve=1 # addr=mfp6J6m4H7XjKnP2ypqRYcmpR1zBSn4AZj hdkeypath=m/0'/0'/875'
cQ9oJ1zCFzAq1HrMMZJ8vAP9FDeQ5PhsUP6vHsJfPa4faxo8L7XC 2017-09-18T19:12:26Z reserve=1 # addr=mfqMqsiFJ6NerkhRJuGoxqJ6vTsrJytobc hdkeypath=m/0'/0'/521'
cMhZjftGBWaxRWuK6SeVb5u5xdX35YpcAh19zFKuBKuprjVAHCuw 2017-09-18T19:12:26Z reserve=1 # addr=mfsxPH6zuw32xmr5dhX3kzFcrqUayXrGoK hdkeypath=m/0'/0'/198'
cV3bwqAR8LdxgRaXBV4vAhHTMUHwpNLCBuuAn7dgyJBhEwpdAu88 2017-09-18T19:12:26Z reserve=1 # addr=mfvn5bzozCoSgz9Bz3AVd6AGCAMKos1wdE hdkeypath=m/0'/0'/166'
cUgZr68qTJQ8wNFVTCReMpfv28VHVMsKLCfTeocfNCMSXaHtGEkM 2017-09-18T19:12:26Z reserve=1 # addr=mfwe3oEA13AtNAFYTeNVeHfDBRe8Y7pfXk hdkeypath=m/0'/1'/189'
cNBaTKHUZJtXQgrBQFpVcVu1ftXnfXH8iEXTjPwiqMKNjcXUUb4o 2017-09-18T19:12:26Z reserve=1 # addr=mfyYF66eFMZZEW1YNU8ko3AEc1NxPDpwQa hdkeypath=m/0'/0'/100'
cMdKZvGmNygfKGR1qYSxaSLnjvdVxLpVwNEvLsXdAdx8GBTG4xy5 2017-09-18T19:12:26Z reserve=1 # addr=mfyc28cLaBNU5eagreMbhE7ZJBy331q7ud hdkeypath=m/0'/1'/103'
cQkQd9vxFGhY83NhiWcTvsT98VvJV332LN5k9rAJzfdqbWspXTcB 2017-09-18T19:12:26Z reserve=1 # addr=mfyhcaQVVdhtnkxk73VAdSKJbRDmD8zsvS hdkeypath=m/0'/1'/181'
cU3U3JXz3Nmr6yar9viqqSmMf81DQeaogbZN9LDwBaA7LK4CiJmY 2017-09-18T19:12:26Z reserve=1 # addr=mfymvVPDE34qmBo5CpbsHHkTM78WCVcdeS hdkeypath=m/0'/1'/198'
cQEF1CVs2KT3WTJ5Djk6ndQUazqhUphtHHsrrR2GyAyWwbf8TgfR 2017-09-18T19:12:26Z reserve=1 # addr=mfzML9isnEGuRZNxspkMN6PquGaKbUbApm hdkeypath=m/0'/1'/6'
cUe51W5TH3qyYwdwUb3fSn3qZJPfpUrUP5CRFQXx9bdcQCNeXtQi 2017-09-18T19:12:26Z reserve=1 # addr=mfzYpdTDEoP1ZDQFGFLzCH4dNXuP5496wg hdkeypath=m/0'/0'/524'
cUKeW7Lgog8EJnaVvCTHM2VJt9y4LScpoUhhjiXCkVjZrpja8Lxf 2017-09-18T19:12:26Z reserve=1 # addr=mfzqd1SazPjMmFEtgcpnDtwcNuoCNkS5Ns hdkeypath=m/0'/0'/963'
cVgy2ciTigtCsxSP8xWJww8e3i5HJnvvQs2AQR7pyrao6472jrw4 2017-09-18T19:12:26Z reserve=1 # addr=mfzy1bZ9KS5TVpYp6hhxU2KdXTn5NfqEGc hdkeypath=m/0'/0'/363'
cUGrwHz1hKn2RE9QPQePsnUDa8Hr1JzsNq6naA62NQ5tv6AMq9Ed 2017-09-18T19:12:26Z reserve=1 # addr=mg24nppTicboNBREawhno4h7oYrn5Ehzca hdkeypath=m/0'/1'/301'
cUVrcE74icmrtCUAuUNvnbWrthv4uptojywg82By8JyfGBnj5Jjk 2017-09-18T19:12:26Z reserve=1 # addr=mg5dgtgL48jcyvKaWKEoSzuiTYL3np3432 hdkeypath=m/0'/0'/435'
cS74qVN1ae87rFWs8zTaoSzoLEKoacCMHgBkohztkzmLfETHbRmf 2017-09-18T19:12:26Z reserve=1 # addr=mg66ivjMqTawMGErboBVk6YRpAoJ22FZmb hdkeypath=m/0'/0'/693'
cUMGyiiGH7QH9dYfo5bKhNAj9maMWScXd9uPKNrTwxAnnaE5ptK1 2017-09-18T19:12:26Z reserve=1 # addr=mg7vjMKssY9PLzATH1bmVg9GZYSozSNp9q hdkeypath=m/0'/0'/653'
cRVAyqcZJsk3Kmo59e3Dqsu3BMFC4roJA9zFyRtjXqnEd5gmuPE4 2017-09-18T19:12:26Z reserve=1 # addr=mg9owk3CG996DLLXekkFdMno8JjjiT7ZZ3 hdkeypath=m/0'/1'/144'
cMtiz9a9EethEytbyCCTiKabiDM2gPeiaxN6QTP3SUGKJ8ZcnodD 2017-09-18T19:12:26Z reserve=1 # addr=mgBJRBCeFRWZQfx8WCBBfXdbeDnZvNkLXH hdkeypath=m/0'/0'/22'
cPwtj9HiYkMRxWpRy7NxBoBtwLeoBZDwy42MoKDk9RSCs5vYAwSb 2017-09-18T19:12:26Z reserve=1 # addr=mgEJhby7hjZpdwwyEjaGx2XJnkDy3prVqT hdkeypath=m/0'/0'/247'
cRkUgMf21JGtsKdd8K1FYnnT39PZC1aAW3fob6okP9SxpSqaEHGQ 2017-09-18T19:12:26Z reserve=1 # addr=mgGp46ihVqEdmNsVntFfURqzkuTYCMLX6h hdkeypath=m/0'/0'/849'
cP86ro7xPC56vcDeiE8VfASCVfRAySSWXiBG2LQWFntGgBNM2XBD 2017-09-18T19:12:26Z reserve=1 # addr=mgHhjD5PFQZJNQcArwXsFZSgPoRA2q5Xgd hdkeypath=m/0'/0'/968'
cP5oSH7Vmryjx5f4ZawC8pDuwZf13ppZuQixQ9iyKk4UvVqxvNYo 2017-09-18T19:12:26Z reserve=1 # addr=mgJdTEGRJjgamgboWQQouxAkG68XMKNAth hdkeypath=m/0'/1'/156'
cP36EPnWCX17rDC6eEDKAvABU54NJRBiPaYfGdjLxSYBjJV16XYF 2017-09-18T19:12:26Z reserve=1 # addr=mgLYtXM2o362mqgnu1L98GUD4BKNJMGZwH hdkeypath=m/0'/0'/625'
cVhQcb83xJEjhUKsopmjSa7qGuLhWJEJUH8ohM4gwQg8x6WnxwMy 2017-09-18T19:12:26Z reserve=1 # addr=mgMST1dNEKbdpUL89JuJ7tucNLfbPDj4s6 hdkeypath=m/0'/0'/588'
cSn5pZaz6GEqDXeiXyWiQHDvEd8i3rroNyRAJqBrWfhpq7eCqK4i 2017-09-18T19:12:26Z reserve=1 # addr=mgMwxCPC6ihG5YSysEPD1ZSbppuyA96MWJ hdkeypath=m/0'/0'/662'
cRkjmnG3576D72kiyemsRD63zwVEiYQNCkorrGSUiE26ktXAanac 2017-09-18T19:12:26Z reserve=1 # addr=mgPRxzaNqXWBukmM5kd3hTia8Td1brng2o hdkeypath=m/0'/0'/380'
cPb8emkLsQFgZ65Znf8tQ7jEKo6EikKFPb3LskJXUBQWGRcZAHhJ 2017-09-18T19:12:26Z reserve=1 # addr=mgUY817xR7aWq1N38nvrkJCQ5NL9iKFTfR hdkeypath=m/0'/0'/41'
cMxBC4eGzBsdk7d2iMx2Vq4y4Nf5eLNsLbyh3DwG271TwikG6hhM 2017-09-18T19:12:26Z reserve=1 # addr=mgXMPYuhyuXYmyR42BYGca6XxwD1mGqv7p hdkeypath=m/0'/1'/153'
cNqCVFqcxW5uqDvQ1hVfxSoQxdEjW6tZD5FoBbP2wLyVs9W6G5vn 2017-09-18T19:12:26Z reserve=1 # addr=mgYHWWh7okm2JVevMjztTaNHn4Rfsuc6rq hdkeypath=m/0'/0'/478'
cUuAELbXdzPGuk5oxauQyZLoZvSTqVMbmhbJ8uHtPtExyze5ixzv 2017-09-18T19:12:26Z reserve=1 # addr=mgZnTfhTDE8ET6Gv837DMvv6mBPpTLZha6 hdkeypath=m/0'/0'/237'
cSkABPcFdcNE5kVoeFhRUQczt61HaQFU5Eo162BXraHLyK9jtuzL 2017-09-18T19:12:26Z reserve=1 # addr=mgcnM7S3WST5DJxYEwh53RAHpZnXoxZBLJ hdkeypath=m/0'/0'/497'
cQxRV2DziyuLoqy9TL3S7gyaafMyyfp21HTMrMkD7WsotKFtbHef 2017-09-18T19:12:26Z reserve=1 # addr=mgdcQj1CJX6Qi6F5C8Rec6D6FarM6y8M9a hdkeypath=m/0'/0'/261'
cNt3pNZSBKFzKukxqWx5J2WAYs1jmE2yasiww8n3ry7QQ5FFiVGg 2017-09-18T19:12:26Z reserve=1 # addr=mggjpuKGAqPndHvqUhXdrGP8R22CrfvAZV hdkeypath=m/0'/0'/357'
cN8iNvSqDgRgsZ6TCb3kJWiSdDq8WtM5Jj8zWS4seUehRsVtfg1f 2017-09-18T19:12:26Z reserve=1 # addr=mghQ9DYfth9wf1dyouwYdxP39zYMr9gp39 hdkeypath=m/0'/0'/611'
cUR11zG7QB3nUZ1LRfarivSxPz7q8g3pak2W887rifVeE54JJgdE 2017-09-18T19:12:26Z reserve=1 # addr=mghYouw6KQyndkr4p15EMC7qE8YjvgUzdC hdkeypath=m/0'/0'/95'
cPZZsqBsdn1cxMfr8a7bCqfChSP1SiWkK9MiC9Tgm9EMQBzMEaPV 2017-09-18T19:12:26Z reserve=1 # addr=mgiaATPDAjuuhiia1WgtefgKCcJk4MHhnw hdkeypath=m/0'/0'/359'
cTZw76RGDARXZKdvaaQ7a54fg8FS6PkF2qTwsi4qWnZLitsvC1rZ 2017-09-18T19:12:26Z reserve=1 # addr=mgjGN46xC1xn5XPxoSzu66goMUZHBHLRsD hdkeypath=m/0'/0'/712'
cVinRphzVCdV3PNX6zyecjj7DRTX6voUUaDUiqYmyTt9whhV53ZY 2017-09-18T19:12:26Z reserve=1 # addr=mgkakhnfWh6bXyJ8s6KHw4GEJqebASzE3g hdkeypath=m/0'/0'/150'
cUWq9LEUq8uQjZdDgwSTFNkvHdRGpSFWH2Arz8oZnSvzKMVDiRBG 2017-09-18T19:12:26Z reserve=1 # addr=mgmCjiVVqzhNjwJZ8uTHwmiJpD3KaJiMxY hdkeypath=m/0'/0'/931'
cRzPwRyxm7Lsdfb1tit6zAGMHPZxHD5pNgFn9VaHBisMgcx1kN79 2017-09-18T19:12:26Z reserve=1 # addr=mgmETogWwFfN3Q5MLxCnypt1HGDjNWzeK5 hdkeypath=m/0'/0'/418'
cTwtS31QNgvwLyW4GjzWNDnzXKUXXDJ7suUkLAokSG66kLgTA3qJ 2017-09-18T19:12:26Z reserve=1 # addr=mgmQZd8n6r8yfiuxvrHEQbPc5cu1VX8Rjk hdkeypath=m/0'/1'/248'
cSgbxaxtcvPP9KmY7hTRxtJC54nvVL22XQytTofdstTNCHB7odkF 2017-09-18T19:12:26Z reserve=1 # addr=mgojwBbnCmcy6h6aEUxkqQvq3LGNWw3QfE hdkeypath=m/0'/1'/240'
cPK4C5rXbBpjyzwZwg285URb3AwUeNUwG2LPMVaewdjpRAJBnLkE 2017-09-18T19:12:26Z reserve=1 # addr=mgqBL6VNo4JDdUiXpbSrbqeyMLgKh7eVAT hdkeypath=m/0'/0'/111'
cVzkdVL55VQS1ZtZheUG3BJHF5STtqjQG1wxogxYbXmSxKbZx1Mo 2017-09-18T19:12:26Z reserve=1 # addr=mgrFMXnHpZYFsrNnv5RFvzZUb3z6Xgs1Q7 hdkeypath=m/0'/0'/879'
cUtCRTwfNUwRtRZ4tb2MePoK1hW8mdbrYnmJAoa2Lu3NcR2NL99o 2017-09-18T19:12:26Z reserve=1 # addr=mgrxNJXe4kcrmfxXfvZT1ju2GNqJsWDP3P hdkeypath=m/0'/0'/165'
cTXju6oD74QJCAB8uDKhgB3WNUBXGuPvk3wXU9oT45tfiGp4rsfn 2017-09-18T19:12:26Z reserve=1 # addr=mgtRpaaDbYg1nFtLj1e7ArYbGkc2VH3mmw hdkeypath=m/0'/1'/124'
cS6fMWZCs4D7FJthikDr3kgN7zvjUSG6WZHsV7aMbXfd6isBjuT7 2017-09-18T19:12:26Z reserve=1 # addr=mguHHUWELMJWvvaudfdJYf3nuCWGCx2A5w hdkeypath=m/0'/0'/952'
cRsZUuoHMDVxFCoBqsJaVN4q1xjb9Qen7brkqHyRJgUqSw2hKueJ 2017-09-18T19:12:26Z reserve=1 # addr=mgun8z5o5KyFnPJKyVcENKU8iaFCBiDibt hdkeypath=m/0'/0'/83'
cRNVw8Lv9NfvbLbbmoqN7YjXW21jnqMgdJ5xfhi78zLYzfwGpwfz 2017-09-18T19:12:26Z reserve=1 # addr=mgvwYbA3QJAU4JMDui3yVdviLv98SiHUZB hdkeypath=m/0'/0'/139'
cPJ5CLyxkbeRLHCUUcA5AFCbo1R8W1kStU1p6H3NHVZwYEJR8CCP 2017-09-18T19:12:26Z reserve=1 # addr=mgvzrhhFuKmRNsrwVv8yPGVUFzJjDfeqvf hdkeypath=m/0'/0'/844'
cRhtQYF3zhzjSuRM1mhZFPLZgoNUHtDNren39WnVai32CsfhDLRS 2017-09-18T19:12:26Z reserve=1 # addr=mgy28x85PnY49QZoimF3HMLJBoLqmre9JB hdkeypath=m/0'/0'/577'
cTkUtTZBQTzBphoVkNBx1WgnJ8Z6LvfiJsmyATKDHw9Hv8j7guXi 2017-09-18T19:12:26Z reserve=1 # addr=mgygzo4CmednkXqruhcxG19yJqVbg3BXFz hdkeypath=m/0'/1'/54'
cUiEZUtqJ1n3ora9u3miFtjJH7KgVZxtPnSotPT88PUZVj538vJ4 2017-09-18T19:12:26Z reserve=1 # addr=mgz4mgyfX4TUVBeYGqLLNAsSkFVur1qaL1 hdkeypath=m/0'/0'/991'
cPMUx7whzrCAaKmDcUm3Uw87XxGMmSujrFgjPm1ShUjdz1G41Ssp 2017-09-18T19:12:26Z reserve=1 # addr=mgzhexcGPnxu7kdcxVpaqzYPVNZnrWPEVE hdkeypath=m/0'/0'/432'
cPtkoZmZTqRKPE5a7w7xFHmXkXsF4ZReytLA45ss6hZJDJsiJyF1 2017-09-18T19:12:26Z reserve=1 # addr=mh2TyYXZMosidMHj3UCKJbynkVLA9k88hZ hdkeypath=m/0'/0'/702'
cNDeMQXduT1773V7tANE65kW8hTHdaqXLPxfZQv8VQzUD1jRHhmq 2017-09-18T19:12:26Z reserve=1 # addr=mh4VoC7FxTPyzLLE2hCMB9qjnYjUccAtjL hdkeypath=m/0'/1'/97'
cTAkLCTj8d1ZKG4k2c222SGKmDu6MxuCzZcEuUBvJ1EvgB3AeSuY 2017-09-18T19:12:26Z reserve=1 # addr=mh5Fs7qQ5hVVHBV95CTd7TiL6R6xKDCtmZ hdkeypath=m/0'/1'/7'
cSCR2oEupHhrBj7wxYp6rt5vho9KZrW4TFokj3Ta9AyZJ4xPfEVj 2017-09-18T19:12:26Z reserve=1 # addr=mh6W5iiDmApTbzoWWbX5oz74sqAKS8mboS hdkeypath=m/0'/0'/956'
cUFfbDFCetV6dyenFxMamsD69YFSxAMfjRMns55frjw1j4zNVSAB 2017-09-18T19:12:26Z reserve=1 # addr=mh7Qbvv13b7Ej9Qk3yhbV6SCmXdL6QGs8Z hdkeypath=m/0'/0'/542'
cQHJAxkPzshvHEJr6DDpZTpQtpsgdxAXS6Sq5Wm6Z151Trt4jeeW 2017-09-18T19:12:26Z reserve=1 # addr=mh8LuZEZkmjDiT54mhkAQZZdNMoWGoQQ6n hdkeypath=m/0'/0'/458'
cTWm6AYc5a6txkkyinv3LzDbXUgwwpXbc7KctH1grQ8ehYPR1Kzh 2017-09-18T19:12:26Z reserve=1 # addr=mh8XtNtizKKTbJm8M53vcMnGccchkW1xqT hdkeypath=m/0'/0'/690'
cV4GF3MrngdszfuMYcPeXvEA2MD8eJ6tJ859VX6UPct7PSwfBkZq 2017-09-18T19:12:26Z reserve=1 # addr=mh9bHKZaUwvpZA91gCZCyqMsWz4GSj9gCG hdkeypath=m/0'/0'/379'
cVT46Quvai57PtVThyWGsYuDKdpP6meEdVUdEqkJYjp2RNrwWmxG 2017-09-18T19:12:26Z reserve=1 # addr=mh9t7dKSRLxRWbihfssoT1XGFJCDs5FsrR hdkeypath=m/0'/1'/221'
cQcfMPiaZAvxuTCoxRWFvqDNQqNcUYhfu3kNbAd13bXpx3KnAZvt 2017-09-18T19:12:26Z reserve=1 # addr=mhAsFXqHTqZCHCz984ezCzTZ1ouSa85iCW hdkeypath=m/0'/0'/957'
cSV9iw52bDtnKauFT99tPokaFsATJH6wTmA7y5wU7L1W1HbYjPfq 2017-09-18T19:12:26Z reserve=1 # addr=mhD5aMUvvBidi51aPtGX5qut6vrJNewMee hdkeypath=m/0'/0'/876'
cPpTAoez3UFBs7Ss87XwLpATK7YfUVKjJF85VHpkWBnvTKWG1xvR 2017-09-18T19:12:26Z reserve=1 # addr=mhD7kSbqambret4VykN31hUkgCqvKw7D3H hdkeypath=m/0'/1'/257'
cRiGkRMKjzEP2LMT15z4BunT5X8ByrZUZgaEpXbRNAwESkDDQVay 2017-09-18T19:12:26Z reserve=1 # addr=mhDBJfHZ4zeA1w2AxsChfW45so6v2DJzAq hdkeypath=m/0'/0'/107'
cPQDVwnnEQWcd9FDbbdMi6iZBg46BcEKJVZzYxeui4bbnBHbffrt 2017-09-18T19:12:26Z reserve=1 # addr=mhDTTNW8Cjuqamw69MhaVnpmqh98sVThZU hdkeypath=m/0'/0'/973'
cTPzU3FsrwYhtDmwceNjmGgrGFq8zpaMwrQAz85iHw3PYAaHkG8D 2017-09-18T19:12:26Z reserve=1 # addr=mhDcJUuV1ZxYbV5xWjYP7zz99TXJYwEeTX hdkeypath=m/0'/0'/246'
cPYTA7xxPEkGV4NL8gFmSCe6R4eu69SLCLDmQM816JuiJnUjp5ao 2017-09-18T19:12:26Z reserve=1 # addr=mhEpZkVypE67XGxM8Aemh1x1ZDKzew5U2q hdkeypath=m/0'/0'/490'
cS95FLFX9vCK9joVhZEArmN7gtHAHDRNLvxj5f5rtWER4hPBu4Zw 2017-09-18T19:12:26Z reserve=1 # addr=mhFM3JHBJFx9scEU6ruErv8puj6cJfyC3y hdkeypath=m/0'/0'/556'
cTVTztRBrW3LqwtxfnKg1zou4Y194h2HcQdzSeNiAmUHDw1cX5mS 2017-09-18T19:12:26Z reserve=1 # addr=mhHCVRyyNiwTzTNLzVBXrbJMzoZ57uGX8M hdkeypath=m/0'/0'/60'
cRUrrM8eDyAmA4dmhc6rRyk1nwAA1BHmKkLa9N5P7qP68hUK96PY 2017-09-18T19:12:26Z reserve=1 # addr=mhHEFFqRY2yinZgvrzj1QVnGTEgZRreKY4 hdkeypath=m/0'/1'/53'
cSrqGuJeguaiSMcXsJh3ucGffDGsawATM1boex8CcMJRRFHjW15G 2017-09-18T19:12:26Z reserve=1 # addr=mhHu5fHf4GUof9s2TF9dkM5H23A9kE8qYa hdkeypath=m/0'/0'/574'
cRtRWMDFSK2ptwjdWSZhYppWn8i85UJMgSZkkoTsVoyc5bhLksYA 2017-09-18T19:12:26Z reserve=1 # addr=mhJm8kuu8tLUz4gZJiRKceWY9rsxx6XDwC hdkeypath=m/0'/0'/26'
cUqoD1fKbbmiynJn1CE4Mudua9aXCBobojRVvQFYUJbiXke4F2pF 2017-09-18T19:12:26Z reserve=1 # addr=mhL7NSncF4nx8zvyqptWrp6nGVKyaSrNJ6 hdkeypath=m/0'/0'/865'
cPUboeZpUxcDgQZq9E5Cgf4P5sXvKh7PbKQn6tDQKUjo8dnW2hja 2017-09-18T19:12:26Z reserve=1 # addr=mhLRN4micxcLs8BcLNxfNauakVZHGFytSd hdkeypath=m/0'/0'/446'
cRYzbeAzJej1hVjQt4GkAyzxhVrfExty8ozTfRNyKVQPpD99FCAA 2017-09-18T19:12:26Z reserve=1 # addr=mhMRk21dfTQbAyE7azEzkWH27qoLrMysEN hdkeypath=m/0'/0'/121'
cPvc5bBm14Y3CXNqXwdvjaQEMrVVz7wvpZ3gs1ShwzU2oJPsZeXn 2017-09-18T19:12:26Z reserve=1 # addr=mhMw17TSYgE4jzoJHiayhqn8Sc9ViMYzyT hdkeypath=m/0'/0'/241'
cVF6hweqSccJn7Vfoi5dx3dJnq3nNawQAuNedPLJvJWnghwJGh7k 2017-09-18T19:12:26Z reserve=1 # addr=mhNq4Xi1vWuT7CHME9XU8QBpA23TjuTS8j hdkeypath=m/0'/0'/216'
cU9p4ZV2JUjGoSh6KoXEQGuNASy4JtP8MD2ntV2mLSauZG3W6e2W 2017-09-18T19:12:26Z reserve=1 # addr=mhPsQVgPqoaw6bZ32jMckskYotgun7SLgD hdkeypath=m/0'/1'/159'
cW9Q5J49iCqXUwv22wc4ss3NxxdqVopCUDvdeD2V2TZhTv2UjoCd 2017-09-18T19:12:26Z reserve=1 # addr=mhQvmLiUUMrxi3j9ci2RmXvCtNiCvdztdY hdkeypath=m/0'/1'/170'
cNcbni84FPTzqv7sDHXtGiXpWZLdXTB36Z2JFFFYVz3UGM9Ygobh 2017-09-18T19:12:26Z reserve=1 # addr=mhSSb6xfyEF4MobdGzurSkcYH5zduniwWf hdkeypath=m/0'/1'/280'
# End of dump

109
test/ref/btcwallet.dump Normal file
View file

@ -0,0 +1,109 @@
# Wallet dump created by Bitcoin v0.15.0
# * Created on 2017-09-18T19:09:18Z
# * Best block at time of backup was 0 (000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f),
# mined on 2009-01-03T18:15:05Z
# extended private masterkey: xprv9s21ZrQH143K354NmfyK5jphFPnQrgpbN7q8gB9ybaFhvJB7KXbDsRywFp9pxZAK94DW7mFJ86F2qD6oYYLTwuNJ6DSbzRKaf9NM9gjKTo1
L5LUujY27o8vP719sKccwRr3XmdC1adSfAf6xhZFa8Gv6dmgY6BG 2017-09-18T19:07:26Z hdmaster=1 # addr=16DKtHYwdUQ4bvTfVk4ztsGaee55c4q92u hdkeypath=m
L1x2Fesucugt9HVTVdkUjanj36ecsx26Ab8fhkQuuK41tY6TgnHe 2017-09-18T19:07:27Z reserve=1 # addr=113dkRcsZF8oubiFvt9hy9D22zgk3pjmVT hdkeypath=m/0'/0'/336'
L4yrXL47zC9kpm7ziShPNMAAtjMZnHZMNBWaBwa7SgKqgTsBH6W2 2017-09-18T19:07:27Z reserve=1 # addr=113pS8xCuWnhUKRBw22LFEnBxTXnK6poDb hdkeypath=m/0'/0'/679'
L1yU69qpjdV51R4381J25QYus1kJx9ruxwqAEgVHRBT7a35bZ6g7 2017-09-18T19:07:27Z reserve=1 # addr=114Lpo71r2iHoPuths1oQkh8kFSxu6BCer hdkeypath=m/0'/0'/287'
L27BH682oja5y3RmNf2TtoJwAZ3kEQCiL3YLsZGFdWNVUXwjK9Dq 2017-09-18T19:07:27Z reserve=1 # addr=18aiMArDWheSKw3CZ9sNo5YaXyUwEimTZ hdkeypath=m/0'/0'/381'
KwFqLv7eAY8juMYrNXS8Pq4wxq343uksWk6JP2w26UbTpddZ8odp 2017-09-18T19:07:27Z reserve=1 # addr=1APUKkXm2c7a8cxGvQqXNu1Xpm8gTXXsD hdkeypath=m/0'/1'/384'
L4FpgfDg3Woo9fN3ZcfX5LY6VFQYrzBgFYWAAFnYcgkRRVCnNe3T 2017-09-18T19:07:27Z reserve=1 # addr=1BpQS3NHZbRhgW3cDmJZUSm6THmHKTe5e hdkeypath=m/0'/0'/184'
L5iYZMCdEUXruDsxLmFfhbCLUZJxLquJf1STVNq9XWGydQTSV9or 2017-09-18T19:07:27Z reserve=1 # addr=1C5bSNmBHhPykTMQ6uvKnpmkgyURkj6iF hdkeypath=m/0'/0'/668'
L5U4tDLoVZf8bxRG7DdYp6QRcPD9FqNqX4zNhnW2wKK1MXLTXwtT 2017-09-18T19:07:27Z reserve=1 # addr=1CbV3RYCf8esKdvNpDDahyYVLvG3etjt5 hdkeypath=m/0'/1'/135'
KzXLu5rU4mZLwxF9qqdSmjF1ZBV1tQter5R9nXBAtrWZymkyfztc 2017-09-18T19:07:27Z reserve=1 # addr=1CtKBXTHhF4cUUdEMCdJVFs9jwn9cDRJx hdkeypath=m/0'/0'/460'
L3yRscb2sCE6jTgCiVWLByPLUxvUHbN2SUUjH3RxP6GEgQaxtajt 2017-09-18T19:07:27Z reserve=1 # addr=1E5icionAv42fy8CKfwW5RckZZytsznua hdkeypath=m/0'/0'/278'
Kx8Jhn21p8gPqmLZjWwSPSPei4wDATADAsXQEm4Nogqy8W6SvzBs 2017-09-18T19:07:27Z reserve=1 # addr=1FfTDTzp3AJiWytPLk9PdXRNE3sfVghPN hdkeypath=m/0'/0'/681'
L4dxASzxJSk7jcjW6qpwFXpmdBqQudbcA8xjo7q1qd9E1DADVakn 2017-09-18T19:07:27Z label= # addr=1FmABfe81aZ2aikRaxSyFFAT9y6bHb627 hdkeypath=m/0'/0'/0'
L3Twqq7LmXhf5boqxxrguJPt9exvAqVV7KjdRVGpGhkJ3R25jrbb 2017-09-18T19:07:27Z reserve=1 # addr=1FqESrZPXGNRda2CTVt2AocNJ1QbVQgh7 hdkeypath=m/0'/0'/546'
KyGs5ZaXzpfJbkx46UDehGjEjHSNHSSKWMXwkgDW2cgNXERkMGU3 2017-09-18T19:07:27Z reserve=1 # addr=1GiJttRW18rVVGrT5y6R38Hyhfw8tnurt hdkeypath=m/0'/0'/417'
KxJ3agJDYe2qnd9ZNSenxjAhzFnoC776ptJdWC1cRC6sxf1MfD68 2017-09-18T19:07:27Z reserve=1 # addr=1GrUMXM5yEcXLWgegqqnPAHTJJ2NHbgms hdkeypath=m/0'/0'/8'
L3aZ2jfMJ9YBWSfG5LQ7owZgnLJkDuBanuB7dpn5b7TCoqHpbnZe 2017-09-18T19:07:27Z reserve=1 # addr=1K5eBDNPXNLH8FJKNtWm11B86LgusXMBH hdkeypath=m/0'/0'/449'
L5WwGbDYfBGsdP1ptTbhRUb4vxNzbJ6j5SA1py33doAcG3zqgmpN 2017-09-18T19:07:27Z reserve=1 # addr=1KuuABVjF3YeBssdagXP9nGATaGg571D5 hdkeypath=m/0'/1'/228'
L5J4jJjdDv8uQ2LMxr19HHXixyDMps8B4fWdJ99v3MyadgY2ekia 2017-09-18T19:07:27Z reserve=1 # addr=1LmvAqEE215Vy4zi7Qywcjagp893JrvYU hdkeypath=m/0'/1'/481'
L4fw5jvacrg1ZgULLabaDN6RPoHkv8V46QTahms7T2mC7rttjk2t 2017-09-18T19:07:27Z reserve=1 # addr=1MSx2SQZVfgo5bt3kD2nMhjuvXgMjZgno hdkeypath=m/0'/0'/784'
KyAxJbSbHnNLQr11e91J4SNPfynS3tAkMeh888FMAJZhyseEwa9b 2017-09-18T19:07:27Z reserve=1 # addr=1PnJpTMpyMhg2Hd88vm9JemJ6AmzPHUNx hdkeypath=m/0'/0'/740'
L1YWjG83Pbegm8fNKEu3g2JM6jQuYcfvAFFhFo21yVGJksW3kDw3 2017-09-18T19:07:27Z reserve=1 # addr=1QMKxPV1xmqsLvpjLGYdRVhsk1r2WwMuo hdkeypath=m/0'/1'/256'
L4zp65kGkCbWaHWbFu1LqGjs7kYgYeKWapKxQtuc1BAmGS2qwKrX 2017-09-18T19:07:27Z reserve=1 # addr=1QnZD4EQVCv7NUQdwCNstw5CAQ5aFa3UF hdkeypath=m/0'/1'/425'
L2SzJD8DqasrVpLvZhzm11pJ1UYhDDBKFNoCwpWNTZUuJSjxoY3n 2017-09-18T19:07:27Z reserve=1 # addr=1RAZnDTjUntih19Cv67YHCpxJXoMtQWQK hdkeypath=m/0'/0'/137'
KxoyRUoDQoqcqpHSKwY9JpNaM7hSvkBn8WwwCvNQA79gH6jYynAT 2017-09-18T19:07:27Z reserve=1 # addr=1RyxjcAbMxDApAWhLGiw2E6K27mW6PTgm hdkeypath=m/0'/1'/213'
L411UbAd5dHVVHEkS7BtLXSQvRhB69aL2H57bzzAAEn6dP413Xhu 2017-09-18T19:07:27Z reserve=1 # addr=1S8fDdBWnu8xMw3fPDqMGBfvzGFcPTGXs hdkeypath=m/0'/1'/433'
L3VsCkFJavPZuGB7uLDSYDDbHJh3f5x68xb37zZt35oQTrAadtNe 2017-09-18T19:07:27Z reserve=1 # addr=1ScMi71DJ5KqtyZLkHLkNqMKB915tJf67 hdkeypath=m/0'/1'/448'
L3AVSiPVrewmkV1TKnpLWAgTxDb9VQp2gxGxP7K2AJXANfqqPGW4 2017-09-18T19:07:27Z reserve=1 # addr=1SizkyFfRsTP4jNWpZBff2Z9HzfeuBxta hdkeypath=m/0'/1'/294'
KxA9ZwF4gYdqTDrR5YBAJo9SwqWnyTn9VpbLFNenQ11nfUrq82Tk 2017-09-18T19:07:27Z reserve=1 # addr=1TuVu4VC6KRiay6Z5hapW9qXXYj5TTWCT hdkeypath=m/0'/0'/52'
L42jH2MdBvPxUwTcnokrvKHFnygwkee47pJ6ESQEAF24KLsYQYJy 2017-09-18T19:07:27Z reserve=1 # addr=1V73irXxmr8LyK2s4w1vPfBPSeq85md5M hdkeypath=m/0'/1'/194'
L1vAFgS3X6zYTkGNq4EybZRxvnkq4vu9NLLFqm3QznEVu6XuDQEC 2017-09-18T19:07:27Z reserve=1 # addr=1VVAzE5m1rwBUyaWbpbwHEM13SptJDGkm hdkeypath=m/0'/0'/202'
L4pUrVxupTRQeU2SzM8sGJ1ZvUkaJT7oKFtS3Wkot2yo1CcYeeKG 2017-09-18T19:07:27Z reserve=1 # addr=1WNJAZboJJJ9mQ4bw6bo9VaiqRnWfdNEV hdkeypath=m/0'/0'/803'
L2WVZ5PoTmpDaGfSyHykJ1DxKa3GyNqX9Lhf3ZEw1zKHEMFZHRwU 2017-09-18T19:07:27Z reserve=1 # addr=1WcgqbW92nsvbrxkJ6ZnKphTNwzbz7NW2 hdkeypath=m/0'/1'/159'
Kyk9Kik13wFdMJWbbFqWHVxEJeWVjqXERWECx3vH9yAS1LzNcbBy 2017-09-18T19:07:27Z reserve=1 # addr=1WrsK2Wbt7JLC76xvRKcDsbjt81Z8ytNW hdkeypath=m/0'/0'/228'
L3S7bt5qqSkW72yjc75wU8LChNdRD9amZgZegrc5UCRrKe1apugG 2017-09-18T19:07:27Z reserve=1 # addr=1WwzHnRGAUqpaw6PCQcXV761uchpArajZ hdkeypath=m/0'/0'/430'
KwNQqjWrbDpsQGJQsWcgk56Kc2kbryF6289YcW2Fe83VdwCiJHcB 2017-09-18T19:07:27Z reserve=1 # addr=1XNwBbZLbau3a9a3aDF3A8SQrX6bgpFMB hdkeypath=m/0'/0'/126'
L1t9fwEWmnL6WJbNaP8kMbHVMhwSwBvn5WipH1kexb5zMUru9ydL 2017-09-18T19:07:27Z reserve=1 # addr=1XPBFJypcpFdxGYybE1rrvqNC27XtfKQB hdkeypath=m/0'/0'/132'
L3AtB99RYL9gnp85Yf6PXmL5D19SefFHqn4WUxfDy4ZEAn7u6ASR 2017-09-18T19:07:27Z reserve=1 # addr=1YAVDkpVPNeyoG11jRDp6tB2GQgAoZuWb hdkeypath=m/0'/0'/869'
KyNMmHu2sqPYo2LTXRS2FNiJ2mJGpXSLp3XFuEZNuKKJ2hcukAdB 2017-09-18T19:07:27Z reserve=1 # addr=1YHqhhg32w2BYc3oHUVkbWLiHdiiKPU8K hdkeypath=m/0'/0'/484'
KyCf7Reuf4QgLXjAqaVzjorSsyfmNLmFYuU2RhuQy1kpTzb1raRZ 2017-09-18T19:07:27Z reserve=1 # addr=1YMCcHgEJvTBhDhCUHTzvGVvPM949gvjd hdkeypath=m/0'/1'/83'
L47bETaCU1aTwqcpHovqcyGABNLGFTK2FctcWP5p2wMLa4cMtYs5 2017-09-18T19:07:27Z reserve=1 # addr=1a2u23iCFefbSszBfme4gv9fBHJ776xaw hdkeypath=m/0'/1'/148'
L2zjRo6EUeyzgw9nH3cCTB2zKH5rQy6xV51gZTowJWGbkrWBQt2L 2017-09-18T19:07:27Z reserve=1 # addr=1aJiMdsDbsaL9cEsXnRFsnvLevFj72NZs hdkeypath=m/0'/1'/466'
L2VnhKdSrU43zbxdFbgBf4qVhCabjA84MtVazF5GE5QXMgBeHk6D 2017-09-18T19:07:27Z reserve=1 # addr=1aN8Uj5jbJ7iFpYXNDoW4kiWCmSmKB3wU hdkeypath=m/0'/0'/520'
L5ic4PBs8sExopkP6KUcRJNpxSzjdsX1Zzrd7c97WhqZkaKpd2qE 2017-09-18T19:07:27Z reserve=1 # addr=1ateLA5VY2PcnUeGNAdbiN3UrF1iUUmMo hdkeypath=m/0'/0'/671'
KwL84Ni5ErcS4FwFVNCR84JPonMZ68TsAi1n7HhYv5Zvei87UDHH 2017-09-18T19:07:27Z reserve=1 # addr=1bYvPtsEyNQPQ3j4fdiRzSGg7682sMGeU hdkeypath=m/0'/0'/149'
KyEfXPW34fjrMND4xrDxBDNArXwZf7vi94zzoXjdX2jwwC3ArtR5 2017-09-18T19:07:27Z reserve=1 # addr=1eztp2sRfJ8xmpFGAEfT5y5JNqtuDTyzY hdkeypath=m/0'/1'/74'
KxJCF2wz7H6y6M5nUbRVg5LHDPq3UUZPEp5nYDaPFtK8rrPyUxwa 2017-09-18T19:07:27Z reserve=1 # addr=1fS8XPt2Rq2vqtgr7Ag5rPiXFxR4Y7Avv hdkeypath=m/0'/0'/486'
Ky2qZAt5bNMj29Sc8xTL5iXw3CJTHPavvJv6r1oBHDiAJ94hx76V 2017-09-18T19:07:27Z reserve=1 # addr=1hdoi7LTQPEKVnX9UAvDJJa5X3nhZaReq hdkeypath=m/0'/0'/161'
L3UdsWgTqP5ptzzepwr8rB7dWiJdsfqQYhpHioNgu7bKSXat74UF 2017-09-18T19:07:27Z reserve=1 # addr=1huWRtuss4wFiU4jsMhwPS4mMZDEhhkEv hdkeypath=m/0'/1'/55'
L12Hj3c8Jf9m4k4uhGJ4na2yJkwr5Nz951jHCcYbQqVKYFp2VuwH 2017-09-18T19:07:27Z reserve=1 # addr=1kVs2qc7qbVHDWydM8zDD6SZbX3geCmZn hdkeypath=m/0'/0'/243'
KxGFokkLAR3ChbHYF7A1dhgqm2zg2AtEF7rqKeA8eUCAKFEU9qfy 2017-09-18T19:07:27Z reserve=1 # addr=1mAPwUHuHFC55m99vjW8HGjBDcXHpFoRG hdkeypath=m/0'/1'/338'
L1sD7D5FgQfWXHucPYmSfoVysVkF9y5n9Ra3R3Xk2grEDDCFqUf4 2017-09-18T19:07:27Z reserve=1 # addr=1mSKeNhNryewnjEFRfXYAosY9N4JMRKYi hdkeypath=m/0'/0'/394'
L4iNbbeUUZMqkteAcgv4Mt5nTtnwnCKZxARvbkeamgrYut7DCFvZ 2017-09-18T19:07:27Z reserve=1 # addr=1na9m5Lf7PXLw147SGbmM5S9CqzvvmCdv hdkeypath=m/0'/0'/840'
L5TNqp59BKW3kiMdNEQy6Yy4uRxzy9vYgJ8DMYBPv2Hf3q5eQ134 2017-09-18T19:07:27Z reserve=1 # addr=1njSR5CtSZAjzYWsQofmU2DvwpcCGKBA2 hdkeypath=m/0'/1'/151'
L3K1PXVicWZu2M1WjojZ5LRFNJzGZt9YH8b8RsfeKH91VBSCtUvu 2017-09-18T19:07:27Z reserve=1 # addr=1oyce6ctVtzu7mHSieMR1boyupeEbxCYY hdkeypath=m/0'/1'/38'
L2MMwuFDfqLsUQBBJwYPX8RBN1u3XozzVLzTAuuVPJz9PBsdEkDp 2017-09-18T19:07:27Z reserve=1 # addr=1qFybRffWdNrRKA5t5HykBzGfB3yDoqd6 hdkeypath=m/0'/0'/985'
L3ZtdKSjKBsTn81nyUBay7mVYQ3wHmqdz4GKpX4oeytQGAKDPDQS 2017-09-18T19:07:27Z reserve=1 # addr=1s8K5CVkGNqLV14QvRPqYEhJVDsGwjtoe hdkeypath=m/0'/0'/518'
KzzDhtHdDU2ZnHW6ZNYLjoZC1Y5Yc65EoHK2deWWiygWdd7PABtG 2017-09-18T19:07:27Z reserve=1 # addr=1sJeE5EM4rKZm9eocsFV99K2wWxCGFuAW hdkeypath=m/0'/0'/167'
L3cWnxWhBNX1SPexR6qDU3Zhxo63eYsUWMrLXNHA7j3KD4MUfQAF 2017-09-18T19:07:27Z reserve=1 # addr=1smSBaXcZZ2W6iaNXTT7CdxwnqZrQmPjq hdkeypath=m/0'/1'/121'
KwS6fT5VB2KQv2txK2dvGMBpZVADg3uYKYABzCisgSAFoHsavezu 2017-09-18T19:07:27Z reserve=1 # addr=1ttvzcWJuS7bWMVEX9tLXhcNTAwhsxYfg hdkeypath=m/0'/1'/200'
KzKPeGCmFb4DLnZQFvGqLs1zCRq8NnCDkdpfn86nJyPBnuQMtvqP 2017-09-18T19:07:27Z reserve=1 # addr=1w98cTmKX6SfhYybTGniCtEb6c5JMxwZU hdkeypath=m/0'/1'/365'
L3XWYmoZnK7pJcDYAFi9K8rSRLPPuj3puqsxRBkWh5dDvodTL55U 2017-09-18T19:07:27Z reserve=1 # addr=1wadqSYW14di7zmdxad8buiuy69WCQpr8 hdkeypath=m/0'/0'/941'
L2eTpDCZSTGAtQh5vSMvfrETSUQY5tXhvjkXPUDFX4CAH25cii28 2017-09-18T19:07:27Z reserve=1 # addr=1y5ZbqPBomrpMvinhCQhUj1vu5FZUP3C8 hdkeypath=m/0'/1'/93'
L3HXmcTnhqxprC86dahcxQN5aZT825jp7831NKbyNvDqzekciuad 2017-09-18T19:07:27Z reserve=1 # addr=1yMhG2ac9cKpave8198HnVB52bT76oMCV hdkeypath=m/0'/0'/198'
L3ATcSGuZotRwcs1AyyEgyCk8f1GAPof2dtLWF1myb1Ag5RSMTwf 2017-09-18T19:07:27Z reserve=1 # addr=1yghmi4bY8MictksXCrYC4fBuZeKfGYPo hdkeypath=m/0'/0'/223'
L1jDMrcjep9PyivZFqnDWbZ1w2dU7Un3UJyLdjqUsofsMGmaw9Pk 2017-09-18T19:07:27Z reserve=1 # addr=1222f2BYuV2i24qAC7pnzesvWZvr9yfJ61 hdkeypath=m/0'/1'/142'
L2BcBHkpgauyEJVtGB3VrK9FthdHSv85xyoS6j6CBvCa9wNLjYgU 2017-09-18T19:07:27Z reserve=1 # addr=123q3BXwTR84fKceHEgypj9nLNY6r6URQL hdkeypath=m/0'/0'/276'
KzyiQE6hysH1FgtXVs9xBUPNipEoAoJ5ouZAfsbGZ17CDS6x587u 2017-09-18T19:07:27Z reserve=1 # addr=124EWXxBgVFiLAZihD4fwWBADn9Hn7srPk hdkeypath=m/0'/0'/217'
L1xM4m7nLXZaqfRmyWWiWLcKkCXcqKbXz6t4S8DVd37fTvCxCmA7 2017-09-18T19:07:27Z reserve=1 # addr=126HaZCXCBjdxb6mEEZz5q6SCeHjdspGoW hdkeypath=m/0'/1'/231'
L2Kwksa8c4h8e1NsWA7LVXNnNTXPpxivqCsPXjCG5Qg7LdJd8sxw 2017-09-18T19:07:27Z reserve=1 # addr=126NinSEzkey9VoNNfHcJpYaN43Bse4HnP hdkeypath=m/0'/1'/255'
KxGp54hzb61WAcXLhpMw51MXCrQf8pkwUB7PWxZyQfcLbEppS5ki 2017-09-18T19:07:27Z reserve=1 # addr=126oMQPf2SqStNtai78HHjBq1pD3MbPhdY hdkeypath=m/0'/0'/900'
KxE3xagi1xBAPwLEU4KfKGJrB4EP8xWcQkNc4nJebYC8MQ433ZFq 2017-09-18T19:07:27Z reserve=1 # addr=127z4EXPBfb3WjxcTafrG9nTaWyRsXj2eN hdkeypath=m/0'/0'/277'
L2KgsusgBr4b6akZnmTMKDHAEM88246zURbGRj8vQfSF8EukFYFC 2017-09-18T19:07:27Z reserve=1 # addr=128rEXMhruANwihRd9fyWio3pDV42qnPCR hdkeypath=m/0'/0'/295'
KyHaLBKZscV3GeBVc1znAC6DbnrW1XeJtVmMnJhttC1fyK3if1aD 2017-09-18T19:07:27Z reserve=1 # addr=129fx9Gn3Vw7ALJANiCee7qiGhjih5Gcx4 hdkeypath=m/0'/1'/250'
L3e6tGJkVg7wJGgcW1ZBvgk1d4HB4g28VMhhXp8WJD9PGiXNAnB5 2017-09-18T19:07:27Z reserve=1 # addr=12AiV2mp4PsjTagfieLZJYUSvJ9wP2TNNm hdkeypath=m/0'/0'/662'
L1jA9JekAdMh7fBtddTjTyh1TGsXuWttc1g9LBn22qmpLMyFn8nr 2017-09-18T19:07:27Z reserve=1 # addr=12CtM6k7EsYFoYQFgKjiCECYuvaxVjE2Uc hdkeypath=m/0'/0'/790'
KzFdNVfg1Tzeh6CcaED94g5W3AsW6f81bDGKySzeTFStoq4WvFyJ 2017-09-18T19:07:27Z reserve=1 # addr=12D4i8v7ij52hvso3woAPbm2KPA7ucQX7h hdkeypath=m/0'/0'/128'
KyZskTR6nmW1kydh9f5g9eyXnXRwnJDX1NiU4JLkd8ptseBDoeWN 2017-09-18T19:07:27Z reserve=1 # addr=12D8X4qLZ7tVHFMzwdFdXYdmZ55X3qD5DX hdkeypath=m/0'/0'/319'
KwFDGuCnShh9BTZV22FyjTfrRNeVwRHTAZCgsF7i9xeqLRJrg6QM 2017-09-18T19:07:27Z reserve=1 # addr=12Dr1yMBpNeampwYsEEScMiZSiE6vC9ooY hdkeypath=m/0'/0'/72'
KzMLxb5XgZtgSGY64T9ekTe6aTnNPt1oYzoPa2F3dCgkMmPvuSiY 2017-09-18T19:07:27Z reserve=1 # addr=12EGgUN3xEZwXcipz41TEyVcm5X2u1Lzf1 hdkeypath=m/0'/0'/636'
KyQ645daANAfhYv1c2ya37wg8WRmGe4Pgbt5bkcYeKnu3xXkUrCt 2017-09-18T19:07:27Z reserve=1 # addr=12FB9PR8oP58KoPSAWicyjgv2PK6qtkpX8 hdkeypath=m/0'/0'/346'
KzA6B9uu6eUgytq69F2WLjvLHea34Xy5DUcpRG32Cr2zWoLw3fqh 2017-09-18T19:07:27Z reserve=1 # addr=12Fznbw763E6VqGTFK4oXXjDDKQnnDWwVG hdkeypath=m/0'/0'/928'
KzLhYhBZwrbcHFmZnuGniN7Xn88u1zHuhEoUj8zVViMuNKeETXdG 2017-09-18T19:07:27Z reserve=1 # addr=12G9f4aFiobRY5nDTN6aR7zWZpR8KYR6im hdkeypath=m/0'/0'/7'
KydySFGfowWh74Tx6aXPzS1a9WkoRnoWLM2p5QY2FjQW8ufvBmr6 2017-09-18T19:07:27Z reserve=1 # addr=12GdJv9KVvoBaQhZuTxnFRChtEoTLMyf9Q hdkeypath=m/0'/0'/830'
L3TTZVZKd7obbkBPgY7fEzoKhQJpZqNnLJz1pqESiQn2Uo6JHNuj 2017-09-18T19:07:27Z reserve=1 # addr=12HcLKceVsqxcTGX3dWAk9qJ3KaofZES2Y hdkeypath=m/0'/1'/352'
KzauKVLNW2ZRornVzaFB5WGbipZjvLAb9UjD8HrqkiVhuZabfrdY 2017-09-18T19:07:27Z reserve=1 # addr=12JvNdkfQmMhrXFiTaPLBRQaGmj47v54Cs hdkeypath=m/0'/0'/547'
L2jYNEHVsSmDd3Dr68hiRZdbGoTNtyqymzNmjLdER8YkscKBumic 2017-09-18T19:07:27Z reserve=1 # addr=12KJW1CRbAbESzZD6oxcDCTg9Ac6NDdb9C hdkeypath=m/0'/0'/914'
Kz1U26YUceKUDj6rw6TtSEUbVxqxDxMsAioeAkQQs8RttSE1nmYa 2017-09-18T19:07:27Z reserve=1 # addr=12LZZ6xC7X3gXGY3t9e128YdePhjDjPrSa hdkeypath=m/0'/0'/125'
L1yKAoC6irDo83KiXFzLh6af9sE7YjmKN375E4b3nX97bRTSfG3g 2017-09-18T19:07:27Z reserve=1 # addr=12M6yokHDBEJ15aAyFS7euRggf8CUwsko2 hdkeypath=m/0'/1'/432'
KzTC5PAZQ5LfnFGz683pM9UZemkTJ2dahb6Mdat4TEJr12zofoqU 2017-09-18T19:07:27Z reserve=1 # addr=12MpKkHPZNQaEG6fLAkHc4vbr1KyXvJPp1 hdkeypath=m/0'/1'/309'
KwWe1KDu6tQ122p54rZEN5qegPDHgPUp86258GkdW2mBRALSyk43 2017-09-18T19:07:27Z reserve=1 # addr=12NPB1tYPtPaEuxBdHcVQfdP3eNotpHyzF hdkeypath=m/0'/1'/66'
KypmNhq9ptrvkz1rCWSszcEMcnruL1Hdm9LiGwroQMHESbp5FsBa 2017-09-18T19:07:27Z reserve=1 # addr=12QaWB8EhG8wFAgQ4rbJzq1KpWgHFzDb2W hdkeypath=m/0'/0'/79'
L5iNfXhyF1ZYP9WrM6hyWZSEPHiTKA1cnwfHKzK1rkQZEgRFJx5P 2017-09-18T19:07:27Z reserve=1 # addr=12R7bNadKXfqbCXA6P7efNDWz81a1F3E9d hdkeypath=m/0'/0'/372'
L2MJYNGatcetU5LdcWKo6fu8My54jQYpDdkyfQVyugawu7SSguAc 2017-09-18T19:07:27Z reserve=1 # addr=12RQfKkwfyVkMNpRG7FnxNK7ZNun52BTvD hdkeypath=m/0'/0'/455'
KwypYV7K3emewSJ9bCT4uTa2xSBD7ZHCAK8aSnqQLdLmpWnW9eje 2017-09-18T19:07:27Z reserve=1 # addr=12SzoA4sow2eyCspHaSHzGcLv3jVLKVK8R hdkeypath=m/0'/1'/6'
KzCABRNQXJCMrScYxLXVipVaNV1puY6SVPoCZY979FMmNjps1tVF 2017-09-18T19:07:27Z reserve=1 # addr=12VWSvvzqT6CLFC6qHA9C5LBxEVqrSHRih hdkeypath=m/0'/0'/799'
KyaN2XahbkmL4Nua1vedpoehvuvmTmqA9BJksYiZGkV2NX9h5Cx1 2017-09-18T19:07:27Z reserve=1 # addr=12WBprMrLCAphMsBGopTdBAjfqzfbqKikN hdkeypath=m/0'/0'/454'
L3wfGdGiD1FazmVq3onXKZfKJeZQUPgxKxBjLp9d47GVX4x4oxJS 2017-09-18T19:07:27Z reserve=1 # addr=12Wb3qFBpNMmCv3q587qAMX59ADwGBDCYJ hdkeypath=m/0'/1'/465'
L112v3tnDrYmWVwcPsim3aMFsUdcuDDo3siCo7V3WDTqfifXA5Ku 2017-09-18T19:07:27Z reserve=1 # addr=12Xb5nGyU14UeJEdkfo1B1dPucA6ULpAHt hdkeypath=m/0'/0'/758'
L3b4N8pobwj3daPFTxcaRxoDYYcj6yaJJpZK9McK5MsGLXnbMNsr 2017-09-18T19:07:27Z reserve=1 # addr=12ZTexE3VGRJn1qk51UdGnA7T9RoYtGEKe hdkeypath=m/0'/0'/144'
# End of dump

View file

@ -20,7 +20,7 @@
test/test.py: Test suite for the MMGen suite
"""
import sys,os
import sys,os,subprocess,shutil,time,re
pn = os.path.dirname(sys.argv[0])
os.chdir(os.path.join(pn,os.pardir))
@ -80,13 +80,17 @@ if not any(e in ('--skip-deps','--resume','-S','-r') for e in sys.argv+shortopts
try: os.listdir(data_dir)
except: pass
else:
import shutil
shutil.rmtree(data_dir)
try: shutil.rmtree(data_dir)
except: # we couldn't remove data dir - perhaps regtest daemon is running
try: subprocess.call(['python','mmgen-regtest','stop'])
except: rdie(1,'Unable to remove data dir!')
else:
time.sleep(2)
shutil.rmtree(data_dir)
os.mkdir(data_dir,0755)
else:
d,pfx = '/dev/shm','mmgen-test-'
try:
import subprocess
subprocess.call('rm -rf %s/%s*'%(d,pfx),shell=True)
except Exception as e:
die(2,'Unable to delete directory tree %s/%s* (%s)'%(d,pfx,e))
@ -119,7 +123,7 @@ opts_data = lambda: {
-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
-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
@ -141,6 +145,7 @@ If no command is given, the whole suite of tests is run.
sys.argv = [sys.argv[0]] + ['--data-dir',data_dir] + sys.argv[1:]
cmd_args = opts.init(opts_data)
opt.popen_spawn = True # popen has issues, so use popen_spawn always
tn_desc = ('','.testnet')[g.testnet]
@ -174,6 +179,9 @@ cfgs = {
},
'segwit': get_segwit_val()
},
'17': {
'tmpdir': os.path.join('test','tmp17'),
},
'1': {
'tmpdir': os.path.join('test','tmp1'),
'wpasswd': 'Dorian',
@ -268,8 +276,12 @@ cfgs = {
'seed_len': 128,
'seed_id': 'FE3C6545',
'ref_bw_seed_id': '33F10310',
'addrfile_chk': ('B230 7526 638F 38CB','B64D 7327 EF2A 60FE','9914 6D10 2307 F348','7DBF 441F E188 8B37'),
'keyaddrfile_chk':('CF83 32FB 8A8B 08E2','FEBF 7878 97BB CC35','C13B F717 D4E8 CF59','4DB5 BAF0 45B7 6E81'),
'addrfile_chk': ('B230 7526 638F 38CB','B64D 7327 EF2A 60FE'),
'addrfile_segwit_chk': ('9914 6D10 2307 F348','7DBF 441F E188 8B37'),
'addrfile_compressed_chk': ('95EB 8CC0 7B3B 7856','629D FDE4 CDC0 F276'),
'keyaddrfile_chk': ('CF83 32FB 8A8B 08E2','FEBF 7878 97BB CC35'),
'keyaddrfile_segwit_chk': ('C13B F717 D4E8 CF59','4DB5 BAF0 45B7 6E81'),
'keyaddrfile_compressed_chk': ('E43A FA46 5751 720A','B995 A6CF D1CD FAD0'),
'passfile_chk': 'EB29 DC4F 924B 289F',
'passfile32_chk': '37B6 C218 2ABC 7508',
'wpasswd': 'reference password',
@ -297,8 +309,12 @@ cfgs = {
'seed_len': 192,
'seed_id': '1378FC64',
'ref_bw_seed_id': 'CE918388',
'addrfile_chk': ('8C17 A5FA 0470 6E89','0A59 C8CD 9439 8B81','91C4 0414 89E4 2089','3BA6 7494 8E2B 858D'),
'keyaddrfile_chk': ('9648 5132 B98E 3AD9','2F72 C83F 44C5 0FAC','C98B DF08 A3D5 204B','25F2 AEB6 AAAC 8BBE'),
'addrfile_chk': ('8C17 A5FA 0470 6E89','0A59 C8CD 9439 8B81'),
'addrfile_segwit_chk': ('91C4 0414 89E4 2089','3BA6 7494 8E2B 858D'),
'addrfile_compressed_chk': ('2615 8401 2E98 7ECA','DF38 22AB AAB0 124E'),
'keyaddrfile_chk': ('9648 5132 B98E 3AD9','2F72 C83F 44C5 0FAC'),
'keyaddrfile_segwit_chk': ('C98B DF08 A3D5 204B','25F2 AEB6 AAAC 8BBE'),
'keyaddrfile_compressed_chk': ('6D6D 3D35 04FD B9C3','B345 9CD8 9EAE 5489'),
'passfile_chk': 'ADEA 0083 094D 489A',
'passfile32_chk': '2A28 C5C7 36EC 217A',
'wpasswd': 'reference password',
@ -326,8 +342,12 @@ cfgs = {
'seed_len': 256,
'seed_id': '98831F3A',
'ref_bw_seed_id': 'B48CD7FC',
'addrfile_chk': ('6FEF 6FB9 7B13 5D91','3C2C 8558 BB54 079E','06C1 9C87 F25C 4EE6','58D1 7B6C E9F9 9C14'),
'keyaddrfile_chk': ('9F2D D781 1812 8BAD','7410 8F95 4B33 B4B2','A447 12C2 DD14 5A9B','0690 460D A600 D315'),
'addrfile_chk': ('6FEF 6FB9 7B13 5D91','3C2C 8558 BB54 079E'),
'addrfile_segwit_chk': ('06C1 9C87 F25C 4EE6','58D1 7B6C E9F9 9C14'),
'addrfile_compressed_chk': ('A33C 4FDE F515 F5BC','5186 02C2 535E B7D5'),
'keyaddrfile_chk': ('9F2D D781 1812 8BAD','7410 8F95 4B33 B4B2'),
'keyaddrfile_segwit_chk': ('A447 12C2 DD14 5A9B','0690 460D A600 D315'),
'keyaddrfile_compressed_chk': ('420A 8EB5 A9E2 7814','3243 DD92 809E FE8D'),
'passfile_chk': '2D6D 8FBA 422E 1315',
'passfile32_chk': 'F6C1 CDFB 97D9 FCAE',
'wpasswd': 'reference password',
@ -475,6 +495,8 @@ cmd_group['ref'] = (
('refwalletgen', ([],'gen new refwallet')),
('refaddrgen', (['mmdat',pwfile],'new refwallet addr chksum')),
('refkeyaddrgen', (['mmdat',pwfile],'new refwallet key-addr chksum')),
('refaddrgen_compressed', (['mmdat',pwfile],'new refwallet addr chksum (compressed)')),
('refkeyaddrgen_compressed', (['mmdat',pwfile],'new refwallet key-addr chksum (compressed)')),
('refpasswdgen', (['mmdat',pwfile],'new refwallet passwd file chksum')),
('ref_b32passwdgen',(['mmdat',pwfile],'new refwallet passwd file chksum (base32)')),
)
@ -515,6 +537,23 @@ cmd_group['conv_out'] = ( # writing
('ref_hincog_conv_out', 'ref seed conversion to hidden incog data')
)
cmd_group['regtest'] = (
('regtest_setup', 'regtest (Bob and Alice) mode setup'),
('regtest_alice_bal1', "Alice's balance"),
('regtest_bob_bal1', "Bob's balance"),
('regtest_bob_split', "splitting Bob's funds"),
('regtest_generate', 'mining a block'),
('regtest_bob_bal2', "Bob's balance"),
('regtest_bob_rbf_send','sending funds to Alice (RBF)'),
('regtest_get_mempool1','mempool (before RBF bump)'),
('regtest_bob_rbf_bump1','bumping RBF transaction'),
('regtest_get_mempool2','mempool (after RBF bump)'),
('regtest_generate', 'mining a block'),
('regtest_bob_bal3', "Bob's balance"),
('regtest_alice_bal2', "Alice's balance"),
('regtest_stop', 'stopping regtest daemon'),
)
cmd_list = OrderedDict()
for k in cmd_group: cmd_list[k] = []
@ -556,6 +595,11 @@ for a,b in cmd_group['conv_out']:
cmd_list['conv_out'].append(k)
cmd_data[k] = (10+i,'%s (%s-bit)' % (b,j),[[[],10+i]])
cmd_data['info_regtest'] = 'regtest mode',[17]
for a,b in cmd_group['regtest']:
cmd_list['regtest'].append(a)
cmd_data[a] = (17,b,[[[],17]])
utils = {
'check_deps': 'check dependencies for specified command',
'clean': 'clean specified tmp dir(s) 1,2,3,4,5 or 6 (no arg = all dirs)',
@ -596,6 +640,8 @@ meta_cmds = OrderedDict([
['saved_ref_conv_out1', [c[0]+'1' for c in cmd_group['conv_out']]],
['saved_ref_conv_out2', [c[0]+'2' for c in cmd_group['conv_out']]],
['saved_ref_conv_out3', [c[0]+'3' for c in cmd_group['conv_out']]],
['regtest', dict(cmd_group['regtest']).keys()],
])
del cmd_group
@ -677,7 +723,6 @@ if opt.list_cmds:
Msg(fs.format(cmd,utils[cmd],w=w))
sys.exit(0)
import time,re
NL = ('\r\n','\n')[g.platform=='linux' and bool(opt.popen_spawn)]
def get_file_with_ext(ext,mydir,delete=True,no_dot=False):
@ -1136,20 +1181,27 @@ class MMGenTestSuite(object):
have_dfl_wallet = False
ok()
def addrgen(self,name,wf,pf=None,check_ref=False,ftype='addr',id_str=None,extra_args=[]):
ftype,chkfile = ((ftype,'{}file_chk'.format(ftype)),('pass','passfile32_chk'))[ftype=='pass32']
add_args = extra_args + (get_segwit_arg(cfg),[])[ftype[:4]=='pass']
dlist = [id_str] if id_str else []
t = MMGenExpect(name,'mmgen-{}gen'.format(ftype), add_args +
['-d',cfg['tmpdir']] + ([],[wf])[bool(wf)] + dlist + [cfg['{}_idx_list'.format(ftype)]])
def addrgen(self,name,wf,pf=None,check_ref=False,ftype='addr',id_str=None,extra_args=[],mmtype=None):
if cfg['segwit'] and ftype[:4] != 'pass' and not mmtype: mmtype = 'segwit'
cmd_pfx = (ftype,'pass')[ftype[:4]=='pass']
t = MMGenExpect(name,'mmgen-{}gen'.format(cmd_pfx),
['-d',cfg['tmpdir']] +
extra_args +
([],['--type='+str(mmtype)])[bool(mmtype)] +
([],[wf])[bool(wf)] +
([],[id_str])[bool(id_str)] +
[cfg['{}_idx_list'.format(cmd_pfx)]])
t.license()
t.passphrase('MMGen wallet',cfg['wpasswd'])
t.expect('Passphrase is OK')
desc = ('address','password')[ftype=='pass']
desc = ('address','password')[ftype[:4]=='pass']
chk = t.expect_getend(r'Checksum for {} data .*?: '.format(desc),regex=True)
if check_ref:
c = (cfg[chkfile][g.testnet + 2*cfg['segwit']],cfg[chkfile])[ftype=='pass']
refcheck('address data checksum',chk,c)
k = 'passfile32_chk' if ftype == 'pass32' \
else 'passfile_chk' if ftype == 'pass' \
else '{}file{}_chk'.format(ftype,'_'+mmtype if mmtype else '')
chk_ref = cfg[k] if ftype[:4] == 'pass' else cfg[k][g.testnet]
refcheck('address data checksum',chk,chk_ref)
return
t.written_to_file('Addresses',oo=True)
t.ok()
@ -1158,9 +1210,11 @@ class MMGenTestSuite(object):
return self.addrgen(name,wf=None,pf=pf,check_ref=check_ref)
def refaddrgen(self,name,wf,pf):
d = ' (%s-bit seed)' % cfg['seed_len']
self.addrgen(name,wf,pf=pf,check_ref=True)
def refaddrgen_compressed(self,name,wf,pf):
self.addrgen(name,wf,pf=pf,check_ref=True,mmtype='compressed')
def addrimport(self,name,addrfile):
outfile = os.path.join(cfg['tmpdir'],'addrfile_w_comments')
add_comments_to_addr_file(addrfile,outfile)
@ -1210,8 +1264,7 @@ class MMGenTestSuite(object):
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)
t.expect('Enter a range or space-separated list of outputs to spend: ',
' '.join([str(i) for i in outputs_list])+'\n')
t.expect('outputs to spend: ',' '.join([str(i) for i in outputs_list])+'\n')
if non_mmgen_input and not txdo_args: t.expect('Accept? (y/N): ','y')
t.expect('OK? (Y/n): ','y') # fee OK?
t.expect('OK? (Y/n): ','y') # change OK?
@ -1408,14 +1461,17 @@ class MMGenTestSuite(object):
self.addrgen_incog(name,[],'',in_fmt='hi',desc='hidden incognito data',
args=['-H','%s,%s'%(rf,hincog_offset),'-l',str(hincog_seedlen)])
def keyaddrgen(self,name,wf,pf=None,check_ref=False):
args = get_segwit_arg(cfg) + ['-d',cfg['tmpdir'],usr_rand_arg,wf,cfg['addr_idx_list']]
t = MMGenExpect(name,'mmgen-keygen', args)
def keyaddrgen(self,name,wf,pf=None,check_ref=False,mmtype=None):
if cfg['segwit'] and not mmtype: mmtype = 'segwit'
args = ['-d',cfg['tmpdir'],usr_rand_arg,wf,cfg['addr_idx_list']]
t = MMGenExpect(name,'mmgen-keygen',
([],['--type='+str(mmtype)])[bool(mmtype)] + args)
t.license()
t.passphrase('MMGen wallet',cfg['wpasswd'])
chk = t.expect_getend(r'Checksum for key-address data .*?: ',regex=True)
if check_ref:
refcheck('key-address data checksum',chk,cfg['keyaddrfile_chk'][g.testnet + 2*cfg['segwit']])
k = 'keyaddrfile{}_chk'.format('_'+mmtype if mmtype else '')
refcheck('key-address data checksum',chk,cfg[k][g.testnet])
return
t.expect('Encrypt key list? (y/N): ','y')
t.usr_rand(usr_rand_chars)
@ -1428,6 +1484,9 @@ class MMGenTestSuite(object):
def refkeyaddrgen(self,name,wf,pf):
self.keyaddrgen(name,wf,pf,check_ref=True)
def refkeyaddrgen_compressed(self,name,wf,pf):
self.keyaddrgen(name,wf,pf,check_ref=True,mmtype='compressed')
def refpasswdgen(self,name,wf,pf):
self.addrgen(name,wf,pf,check_ref=True,ftype='pass',id_str='alice@crypto.org')
@ -1724,10 +1783,9 @@ class MMGenTestSuite(object):
def ref_tool_decrypt(self,name):
f = os.path.join(ref_dir,ref_enc_fn)
aa = []
t = MMGenExpect(name,'mmgen-tool',
aa + ['-q','decrypt',f,'outfile=-','hash_preset=1'])
t = MMGenExpect(name,'mmgen-tool', ['-q','decrypt',f,'outfile=-','hash_preset=1'])
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())
@ -1794,6 +1852,134 @@ class MMGenTestSuite(object):
add_args=add_args,
extra_desc='(check)')
def regtest_setup(self,name):
try: shutil.rmtree(os.path.join(data_dir,'regtest'))
except: pass
os.environ['MMGEN_TEST_SUITE'] = '' # mnemonic is piped to stdin, so stop being a terminal
t = MMGenExpect(name,'mmgen-regtest',['-m','--data-dir='+data_dir,'setup'])
os.environ['MMGEN_TEST_SUITE'] = '1'
t.expect('Mined')
t.expect('Setting up')
t.expect('Creating')
t.expect('Creating')
t.expect('Importing')
t.expect('Importing')
t.expect('Importing')
t.expect('Setting up')
t.expect('Creating')
t.expect('Creating')
t.expect('Importing')
t.expect('Importing')
t.expect('Importing')
t.expect('Sending')
t.expect('Sending')
t.expect('Mined')
t.expect('Setup complete')
t.ok()
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(total,'{} BTC'.format(bal))
def regtest_alice_bal1(self,name):
return self.regtest_user_bal(name,'alice','500')
def regtest_alice_bal2(self,name):
return self.regtest_user_bal(name,'alice','600')
def regtest_bob_bal1(self,name):
return self.regtest_user_bal(name,'bob','500')
def regtest_bob_bal2(self,name):
return self.regtest_user_bal(name,'bob','499.999942')
def regtest_bob_bal3(self,name):
return self.regtest_user_bal(name,'bob','399.9998214')
def regtest_user_txdo(self,name,user,fee,outputs_cl,outputs_prompt,extra_args=[],no_send=False):
os.environ['MMGEN_BOGUS_SEND'] = ''
t = MMGenExpect(name,'mmgen-txdo',
['-d',cfg['tmpdir'],'-B','--'+user,'--tx-fee='+fee] + extra_args + outputs_cl)
os.environ['MMGEN_BOGUS_SEND'] = '1'
t.expect(r"'q'=quit view, .*?:.",'M',regex=True) # sort by mmid
t.expect(r"'q'=quit view, .*?:.",'q',regex=True)
t.expect('outputs to spend: ',outputs_prompt+'\n')
t.expect('OK? (Y/n): ','y') # fee OK?
t.expect('OK? (Y/n): ','y') # change OK?
t.expect('Add a comment to transaction? (y/N): ','\n')
t.expect('View decoded transaction\? .*?: ','t',regex=True)
t.expect('to continue: ','\n')
t.written_to_file('Signed transaction')
if not no_send:
t.expect('to confirm: ','YES, I REALLY WANT TO DO THIS\n')
t.expect('Transaction sent')
t.read()
t.ok()
def regtest_bob_split(self,name):
from mmgen.regtest import sids
outputs_cl = [sids['bob']+':C:1,100', sids['bob']+':L:2,200',sids['bob']+':S:2']
return self.regtest_user_txdo(name,'bob','20s',outputs_cl,'1')
def regtest_bob_rbf_send(self,name):
from mmgen.regtest import sids
outputs_cl = [
'n2XovQAmdtRBS7H1PUnRFk1FR5n8wDAsXB,60', # sids['alice']:L:1
'mn67MDDa16eV2H6yDtPi3mKTAqqDxoWpJ3,40', # sids['alice']:C:1
sids['bob']+':S:2']
return self.regtest_user_txdo(name,'bob','10s',outputs_cl,'3',extra_args=['--rbf'])
def regtest_user_txbump(self,name,user,txfile,fee,red_op,no_send=False):
os.environ['MMGEN_BOGUS_SEND'] = ''
t = MMGenExpect(name,'mmgen-txbump',
['-d',cfg['tmpdir'],'--send','--'+user,'--tx-fee='+fee,'--output-to-reduce='+red_op] + [txfile])
os.environ['MMGEN_BOGUS_SEND'] = '1'
t.expect('OK? (Y/n): ','y') # output OK?
t.expect('OK? (Y/n): ','y') # fee OK?
t.expect('Add a comment to transaction? (y/N): ','n')
t.written_to_file('Signed transaction')
if not no_send:
t.expect('to confirm: ','YES, I REALLY WANT TO DO THIS\n')
t.expect('Transaction sent')
t.written_to_file('Signed transaction')
t.read()
t.ok()
def regtest_bob_rbf_bump1(self,name):
txfile = get_file_with_ext(',10].sigtx',cfg['tmpdir'],delete=False,no_dot=True)
return self.regtest_user_txbump(name,'bob',txfile,'60s','c')
def regtest_generate(self,name):
t = MMGenExpect(name,'mmgen-regtest',['generate'])
t.expect('Mined 1 block')
t.ok()
def regtest_get_mempool(self,name):
t = MMGenExpect(name,'mmgen-regtest',['show_mempool'])
ret = eval(t.read())
return ret
def regtest_get_mempool1(self,name):
mp = self.regtest_get_mempool(name)
if len(mp) != 1:
rdie(2,'Mempool has more or less than one TX!')
write_to_tmpfile(cfg,'rbf_txid',mp[0]+'\n')
ok()
def regtest_get_mempool2(self,name):
mp = self.regtest_get_mempool(name)
if len(mp) != 1:
rdie(2,'Mempool has more or less than one TX!')
chk = read_from_tmpfile(cfg,'rbf_txid')
if chk.strip() == mp[0]:
rdie(2,'TX in mempool has not changed! RBF bump failed')
ok()
def regtest_stop(self,name):
t = MMGenExpect(name,'mmgen-regtest',['stop'])
t.ok()
# END methods
for k in (
@ -1815,13 +2001,15 @@ class MMGenTestSuite(object):
'ref_hincog_conv_out',
'ref_wallet_chk',
'refwalletgen',
'refaddrgen',
'ref_seed_chk',
'ref_hex_chk',
'ref_mn_chk',
'ref_brain_chk',
'ref_hincog_chk',
'refaddrgen',
'refkeyaddrgen',
'refaddrgen_compressed',
'refkeyaddrgen_compressed',
'refpasswdgen',
'ref_b32passwdgen'
):
@ -1887,6 +2075,7 @@ try:
else:
clean()
for cmd in cmd_data:
if cmd == 'info_regtest': break # don't run these by default
if cmd[:5] == 'info_':
msg(green('%sTesting %s' % (('\n','')[bool(opt.resume)],cmd_data[cmd][0])))
continue