2015-05-01 22:04:07 +03:00
#!/usr/bin/env python
2016-12-05 21:53:16 +03:00
# -*- coding: UTF-8 -*-
2016-02-28 16:41:43 +03:00
# mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
# Copyright (C)2013-2016 Philemon <mmgen-py@yandex.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
test / test . py : Test suite for the MMGen suite
"""
2015-01-03 00:14:40 +03:00
2016-12-05 21:53:16 +03:00
2015-01-03 00:14:40 +03:00
import sys , os
2016-02-28 16:41:43 +03:00
2016-07-26 22:16:25 +03:00
def run_in_tb ( ) :
fn = sys . argv [ 0 ]
source = open ( fn )
try :
exec source in { ' inside_tb ' : 1 }
except SystemExit :
pass
except :
def color ( s ) : return ' \033 [36;1m ' + s + ' \033 [0m '
e = sys . exc_info ( )
sys . stdout . write ( color ( ' \n Test script returned: %s \n ' % ( e [ 0 ] . __name__ ) ) )
if not ' inside_tb ' in globals ( ) and ' MMGEN_TEST_TRACEBACK ' in os . environ :
run_in_tb ( )
sys . exit ( )
2015-01-03 00:14:40 +03:00
pn = os . path . dirname ( sys . argv [ 0 ] )
os . chdir ( os . path . join ( pn , os . pardir ) )
sys . path . __setitem__ ( 0 , os . path . abspath ( os . curdir ) )
2016-02-28 16:41:43 +03:00
# Import these _after_ local path's been added to sys.path
from mmgen . common import *
from mmgen . test import *
2016-11-14 14:45:08 +03:00
2016-11-21 19:59:03 +03:00
g . quiet = False # if 'quiet' was set in config file, disable here
os . environ [ ' MMGEN_QUIET ' ] = ' 0 ' # and for the spawned scripts
2016-11-14 14:45:08 +03:00
tb_cmd = ' scripts/traceback.py '
log_file = ' test.py_log '
2016-02-28 16:41:43 +03:00
scripts = (
' addrgen ' , ' addrimport ' , ' keygen ' ,
' passchg ' , ' tool ' ,
' txcreate ' , ' txsend ' , ' txsign ' ,
' walletchk ' , ' walletconv ' , ' walletgen '
)
2015-05-01 22:04:07 +03:00
2016-02-28 16:41:43 +03:00
hincog_fn = ' rand_data '
2015-01-12 00:07:21 +03:00
hincog_bytes = 1024 * 1024
hincog_offset = 98765
hincog_seedlen = 256
2016-02-28 16:41:43 +03:00
incog_id_fn = ' incog_id '
non_mmgen_fn = ' btckey '
pwfile = ' passwd_file '
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
ref_dir = os . path . join ( ' test ' , ' ref ' )
2015-04-07 17:57:17 +03:00
2016-02-28 16:41:43 +03:00
ref_wallet_brainpass = ' abc '
ref_wallet_hash_preset = ' 1 '
2015-04-07 17:57:17 +03:00
ref_wallet_incog_offset = 123
2016-07-31 19:57:54 +03:00
from mmgen . obj import MMGenTXLabel
ref_tx_label = ' ' . join ( [ unichr ( i ) for i in range ( 65 , 91 ) +
range ( 1040 , 1072 ) + # cyrillic
range ( 913 , 939 ) + # greek
range ( 97 , 123 ) ] ) [ : MMGenTXLabel . max_len ]
2017-05-14 21:54:05 +03:00
tx_fee = ' 0.0001 '
2016-02-28 16:41:43 +03:00
ref_bw_hash_preset = ' 1 '
ref_bw_file = ' wallet.mmbrain '
ref_bw_file_spc = ' wallet-spaced.mmbrain '
2015-04-07 17:57:17 +03:00
2016-02-28 16:41:43 +03:00
ref_kafile_pass = ' kafile password '
ref_kafile_hash_preset = ' 1 '
2015-04-07 17:57:17 +03:00
2016-02-28 16:41:43 +03:00
ref_enc_fn = ' sample-text.mmenc '
2015-04-25 19:39:25 +03:00
tool_enc_passwd = " Scrypt it, don ' t hash it! "
sample_text = \
2016-02-28 16:41:43 +03:00
' The Times 03/Jan/2009 Chancellor on brink of second bailout for banks \n '
2015-04-07 17:57:17 +03:00
2016-11-21 19:59:03 +03:00
# Laggy flash media cause pexpect to crash, so create a temporary directory
# under '/dev/shm' and put datadir and temp files here.
2016-12-12 00:30:23 +03:00
shortopts = ' ' . join ( [ e [ 1 : ] for e in sys . argv if len ( e ) > 1 and e [ 0 ] == ' - ' and e [ 1 ] != ' - ' ] )
shortopts = [ ' - ' + e for e in list ( shortopts ) ]
data_dir = os . path . join ( ' test ' , ' data_dir ' )
if not any ( e in ( ' --skip-deps ' , ' --resume ' , ' -S ' , ' -r ' ) for e in sys . argv + shortopts ) :
if g . platform == ' win ' :
try : os . listdir ( data_dir )
except : pass
else :
import shutil
shutil . rmtree ( data_dir )
os . mkdir ( data_dir , 0755 )
2016-11-23 17:17:08 +03:00
else :
2016-12-12 00:30:23 +03:00
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 ) )
try :
import tempfile
shm_dir = tempfile . mkdtemp ( ' ' , pfx , d )
except Exception as e :
die ( 2 , ' Unable to create temporary directory in %s ( %s ) ' % ( d , e ) )
dd = os . path . join ( shm_dir , ' data_dir ' )
os . mkdir ( dd , 0755 )
try : os . unlink ( data_dir )
except : pass
os . symlink ( dd , data_dir )
2016-11-21 19:59:03 +03:00
opts_data = {
2016-12-05 21:53:16 +03:00
# 'sets': [('interactive',bool,'verbose',None)],
2016-11-21 19:59:03 +03:00
' 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 , - - buf - keypress Use buffered keypresses as with real human input
2016-11-23 17:17:08 +03:00
- c , - - print - cmdline Print the command line of each spawned command
2016-11-21 19:59:03 +03:00
- d , - - debug - scripts Turn on debugging output in executed scripts
2016-12-05 21:53:16 +03:00
- x , - - debug - pexpect Produce debugging output for pexpect calls
2016-11-21 19:59:03 +03:00
- 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
- 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
2016-12-05 21:53:16 +03:00
- I , - - interactive Interactive mode ( without pexpect )
2016-12-15 14:08:03 +03:00
- O , - - popen - spawn Use pexpect ' s popen_spawn instead of popen
2016-11-21 19:59:03 +03:00
- 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 ' {tb_cmd} ' script
- v , - - verbose Produce more verbose output
2016-11-23 17:17:08 +03:00
- W , - - no - dw - delete Don ' t remove default wallet from data dir after dw tests are done
2016-11-21 19:59:03 +03:00
""" .format(tb_cmd=tb_cmd,lf=log_file),
' notes ' : """
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 )
tn_desc = ( ' ' , ' .testnet ' ) [ g . testnet ]
2015-01-03 00:14:40 +03:00
cfgs = {
2016-11-21 19:59:03 +03:00
' 15 ' : {
' tmpdir ' : os . path . join ( ' test ' , ' tmp15 ' ) ,
' wpasswd ' : ' Dorian ' ,
' kapasswd ' : ' Grok the blockchain ' ,
' addr_idx_list ' : ' 12,99,5-10,5,12 ' , # 8 addresses
' dep_generators ' : {
pwfile : ' walletgen_dfl_wallet ' ,
' addrs ' : ' addrgen_dfl_wallet ' ,
' rawtx ' : ' txcreate_dfl_wallet ' ,
' sigtx ' : ' txsign_dfl_wallet ' ,
' mmseed ' : ' export_seed_dfl_wallet ' ,
2016-11-23 17:17:08 +03:00
' del_dw_run ' : ' delete_dfl_wallet ' ,
2016-11-21 19:59:03 +03:00
} ,
} ,
' 16 ' : {
' tmpdir ' : os . path . join ( ' test ' , ' tmp16 ' ) ,
' wpasswd ' : ' My changed password ' ,
' hash_preset ' : ' 2 ' ,
' dep_generators ' : {
pwfile : ' passchg_dfl_wallet ' ,
} ,
} ,
2015-05-01 22:04:07 +03:00
' 1 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp1 ' ) ,
' wpasswd ' : ' Dorian ' ,
' kapasswd ' : ' Grok the blockchain ' ,
' addr_idx_list ' : ' 12,99,5-10,5,12 ' , # 8 addresses
2015-05-01 22:04:07 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
pwfile : ' walletgen ' ,
' mmdat ' : ' walletgen ' ,
' addrs ' : ' addrgen ' ,
2017-05-14 21:54:05 +03:00
' rawtx ' : ' txcreate ' ,
2017-05-17 15:37:30 +03:00
' txbump ' : ' txbump ' ,
2017-05-14 21:54:05 +03:00
' sigtx ' : ' txsign ' ,
2016-02-28 16:41:43 +03:00
' mmwords ' : ' export_mnemonic ' ,
' mmseed ' : ' export_seed ' ,
2016-12-15 20:53:29 +03:00
' mmhex ' : ' export_hex ' ,
2016-02-28 16:41:43 +03:00
' mmincog ' : ' export_incog ' ,
' mmincox ' : ' export_incog_hex ' ,
hincog_fn : ' export_incog_hidden ' ,
incog_id_fn : ' export_incog_hidden ' ,
' akeys.mmenc ' : ' keyaddrgen '
2015-05-01 22:04:07 +03:00
} ,
} ,
' 2 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp2 ' ) ,
' wpasswd ' : ' Hodling away ' ,
' addr_idx_list ' : ' 37,45,3-6,22-23 ' , # 8 addresses
2015-05-01 22:04:07 +03:00
' seed_len ' : 128 ,
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' walletgen2 ' ,
' addrs ' : ' addrgen2 ' ,
2016-07-12 22:25:53 +03:00
' rawtx ' : ' txcreate2 ' ,
' sigtx ' : ' txsign2 ' ,
2016-02-28 16:41:43 +03:00
' mmwords ' : ' export_mnemonic2 ' ,
2015-05-01 22:04:07 +03:00
} ,
} ,
' 3 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp3 ' ) ,
' wpasswd ' : ' Major miner ' ,
' addr_idx_list ' : ' 73,54,1022-1023,2-5 ' , # 8 addresses
2015-05-01 22:04:07 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' walletgen3 ' ,
' addrs ' : ' addrgen3 ' ,
2016-07-12 22:25:53 +03:00
' rawtx ' : ' txcreate3 ' ,
' sigtx ' : ' txsign3 '
2015-05-01 22:04:07 +03:00
} ,
} ,
' 4 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp4 ' ) ,
2016-07-26 22:16:25 +03:00
' wpasswd ' : ' Hashrate good ' ,
2016-02-28 16:41:43 +03:00
' addr_idx_list ' : ' 63,1004,542-544,7-9 ' , # 8 addresses
2015-05-01 22:04:07 +03:00
' seed_len ' : 192 ,
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' walletgen4 ' ,
' mmbrain ' : ' walletgen4 ' ,
' addrs ' : ' addrgen4 ' ,
2016-07-26 22:16:25 +03:00
' rawtx ' : ' txcreate4 ' ,
' sigtx ' : ' txsign4 ' ,
2017-05-17 15:37:30 +03:00
' txdo ' : ' txdo4 ' ,
2015-05-01 22:04:07 +03:00
} ,
2016-02-28 16:41:43 +03:00
' bw_filename ' : ' brainwallet.mmbrain ' ,
' bw_params ' : ' 192,1 ' ,
2015-05-01 22:04:07 +03:00
} ,
2016-07-26 22:16:25 +03:00
' 14 ' : {
' kapasswd ' : ' Maxwell ' ,
' tmpdir ' : os . path . join ( ' test ' , ' tmp14 ' ) ,
' wpasswd ' : ' The Halving ' ,
' addr_idx_list ' : ' 61,998,502-504,7-9 ' , # 8 addresses
' seed_len ' : 256 ,
' dep_generators ' : {
' mmdat ' : ' walletgen14 ' ,
' addrs ' : ' addrgen14 ' ,
' akeys.mmenc ' : ' keyaddrgen14 ' ,
} ,
} ,
2015-05-01 22:04:07 +03:00
' 5 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp5 ' ) ,
' wpasswd ' : ' My changed password ' ,
2015-05-01 22:04:07 +03:00
' hash_preset ' : ' 2 ' ,
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' passchg ' ,
pwfile : ' passchg ' ,
2015-05-01 22:04:07 +03:00
} ,
} ,
2015-01-06 20:10:29 +03:00
' 6 ' : {
2016-02-28 16:41:43 +03:00
' name ' : ' reference wallet check (128-bit) ' ,
2015-04-07 17:57:17 +03:00
' seed_len ' : 128 ,
2016-02-28 16:41:43 +03:00
' seed_id ' : ' FE3C6545 ' ,
' ref_bw_seed_id ' : ' 33F10310 ' ,
2016-11-11 16:05:27 +03:00
' addrfile_chk ' : ( ' B230 7526 638F 38CB ' , ' B64D 7327 EF2A 60FE ' ) [ g . testnet ] ,
' keyaddrfile_chk ' : ( ' CF83 32FB 8A8B 08E2 ' , ' FEBF 7878 97BB CC35 ' ) [ g . testnet ] ,
2016-02-28 16:41:43 +03:00
' wpasswd ' : ' reference password ' ,
' ref_wallet ' : ' FE3C6545-D782B529[128,1].mmdat ' ,
' ic_wallet ' : ' FE3C6545-E29303EA-5E229E30[128,1].mmincog ' ,
' ic_wallet_hex ' : ' FE3C6545-BC4BE3F2-32586837[128,1].mmincox ' ,
2016-11-23 22:04:17 +03:00
' hic_wallet ' : ' FE3C6545-161E495F-BEB7548E[128,1].incog-offset123 ' ,
' hic_wallet_old ' : ' FE3C6545-161E495F-9860A85B[128,1].incog-old.offset123 ' ,
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp6 ' ) ,
' kapasswd ' : ' ' ,
' addr_idx_list ' : ' 1010,500-501,31-33,1,33,500,1011 ' , # 8 addresses
2015-04-07 17:57:17 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' refwalletgen1 ' ,
pwfile : ' refwalletgen1 ' ,
' addrs ' : ' refaddrgen1 ' ,
' akeys.mmenc ' : ' refkeyaddrgen1 '
2015-04-07 17:57:17 +03:00
} ,
} ,
' 7 ' : {
2016-02-28 16:41:43 +03:00
' name ' : ' reference wallet check (192-bit) ' ,
2015-04-07 17:57:17 +03:00
' seed_len ' : 192 ,
2016-02-28 16:41:43 +03:00
' seed_id ' : ' 1378FC64 ' ,
' ref_bw_seed_id ' : ' CE918388 ' ,
2016-11-11 16:05:27 +03:00
' addrfile_chk ' : ( ' 8C17 A5FA 0470 6E89 ' , ' 0A59 C8CD 9439 8B81 ' ) [ g . testnet ] ,
' keyaddrfile_chk ' : ( ' 9648 5132 B98E 3AD9 ' , ' 2F72 C83F 44C5 0FAC ' ) [ g . testnet ] ,
2016-02-28 16:41:43 +03:00
' wpasswd ' : ' reference password ' ,
' ref_wallet ' : ' 1378FC64-6F0F9BB4[192,1].mmdat ' ,
' ic_wallet ' : ' 1378FC64-2907DE97-F980D21F[192,1].mmincog ' ,
' ic_wallet_hex ' : ' 1378FC64-4DCB5174-872806A7[192,1].mmincox ' ,
2016-11-23 22:04:17 +03:00
' hic_wallet ' : ' 1378FC64-B55E9958-77256FC1[192,1].incog.offset123 ' ,
' hic_wallet_old ' : ' 1378FC64-B55E9958-D85FF20C[192,1].incog-old.offset123 ' ,
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp7 ' ) ,
' kapasswd ' : ' ' ,
' addr_idx_list ' : ' 1010,500-501,31-33,1,33,500,1011 ' , # 8 addresses
2015-04-07 17:57:17 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' refwalletgen2 ' ,
pwfile : ' refwalletgen2 ' ,
' addrs ' : ' refaddrgen2 ' ,
' akeys.mmenc ' : ' refkeyaddrgen2 '
2015-04-07 17:57:17 +03:00
} ,
} ,
' 8 ' : {
2016-02-28 16:41:43 +03:00
' name ' : ' reference wallet check (256-bit) ' ,
2015-04-07 17:57:17 +03:00
' seed_len ' : 256 ,
2016-02-28 16:41:43 +03:00
' seed_id ' : ' 98831F3A ' ,
' ref_bw_seed_id ' : ' B48CD7FC ' ,
2016-11-11 16:05:27 +03:00
' addrfile_chk ' : ( ' 6FEF 6FB9 7B13 5D91 ' , ' 3C2C 8558 BB54 079E ' ) [ g . testnet ] ,
' keyaddrfile_chk ' : ( ' 9F2D D781 1812 8BAD ' , ' 7410 8F95 4B33 B4B2 ' ) [ g . testnet ] ,
2016-02-28 16:41:43 +03:00
' wpasswd ' : ' reference password ' ,
2016-11-11 16:05:27 +03:00
' ref_wallet ' : ' 98831F3A- {} [256,1].mmdat ' . format ( ( ' 27F2BF93 ' , ' E2687906 ' ) [ g . testnet ] ) ,
' ref_addrfile ' : ' 98831F3A[1,31-33,500-501,1010-1011] {} .addrs ' . format ( tn_desc ) ,
' ref_keyaddrfile ' : ' 98831F3A[1,31-33,500-501,1010-1011] {} .akeys.mmenc ' . format ( tn_desc ) ,
' ref_addrfile_chksum ' : ( ' 6FEF 6FB9 7B13 5D91 ' , ' 3C2C 8558 BB54 079E ' ) [ g . testnet ] ,
' ref_keyaddrfile_chksum ' : ( ' 9F2D D781 1812 8BAD ' , ' 7410 8F95 4B33 B4B2 ' ) [ g . testnet ] ,
2016-02-28 16:41:43 +03:00
# 'ref_fake_unspent_data':'98831F3A_unspent.json',
2016-11-11 16:05:27 +03:00
' ref_tx_file ' : ' FFB367[1.234] {} .rawtx ' . format ( tn_desc ) ,
2016-02-28 16:41:43 +03:00
' ic_wallet ' : ' 98831F3A-5482381C-18460FB1[256,1].mmincog ' ,
' ic_wallet_hex ' : ' 98831F3A-1630A9F2-870376A9[256,1].mmincox ' ,
2016-11-23 22:04:17 +03:00
' hic_wallet ' : ' 98831F3A-F59B07A0-559CEF19[256,1].incog.offset123 ' ,
' hic_wallet_old ' : ' 98831F3A-F59B07A0-848535F3[256,1].incog-old.offset123 ' ,
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp8 ' ) ,
' kapasswd ' : ' ' ,
' addr_idx_list ' : ' 1010,500-501,31-33,1,33,500,1011 ' , # 8 addresses
2015-01-06 20:10:29 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' mmdat ' : ' refwalletgen3 ' ,
pwfile : ' refwalletgen3 ' ,
' addrs ' : ' refaddrgen3 ' ,
' akeys.mmenc ' : ' refkeyaddrgen3 '
2015-01-06 20:10:29 +03:00
} ,
} ,
2015-01-09 21:02:16 +03:00
' 9 ' : {
2016-02-28 16:41:43 +03:00
' tmpdir ' : os . path . join ( ' test ' , ' tmp9 ' ) ,
' tool_enc_infn ' : ' tool_encrypt.in ' ,
# 'tool_enc_ref_infn': 'tool_encrypt_ref.in',
' wpasswd ' : ' reference password ' ,
2015-01-09 21:02:16 +03:00
' dep_generators ' : {
2016-02-28 16:41:43 +03:00
' tool_encrypt.in ' : ' tool_encrypt ' ,
' tool_encrypt.in.mmenc ' : ' tool_encrypt ' ,
# 'tool_encrypt_ref.in': 'tool_encrypt_ref',
# 'tool_encrypt_ref.in.mmenc': 'tool_encrypt_ref',
2015-01-09 21:02:16 +03:00
} ,
} ,
}
2015-04-25 19:39:25 +03:00
from copy import deepcopy
for a , b in ( ' 6 ' , ' 11 ' ) , ( ' 7 ' , ' 12 ' ) , ( ' 8 ' , ' 13 ' ) :
cfgs [ b ] = deepcopy ( cfgs [ a ] )
2016-02-28 16:41:43 +03:00
cfgs [ b ] [ ' tmpdir ' ] = os . path . join ( ' test ' , ' tmp ' + b )
2015-04-25 19:39:25 +03:00
2015-01-09 21:02:16 +03:00
from collections import OrderedDict
2015-10-25 13:04:30 +03:00
cmd_group = OrderedDict ( )
cmd_group [ ' help ' ] = OrderedDict ( [
2015-01-09 21:02:16 +03:00
# test description depends
2015-05-01 22:04:07 +03:00
[ ' helpscreens ' , ( 1 , ' help screens ' , [ ] , 1 ) ] ,
2016-11-17 18:10:27 +03:00
[ ' longhelpscreens ' , ( 1 , ' help screens (--longhelp) ' , [ ] , 1 ) ] ,
2015-10-25 13:04:30 +03:00
] )
2016-11-23 17:17:08 +03:00
cmd_group [ ' dfl_wallet ' ] = OrderedDict ( [
[ ' walletgen_dfl_wallet ' , ( 15 , ' wallet generation (default wallet) ' , [ [ [ ] , 15 ] ] , 1 ) ] ,
[ ' export_seed_dfl_wallet ' , ( 15 , ' seed export to mmseed format (default wallet) ' , [ [ [ pwfile ] , 15 ] ] , 1 ) ] ,
[ ' addrgen_dfl_wallet ' , ( 15 , ' address generation (default wallet) ' , [ [ [ pwfile ] , 15 ] ] , 1 ) ] ,
[ ' txcreate_dfl_wallet ' , ( 15 , ' transaction creation (default wallet) ' , [ [ [ ' addrs ' ] , 15 ] ] , 1 ) ] ,
[ ' txsign_dfl_wallet ' , ( 15 , ' transaction signing (default wallet) ' , [ [ [ ' rawtx ' , pwfile ] , 15 ] ] , 1 ) ] ,
[ ' passchg_dfl_wallet ' , ( 16 , ' password, label and hash preset change (default wallet) ' , [ [ [ pwfile ] , 15 ] ] , 1 ) ] ,
[ ' walletchk_newpass_dfl_wallet ' , ( 16 , ' wallet check with new pw, label and hash preset ' , [ [ [ pwfile ] , 16 ] ] , 1 ) ] ,
[ ' delete_dfl_wallet ' , ( 15 , ' delete default wallet ' , [ [ [ pwfile ] , 15 ] ] , 1 ) ] ,
] )
2015-10-25 13:04:30 +03:00
cmd_group [ ' main ' ] = OrderedDict ( [
2016-11-23 17:17:08 +03:00
[ ' walletgen ' , ( 1 , ' wallet generation ' , [ [ [ ' del_dw_run ' ] , 15 ] ] , 1 ) ] ,
2016-02-28 16:41:43 +03:00
# ['walletchk', (1,'wallet check', [[['mmdat'],1]])],
[ ' passchg ' , ( 5 , ' password, label and hash preset change ' , [ [ [ ' mmdat ' , pwfile ] , 1 ] ] , 1 ) ] ,
[ ' walletchk_newpass ' , ( 5 , ' wallet check with new pw, label and hash preset ' , [ [ [ ' mmdat ' , pwfile ] , 5 ] ] , 1 ) ] ,
[ ' addrgen ' , ( 1 , ' address generation ' , [ [ [ ' mmdat ' , pwfile ] , 1 ] ] , 1 ) ] ,
[ ' addrimport ' , ( 1 , ' address import ' , [ [ [ ' addrs ' ] , 1 ] ] , 1 ) ] ,
[ ' txcreate ' , ( 1 , ' transaction creation ' , [ [ [ ' addrs ' ] , 1 ] ] , 1 ) ] ,
2017-05-17 15:37:30 +03:00
[ ' txbump ' , ( 1 , ' transaction fee bumping (no send) ' , [ [ [ ' rawtx ' ] , 1 ] ] , 1 ) ] ,
[ ' txsign ' , ( 1 , ' transaction signing ' , [ [ [ ' mmdat ' , ' rawtx ' , pwfile , ' txbump ' ] , 1 ] ] , 1 ) ] ,
2016-07-12 22:25:53 +03:00
[ ' txsend ' , ( 1 , ' transaction sending ' , [ [ [ ' sigtx ' ] , 1 ] ] ) ] ,
2016-12-12 00:30:23 +03:00
# txdo must go after txsign
[ ' txdo ' , ( 1 , ' online transaction ' , [ [ [ ' sigtx ' , ' mmdat ' ] , 1 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
2016-12-15 20:53:29 +03:00
[ ' export_hex ' , ( 1 , ' seed export to hexadecimal format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' export_seed ' , ( 1 , ' seed export to mmseed format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
[ ' export_mnemonic ' , ( 1 , ' seed export to mmwords format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
[ ' export_incog ' , ( 1 , ' seed export to mmincog format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
[ ' export_incog_hex ' , ( 1 , ' seed export to mmincog hex format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
[ ' export_incog_hidden ' , ( 1 , ' seed export to hidden mmincog format ' , [ [ [ ' mmdat ' ] , 1 ] ] ) ] ,
2016-12-15 20:53:29 +03:00
[ ' addrgen_hex ' , ( 1 , ' address generation from mmhex file ' , [ [ [ ' mmhex ' , ' addrs ' ] , 1 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' addrgen_seed ' , ( 1 , ' address generation from mmseed file ' , [ [ [ ' mmseed ' , ' addrs ' ] , 1 ] ] ) ] ,
[ ' addrgen_mnemonic ' , ( 1 , ' address generation from mmwords file ' , [ [ [ ' mmwords ' , ' addrs ' ] , 1 ] ] ) ] ,
[ ' addrgen_incog ' , ( 1 , ' address generation from mmincog file ' , [ [ [ ' mmincog ' , ' addrs ' ] , 1 ] ] ) ] ,
[ ' addrgen_incog_hex ' , ( 1 , ' address generation from mmincog hex file ' , [ [ [ ' mmincox ' , ' addrs ' ] , 1 ] ] ) ] ,
[ ' addrgen_incog_hidden ' , ( 1 , ' address generation from hidden mmincog file ' , [ [ [ hincog_fn , ' addrs ' ] , 1 ] ] ) ] ,
[ ' keyaddrgen ' , ( 1 , ' key-address file generation ' , [ [ [ ' mmdat ' , pwfile ] , 1 ] ] ) ] ,
2016-07-12 22:25:53 +03:00
[ ' txsign_keyaddr ' , ( 1 , ' transaction signing with key-address file ' , [ [ [ ' akeys.mmenc ' , ' rawtx ' ] , 1 ] ] ) ] ,
2015-01-09 21:02:16 +03:00
2016-11-23 17:17:08 +03:00
[ ' walletgen2 ' , ( 2 , ' wallet generation (2), 128-bit seed ' , [ [ [ ' del_dw_run ' ] , 15 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' addrgen2 ' , ( 2 , ' address generation (2) ' , [ [ [ ' mmdat ' ] , 2 ] ] ) ] ,
[ ' txcreate2 ' , ( 2 , ' transaction creation (2) ' , [ [ [ ' addrs ' ] , 2 ] ] ) ] ,
2016-07-12 22:25:53 +03:00
[ ' txsign2 ' , ( 2 , ' transaction signing, two transactions ' , [ [ [ ' mmdat ' , ' rawtx ' ] , 1 ] , [ [ ' mmdat ' , ' rawtx ' ] , 2 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' export_mnemonic2 ' , ( 2 , ' seed export to mmwords format (2) ' , [ [ [ ' mmdat ' ] , 2 ] ] ) ] ,
2015-01-09 21:02:16 +03:00
2016-11-23 17:17:08 +03:00
[ ' walletgen3 ' , ( 3 , ' wallet generation (3) ' , [ [ [ ' del_dw_run ' ] , 15 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' addrgen3 ' , ( 3 , ' address generation (3) ' , [ [ [ ' mmdat ' ] , 3 ] ] ) ] ,
[ ' txcreate3 ' , ( 3 , ' tx creation with inputs and outputs from two wallets ' , [ [ [ ' addrs ' ] , 1 ] , [ [ ' addrs ' ] , 3 ] ] ) ] ,
2016-07-12 22:25:53 +03:00
[ ' txsign3 ' , ( 3 , ' tx signing with inputs and outputs from two wallets ' , [ [ [ ' mmdat ' ] , 1 ] , [ [ ' mmdat ' , ' rawtx ' ] , 3 ] ] ) ] ,
2015-01-09 21:02:16 +03:00
2016-11-23 17:17:08 +03:00
[ ' walletgen14 ' , ( 14 , ' wallet generation (14) ' , [ [ [ ' del_dw_run ' ] , 15 ] ] , 14 ) ] ,
2016-07-26 22:16:25 +03:00
[ ' addrgen14 ' , ( 14 , ' address generation (14) ' , [ [ [ ' mmdat ' ] , 14 ] ] ) ] ,
[ ' keyaddrgen14 ' , ( 14 , ' key-address file generation (14) ' , [ [ [ ' mmdat ' ] , 14 ] ] , 14 ) ] ,
2016-11-23 17:17:08 +03:00
[ ' walletgen4 ' , ( 4 , ' wallet generation (4) (brainwallet) ' , [ [ [ ' del_dw_run ' ] , 15 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
[ ' addrgen4 ' , ( 4 , ' address generation (4) ' , [ [ [ ' mmdat ' ] , 4 ] ] ) ] ,
2016-07-26 22:16:25 +03:00
[ ' txcreate4 ' , ( 4 , ' tx creation with inputs and outputs from four seed sources, key-address file and non-MMGen inputs and outputs ' , [ [ [ ' addrs ' ] , 1 ] , [ [ ' addrs ' ] , 2 ] , [ [ ' addrs ' ] , 3 ] , [ [ ' addrs ' ] , 4 ] , [ [ ' addrs ' , ' akeys.mmenc ' ] , 14 ] ] ) ] ,
[ ' txsign4 ' , ( 4 , ' tx signing with inputs and outputs from incog file, mnemonic file, wallet, brainwallet, key-address file and non-MMGen inputs and outputs ' , [ [ [ ' mmincog ' ] , 1 ] , [ [ ' mmwords ' ] , 2 ] , [ [ ' mmdat ' ] , 3 ] , [ [ ' mmbrain ' , ' rawtx ' ] , 4 ] , [ [ ' akeys.mmenc ' ] , 14 ] ] ) ] ,
2016-12-12 00:30:23 +03:00
[ ' txdo4 ' , ( 4 , ' tx creation,signing and sending with inputs and outputs from four seed sources, key-address file and non-MMGen inputs and outputs ' , [ [ [ ' addrs ' ] , 1 ] , [ [ ' addrs ' ] , 2 ] , [ [ ' addrs ' ] , 3 ] , [ [ ' addrs ' ] , 4 ] , [ [ ' addrs ' , ' akeys.mmenc ' ] , 14 ] , [ [ ' mmincog ' ] , 1 ] , [ [ ' mmwords ' ] , 2 ] , [ [ ' mmdat ' ] , 3 ] , [ [ ' mmbrain ' , ' rawtx ' ] , 4 ] , [ [ ' akeys.mmenc ' ] , 14 ] ] ) ] , # must go after txsign4
2017-05-17 15:37:30 +03:00
[ ' txbump4 ' , ( 4 , ' tx fee bump + send with inputs and outputs from four seed sources, key-address file and non-MMGen inputs and outputs ' , [ [ [ ' akeys.mmenc ' ] , 14 ] , [ [ ' mmincog ' ] , 1 ] , [ [ ' mmwords ' ] , 2 ] , [ [ ' mmdat ' ] , 3 ] , [ [ ' akeys.mmenc ' ] , 14 ] , [ [ ' mmbrain ' , ' sigtx ' , ' mmdat ' , ' txdo ' ] , 4 ] ] ) ] , # must go after txsign4
2015-10-25 13:04:30 +03:00
] )
cmd_group [ ' tool ' ] = OrderedDict ( [
[ ' tool_encrypt ' , ( 9 , " ' mmgen-tool encrypt ' (random data) " , [ ] , 1 ) ] ,
2016-02-28 16:41:43 +03:00
[ ' tool_decrypt ' , ( 9 , " ' mmgen-tool decrypt ' (random data) " , [ [ [ cfgs [ ' 9 ' ] [ ' tool_enc_infn ' ] , cfgs [ ' 9 ' ] [ ' tool_enc_infn ' ] + ' .mmenc ' ] , 9 ] ] , 1 ) ] ,
2015-04-07 17:57:17 +03:00
# ['tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])],
2015-01-12 00:07:21 +03:00
[ ' tool_find_incog_data ' , ( 9 , " ' mmgen-tool find_incog_data ' " , [ [ [ hincog_fn ] , 1 ] , [ [ incog_id_fn ] , 1 ] ] ) ] ,
2016-02-28 16:41:43 +03:00
# ['pywallet', (9,"'mmgen-pywallet'", [],1)],
2015-01-09 21:02:16 +03:00
] )
2015-04-25 19:39:25 +03:00
# saved reference data
2015-10-25 13:04:30 +03:00
cmd_group [ ' ref ' ] = (
2015-04-25 19:39:25 +03:00
# reading
( ' ref_wallet_chk ' , ( [ ] , ' saved reference wallet ' ) ) ,
( ' ref_seed_chk ' , ( [ ] , ' saved seed file ' ) ) ,
2016-12-15 20:53:29 +03:00
( ' ref_hex_chk ' , ( [ ] , ' saved mmhex file ' ) ) ,
2015-04-25 19:39:25 +03:00
( ' ref_mn_chk ' , ( [ ] , ' saved mnemonic file ' ) ) ,
( ' ref_hincog_chk ' , ( [ ] , ' saved hidden incog reference wallet ' ) ) ,
( ' ref_brain_chk ' , ( [ ] , ' saved brainwallet ' ) ) ,
# generating new reference ('abc' brainwallet) files:
2015-11-26 00:16:14 +03:00
( ' refwalletgen ' , ( [ ] , ' gen new refwallet ' ) ) ,
2016-02-28 16:41:43 +03:00
( ' refaddrgen ' , ( [ ' mmdat ' , pwfile ] , ' new refwallet addr chksum ' ) ) ,
( ' refkeyaddrgen ' , ( [ ' mmdat ' , pwfile ] , ' new refwallet key-addr chksum ' ) )
2015-04-25 19:39:25 +03:00
)
# misc. saved reference data
2015-10-25 13:04:30 +03:00
cmd_group [ ' ref_other ' ] = (
2015-04-25 19:39:25 +03:00
( ' ref_addrfile_chk ' , ' saved reference address file ' ) ,
( ' ref_keyaddrfile_chk ' , ' saved reference key-address file ' ) ,
# Create the fake inputs:
# ('txcreate8', 'transaction creation (8)'),
( ' ref_tx_chk ' , ' saved reference tx file ' ) ,
( ' ref_brain_chk_spc3 ' , ' saved brainwallet (non-standard spacing) ' ) ,
( ' ref_tool_decrypt ' , ' decryption of saved MMGen-encrypted file ' ) ,
)
# mmgen-walletconv:
2015-10-25 13:04:30 +03:00
cmd_group [ ' conv_in ' ] = ( # reading
2015-04-25 19:39:25 +03:00
( ' ref_wallet_conv ' , ' conversion of saved reference wallet ' ) ,
( ' ref_mn_conv ' , ' conversion of saved mnemonic ' ) ,
( ' ref_seed_conv ' , ' conversion of saved seed file ' ) ,
2016-12-15 20:53:29 +03:00
( ' ref_hex_conv ' , ' conversion of saved hexadecimal seed file ' ) ,
2015-04-25 19:39:25 +03:00
( ' ref_brain_conv ' , ' conversion of ref brainwallet ' ) ,
( ' ref_incog_conv ' , ' conversion of saved incog wallet ' ) ,
( ' ref_incox_conv ' , ' conversion of saved hex incog wallet ' ) ,
( ' ref_hincog_conv ' , ' conversion of saved hidden incog wallet ' ) ,
( ' ref_hincog_conv_old ' , ' conversion of saved hidden incog wallet (old format) ' )
)
2015-10-25 13:04:30 +03:00
cmd_group [ ' conv_out ' ] = ( # writing
2015-04-25 19:39:25 +03:00
( ' ref_wallet_conv_out ' , ' ref seed conversion to wallet ' ) ,
( ' ref_mn_conv_out ' , ' ref seed conversion to mnemonic ' ) ,
2016-12-15 20:53:29 +03:00
( ' ref_hex_conv_out ' , ' ref seed conversion to hex seed ' ) ,
2015-04-25 19:39:25 +03:00
( ' ref_seed_conv_out ' , ' ref seed conversion to seed ' ) ,
( ' ref_incog_conv_out ' , ' ref seed conversion to incog data ' ) ,
( ' ref_incox_conv_out ' , ' ref seed conversion to hex incog data ' ) ,
( ' ref_hincog_conv_out ' , ' ref seed conversion to hidden incog data ' )
)
2015-10-25 13:04:30 +03:00
cmd_list = OrderedDict ( )
for k in cmd_group : cmd_list [ k ] = [ ]
cmd_data = OrderedDict ( )
for k , v in (
2016-02-28 16:41:43 +03:00
( ' help ' , ( ' help screens ' , [ ] ) ) ,
2016-11-23 17:17:08 +03:00
( ' dfl_wallet ' , ( ' basic operations with default wallet ' , [ 15 , 16 ] ) ) ,
( ' main ' , ( ' basic operations ' , [ 1 , 2 , 3 , 4 , 5 , 15 , 16 ] ) ) ,
2016-02-28 16:41:43 +03:00
( ' tool ' , ( ' tools ' , [ 9 ] ) )
2015-10-25 13:04:30 +03:00
) :
cmd_data [ ' info_ ' + k ] = v
for i in cmd_group [ k ] :
cmd_list [ k ] . append ( i )
cmd_data [ i ] = cmd_group [ k ] [ i ]
2016-02-28 16:41:43 +03:00
cmd_data [ ' info_ref ' ] = ' reference data ' , [ 6 , 7 , 8 ]
2015-10-25 13:04:30 +03:00
for a , b in cmd_group [ ' ref ' ] :
2015-04-25 19:39:25 +03:00
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
2015-10-25 13:04:30 +03:00
k = a + str ( i )
cmd_list [ ' ref ' ] . append ( k )
2016-02-28 16:41:43 +03:00
cmd_data [ k ] = ( 5 + i , ' %s ( %s -bit) ' % ( b [ 1 ] , j ) , [ [ b [ 0 ] , 5 + i ] ] , 1 )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
cmd_data [ ' info_ref_other ' ] = ' other reference data ' , [ 8 ]
2015-10-25 13:04:30 +03:00
for a , b in cmd_group [ ' ref_other ' ] :
cmd_list [ ' ref_other ' ] . append ( a )
cmd_data [ a ] = ( 8 , b , [ [ [ ] , 8 ] ] , 1 )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
cmd_data [ ' info_conv_in ' ] = ' wallet conversion from reference data ' , [ 11 , 12 , 13 ]
2015-10-25 13:04:30 +03:00
for a , b in cmd_group [ ' conv_in ' ] :
2015-04-25 19:39:25 +03:00
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
2015-10-25 13:04:30 +03:00
k = a + str ( i )
cmd_list [ ' conv_in ' ] . append ( k )
2016-02-28 16:41:43 +03:00
cmd_data [ k ] = ( 10 + i , ' %s ( %s -bit) ' % ( b , j ) , [ [ [ ] , 10 + i ] ] , 1 )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
cmd_data [ ' info_conv_out ' ] = ' wallet conversion to reference data ' , [ 11 , 12 , 13 ]
2015-10-25 13:04:30 +03:00
for a , b in cmd_group [ ' conv_out ' ] :
2015-04-25 19:39:25 +03:00
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
2015-10-25 13:04:30 +03:00
k = a + str ( i )
cmd_list [ ' conv_out ' ] . append ( k )
2016-02-28 16:41:43 +03:00
cmd_data [ k ] = ( 10 + i , ' %s ( %s -bit) ' % ( b , j ) , [ [ [ ] , 10 + i ] ] , 1 )
2015-04-25 19:39:25 +03:00
2015-01-09 21:02:16 +03:00
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) ' ,
2015-01-03 00:14:40 +03:00
}
2015-01-09 21:02:16 +03:00
addrs_per_wallet = 8
2015-01-03 20:45:01 +03:00
2015-01-03 00:14:40 +03:00
# total of two outputs must be < 10 BTC
2015-10-25 13:04:30 +03:00
for k in cfgs :
2015-01-03 00:14:40 +03:00
cfgs [ k ] [ ' amts ' ] = [ 0 , 0 ]
for idx , mod in ( 0 , 6 ) , ( 1 , 4 ) :
2016-02-28 16:41:43 +03:00
cfgs [ k ] [ ' amts ' ] [ idx ] = ' %s . %s ' % ( ( getrandnum ( 2 ) % mod ) , str ( getrandnum ( 4 ) ) [ : 5 ] )
2015-01-03 00:14:40 +03:00
meta_cmds = OrderedDict ( [
2016-02-28 16:41:43 +03:00
[ ' ref1 ' , ( ' refwalletgen1 ' , ' refaddrgen1 ' , ' refkeyaddrgen1 ' ) ] ,
[ ' ref2 ' , ( ' refwalletgen2 ' , ' refaddrgen2 ' , ' refkeyaddrgen2 ' ) ] ,
[ ' ref3 ' , ( ' refwalletgen3 ' , ' refaddrgen3 ' , ' refkeyaddrgen3 ' ) ] ,
[ ' gen ' , ( ' walletgen ' , ' addrgen ' ) ] ,
[ ' pass ' , ( ' passchg ' , ' walletchk_newpass ' ) ] ,
[ ' tx ' , ( ' addrimport ' , ' txcreate ' , ' txsign ' , ' txsend ' ) ] ,
[ ' export ' , [ k for k in cmd_data if k [ : 7 ] == ' export_ ' and cmd_data [ k ] [ 0 ] == 1 ] ] ,
[ ' gen_sp ' , [ k for k in cmd_data if k [ : 8 ] == ' addrgen_ ' and cmd_data [ k ] [ 0 ] == 1 ] ] ,
[ ' online ' , ( ' keyaddrgen ' , ' txsign_keyaddr ' ) ] ,
2015-04-25 19:39:25 +03:00
[ ' 2 ' , [ k for k in cmd_data if cmd_data [ k ] [ 0 ] == 2 ] ] ,
[ ' 3 ' , [ k for k in cmd_data if cmd_data [ k ] [ 0 ] == 3 ] ] ,
[ ' 4 ' , [ k for k in cmd_data if cmd_data [ k ] [ 0 ] == 4 ] ] ,
2016-02-28 16:41:43 +03:00
[ ' saved_ref1 ' , [ c [ 0 ] + ' 1 ' for c in cmd_group [ ' ref ' ] ] ] ,
[ ' saved_ref2 ' , [ c [ 0 ] + ' 2 ' for c in cmd_group [ ' ref ' ] ] ] ,
[ ' saved_ref3 ' , [ c [ 0 ] + ' 3 ' for c in cmd_group [ ' ref ' ] ] ] ,
2015-04-25 19:39:25 +03:00
2015-10-25 13:04:30 +03:00
[ ' saved_ref_other ' , [ c [ 0 ] for c in cmd_group [ ' ref_other ' ] ] ] ,
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
[ ' saved_ref_conv_in1 ' , [ c [ 0 ] + ' 1 ' for c in cmd_group [ ' conv_in ' ] ] ] ,
[ ' saved_ref_conv_in2 ' , [ c [ 0 ] + ' 2 ' for c in cmd_group [ ' conv_in ' ] ] ] ,
[ ' saved_ref_conv_in3 ' , [ c [ 0 ] + ' 3 ' for c in cmd_group [ ' conv_in ' ] ] ] ,
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
[ ' 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 ' ] ] ] ,
2015-01-03 00:14:40 +03:00
] )
2015-10-25 13:04:30 +03:00
del cmd_group
2016-11-17 18:10:27 +03:00
add_spawn_args = ' ' . join ( [ ' {} {} ' . format (
' -- ' + k . replace ( ' _ ' , ' - ' ) ,
getattr ( opt , k ) if getattr ( opt , k ) != True else ' '
) for k in ' testnet ' , ' rpc_host ' if getattr ( opt , k ) ] ) . split ( )
2016-11-21 19:59:03 +03:00
add_spawn_args + = [ ' --data-dir ' , data_dir ]
2016-07-26 22:16:25 +03:00
2016-11-11 16:05:27 +03:00
if opt . profile : opt . names = True
2016-07-26 22:16:25 +03:00
if opt . resume : opt . skip_deps = True
2016-07-12 22:25:53 +03:00
if opt . log :
log_fd = open ( log_file , ' a ' )
log_fd . write ( ' \n Log started: %s \n ' % make_timestr ( ) )
2015-01-03 00:14:40 +03:00
2016-07-27 22:55:47 +03:00
usr_rand_chars = ( 5 , 30 ) [ bool ( opt . usr_random ) ]
usr_rand_arg = ' -r %s ' % usr_rand_chars
2015-01-10 18:52:30 +03:00
if opt . system : sys . path . pop ( 0 )
2016-12-05 21:53:16 +03:00
ia = bool ( opt . interactive )
2015-01-03 00:14:40 +03:00
2016-12-05 21:53:16 +03:00
# Disable color in spawned scripts so we can parse their output
2016-07-26 22:16:25 +03:00
os . environ [ ' MMGEN_DISABLE_COLOR ' ] = ' 1 '
2016-12-05 21:53:16 +03:00
os . environ [ ' MMGEN_NO_LICENSE ' ] = ' 1 '
2016-07-26 22:16:25 +03:00
os . environ [ ' MMGEN_MIN_URANDCHARS ' ] = ' 3 '
2016-12-12 00:30:23 +03:00
os . environ [ ' MMGEN_BOGUS_SEND ' ] = ' 1 '
2015-04-30 00:09:29 +03:00
2016-02-28 16:41:43 +03:00
if opt . debug_scripts : os . environ [ ' MMGEN_DEBUG ' ] = ' 1 '
2015-01-12 14:41:17 +03:00
2015-01-10 18:52:30 +03:00
if opt . buf_keypress :
2015-01-03 00:14:40 +03:00
send_delay = 0.3
else :
send_delay = 0
2016-02-28 16:41:43 +03:00
os . environ [ ' MMGEN_DISABLE_HOLD_PROTECT ' ] = ' 1 '
2015-01-03 00:14:40 +03:00
2015-01-10 18:52:30 +03:00
if opt . exact_output :
2015-01-03 00:14:40 +03:00
def msg ( s ) : pass
vmsg = vmsg_r = msg_r = msg
else :
2016-02-28 16:41:43 +03:00
def msg ( s ) : sys . stderr . write ( s + ' \n ' )
2015-01-03 00:14:40 +03:00
def vmsg ( s ) :
2016-02-28 16:41:43 +03:00
if opt . verbose : sys . stderr . write ( s + ' \n ' )
2015-01-03 00:14:40 +03:00
def msg_r ( s ) : sys . stderr . write ( s )
def vmsg_r ( s ) :
2015-01-10 18:52:30 +03:00
if opt . verbose : sys . stderr . write ( s )
2015-01-03 00:14:40 +03:00
stderr_save = sys . stderr
def silence ( ) :
2015-01-10 18:52:30 +03:00
if not ( opt . verbose or opt . exact_output ) :
2016-07-27 22:55:47 +03:00
f = ( ' /dev/null ' , ' stderr.out ' ) [ g . platform == ' win ' ]
2016-02-28 16:41:43 +03:00
sys . stderr = open ( f , ' a ' )
2015-01-03 00:14:40 +03:00
def end_silence ( ) :
2015-01-10 18:52:30 +03:00
if not ( opt . verbose or opt . exact_output ) :
2015-01-03 00:14:40 +03:00
sys . stderr = stderr_save
2016-02-28 16:41:43 +03:00
def errmsg ( s ) : stderr_save . write ( s + ' \n ' )
2015-01-06 20:10:29 +03:00
def errmsg_r ( s ) : stderr_save . write ( s )
2015-01-03 00:14:40 +03:00
2015-01-10 18:52:30 +03:00
if opt . list_cmds :
2016-02-28 16:41:43 +03:00
fs = ' { :< {w} } - {} '
Msg ( green ( ' AVAILABLE COMMANDS: ' ) )
2015-01-03 00:14:40 +03:00
w = max ( [ len ( i ) for i in cmd_data ] )
for cmd in cmd_data :
2016-02-28 16:41:43 +03:00
if cmd [ : 5 ] == ' info_ ' :
2015-10-25 13:04:30 +03:00
m = capfirst ( cmd_data [ cmd ] [ 0 ] )
2017-02-23 10:55:39 +03:00
Msg ( green ( ' %s : ' % m ) )
2015-10-25 13:04:30 +03:00
continue
2016-02-28 16:41:43 +03:00
Msg ( ' ' + fs . format ( cmd , cmd_data [ cmd ] [ 1 ] , w = w ) )
2015-04-25 19:39:25 +03:00
2015-01-03 00:14:40 +03:00
w = max ( [ len ( i ) for i in meta_cmds ] )
2016-02-28 16:41:43 +03:00
Msg ( green ( ' \n AVAILABLE METACOMMANDS: ' ) )
2015-01-03 00:14:40 +03:00
for cmd in meta_cmds :
2016-02-28 16:41:43 +03:00
Msg ( fs . format ( cmd , ' ' . join ( meta_cmds [ cmd ] ) , w = w ) )
2015-04-25 19:39:25 +03:00
2015-10-25 13:04:30 +03:00
w = max ( [ len ( i ) for i in cmd_list ] )
2016-02-28 16:41:43 +03:00
Msg ( green ( ' \n AVAILABLE COMMAND GROUPS: ' ) )
2015-10-25 13:04:30 +03:00
for g in cmd_list :
2016-02-28 16:41:43 +03:00
Msg ( fs . format ( g , ' ' . join ( cmd_list [ g ] ) , w = w ) )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
Msg ( green ( ' \n AVAILABLE UTILITIES: ' ) )
2015-01-03 00:14:40 +03:00
w = max ( [ len ( i ) for i in utils ] )
for cmd in sorted ( utils ) :
2015-01-09 21:02:16 +03:00
Msg ( fs . format ( cmd , utils [ cmd ] , w = w ) )
2015-01-03 00:14:40 +03:00
sys . exit ( )
2015-05-01 22:04:07 +03:00
import time , re
2016-12-05 21:53:16 +03:00
if g . platform == ' linux ' :
2015-05-01 22:04:07 +03:00
import pexpect
2016-12-15 14:08:03 +03:00
if opt . popen_spawn :
2016-12-05 21:53:16 +03:00
import termios , atexit
def at_exit ( ) : os . system ( ' stty sane ' )
atexit . register ( at_exit )
from pexpect . popen_spawn import PopenSpawn
use_popen_spawn , NL = True , ' \n '
else :
use_popen_spawn , NL = False , ' \r \n '
else : # Windows
use_popen_spawn , NL = True , ' \r \n '
try :
import pexpect
from pexpect . popen_spawn import PopenSpawn
except :
ia = True
m1 = ( ' Missing pexpect module detected. Skipping some tests and running in '
' \n interactive mode. User prompts and control value checks will be ' )
m2 = ' HIGHLIGHTED IN GREEN '
m3 = ' . \n Control values should be checked against the program output. \n Continue? '
if not keypress_confirm ( green ( m1 ) + grnbg ( m2 ) + green ( m3 ) , default_yes = True ) :
errmsg ( ' Exiting at user request ' )
sys . exit ( )
2015-05-01 22:04:07 +03:00
2015-01-03 00:14:40 +03:00
def my_send ( p , t , delay = send_delay , s = False ) :
if delay : time . sleep ( delay )
ret = p . send ( t ) # returns num bytes written
if delay : time . sleep ( delay )
2015-01-10 18:52:30 +03:00
if opt . verbose :
2016-02-28 16:41:43 +03:00
ls = ( ' ' , ' ' ) [ bool ( opt . debug or not s ) ]
es = ( ' ' , ' ' ) [ bool ( s ) ]
msg ( ' %s SEND %s %s ' % ( ls , es , yellow ( " ' %s ' " % t . replace ( ' \n ' , r ' \ n ' ) ) ) )
2015-01-03 00:14:40 +03:00
return ret
def my_expect ( p , s , t = ' ' , delay = send_delay , regex = False , nonl = False ) :
2016-02-28 16:41:43 +03:00
quo = ( ' ' , " ' " ) [ type ( s ) == str ]
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
if opt . verbose : msg_r ( ' EXPECT %s ' % yellow ( quo + str ( s ) + quo ) )
else : msg_r ( ' + ' )
2015-01-03 00:14:40 +03:00
try :
if s == ' ' : ret = 0
else :
2016-02-28 16:41:43 +03:00
f = ( p . expect_exact , p . expect ) [ bool ( regex ) ]
2016-12-05 21:53:16 +03:00
ret = f ( s , timeout = ( 60 , 5 ) [ bool ( opt . debug_pexpect ) ] )
2015-01-03 00:14:40 +03:00
except pexpect . TIMEOUT :
2016-12-05 21:53:16 +03:00
if opt . debug_pexpect : raise
2016-02-28 16:41:43 +03:00
errmsg ( red ( ' \n ERROR. Expect %s %s %s timed out. Exiting ' % ( quo , s , quo ) ) )
2015-01-03 00:14:40 +03:00
sys . exit ( 1 )
2016-12-05 21:53:16 +03:00
debug_pexpect_msg ( p )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
if opt . debug or ( opt . verbose and type ( s ) != str ) : msg_r ( ' ==> %s ' % ret )
2015-01-03 00:14:40 +03:00
if ret == - 1 :
2016-02-28 16:41:43 +03:00
errmsg ( ' Error. Expect returned %s ' % ret )
2015-01-03 00:14:40 +03:00
sys . exit ( 1 )
else :
if t == ' ' :
2016-02-28 16:41:43 +03:00
if not nonl : vmsg ( ' ' )
2015-04-25 19:39:25 +03:00
else :
my_send ( p , t , delay , s )
2015-01-03 00:14:40 +03:00
return ret
2015-10-25 13:04:30 +03:00
def get_file_with_ext ( ext , mydir , delete = True , no_dot = False ) :
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
dot = ( ' . ' , ' ' ) [ bool ( no_dot ) ]
2015-01-03 20:45:01 +03:00
flist = [ os . path . join ( mydir , f ) for f in os . listdir ( mydir )
2015-10-25 13:04:30 +03:00
if f == ext or f [ - len ( dot + ext ) : ] == dot + ext ]
2015-01-03 20:45:01 +03:00
if not flist : return False
if len ( flist ) > 1 :
if delete :
2015-01-10 18:52:30 +03:00
if not opt . quiet :
2015-01-03 20:45:01 +03:00
msg ( " Multiple *. %s files in ' %s ' - deleting " % ( ext , mydir ) )
for f in flist : os . unlink ( f )
2015-01-03 00:14:40 +03:00
return False
else :
return flist [ 0 ]
2016-07-26 22:16:25 +03:00
def find_generated_exts ( cmd ) :
out = [ ]
for k in cfgs :
for ext , prog in cfgs [ k ] [ ' dep_generators ' ] . items ( ) :
if prog == cmd :
out . append ( ( ext , cfgs [ k ] [ ' tmpdir ' ] ) )
return out
2015-01-03 00:14:40 +03:00
def get_addrfile_checksum ( display = False ) :
2016-02-28 16:41:43 +03:00
addrfile = get_file_with_ext ( ' addrs ' , cfg [ ' tmpdir ' ] )
2015-01-03 00:14:40 +03:00
silence ( )
2016-07-26 22:16:25 +03:00
from mmgen . addr import AddrList
chk = AddrList ( addrfile ) . chksum
2016-02-28 16:41:43 +03:00
if opt . verbose and display : msg ( ' Checksum: %s ' % cyan ( chk ) )
2015-01-03 00:14:40 +03:00
end_silence ( )
return chk
def verify_checksum_or_exit ( checksum , chk ) :
if checksum != chk :
2016-02-28 16:41:43 +03:00
errmsg ( red ( ' Checksum error: %s ' % chk ) )
2015-01-03 00:14:40 +03:00
sys . exit ( 1 )
2016-02-28 16:41:43 +03:00
vmsg ( green ( ' Checksums match: %s ' ) % ( cyan ( chk ) ) )
2015-01-03 00:14:40 +03:00
2016-12-05 21:53:16 +03:00
def debug_pexpect_msg ( p ) :
if opt . debug_pexpect :
errmsg ( ' \n {} {} {} ' . format ( red ( ' BEFORE [ ' ) , p . before , red ( ' ] ' ) ) )
errmsg ( ' {} {} {} ' . format ( red ( ' MATCH [ ' ) , p . after , red ( ' ] ' ) ) )
2015-01-07 07:41:25 +03:00
2015-01-03 00:14:40 +03:00
class MMGenExpect ( object ) :
2016-12-10 16:09:06 +03:00
def __init__ ( self , name , mmgen_cmd , cmd_args = [ ] , extra_desc = ' ' , no_output = False ) :
cmd = ( ( ' ./ ' , ' ' ) [ bool ( opt . system ) ] + mmgen_cmd , ' python ' ) [ g . platform == ' win ' ]
2016-11-17 18:10:27 +03:00
cmd_args = add_spawn_args + cmd_args
2016-12-10 16:09:06 +03:00
args = ( cmd_args , [ mmgen_cmd ] + cmd_args ) [ g . platform == ' win ' ]
desc = ( cmd_data [ name ] [ 1 ] , name ) [ bool ( opt . names ) ] + ( ' ' + extra_desc ) . strip ( )
for i in args :
if type ( i ) not in ( str , unicode ) :
m1 = ' Error: missing input files in cmd line?: '
m2 = ' \n Name: {} \n Cmd: {} \n Cmd args: {} '
die ( 2 , ( m1 + m2 ) . format ( name , cmd , args ) )
if use_popen_spawn :
args = [ ( " ' " + a + " ' " if ' ' in a else a ) for a in args ]
cmd_str = ' {} {} ' . format ( cmd , ' ' . join ( args ) )
if use_popen_spawn :
cmd_str = cmd_str . replace ( ' \\ ' , ' / ' )
2016-07-12 22:25:53 +03:00
if opt . log :
log_fd . write ( cmd_str + ' \n ' )
2016-11-23 17:17:08 +03:00
if opt . verbose or opt . print_cmdline or opt . exact_output :
clr1 , clr2 , eol = ( ( green , cyan , ' \n ' ) , ( nocolor , nocolor , ' ' ) ) [ bool ( opt . print_cmdline ) ]
sys . stderr . write ( green ( ' Testing: {} \n ' . format ( desc ) ) )
sys . stderr . write ( clr1 ( ' Executing {} {} ' . format ( clr2 ( cmd_str ) , eol ) ) )
2015-01-03 00:14:40 +03:00
else :
2016-02-28 16:41:43 +03:00
m = ' Testing %s : ' % desc
2016-12-05 21:53:16 +03:00
msg_r ( ( m , yellow ( m ) ) [ ia ] )
2015-01-10 18:52:30 +03:00
2016-12-10 16:09:06 +03:00
if mmgen_cmd == ' ' : return
2016-11-23 17:17:08 +03:00
2016-12-05 21:53:16 +03:00
if opt . direct_exec or ia :
2016-02-28 16:41:43 +03:00
msg ( ' ' )
2015-10-25 13:04:30 +03:00
from subprocess import call , check_output
2016-02-28 16:41:43 +03:00
f = ( call , check_output ) [ bool ( no_output ) ]
2016-12-10 16:09:06 +03:00
ret = f ( [ cmd ] + args )
2015-10-25 13:04:30 +03:00
if f == call and ret != 0 :
2016-11-23 17:17:08 +03:00
m = ' ERROR: process returned a non-zero exit status ( %s ) '
die ( 1 , red ( m % ret ) )
2015-01-10 18:52:30 +03:00
else :
2015-05-01 10:39:45 +03:00
if opt . traceback :
2016-12-10 16:09:06 +03:00
cmd , args = tb_cmd , [ cmd ] + args
2016-12-05 21:53:16 +03:00
if use_popen_spawn :
2016-12-10 16:09:06 +03:00
self . p = PopenSpawn ( cmd_str )
2016-12-05 21:53:16 +03:00
else :
2016-12-10 16:09:06 +03:00
self . p = pexpect . spawn ( cmd , args )
2015-01-10 18:52:30 +03:00
if opt . exact_output : self . p . logfile = sys . stdout
2015-01-03 00:14:40 +03:00
def license ( self ) :
2016-11-17 18:10:27 +03:00
if ' MMGEN_NO_LICENSE ' in os . environ : return
2015-01-03 00:14:40 +03:00
p = " ' w ' for conditions and warranty info, or ' c ' to continue: "
my_expect ( self . p , p , ' c ' )
2016-02-28 16:41:43 +03:00
def label ( self , label = ' Test Label ' ) :
p = ' Enter a wallet label, or hit ENTER for no label: '
my_expect ( self . p , p , label + ' \n ' )
2015-04-30 00:09:29 +03:00
def usr_rand_out ( self , saved = False ) :
2016-02-28 16:41:43 +03:00
m = ' %s user-supplied entropy ' % ( ( ' ' , ' saved ' ) [ saved ] )
my_expect ( self . p , ' Generating encryption key from OS random data plus ' + m )
2015-04-30 00:09:29 +03:00
2015-01-03 00:14:40 +03:00
def usr_rand ( self , num_chars ) :
2016-07-27 22:55:47 +03:00
if opt . usr_random :
self . interactive ( )
my_send ( self . p , ' \n ' )
else :
rand_chars = list ( getrandstr ( num_chars , no_space = True ) )
my_expect ( self . p , ' symbols left: ' , ' x ' )
try :
vmsg_r ( ' SEND ' )
while self . p . expect ( ' left: ' , 0.1 ) == 0 :
ch = rand_chars . pop ( 0 )
msg_r ( yellow ( ch ) + ' ' if opt . verbose else ' + ' )
self . p . send ( ch )
except :
vmsg ( ' EOT ' )
my_expect ( self . p , ' ENTER to continue: ' , ' \n ' )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
def passphrase_new ( self , desc , passphrase ) :
2016-02-28 16:41:43 +03:00
my_expect ( self . p , ( ' Enter passphrase for %s : ' % desc ) , passphrase + ' \n ' )
my_expect ( self . p , ' Repeat passphrase: ' , passphrase + ' \n ' )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
def passphrase ( self , desc , passphrase , pwtype = ' ' ) :
if pwtype : pwtype + = ' '
my_expect ( self . p , ( ' Enter %s passphrase for %s .*?: ' % ( pwtype , desc ) ) ,
passphrase + ' \n ' , regex = True )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
def hash_preset ( self , desc , preset = ' ' ) :
2016-02-28 16:41:43 +03:00
my_expect ( self . p , ( ' Enter hash preset for %s ' % desc ) )
my_expect ( self . p , ( ' or hit ENTER .*?: ' ) , str ( preset ) + ' \n ' , regex = True )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
def written_to_file ( self , desc , overwrite_unlikely = False , query = ' Overwrite? ' , oo = False ) :
s1 = ' %s written to file ' % desc
2015-01-03 00:14:40 +03:00
s2 = query + " Type uppercase ' YES ' to confirm: "
2016-02-28 16:41:43 +03:00
ret = my_expect ( self . p , ( [ s1 , s2 ] , s1 ) [ overwrite_unlikely ] )
2015-01-03 00:14:40 +03:00
if ret == 1 :
2016-02-28 16:41:43 +03:00
my_send ( self . p , ' YES \n ' )
2015-10-25 13:04:30 +03:00
# if oo:
outfile = self . expect_getend ( " Overwriting file ' " ) . rstrip ( " ' " )
return outfile
# else:
# ret = my_expect(self.p,s1)
2016-12-05 21:53:16 +03:00
self . expect ( NL , nonl = True )
outfile = self . p . before . strip ( ) . strip ( " ' " )
if opt . debug_pexpect : msgred ( ' Outfile [ %s ] ' % outfile )
2016-02-28 16:41:43 +03:00
vmsg ( ' %s file: %s ' % ( desc , cyan ( outfile . replace ( " ' " , ' ' ) ) ) )
2015-01-03 00:14:40 +03:00
return outfile
def no_overwrite ( self ) :
2016-02-28 16:41:43 +03:00
self . expect ( " Overwrite? Type uppercase ' YES ' to confirm: " , ' \n ' )
self . expect ( ' Exiting at user request ' )
2015-01-03 00:14:40 +03:00
def tx_view ( self ) :
2016-02-28 16:41:43 +03:00
my_expect ( self . p , r ' View .*?transaction.*? \ (y \ )es, \ (N \ )o, pager \ (v \ )iew.*?: ' , ' \n ' , regex = True )
2015-01-03 00:14:40 +03:00
def expect_getend ( self , s , regex = False ) :
ret = self . expect ( s , regex = regex , nonl = True )
2016-12-05 21:53:16 +03:00
debug_pexpect_msg ( self . p )
# end = self.readline().strip()
# readline() of partial lines doesn't work with PopenSpawn, so do this instead:
self . expect ( NL , nonl = True )
debug_pexpect_msg ( self . p )
end = self . p . before
2016-02-28 16:41:43 +03:00
vmsg ( ' ==> %s ' % cyan ( end ) )
2015-01-03 00:14:40 +03:00
return end
def interactive ( self ) :
return self . p . interact ( )
def logfile ( self , arg ) :
self . p . logfile = arg
def expect ( self , * args , * * kwargs ) :
return my_expect ( self . p , * args , * * kwargs )
def send ( self , * args , * * kwargs ) :
return my_send ( self . p , * args , * * kwargs )
2016-12-05 21:53:16 +03:00
# def readline(self):
# return self.p.readline()
# def readlines(self):
# return [l.rstrip()+'\n' for l in self.p.readlines()]
2015-01-07 07:41:25 +03:00
def read ( self , n = None ) :
2015-01-03 00:14:40 +03:00
return self . p . read ( n )
2016-12-05 21:53:16 +03:00
def close ( self ) :
if not use_popen_spawn :
self . p . close ( )
2016-07-26 22:16:25 +03:00
from mmgen . obj import BTCAmt
2015-01-03 00:14:40 +03:00
from mmgen . bitcoin import verify_addr
2016-07-26 22:16:25 +03:00
def create_fake_unspent_entry ( address , sid = None , idx = None , lbl = None , non_mmgen = None ) :
if lbl : lbl = ' ' + lbl
return {
' account ' : ( non_mmgen or ( ' %s : %s %s ' % ( sid , idx , lbl ) ) ) . decode ( ' utf8 ' ) ,
2016-02-28 16:41:43 +03:00
' vout ' : int ( getrandnum ( 4 ) % 8 ) ,
2016-07-26 22:16:25 +03:00
' txid ' : hexlify ( os . urandom ( 32 ) ) . decode ( ' utf8 ' ) ,
' amount ' : BTCAmt ( ' %s . %s ' % ( 10 + ( getrandnum ( 4 ) % 40 ) , getrandnum ( 4 ) % 100000000 ) ) ,
2016-02-28 16:41:43 +03:00
' address ' : address ,
' spendable ' : False ,
' scriptPubKey ' : ( ' 76a914 ' + verify_addr ( address , return_hex = True ) + ' 88ac ' ) ,
2016-07-26 22:16:25 +03:00
' confirmations ' : getrandnum ( 4 ) % 50000
}
labels = [
" Automotive " ,
" Travel expenses " ,
" Healthcare " ,
" Freelancing 1 " ,
" Freelancing 2 " ,
2016-07-27 22:55:47 +03:00
" Alice ' s allowance " ,
2016-07-26 22:16:25 +03:00
" Bob ' s bequest " ,
" House purchase " ,
" Real estate fund " ,
" Job 1 " ,
" XYZ Corp. " ,
" Eddie ' s endowment " ,
" Emergency fund " ,
" Real estate fund " ,
" Ian ' s inheritance " ,
" " ,
" Rainy day " ,
" Fred ' s funds " ,
" Job 2 " ,
" Carl ' s capital " ,
]
label_iter = None
2015-01-06 20:10:29 +03:00
def create_fake_unspent_data ( adata , unspent_data_file , tx_data , non_mmgen_input = ' ' ) :
2015-01-03 00:14:40 +03:00
out = [ ]
2015-10-25 13:04:30 +03:00
for s in tx_data :
2015-01-03 00:14:40 +03:00
sid = tx_data [ s ] [ ' sid ' ]
2016-07-26 22:16:25 +03:00
a = adata . addrlist ( sid )
2015-04-30 00:09:29 +03:00
for n , ( idx , btcaddr ) in enumerate ( a . addrpairs ( ) , 1 ) :
2016-07-26 22:16:25 +03:00
while True :
try : lbl = next ( label_iter )
except : label_iter = iter ( labels )
else : break
out . append ( create_fake_unspent_entry ( btcaddr , sid , idx , lbl ) )
if n == 1 : # create a duplicate address. This means addrs_per_wallet += 1
out . append ( create_fake_unspent_entry ( btcaddr , sid , idx , lbl ) )
2015-01-03 00:14:40 +03:00
if non_mmgen_input :
2016-08-22 14:20:46 +03:00
from mmgen . bitcoin import privnum2addr , hex2wif
2015-01-09 21:02:16 +03:00
privnum = getrandnum ( 32 )
2015-01-03 00:14:40 +03:00
btcaddr = privnum2addr ( privnum , compressed = True )
of = os . path . join ( cfgs [ non_mmgen_input ] [ ' tmpdir ' ] , non_mmgen_fn )
2017-05-14 21:54:05 +03:00
wif = hex2wif ( ' {:064x} ' . format ( privnum ) , compressed = True )
# Msg(yellow(wif + ' ' + btcaddr))
write_data_to_file ( of , wif + ' \n ' , ' compressed bitcoin key ' , silent = True )
2015-01-03 00:14:40 +03:00
2016-07-26 22:16:25 +03:00
out . append ( create_fake_unspent_entry ( btcaddr , non_mmgen = ' Non-MMGen address ' ) )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
# msg('\n'.join([repr(o) for o in out])); sys.exit()
write_data_to_file ( unspent_data_file , repr ( out ) , ' Unspent outputs ' , silent = True )
2015-01-03 00:14:40 +03:00
2015-10-25 13:04:30 +03:00
def add_comments_to_addr_file ( addrfile , outfile ) :
2015-01-03 00:14:40 +03:00
silence ( )
msg ( green ( " Adding comments to address file ' %s ' " % addrfile ) )
2016-07-26 22:16:25 +03:00
from mmgen . addr import AddrList
a = AddrList ( addrfile )
2015-10-25 13:04:30 +03:00
for n , idx in enumerate ( a . idxs ( ) , 1 ) :
2016-02-28 16:41:43 +03:00
if n % 2 : a . set_comment ( idx , ' Test address %s ' % n )
2016-07-26 22:16:25 +03:00
a . format ( enable_comments = True )
write_data_to_file ( outfile , a . fmt_data , silent = True )
2015-01-03 00:14:40 +03:00
end_silence ( )
def make_brainwallet_file ( fn ) :
# Print random words with random whitespace in between
2015-04-01 23:24:34 +03:00
from mmgen . mn_tirosh import words
2015-10-25 13:04:30 +03:00
wl = words . split ( )
2016-02-28 16:41:43 +03:00
nwords , ws_list , max_spaces = 10 , ' \n ' , 5
2015-01-03 00:14:40 +03:00
def rand_ws_seq ( ) :
2015-01-09 21:02:16 +03:00
nchars = getrandnum ( 1 ) % max_spaces + 1
2016-02-28 16:41:43 +03:00
return ' ' . join ( [ ws_list [ getrandnum ( 1 ) % len ( ws_list ) ] for i in range ( nchars ) ] )
2015-01-09 21:02:16 +03:00
rand_pairs = [ wl [ getrandnum ( 4 ) % len ( wl ) ] + rand_ws_seq ( ) for i in range ( nwords ) ]
2016-02-28 16:41:43 +03:00
d = ' ' . join ( rand_pairs ) . rstrip ( ) + ' \n '
if opt . verbose : msg_r ( ' Brainwallet password: \n %s ' % cyan ( d ) )
write_data_to_file ( fn , d , ' brainwallet password ' , silent = True )
2015-01-03 00:14:40 +03:00
def do_between ( ) :
2015-01-10 18:52:30 +03:00
if opt . pause :
2016-02-28 16:41:43 +03:00
if keypress_confirm ( green ( ' Continue? ' ) , default_yes = True ) :
if opt . verbose or opt . exact_output : sys . stderr . write ( ' \n ' )
2015-01-03 00:14:40 +03:00
else :
2016-02-28 16:41:43 +03:00
errmsg ( ' Exiting at user request ' )
2015-01-03 00:14:40 +03:00
sys . exit ( )
2015-01-10 18:52:30 +03:00
elif opt . verbose or opt . exact_output :
2016-02-28 16:41:43 +03:00
sys . stderr . write ( ' \n ' )
2015-01-03 00:14:40 +03:00
2015-01-03 20:45:01 +03:00
2015-01-03 00:14:40 +03:00
rebuild_list = OrderedDict ( )
2015-10-25 13:04:30 +03:00
def check_needs_rerun (
ts ,
cmd ,
build = False ,
root = True ,
force_delete = False ,
dpy = False
) :
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
rerun = ( False , True ) [ root ] # force_delete is not passed to recursive call
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
fns = [ ]
if force_delete or not root :
2015-01-12 00:07:21 +03:00
# does cmd produce a needed dependency(ies)?
ret = ts . get_num_exts_for_cmd ( cmd , dpy )
2015-01-09 21:02:16 +03:00
if ret :
for ext in ret [ 1 ] :
fn = get_file_with_ext ( ext , cfgs [ ret [ 0 ] ] [ ' tmpdir ' ] , delete = build )
if fn :
if force_delete : os . unlink ( fn )
else : fns . append ( fn )
else : rerun = True
2015-01-03 20:45:01 +03:00
2015-01-09 21:02:16 +03:00
fdeps = ts . generate_file_deps ( cmd )
cdeps = ts . generate_cmd_deps ( fdeps )
2016-12-05 21:53:16 +03:00
# print 'cmd,fdeps,cdeps,fns: ',cmd,fdeps,cdeps,fns # DEBUG
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
for fn in fns :
2015-01-03 00:14:40 +03:00
my_age = os . stat ( fn ) . st_mtime
2015-01-03 20:45:01 +03:00
for num , ext in fdeps :
f = get_file_with_ext ( ext , cfgs [ num ] [ ' tmpdir ' ] , delete = build )
2016-12-05 21:53:16 +03:00
if f and os . stat ( f ) . st_mtime > my_age :
rerun = True
2015-01-03 20:45:01 +03:00
for cdep in cdeps :
2016-12-05 21:53:16 +03:00
if check_needs_rerun ( ts , cdep , build = build , root = False , dpy = cmd ) :
rerun = True
2015-01-03 00:14:40 +03:00
2015-01-03 20:45:01 +03:00
if build :
if rerun :
2015-01-09 21:02:16 +03:00
for fn in fns :
if not root : os . unlink ( fn )
2016-07-12 22:25:53 +03:00
if not ( dpy and opt . skip_deps ) :
ts . do_cmd ( cmd )
2015-01-03 20:45:01 +03:00
if not root : do_between ( )
else :
# If prog produces multiple files:
if cmd not in rebuild_list or rerun == True :
2016-02-28 16:41:43 +03:00
rebuild_list [ cmd ] = ( rerun , fns [ 0 ] if fns else ' ' ) # FIX
2015-01-03 00:14:40 +03:00
2015-01-03 20:45:01 +03:00
return rerun
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
def refcheck ( desc , chk , refchk ) :
vmsg ( " Comparing %s ' %s ' to stored reference " % ( desc , chk ) )
2015-01-06 20:10:29 +03:00
if chk == refchk :
ok ( )
else :
2016-02-28 16:41:43 +03:00
if not opt . verbose : errmsg ( ' ' )
2015-01-06 20:10:29 +03:00
errmsg ( red ( """
Fatal error - % s ' %s ' does not match reference value ' %s ' . Aborting test
2015-04-25 19:39:25 +03:00
""" .strip() % (desc,chk,refchk)))
2015-01-06 20:10:29 +03:00
sys . exit ( 3 )
2015-01-12 00:07:21 +03:00
def check_deps ( cmds ) :
2015-01-09 21:02:16 +03:00
if len ( cmds ) != 1 :
2016-02-28 16:41:43 +03:00
die ( 1 , ' Usage: %s check_deps <command> ' % g . prog_name )
2015-01-09 21:02:16 +03:00
cmd = cmds [ 0 ]
if cmd not in cmd_data :
2016-02-28 16:41:43 +03:00
die ( 1 , " ' %s ' : unrecognized command " % cmd )
2015-01-09 21:02:16 +03:00
2015-01-10 18:52:30 +03:00
if not opt . quiet :
2015-01-09 21:02:16 +03:00
msg ( " Checking dependencies for ' %s ' " % ( cmd ) )
check_needs_rerun ( ts , cmd , build = False )
w = max ( len ( i ) for i in rebuild_list ) + 1
for cmd in rebuild_list :
c = rebuild_list [ cmd ]
2016-02-28 16:41:43 +03:00
m = ' Rebuild ' if ( c [ 0 ] and c [ 1 ] ) else ' Build ' if c [ 0 ] else ' OK '
msg ( ' cmd { :< {w} } {} ' . format ( cmd + ' : ' , m , w = w ) )
2015-04-25 19:39:25 +03:00
# mmsg(cmd,c)
2015-01-09 21:02:16 +03:00
2015-10-25 13:04:30 +03:00
def clean ( usr_dirs = [ ] ) :
2016-12-05 21:53:16 +03:00
if opt . skip_deps and not ia : return
2015-10-25 13:04:30 +03:00
all_dirs = MMGenTestSuite ( ) . list_tmp_dirs ( )
dirs = ( usr_dirs or all_dirs )
2015-01-10 18:52:30 +03:00
for d in sorted ( dirs ) :
2015-10-25 13:04:30 +03:00
if str ( d ) in all_dirs :
cleandir ( all_dirs [ str ( d ) ] )
2015-01-09 21:02:16 +03:00
else :
2016-02-28 16:41:43 +03:00
die ( 1 , ' %s : invalid directory number ' % d )
2016-12-18 19:59:27 +03:00
cleandir ( os . path . join ( ' test ' , ' data_dir ' ) )
2015-01-06 20:10:29 +03:00
2015-01-03 00:14:40 +03:00
class MMGenTestSuite ( object ) :
def __init__ ( self ) :
pass
2015-01-09 21:02:16 +03:00
def list_tmp_dirs ( self ) :
d = { }
for k in cfgs : d [ k ] = cfgs [ k ] [ ' tmpdir ' ]
return d
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
def get_num_exts_for_cmd ( self , cmd , dpy = False ) : # dpy ignored here
num = str ( cmd_data [ cmd ] [ 0 ] )
dgl = cfgs [ num ] [ ' dep_generators ' ]
2015-04-25 19:39:25 +03:00
# mmsg(num,cmd,dgl)
2015-01-09 21:02:16 +03:00
if cmd in dgl . values ( ) :
2015-01-12 00:07:21 +03:00
exts = [ k for k in dgl if dgl [ k ] == cmd ]
return ( num , exts )
2015-01-09 21:02:16 +03:00
else :
return None
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
def do_cmd ( self , cmd ) :
2015-01-03 00:14:40 +03:00
2016-12-05 21:53:16 +03:00
if ia and ( len ( cmd_data [ cmd ] ) < 4 or cmd_data [ cmd ] [ 3 ] != 1 ) : return
2015-05-01 22:04:07 +03:00
2016-07-26 22:16:25 +03:00
# delete files produced by this cmd
# for ext,tmpdir in find_generated_exts(cmd):
# print cmd, get_file_with_ext(ext,tmpdir)
2015-01-09 21:02:16 +03:00
d = [ ( str ( num ) , ext ) for exts , num in cmd_data [ cmd ] [ 2 ] for ext in exts ]
2016-07-26 22:16:25 +03:00
# delete files depended on by this cmd
2015-01-09 21:02:16 +03:00
al = [ get_file_with_ext ( ext , cfgs [ num ] [ ' tmpdir ' ] ) for num , ext in d ]
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
global cfg
cfg = cfgs [ str ( cmd_data [ cmd ] [ 0 ] ) ]
2015-01-03 00:14:40 +03:00
2016-07-26 22:16:25 +03:00
if opt . resume :
if cmd == opt . resume :
msg ( yellow ( " Resuming at ' %s ' " % cmd ) )
opt . resume = False
opt . skip_deps = False
else :
return
2016-11-11 16:05:27 +03:00
if opt . profile : start = time . time ( )
2015-01-09 21:02:16 +03:00
self . __class__ . __dict__ [ cmd ] ( * ( [ self , cmd ] + al ) )
2016-11-11 16:05:27 +03:00
if opt . profile :
msg ( ' \r \033 [50C {:.4f} ' . format ( time . time ( ) - start ) )
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
def generate_file_deps ( self , cmd ) :
return [ ( str ( n ) , e ) for exts , n in cmd_data [ cmd ] [ 2 ] for e in exts ]
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
def generate_cmd_deps ( self , fdeps ) :
return [ cfgs [ str ( n ) ] [ ' dep_generators ' ] [ ext ] for n , ext in fdeps ]
2015-01-03 00:14:40 +03:00
2016-11-17 18:10:27 +03:00
def helpscreens ( self , name , arg = ' --help ' ) :
2015-05-01 22:04:07 +03:00
for s in scripts :
2016-11-17 18:10:27 +03:00
t = MMGenExpect ( name , ( ' mmgen- ' + s ) , [ arg ] ,
2016-02-28 16:41:43 +03:00
extra_desc = ' (mmgen- %s ) ' % s , no_output = True )
2016-12-05 21:53:16 +03:00
if not ia :
2015-05-01 22:04:07 +03:00
t . read ( ) ; ok ( )
2016-11-17 18:10:27 +03:00
def longhelpscreens ( self , name ) : self . helpscreens ( name , arg = ' --longhelp ' )
2016-11-23 17:17:08 +03:00
def walletgen ( self , name , del_dw_run = ' dummy ' , seed_len = None , gen_dfl_wallet = False ) :
2016-12-05 21:53:16 +03:00
if ia :
2016-11-23 17:17:08 +03:00
m = " \n Answer ' {} ' at the the interactive prompt " . format ( ( ' n ' , ' y ' ) [ gen_dfl_wallet ] )
msg ( grnbg ( m ) )
2016-02-28 16:41:43 +03:00
write_to_tmpfile ( cfg , pwfile , cfg [ ' wpasswd ' ] + ' \n ' )
2016-07-27 22:55:47 +03:00
add_args = ( [ usr_rand_arg ] ,
2016-12-05 21:53:16 +03:00
[ ' -q ' , ' -r0 ' , ' -L ' , ' Interactive Mode Wallet ' , ' -P ' , get_tmpfile_fn ( cfg , pwfile ) ] ) [ bool ( ia ) ]
2016-02-28 16:41:43 +03:00
args = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -p1 ' ]
if seed_len : args + = [ ' -l ' , str ( seed_len ) ]
t = MMGenExpect ( name , ' mmgen-walletgen ' , args + add_args )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-03 00:14:40 +03:00
t . license ( )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2016-02-28 16:41:43 +03:00
t . passphrase_new ( ' new MMGen wallet ' , cfg [ ' wpasswd ' ] )
2015-04-30 00:09:29 +03:00
t . label ( )
2016-11-23 17:17:08 +03:00
global have_dfl_wallet
if not have_dfl_wallet :
t . expect ( ' move it to the data directory? (Y/n): ' , ( ' n ' , ' y ' ) [ gen_dfl_wallet ] )
if gen_dfl_wallet : have_dfl_wallet = True
2016-02-28 16:41:43 +03:00
t . written_to_file ( ' MMGen wallet ' )
2015-01-06 20:10:29 +03:00
ok ( )
2016-11-21 19:59:03 +03:00
def walletgen_dfl_wallet ( self , name , seed_len = None ) :
2016-11-23 17:17:08 +03:00
self . walletgen ( name , seed_len = seed_len , gen_dfl_wallet = True )
2016-11-21 19:59:03 +03:00
2015-04-30 00:09:29 +03:00
def brainwalletgen_ref ( self , name ) :
2016-02-28 16:41:43 +03:00
sl_arg = ' -l %s ' % cfg [ ' seed_len ' ]
hp_arg = ' -p %s ' % ref_wallet_hash_preset
2015-04-07 17:57:17 +03:00
label = " test.py ref. wallet (pw ' %s ' , seed len %s ) " \
2015-04-30 00:09:29 +03:00
% ( ref_wallet_brainpass , cfg [ ' seed_len ' ] )
2016-02-28 16:41:43 +03:00
bf = ' ref.mmbrain '
args = [ ' -d ' , cfg [ ' tmpdir ' ] , hp_arg , sl_arg , ' -ib ' , ' -L ' , label ]
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , bf , ref_wallet_brainpass )
write_to_tmpfile ( cfg , pwfile , cfg [ ' wpasswd ' ] )
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
add_args = [ ' -r0 ' , ' -q ' , ' -P %s ' % get_tmpfile_fn ( cfg , pwfile ) ,
2015-10-25 13:04:30 +03:00
get_tmpfile_fn ( cfg , bf ) ]
else :
2016-07-27 22:55:47 +03:00
add_args = [ usr_rand_arg ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-walletconv ' , args + add_args )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-12 22:49:40 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . expect ( ' Enter brainwallet: ' , ref_wallet_brainpass + ' \n ' )
t . passphrase_new ( ' new MMGen wallet ' , cfg [ ' wpasswd ' ] )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2016-12-10 16:09:06 +03:00
sid = os . path . basename ( t . written_to_file ( ' MMGen wallet ' ) . split ( ' - ' ) [ 0 ] )
2016-02-28 16:41:43 +03:00
refcheck ( ' Seed ID ' , sid , cfg [ ' seed_id ' ] )
2015-04-30 00:09:29 +03:00
def refwalletgen ( self , name ) : self . brainwalletgen_ref ( name )
2015-04-07 17:57:17 +03:00
2015-05-01 22:04:07 +03:00
def passchg ( self , name , wf , pf ) :
2016-12-05 21:53:16 +03:00
# ia: reuse password, since there's no way to change it non-interactively
2015-05-01 22:04:07 +03:00
silence ( )
write_to_tmpfile ( cfg , pwfile , get_data_from_file ( pf ) )
end_silence ( )
2016-12-05 21:53:16 +03:00
add_args = ( [ usr_rand_arg ] , [ ' -q ' , ' -r0 ' , ' -P ' , pf ] ) [ bool ( ia ) ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-passchg ' , add_args +
2016-11-23 17:17:08 +03:00
[ ' -d ' , cfg [ ' tmpdir ' ] , ' -p ' , ' 2 ' , ' -L ' , ' Changed label ' ] + ( [ ] , [ wf ] ) [ bool ( wf ) ] )
2016-12-05 21:53:16 +03:00
if ia : return
2015-04-30 00:09:29 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' MMGen wallet ' , cfgs [ ' 1 ' ] [ ' wpasswd ' ] , pwtype = ' old ' )
t . expect_getend ( ' Hash preset changed to ' )
2016-11-23 17:17:08 +03:00
t . passphrase ( ' MMGen wallet ' , cfg [ ' wpasswd ' ] , pwtype = ' new ' ) # reuse passphrase?
2016-02-28 16:41:43 +03:00
t . expect ( ' Repeat passphrase: ' , cfg [ ' wpasswd ' ] + ' \n ' )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2016-11-23 17:17:08 +03:00
# t.expect('Enter a wallet label.*: ','Changed Label\n',regex=True)
2016-02-28 16:41:43 +03:00
t . expect_getend ( ' Label changed to ' )
# t.expect_getend('Key ID changed: ')
2016-11-21 19:59:03 +03:00
if not wf :
t . expect ( " Type uppercase ' YES ' to confirm: " , ' YES \n ' )
t . written_to_file ( ' New wallet ' )
2016-12-05 21:53:16 +03:00
t . expect ( ' Securely deleting old wallet ' )
# t.expect('Okay to WIPE 1 regular file ? (Yes/No)','Yes\n')
t . expect ( ' Wallet passphrase has changed ' )
2016-11-21 19:59:03 +03:00
t . expect_getend ( ' has been changed to ' )
else :
t . written_to_file ( ' MMGen wallet ' )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 20:45:01 +03:00
2016-11-21 19:59:03 +03:00
def passchg_dfl_wallet ( self , name , pf ) :
2016-12-05 21:53:16 +03:00
if ia :
2016-11-23 17:17:08 +03:00
m = " \n Answer ' YES ' <ENTER> at the the interactive prompt "
msg ( grnbg ( m ) )
2016-11-21 19:59:03 +03:00
return self . passchg ( name = name , wf = None , pf = pf )
2016-02-28 16:41:43 +03:00
def walletchk ( self , name , wf , pf , desc = ' MMGen wallet ' ,
add_args = [ ] , sid = None , pw = False , extra_desc = ' ' ) :
2016-12-05 21:53:16 +03:00
args = ( [ ] , [ ' -P ' , pf , ' -q ' ] ) [ bool ( ia and pf ) ]
2015-05-01 22:04:07 +03:00
hp = cfg [ ' hash_preset ' ] if ' hash_preset ' in cfg else ' 1 '
2016-02-28 16:41:43 +03:00
wf_arg = ( [ ] , [ wf ] ) [ bool ( wf ) ]
t = MMGenExpect ( name , ' mmgen-walletchk ' ,
add_args + args + [ ' -p ' , hp ] + wf_arg ,
2015-10-25 13:04:30 +03:00
extra_desc = extra_desc )
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
if sid :
2016-02-28 16:41:43 +03:00
n = ( ' should be ' , ' ' ) [ desc == ' MMGen wallet ' ]
m = grnbg ( ' Seed ID %s : ' % n )
msg ( grnbg ( ' %s %s ' % ( m , cyan ( sid ) ) ) )
2015-10-25 13:04:30 +03:00
return
2016-02-28 16:41:43 +03:00
if desc != ' hidden incognito data ' :
2016-11-21 19:59:03 +03:00
t . expect ( " Getting %s from file ' " % ( desc ) )
2015-10-25 13:04:30 +03:00
if pw :
t . passphrase ( desc , cfg [ ' wpasswd ' ] )
t . expect (
2016-02-28 16:41:43 +03:00
[ ' Passphrase is OK ' , ' Passphrase.* are correct ' ] ,
2015-10-25 13:04:30 +03:00
regex = True
)
2016-02-28 16:41:43 +03:00
chk = t . expect_getend ( ' Valid %s for Seed ID ' % desc ) [ : 8 ]
2015-10-25 13:04:30 +03:00
if sid : cmp_or_die ( chk , sid )
else : ok ( )
2015-01-03 00:14:40 +03:00
2016-11-21 19:59:03 +03:00
def walletchk_newpass ( self , name , wf , pf ) :
2015-10-25 13:04:30 +03:00
return self . walletchk ( name , wf , pf , pw = True )
2015-04-07 17:57:17 +03:00
2016-11-21 19:59:03 +03:00
def walletchk_newpass_dfl_wallet ( self , name , pf ) :
return self . walletchk_newpass ( name , wf = None , pf = pf )
def delete_dfl_wallet ( self , name , pf ) :
2016-11-23 17:17:08 +03:00
with open ( os . path . join ( cfg [ ' tmpdir ' ] , ' del_dw_run ' ) , ' w ' ) as f : pass
if opt . no_dw_delete : return True
2016-11-21 19:59:03 +03:00
for wf in [ f for f in os . listdir ( g . data_dir ) if f [ - 6 : ] == ' .mmdat ' ] :
os . unlink ( os . path . join ( g . data_dir , wf ) )
2016-11-23 17:17:08 +03:00
MMGenExpect ( name , ' ' )
global have_dfl_wallet
have_dfl_wallet = False
2016-12-05 21:53:16 +03:00
if not ia : ok ( )
2016-11-21 19:59:03 +03:00
2016-07-26 22:16:25 +03:00
def addrgen ( self , name , wf , pf = None , check_ref = False ) :
2016-12-05 21:53:16 +03:00
add_args = ( [ ] , [ ' -q ' ] + ( [ ] , [ ' -P ' , pf ] ) [ bool ( pf ) ] ) [ ia ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-addrgen ' , add_args +
2016-11-21 19:59:03 +03:00
[ ' -d ' , cfg [ ' tmpdir ' ] ] + ( [ ] , [ wf ] ) [ bool ( wf ) ] + [ cfg [ ' addr_idx_list ' ] ] )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-03 00:14:40 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' MMGen wallet ' , cfg [ ' wpasswd ' ] )
t . expect ( ' Passphrase is OK ' )
chk = t . expect_getend ( r ' Checksum for address data .*?: ' , regex = True )
2015-01-06 20:10:29 +03:00
if check_ref :
2016-02-28 16:41:43 +03:00
refcheck ( ' address data checksum ' , chk , cfg [ ' addrfile_chk ' ] )
2015-01-06 20:10:29 +03:00
return
2016-02-28 16:41:43 +03:00
t . written_to_file ( ' Addresses ' , oo = True )
2015-01-06 20:10:29 +03:00
ok ( )
2016-11-23 17:17:08 +03:00
def addrgen_dfl_wallet ( self , name , pf = None , check_ref = False ) :
2016-11-21 19:59:03 +03:00
return self . addrgen ( name , wf = None , pf = pf , check_ref = check_ref )
2015-10-25 13:04:30 +03:00
def refaddrgen ( self , name , wf , pf ) :
2016-02-28 16:41:43 +03:00
d = ' ( %s -bit seed) ' % cfg [ ' seed_len ' ]
2015-10-25 13:04:30 +03:00
self . addrgen ( name , wf , pf = pf , check_ref = True )
2015-04-07 17:57:17 +03:00
2015-01-03 00:14:40 +03:00
def addrimport ( self , name , addrfile ) :
2016-12-05 21:53:16 +03:00
add_args = ( [ ] , [ ' -q ' , ' -t ' ] ) [ ia ]
2016-02-28 16:41:43 +03:00
outfile = os . path . join ( cfg [ ' tmpdir ' ] , ' addrfile_w_comments ' )
2015-01-03 00:14:40 +03:00
add_comments_to_addr_file ( addrfile , outfile )
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-addrimport ' , add_args + [ outfile ] )
2016-12-05 21:53:16 +03:00
if ia : return
2016-02-28 16:41:43 +03:00
t . expect_getend ( r ' Checksum for address data .* \ [.* \ ]: ' , regex = True )
t . expect_getend ( ' Validating addresses...OK. ' )
t . expect ( " Type uppercase ' YES ' to confirm: " , ' \n ' )
vmsg ( ' This is a simulation, so no addresses were actually imported into the tracking \n wallet ' )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-12-12 00:30:23 +03:00
def txcreate_common ( self , name , sources = [ ' 1 ' ] , non_mmgen_input = ' ' , do_label = False , txdo_args = [ ] , add_args = [ ] ) :
2015-01-10 18:52:30 +03:00
if opt . verbose or opt . exact_output :
2016-07-26 22:16:25 +03:00
sys . stderr . write ( green ( ' Generating fake tracking wallet info \n ' ) )
2015-01-03 00:14:40 +03:00
silence ( )
2016-07-30 14:42:22 +03:00
from mmgen . addr import AddrList , AddrData , AddrIdxList
2016-07-26 22:16:25 +03:00
tx_data , ad = { } , AddrData ( )
2015-01-03 00:14:40 +03:00
for s in sources :
2016-02-28 16:41:43 +03:00
afile = get_file_with_ext ( ' addrs ' , cfgs [ s ] [ ' tmpdir ' ] )
2016-07-26 22:16:25 +03:00
ai = AddrList ( afile )
ad . add ( ai )
2016-07-30 14:42:22 +03:00
aix = AddrIdxList ( fmt_str = cfgs [ s ] [ ' addr_idx_list ' ] )
2015-01-03 00:14:40 +03:00
if len ( aix ) != addrs_per_wallet :
2016-02-28 16:41:43 +03:00
errmsg ( red ( ' Address index list length != %s : %s ' %
2015-01-03 00:14:40 +03:00
( addrs_per_wallet , repr ( aix ) ) ) )
sys . exit ( )
tx_data [ s ] = {
2015-01-06 20:10:29 +03:00
' addrfile ' : afile ,
2016-07-26 22:16:25 +03:00
' chk ' : ai . chksum ,
2015-01-06 20:10:29 +03:00
' sid ' : ai . seed_id ,
2015-01-03 00:14:40 +03:00
' addr_idxs ' : aix [ - 2 : ] ,
}
2016-02-28 16:41:43 +03:00
unspent_data_file = os . path . join ( cfg [ ' tmpdir ' ] , ' unspent.json ' )
2016-07-26 22:16:25 +03:00
create_fake_unspent_data ( ad , unspent_data_file , tx_data , non_mmgen_input )
if opt . verbose or opt . exact_output :
sys . stderr . write ( " Fake transaction wallet data written to file ' %s ' \n " % unspent_data_file )
2015-01-03 00:14:40 +03:00
# make the command line
from mmgen . bitcoin import privnum2addr
2015-01-09 21:02:16 +03:00
btcaddr = privnum2addr ( getrandnum ( 32 ) , compressed = True )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
cmd_args = [ ' -d ' , cfg [ ' tmpdir ' ] ]
2015-10-25 13:04:30 +03:00
for num in tx_data :
2015-01-03 00:14:40 +03:00
s = tx_data [ num ]
cmd_args + = [
2016-02-28 16:41:43 +03:00
' %s : %s , %s ' % ( s [ ' sid ' ] , s [ ' addr_idxs ' ] [ 0 ] , cfgs [ num ] [ ' amts ' ] [ 0 ] ) ,
2015-01-03 00:14:40 +03:00
]
# + one BTC address
# + one change address and one BTC address
if num is tx_data . keys ( ) [ - 1 ] :
2016-02-28 16:41:43 +03:00
cmd_args + = [ ' %s : %s ' % ( s [ ' sid ' ] , s [ ' addr_idxs ' ] [ 1 ] ) ]
cmd_args + = [ ' %s , %s ' % ( btcaddr , cfgs [ num ] [ ' amts ' ] [ 1 ] ) ]
2015-01-03 00:14:40 +03:00
for num in tx_data : cmd_args + = [ tx_data [ num ] [ ' addrfile ' ] ]
2016-02-28 16:41:43 +03:00
os . environ [ ' MMGEN_BOGUS_WALLET_DATA ' ] = unspent_data_file
2015-01-03 00:14:40 +03:00
end_silence ( )
2016-02-28 16:41:43 +03:00
if opt . verbose or opt . exact_output : sys . stderr . write ( ' \n ' )
2015-01-03 00:14:40 +03:00
2016-12-05 21:53:16 +03:00
if ia :
2016-12-12 00:30:23 +03:00
add_args + = [ ' -q ' ]
2016-02-28 16:41:43 +03:00
m = ' \n Answer the interactive prompts as follows: \n ' + \
2016-11-23 17:17:08 +03:00
" ' y ' , ' y ' , ' q ' , ' 1-9 ' <ENTER>, ENTER, ENTER, ENTER, ENTER, ' y ' "
2015-10-25 13:04:30 +03:00
msg ( grnbg ( m ) )
2016-12-12 00:30:23 +03:00
bwd_msg = ' MMGEN_BOGUS_WALLET_DATA= %s ' % unspent_data_file
if opt . print_cmdline : msg ( bwd_msg )
if opt . log : log_fd . write ( bwd_msg + ' ' )
2017-05-17 15:37:30 +03:00
t = MMGenExpect ( name , ' mmgen- ' + ( ' txcreate ' , ' txdo ' ) [ bool ( txdo_args ) ] , [ ' --rbf ' , ' -f ' , tx_fee ] + add_args + cmd_args + txdo_args )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-03 00:14:40 +03:00
t . license ( )
2016-12-12 00:30:23 +03:00
if txdo_args and add_args : # txdo4
t . hash_preset ( ' key-address data ' , ' 1 ' )
t . passphrase ( ' key-address data ' , cfgs [ ' 14 ' ] [ ' kapasswd ' ] )
t . expect ( ' Check key-to-address validity? (y/N): ' , ' y ' )
2015-10-25 13:04:30 +03:00
for num in tx_data :
2016-02-28 16:41:43 +03:00
t . expect_getend ( ' Getting address data from file ' )
chk = t . expect_getend ( r ' Checksum for address data .*?: ' , regex = True )
2015-01-03 00:14:40 +03:00
verify_checksum_or_exit ( tx_data [ num ] [ ' chk ' ] , chk )
# not in tracking wallet warning, (1 + num sources) times
2016-02-28 16:41:43 +03:00
if t . expect ( [ ' Continue anyway? (y/N): ' ,
' Unable to connect to bitcoind ' ] ) == 0 :
t . send ( ' y ' )
2015-01-03 00:14:40 +03:00
else :
2016-02-28 16:41:43 +03:00
errmsg ( red ( ' Error: unable to connect to bitcoind. Exiting ' ) )
2015-01-03 00:14:40 +03:00
sys . exit ( 1 )
2015-10-25 13:04:30 +03:00
for num in tx_data :
2016-02-28 16:41:43 +03:00
t . expect ( ' Continue anyway? (y/N): ' , ' y ' )
2016-07-30 14:42:22 +03:00
t . expect ( r " ' q ' =quit view, .*?:. " , ' M ' , regex = True )
t . expect ( r " ' q ' =quit view, .*?:. " , ' q ' , regex = True )
2016-07-26 22:16:25 +03:00
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 )
2016-02-28 16:41:43 +03:00
t . expect ( ' Enter a range or space-separated list of outputs to spend: ' ,
' ' . join ( [ str ( i ) for i in outputs_list ] ) + ' \n ' )
2016-12-12 00:30:23 +03:00
if non_mmgen_input and not txdo_args : t . expect ( ' Accept? (y/N): ' , ' y ' )
2016-06-25 18:27:45 +03:00
t . expect ( ' OK? (Y/n): ' , ' y ' ) # fee OK?
t . expect ( ' OK? (Y/n): ' , ' y ' ) # change OK?
2016-07-31 19:57:54 +03:00
if do_label :
t . expect ( ' Add a comment to transaction? (y/N): ' , ' y ' )
t . expect ( ' Comment: ' , ref_tx_label . encode ( ' utf8 ' ) + ' \n ' )
else :
t . expect ( ' Add a comment to transaction? (y/N): ' , ' \n ' )
2015-01-03 00:14:40 +03:00
t . tx_view ( )
2016-12-12 00:30:23 +03:00
if txdo_args : return t
2016-02-28 16:41:43 +03:00
t . expect ( ' Save transaction? (y/N): ' , ' y ' )
t . written_to_file ( ' Transaction ' )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-12-12 00:30:23 +03:00
def txcreate ( self , name , addrfile ) :
self . txcreate_common ( name , sources = [ ' 1 ' ] )
2017-05-17 15:37:30 +03:00
def txbump ( self , name , txfile , prepend_args = [ ] , seed_args = [ ] ) :
args = prepend_args + [ ' -q ' , ' -d ' , cfg [ ' tmpdir ' ] , txfile ] + seed_args
t = MMGenExpect ( name , ' mmgen-txbump ' , args )
if seed_args :
t . hash_preset ( ' key-address data ' , ' 1 ' )
t . passphrase ( ' key-address data ' , cfgs [ ' 14 ' ] [ ' kapasswd ' ] )
t . expect ( ' Check key-to-address validity? (y/N): ' , ' y ' )
t . expect ( ' Which output do you wish to deduct the fee from? ' , ' 1 \n ' )
# Fee must be > tx_fee + network relay fee (currently 0.00001)
t . expect ( ' OK? (Y/n): ' , ' \n ' )
t . expect ( ' Enter transaction fee: ' , ' 124s \n ' )
t . expect ( ' OK? (Y/n): ' , ' \n ' )
if seed_args : # sign and send
t . expect ( ' Edit transaction comment? (y/N): ' , ' \n ' )
for cnum , desc in ( ' 1 ' , ' incognito data ' ) , ( ' 3 ' , ' MMGen wallet ' ) , ( ' 4 ' , ' MMGen wallet ' ) :
t . passphrase ( ( ' %s ' % desc ) , cfgs [ cnum ] [ ' wpasswd ' ] )
t . expect ( " Type uppercase ' YES ' to confirm: " , ' YES \n ' )
else :
t . expect ( ' Add a comment to transaction? (y/N): ' , ' \n ' )
t . expect ( ' Save transaction? (y/N): ' , ' y ' )
t . written_to_file ( ' Transaction ' )
os . unlink ( txfile ) # our tx file replaces the original
os . system ( ' touch ' + os . path . join ( cfg [ ' tmpdir ' ] , ' txbump ' ) )
ok ( )
2016-12-12 00:30:23 +03:00
def txdo ( self , name , addrfile , wallet ) :
t = self . txcreate_common ( name , sources = [ ' 1 ' ] , txdo_args = [ wallet ] )
self . txsign ( name , ' ' , ' ' , pf = ' ' , save = True , has_label = False , txdo_handle = t )
self . txsend ( name , ' ' , txdo_handle = t )
def txcreate_dfl_wallet ( self , name , addrfile ) :
self . txcreate_common ( name , sources = [ ' 15 ' ] )
2016-07-31 19:57:54 +03:00
def txsign_end ( self , t , tnum = None , has_label = False ) :
2016-02-28 16:41:43 +03:00
t . expect ( ' Signing transaction ' )
2016-07-31 19:57:54 +03:00
cprompt = ( ' Add a comment to transaction ' , ' Edit transaction comment ' ) [ has_label ]
2016-07-12 22:25:53 +03:00
t . expect ( ' %s ? (y/N): ' % cprompt , ' \n ' )
t . expect ( ' Save signed transaction.*? \ ? \ (Y/n \ ): ' , ' y ' , regex = True )
2016-02-28 16:41:43 +03:00
add = ' # ' + tnum if tnum else ' '
t . written_to_file ( ' Signed transaction ' + add , oo = True )
2017-05-17 15:37:30 +03:00
def txsign ( self , name , txfile , wf , pf = ' ' , bumpf = ' ' , save = True , has_label = False , txdo_handle = None ) :
2016-12-05 21:53:16 +03:00
add_args = ( [ ] , [ ' -q ' , ' -P ' , pf ] ) [ ia ]
if ia :
2016-02-28 16:41:43 +03:00
m = ' \n Answer the interactive prompts as follows: \n ENTER, ENTER, ENTER '
2015-10-25 13:04:30 +03:00
msg ( grnbg ( m ) )
2016-12-12 00:30:23 +03:00
if txdo_handle :
t = txdo_handle
if ia : return
else :
t = MMGenExpect ( name , ' mmgen-txsign ' , add_args + [ ' -d ' , cfg [ ' tmpdir ' ] , txfile ] + ( [ ] , [ wf ] ) [ bool ( wf ) ] )
if ia : return
t . license ( )
t . tx_view ( )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' MMGen wallet ' , cfg [ ' wpasswd ' ] )
2016-12-12 00:30:23 +03:00
if txdo_handle : return
2015-04-07 17:57:17 +03:00
if save :
2016-07-31 19:57:54 +03:00
self . txsign_end ( t , has_label = has_label )
2015-04-07 17:57:17 +03:00
else :
2016-07-31 19:57:54 +03:00
cprompt = ( ' Add a comment to transaction ' , ' Edit transaction comment ' ) [ has_label ]
2016-07-12 22:25:53 +03:00
t . expect ( ' %s ? (y/N): ' % cprompt , ' \n ' )
2015-10-25 13:04:30 +03:00
t . close ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-11-21 19:59:03 +03:00
def txsign_dfl_wallet ( self , name , txfile , pf = ' ' , save = True , has_label = False ) :
return self . txsign ( name , txfile , wf = None , pf = pf , save = save , has_label = has_label )
2016-12-12 00:30:23 +03:00
def txsend ( self , name , sigfile , txdo_handle = None ) :
if txdo_handle :
t = txdo_handle
else :
t = MMGenExpect ( name , ' mmgen-txsend ' , [ ' -d ' , cfg [ ' tmpdir ' ] , sigfile ] )
t . license ( )
t . tx_view ( )
t . expect ( ' Add a comment to transaction? (y/N): ' , ' \n ' )
2016-02-28 16:41:43 +03:00
t . expect ( ' broadcast this transaction to the network? ' )
2016-12-12 00:30:23 +03:00
m = ' YES, I REALLY WANT TO DO THIS '
t . expect ( " ' %s ' to confirm: " % m , m + ' \n ' )
t . expect ( ' BOGUS transaction NOT sent ' )
2017-05-17 15:37:30 +03:00
t . written_to_file ( ' Sent transaction ' )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-11-23 17:17:08 +03:00
def walletconv_export ( self , name , wf , desc , uargs = [ ] , out_fmt = ' w ' , pf = None , out_pw = False ) :
opts = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -o ' , out_fmt ] + uargs + \
( [ ] , [ wf ] ) [ bool ( wf ) ] + ( [ ] , [ ' -P ' , pf ] ) [ bool ( pf ) ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-walletconv ' , opts )
2016-12-05 21:53:16 +03:00
if ia : return
2015-04-30 00:09:29 +03:00
t . license ( )
2016-11-23 17:17:08 +03:00
if not pf :
t . passphrase ( ' MMGen wallet ' , cfg [ ' wpasswd ' ] )
if out_pw :
2016-02-28 16:41:43 +03:00
t . passphrase_new ( ' new ' + desc , cfg [ ' wpasswd ' ] )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2016-11-23 17:17:08 +03:00
2016-02-28 16:41:43 +03:00
if ' ' . join ( desc . split ( ) [ - 2 : ] ) == ' incognito data ' :
t . expect ( ' Generating encryption key from OS random data ' )
t . expect ( ' Generating encryption key from OS random data ' )
ic_id = t . expect_getend ( ' New Incog Wallet ID: ' )
t . expect ( ' Generating encryption key from OS random data ' )
if desc == ' hidden incognito data ' :
2015-04-30 00:09:29 +03:00
write_to_tmpfile ( cfg , incog_id_fn , ic_id )
2016-02-28 16:41:43 +03:00
ret = t . expect ( [ ' Create? (Y/n): ' , " ' YES ' to confirm: " ] )
2015-04-30 00:09:29 +03:00
if ret == 0 :
2016-02-28 16:41:43 +03:00
t . send ( ' \n ' )
t . expect ( ' Enter file size: ' , str ( hincog_bytes ) + ' \n ' )
2015-04-30 00:09:29 +03:00
else :
2016-02-28 16:41:43 +03:00
t . send ( ' YES \n ' )
if out_fmt == ' w ' : t . label ( )
2015-04-30 00:09:29 +03:00
return t . written_to_file ( capfirst ( desc ) , oo = True )
2015-01-03 00:14:40 +03:00
2016-11-23 17:17:08 +03:00
def export_seed ( self , name , wf , desc = ' seed data ' , out_fmt = ' seed ' , pf = None ) :
f = self . walletconv_export ( name , wf , desc = desc , out_fmt = out_fmt , pf = pf )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-03 00:14:40 +03:00
silence ( )
2016-02-28 16:41:43 +03:00
msg ( ' %s : %s ' % ( capfirst ( desc ) , cyan ( get_data_from_file ( f , desc ) ) ) )
2015-01-03 00:14:40 +03:00
end_silence ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-12-15 20:53:29 +03:00
def export_hex ( self , name , wf , desc = ' hexadecimal seed data ' , out_fmt = ' hex ' , pf = None ) :
self . export_seed ( name , wf , desc = desc , out_fmt = out_fmt , pf = pf )
2016-11-23 17:17:08 +03:00
def export_seed_dfl_wallet ( self , name , pf , desc = ' seed data ' , out_fmt = ' seed ' ) :
self . export_seed ( name , wf = None , desc = desc , out_fmt = out_fmt , pf = pf )
2016-11-21 19:59:03 +03:00
2015-04-30 00:09:29 +03:00
def export_mnemonic ( self , name , wf ) :
2016-02-28 16:41:43 +03:00
self . export_seed ( name , wf , desc = ' mnemonic data ' , out_fmt = ' words ' )
2015-04-30 00:09:29 +03:00
2016-02-28 16:41:43 +03:00
def export_incog ( self , name , wf , desc = ' incognito data ' , out_fmt = ' i ' , add_args = [ ] ) :
2016-07-27 22:55:47 +03:00
uargs = [ ' -p1 ' , usr_rand_arg ] + add_args
2016-11-23 17:17:08 +03:00
self . walletconv_export ( name , wf , desc = desc , out_fmt = out_fmt , uargs = uargs , out_pw = True )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-04-30 00:09:29 +03:00
def export_incog_hex ( self , name , wf ) :
2016-02-28 16:41:43 +03:00
self . export_incog ( name , wf , desc = ' hex incognito data ' , out_fmt = ' xi ' )
2015-01-03 00:14:40 +03:00
# TODO: make outdir and hidden incog compatible (ignore --outdir and warn user?)
2015-04-30 00:09:29 +03:00
def export_incog_hidden ( self , name , wf ) :
rf = os . path . join ( cfg [ ' tmpdir ' ] , hincog_fn )
2016-02-28 16:41:43 +03:00
add_args = [ ' -J ' , ' %s , %s ' % ( rf , hincog_offset ) ]
2015-04-30 00:09:29 +03:00
self . export_incog (
2016-02-28 16:41:43 +03:00
name , wf , desc = ' hidden incognito data ' , out_fmt = ' hi ' , add_args = add_args )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
def addrgen_seed ( self , name , wf , foo , desc = ' seed data ' , in_fmt = ' seed ' ) :
stdout = ( False , True ) [ desc == ' seed data ' ] #capture output to screen once
add_arg = ( [ ] , [ ' -S ' ] ) [ bool ( stdout ) ]
t = MMGenExpect ( name , ' mmgen-addrgen ' , add_arg +
[ ' -i ' + in_fmt , ' -d ' , cfg [ ' tmpdir ' ] , wf , cfg [ ' addr_idx_list ' ] ] )
2015-01-03 00:14:40 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . expect_getend ( ' Valid %s for Seed ID ' % desc )
vmsg ( ' Comparing generated checksum with checksum from previous address file ' )
chk = t . expect_getend ( r ' Checksum for address data .*?: ' , regex = True )
2015-04-30 00:09:29 +03:00
if stdout : t . read ( )
2015-01-03 00:14:40 +03:00
verify_checksum_or_exit ( get_addrfile_checksum ( ) , chk )
2015-04-30 00:09:29 +03:00
# t.no_overwrite()
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-12-15 20:53:29 +03:00
def addrgen_hex ( self , name , wf , foo , desc = ' hexadecimal seed data ' , in_fmt = ' hex ' ) :
self . addrgen_seed ( name , wf , foo , desc = desc , in_fmt = in_fmt )
2015-05-01 10:39:45 +03:00
def addrgen_mnemonic ( self , name , wf , foo ) :
2016-02-28 16:41:43 +03:00
self . addrgen_seed ( name , wf , foo , desc = ' mnemonic data ' , in_fmt = ' words ' )
def addrgen_incog ( self , name , wf = [ ] , foo = ' ' , in_fmt = ' i ' , desc = ' incognito data ' , args = [ ] ) :
t = MMGenExpect ( name , ' mmgen-addrgen ' , args + [ ' -i ' + in_fmt , ' -d ' , cfg [ ' tmpdir ' ] ] +
( [ ] , [ wf ] ) [ bool ( wf ) ] + [ cfg [ ' addr_idx_list ' ] ] )
2015-01-03 00:14:40 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . expect_getend ( ' Incog Wallet ID: ' )
2015-05-01 10:39:45 +03:00
t . hash_preset ( desc , ' 1 ' )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' %s \ w {8} ' % desc , cfg [ ' wpasswd ' ] )
vmsg ( ' Comparing generated checksum with checksum from address file ' )
chk = t . expect_getend ( r ' Checksum for address data .*?: ' , regex = True )
2015-04-30 00:09:29 +03:00
t . close ( )
2015-01-03 00:14:40 +03:00
verify_checksum_or_exit ( get_addrfile_checksum ( ) , chk )
2015-04-30 00:09:29 +03:00
# t.no_overwrite()
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-05-01 10:39:45 +03:00
def addrgen_incog_hex ( self , name , wf , foo ) :
2016-02-28 16:41:43 +03:00
self . addrgen_incog ( name , wf , ' ' , in_fmt = ' xi ' , desc = ' hex incognito data ' )
2015-01-03 00:14:40 +03:00
2015-05-01 10:39:45 +03:00
def addrgen_incog_hidden ( self , name , wf , foo ) :
2015-01-03 00:14:40 +03:00
rf = os . path . join ( cfg [ ' tmpdir ' ] , hincog_fn )
2016-02-28 16:41:43 +03:00
self . addrgen_incog ( name , [ ] , ' ' , in_fmt = ' hi ' , desc = ' hidden incognito data ' ,
args = [ ' -H ' , ' %s , %s ' % ( rf , hincog_offset ) , ' -l ' , str ( hincog_seedlen ) ] )
2015-01-03 00:14:40 +03:00
2016-07-26 22:16:25 +03:00
def keyaddrgen ( self , name , wf , pf = None , check_ref = False ) :
2016-11-17 18:10:27 +03:00
args = [ ' -d ' , cfg [ ' tmpdir ' ] , usr_rand_arg , wf , cfg [ ' addr_idx_list ' ] ]
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
m = " \n Answer ' n ' at the interactive prompt "
msg ( grnbg ( m ) )
2016-07-26 22:16:25 +03:00
args = [ ' -q ' ] + ( [ ] , [ ' -P ' , pf ] ) [ bool ( pf ) ] + args
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-keygen ' , args )
2016-12-05 21:53:16 +03:00
if ia : return
2015-01-03 00:14:40 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' MMGen wallet ' , cfg [ ' wpasswd ' ] )
chk = t . expect_getend ( r ' Checksum for key-address data .*?: ' , regex = True )
2015-01-06 20:10:29 +03:00
if check_ref :
2016-02-28 16:41:43 +03:00
refcheck ( ' key-address data checksum ' , chk , cfg [ ' keyaddrfile_chk ' ] )
2015-01-06 20:10:29 +03:00
return
2016-02-28 16:41:43 +03:00
t . expect ( ' Encrypt key list? (y/N): ' , ' y ' )
2016-11-17 18:10:27 +03:00
t . usr_rand ( usr_rand_chars )
2016-02-28 16:41:43 +03:00
t . hash_preset ( ' new key list ' , ' 1 ' )
2016-11-11 16:05:27 +03:00
# t.passphrase_new('new key list','kafile password')
2016-02-28 16:41:43 +03:00
t . passphrase_new ( ' new key list ' , cfg [ ' kapasswd ' ] )
t . written_to_file ( ' Secret keys ' , oo = True )
2015-01-06 20:10:29 +03:00
ok ( )
2015-10-25 13:04:30 +03:00
def refkeyaddrgen ( self , name , wf , pf ) :
self . keyaddrgen ( name , wf , pf , check_ref = True )
2015-04-07 17:57:17 +03:00
2015-01-03 00:14:40 +03:00
def txsign_keyaddr ( self , name , keyaddr_file , txfile ) :
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-txsign ' , [ ' -d ' , cfg [ ' tmpdir ' ] , ' -M ' , keyaddr_file , txfile ] )
2015-01-03 00:14:40 +03:00
t . license ( )
2016-07-26 22:16:25 +03:00
t . hash_preset ( ' key-address data ' , ' 1 ' )
t . passphrase ( ' key-address data ' , cfg [ ' kapasswd ' ] )
2016-02-28 16:41:43 +03:00
t . expect ( ' Check key-to-address validity? (y/N): ' , ' y ' )
2015-01-04 11:14:11 +03:00
t . tx_view ( )
2015-04-07 17:57:17 +03:00
self . txsign_end ( t )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-11-23 17:17:08 +03:00
def walletgen2 ( self , name , del_dw_run = ' dummy ' ) :
2015-01-12 14:41:17 +03:00
self . walletgen ( name , seed_len = 128 )
2015-01-03 00:14:40 +03:00
2015-05-01 22:04:07 +03:00
def addrgen2 ( self , name , wf ) :
2016-02-28 16:41:43 +03:00
self . addrgen ( name , wf , pf = ' ' )
2015-01-03 00:14:40 +03:00
def txcreate2 ( self , name , addrfile ) :
self . txcreate_common ( name , sources = [ ' 2 ' ] )
def txsign2 ( self , name , txf1 , wf1 , txf2 , wf2 ) :
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-txsign ' , [ ' -d ' , cfg [ ' tmpdir ' ] , txf1 , wf1 , txf2 , wf2 ] )
2015-01-03 00:14:40 +03:00
t . license ( )
2015-04-07 17:57:17 +03:00
for cnum in ( ' 1 ' , ' 2 ' ) :
2015-01-03 00:14:40 +03:00
t . tx_view ( )
2016-02-28 16:41:43 +03:00
t . passphrase ( ' MMGen wallet ' , cfgs [ cnum ] [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
self . txsign_end ( t , cnum )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-05-01 22:04:07 +03:00
def export_mnemonic2 ( self , name , wf ) :
self . export_mnemonic ( name , wf )
2015-01-03 00:14:40 +03:00
2016-11-23 17:17:08 +03:00
def walletgen3 ( self , name , del_dw_run = ' dummy ' ) :
2015-01-03 00:14:40 +03:00
self . walletgen ( name )
2015-05-01 22:04:07 +03:00
def addrgen3 ( self , name , wf ) :
2016-02-28 16:41:43 +03:00
self . addrgen ( name , wf , pf = ' ' )
2015-01-03 00:14:40 +03:00
def txcreate3 ( self , name , addrfile1 , addrfile2 ) :
self . txcreate_common ( name , sources = [ ' 1 ' , ' 3 ' ] )
def txsign3 ( self , name , wf1 , wf2 , txf2 ) :
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-txsign ' , [ ' -d ' , cfg [ ' tmpdir ' ] , wf1 , wf2 , txf2 ] )
2015-01-03 00:14:40 +03:00
t . license ( )
t . tx_view ( )
2015-04-07 17:57:17 +03:00
for cnum in ( ' 1 ' , ' 3 ' ) :
2016-02-28 16:41:43 +03:00
# t.expect_getend('Getting MMGen wallet data from file ')
t . passphrase ( ' MMGen wallet ' , cfgs [ cnum ] [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
self . txsign_end ( t )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-11-23 17:17:08 +03:00
def walletgen4 ( self , name , del_dw_run = ' dummy ' ) :
2015-04-30 00:09:29 +03:00
bwf = os . path . join ( cfg [ ' tmpdir ' ] , cfg [ ' bw_filename ' ] )
make_brainwallet_file ( bwf )
seed_len = str ( cfg [ ' seed_len ' ] )
2016-07-27 22:55:47 +03:00
args = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -p1 ' , usr_rand_arg , ' -l ' + seed_len , ' -ib ' ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-walletconv ' , args + [ bwf ] )
2015-04-30 00:09:29 +03:00
t . license ( )
2016-02-28 16:41:43 +03:00
t . passphrase_new ( ' new MMGen wallet ' , cfg [ ' wpasswd ' ] )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2015-04-30 00:09:29 +03:00
t . label ( )
2016-02-28 16:41:43 +03:00
t . written_to_file ( ' MMGen wallet ' )
2015-04-30 00:09:29 +03:00
ok ( )
2015-05-01 22:04:07 +03:00
def addrgen4 ( self , name , wf ) :
2016-02-28 16:41:43 +03:00
self . addrgen ( name , wf , pf = ' ' )
2015-01-03 00:14:40 +03:00
2016-07-26 22:16:25 +03:00
def txcreate4 ( self , name , f1 , f2 , f3 , f4 , f5 , f6 ) :
2016-07-31 19:57:54 +03:00
self . txcreate_common ( name , sources = [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 14 ' ] , non_mmgen_input = ' 4 ' , do_label = 1 )
2015-01-03 00:14:40 +03:00
2016-12-12 00:30:23 +03:00
def txdo4 ( self , name , f1 , f2 , f3 , f4 , f5 , f6 , f7 , f8 , f9 , f10 , f11 , f12 ) :
2015-01-03 20:45:01 +03:00
non_mm_fn = os . path . join ( cfg [ ' tmpdir ' ] , non_mmgen_fn )
2016-12-12 00:30:23 +03:00
add_args = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -i ' , ' brain ' , ' -b ' + cfg [ ' bw_params ' ] , ' -p1 ' , ' -k ' , non_mm_fn , ' -M ' , f12 ]
t = self . txcreate_common ( name , sources = [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 14 ' ] , non_mmgen_input = ' 4 ' , do_label = 1 , txdo_args = [ f7 , f8 , f9 , f10 ] , add_args = add_args )
2017-05-17 15:37:30 +03:00
os . system ( ' rm -f %s /*.sigtx ' % cfg [ ' tmpdir ' ] )
2016-12-12 00:30:23 +03:00
self . txsign4 ( name , f7 , f8 , f9 , f10 , f11 , f12 , txdo_handle = t )
self . txsend ( name , ' ' , txdo_handle = t )
2017-05-17 15:37:30 +03:00
os . system ( ' touch ' + os . path . join ( cfg [ ' tmpdir ' ] , ' txdo ' ) )
def txbump4 ( self , name , f1 , f2 , f3 , f4 , f5 , f6 , f7 , f8 , f9 ) : # f7:txfile,f9:'txdo'
non_mm_fn = os . path . join ( cfg [ ' tmpdir ' ] , non_mmgen_fn )
self . txbump ( name , f7 , prepend_args = [ ' -p1 ' , ' -k ' , non_mm_fn , ' -M ' , f1 ] , seed_args = [ f2 , f3 , f4 , f5 , f6 , f8 ] )
2016-12-12 00:30:23 +03:00
def txsign4 ( self , name , f1 , f2 , f3 , f4 , f5 , f6 , txdo_handle = None ) :
if txdo_handle :
t = txdo_handle
else :
non_mm_fn = os . path . join ( cfg [ ' tmpdir ' ] , non_mmgen_fn )
a = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -i ' , ' brain ' , ' -b ' + cfg [ ' bw_params ' ] , ' -p1 ' , ' -k ' , non_mm_fn , ' -M ' , f6 , f1 , f2 , f3 , f4 , f5 ]
t = MMGenExpect ( name , ' mmgen-txsign ' , a )
t . license ( )
t . hash_preset ( ' key-address data ' , ' 1 ' )
t . passphrase ( ' key-address data ' , cfgs [ ' 14 ' ] [ ' kapasswd ' ] )
t . expect ( ' Check key-to-address validity? (y/N): ' , ' y ' )
t . tx_view ( )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
for cnum , desc in ( ' 1 ' , ' incognito data ' ) , ( ' 3 ' , ' MMGen wallet ' ) :
t . passphrase ( ( ' %s ' % desc ) , cfgs [ cnum ] [ ' wpasswd ' ] )
2015-01-03 00:14:40 +03:00
2016-12-12 00:30:23 +03:00
if txdo_handle : return
2016-07-31 19:57:54 +03:00
self . txsign_end ( t , has_label = True )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2016-02-28 16:41:43 +03:00
def tool_encrypt ( self , name , infile = ' ' ) :
2015-01-09 21:02:16 +03:00
if infile :
infn = infile
else :
d = os . urandom ( 1033 )
tmp_fn = cfg [ ' tool_enc_infn ' ]
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , tmp_fn , d , binary = True )
2015-01-09 21:02:16 +03:00
infn = get_tmpfile_fn ( cfg , tmp_fn )
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
pwfn = ' ni_pw '
2016-02-28 16:41:43 +03:00
write_to_tmpfile ( cfg , pwfn , tool_enc_passwd + ' \n ' )
pre = [ ' -P ' , get_tmpfile_fn ( cfg , pwfn ) ]
app = [ ' hash_preset=1 ' ]
2015-10-25 13:04:30 +03:00
else :
pre , app = [ ] , [ ]
2016-11-17 18:10:27 +03:00
t = MMGenExpect ( name , ' mmgen-tool ' , pre + [ ' -d ' , cfg [ ' tmpdir ' ] , usr_rand_arg , ' encrypt ' , infn ] + app )
2016-12-05 21:53:16 +03:00
if ia : return
2016-11-17 18:10:27 +03:00
t . usr_rand ( usr_rand_chars )
2016-02-28 16:41:43 +03:00
t . hash_preset ( ' user data ' , ' 1 ' )
t . passphrase_new ( ' user data ' , tool_enc_passwd )
t . written_to_file ( ' Encrypted data ' )
2015-01-09 21:02:16 +03:00
ok ( )
2015-10-25 13:04:30 +03:00
2015-04-07 17:57:17 +03:00
# Generate the reference mmenc file
# def tool_encrypt_ref(self,name):
# infn = get_tmpfile_fn(cfg,cfg['tool_enc_ref_infn'])
2015-10-25 13:04:30 +03:00
# write_data_to_file(infn,cfg['tool_enc_reftext'],silent=True)
2015-04-07 17:57:17 +03:00
# self.tool_encrypt(name,infn)
2015-01-09 21:02:16 +03:00
def tool_decrypt ( self , name , f1 , f2 ) :
2016-02-28 16:41:43 +03:00
of = name + ' .out '
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
pwfn = ' ni_pw '
2016-02-28 16:41:43 +03:00
pre = [ ' -P ' , get_tmpfile_fn ( cfg , pwfn ) ]
2015-10-25 13:04:30 +03:00
else :
pre = [ ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-tool ' ,
pre + [ ' -d ' , cfg [ ' tmpdir ' ] , ' decrypt ' , f2 , ' outfile= ' + of , ' hash_preset=1 ' ] )
2016-12-05 21:53:16 +03:00
if not ia :
2016-02-28 16:41:43 +03:00
t . passphrase ( ' user data ' , tool_enc_passwd )
t . written_to_file ( ' Decrypted data ' )
2015-10-25 13:04:30 +03:00
d1 = read_from_file ( f1 , binary = True )
d2 = read_from_file ( get_tmpfile_fn ( cfg , of ) , binary = True )
2016-12-05 21:53:16 +03:00
cmp_or_die ( d1 , d2 , skip_ok = ia )
2015-01-09 21:02:16 +03:00
2015-01-12 00:07:21 +03:00
def tool_find_incog_data ( self , name , f1 , f2 ) :
i_id = read_from_file ( f2 ) . rstrip ( )
2016-02-28 16:41:43 +03:00
vmsg ( ' Incog ID: %s ' % cyan ( i_id ) )
t = MMGenExpect ( name , ' mmgen-tool ' ,
[ ' -d ' , cfg [ ' tmpdir ' ] , ' find_incog_data ' , f1 , i_id ] )
2016-12-05 21:53:16 +03:00
if ia : return
2016-02-28 16:41:43 +03:00
o = t . expect_getend ( ' Incog data for ID %s found at offset ' % i_id )
2015-04-30 00:09:29 +03:00
os . unlink ( f1 )
2015-01-12 00:07:21 +03:00
cmp_or_die ( hincog_offset , int ( o ) )
2015-04-07 17:57:17 +03:00
# Saved reference file tests
2015-04-25 19:39:25 +03:00
def ref_wallet_conv ( self , name ) :
wf = os . path . join ( ref_dir , cfg [ ' ref_wallet ' ] )
2016-02-28 16:41:43 +03:00
self . walletconv_in ( name , wf , ' MMGen wallet ' , pw = True , oo = True )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
def ref_mn_conv ( self , name , ext = ' mmwords ' , desc = ' Mnemonic data ' ) :
wf = os . path . join ( ref_dir , cfg [ ' seed_id ' ] + ' . ' + ext )
2015-04-25 19:39:25 +03:00
self . walletconv_in ( name , wf , desc , oo = True )
def ref_seed_conv ( self , name ) :
2016-02-28 16:41:43 +03:00
self . ref_mn_conv ( name , ext = ' mmseed ' , desc = ' Seed data ' )
2015-04-25 19:39:25 +03:00
2016-12-15 20:53:29 +03:00
def ref_hex_conv ( self , name ) :
self . ref_mn_conv ( name , ext = ' mmhex ' , desc = ' Hexadecimal seed data ' )
2015-04-25 19:39:25 +03:00
def ref_brain_conv ( self , name ) :
2016-02-28 16:41:43 +03:00
uopts = [ ' -i ' , ' b ' , ' -p ' , ' 1 ' , ' -l ' , str ( cfg [ ' seed_len ' ] ) ]
self . walletconv_in ( name , None , ' brainwallet ' , uopts , oo = True )
2015-04-25 19:39:25 +03:00
2016-02-28 16:41:43 +03:00
def ref_incog_conv ( self , name , wfk = ' ic_wallet ' , in_fmt = ' i ' , desc = ' incognito data ' ) :
uopts = [ ' -i ' , in_fmt , ' -p ' , ' 1 ' , ' -l ' , str ( cfg [ ' seed_len ' ] ) ]
2015-04-25 19:39:25 +03:00
wf = os . path . join ( ref_dir , cfg [ wfk ] )
self . walletconv_in ( name , wf , desc , uopts , oo = True , pw = True )
def ref_incox_conv ( self , name ) :
2016-02-28 16:41:43 +03:00
self . ref_incog_conv ( name , in_fmt = ' xi ' , wfk = ' ic_wallet_hex ' , desc = ' hex incognito data ' )
2015-04-25 19:39:25 +03:00
def ref_hincog_conv ( self , name , wfk = ' hic_wallet ' , add_uopts = [ ] ) :
ic_f = os . path . join ( ref_dir , cfg [ wfk ] )
2016-02-28 16:41:43 +03:00
uopts = [ ' -i ' , ' hi ' , ' -p ' , ' 1 ' , ' -l ' , str ( cfg [ ' seed_len ' ] ) ] + add_uopts
hi_opt = [ ' -H ' , ' %s , %s ' % ( ic_f , ref_wallet_incog_offset ) ]
self . walletconv_in ( name , None , ' hidden incognito data ' , uopts + hi_opt , oo = True , pw = True )
2015-04-25 19:39:25 +03:00
def ref_hincog_conv_old ( self , name ) :
2016-02-28 16:41:43 +03:00
self . ref_hincog_conv ( name , wfk = ' hic_wallet_old ' , add_uopts = [ ' -O ' ] )
2015-04-25 19:39:25 +03:00
def ref_wallet_conv_out ( self , name ) :
2016-02-28 16:41:43 +03:00
self . walletconv_out ( name , ' MMGen wallet ' , ' w ' , pw = True )
2015-04-25 19:39:25 +03:00
def ref_mn_conv_out ( self , name ) :
2016-02-28 16:41:43 +03:00
self . walletconv_out ( name , ' mnemonic data ' , ' mn ' )
2015-04-25 19:39:25 +03:00
def ref_seed_conv_out ( self , name ) :
2016-02-28 16:41:43 +03:00
self . walletconv_out ( name , ' seed data ' , ' seed ' )
2015-04-25 19:39:25 +03:00
2016-12-15 20:53:29 +03:00
def ref_hex_conv_out ( self , name ) :
self . walletconv_out ( name , ' hexadecimal seed data ' , ' hexseed ' )
2015-04-25 19:39:25 +03:00
def ref_incog_conv_out ( self , name ) :
2016-02-28 16:41:43 +03:00
self . walletconv_out ( name , ' incognito data ' , out_fmt = ' i ' , pw = True )
2015-04-25 19:39:25 +03:00
def ref_incox_conv_out ( self , name ) :
2016-02-28 16:41:43 +03:00
self . walletconv_out ( name , ' hex incognito data ' , out_fmt = ' xi ' , pw = True )
2015-04-25 19:39:25 +03:00
def ref_hincog_conv_out ( self , name , extra_uopts = [ ] ) :
2015-10-25 13:04:30 +03:00
ic_f = os . path . join ( cfg [ ' tmpdir ' ] , hincog_fn )
2016-02-28 16:41:43 +03:00
hi_parms = ' %s , %s ' % ( ic_f , ref_wallet_incog_offset )
sl_parm = ' -l ' + str ( cfg [ ' seed_len ' ] )
2015-04-25 19:39:25 +03:00
self . walletconv_out ( name ,
2016-02-28 16:41:43 +03:00
' hidden incognito data ' , ' hi ' ,
uopts = [ ' -J ' , hi_parms , sl_parm ] + extra_uopts ,
uopts_chk = [ ' -H ' , hi_parms , sl_parm ] ,
2015-04-25 19:39:25 +03:00
pw = True
)
2015-04-07 17:57:17 +03:00
def ref_wallet_chk ( self , name ) :
wf = os . path . join ( ref_dir , cfg [ ' ref_wallet ' ] )
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pwfile , cfg [ ' wpasswd ' ] )
pf = get_tmpfile_fn ( cfg , pwfile )
else :
pf = None
self . walletchk ( name , wf , pf = pf , pw = True , sid = cfg [ ' seed_id ' ] )
2015-04-07 17:57:17 +03:00
2016-12-15 20:53:29 +03:00
def ref_ss_chk ( self , name , ss = None ) :
wf = os . path . join ( ref_dir , ' %s . %s ' % ( cfg [ ' seed_id ' ] , ss . ext ) )
self . walletchk ( name , wf , pf = None , desc = ss . desc , sid = cfg [ ' seed_id ' ] )
def ref_seed_chk ( self , name ) :
2016-07-26 22:16:25 +03:00
from mmgen . seed import SeedFile
2016-12-15 20:53:29 +03:00
self . ref_ss_chk ( name , ss = SeedFile )
def ref_hex_chk ( self , name ) :
from mmgen . seed import HexSeedFile
self . ref_ss_chk ( name , ss = HexSeedFile )
2015-04-07 17:57:17 +03:00
2016-07-26 22:16:25 +03:00
def ref_mn_chk ( self , name ) :
from mmgen . seed import Mnemonic
2016-12-15 20:53:29 +03:00
self . ref_ss_chk ( name , ss = Mnemonic )
2015-04-07 17:57:17 +03:00
def ref_brain_chk ( self , name , bw_file = ref_bw_file ) :
wf = os . path . join ( ref_dir , bw_file )
2016-02-28 16:41:43 +03:00
add_args = [ ' -l %s ' % cfg [ ' seed_len ' ] , ' -p ' + ref_bw_hash_preset ]
2015-10-25 13:04:30 +03:00
self . walletchk ( name , wf , pf = None , add_args = add_args ,
2016-02-28 16:41:43 +03:00
desc = ' brainwallet ' , sid = cfg [ ' ref_bw_seed_id ' ] )
2015-04-07 17:57:17 +03:00
2015-04-25 19:39:25 +03:00
def ref_brain_chk_spc3 ( self , name ) :
2015-04-07 17:57:17 +03:00
self . ref_brain_chk ( name , bw_file = ref_bw_file_spc )
2016-02-28 16:41:43 +03:00
def ref_hincog_chk ( self , name , desc = ' hidden incognito data ' ) :
2015-10-25 13:04:30 +03:00
for wtype , edesc , of_arg in ( ' hic_wallet ' , ' ' , [ ] ) , \
2016-02-28 16:41:43 +03:00
( ' hic_wallet_old ' , ' (old format) ' , [ ' -O ' ] ) :
ic_arg = [ ' -H %s , %s ' % (
2015-04-07 17:57:17 +03:00
os . path . join ( ref_dir , cfg [ wtype ] ) ,
2015-05-01 10:39:45 +03:00
ref_wallet_incog_offset
2015-10-25 13:04:30 +03:00
) ]
2016-02-28 16:41:43 +03:00
slarg = [ ' -l %s ' % cfg [ ' seed_len ' ] ]
hparg = [ ' -p1 ' ]
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pwfile , cfg [ ' wpasswd ' ] )
2016-02-28 16:41:43 +03:00
add_args = [ ' -q ' , ' -P %s ' % get_tmpfile_fn ( cfg , pwfile ) ]
2015-10-25 13:04:30 +03:00
else :
add_args = [ ]
2016-12-05 21:53:16 +03:00
if ia and wtype == ' hic_wallet_old ' :
2015-10-25 13:04:30 +03:00
m = grnbg ( " Answer ' y ' at the interactive prompt if Seed ID is " )
n = cyan ( cfg [ ' seed_id ' ] )
2016-02-28 16:41:43 +03:00
msg ( ' \n %s %s ' % ( m , n ) )
2016-11-11 16:05:27 +03:00
if wtype == ' hic_wallet_old ' and opt . profile : msg ( ' ' )
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-walletchk ' ,
2015-10-25 13:04:30 +03:00
add_args + slarg + hparg + of_arg + ic_arg ,
extra_desc = edesc )
2016-12-05 21:53:16 +03:00
if ia : continue
2015-05-01 10:39:45 +03:00
t . passphrase ( desc , cfg [ ' wpasswd ' ] )
2015-04-25 19:39:25 +03:00
if wtype == ' hic_wallet_old ' :
2016-02-28 16:41:43 +03:00
t . expect ( ' Is the Seed ID correct? (Y/n): ' , ' \n ' )
chk = t . expect_getend ( ' Seed ID: ' )
2015-04-07 17:57:17 +03:00
t . close ( )
cmp_or_die ( cfg [ ' seed_id ' ] , chk )
2016-02-28 16:41:43 +03:00
def ref_addrfile_chk ( self , name , ftype = ' addr ' ) :
2015-04-07 17:57:17 +03:00
wf = os . path . join ( ref_dir , cfg [ ' ref_ ' + ftype + ' file ' ] )
2016-12-05 21:53:16 +03:00
if ia :
2015-10-25 13:04:30 +03:00
m = " \n Answer the interactive prompts as follows: ' 1 ' <ENTER>, ENTER "
msg ( grnbg ( m ) )
2016-02-28 16:41:43 +03:00
pfn = ' ref_kafile_passwd '
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pfn , ref_kafile_pass )
2016-02-28 16:41:43 +03:00
aa = [ ' -P ' , get_tmpfile_fn ( cfg , pfn ) ]
2015-10-25 13:04:30 +03:00
else :
aa = [ ]
2016-02-28 16:41:43 +03:00
t = MMGenExpect ( name , ' mmgen-tool ' , aa + [ ftype + ' file_chksum ' , wf ] )
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
k = ' ref_ %s addrfile_chksum ' % ( ' ' , ' key ' ) [ ftype == ' keyaddr ' ]
m = grnbg ( ' Checksum should be: ' )
2015-10-25 13:04:30 +03:00
n = cyan ( cfg [ k ] )
2016-02-28 16:41:43 +03:00
msg ( grnbg ( ' %s %s ' % ( m , n ) ) )
2015-10-25 13:04:30 +03:00
return
2016-02-28 16:41:43 +03:00
if ftype == ' keyaddr ' :
2016-07-26 22:16:25 +03:00
w = ' key-address data '
2015-04-07 17:57:17 +03:00
t . hash_preset ( w , ref_kafile_hash_preset )
t . passphrase ( w , ref_kafile_pass )
2016-02-28 16:41:43 +03:00
t . expect ( ' Check key-to-address validity? (y/N): ' , ' y ' )
o = t . read ( ) . strip ( ) . split ( ' \n ' ) [ - 1 ]
2015-04-07 17:57:17 +03:00
cmp_or_die ( cfg [ ' ref_ ' + ftype + ' file_chksum ' ] , o )
def ref_keyaddrfile_chk ( self , name ) :
2016-02-28 16:41:43 +03:00
self . ref_addrfile_chk ( name , ftype = ' keyaddr ' )
2015-04-07 17:57:17 +03:00
# def txcreate8(self,name,addrfile):
# self.txcreate_common(name,sources=['8'])
def ref_tx_chk ( self , name ) :
tf = os . path . join ( ref_dir , cfg [ ' ref_tx_file ' ] )
wf = os . path . join ( ref_dir , cfg [ ' ref_wallet ' ] )
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pwfile , cfg [ ' wpasswd ' ] )
pf = get_tmpfile_fn ( cfg , pwfile )
2016-07-31 19:57:54 +03:00
self . txsign ( name , tf , wf , pf , save = False , has_label = True )
2015-04-07 17:57:17 +03:00
def ref_tool_decrypt ( self , name ) :
f = os . path . join ( ref_dir , ref_enc_fn )
2015-10-25 13:04:30 +03:00
aa = [ ]
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
pfn = ' tool_enc_passwd '
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pfn , tool_enc_passwd )
2016-02-28 16:41:43 +03:00
aa = [ ' -P ' , get_tmpfile_fn ( cfg , pfn ) ]
t = MMGenExpect ( name , ' mmgen-tool ' ,
aa + [ ' -q ' , ' decrypt ' , f , ' outfile=- ' , ' hash_preset=1 ' ] )
2016-12-05 21:53:16 +03:00
if ia : return
2016-02-28 16:41:43 +03:00
t . passphrase ( ' user data ' , tool_enc_passwd )
2016-12-05 21:53:16 +03:00
t . expect ( NL , nonl = True )
2015-04-07 17:57:17 +03:00
import re
o = re . sub ( ' \r \n ' , ' \n ' , t . read ( ) )
2015-04-25 19:39:25 +03:00
cmp_or_die ( sample_text , o )
2015-04-07 17:57:17 +03:00
2015-10-25 13:04:30 +03:00
# wallet conversion tests
def walletconv_in ( self , name , infile , desc , uopts = [ ] , pw = False , oo = False ) :
2016-07-27 22:55:47 +03:00
opts = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -o ' , ' words ' , usr_rand_arg ]
2015-10-25 13:04:30 +03:00
if_arg = [ infile ] if infile else [ ]
2016-02-28 16:41:43 +03:00
d = ' (convert) '
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
opts + = [ ' -q ' ]
msg ( ' ' )
2015-10-25 13:04:30 +03:00
if pw :
2016-02-28 16:41:43 +03:00
pfn = ' ni_passwd '
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pfn , cfg [ ' wpasswd ' ] )
2016-02-28 16:41:43 +03:00
opts + = [ ' -P ' , get_tmpfile_fn ( cfg , pfn ) ]
if desc == ' brainwallet ' :
2015-10-25 13:04:30 +03:00
m = " \n Answer the interactive prompt as follows: ' %s ' <ENTER> "
msg ( grnbg ( m % ref_wallet_brainpass ) )
2016-02-28 16:41:43 +03:00
if ' -O ' in uopts :
2015-10-25 13:04:30 +03:00
m = grnbg ( " Answer ' y ' at the interactive prompt if Seed ID is " )
n = cyan ( cfg [ ' seed_id ' ] )
2016-02-28 16:41:43 +03:00
msg ( ' \n %s %s ' % ( m , n ) )
t = MMGenExpect ( name , ' mmgen-walletconv ' , opts + uopts + if_arg , extra_desc = d )
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
m = grnbg ( ' Seed ID should be: ' )
2015-10-25 13:04:30 +03:00
n = cyan ( cfg [ ' seed_id ' ] )
2016-02-28 16:41:43 +03:00
msg ( grnbg ( ' %s %s ' % ( m , n ) ) )
2015-10-25 13:04:30 +03:00
return
t . license ( )
2016-02-28 16:41:43 +03:00
if desc == ' brainwallet ' :
t . expect ( ' Enter brainwallet: ' , ref_wallet_brainpass + ' \n ' )
2015-10-25 13:04:30 +03:00
if pw :
t . passphrase ( desc , cfg [ ' wpasswd ' ] )
2016-02-28 16:41:43 +03:00
if name [ : 19 ] == ' ref_hincog_conv_old ' :
t . expect ( ' Is the Seed ID correct? (Y/n): ' , ' \n ' )
2015-10-25 13:04:30 +03:00
else :
2016-02-28 16:41:43 +03:00
t . expect ( [ ' Passphrase is OK ' , ' are correct ' ] )
2015-10-25 13:04:30 +03:00
# Output
2016-02-28 16:41:43 +03:00
wf = t . written_to_file ( ' Mnemonic data ' , oo = oo )
2015-10-25 13:04:30 +03:00
t . close ( )
ok ( )
# back check of result
2016-11-11 16:05:27 +03:00
if opt . profile : msg ( ' ' )
2015-10-25 13:04:30 +03:00
self . walletchk ( name , wf , pf = None ,
2016-02-28 16:41:43 +03:00
desc = ' mnemonic data ' ,
2015-10-25 13:04:30 +03:00
sid = cfg [ ' seed_id ' ] ,
2016-02-28 16:41:43 +03:00
extra_desc = ' (check) '
2015-10-25 13:04:30 +03:00
)
2016-02-28 16:41:43 +03:00
def walletconv_out ( self , name , desc , out_fmt = ' w ' , uopts = [ ] , uopts_chk = [ ] , pw = False ) :
opts = [ ' -d ' , cfg [ ' tmpdir ' ] , ' -p1 ' , ' -o ' , out_fmt ] + uopts
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
pfn = ' ni_passwd '
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pfn , cfg [ ' wpasswd ' ] )
2016-02-28 16:41:43 +03:00
l = ' Non-Interactive Test Wallet '
aa = [ ' -q ' , ' -L ' , l , ' -r0 ' , ' -P ' , get_tmpfile_fn ( cfg , pfn ) ]
if desc == ' hidden incognito data ' :
2015-10-25 13:04:30 +03:00
rd = os . urandom ( ref_wallet_incog_offset + 128 )
write_to_tmpfile ( cfg , hincog_fn , rd )
else :
2016-07-27 22:55:47 +03:00
aa = [ usr_rand_arg ]
2016-02-28 16:41:43 +03:00
infile = os . path . join ( ref_dir , cfg [ ' seed_id ' ] + ' .mmwords ' )
t = MMGenExpect ( name , ' mmgen-walletconv ' , aa + opts + [ infile ] , extra_desc = ' (convert) ' )
2015-10-25 13:04:30 +03:00
2016-02-28 16:41:43 +03:00
add_args = [ ' -l %s ' % cfg [ ' seed_len ' ] ]
2016-12-05 21:53:16 +03:00
if ia :
2016-02-28 16:41:43 +03:00
pfn = ' ni_passwd '
2015-10-25 13:04:30 +03:00
write_to_tmpfile ( cfg , pfn , cfg [ ' wpasswd ' ] )
pf = get_tmpfile_fn ( cfg , pfn )
2016-02-28 16:41:43 +03:00
if desc != ' hidden incognito data ' :
2015-10-25 13:04:30 +03:00
from mmgen . seed import SeedSource
2016-07-26 22:16:25 +03:00
ext = SeedSource . fmt_code_to_type ( out_fmt ) . ext
2016-02-28 16:41:43 +03:00
hps = ( ' ' , ' ,1 ' ) [ bool ( pw ) ] # TODO real hp
pre_ext = ' [ %s %s ]. ' % ( cfg [ ' seed_len ' ] , hps )
2015-10-25 13:04:30 +03:00
wf = get_file_with_ext ( pre_ext + ext , cfg [ ' tmpdir ' ] , no_dot = True )
else :
t . license ( )
if pw :
2016-02-28 16:41:43 +03:00
t . passphrase_new ( ' new ' + desc , cfg [ ' wpasswd ' ] )
2016-07-27 22:55:47 +03:00
t . usr_rand ( usr_rand_chars )
2016-02-28 16:41:43 +03:00
if ' ' . join ( desc . split ( ) [ - 2 : ] ) == ' incognito data ' :
2015-10-25 13:04:30 +03:00
for i in ( 1 , 2 , 3 ) :
2016-02-28 16:41:43 +03:00
t . expect ( ' Generating encryption key from OS random data ' )
if desc == ' hidden incognito data ' :
ret = t . expect ( [ ' Create? (Y/n): ' , " ' YES ' to confirm: " ] )
2015-10-25 13:04:30 +03:00
if ret == 0 :
2016-02-28 16:41:43 +03:00
t . send ( ' \n ' )
t . expect ( ' Enter file size: ' , str ( hincog_bytes ) + ' \n ' )
2015-10-25 13:04:30 +03:00
else :
2016-02-28 16:41:43 +03:00
t . send ( ' YES \n ' )
if out_fmt == ' w ' : t . label ( )
2015-10-25 13:04:30 +03:00
wf = t . written_to_file ( capfirst ( desc ) , oo = True )
pf = None
ok ( )
2016-02-28 16:41:43 +03:00
if desc == ' hidden incognito data ' :
2015-10-25 13:04:30 +03:00
add_args + = uopts_chk
wf = None
2016-11-11 16:05:27 +03:00
if opt . profile : msg ( ' ' )
2015-10-25 13:04:30 +03:00
self . walletchk ( name , wf , pf = pf ,
desc = desc , sid = cfg [ ' seed_id ' ] , pw = pw ,
add_args = add_args ,
2016-02-28 16:41:43 +03:00
extra_desc = ' (check) ' )
2016-11-21 19:59:03 +03:00
# END methods
2015-10-25 13:04:30 +03:00
for k in (
2016-02-28 16:41:43 +03:00
' ref_wallet_conv ' ,
' ref_mn_conv ' ,
' ref_seed_conv ' ,
2016-12-15 20:53:29 +03:00
' ref_hex_conv ' ,
2016-02-28 16:41:43 +03:00
' ref_brain_conv ' ,
' ref_incog_conv ' ,
' ref_incox_conv ' ,
' ref_hincog_conv ' ,
' ref_hincog_conv_old ' ,
' ref_wallet_conv_out ' ,
' ref_mn_conv_out ' ,
' ref_seed_conv_out ' ,
2016-12-15 20:53:29 +03:00
' ref_hex_conv_out ' ,
2016-02-28 16:41:43 +03:00
' ref_incog_conv_out ' ,
' ref_incox_conv_out ' ,
' ref_hincog_conv_out ' ,
' ref_wallet_chk ' ,
' refwalletgen ' ,
' refaddrgen ' ,
' ref_seed_chk ' ,
2016-12-15 20:53:29 +03:00
' ref_hex_chk ' ,
2016-02-28 16:41:43 +03:00
' ref_mn_chk ' ,
' ref_brain_chk ' ,
' ref_hincog_chk ' ,
' refkeyaddrgen ' ,
2015-10-25 13:04:30 +03:00
) :
for i in ( ' 1 ' , ' 2 ' , ' 3 ' ) :
locals ( ) [ k + i ] = locals ( ) [ k ]
2016-07-26 22:16:25 +03:00
for k in ( ' walletgen ' , ' addrgen ' , ' keyaddrgen ' ) : locals ( ) [ k + ' 14 ' ] = locals ( ) [ k ]
2016-11-21 19:59:03 +03:00
# create temporary dirs
2016-12-12 00:30:23 +03:00
if not opt . resume and not opt . skip_deps :
if g . platform == ' win ' :
for cfg in sorted ( cfgs ) :
mk_tmpdir ( cfgs [ cfg ] [ ' tmpdir ' ] )
else :
for cfg in sorted ( cfgs ) :
src = os . path . join ( shm_dir , cfgs [ cfg ] [ ' tmpdir ' ] . split ( ' / ' ) [ - 1 ] )
mk_tmpdir ( src )
try :
os . unlink ( cfgs [ cfg ] [ ' tmpdir ' ] )
except OSError as e :
if e . errno != 2 : raise
finally :
os . symlink ( src , cfgs [ cfg ] [ ' tmpdir ' ] )
2015-10-25 13:04:30 +03:00
2016-11-23 17:17:08 +03:00
have_dfl_wallet = False
2015-01-07 07:41:25 +03:00
# main()
2015-01-10 18:52:30 +03:00
if opt . pause :
2015-01-03 00:14:40 +03:00
import termios , atexit
fd = sys . stdin . fileno ( )
old = termios . tcgetattr ( fd )
def at_exit ( ) :
termios . tcsetattr ( fd , termios . TCSADRAIN , old )
atexit . register ( at_exit )
2015-01-07 07:41:25 +03:00
start_time = int ( time . time ( ) )
2016-11-23 17:17:08 +03:00
def end_msg ( ) :
t = int ( time . time ( ) ) - start_time
m1 = ' All requested tests finished OK, elapsed time: {:02d} : {:02d} \n '
2016-12-05 21:53:16 +03:00
m2 = ( ' ' , ' Please re-check all {} control values against the program output. \n ' . format ( grnbg ( ' HIGHLIGHTED ' ) ) ) [ ia ]
2016-11-23 17:17:08 +03:00
sys . stderr . write ( green ( m1 . format ( t / 60 , t % 60 ) ) )
sys . stderr . write ( m2 )
2015-01-09 21:02:16 +03:00
ts = MMGenTestSuite ( )
2015-01-03 00:14:40 +03:00
try :
2015-01-09 21:02:16 +03:00
if cmd_args :
2015-04-07 17:57:17 +03:00
for arg in cmd_args :
if arg in utils :
globals ( ) [ arg ] ( cmd_args [ cmd_args . index ( arg ) + 1 : ] )
sys . exit ( )
2016-02-28 16:41:43 +03:00
elif ' info_ ' + arg in cmd_data :
dirs = cmd_data [ ' info_ ' + arg ] [ 1 ]
2015-10-25 13:04:30 +03:00
if dirs : clean ( dirs )
for cmd in cmd_list [ arg ] :
check_needs_rerun ( ts , cmd , build = True )
2015-04-07 17:57:17 +03:00
elif arg in meta_cmds :
2015-04-25 19:39:25 +03:00
for cmd in meta_cmds [ arg ] :
check_needs_rerun ( ts , cmd , build = True )
2015-04-07 17:57:17 +03:00
elif arg in cmd_data :
check_needs_rerun ( ts , arg , build = True )
2015-01-03 00:14:40 +03:00
else :
2016-02-28 16:41:43 +03:00
die ( 1 , ' %s : unrecognized command ' % arg )
2015-01-03 00:14:40 +03:00
else :
2015-01-09 21:02:16 +03:00
clean ( )
2015-01-03 00:14:40 +03:00
for cmd in cmd_data :
2016-02-28 16:41:43 +03:00
if cmd [ : 5 ] == ' info_ ' :
2016-07-26 22:16:25 +03:00
msg ( green ( ' %s Testing %s ' % ( ( ' \n ' , ' ' ) [ bool ( opt . resume ) ] , cmd_data [ cmd ] [ 0 ] ) ) )
2015-10-25 13:04:30 +03:00
continue
2015-01-09 21:02:16 +03:00
ts . do_cmd ( cmd )
2015-01-03 00:14:40 +03:00
if cmd is not cmd_data . keys ( ) [ - 1 ] : do_between ( )
2016-07-26 22:16:25 +03:00
except KeyboardInterrupt :
die ( 1 , ' \n Exiting at user request ' )
raise
2015-01-03 00:14:40 +03:00
except :
sys . stderr = stderr_save
raise
2016-11-23 17:17:08 +03:00
end_msg ( )