Add g.proto.witness_ver_num, minor fixes and changes
This commit is contained in:
parent
cf20311af5
commit
e9385725cf
12 changed files with 121 additions and 87 deletions
|
|
@ -27,9 +27,8 @@ from mmgen.obj import *
|
|||
|
||||
pnm = g.proj_name
|
||||
|
||||
def sc_dmsg(desc,data):
|
||||
if os.getenv('MMGEN_DEBUG_ADDRLIST'):
|
||||
Msg('sc_debug_{}: {}'.format(desc,data))
|
||||
def dmsg_sc(desc,data):
|
||||
if g.debug_addrlist: Msg('sc_debug_{}: {}'.format(desc,data))
|
||||
|
||||
class AddrGenerator(MMGenObject):
|
||||
def __new__(cls,addr_type):
|
||||
|
|
@ -45,8 +44,7 @@ class AddrGenerator(MMGenObject):
|
|||
'segwit': AddrGeneratorSegwit,
|
||||
'ethereum': AddrGeneratorEthereum,
|
||||
'zcash_z': AddrGeneratorZcashZ,
|
||||
'monero': AddrGeneratorMonero
|
||||
}
|
||||
'monero': AddrGeneratorMonero}
|
||||
assert gen_method in gen_methods
|
||||
me = super(cls,cls).__new__(gen_methods[gen_method])
|
||||
me.desc = gen_methods
|
||||
|
|
@ -59,7 +57,7 @@ class AddrGeneratorP2PKH(AddrGenerator):
|
|||
return CoinAddr(g.proto.pubhash2addr(hash160(pubhex),p2sh=False))
|
||||
|
||||
def to_segwit_redeem_script(self,pubhex):
|
||||
raise NotImplementedError,'Coin/type pair incompatible with Segwit'
|
||||
raise NotImplementedError,'Segwit redeem script not supported by this address type'
|
||||
|
||||
class AddrGeneratorSegwit(AddrGenerator):
|
||||
def to_addr(self,pubhex):
|
||||
|
|
@ -77,7 +75,7 @@ class AddrGeneratorEthereum(AddrGenerator):
|
|||
return CoinAddr(sha3.keccak_256(pubhex[2:].decode('hex')).digest()[12:].encode('hex'))
|
||||
|
||||
def to_segwit_redeem_script(self,pubhex):
|
||||
raise NotImplementedError,'Coin/type pair incompatible with Segwit'
|
||||
raise NotImplementedError,'Segwit redeem script not supported by this address type'
|
||||
|
||||
# github.com/FiloSottile/zcash-mini/zcash/address.go
|
||||
class AddrGeneratorZcashZ(AddrGenerator):
|
||||
|
|
@ -197,7 +195,7 @@ class KeyGenerator(MMGenObject):
|
|||
def test_for_secp256k1(self,silent=False):
|
||||
try:
|
||||
from mmgen.secp256k1 import priv2pub
|
||||
assert priv2pub(os.urandom(32),1)
|
||||
assert priv2pub(('deadbeef'*8).decode('hex'),1)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
|
@ -303,7 +301,7 @@ class AddrListIDStr(unicode,Hilite):
|
|||
bc = (g.proto.base_coin,g.coin)[g.proto.base_coin=='ETH']
|
||||
mt = addrlist.al_id.mmtype
|
||||
ret = '{}{}{}[{}]'.format(addrlist.al_id.sid,('-'+bc,'')[bc=='BTC'],('-'+mt,'')[mt in ('L','E')],s)
|
||||
sc_dmsg('id_str',ret[8:].split('[')[0])
|
||||
dmsg_sc('id_str',ret[8:].split('[')[0])
|
||||
|
||||
return unicode.__new__(cls,ret)
|
||||
|
||||
|
|
@ -397,7 +395,7 @@ Removed %s duplicate WIF key%s from keylist (also in {pnm} key-address file
|
|||
|
||||
seed = seed.get_data()
|
||||
seed = self.scramble_seed(seed)
|
||||
sc_dmsg('seed',seed[:8].encode('hex'))
|
||||
dmsg_sc('seed',seed[:8].encode('hex'))
|
||||
|
||||
compressed = self.al_id.mmtype.compressed
|
||||
pubkey_type = self.al_id.mmtype.pubkey_type
|
||||
|
|
@ -441,7 +439,7 @@ Removed %s duplicate WIF key%s from keylist (also in {pnm} key-address file
|
|||
dmsg('Key {:>03}: {}'.format(pos,e.passwd))
|
||||
|
||||
out.append(e)
|
||||
if g.debug: Msg('generate():\n', e.pformat())
|
||||
if g.debug: Msg('generate():\n{}'.format(e.pformat()))
|
||||
|
||||
qmsg('\r%s: %s %s%s generated%s' % (
|
||||
self.al_id.hl(),t_addrs,self.gen_desc,suf(t_addrs,self.gen_desc_pl),' '*15))
|
||||
|
|
@ -452,13 +450,13 @@ Removed %s duplicate WIF key%s from keylist (also in {pnm} key-address file
|
|||
def scramble_seed(self,seed):
|
||||
is_btcfork = g.proto.base_coin == 'BTC'
|
||||
if is_btcfork and self.al_id.mmtype == 'L':
|
||||
sc_dmsg('str','(none)')
|
||||
dmsg_sc('str','(none)')
|
||||
return seed
|
||||
if g.proto.base_coin == 'ETH':
|
||||
scramble_key = g.coin.lower()
|
||||
else:
|
||||
scramble_key = (g.coin.lower()+':','')[is_btcfork] + self.al_id.mmtype.name
|
||||
sc_dmsg('str',scramble_key)
|
||||
dmsg_sc('str',scramble_key)
|
||||
from mmgen.crypto import scramble_seed
|
||||
return scramble_seed(seed,scramble_key,self.scramble_hash_rounds)
|
||||
|
||||
|
|
@ -559,7 +557,7 @@ Removed %s duplicate WIF key%s from keylist (also in {pnm} key-address file
|
|||
lbl_p2 = ':'.join(l_coin+l_type)
|
||||
lbl = self.al_id.sid + ('',' ')[bool(lbl_p2)] + lbl_p2
|
||||
|
||||
sc_dmsg('lbl',lbl[9:])
|
||||
dmsg_sc('lbl',lbl[9:])
|
||||
out.append(u'{} {{'.format(lbl))
|
||||
|
||||
fs = ' {:<%s} {:<34}{}' % len(str(self.data[-1].idx))
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ def sha256_rounds(s,n):
|
|||
def scramble_seed(seed,scramble_key,hash_rounds):
|
||||
import hmac
|
||||
scr_seed = hmac.new(seed,scramble_key,sha256).digest()
|
||||
fs = 'Seed: {}\nScramble key: {}\nScrambled seed: {}\nScrambled seed len: {}'
|
||||
dmsg(fs.format(hexlify(seed),scramble_key,hexlify(scr_seed),len(scr_seed)))
|
||||
fs = 'Seed: {}\nScramble key: {}\nScrambled seed: {}'
|
||||
dmsg(fs.format(hexlify(seed),scramble_key,hexlify(scr_seed)))
|
||||
return sha256_rounds(scr_seed,hash_rounds)
|
||||
|
||||
def encrypt_seed(seed,key):
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ class g(object):
|
|||
|
||||
coin = 'BTC'
|
||||
debug = False
|
||||
debug_opts = False
|
||||
debug_rpc = False
|
||||
debug_addrlist = False
|
||||
quiet = False
|
||||
no_license = False
|
||||
hold_protect = True
|
||||
|
|
@ -136,6 +139,9 @@ class g(object):
|
|||
env_opts = (
|
||||
'MMGEN_BOGUS_WALLET_DATA',
|
||||
'MMGEN_DEBUG',
|
||||
'MMGEN_DEBUG_OPTS',
|
||||
'MMGEN_DEBUG_RPC',
|
||||
'MMGEN_DEBUG_ADDRLIST',
|
||||
'MMGEN_QUIET',
|
||||
'MMGEN_DISABLE_COLOR',
|
||||
'MMGEN_FORCE_256_COLOR',
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ Cryptocoin address/key operations (compressed public keys supported):
|
|||
privhex2addr - generate coin address from private key in hex format
|
||||
privhex2pubhex - generate a hex public key from a hex private key
|
||||
pubhex2addr - convert a hex pubkey to an address
|
||||
pubhex2redeem_script - convert a hex pubkey to a witness redeem script
|
||||
wif2redeem_script - convert a WIF private key to a witness redeem script
|
||||
wif2segwit_pair - generate both a Segwit redeem script and address from WIF
|
||||
pubhex2redeem_script - convert a hex pubkey to a Segwit P2SH-P2WPKH redeem script
|
||||
wif2redeem_script - convert a WIF private key to a Segwit P2SH-P2WPKH redeem script
|
||||
wif2segwit_pair - generate both a Segwit P2SH-P2WPKH redeem script and address from WIF
|
||||
pubkey2addr - convert coin public key to address
|
||||
randpair - generate a random private key/address pair
|
||||
randwif - generate a random private key in WIF format
|
||||
|
|
|
|||
|
|
@ -383,8 +383,6 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject):
|
|||
return Hilite.fmtc(s,**kwargs)
|
||||
|
||||
def is_for_chain(self,chain):
|
||||
from mmgen.globalvars import g
|
||||
vn = g.proto.get_protocol_by_chain(chain).addr_ver_num
|
||||
|
||||
def pfx_ok(pfx):
|
||||
if type(pfx) == tuple:
|
||||
|
|
@ -392,6 +390,10 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject):
|
|||
elif self[:len(pfx)] == pfx: return True
|
||||
return False
|
||||
|
||||
from mmgen.globalvars import g
|
||||
proto = g.proto.get_protocol_by_chain(chain)
|
||||
vn = proto.addr_ver_num
|
||||
|
||||
if self.addr_fmt == 'p2sh' and 'p2sh2' in vn:
|
||||
return pfx_ok(vn['p2sh'][1]) or pfx_ok(vn['p2sh2'][1])
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ def init(opts_f,add_opts=[],opt_filter=None):
|
|||
uopts,args,short_opts,long_opts,skipped_opts,do_help = \
|
||||
mmgen.share.Opts.parse_opts(sys.argv,opts_data,opt_filter=opt_filter,defer_help=True)
|
||||
|
||||
if g.debug: opt_preproc_debug(short_opts,long_opts,skipped_opts,uopts,args)
|
||||
if g.debug_opts: opt_preproc_debug(short_opts,long_opts,skipped_opts,uopts,args)
|
||||
|
||||
# Save this for usage()
|
||||
global usage_txt
|
||||
|
|
@ -292,6 +292,7 @@ def init(opts_f,add_opts=[],opt_filter=None):
|
|||
|
||||
if g.bob or g.alice:
|
||||
g.testnet = True
|
||||
g.regtest = True
|
||||
g.proto = CoinProtocol(g.coin,g.testnet)
|
||||
g.data_dir = os.path.join(g.data_dir_root,'regtest',g.coin.lower(),('alice','bob')[g.bob])
|
||||
check_or_create_dir(g.data_dir)
|
||||
|
|
@ -309,7 +310,7 @@ def init(opts_f,add_opts=[],opt_filter=None):
|
|||
ymsg("Warning: config file options have changed! See '{}' for details".format(g.cfg_file+'.sample'))
|
||||
my_raw_input('Hit ENTER to continue: ')
|
||||
|
||||
if g.debug: opt_postproc_debug()
|
||||
if g.debug_opts: opt_postproc_debug()
|
||||
|
||||
# We don't need this data anymore
|
||||
del mmgen.share.Opts
|
||||
|
|
|
|||
|
|
@ -83,10 +83,14 @@ class BitcoinProtocol(MMGenObject):
|
|||
(478559,'00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148','bch',False),
|
||||
(None,'','b2x',True)
|
||||
]
|
||||
caps = ('rbf','segwit')
|
||||
mmcaps = ('key','addr','rpc','tx')
|
||||
base_coin = 'BTC'
|
||||
addr_width = 34
|
||||
caps = ('rbf','segwit')
|
||||
mmcaps = ('key','addr','rpc','tx')
|
||||
base_coin = 'BTC'
|
||||
addr_width = 34
|
||||
# From BIP173: witness version 'n' is stored as 'OP_n'. OP_0 is encoded as 0x00,
|
||||
# but OP_1 through OP_16 are encoded as 0x51 though 0x60 (81 to 96 in decimal).
|
||||
witness_vernum_hex = '00'
|
||||
witness_vernum = int(witness_vernum_hex,16)
|
||||
|
||||
@staticmethod
|
||||
def get_protocol_by_chain(chain):
|
||||
|
|
@ -147,7 +151,7 @@ class BitcoinProtocol(MMGenObject):
|
|||
else:
|
||||
if g.debug: Msg('Invalid checksum in address')
|
||||
break
|
||||
if g.debug: Msg("Invalid address '{}'".format(addr))
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
|
|
@ -163,7 +167,7 @@ class BitcoinProtocol(MMGenObject):
|
|||
# https://bitcoincore.org/en/segwit_wallet_dev/
|
||||
# The P2SH redeemScript is always 22 bytes. It starts with a OP_0, followed
|
||||
# by a canonical push of the keyhash (i.e. 0x0014{20-byte keyhash})
|
||||
return '0014' + hash160(pubhex)
|
||||
return cls.witness_vernum_hex + '14' + hash160(pubhex)
|
||||
|
||||
@classmethod
|
||||
def pubhex2segwitaddr(cls,pubhex):
|
||||
|
|
|
|||
17
mmgen/rpc.py
17
mmgen/rpc.py
|
|
@ -25,14 +25,17 @@ import httplib,base64,json
|
|||
from mmgen.common import *
|
||||
from decimal import Decimal
|
||||
|
||||
def dmsg_rpc(s):
|
||||
if g.debug_rpc: msg(s)
|
||||
|
||||
class RPCFailure(Exception): pass
|
||||
|
||||
class CoinDaemonRPCConnection(object):
|
||||
|
||||
def __init__(self,host=None,port=None,user=None,passwd=None,auth_cookie=None):
|
||||
|
||||
dmsg('=== CoinDaemonRPCConnection.__init__() debug ===')
|
||||
dmsg(' host [{}] port [{}] user [{}] passwd [{}] auth_cookie [{}]\n'.format(
|
||||
dmsg_rpc('=== CoinDaemonRPCConnection.__init__() debug ===')
|
||||
dmsg_rpc(' host [{}] port [{}] user [{}] passwd [{}] auth_cookie [{}]\n'.format(
|
||||
host,port,user,passwd,auth_cookie))
|
||||
|
||||
import socket
|
||||
|
|
@ -98,8 +101,8 @@ class CoinDaemonRPCConnection(object):
|
|||
elif cf['on_fail'] == 'die':
|
||||
die(args[1],yellow(s))
|
||||
|
||||
dmsg('=== request() debug ===')
|
||||
dmsg(' RPC POST data ==> %s\n' % p)
|
||||
dmsg_rpc('=== request() debug ===')
|
||||
dmsg_rpc(' RPC POST data ==> %s\n' % p)
|
||||
caller = self
|
||||
class MyJSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
|
|
@ -112,7 +115,7 @@ class CoinDaemonRPCConnection(object):
|
|||
# dump = json.dumps(p,cls=MyJSONEncoder,ensure_ascii=False)
|
||||
# print(dump)
|
||||
|
||||
dmsg(' RPC AUTHORIZATION data ==> raw: [{}]\n{}enc: [Basic {}]\n'.format(
|
||||
dmsg_rpc(' RPC AUTHORIZATION data ==> raw: [{}]\n{}enc: [Basic {}]\n'.format(
|
||||
self.auth_str,' '*31,base64.b64encode(self.auth_str)))
|
||||
try:
|
||||
hc.request('POST', '/', json.dumps(p,cls=MyJSONEncoder), {
|
||||
|
|
@ -129,7 +132,7 @@ class CoinDaemonRPCConnection(object):
|
|||
m = 'Unable to connect to {} at {}:{} (but port is bound?)'
|
||||
return do_fail(None,2,m.format(g.proto.daemon_name,self.host,self.port))
|
||||
|
||||
dmsg(' RPC GETRESPONSE data ==> %s\n' % r.__dict__)
|
||||
dmsg_rpc(' RPC GETRESPONSE data ==> %s\n' % r.__dict__)
|
||||
|
||||
if r.status != 200:
|
||||
if cf['on_fail'] not in ('silent','raise'):
|
||||
|
|
@ -145,7 +148,7 @@ class CoinDaemonRPCConnection(object):
|
|||
|
||||
r2 = r.read()
|
||||
|
||||
dmsg(' RPC REPLY data ==> %s\n' % r2)
|
||||
dmsg_rpc(' RPC REPLY data ==> %s\n' % r2)
|
||||
|
||||
if not r2:
|
||||
return do_fail(r,2,'Error: empty reply')
|
||||
|
|
|
|||
18
mmgen/tx.py
18
mmgen/tx.py
|
|
@ -131,10 +131,12 @@ def bytes2coin_amt(hex_bytes):
|
|||
return g.proto.coin_amt(bytes2int(hex_bytes) * g.proto.coin_amt.min_coin_unit)
|
||||
|
||||
def scriptPubKey2addr(s):
|
||||
if len(s) == 50 and s[:6] == '76a914' and s[-4:] == '88ac': addr_hex,p2sh = s[6:-4],False
|
||||
elif len(s) == 46 and s[:4] == 'a914' and s[-2:] == '87': addr_hex,p2sh = s[4:-2],True
|
||||
else: raise NotImplementedError,'Unknown scriptPubKey'
|
||||
return g.proto.pubhash2addr(addr_hex,p2sh)
|
||||
if len(s) == 50 and s[:6] == '76a914' and s[-4:] == '88ac':
|
||||
return g.proto.pubhash2addr(s[6:-4],p2sh=False)
|
||||
elif len(s) == 46 and s[:4] == 'a914' and s[-2:] == '87':
|
||||
return g.proto.pubhash2addr(s[4:-2],p2sh=True)
|
||||
else:
|
||||
raise NotImplementedError,'Unknown scriptPubKey ({})'.format(s)
|
||||
|
||||
from collections import OrderedDict
|
||||
class DeserializedTX(OrderedDict,MMGenObject): # need to add MMGen types
|
||||
|
|
@ -162,7 +164,7 @@ class DeserializedTX(OrderedDict,MMGenObject): # need to add MMGen types
|
|||
return ret
|
||||
|
||||
d['version'] = bytes2int(hshift(tx,4))
|
||||
has_witness = (False,True)[hexlify(tx[0])=='00']
|
||||
has_witness = tx[0] == '\x00'
|
||||
if has_witness:
|
||||
u = hshift(tx,2,skip=True)[2:]
|
||||
if u != '01':
|
||||
|
|
@ -383,7 +385,7 @@ class MMGenTX(MMGenObject):
|
|||
# serialization, divide the result by 4 and round up to the next integer.
|
||||
|
||||
# TODO: results differ slightly from actual transaction size
|
||||
def estimate_vsize(self):
|
||||
def estimate_size(self):
|
||||
if not self.inputs or not self.outputs: return None
|
||||
|
||||
sig_size = 72 # sig in DER format
|
||||
|
|
@ -439,8 +441,6 @@ class MMGenTX(MMGenObject):
|
|||
# pmsg('estimate_size_old',self.estimate_size_old())
|
||||
return ret
|
||||
|
||||
estimate_size = estimate_vsize
|
||||
|
||||
def get_fee(self):
|
||||
return self.sum_inputs() - self.sum_outputs()
|
||||
|
||||
|
|
@ -609,8 +609,6 @@ class MMGenTX(MMGenObject):
|
|||
|
||||
msg_r('Signing transaction{}...'.format(tx_num_str))
|
||||
wifs = [d.sec.wif for d in keys]
|
||||
# keys.pmsg()
|
||||
# pmsg(wifs)
|
||||
ret = g.rpch.signrawtransaction(self.hex,sig_data,wifs,g.proto.sighash_type,on_fail='return')
|
||||
|
||||
from mmgen.rpc import rpc_error,rpc_errmsg
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ def pformat(d):
|
|||
return pprint.PrettyPrinter(indent=4).pformat(d)
|
||||
def pmsg(*args):
|
||||
if not args: return
|
||||
Msg(pformat(args if len(args) > 1 else args[0]))
|
||||
msg(pformat(args if len(args) > 1 else args[0]))
|
||||
def pdie(*args):
|
||||
if not args: sys.exit(1)
|
||||
Die(1,(pformat(args if len(args) > 1 else args[0])))
|
||||
die(1,(pformat(args if len(args) > 1 else args[0])))
|
||||
|
||||
def set_for_type(val,refval,desc,invert_bool=False,src=None):
|
||||
src_str = (''," in '{}'".format(src))[bool(src)]
|
||||
|
|
|
|||
|
|
@ -235,8 +235,11 @@ class MMGenPexpect(object):
|
|||
self.expect("Overwrite? Type uppercase 'YES' to confirm: ",'\n')
|
||||
self.expect('Exiting at user request')
|
||||
|
||||
def tx_view(self):
|
||||
my_expect(self.p,r'View .*?transaction.*? \(y\)es, \(N\)o, pager \(v\)iew.*?: ','\n',regex=True)
|
||||
def tx_view(self,view=None):
|
||||
repl = { 'terse':'t', 'full':'v' }[view] if view else 'n'
|
||||
my_expect(self.p,r'View .*?transaction.*? \(y\)es, \(N\)o, pager \(v\)iew.*?: ',repl,regex=True)
|
||||
if repl in ('t','v'):
|
||||
my_expect(self.p,r'any key to continue: ','\n')
|
||||
|
||||
def expect_getend(self,s,regex=False):
|
||||
ret = self.expect(s,regex=regex,nonl=True)
|
||||
|
|
|
|||
93
test/test.py
93
test/test.py
|
|
@ -177,8 +177,14 @@ if opt.segwit and 'S' not in g.proto.mmtypes:
|
|||
|
||||
def randbool():
|
||||
return hexlify(os.urandom(1))[1] in '12345678'
|
||||
def get_segwit_val():
|
||||
def get_segwit_bool():
|
||||
return randbool() if opt.segwit_random else True if opt.segwit else False
|
||||
def disable_debug():
|
||||
ds = os.getenv('MMGEN_DEBUG')
|
||||
if ds is not None: os.environ['MMGEN_DEBUG'] = ''
|
||||
return ds
|
||||
def restore_debug(ds):
|
||||
if ds is not None: os.environ['MMGEN_DEBUG'] = ds
|
||||
|
||||
cfgs = {
|
||||
'15': {
|
||||
|
|
@ -194,7 +200,7 @@ cfgs = {
|
|||
'mmseed': 'export_seed_dfl_wallet',
|
||||
'del_dw_run': 'delete_dfl_wallet',
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'16': {
|
||||
'tmpdir': os.path.join('test','tmp16'),
|
||||
|
|
@ -203,7 +209,7 @@ cfgs = {
|
|||
'dep_generators': {
|
||||
pwfile: 'passchg_dfl_wallet',
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'17': { 'tmpdir': os.path.join('test','tmp17') },
|
||||
'18': { 'tmpdir': os.path.join('test','tmp18') },
|
||||
|
|
@ -229,7 +235,7 @@ cfgs = {
|
|||
incog_id_fn: 'export_incog_hidden',
|
||||
'akeys.mmenc': 'keyaddrgen'
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'2': {
|
||||
'tmpdir': os.path.join('test','tmp2'),
|
||||
|
|
@ -243,7 +249,7 @@ cfgs = {
|
|||
'sigtx': 'txsign2',
|
||||
'mmwords': 'export_mnemonic2',
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'3': {
|
||||
'tmpdir': os.path.join('test','tmp3'),
|
||||
|
|
@ -255,7 +261,7 @@ cfgs = {
|
|||
'rawtx': 'txcreate3',
|
||||
'sigtx': 'txsign3'
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'4': {
|
||||
'tmpdir': os.path.join('test','tmp4'),
|
||||
|
|
@ -272,7 +278,7 @@ cfgs = {
|
|||
},
|
||||
'bw_filename': 'brainwallet.mmbrain',
|
||||
'bw_params': '192,1',
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'14': {
|
||||
'kapasswd': 'Maxwell',
|
||||
|
|
@ -285,7 +291,7 @@ cfgs = {
|
|||
'addrs': 'addrgen14',
|
||||
'akeys.mmenc': 'keyaddrgen14',
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'5': {
|
||||
'tmpdir': os.path.join('test','tmp5'),
|
||||
|
|
@ -295,7 +301,7 @@ cfgs = {
|
|||
'mmdat': 'passchg',
|
||||
pwfile: 'passchg',
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'6': {
|
||||
'name': 'reference wallet check (128-bit)',
|
||||
|
|
@ -347,7 +353,7 @@ cfgs = {
|
|||
'addrs': 'refaddrgen1',
|
||||
'akeys.mmenc': 'refkeyaddrgen1'
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'7': {
|
||||
'name': 'reference wallet check (192-bit)',
|
||||
|
|
@ -399,7 +405,7 @@ cfgs = {
|
|||
'addrs': 'refaddrgen2',
|
||||
'akeys.mmenc': 'refkeyaddrgen2'
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'8': {
|
||||
'name': 'reference wallet check (256-bit)',
|
||||
|
|
@ -488,7 +494,7 @@ cfgs = {
|
|||
'addrs': 'refaddrgen3',
|
||||
'akeys.mmenc': 'refkeyaddrgen3'
|
||||
},
|
||||
'segwit': get_segwit_val()
|
||||
'segwit': get_segwit_bool()
|
||||
},
|
||||
'9': {
|
||||
'tmpdir': os.path.join('test','tmp9'),
|
||||
|
|
@ -1013,7 +1019,10 @@ class MMGenExpect(MMGenPexpect):
|
|||
def create_fake_unspent_entry(coinaddr,al_id=None,idx=None,lbl=None,non_mmgen=False,segwit=False):
|
||||
if 'S' not in g.proto.mmtypes: segwit = False
|
||||
if lbl: lbl = ' ' + lbl
|
||||
spk1,spk2 = (('76a914','88ac'),('a914','87'))[segwit and coinaddr.addr_fmt=='p2sh']
|
||||
spk_beg,spk_end = (
|
||||
('76a914','88ac'),
|
||||
('a914','87'),
|
||||
)[segwit and coinaddr.addr_fmt=='p2sh']
|
||||
amt1,amt2 = {'btc':(10,40),'bch':(10,40),'ltc':(1000,4000)}[coin_sel]
|
||||
return {
|
||||
'account': '{}:{}'.format(g.proto.base_coin.lower(),coinaddr) if non_mmgen \
|
||||
|
|
@ -1023,7 +1032,7 @@ def create_fake_unspent_entry(coinaddr,al_id=None,idx=None,lbl=None,non_mmgen=Fa
|
|||
'amount': g.proto.coin_amt('%s.%s' % (amt1+(getrandnum(4) % amt2), getrandnum(4) % 100000000)),
|
||||
'address': coinaddr,
|
||||
'spendable': False,
|
||||
'scriptPubKey': '{}{}{}'.format(spk1,coinaddr.hex,spk2),
|
||||
'scriptPubKey': '{}{}{}'.format(spk_beg,coinaddr.hex,spk_end),
|
||||
'confirmations': getrandnum(4) % 50000
|
||||
}
|
||||
|
||||
|
|
@ -1067,10 +1076,10 @@ def create_fake_unspent_data(adata,tx_data,non_mmgen_input=''):
|
|||
|
||||
if non_mmgen_input:
|
||||
privkey = PrivKey(os.urandom(32),compressed=True,pubkey_type='std')
|
||||
coinaddr = AddrGenerator('p2pkh').to_addr(KeyGenerator('std').to_pubhex(privkey))
|
||||
rand_coinaddr = AddrGenerator('p2pkh').to_addr(KeyGenerator('std').to_pubhex(privkey))
|
||||
of = os.path.join(cfgs[non_mmgen_input]['tmpdir'],non_mmgen_fn)
|
||||
write_data_to_file(of,privkey.wif+'\n','compressed {} key'.format(g.proto.name),silent=True)
|
||||
out.append(create_fake_unspent_entry(coinaddr,non_mmgen=True,segwit=False))
|
||||
out.append(create_fake_unspent_entry(rand_coinaddr,non_mmgen=True,segwit=False))
|
||||
|
||||
# msg('\n'.join([repr(o) for o in out])); sys.exit(0)
|
||||
return out
|
||||
|
|
@ -1108,7 +1117,7 @@ def create_tx_data(sources):
|
|||
def make_txcreate_cmdline(tx_data):
|
||||
privkey = PrivKey(os.urandom(32),compressed=True,pubkey_type='std')
|
||||
t = ('p2pkh','segwit')['S' in g.proto.mmtypes]
|
||||
coinaddr = AddrGenerator(t).to_addr(KeyGenerator('std').to_pubhex(privkey))
|
||||
rand_coinaddr = AddrGenerator(t).to_addr(KeyGenerator('std').to_pubhex(privkey))
|
||||
|
||||
# total of two outputs must be < 10 BTC (<1000 LTC)
|
||||
mods = {'btc':(6,4),'bch':(6,4),'ltc':(600,400)}[coin_sel]
|
||||
|
|
@ -1127,7 +1136,7 @@ def make_txcreate_cmdline(tx_data):
|
|||
# + one change address and one BTC address
|
||||
if num is tx_data.keys()[-1]:
|
||||
cmd_args += ['{}:{}'.format(s['al_id'],s['addr_idxs'][1])]
|
||||
cmd_args += ['{},{}'.format(coinaddr,cfgs[num]['amts'][1])]
|
||||
cmd_args += ['{},{}'.format(rand_coinaddr,cfgs[num]['amts'][1])]
|
||||
|
||||
return cmd_args + [tx_data[num]['addrfile'] for num in tx_data]
|
||||
|
||||
|
|
@ -1441,7 +1450,8 @@ class MMGenTestSuite(object):
|
|||
ok()
|
||||
|
||||
def addrgen(self,name,wf,pf=None,check_ref=False,ftype='addr',id_str=None,extra_args=[],mmtype=None):
|
||||
if cfg['segwit'] and ftype[:4] != 'pass' and not mmtype: mmtype = 'segwit'
|
||||
if ftype[:4] != 'pass' and not mmtype:
|
||||
if cfg['segwit']: mmtype = 'segwit'
|
||||
cmd_pfx = (ftype,'pass')[ftype[:4]=='pass']
|
||||
t = MMGenExpect(name,'mmgen-{}gen'.format(cmd_pfx),
|
||||
['-d',cfg['tmpdir']] +
|
||||
|
|
@ -1455,16 +1465,20 @@ class MMGenTestSuite(object):
|
|||
t.expect('Passphrase is OK')
|
||||
desc = ('address','password')[ftype[:4]=='pass']
|
||||
chk = t.expect_getend(r'Checksum for {} data .*?: '.format(desc),regex=True)
|
||||
if ftype[:4] == 'pass':
|
||||
t.expect('Encrypt password list? (y/N): ','\n')
|
||||
t.written_to_file('Password list',oo=True)
|
||||
else:
|
||||
t.written_to_file('Addresses',oo=True)
|
||||
if check_ref:
|
||||
k = 'passfile32_chk' if ftype == 'pass32' \
|
||||
else 'passfilehex_chk' if ftype == 'passhex' \
|
||||
else 'passfile_chk' if ftype == 'pass' \
|
||||
else '{}file{}_chk'.format(ftype,'_'+mmtype if mmtype else '')
|
||||
chk_ref = cfg[k] if ftype[:4] == 'pass' else cfg[k][fork][g.testnet]
|
||||
refcheck('address data checksum',chk,chk_ref)
|
||||
return
|
||||
t.written_to_file('Addresses',oo=True)
|
||||
t.ok()
|
||||
refcheck('{}list data checksum'.format(ftype),chk,chk_ref)
|
||||
else:
|
||||
t.ok()
|
||||
|
||||
def addrgen_dfl_wallet(self,name,pf=None,check_ref=False):
|
||||
return self.addrgen(name,wf=None,pf=pf,check_ref=check_ref)
|
||||
|
|
@ -1486,7 +1500,7 @@ class MMGenTestSuite(object):
|
|||
vmsg('This is a simulation, so no addresses were actually imported into the tracking\nwallet')
|
||||
t.ok(exit_val=1)
|
||||
|
||||
def txcreate_common(self,name,sources=['1'],non_mmgen_input='',do_label=False,txdo_args=[],add_args=[]):
|
||||
def txcreate_common(self,name,sources=['1'],non_mmgen_input='',do_label=False,txdo_args=[],add_args=[],view=None):
|
||||
if opt.verbose or opt.exact_output:
|
||||
sys.stderr.write(green('Generating fake tracking wallet info\n'))
|
||||
|
||||
|
|
@ -1538,7 +1552,7 @@ class MMGenTestSuite(object):
|
|||
t.expect('Comment: ',ref_tx_label.encode('utf8')+'\n')
|
||||
else:
|
||||
t.expect('Add a comment to transaction? (y/N): ','\n')
|
||||
t.tx_view()
|
||||
t.tx_view(view=view)
|
||||
if txdo_args: return t
|
||||
t.expect('Save transaction? (y/N): ','y')
|
||||
t.written_to_file('Transaction')
|
||||
|
|
@ -1619,7 +1633,7 @@ class MMGenTestSuite(object):
|
|||
t = MMGenExpect(name,'mmgen-txsend', extra_opts + ['-d',cfg['tmpdir'],sigfile])
|
||||
if really_send: os.environ['MMGEN_BOGUS_SEND'] = '1'
|
||||
t.license()
|
||||
t.tx_view()
|
||||
t.tx_view(view='terse')
|
||||
t.expect('Add a comment to transaction? (y/N): ','\n')
|
||||
t.expect('Are you sure you want to broadcast this')
|
||||
m = 'YES, I REALLY WANT TO DO THIS'
|
||||
|
|
@ -1735,7 +1749,8 @@ class MMGenTestSuite(object):
|
|||
args=['-H','%s,%s'%(rf,hincog_offset),'-l',str(hincog_seedlen)])
|
||||
|
||||
def keyaddrgen(self,name,wf,pf=None,check_ref=False,mmtype=None):
|
||||
if cfg['segwit'] and not mmtype: mmtype = 'segwit'
|
||||
if cfg['segwit'] and not mmtype:
|
||||
mmtype = 'segwit'
|
||||
args = ['-d',cfg['tmpdir'],usr_rand_arg,wf,cfg['addr_idx_list']]
|
||||
t = MMGenExpect(name,'mmgen-keygen',
|
||||
([],['--type='+str(mmtype)])[bool(mmtype)] + args,extra_desc=('','(segwit)')[mmtype=='segwit'])
|
||||
|
|
@ -1866,7 +1881,7 @@ class MMGenTestSuite(object):
|
|||
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()
|
||||
t.tx_view(view='terse')
|
||||
|
||||
for cnum,desc in (('1','incognito data'),('3','MMGen wallet')):
|
||||
t.passphrase(('%s' % desc),cfgs[cnum]['wpasswd'])
|
||||
|
|
@ -2134,8 +2149,7 @@ class MMGenTestSuite(object):
|
|||
|
||||
def ref_segwitaddrfile_chk(self,name):
|
||||
if not 'S' in g.proto.mmtypes:
|
||||
msg_r('Skipping {} (not supported)'.format(name))
|
||||
ok()
|
||||
msg_r('Skipping {} (not supported)'.format(name)); ok()
|
||||
else:
|
||||
self.ref_addrfile_chk(name,ftype='segwitaddr')
|
||||
|
||||
|
|
@ -2294,7 +2308,7 @@ class MMGenTestSuite(object):
|
|||
def regtest_user_bal(self,name,user,bal):
|
||||
t = MMGenExpect(name,'mmgen-tool',['--'+user,'listaddresses','showempty=1'])
|
||||
total = t.expect_getend('TOTAL: ')
|
||||
cmp_or_die(total,'{} {}'.format(bal,g.coin))
|
||||
cmp_or_die('{} {}'.format(bal,g.coin),total)
|
||||
|
||||
def regtest_alice_bal1(self,name):
|
||||
return self.regtest_user_bal(name,'alice',rtFundAmt)
|
||||
|
|
@ -2318,11 +2332,11 @@ class MMGenTestSuite(object):
|
|||
t = MMGenExpect(name,'mmgen-regtest',['get_balances'])
|
||||
t.expect('Switching')
|
||||
ret = t.expect_getend("Bob's balance:").strip()
|
||||
cmp_or_die(ret,rtBals[4],skip_ok=True)
|
||||
cmp_or_die(rtBals[4],ret,skip_ok=True)
|
||||
ret = t.expect_getend("Alice's balance:").strip()
|
||||
cmp_or_die(ret,rtBals[5],skip_ok=True)
|
||||
cmp_or_die(rtBals[5],ret,skip_ok=True)
|
||||
ret = t.expect_getend("Total balance:").strip()
|
||||
cmp_or_die(ret,rtBals[6],skip_ok=True)
|
||||
cmp_or_die(rtBals[6],ret,skip_ok=True)
|
||||
t.ok()
|
||||
|
||||
def regtest_user_txdo( self,name,user,fee,
|
||||
|
|
@ -2437,9 +2451,11 @@ class MMGenTestSuite(object):
|
|||
t.ok()
|
||||
|
||||
def regtest_get_mempool(self,name):
|
||||
t = MMGenExpect(name,'mmgen-regtest',['show_mempool'])
|
||||
ds = disable_debug()
|
||||
ret = MMGenExpect(name,'mmgen-regtest',['show_mempool']).read()
|
||||
restore_debug(ds)
|
||||
from ast import literal_eval
|
||||
return literal_eval(t.read())
|
||||
return literal_eval(ret)
|
||||
|
||||
def regtest_get_mempool1(self,name):
|
||||
mp = self.regtest_get_mempool(name)
|
||||
|
|
@ -2461,11 +2477,14 @@ class MMGenTestSuite(object):
|
|||
|
||||
@staticmethod
|
||||
def gen_pairs(n):
|
||||
return [subprocess.check_output(
|
||||
ds = disable_debug()
|
||||
ret = [subprocess.check_output(
|
||||
['python',os.path.join('cmds','mmgen-tool'),'--testnet=1'] +
|
||||
([],['--type=compressed'])[bool((i+1)%2)] +
|
||||
['-r0','randpair']
|
||||
).split() for i in range(n)]
|
||||
restore_debug(ds)
|
||||
return ret
|
||||
|
||||
def regtest_bob_pre_import(self,name):
|
||||
pairs = self.gen_pairs(5)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue