2015-01-03 00:14:40 +03:00
#!/usr/bin/python
# Chdir to repo root.
# Since script is not in repo root, fix sys.path so that modules are
# imported from repo, not system.
import sys , os
pn = os . path . dirname ( sys . argv [ 0 ] )
os . chdir ( os . path . join ( pn , os . pardir ) )
sys . path . __setitem__ ( 0 , os . path . abspath ( os . curdir ) )
2015-04-16 17:21:05 +03:00
import mmgen . globalvars as g
2015-01-10 18:52:30 +03:00
import mmgen . opt as opt
2015-04-25 19:39:25 +03:00
from mmgen . util import mmsg , mdie , Msg , die
2015-01-09 21:02:16 +03:00
from mmgen . test import *
2015-01-06 20:10:29 +03:00
2015-01-12 00:07:21 +03:00
hincog_fn = " rand_data "
hincog_bytes = 1024 * 1024
hincog_offset = 98765
hincog_seedlen = 256
incog_id_fn = " incog_id "
2015-01-03 00:14:40 +03:00
non_mmgen_fn = " btckey "
2015-04-07 17:57:17 +03:00
ref_dir = os . path . join ( " test " , " ref " )
ref_wallet_brainpass = " abc "
ref_wallet_hash_preset = " 1 "
ref_wallet_incog_offset = 123
ref_bw_hash_preset = " 1 "
ref_bw_file = " brainwallet "
ref_bw_file_spc = " brainwallet-spaced "
ref_kafile_pass = " kafile password "
ref_kafile_hash_preset = " 1 "
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 = \
" The Times 03/Jan/2009 Chancellor on brink of second bailout for banks \n "
2015-04-07 17:57:17 +03:00
2015-01-03 00:14:40 +03:00
cfgs = {
2015-01-06 20:10:29 +03:00
' 6 ' : {
2015-04-07 17:57:17 +03:00
' name ' : " reference wallet check (128-bit) " ,
' seed_len ' : 128 ,
' seed_id ' : " FE3C6545 " ,
' ref_bw_seed_id ' : " 33F10310 " ,
' addrfile_chk ' : " B230 7526 638F 38CB 8FDC 8B76 " ,
' keyaddrfile_chk ' : " CF83 32FB 8A8B 08E2 0F00 D601 " ,
' wpasswd ' : " reference password " ,
' ref_wallet ' : " FE3C6545-D782B529[128,1].mmdat " ,
2015-04-25 19:39:25 +03:00
' ic_wallet ' : " FE3C6545-E29303EA-5E229E30[128,1].mmincog " ,
' ic_wallet_hex ' : " FE3C6545-BC4BE3F2-32586837[128,1].mmincox " ,
' hic_wallet ' : " FE3C6545-161E495F-BEB7548E[128:1].incog-offset123 " ,
' hic_wallet_old ' : " FE3C6545-161E495F-9860A85B[128:1].incog-old.offset123 " ,
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp6 " ) ,
' kapasswd ' : " " ,
' addr_idx_list ' : " 1010,500-501,31-33,1,33,500,1011 " , # 8 addresses
' dep_generators ' : {
' mmdat ' : " refwalletgen1 " ,
' addrs ' : " refaddrgen1 " ,
' akeys.mmenc ' : " refkeyaddrgen1 "
} ,
} ,
' 7 ' : {
' name ' : " reference wallet check (192-bit) " ,
' seed_len ' : 192 ,
' seed_id ' : " 1378FC64 " ,
' ref_bw_seed_id ' : " CE918388 " ,
' addrfile_chk ' : " 8C17 A5FA 0470 6E89 3A87 8182 " ,
' keyaddrfile_chk ' : " 9648 5132 B98E 3AD9 6FC3 C5AD " ,
' wpasswd ' : " reference password " ,
' ref_wallet ' : " 1378FC64-6F0F9BB4[192,1].mmdat " ,
2015-04-25 19:39:25 +03:00
' ic_wallet ' : " 1378FC64-2907DE97-F980D21F[192,1].mmincog " ,
' ic_wallet_hex ' : " 1378FC64-4DCB5174-872806A7[192,1].mmincox " ,
' hic_wallet ' : " 1378FC64-B55E9958-77256FC1[192:1].incog.offset123 " ,
' hic_wallet_old ' : " 1378FC64-B55E9958-D85FF20C[192:1].incog-old.offset123 " ,
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp7 " ) ,
' kapasswd ' : " " ,
' addr_idx_list ' : " 1010,500-501,31-33,1,33,500,1011 " , # 8 addresses
' dep_generators ' : {
' mmdat ' : " refwalletgen2 " ,
' addrs ' : " refaddrgen2 " ,
' akeys.mmenc ' : " refkeyaddrgen2 "
} ,
} ,
' 8 ' : {
' name ' : " reference wallet check (256-bit) " ,
' seed_len ' : 256 ,
' seed_id ' : " 98831F3A " ,
' ref_bw_seed_id ' : " B48CD7FC " ,
2015-01-06 20:10:29 +03:00
' addrfile_chk ' : " 6FEF 6FB9 7B13 5D91 854A 0BD3 " ,
' keyaddrfile_chk ' : " 9F2D D781 1812 8BAD C396 9DEB " ,
2015-04-07 17:57:17 +03:00
' wpasswd ' : " reference password " ,
' ref_wallet ' : " 98831F3A-27F2BF93[256,1].mmdat " ,
' ref_addrfile ' : " 98831F3A[1,31-33,500-501,1010-1011].addrs " ,
' ref_keyaddrfile ' : " 98831F3A[1,31-33,500-501,1010-1011].akeys.mmenc " ,
' ref_addrfile_chksum ' : " 6FEF 6FB9 7B13 5D91 854A 0BD3 " ,
' ref_keyaddrfile_chksum ' : " 9F2D D781 1812 8BAD C396 9DEB " ,
# 'ref_fake_unspent_data':"98831F3A_unspent.json",
' ref_tx_file ' : " tx_FFB367[1.234].raw " ,
2015-04-25 19:39:25 +03:00
' ic_wallet ' : " 98831F3A-5482381C-18460FB1[256,1].mmincog " ,
' ic_wallet_hex ' : " 98831F3A-1630A9F2-870376A9[256,1].mmincox " ,
' hic_wallet ' : " 98831F3A-F59B07A0-559CEF19[256:1].incog.offset123 " ,
' hic_wallet_old ' : " 98831F3A-F59B07A0-848535F3[256:1].incog-old.offset123 " ,
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp8 " ) ,
2015-01-06 20:10:29 +03:00
' kapasswd ' : " " ,
' addr_idx_list ' : " 1010,500-501,31-33,1,33,500,1011 " , # 8 addresses
' dep_generators ' : {
2015-04-07 17:57:17 +03:00
' mmdat ' : " refwalletgen3 " ,
' addrs ' : " refaddrgen3 " ,
' akeys.mmenc ' : " refkeyaddrgen3 "
2015-01-06 20:10:29 +03:00
} ,
} ,
2015-01-03 00:14:40 +03:00
' 1 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp1 " ) ,
2015-01-03 00:14:40 +03:00
' wpasswd ' : " Dorian " ,
' kapasswd ' : " Grok the blockchain " ,
' addr_idx_list ' : " 12,99,5-10,5,12 " , # 8 addresses
' dep_generators ' : {
' mmdat ' : " walletgen " ,
' addrs ' : " addrgen " ,
' raw ' : " txcreate " ,
' sig ' : " txsign " ,
' mmwords ' : " export_mnemonic " ,
' mmseed ' : " export_seed " ,
' mmincog ' : " export_incog " ,
' mmincox ' : " export_incog_hex " ,
2015-01-12 00:07:21 +03:00
hincog_fn : " export_incog_hidden " ,
incog_id_fn : " export_incog_hidden " ,
2015-01-03 00:14:40 +03:00
' akeys.mmenc ' : " keyaddrgen "
} ,
} ,
' 2 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp2 " ) ,
2015-01-03 00:14:40 +03:00
' wpasswd ' : " Hodling away " ,
' addr_idx_list ' : " 37,45,3-6,22-23 " , # 8 addresses
2015-04-25 19:39:25 +03:00
' seed_len ' : 128 ,
2015-01-03 00:14:40 +03:00
' dep_generators ' : {
' mmdat ' : " walletgen2 " ,
' addrs ' : " addrgen2 " ,
' raw ' : " txcreate2 " ,
' sig ' : " txsign2 " ,
' mmwords ' : " export_mnemonic2 " ,
} ,
} ,
' 3 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp3 " ) ,
2015-01-03 00:14:40 +03:00
' wpasswd ' : " Major miner " ,
' addr_idx_list ' : " 73,54,1022-1023,2-5 " , # 8 addresses
' dep_generators ' : {
' mmdat ' : " walletgen3 " ,
' addrs ' : " addrgen3 " ,
' raw ' : " txcreate3 " ,
' sig ' : " txsign3 "
} ,
} ,
' 4 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp4 " ) ,
2015-01-03 00:14:40 +03:00
' wpasswd ' : " Hashrate rising " ,
' addr_idx_list ' : " 63,1004,542-544,7-9 " , # 8 addresses
2015-04-25 19:39:25 +03:00
' seed_len ' : 192 ,
2015-01-03 00:14:40 +03:00
' dep_generators ' : {
' mmdat ' : " walletgen4 " ,
' mmbrain ' : " walletgen4 " ,
' addrs ' : " addrgen4 " ,
' raw ' : " txcreate4 " ,
' sig ' : " txsign4 " ,
} ,
' bw_filename ' : " brainwallet.mmbrain " ,
2015-01-06 20:10:29 +03:00
' bw_params ' : " 192,1 " ,
2015-01-03 00:14:40 +03:00
} ,
2015-01-03 20:45:01 +03:00
' 5 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp5 " ) ,
2015-01-03 20:45:01 +03:00
' wpasswd ' : " My changed password " ,
' dep_generators ' : {
' mmdat ' : " passchg " ,
} ,
} ,
2015-01-09 21:02:16 +03:00
' 9 ' : {
2015-04-07 17:57:17 +03:00
' tmpdir ' : os . path . join ( " test " , " tmp9 " ) ,
2015-01-09 21:02:16 +03:00
' tool_enc_infn ' : " tool_encrypt.in " ,
2015-04-07 17:57:17 +03:00
# 'tool_enc_ref_infn': "tool_encrypt_ref.in",
2015-01-09 21:02:16 +03:00
' dep_generators ' : {
' tool_encrypt.in ' : " tool_encrypt " ,
' tool_encrypt.in.mmenc ' : " tool_encrypt " ,
2015-04-07 17:57:17 +03:00
# '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 ] )
cfgs [ b ] [ ' tmpdir ' ] = os . path . join ( " test " , " tmp " + b )
2015-01-09 21:02:16 +03:00
from collections import OrderedDict
cmd_data = OrderedDict ( [
# test description depends
[ ' walletgen ' , ( 1 , ' wallet generation ' , [ [ [ ] , 1 ] ] ) ] ,
2015-04-07 17:57:17 +03:00
# ['walletchk', (1,'wallet check', [[["mmdat"],1]])],
2015-01-09 21:02:16 +03:00
[ ' passchg ' , ( 5 , ' password, label and hash preset change ' , [ [ [ " mmdat " ] , 1 ] ] ) ] ,
[ ' walletchk_newpass ' , ( 5 , ' wallet check with new pw, label and hash preset ' , [ [ [ " mmdat " ] , 5 ] ] ) ] ,
[ ' addrgen ' , ( 1 , ' address generation ' , [ [ [ " mmdat " ] , 1 ] ] ) ] ,
[ ' addrimport ' , ( 1 , ' address import ' , [ [ [ " addrs " ] , 1 ] ] ) ] ,
[ ' txcreate ' , ( 1 , ' transaction creation ' , [ [ [ " addrs " ] , 1 ] ] ) ] ,
[ ' txsign ' , ( 1 , ' transaction signing ' , [ [ [ " mmdat " , " raw " ] , 1 ] ] ) ] ,
[ ' txsend ' , ( 1 , ' transaction sending ' , [ [ [ " sig " ] , 1 ] ] ) ] ,
[ ' 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 ] ] ) ] ,
[ ' 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 " ] , 1 ] ] ) ] ,
[ ' txsign_keyaddr ' , ( 1 , ' transaction signing with key-address file ' , [ [ [ " akeys.mmenc " , " raw " ] , 1 ] ] ) ] ,
2015-01-12 14:41:17 +03:00
[ ' walletgen2 ' , ( 2 , ' wallet generation (2), 128-bit seed ' , [ ] ) ] ,
2015-01-09 21:02:16 +03:00
[ ' addrgen2 ' , ( 2 , ' address generation (2) ' , [ [ [ " mmdat " ] , 2 ] ] ) ] ,
[ ' txcreate2 ' , ( 2 , ' transaction creation (2) ' , [ [ [ " addrs " ] , 2 ] ] ) ] ,
[ ' txsign2 ' , ( 2 , ' transaction signing, two transactions ' , [ [ [ " mmdat " , " raw " ] , 1 ] , [ [ " mmdat " , " raw " ] , 2 ] ] ) ] ,
[ ' export_mnemonic2 ' , ( 2 , ' seed export to mmwords format (2) ' , [ [ [ " mmdat " ] , 2 ] ] ) ] ,
[ ' walletgen3 ' , ( 3 , ' wallet generation (3) ' , [ ] ) ] ,
[ ' addrgen3 ' , ( 3 , ' address generation (3) ' , [ [ [ " mmdat " ] , 3 ] ] ) ] ,
[ ' txcreate3 ' , ( 3 , ' tx creation with inputs and outputs from two wallets ' , [ [ [ " addrs " ] , 1 ] , [ [ " addrs " ] , 3 ] ] ) ] ,
[ ' txsign3 ' , ( 3 , ' tx signing with inputs and outputs from two wallets ' , [ [ [ " mmdat " ] , 1 ] , [ [ " mmdat " , " raw " ] , 3 ] ] ) ] ,
[ ' walletgen4 ' , ( 4 , ' wallet generation (4) (brainwallet) ' , [ ] ) ] ,
[ ' addrgen4 ' , ( 4 , ' address generation (4) ' , [ [ [ " mmdat " ] , 4 ] ] ) ] ,
[ ' txcreate4 ' , ( 4 , ' tx creation with inputs and outputs from four seed sources, plus non-MMGen inputs and outputs ' , [ [ [ " addrs " ] , 1 ] , [ [ " addrs " ] , 2 ] , [ [ " addrs " ] , 3 ] , [ [ " addrs " ] , 4 ] ] ) ] ,
[ ' txsign4 ' , ( 4 , ' tx signing with inputs and outputs from incog file, mnemonic file, wallet and brainwallet, plus non-MMGen inputs and outputs ' , [ [ [ " mmincog " ] , 1 ] , [ [ " mmwords " ] , 2 ] , [ [ " mmdat " ] , 3 ] , [ [ " mmbrain " , " raw " ] , 4 ] ] ) ] ,
[ ' tool_encrypt ' , ( 9 , " ' mmgen-tool encrypt ' (random data) " , [ ] ) ] ,
2015-04-25 19:39:25 +03:00
[ ' tool_decrypt ' , ( 9 , " ' mmgen-tool decrypt ' (random data) " , [ [ [ cfgs [ ' 9 ' ] [ ' tool_enc_infn ' ] , cfgs [ ' 9 ' ] [ ' tool_enc_infn ' ] + " .mmenc " ] , 9 ] ] ) ] ,
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 ] ] ) ] ,
2015-01-09 21:02:16 +03:00
] )
2015-04-25 19:39:25 +03:00
# saved reference data
cmd_data_ref = (
# reading
( ' ref_wallet_chk ' , ( [ ] , ' saved reference wallet ' ) ) ,
( ' ref_seed_chk ' , ( [ ] , ' saved seed file ' ) ) ,
( ' 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:
( ' refwalletgen ' , ( [ ] , ' gen new refwallet ' ) ) ,
( ' refaddrgen ' , ( [ " mmdat " ] , ' new refwallet addr chksum ' ) ) ,
( ' refkeyaddrgen ' , ( [ " mmdat " ] , ' new refwallet key-addr chksum ' ) )
)
# misc. saved reference data
cmd_data_ref_other = (
( ' 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:
cmd_data_conv_in = ( # reading
( ' ref_wallet_conv ' , ' conversion of saved reference wallet ' ) ,
( ' ref_mn_conv ' , ' conversion of saved mnemonic ' ) ,
( ' ref_seed_conv ' , ' conversion of saved seed file ' ) ,
( ' 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) ' )
)
cmd_data_conv_out = ( # writing
( ' ref_wallet_conv_out ' , ' ref seed conversion to wallet ' ) ,
( ' ref_mn_conv_out ' , ' ref seed conversion to mnemonic ' ) ,
( ' 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 ' )
)
cmd_groups = OrderedDict ( [
( ' main ' , cmd_data . keys ( ) ) ,
( ' ref ' , [ c [ 0 ] + str ( i ) for c in cmd_data_ref for i in ( 1 , 2 , 3 ) ] ) ,
( ' ref_other ' , [ c [ 0 ] for c in cmd_data_ref_other ] ) ,
( ' conv_in ' , [ c [ 0 ] + str ( i ) for c in cmd_data_conv_in for i in ( 1 , 2 , 3 ) ] ) ,
( ' conv_out ' , [ c [ 0 ] + str ( i ) for c in cmd_data_conv_out for i in ( 1 , 2 , 3 ) ] ) ,
] )
for a , b in cmd_data_ref :
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
cmd_data [ a + str ( i ) ] = ( 5 + i , " %s ( %s -bit) " % ( b [ 1 ] , j ) , [ [ b [ 0 ] , 5 + i ] ] )
for a , b in cmd_data_ref_other :
cmd_data [ a ] = ( 8 , b , [ [ [ ] , 8 ] ] )
for a , b in cmd_data_conv_in :
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
cmd_data [ a + str ( i ) ] = ( 10 + i , " %s ( %s -bit) " % ( b , j ) , [ [ [ ] , 10 + i ] ] )
for a , b in cmd_data_conv_out :
for i , j in ( 1 , 128 ) , ( 2 , 192 ) , ( 3 , 256 ) :
cmd_data [ a + str ( i ) ] = ( 10 + i , " %s ( %s -bit) " % ( b , j ) , [ [ [ ] , 10 + i ] ] )
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
for k in cfgs . keys ( ) :
cfgs [ k ] [ ' amts ' ] = [ 0 , 0 ]
for idx , mod in ( 0 , 6 ) , ( 1 , 4 ) :
2015-01-09 21:02:16 +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 ( [
2015-04-25 19:39:25 +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 " ) ] ,
[ ' 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 ] ] ,
[ ' tool ' , ( " tool_encrypt " , " tool_decrypt " , " tool_find_incog_data " ) ] ,
[ ' saved_ref1 ' , [ c [ 0 ] + " 1 " for c in cmd_data_ref ] ] ,
[ ' saved_ref2 ' , [ c [ 0 ] + " 2 " for c in cmd_data_ref ] ] ,
[ ' saved_ref3 ' , [ c [ 0 ] + " 3 " for c in cmd_data_ref ] ] ,
[ ' saved_ref_other ' , [ c [ 0 ] for c in cmd_data_ref_other ] ] ,
[ ' saved_ref_conv_in1 ' , [ c [ 0 ] + " 1 " for c in cmd_data_conv_in ] ] ,
[ ' saved_ref_conv_in2 ' , [ c [ 0 ] + " 2 " for c in cmd_data_conv_in ] ] ,
[ ' saved_ref_conv_in3 ' , [ c [ 0 ] + " 3 " for c in cmd_data_conv_in ] ] ,
[ ' saved_ref_conv_out1 ' , [ c [ 0 ] + " 1 " for c in cmd_data_conv_out ] ] ,
[ ' saved_ref_conv_out2 ' , [ c [ 0 ] + " 2 " for c in cmd_data_conv_out ] ] ,
[ ' saved_ref_conv_out3 ' , [ c [ 0 ] + " 3 " for c in cmd_data_conv_out ] ] ,
2015-01-03 00:14:40 +03:00
] )
2015-01-10 18:52:30 +03:00
opts_data = {
2015-01-03 00:14:40 +03:00
' desc ' : " Test suite for the MMGen suite " ,
2015-04-07 17:57:17 +03:00
' usage ' : " [options] [command(s) or metacommand(s)] " ,
2015-01-03 00:14:40 +03:00
' options ' : """
2015-01-12 14:41:17 +03:00
- h , - - help Print this help message
- b , - - buf - keypress Use buffered keypresses as with real human input
- d , - - debug - scripts Turn on debugging output in executed scripts
- 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 tests and commands in the test suite
- p , - - pause Pause between tests , resuming on keypress
- q , - - quiet Produce minimal output . Suppress dependency info
- s , - - system Test scripts and modules installed on system rather than
those in the repo root
- v , - - verbose Produce more verbose output
2015-01-03 00:14:40 +03:00
""" ,
' notes ' : """
If no command is given , the whole suite of tests is run .
"""
}
2015-01-10 18:52:30 +03:00
cmd_args = opt . opts . init ( opts_data )
2015-01-03 00:14:40 +03:00
2015-01-10 18:52:30 +03:00
if opt . system : sys . path . pop ( 0 )
2015-01-03 00:14:40 +03:00
2015-01-12 14:41:17 +03:00
if opt . debug_scripts : os . environ [ " MMGEN_DEBUG " ] = " 1 "
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
2015-01-10 18:52:30 +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 :
def msg ( s ) : sys . stderr . write ( s + " \n " )
def vmsg ( s ) :
2015-01-10 18:52:30 +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 ) :
2015-01-03 00:14:40 +03:00
sys . stderr = open ( " /dev/null " , " a " )
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
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 :
2015-01-09 21:02:16 +03:00
fs = " { :< {w} } - {} "
2015-04-25 19:39:25 +03:00
Msg ( " AVAILABLE COMMANDS: " )
2015-01-03 00:14:40 +03:00
w = max ( [ len ( i ) for i in cmd_data ] )
for cmd in cmd_data :
2015-01-09 21:02:16 +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 ] )
2015-04-25 19:39:25 +03:00
Msg ( " \n AVAILABLE METACOMMANDS: " )
2015-01-03 00:14:40 +03:00
for cmd in meta_cmds :
2015-04-25 19:39:25 +03:00
Msg ( fs . format ( cmd , " " . join ( meta_cmds [ cmd ] ) , w = w ) )
w = max ( [ len ( i ) for i in cmd_groups . keys ( ) ] )
Msg ( " \n AVAILABLE COMMAND GROUPS: " )
for g in cmd_groups . keys ( ) :
Msg ( fs . format ( g , " " . join ( cmd_groups [ g ] ) , w = w ) )
Msg ( " \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 ( )
import pexpect , time , re
2015-01-06 20:10:29 +03:00
from mmgen . util import get_data_from_file , write_to_file , get_lines_from_file
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 :
ls = " " if opt . debug or not s else " "
2015-01-03 00:14:40 +03:00
es = " " if s else " "
msg ( " %s SEND %s %s " % ( ls , es , yellow ( " ' %s ' " % t . replace ( ' \n ' , r ' \ n ' ) ) ) )
return ret
def my_expect ( p , s , t = ' ' , delay = send_delay , regex = False , nonl = False ) :
quo = " ' " if type ( s ) == str else " "
2015-01-10 18:52:30 +03:00
if opt . verbose : msg_r ( " EXPECT %s " % yellow ( quo + str ( s ) + quo ) )
2015-01-03 00:14:40 +03:00
else : msg_r ( " + " )
try :
if s == ' ' : ret = 0
else :
f = p . expect if regex else p . expect_exact
ret = f ( s , timeout = 3 )
except pexpect . TIMEOUT :
errmsg ( red ( " \n ERROR. Expect %s %s %s timed out. Exiting " % ( quo , s , quo ) ) )
sys . exit ( 1 )
2015-01-10 18:52:30 +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 :
errmsg ( " Error. Expect returned %s " % ret )
sys . exit ( 1 )
else :
if t == ' ' :
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-01-03 20:45:01 +03:00
def get_file_with_ext ( ext , mydir , delete = True ) :
2015-01-03 00:14:40 +03:00
2015-01-03 20:45:01 +03:00
flist = [ os . path . join ( mydir , f ) for f in os . listdir ( mydir )
if f == ext or f [ - ( len ( ext ) + 1 ) : ] == " . " + ext ]
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 ]
def get_addrfile_checksum ( display = False ) :
addrfile = get_file_with_ext ( " addrs " , cfg [ ' tmpdir ' ] )
silence ( )
2015-01-06 20:10:29 +03:00
from mmgen . addr import AddrInfo
chk = AddrInfo ( addrfile ) . checksum
2015-01-10 18:52:30 +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 :
errmsg ( red ( " Checksum error: %s " % chk ) )
sys . exit ( 1 )
vmsg ( green ( " Checksums match: %s " ) % ( cyan ( chk ) ) )
2015-01-07 07:41:25 +03:00
2015-01-03 00:14:40 +03:00
class MMGenExpect ( object ) :
2015-04-07 17:57:17 +03:00
def __init__ ( self , name , mmgen_cmd , cmd_args = [ ] , extra_desc = " " ) :
2015-01-10 18:52:30 +03:00
if not opt . system :
2015-01-03 00:14:40 +03:00
mmgen_cmd = os . path . join ( os . curdir , mmgen_cmd )
desc = cmd_data [ name ] [ 1 ]
2015-04-07 17:57:17 +03:00
if extra_desc : desc + = " " + extra_desc
2015-01-10 18:52:30 +03:00
if opt . verbose or opt . exact_output :
2015-01-03 00:14:40 +03:00
sys . stderr . write (
green ( " Testing %s \n Executing " % desc ) +
cyan ( " ' %s %s ' \n " % ( mmgen_cmd , " " . join ( cmd_args ) ) )
)
else :
msg_r ( " Testing %s " % ( desc + " : " ) )
2015-01-10 18:52:30 +03:00
if opt . direct_exec :
os . system ( " " . join ( [ mmgen_cmd ] + cmd_args ) )
sys . exit ( )
else :
self . p = pexpect . spawn ( mmgen_cmd , cmd_args )
if opt . exact_output : self . p . logfile = sys . stdout
2015-01-03 00:14:40 +03:00
def license ( self ) :
p = " ' w ' for conditions and warranty info, or ' c ' to continue: "
my_expect ( self . p , p , ' c ' )
def usr_rand ( self , num_chars ) :
2015-01-09 21:02:16 +03:00
rand_chars = list ( getrandstr ( num_chars , no_space = True ) )
2015-01-03 00:14:40 +03:00
my_expect ( self . p , ' symbols left: ' , ' x ' )
try :
vmsg_r ( " SEND " )
while self . p . expect ( ' left: ' , 0.1 ) == 0 :
ch = rand_chars . pop ( 0 )
2015-01-10 18:52:30 +03:00
msg_r ( yellow ( ch ) + " " if opt . verbose else " + " )
2015-01-03 00:14:40 +03:00
self . p . send ( ch )
except :
vmsg ( " EOT " )
my_expect ( self . p , " ENTER to continue: " , ' \n ' )
2015-04-25 19:39:25 +03:00
def passphrase_new ( self , desc , passphrase ) :
my_expect ( self . p , ( " Enter passphrase for %s : " % desc ) , passphrase + " \n " )
2015-01-03 00:14:40 +03:00
my_expect ( self . p , " Repeat passphrase: " , passphrase + " \n " )
2015-04-25 19:39:25 +03:00
def passphrase ( self , desc , passphrase , pwtype = " " ) :
2015-01-03 20:45:01 +03:00
if pwtype : pwtype + = " "
2015-04-25 19:39:25 +03:00
my_expect ( self . p , ( " Enter %s passphrase for %s .*?: " % ( pwtype , desc ) ) ,
2015-01-03 00:14:40 +03:00
passphrase + " \n " , regex = True )
2015-04-25 19:39:25 +03:00
def hash_preset ( self , desc , preset = ' ' ) :
my_expect ( self . p , ( " Enter hash preset for %s , " % desc ) )
2015-04-01 23:24:34 +03:00
my_expect ( self . p , ( " or hit ENTER .*?: " ) , str ( preset ) + " \n " , regex = True )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +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: "
ret = my_expect ( self . p , s1 if overwrite_unlikely else [ s1 , s2 ] )
if ret == 1 :
my_send ( self . p , " YES \n " )
2015-04-25 19:39:25 +03:00
if oo :
outfile = self . expect_getend ( " Overwriting file ' " ) . rstrip ( " ' " )
return outfile
else :
ret = my_expect ( self . p , s1 )
2015-01-03 00:14:40 +03:00
outfile = self . p . readline ( ) . strip ( ) . strip ( " ' " )
2015-04-25 19:39:25 +03:00
vmsg ( " %s file: %s " % ( desc , cyan ( outfile . replace ( " ' " , " " ) ) ) )
2015-01-03 00:14:40 +03:00
return outfile
def no_overwrite ( self ) :
self . expect ( " Overwrite? Type uppercase ' YES ' to confirm: " , " \n " )
self . expect ( " Exiting at user request " )
def tx_view ( self ) :
2015-01-04 11:14:11 +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 )
end = self . readline ( ) . strip ( )
vmsg ( " ==> %s " % cyan ( end ) )
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 )
def readline ( self ) :
return self . p . readline ( )
2015-04-07 17:57:17 +03:00
def close ( self ) :
return self . p . close ( )
2015-01-07 07:41:25 +03:00
def readlines ( self ) :
return [ l . rstrip ( ) + " \n " for l in self . p . readlines ( ) ]
def read ( self , n = None ) :
2015-01-03 00:14:40 +03:00
return self . p . read ( n )
from mmgen . rpc . data import TransactionInfo
from decimal import Decimal
from mmgen . bitcoin import verify_addr
def add_fake_unspent_entry ( out , address , comment ) :
out . append ( TransactionInfo (
account = unicode ( comment ) ,
2015-01-09 21:02:16 +03:00
vout = int ( getrandnum ( 4 ) % 8 ) ,
2015-01-03 00:14:40 +03:00
txid = unicode ( hexlify ( os . urandom ( 32 ) ) ) ,
2015-01-09 21:02:16 +03:00
amount = Decimal ( " %s . %s " % ( 10 + ( getrandnum ( 4 ) % 40 ) , getrandnum ( 4 ) % 100000000 ) ) ,
2015-01-03 00:14:40 +03:00
address = address ,
spendable = False ,
scriptPubKey = ( " 76a914 " + verify_addr ( address , return_hex = True ) + " 88ac " ) ,
2015-01-09 21:02:16 +03:00
confirmations = getrandnum ( 4 ) % 500
2015-01-03 00:14:40 +03:00
) )
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 = [ ]
for s in tx_data . keys ( ) :
sid = tx_data [ s ] [ ' sid ' ]
2015-01-06 20:10:29 +03:00
a = adata . addrinfo ( sid )
for idx , btcaddr in a . addrpairs ( ) :
add_fake_unspent_entry ( out , btcaddr , " %s : %s Test Wallet " % ( sid , idx ) )
2015-01-03 00:14:40 +03:00
if non_mmgen_input :
from mmgen . bitcoin import privnum2addr , hextowif
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 )
write_to_file ( of , hextowif ( " {:064x} " . format ( privnum ) ,
2015-01-10 18:52:30 +03:00
compressed = True ) + " \n " , " compressed bitcoin key " )
2015-01-03 00:14:40 +03:00
add_fake_unspent_entry ( out , btcaddr , " Non-MMGen address " )
2015-01-06 20:10:29 +03:00
# msg("\n".join([repr(o) for o in out])); sys.exit()
2015-01-10 18:52:30 +03:00
write_to_file ( unspent_data_file , repr ( out ) , " Unspent outputs " , verbose = True )
2015-01-03 00:14:40 +03:00
def add_comments_to_addr_file ( addrfile , tfile ) :
silence ( )
msg ( green ( " Adding comments to address file ' %s ' " % addrfile ) )
2015-01-06 20:10:29 +03:00
from mmgen . addr import AddrInfo
a = AddrInfo ( addrfile )
for i in a . idxs ( ) : a . set_comment ( idx , " Test address %s " % idx )
write_to_file ( tfile , a . fmt_data ( ) , { } )
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
wl = words . split ( " \n " )
2015-01-03 00:14:40 +03:00
nwords , ws_list , max_spaces = 10 , " \n " , 5
def rand_ws_seq ( ) :
2015-01-09 21:02:16 +03:00
nchars = getrandnum ( 1 ) % max_spaces + 1
return " " . join ( [ ws_list [ getrandnum ( 1 ) % len ( ws_list ) ] for i in range ( nchars ) ] )
rand_pairs = [ wl [ getrandnum ( 4 ) % len ( wl ) ] + rand_ws_seq ( ) for i in range ( nwords ) ]
2015-01-03 00:14:40 +03:00
d = " " . join ( rand_pairs ) . rstrip ( ) + " \n "
2015-01-10 18:52:30 +03:00
if opt . verbose : msg_r ( " Brainwallet password: \n %s " % cyan ( d ) )
write_to_file ( fn , d , " brainwallet password " )
2015-01-03 00:14:40 +03:00
def do_between ( ) :
2015-01-10 18:52:30 +03:00
if opt . pause :
2015-01-03 00:14:40 +03:00
from mmgen . util import keypress_confirm
if keypress_confirm ( green ( " Continue? " ) , default_yes = True ) :
2015-01-10 18:52:30 +03:00
if opt . verbose or opt . exact_output : sys . stderr . write ( " \n " )
2015-01-03 00:14:40 +03:00
else :
errmsg ( " Exiting at user request " )
sys . exit ( )
2015-01-10 18:52:30 +03:00
elif opt . verbose or opt . exact_output :
2015-01-03 00:14:40 +03:00
sys . stderr . write ( " \n " )
2015-01-03 20:45:01 +03:00
2015-01-03 00:14:40 +03:00
rebuild_list = OrderedDict ( )
2015-01-09 21:02:16 +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
2015-01-09 21:02:16 +03:00
rerun = True if root else False # 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 )
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 )
if f and os . stat ( f ) . st_mtime > my_age : rerun = True
for cdep in cdeps :
2015-01-09 21:02: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 )
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 :
2015-01-09 21:02:16 +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 :
2015-01-10 18:52:30 +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 :
msg ( " Usage: %s check_deps <command> " % g . prog_name )
sys . exit ( 1 )
cmd = cmds [ 0 ]
if cmd not in cmd_data :
msg ( " ' %s ' : unrecognized command " % cmd )
sys . exit ( 1 )
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 ]
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
def clean ( dirs = [ ] ) :
ts = MMGenTestSuite ( )
dirlist = ts . list_tmp_dirs ( )
if not dirs : dirs = dirlist . keys ( )
2015-01-10 18:52:30 +03:00
for d in sorted ( dirs ) :
if d in dirlist :
2015-01-09 21:02:16 +03:00
cleandir ( dirlist [ d ] )
else :
msg ( " %s : invalid directory number " % d )
sys . exit ( 1 )
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
2015-01-09 21:02:16 +03:00
d = [ ( str ( num ) , ext ) for exts , num in cmd_data [ cmd ] [ 2 ] for ext in exts ]
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
2015-01-09 21:02:16 +03:00
self . __class__ . __dict__ [ cmd ] ( * ( [ self , cmd ] + al ) )
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
2015-01-12 14:41:17 +03:00
def walletgen ( self , name , brain = False , seed_len = None ) :
2015-01-03 00:14:40 +03:00
args = [ " -d " , cfg [ ' tmpdir ' ] , " -p1 " , " -r10 " ]
2015-01-12 14:41:17 +03:00
if seed_len : args + = [ " -l " , str ( seed_len ) ]
2015-01-06 20:10:29 +03:00
# if 'seed_len' in cfg: args += ["-l",cfg['seed_len']]
2015-01-03 00:14:40 +03:00
if brain :
bwf = os . path . join ( cfg [ ' tmpdir ' ] , cfg [ ' bw_filename ' ] )
args + = [ " -b " , cfg [ ' bw_params ' ] , bwf ]
make_brainwallet_file ( bwf )
t = MMGenExpect ( name , " mmgen-walletgen " , args )
t . license ( )
if brain :
t . expect (
" A brainwallet will be secure only if you really know what you ' re doing " )
t . expect ( " Type uppercase ' YES ' to confirm: " , " YES \n " )
t . usr_rand ( 10 )
2015-01-06 20:10:29 +03:00
for s in " user-supplied entropy " , " saved user-supplied entropy " :
t . expect ( " Generating encryption key from OS random data plus %s " % s )
if brain : break
2015-01-03 00:14:40 +03:00
2015-01-09 21:02:16 +03:00
t . passphrase_new ( " new MMGen wallet " , cfg [ ' wpasswd ' ] )
2015-01-03 00:14:40 +03:00
t . written_to_file ( " Wallet " )
2015-01-06 20:10:29 +03:00
ok ( )
def refwalletgen ( self , name ) :
2015-04-07 17:57:17 +03:00
label = " test.py ref. wallet (pw ' %s ' , seed len %s ) " \
% ( ref_wallet_brainpass , cfg [ ' seed_len ' ] )
bw_arg = " -b %s , %s " % ( cfg [ ' seed_len ' ] , ref_wallet_hash_preset )
args = [ " -d " , cfg [ ' tmpdir ' ] , " -p1 " , " -r10 " , bw_arg , " -L " , label ]
d = " ( %s -bit seed) " % cfg [ ' seed_len ' ]
2015-01-06 20:10:29 +03:00
t = MMGenExpect ( name , " mmgen-walletgen " , args )
2015-01-12 22:49:40 +03:00
t . license ( )
t . expect ( " Type uppercase ' YES ' to confirm: " , " YES \n " )
2015-04-07 17:57:17 +03:00
t . expect ( " passphrase: " , ref_wallet_brainpass + " \n " )
2015-01-06 20:10:29 +03:00
t . usr_rand ( 10 )
2015-01-09 21:02:16 +03:00
t . passphrase_new ( " new MMGen wallet " , cfg [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
seed_id = t . written_to_file ( " Wallet " ) . split ( " - " ) [ 0 ] . split ( " / " ) [ - 1 ]
2015-04-25 19:39:25 +03:00
refcheck ( " seed ID " , seed_id , cfg [ ' seed_id ' ] )
2015-04-07 17:57:17 +03:00
2015-04-25 19:39:25 +03:00
refwalletgen1 = refwalletgen2 = refwalletgen3 = refwalletgen
2015-01-03 00:14:40 +03:00
2015-01-03 20:45:01 +03:00
def passchg ( self , name , walletfile ) :
t = MMGenExpect ( name , " mmgen-passchg " ,
[ " -d " , cfg [ ' tmpdir ' ] , " -p " , " 2 " , " -L " , " New Label " , " -r " , " 16 " , walletfile ] )
t . passphrase ( " MMGen wallet " , cfgs [ ' 1 ' ] [ ' wpasswd ' ] , pwtype = " old " )
t . expect_getend ( " Label changed: " )
2015-04-07 17:57:17 +03:00
t . expect_getend ( " Hash preset changed: " )
2015-01-03 20:45:01 +03:00
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] , pwtype = " new " )
t . expect ( " Repeat passphrase: " , cfg [ ' wpasswd ' ] + " \n " )
t . usr_rand ( 16 )
t . expect_getend ( " Key ID changed: " )
t . written_to_file ( " Wallet " )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 20:45:01 +03:00
2015-01-03 00:14:40 +03:00
def walletchk_beg ( self , name , args ) :
t = MMGenExpect ( name , " mmgen-walletchk " , args )
t . expect ( " Getting MMGen wallet data from file ' %s ' " % args [ - 1 ] )
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] )
t . expect ( " Passphrase is OK " )
t . expect ( " Wallet is OK " )
return t
def walletchk ( self , name , walletfile ) :
2015-04-07 17:57:17 +03:00
self . walletchk_beg ( name , [ walletfile ] )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-04-07 17:57:17 +03:00
walletchk_newpass = walletchk
2015-01-06 20:10:29 +03:00
def addrgen ( self , name , walletfile , check_ref = False ) :
2015-01-03 00:14:40 +03:00
t = MMGenExpect ( name , " mmgen-addrgen " , [ " -d " , cfg [ ' tmpdir ' ] , walletfile , cfg [ ' addr_idx_list ' ] ] )
t . license ( )
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] )
t . expect ( " Passphrase is OK " )
2015-01-06 20:10:29 +03:00
t . expect ( " [0-9]+ addresses generated " , regex = True )
chk = t . expect_getend ( r " Checksum for address data .*?: " , regex = True )
if check_ref :
refcheck ( " address data checksum " , chk , cfg [ ' addrfile_chk ' ] )
return
2015-01-03 00:14:40 +03:00
t . written_to_file ( " Addresses " )
2015-01-06 20:10:29 +03:00
ok ( )
def refaddrgen ( self , name , walletfile ) :
2015-04-07 17:57:17 +03:00
d = " ( %s -bit seed) " % cfg [ ' seed_len ' ]
2015-01-06 20:10:29 +03:00
self . addrgen ( name , walletfile , check_ref = True )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
refaddrgen1 = refaddrgen2 = refaddrgen3 = refaddrgen
2015-04-07 17:57:17 +03:00
2015-01-03 00:14:40 +03:00
def addrimport ( self , name , addrfile ) :
outfile = os . path . join ( cfg [ ' tmpdir ' ] , " addrfile_w_comments " )
add_comments_to_addr_file ( addrfile , outfile )
t = MMGenExpect ( name , " mmgen-addrimport " , [ outfile ] )
2015-04-07 17:57:17 +03:00
t . expect_getend ( r " Checksum for address data .* \ [.* \ ]: " , regex = True )
2015-01-03 00:14:40 +03:00
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
def txcreate ( self , name , addrfile ) :
self . txcreate_common ( name , sources = [ ' 1 ' ] )
def txcreate_common ( self , name , sources = [ ' 1 ' ] , non_mmgen_input = ' ' ) :
2015-01-10 18:52:30 +03:00
if opt . verbose or opt . exact_output :
2015-01-03 00:14:40 +03:00
sys . stderr . write ( green ( " Generating fake transaction info \n " ) )
silence ( )
2015-01-06 20:10:29 +03:00
from mmgen . addr import AddrInfo , AddrInfoList
tx_data , ail = { } , AddrInfoList ( )
2015-01-03 00:14:40 +03:00
from mmgen . util import parse_addr_idxs
for s in sources :
afile = get_file_with_ext ( " addrs " , cfgs [ s ] [ " tmpdir " ] )
2015-01-06 20:10:29 +03:00
ai = AddrInfo ( afile )
ail . add ( ai )
2015-01-03 00:14:40 +03:00
aix = parse_addr_idxs ( cfgs [ s ] [ ' addr_idx_list ' ] )
if len ( aix ) != addrs_per_wallet :
2015-04-07 17:57:17 +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 ,
' chk ' : ai . checksum ,
' sid ' : ai . seed_id ,
2015-01-03 00:14:40 +03:00
' addr_idxs ' : aix [ - 2 : ] ,
}
unspent_data_file = os . path . join ( cfg [ ' tmpdir ' ] , " unspent.json " )
2015-01-06 20:10:29 +03:00
create_fake_unspent_data ( ail , unspent_data_file , tx_data , non_mmgen_input )
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
cmd_args = [ " -d " , cfg [ ' tmpdir ' ] ]
for num in tx_data . keys ( ) :
s = tx_data [ num ]
cmd_args + = [
" %s : %s , %s " % ( s [ ' sid ' ] , s [ ' addr_idxs ' ] [ 0 ] , cfgs [ num ] [ ' amts ' ] [ 0 ] ) ,
]
# + one BTC address
# + one change address and one BTC address
if num is tx_data . keys ( ) [ - 1 ] :
cmd_args + = [ " %s : %s " % ( s [ ' sid ' ] , s [ ' addr_idxs ' ] [ 1 ] ) ]
cmd_args + = [ " %s , %s " % ( btcaddr , cfgs [ num ] [ ' amts ' ] [ 1 ] ) ]
for num in tx_data : cmd_args + = [ tx_data [ num ] [ ' addrfile ' ] ]
2015-01-10 18:52:30 +03:00
os . environ [ " MMGEN_BOGUS_WALLET_DATA " ] = unspent_data_file
2015-01-03 00:14:40 +03:00
end_silence ( )
2015-01-10 18:52:30 +03:00
if opt . verbose or opt . exact_output : sys . stderr . write ( " \n " )
2015-01-03 00:14:40 +03:00
2015-01-10 18:52:30 +03:00
t = MMGenExpect ( name , " mmgen-txcreate " , cmd_args )
2015-01-03 00:14:40 +03:00
t . license ( )
for num in tx_data . keys ( ) :
t . expect_getend ( " Getting address data from file " )
2015-04-07 17:57:17 +03:00
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
if t . expect ( [ " Continue anyway? (y/N): " ,
" Unable to connect to bitcoind " ] ) == 0 :
t . send ( " y " )
else :
errmsg ( red ( " Error: unable to connect to bitcoind. Exiting " ) )
sys . exit ( 1 )
for num in tx_data . keys ( ) :
t . expect ( " Continue anyway? (y/N): " , " y " )
t . expect ( r " ' q ' = quit sorting, .*?: " , " M " , regex = True )
t . expect ( r " ' q ' = quit sorting, .*?: " , " q " , regex = True )
outputs_list = [ addrs_per_wallet * i + 1 for i in range ( len ( tx_data ) ) ]
if non_mmgen_input : outputs_list . append ( len ( tx_data ) * addrs_per_wallet + 1 )
t . expect ( " Enter a range or space-separated list of outputs to spend: " ,
" " . join ( [ str ( i ) for i in outputs_list ] ) + " \n " )
if non_mmgen_input : t . expect ( " Accept? (y/N): " , " y " )
t . expect ( " OK? (Y/n): " , " y " )
t . expect ( " Add a comment to transaction? (y/N): " , " \n " )
t . tx_view ( )
2015-01-06 20:10:29 +03:00
t . expect ( " Save transaction? (y/N): " , " y " )
2015-01-03 00:14:40 +03:00
t . written_to_file ( " Transaction " )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-04-07 17:57:17 +03:00
def txsign_end ( self , t , tnum = None ) :
t . expect ( " Signing transaction " )
t . expect ( " Edit transaction comment? (y/N): " , " \n " )
t . expect ( " Save signed transaction? (y/N): " , " y " )
add = " # " + tnum if tnum else " "
t . written_to_file ( " Signed transaction " + add )
def txsign ( self , name , txfile , walletfile , save = True ) :
t = MMGenExpect ( name , " mmgen-txsign " ,
[ " -d " , cfg [ ' tmpdir ' ] , txfile , walletfile ] )
2015-01-03 00:14:40 +03:00
t . license ( )
t . tx_view ( )
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
if save :
self . txsign_end ( t )
else :
t . expect ( " Edit transaction comment? (y/N): " , " \n " )
t . expect ( " Save signed transaction? (y/N): " , " \n " )
t . expect ( " Signed transaction not saved " )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def txsend ( self , name , sigfile ) :
t = MMGenExpect ( name , " mmgen-txsend " , [ " -d " , cfg [ ' tmpdir ' ] , sigfile ] )
t . license ( )
t . tx_view ( )
t . expect ( " Edit transaction comment? (y/N): " , " \n " )
2015-04-07 17:57:17 +03:00
t . expect ( " broadcast this transaction to the network? " )
t . expect ( " ' YES, I REALLY WANT TO DO THIS ' to confirm: " , " \n " )
2015-01-03 00:14:40 +03:00
t . expect ( " Exiting at user request " )
2015-04-07 17:57:17 +03:00
vmsg ( " This is a simulation; no transaction was sent " )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def export_seed ( self , name , walletfile ) :
t = self . walletchk_beg ( name , [ " -s " , " -d " , cfg [ ' tmpdir ' ] , walletfile ] )
f = t . written_to_file ( " Seed data " )
silence ( )
msg ( " Seed data: %s " % cyan ( get_data_from_file ( f , " seed data " ) ) )
end_silence ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def export_mnemonic ( self , name , walletfile ) :
t = self . walletchk_beg ( name , [ " -m " , " -d " , cfg [ ' tmpdir ' ] , walletfile ] )
f = t . written_to_file ( " Mnemonic data " )
silence ( )
msg_r ( " Mnemonic data: %s " % cyan ( get_data_from_file ( f , " mnemonic data " ) ) )
end_silence ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def export_incog ( self , name , walletfile , args = [ " -g " ] ) :
t = MMGenExpect ( name , " mmgen-walletchk " , args + [ " -d " , cfg [ ' tmpdir ' ] , " -r " , " 10 " , walletfile ] )
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] )
t . usr_rand ( 10 )
2015-01-12 00:07:21 +03:00
incog_id = t . expect_getend ( " Incog ID: " )
write_to_tmpfile ( cfg , incog_id_fn , incog_id + " \n " )
2015-01-03 00:14:40 +03:00
if args [ 0 ] == " -G " : return t
t . written_to_file ( " Incognito wallet data " , overwrite_unlikely = True )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def export_incog_hex ( self , name , walletfile ) :
self . export_incog ( name , walletfile , args = [ " -X " ] )
# TODO: make outdir and hidden incog compatible (ignore --outdir and warn user?)
def export_incog_hidden ( self , name , walletfile ) :
rf , rd = os . path . join ( cfg [ ' tmpdir ' ] , hincog_fn ) , os . urandom ( hincog_bytes )
vmsg ( green ( " Writing %s bytes of data to file ' %s ' " % ( hincog_bytes , rf ) ) )
2015-01-10 18:52:30 +03:00
write_to_file ( rf , rd , verbose = opt . verbose )
2015-01-03 00:14:40 +03:00
t = self . export_incog ( name , walletfile , args = [ " -G " , " %s , %s " % ( rf , hincog_offset ) ] )
t . written_to_file ( " Data " , query = " " )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
def addrgen_seed ( self , name , walletfile , foo , desc = " seed data " , arg = " -s " ) :
2015-01-03 00:14:40 +03:00
t = MMGenExpect ( name , " mmgen-addrgen " ,
[ arg , " -d " , cfg [ ' tmpdir ' ] , walletfile , cfg [ ' addr_idx_list ' ] ] )
t . license ( )
2015-04-25 19:39:25 +03:00
t . expect_getend ( " Valid %s for seed ID " % desc )
2015-01-03 00:14:40 +03:00
vmsg ( " Comparing generated checksum with checksum from previous address file " )
chk = t . expect_getend ( r " Checksum for address data .*?: " , regex = True )
verify_checksum_or_exit ( get_addrfile_checksum ( ) , chk )
t . no_overwrite ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def addrgen_mnemonic ( self , name , walletfile , foo ) :
2015-04-25 19:39:25 +03:00
self . addrgen_seed ( name , walletfile , foo , desc = " mnemonic " , arg = " -m " )
2015-01-03 00:14:40 +03:00
def addrgen_incog ( self , name , walletfile , foo , args = [ " -g " ] ) :
t = MMGenExpect ( name , " mmgen-addrgen " , args + [ " -d " ,
cfg [ ' tmpdir ' ] , walletfile , cfg [ ' addr_idx_list ' ] ] )
t . license ( )
t . expect_getend ( " Incog ID: " )
2015-04-25 19:39:25 +03:00
t . passphrase ( " incognito wallet data \ w {8} " , cfg [ ' wpasswd ' ] )
2015-01-03 00:14:40 +03:00
t . hash_preset ( " incog wallet " , ' 1 ' )
vmsg ( " Comparing generated checksum with checksum from address file " )
chk = t . expect_getend ( r " Checksum for address data .*?: " , regex = True )
verify_checksum_or_exit ( get_addrfile_checksum ( ) , chk )
t . no_overwrite ( )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def addrgen_incog_hex ( self , name , walletfile , foo ) :
self . addrgen_incog ( name , walletfile , foo , args = [ " -X " ] )
def addrgen_incog_hidden ( self , name , walletfile , foo ) :
rf = os . path . join ( cfg [ ' tmpdir ' ] , hincog_fn )
self . addrgen_incog ( name , walletfile , foo ,
args = [ " -G " , " %s , %s , %s " % ( rf , hincog_offset , hincog_seedlen ) ] )
2015-01-06 20:10:29 +03:00
def keyaddrgen ( self , name , walletfile , check_ref = False ) :
2015-01-03 00:14:40 +03:00
t = MMGenExpect ( name , " mmgen-keygen " ,
[ " -d " , cfg [ ' tmpdir ' ] , walletfile , cfg [ ' addr_idx_list ' ] ] )
t . license ( )
t . expect ( " Type uppercase ' YES ' to confirm: " , " YES \n " )
t . passphrase ( " MMGen wallet " , cfg [ ' wpasswd ' ] )
2015-01-06 20:10:29 +03:00
chk = t . expect_getend ( r " Checksum for key-address data .*?: " , regex = True )
if check_ref :
refcheck ( " key-address data checksum " , chk , cfg [ ' keyaddrfile_chk ' ] )
return
2015-01-03 00:14:40 +03:00
t . expect ( " Encrypt key list? (y/N): " , " y " )
t . hash_preset ( " new key list " , ' 1 ' )
2015-01-09 21:02:16 +03:00
t . passphrase_new ( " new key list " , cfg [ ' kapasswd ' ] )
2015-01-03 00:14:40 +03:00
t . written_to_file ( " Keys " )
2015-01-06 20:10:29 +03:00
ok ( )
def refkeyaddrgen ( self , name , walletfile ) :
self . keyaddrgen ( name , walletfile , check_ref = True )
2015-01-03 00:14:40 +03:00
2015-04-25 19:39:25 +03:00
refkeyaddrgen1 = refkeyaddrgen2 = refkeyaddrgen3 = refkeyaddrgen
2015-04-07 17:57:17 +03:00
2015-01-03 00:14:40 +03:00
def txsign_keyaddr ( self , name , keyaddr_file , txfile ) :
t = MMGenExpect ( name , " mmgen-txsign " , [ " -d " , cfg [ ' tmpdir ' ] , " -M " , keyaddr_file , txfile ] )
t . license ( )
t . hash_preset ( " key-address file " , ' 1 ' )
t . passphrase ( " key-address file " , cfg [ ' kapasswd ' ] )
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
def walletgen2 ( self , name ) :
2015-01-12 14:41:17 +03:00
self . walletgen ( name , seed_len = 128 )
2015-01-03 00:14:40 +03:00
def addrgen2 ( self , name , walletfile ) :
self . addrgen ( name , walletfile )
def txcreate2 ( self , name , addrfile ) :
self . txcreate_common ( name , sources = [ ' 2 ' ] )
def txsign2 ( self , name , txf1 , wf1 , txf2 , wf2 ) :
t = MMGenExpect ( name , " mmgen-txsign " , [ " -d " , cfg [ ' tmpdir ' ] , txf1 , wf1 , txf2 , wf2 ] )
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 ( )
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
def export_mnemonic2 ( self , name , walletfile ) :
self . export_mnemonic ( name , walletfile )
def walletgen3 ( self , name ) :
self . walletgen ( name )
def addrgen3 ( self , name , walletfile ) :
self . addrgen ( name , walletfile )
def txcreate3 ( self , name , addrfile1 , addrfile2 ) :
self . txcreate_common ( name , sources = [ ' 1 ' , ' 3 ' ] )
def txsign3 ( self , name , wf1 , wf2 , txf2 ) :
t = MMGenExpect ( name , " mmgen-txsign " , [ " -d " , cfg [ ' tmpdir ' ] , wf1 , wf2 , txf2 ] )
t . license ( )
t . tx_view ( )
2015-04-07 17:57:17 +03:00
for cnum in ( ' 1 ' , ' 3 ' ) :
2015-01-03 00:14:40 +03:00
t . expect_getend ( " Getting MMGen wallet data from file " )
2015-04-07 17:57:17 +03:00
t . passphrase ( " MMGen wallet " , cfgs [ cnum ] [ ' wpasswd ' ] )
self . txsign_end ( t )
2015-01-06 20:10:29 +03:00
ok ( )
2015-01-03 00:14:40 +03:00
def walletgen4 ( self , name ) :
self . walletgen ( name , brain = True )
def addrgen4 ( self , name , walletfile ) :
self . addrgen ( name , walletfile )
def txcreate4 ( self , name , f1 , f2 , f3 , f4 ) :
self . txcreate_common ( name , sources = [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' ] , non_mmgen_input = ' 4 ' )
2015-01-03 20:45:01 +03:00
def txsign4 ( self , name , f1 , f2 , f3 , f4 , f5 ) :
non_mm_fn = os . path . join ( cfg [ ' tmpdir ' ] , non_mmgen_fn )
2015-01-03 00:14:40 +03:00
t = MMGenExpect ( name , " mmgen-txsign " ,
[ " -d " , cfg [ ' tmpdir ' ] , " -b " , cfg [ ' bw_params ' ] , " -k " , non_mm_fn , f1 , f2 , f3 , f4 , f5 ] )
t . license ( )
t . tx_view ( )
2015-04-25 19:39:25 +03:00
for cnum , desc , app in ( ' 1 ' , " incognito " , " incognito " ) , ( ' 3 ' , " MMGen " , " MMGen " ) :
t . expect_getend ( " Getting %s wallet data from file " % desc )
t . passphrase ( " %s wallet " % app , cfgs [ cnum ] [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
if cnum == ' 1 ' :
2015-01-03 00:14:40 +03:00
t . hash_preset ( " incog wallet " , ' 1 ' )
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
2015-01-09 21:02:16 +03:00
def tool_encrypt ( self , name , infile = " " ) :
if infile :
infn = infile
else :
d = os . urandom ( 1033 )
tmp_fn = cfg [ ' tool_enc_infn ' ]
write_to_tmpfile ( cfg , tmp_fn , d )
infn = get_tmpfile_fn ( cfg , tmp_fn )
t = MMGenExpect ( name , " mmgen-tool " , [ " -d " , cfg [ ' tmpdir ' ] , " encrypt " , infn ] )
t . hash_preset ( " user data " , ' 1 ' )
2015-04-25 19:39:25 +03:00
t . passphrase_new ( " user data " , tool_enc_passwd )
2015-01-09 21:02:16 +03:00
t . written_to_file ( " Encrypted data " )
ok ( )
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'])
# write_to_file(infn,cfg['tool_enc_reftext'],silent=True)
# self.tool_encrypt(name,infn)
2015-01-09 21:02:16 +03:00
def tool_decrypt ( self , name , f1 , f2 ) :
of = name + " .out "
t = MMGenExpect ( name , " mmgen-tool " ,
[ " -d " , cfg [ ' tmpdir ' ] , " decrypt " , f2 , " outfile= " + of , " hash_preset=1 " ] )
2015-04-25 19:39:25 +03:00
t . passphrase ( " user data " , tool_enc_passwd )
2015-01-09 21:02:16 +03:00
t . written_to_file ( " Decrypted data " )
d1 = read_from_file ( f1 )
d2 = read_from_file ( get_tmpfile_fn ( cfg , of ) )
cmp_or_die ( d1 , d2 )
2015-01-12 00:07:21 +03:00
def tool_find_incog_data ( self , name , f1 , f2 ) :
i_id = read_from_file ( f2 ) . rstrip ( )
vmsg ( " Incog ID: %s " % cyan ( i_id ) )
t = MMGenExpect ( name , " mmgen-tool " ,
[ " -d " , cfg [ ' tmpdir ' ] , " find_incog_data " , f1 , i_id ] )
o = t . expect_getend ( " Incog data for ID \ w {8} found at offset " , regex = True )
cmp_or_die ( hincog_offset , int ( o ) )
2015-04-25 19:39:25 +03:00
def walletconv_out ( self , name , desc , out_fmt = " w " , uopts = [ ] , uopts_chk = [ ] , pw = False ) :
opts = [ " -d " , cfg [ ' tmpdir ' ] , " -r10 " , " -p1 " , " -o " , out_fmt ] + uopts
infile = os . path . join ( ref_dir , cfg [ ' seed_id ' ] + " .mmwords " )
d = " (convert) "
t = MMGenExpect ( name , " mmgen-walletconv " , opts + [ infile ] , extra_desc = d )
t . license ( )
if pw :
t . passphrase_new ( " new " + desc , cfg [ ' wpasswd ' ] )
t . usr_rand ( 10 )
if desc == " hidden incognito data " :
ret = t . expect ( [ " Create? (Y/n): " , " ' YES ' to confirm: " ] , " YES \n " )
if ret == 0 :
t . expect ( " Enter file size: " , " 1234 \n " )
wf = t . written_to_file ( desc [ 0 ] . upper ( ) + desc [ 1 : ] , oo = True )
ok ( )
d = " (check) "
if desc == " hidden incognito data " :
self . keygen_chksum_chk_hincog ( name , cfg [ ' seed_id ' ] , uopts_chk )
# elif pw:
# self.walletchk_chksum_chk(name,wf,cfg['seed_id'],uopts=uopts_chk)
else :
self . keygen_chksum_chk ( name , wf , cfg [ ' seed_id ' ] , pw = pw )
def walletconv_in ( self , name , infile , desc , uopts = [ ] , pw = False , oo = False ) :
opts = [ " -d " , cfg [ ' tmpdir ' ] , " -o " , " words " , " -r10 " ]
if_arg = [ infile ] if infile else [ ]
d = " (convert) "
t = MMGenExpect ( name , " mmgen-walletconv " , opts + uopts + if_arg , extra_desc = d )
t . license ( )
if desc == " brainwallet " :
t . expect ( " Enter brainwallet: " , ref_wallet_brainpass + " \n " )
if pw :
t . passphrase ( desc , cfg [ ' wpasswd ' ] )
if name [ : 19 ] == " ref_hincog_conv_old " :
t . expect ( " Is the seed ID correct? (Y/n): " , " \n " )
else :
t . expect ( [ " Passphrase is OK " , " are correct " ] )
# Output
wf = t . written_to_file ( " Mnemonic data " , oo = oo )
t . close ( )
ok ( )
# back check of result
d = " (check) "
self . keygen_chksum_chk ( name , wf , cfg [ ' seed_id ' ] )
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 ' ] )
self . walletconv_in ( name , wf , " MMGen wallet " , pw = True , oo = True )
def ref_mn_conv ( self , name , ext = " mmwords " , desc = " Mnemonic data " ) :
wf = os . path . join ( ref_dir , cfg [ ' seed_id ' ] + " . " + ext )
self . walletconv_in ( name , wf , desc , oo = True )
def ref_seed_conv ( self , name ) :
self . ref_mn_conv ( name , ext = " mmseed " , desc = " Seed data " )
def ref_brain_conv ( self , name ) :
uopts = [ " -i " , " b " , " -p " , " 1 " , " -l " , str ( cfg [ ' seed_len ' ] ) ]
self . walletconv_in ( name , None , " brainwallet " , uopts , oo = True )
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 ' ] ) ]
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 ) :
self . ref_incog_conv ( name , in_fmt = " xi " , wfk = " ic_wallet_hex " , desc = " hex incognito data " )
def ref_hincog_conv ( self , name , wfk = ' hic_wallet ' , add_uopts = [ ] ) :
ic_f = os . path . join ( ref_dir , cfg [ wfk ] )
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 )
def ref_hincog_conv_old ( self , name ) :
self . ref_hincog_conv ( name , wfk = ' hic_wallet_old ' , add_uopts = [ " -O " ] )
def ref_wallet_conv_out ( self , name ) :
self . walletconv_out ( name , " MMGen wallet " , " w " , pw = True )
def ref_mn_conv_out ( self , name ) :
self . walletconv_out ( name , " mnemonic data " , " mn " )
def ref_seed_conv_out ( self , name ) :
self . walletconv_out ( name , " seed data " , " seed " )
def ref_incog_conv_out ( self , name ) :
self . walletconv_out ( name , " incognito data " , out_fmt = " i " , pw = True )
def ref_incox_conv_out ( self , name ) :
self . walletconv_out ( name , " hex incognito data " , out_fmt = " xi " , pw = True )
def ref_hincog_conv_out ( self , name , extra_uopts = [ ] ) :
ic_f = os . path . join ( cfg [ ' tmpdir ' ] , " rand.data " )
hi_parms = " %s , %s " % ( ic_f , ref_wallet_incog_offset )
hi_parms_legacy = " %s , %s , %s " % ( ic_f , ref_wallet_incog_offset , cfg [ ' seed_len ' ] )
self . walletconv_out ( name ,
" hidden incognito data " , " hi " ,
uopts = [ " -J " , hi_parms ] + extra_uopts ,
uopts_chk = [ " -G " , hi_parms_legacy ] ,
pw = True
)
ref_wallet_conv1 = ref_wallet_conv2 = ref_wallet_conv3 = ref_wallet_conv
ref_mn_conv1 = ref_mn_conv2 = ref_mn_conv3 = ref_mn_conv
ref_seed_conv1 = ref_seed_conv2 = ref_seed_conv3 = ref_seed_conv
ref_brain_conv1 = ref_brain_conv2 = ref_brain_conv3 = ref_brain_conv
ref_incog_conv1 = ref_incog_conv2 = ref_incog_conv3 = ref_incog_conv
ref_incox_conv1 = ref_incox_conv2 = ref_incox_conv3 = ref_incox_conv
ref_hincog_conv1 = ref_hincog_conv2 = ref_hincog_conv3 = ref_hincog_conv
ref_hincog_conv_old1 = ref_hincog_conv_old2 = ref_hincog_conv_old3 = ref_hincog_conv_old
ref_wallet_conv_out1 = ref_wallet_conv_out2 = ref_wallet_conv_out3 = ref_wallet_conv_out
ref_mn_conv_out1 = ref_mn_conv_out2 = ref_mn_conv_out3 = ref_mn_conv_out
ref_seed_conv_out1 = ref_seed_conv_out2 = ref_seed_conv_out3 = ref_seed_conv_out
ref_incog_conv_out1 = ref_incog_conv_out2 = ref_incog_conv_out3 = ref_incog_conv_out
ref_incox_conv_out1 = ref_incox_conv_out2 = ref_incox_conv_out3 = ref_incox_conv_out
ref_hincog_conv_out1 = ref_hincog_conv_out2 = ref_hincog_conv_out3 = ref_hincog_conv_out
2015-04-07 17:57:17 +03:00
def ref_wallet_chk ( self , name ) :
wf = os . path . join ( ref_dir , cfg [ ' ref_wallet ' ] )
self . walletchk ( name , wf )
ref_wallet_chk1 = ref_wallet_chk2 = ref_wallet_chk3 = ref_wallet_chk
def ref_seed_chk ( self , name , ext = g . seed_ext ) :
wf = os . path . join ( ref_dir , " %s . %s " % ( cfg [ ' seed_id ' ] , ext ) )
2015-04-25 19:39:25 +03:00
desc = " seed data " if ext == g . seed_ext else " mnemonic "
self . keygen_chksum_chk ( name , wf , cfg [ ' seed_id ' ] )
2015-04-07 17:57:17 +03:00
ref_seed_chk1 = ref_seed_chk2 = ref_seed_chk3 = ref_seed_chk
def ref_mn_chk ( self , name ) : self . ref_seed_chk ( name , ext = g . mn_ext )
ref_mn_chk1 = ref_mn_chk2 = ref_mn_chk3 = ref_mn_chk
def ref_brain_chk ( self , name , bw_file = ref_bw_file ) :
wf = os . path . join ( ref_dir , bw_file )
arg = " -b %s , %s " % ( cfg [ ' seed_len ' ] , ref_bw_hash_preset )
2015-04-25 19:39:25 +03:00
self . keygen_chksum_chk ( name , wf , cfg [ ' ref_bw_seed_id ' ] , [ arg ] )
def keygen_chksum_chk_hincog ( self , name , seed_id , hincog_parm ) :
t = MMGenExpect ( name , " mmgen-keygen " , [ " -p1 " , " -q " , " -S " , " -A " ] + hincog_parm + [ " 1 " ] , extra_desc = " (check) " )
t . passphrase ( " " , cfg [ ' wpasswd ' ] )
t . expect ( " Encrypt key list? (y/N): " , " \n " )
t . expect ( " any printable ASCII symbol. \r \n " )
chk = t . readline ( ) [ : 8 ]
vmsg ( " Seed ID: %s " % cyan ( chk ) )
cmp_or_die ( seed_id , chk )
def keygen_chksum_chk ( self , name , wf , seed_id , args = [ ] , pw = False ) :
hp_arg = [ " -p1 " ] if pw else [ ]
t = MMGenExpect ( name , " mmgen-keygen " , [ " -q " , " -S " , " -A " ] + args + hp_arg + [ wf , " 1 " ] , extra_desc = " (check) " )
if pw :
t . passphrase ( " " , cfg [ ' wpasswd ' ] )
t . expect ( " Encrypt key list? (y/N): " , " \n " )
t . expect ( " any printable ASCII symbol. \r \n " )
chk = t . readline ( ) [ : 8 ]
vmsg ( " Seed ID: %s " % cyan ( chk ) )
cmp_or_die ( seed_id , chk )
2015-04-07 17:57:17 +03:00
2015-04-25 19:39:25 +03:00
# Use this for encrypted wallets instead of keygen_chksum_chk()
def walletchk_chksum_chk ( self , name , wf , seed_id , uopts = [ ] ) :
t = MMGenExpect ( name , " mmgen-walletchk " , [ " -v " , wf ] + uopts ,
extra_desc = " (check) " )
t . passphrase ( " " , cfg [ ' wpasswd ' ] )
chk = t . expect_getend ( " Seed ID checksum OK ( " ) [ : 8 ]
2015-04-07 17:57:17 +03:00
t . close ( )
cmp_or_die ( seed_id , chk )
ref_brain_chk1 = ref_brain_chk2 = ref_brain_chk3 = ref_brain_chk
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 )
2015-04-25 19:39:25 +03:00
def ref_hincog_chk ( self , name ) :
for wtype , desc , earg in ( ' hic_wallet ' , ' ' , [ ] ) , \
( ' hic_wallet_old ' , ' (old format) ' , [ " -o " ] ) :
2015-04-07 17:57:17 +03:00
ic_arg = " %s , %s , %s " % (
os . path . join ( ref_dir , cfg [ wtype ] ) ,
ref_wallet_incog_offset , cfg [ ' seed_len ' ]
)
t = MMGenExpect ( name , " mmgen-keygen " ,
[ " -q " , " -A " ] + earg + [ " -G " ] + [ ic_arg ] + [ ' 1 ' ] , extra_desc = desc )
2015-04-25 19:39:25 +03:00
t . passphrase ( " incognito wallet " , cfg [ ' wpasswd ' ] )
2015-04-07 17:57:17 +03:00
t . hash_preset ( " incog wallet " , " 1 " )
2015-04-25 19:39:25 +03:00
if wtype == ' hic_wallet_old ' :
2015-04-07 17:57:17 +03:00
t . expect ( " Is the seed ID correct? (Y/n): " , " \n " )
chk = t . expect_getend ( " Valid incog data for seed ID " )
t . close ( )
cmp_or_die ( cfg [ ' seed_id ' ] , chk )
2015-04-25 19:39:25 +03:00
ref_hincog_chk1 = ref_hincog_chk2 = ref_hincog_chk3 = ref_hincog_chk
2015-04-07 17:57:17 +03:00
def ref_addrfile_chk ( self , name , ftype = " addr " ) :
wf = os . path . join ( ref_dir , cfg [ ' ref_ ' + ftype + ' file ' ] )
t = MMGenExpect ( name , " mmgen-tool " , [ ftype + " file_chksum " , wf ] )
if ftype == " keyaddr " :
w = " key-address file "
t . hash_preset ( w , ref_kafile_hash_preset )
t . passphrase ( w , ref_kafile_pass )
t . expect ( " Check key-to-address validity? (y/N): " , " y " )
o = t . expect_getend ( " Checksum for .*address data .*: " , regex = True )
cmp_or_die ( cfg [ ' ref_ ' + ftype + ' file_chksum ' ] , o )
def ref_keyaddrfile_chk ( self , name ) :
self . ref_addrfile_chk ( name , ftype = " keyaddr " )
# 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 ' ] )
self . txsign ( name , tf , wf , save = False )
def ref_tool_decrypt ( self , name ) :
f = os . path . join ( ref_dir , ref_enc_fn )
t = MMGenExpect ( name , " mmgen-tool " ,
[ " -q " , " decrypt " , f , " outfile=- " , " hash_preset=1 " ] )
2015-04-25 19:39:25 +03:00
t . passphrase ( " user data " , tool_enc_passwd )
2015-04-07 17:57:17 +03:00
t . readline ( )
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-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 ( ) )
2015-01-09 21:02:16 +03:00
ts = MMGenTestSuite ( )
for cfg in sorted ( cfgs ) : mk_tmpdir ( cfgs [ cfg ] )
2015-01-07 07:41:25 +03:00
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 ( )
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 )
elif arg in cmd_groups . keys ( ) :
for cmd in cmd_groups [ 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 :
2015-04-07 17:57:17 +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 :
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 ( )
except :
sys . stderr = stderr_save
raise
t = int ( time . time ( ) ) - start_time
2015-01-12 14:41:17 +03:00
sys . stderr . write ( green (
" All requested tests finished OK, elapsed time: %02i : %02i \n "
% ( t / 60 , t % 60 ) ) )