Small changes in opts handling code
This commit is contained in:
parent
9d6c3223a8
commit
4c4377d618
20 changed files with 186 additions and 177 deletions
|
|
@ -90,7 +90,6 @@ def generate_addrs(seed, addrnums):
|
|||
seed = sha512(seed).digest()
|
||||
num += 1 # round
|
||||
|
||||
if opt.debug: print "Seed round %s: %s" % (num, hexlify(seed))
|
||||
if num != addrnums[pos]: continue
|
||||
|
||||
pos += 1
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ def verify_addr(addr,verbose=False,return_hex=False):
|
|||
if step2[:8] == addr_hex[42:]:
|
||||
return addr_hex[2:42] if return_hex else True
|
||||
else:
|
||||
if verbose: print "Invalid checksum in address '%s'" % addr
|
||||
if verbose: Msg("Invalid checksum in address '%s'" % addr)
|
||||
break
|
||||
|
||||
if verbose: print "Invalid address '%s'" % addr
|
||||
if verbose: Msg("Invalid address '%s'" % addr)
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -134,8 +134,8 @@ def _b58_pad(s,a,b,pad,f,w):
|
|||
try:
|
||||
outlen = b[a.index(len(s))]
|
||||
except:
|
||||
print "_b58_pad() accepts only %s %s bytes long "\
|
||||
"(input was %s bytes)" % (w,",".join([str(i) for i in a]),len(s))
|
||||
Msg("_b58_pad() accepts only %s %s bytes long "\
|
||||
"(input was %s bytes)" % (w,",".join([str(i) for i in a]),len(s)))
|
||||
return False
|
||||
|
||||
out = f(s)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ email = "<mmgen-py@yandex.com>"
|
|||
Cdates = '2013-2015'
|
||||
version = '0.7.9'
|
||||
|
||||
required_opts = [ # list must contain "usr_randchars"
|
||||
"quiet","verbose","debug","outdir","echo_passphrase","passwd_file","usr_randchars"
|
||||
]
|
||||
min_screen_width = 80
|
||||
max_tx_comment_len = 72
|
||||
|
||||
|
|
@ -74,9 +77,6 @@ mmenc_ext = "mmenc"
|
|||
default_wl = "electrum"
|
||||
#default_wl = "tirosh"
|
||||
|
||||
# If user opt is set, different global opt is set to 'True'
|
||||
usr_set_vars = { "usr_randchars": "use_urandchars" }
|
||||
|
||||
# Global value sets user opt
|
||||
dfl_vars = "seed_len","hash_preset","usr_randchars","debug"
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ def decrypt_seed(enc_seed, key, seed_id, key_id):
|
|||
# else:
|
||||
# qmsg("Generated IDs (Seed/Key): %s/%s" % (chk2,chk1))
|
||||
|
||||
if opt.debug: print "Decrypted seed: %s" % hexlify(dec_seed)
|
||||
if opt.debug: Msg("Decrypted seed: %s" % hexlify(dec_seed))
|
||||
|
||||
vmsg("OK")
|
||||
return dec_seed
|
||||
|
|
@ -155,11 +155,10 @@ def make_key(passwd,salt,hash_preset,
|
|||
|
||||
if from_what: what += " from "
|
||||
if opt.verbose or verbose:
|
||||
msg_r("Generating %s%s.\nPlease wait..." % (what,from_what))
|
||||
msg_r("Generating %s%s..." % (what,from_what))
|
||||
key = scrypt_hash_passphrase(passwd, salt, hash_preset)
|
||||
if opt.verbose or verbose:
|
||||
msg("done")
|
||||
if opt.debug: print "Key: %s" % hexlify(key)
|
||||
if opt.verbose or verbose: msg("done")
|
||||
if opt.debug: Msg("Key: %s" % hexlify(key))
|
||||
return key
|
||||
|
||||
|
||||
|
|
@ -399,7 +398,7 @@ def _get_seed(infile,silent=False,seed_id=""):
|
|||
msg("Invalid %s file '%s'" % (source,infile))
|
||||
sys.exit(2)
|
||||
|
||||
if opt.debug: print "Seed: %s" % hexlify(seed)
|
||||
if opt.debug: Msg("Seed: %s" % hexlify(seed))
|
||||
|
||||
return seed
|
||||
|
||||
|
|
@ -415,9 +414,9 @@ def get_seed_retry(infile,seed_id=""):
|
|||
|
||||
def _get_seed_from_brain_passphrase(words):
|
||||
bp = " ".join(words)
|
||||
if opt.debug: print "Sanitized brain passphrase: %s" % bp
|
||||
if opt.debug: Msg("Sanitized brain passphrase: %s" % bp)
|
||||
seed_len,hash_preset = get_from_brain_opt_params()
|
||||
if opt.debug: print "Brainwallet l = %s, p = %s" % (seed_len,hash_preset)
|
||||
if opt.debug: Msg("Brainwallet l = %s, p = %s" % (seed_len,hash_preset))
|
||||
vmsg_r("Hashing brainwallet data. Please wait...")
|
||||
# Use buflen arg of scrypt.hash() to get seed of desired length
|
||||
seed = scrypt_hash_passphrase(bp, "", hash_preset, buflen=seed_len/8)
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ cmd_args = opt.opts.init(opts_data,add_opts=["b16"])
|
|||
if opt.show_hash_presets: show_hash_presets()
|
||||
if opt.from_incog_hex or opt.from_incog_hidden: opt.from_incog = True
|
||||
|
||||
if opt.debug: opt.opts.show_opts_and_cmd_args(cmd_args)
|
||||
|
||||
if len(cmd_args) == 1 and (
|
||||
opt.from_mnemonic
|
||||
or opt.from_brain
|
||||
|
|
@ -130,7 +128,7 @@ if len(cmd_args) == 1 and (
|
|||
elif len(cmd_args) == 2:
|
||||
infile,addr_idx_arg = cmd_args
|
||||
check_infile(infile)
|
||||
else: opt.opts.usage(opts_data)
|
||||
else: opt.opts.usage()
|
||||
|
||||
addr_idxs = parse_addr_idxs(addr_idx_arg)
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ command
|
|||
cmd_args = opt.opts.init(opts_data)
|
||||
|
||||
if len(cmd_args) < 1:
|
||||
opt.opts.usage(opts_data)
|
||||
opt.opts.usage()
|
||||
sys.exit(1)
|
||||
|
||||
command = cmd_args.pop(0)
|
||||
|
|
|
|||
|
|
@ -334,8 +334,6 @@ def mmaddr2btcaddr(c,mmaddr,acct_data,ail):
|
|||
|
||||
cmd_args = opt.opts.init(opts_data)
|
||||
|
||||
if opt.debug: show_opts_and_cmd_args(cmd_args)
|
||||
|
||||
if opt.comment_file:
|
||||
comment = get_tx_comment_from_file(opt.comment_file)
|
||||
|
||||
|
|
@ -394,8 +392,6 @@ if not opt.info:
|
|||
msg("Transaction fee too large: %s > %s" % (tx_fee,g.max_tx_fee))
|
||||
sys.exit(2)
|
||||
|
||||
if opt.debug: show_opts_and_cmd_args(cmd_args)
|
||||
|
||||
if g.bogus_wallet_data: # for debugging purposes only
|
||||
import mmgen.rpc.data
|
||||
us = eval(get_data_from_file(g.bogus_wallet_data))
|
||||
|
|
@ -459,8 +455,8 @@ if change > 0: tx_out[change_addr] = float(change)
|
|||
tx_in = [{"txid":i.txid, "vout":i.vout} for i in sel_unspent]
|
||||
|
||||
if opt.debug:
|
||||
print "tx_in:", repr(tx_in)
|
||||
print "tx_out:", repr(tx_out)
|
||||
Msg("tx_in: " + repr(tx_in))
|
||||
Msg("tx_out: " + repr(tx_out))
|
||||
|
||||
if opt.comment_file:
|
||||
if keypress_confirm("Edit comment?",False):
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ cmd_args = opt.opts.init(opts_data)
|
|||
|
||||
if len(cmd_args) == 1:
|
||||
infile = cmd_args[0]; check_infile(infile)
|
||||
else: opt.opts.usage(opts_data)
|
||||
else: opt.opts.usage()
|
||||
|
||||
# Begin execution
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ def sign_transaction(c,tx_hex,tx_num_str,sig_data,keys=None):
|
|||
|
||||
if keys:
|
||||
qmsg("Passing %s key%s to bitcoind" % (len(keys),suf(keys,"k")))
|
||||
if opt.debug: print "Keys:\n %s" % "\n ".join(keys)
|
||||
if opt.debug: Msg("Keys:\n %s" % "\n ".join(keys))
|
||||
|
||||
msg_r("Signing transaction{}...".format(tx_num_str))
|
||||
from mmgen.rpc import exceptions
|
||||
|
|
@ -207,10 +207,10 @@ def check_maps_from_seeds(maplist,label,infiles,saved_seeds,return_keys=False):
|
|||
return ret
|
||||
|
||||
def missing_keys_errormsg(addrs):
|
||||
print """
|
||||
Msg("""
|
||||
A key file must be supplied (or use the '--use-wallet-dat' option)
|
||||
for the following non-{} address{}:\n {}""".format(
|
||||
g.proj_name,suf(addrs,"a"),"\n ".join(addrs)).strip()
|
||||
g.proj_name,suf(addrs,"a"),"\n ".join(addrs)).strip())
|
||||
|
||||
|
||||
def parse_mmgen_keyaddr_file():
|
||||
|
|
@ -287,7 +287,7 @@ for l in (
|
|||
|
||||
if opt.from_incog_hex or opt.from_incog_hidden: opt.from_incog = True
|
||||
|
||||
if not infiles: opt.opts.usage(opts_data)
|
||||
if not infiles: opt.opts.usage()
|
||||
for i in infiles: check_infile(i)
|
||||
|
||||
c = connect_to_bitcoind()
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ def export_to_hidden_incog(incog_enc):
|
|||
outfile,offset = opt.export_incog_hidden.split(",") #Already sanity-checked
|
||||
if opt.outdir: outfile = make_full_path(opt.outdir,outfile)
|
||||
|
||||
if opt.debug:
|
||||
Msg("Incog data len %s, offset %s" % (len(incog_enc),offset))
|
||||
check_data_fits_file_at_offset(outfile,int(offset),len(incog_enc),"write")
|
||||
|
||||
if not opt.quiet: confirm_or_exit("","alter file '%s'" % outfile)
|
||||
|
|
@ -112,7 +114,7 @@ cmd_args = opt.opts.init(opts_data)
|
|||
if opt.export_incog_hidden or opt.export_incog_hex:
|
||||
opt.export_incog = True
|
||||
|
||||
if len(cmd_args) != 1: opt.opts.usage(opts_data)
|
||||
if len(cmd_args) != 1: opt.opts.usage()
|
||||
|
||||
check_infile(cmd_args[0])
|
||||
|
||||
|
|
|
|||
|
|
@ -125,8 +125,6 @@ cmd_args = opt.opts.init(opts_data)
|
|||
|
||||
if opt.show_hash_presets: show_hash_presets()
|
||||
|
||||
if opt.debug: opt.opts.show_opts_and_cmd_args(cmd_args)
|
||||
|
||||
if len(cmd_args) == 1:
|
||||
infile = cmd_args[0]
|
||||
check_infile(infile)
|
||||
|
|
@ -140,7 +138,7 @@ if len(cmd_args) == 1:
|
|||
sys.exit(1)
|
||||
elif len(cmd_args) == 0:
|
||||
infile = ""
|
||||
else: opt.opts.usage(opts_data)
|
||||
else: opt.opts.usage()
|
||||
|
||||
g.use_urandchars = True
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ mnemonic.py: Mnemonic routines for the MMGen suite
|
|||
|
||||
import sys
|
||||
from binascii import hexlify
|
||||
from mmgen.util import msg,msg_r,make_chksum_8,Vmsg
|
||||
from mmgen.util import msg,msg_r,make_chksum_8,Vmsg,Msg
|
||||
from mmgen.crypto import get_random
|
||||
import mmgen.config as g
|
||||
import mmgen.opt as opt
|
||||
|
|
@ -107,24 +107,24 @@ def get_mnemonic_from_seed(seed, wl, label="", verbose=False):
|
|||
|
||||
def check_wordlist(wl,label):
|
||||
|
||||
print "Wordlist: %s" % label.capitalize()
|
||||
Msg("Wordlist: %s" % label.capitalize())
|
||||
|
||||
from hashlib import sha256
|
||||
|
||||
print "Length: %i words" % len(wl)
|
||||
Msg("Length: %i words" % len(wl))
|
||||
new_chksum = sha256(" ".join(wl)).hexdigest()[:8]
|
||||
|
||||
if new_chksum != wl_checksums[label]:
|
||||
print "ERROR: Checksum mismatch. Computed: %s, Saved: %s" % \
|
||||
(new_chksum,wl_checksums[label])
|
||||
Msg("ERROR: Checksum mismatch. Computed: %s, Saved: %s" % \
|
||||
(new_chksum,wl_checksums[label]))
|
||||
sys.exit(3)
|
||||
|
||||
print "Checksum: %s (matches)" % new_chksum
|
||||
Msg("Checksum: %s (matches)" % new_chksum)
|
||||
|
||||
if (sorted(wl) == wl):
|
||||
print "List is sorted"
|
||||
Msg("List is sorted")
|
||||
else:
|
||||
print "ERROR: List is not sorted!"
|
||||
Msg("ERROR: List is not sorted!")
|
||||
sys.exit(3)
|
||||
|
||||
from mmgen.mn_electrum import electrum_words as el
|
||||
|
|
@ -146,4 +146,4 @@ def do_random_mn(nbytes,wordlist):
|
|||
wl = get_wordlist(wlname)
|
||||
mn = get_mnemonic_from_seed(r,wl,wordlist)
|
||||
Vmsg("%s wordlist mnemonic:" % (wlname.capitalize()))
|
||||
print " ".join(mn)
|
||||
Msg(" ".join(mn))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
opt.py: an empty namespace for the global opt variables
|
||||
opt.py: a namespace for the global opt variables
|
||||
"""
|
||||
import opts
|
||||
|
|
|
|||
141
mmgen/opts.py
141
mmgen/opts.py
|
|
@ -17,24 +17,25 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
opts.py: Further options processing after mmgen.share.Opts
|
||||
opts.py: MMGen-specific options processing after general processing by share.Opts
|
||||
"""
|
||||
import sys
|
||||
|
||||
import mmgen.config as g
|
||||
import mmgen.share.Opts
|
||||
import opt
|
||||
from mmgen.util import msg,msgrepr_exit,msgrepr
|
||||
from mmgen.util import msg,msgrepr_exit,msgrepr,Msg
|
||||
|
||||
def usage(opts_data):
|
||||
print "USAGE: %s %s" % (opts_data['prog_name'], opts_data['usage'])
|
||||
def usage():
|
||||
Msg("USAGE: %s %s" % (g.prog_name, usage_txt))
|
||||
sys.exit(2)
|
||||
|
||||
def print_version_info():
|
||||
print """
|
||||
'{g.prog_name}' version {g.version}. Part of the {g.proj_name} suite.
|
||||
Copyright (C) {g.Cdates} by {g.author} {g.email}.
|
||||
""".format(g=g).strip()
|
||||
Msg("""
|
||||
{pnu} version {g.version}. Part of the {g.proj_name} suite, a Bitcoin
|
||||
cold-storage solution for the command line. Copyright (C) {g.Cdates}
|
||||
by {g.author} {g.email}
|
||||
""".format(g=g,pnu=g.prog_name.upper()).strip())
|
||||
|
||||
def warn_incompatible_opts(incompat_list):
|
||||
bad = [k for k in opt.__dict__ if opt.__dict__[k] and k in incompat_list]
|
||||
|
|
@ -43,13 +44,15 @@ def warn_incompatible_opts(incompat_list):
|
|||
["--"+b.replace("_","-") for b in bad]))
|
||||
sys.exit(1)
|
||||
|
||||
def typeconvert_from_dfl(opts,opt):
|
||||
def typeconvert_from_dfl(key):
|
||||
|
||||
vtype = type(g.__dict__[opt])
|
||||
if g.debug: print "Override opt: %-15s [%s]" % (opt,vtype)
|
||||
vtype = type(g.__dict__[key])
|
||||
if g.debug: Msg("Override opt: %-15s [%s]" % (key,vtype))
|
||||
|
||||
global opt
|
||||
|
||||
try:
|
||||
opts[opt] = vtype(opts[opt])
|
||||
opt.__dict__[key] = vtype(opt.__dict__[key])
|
||||
except:
|
||||
d = {
|
||||
'int': 'an integer',
|
||||
|
|
@ -57,9 +60,10 @@ def typeconvert_from_dfl(opts,opt):
|
|||
'float': 'a float',
|
||||
'bool': 'a boolean value',
|
||||
}
|
||||
m = [d[k] for k in d if __builtins__[k] == vtype][0]
|
||||
msg("'%s': invalid parameter for '--%s' option (not %s)" %
|
||||
(opts[opt],opt.replace("_","-"),m))
|
||||
m = [d[k] for k in d if __builtins__[k] == vtype]
|
||||
msgrepr_exit(key,vtype)
|
||||
fs = "'%s': invalid parameter for '--%s' option (not %s)"
|
||||
msg(fs % (opt.__dict__[key],opt.replace("_","-"),m))
|
||||
sys.exit(1)
|
||||
|
||||
def init(opts_data,add_opts=[]):
|
||||
|
|
@ -67,39 +71,55 @@ def init(opts_data,add_opts=[]):
|
|||
if len(sys.argv) == 2 and sys.argv[1] == '--version':
|
||||
print_version_info(); sys.exit()
|
||||
|
||||
opts,args,short_opts,long_opts = mmgen.share.Opts.parse_opts(sys.argv,opts_data)
|
||||
uopts,args,short_opts,long_opts = \
|
||||
mmgen.share.Opts.parse_opts(sys.argv,opts_data)
|
||||
|
||||
if g.debug:
|
||||
print "short opts: %s" % repr(short_opts)
|
||||
print "long opts: %s" % repr(long_opts)
|
||||
print "user-selected opts: %s" % repr(opts)
|
||||
print "cmd args: %s" % repr(args)
|
||||
d = (
|
||||
("short opts", short_opts),
|
||||
("long opts", long_opts),
|
||||
("user-selected opts", uopts),
|
||||
("cmd args", args),
|
||||
)
|
||||
for e in d: Msg("{:<20}: {}".format(*e))
|
||||
|
||||
# check opts without modifying them
|
||||
if not check_opts(opts,long_opts): sys.exit(1)
|
||||
# Save this for usage()
|
||||
global usage_txt
|
||||
usage_txt = opts_data['usage']
|
||||
|
||||
# If user opt is set, an opt in mmgen.config is set to 'True'
|
||||
for v in g.usr_set_vars:
|
||||
if v in opts:
|
||||
g.__dict__[g.usr_set_vars[v]] = True
|
||||
# We don't need this data anymore
|
||||
del mmgen.share.Opts
|
||||
for k in 'prog_name','desc','usage','options','notes':
|
||||
if k in opts_data: del opts_data[k]
|
||||
|
||||
# Remove all unneeded attributes from opt, our special global namespace
|
||||
for k in dir(opt):
|
||||
if k[:2] == "__": del opt.__dict__[k]
|
||||
|
||||
# Transfer uopts into opt, setting required opts to None if not set by user
|
||||
for o in [s.rstrip("=") for s in long_opts] + g.required_opts + add_opts:
|
||||
opt.__dict__[o] = uopts[o] if o in uopts else None
|
||||
|
||||
# check user-set opts without modifying them
|
||||
if not check_opts(uopts): sys.exit(1)
|
||||
|
||||
# A special case - do this here, before opt gets set from g.dfl_vars
|
||||
if opt.usr_randchars: g.use_urandchars = True
|
||||
|
||||
# If user opt is unset, set it to default value in mmgen.config (g):
|
||||
# If set, convert its type based on value in mmgen.config
|
||||
for v in g.dfl_vars:
|
||||
if v in opts: typeconvert_from_dfl(opts,v)
|
||||
else: opts[v] = g.__dict__[v]
|
||||
for k in g.dfl_vars:
|
||||
if k in opt.__dict__ and opt.__dict__[k] != None:
|
||||
typeconvert_from_dfl(k)
|
||||
else: opt.__dict__[k] = g.__dict__[k]
|
||||
|
||||
if g.debug: print "opts after typeconvert: %s" % opts
|
||||
if opt.debug: opt.verbose = True
|
||||
|
||||
# A hack, but harmless
|
||||
extra_opts = [
|
||||
"quiet","verbose","debug",
|
||||
"outdir","echo_passphrase","passwd_file"
|
||||
] + add_opts
|
||||
|
||||
# Transfer opts into our custom namespace
|
||||
for o in [s.rstrip("=") for s in long_opts] + extra_opts:
|
||||
opt.__dict__[o] = opts[o] if o in opts else None
|
||||
if g.debug:
|
||||
Msg("opts after typeconvert:")
|
||||
for k in opt.__dict__:
|
||||
if opt.__dict__[k] != None and k != "opts":
|
||||
msg(" %-18s: %s" % (k,opt.__dict__[k]))
|
||||
|
||||
for l in (
|
||||
('from_incog_hidden','from_incog','from_seed','from_mnemonic','from_brain'),
|
||||
|
|
@ -108,25 +128,17 @@ def init(opts_data,add_opts=[]):
|
|||
('quiet','verbose')
|
||||
): warn_incompatible_opts(l)
|
||||
|
||||
del mmgen.share.Opts
|
||||
return args
|
||||
|
||||
def show_opts_and_cmd_args(cmd_args):
|
||||
print "Processed options:"
|
||||
d = opt.__dict__
|
||||
for k in d:
|
||||
if k[:2] != "__" and k != "opts" and d[k] != None:
|
||||
msg("%-20s: %s" % (k, d[k]))
|
||||
print "Cmd args: %s" % repr(cmd_args)
|
||||
|
||||
# save for debugging
|
||||
def show_all_opts():
|
||||
msg("Processed options:")
|
||||
d = opt.__dict__
|
||||
for k in d:
|
||||
if k[:2] != "__" and k != "opts":
|
||||
msg("%-20s: %s" % (k, d[k]))
|
||||
for k in [o for o in d if o != "opts"]:
|
||||
tstr = type(d[k]) if d[k] not in (None,False,True) else ""
|
||||
msg("%-20s: %-8s %s" % (k, d[k], tstr))
|
||||
|
||||
def check_opts(opts,long_opts): # Returns false if any check fails
|
||||
def check_opts(usr_opts): # Returns false if any check fails
|
||||
|
||||
def opt_splits(val,sep,n,what):
|
||||
sepword = "comma" if sep == "," else (
|
||||
|
|
@ -163,21 +175,22 @@ def check_opts(opts,long_opts): # Returns false if any check fails
|
|||
return False
|
||||
return True
|
||||
|
||||
for opt,val in opts.items():
|
||||
global opt
|
||||
for key,val in [(k,getattr(opt,k)) for k in usr_opts]:
|
||||
|
||||
what = "parameter for '--%s' option" % opt.replace("_","-")
|
||||
what = "parameter for '--%s' option" % key.replace("_","-")
|
||||
|
||||
# Check for file existence and readability
|
||||
if opt in ('keys_from_file','mmgen_keys_from_file',
|
||||
if key in ('keys_from_file','mmgen_keys_from_file',
|
||||
'passwd_file','keysforaddrs','comment_file'):
|
||||
from mmgen.util import check_infile
|
||||
check_infile(val) # exits on error
|
||||
continue
|
||||
|
||||
if opt == 'outdir':
|
||||
if key == 'outdir':
|
||||
from mmgen.util import check_outdir
|
||||
check_outdir(val) # exits on error
|
||||
elif opt == 'label':
|
||||
elif key == 'label':
|
||||
if not opt_compares(len(val),"<=",g.max_wallet_label_len,"label length"):
|
||||
return False
|
||||
try: val.decode("ascii")
|
||||
|
|
@ -187,8 +200,8 @@ def check_opts(opts,long_opts): # Returns false if any check fails
|
|||
w = "character in label"
|
||||
for ch in list(val):
|
||||
if not opt_is_in_list(ch,g.wallet_label_symbols,w): return False
|
||||
elif opt == 'export_incog_hidden' or opt == 'from_incog_hidden':
|
||||
if opt == 'from_incog_hidden':
|
||||
elif key == 'export_incog_hidden' or key == 'from_incog_hidden':
|
||||
if key == 'from_incog_hidden':
|
||||
if not opt_splits(val,",",3,what): return False
|
||||
infile,offset,seed_len = val.split(",")
|
||||
from mmgen.util import check_infile
|
||||
|
|
@ -204,7 +217,7 @@ def check_opts(opts,long_opts): # Returns false if any check fails
|
|||
w = "offset " + what
|
||||
if not opt_is_int(offset,w): return False
|
||||
if not opt_compares(offset,">=",0,what): return False
|
||||
elif opt == 'from_brain':
|
||||
elif key == 'from_brain':
|
||||
if not opt_splits(val,",",2,what): return False
|
||||
l,p = val.split(",")
|
||||
w = "seed length " + what
|
||||
|
|
@ -212,16 +225,16 @@ def check_opts(opts,long_opts): # Returns false if any check fails
|
|||
if not opt_is_in_list(int(l),g.seed_lens,w): return False
|
||||
w = "hash preset " + what
|
||||
if not opt_is_in_list(p,g.hash_presets.keys(),w): return False
|
||||
elif opt == 'seed_len':
|
||||
elif key == 'seed_len':
|
||||
if not opt_is_int(val,what): return False
|
||||
if not opt_is_in_list(int(val),g.seed_lens,what): return False
|
||||
elif opt == 'hash_preset':
|
||||
elif key == 'hash_preset':
|
||||
if not opt_is_in_list(val,g.hash_presets.keys(),what): return False
|
||||
elif opt == 'usr_randchars':
|
||||
elif key == 'usr_randchars':
|
||||
if not opt_is_int(val,what): return False
|
||||
if not opt_compares(val,">=",g.min_urandchars,what): return False
|
||||
if not opt_compares(val,"<=",g.max_urandchars,what): return False
|
||||
else:
|
||||
if 'debug' in opts: print "check_opts(): No test for opt '%s'" % opt
|
||||
if g.debug: Msg("check_opts(): No test for opt '%s'" % key)
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -242,4 +242,4 @@ def do_pager(text):
|
|||
p.communicate(text+end+"\n")
|
||||
msg_r("\r")
|
||||
break
|
||||
else: print text+end
|
||||
else: Msg(text+end)
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ cmd_help = """
|
|||
""".format(pnm=g.proj_name)
|
||||
|
||||
def tool_usage(prog_name, command):
|
||||
print "USAGE: '%s %s%s'" % (prog_name, command,
|
||||
(" "+" ".join(cmd_data[command]) if cmd_data[command] else ""))
|
||||
Msg("USAGE: '%s %s%s'" % (prog_name, command,
|
||||
(" "+" ".join(cmd_data[command]) if cmd_data[command] else "")))
|
||||
|
||||
def process_args(prog_name, command, cmd_args):
|
||||
c_args = [[i.split(" [")[0],i.split(" [")[1][:-1]]
|
||||
|
|
@ -182,15 +182,15 @@ def process_args(prog_name, command, cmd_args):
|
|||
# print c_args; print c_kwargs; print u_args; print u_kwargs; sys.exit()
|
||||
|
||||
if set(u_kwargs) > set(c_kwargs):
|
||||
print "Invalid named argument"
|
||||
Msg("Invalid named argument")
|
||||
sys.exit(1)
|
||||
|
||||
def convert_type(arg,arg_name,arg_type):
|
||||
try:
|
||||
return __builtins__[arg_type](arg)
|
||||
except:
|
||||
print "'%s': Invalid argument for argument %s ('%s' required)" % \
|
||||
(arg, arg_name, arg_type)
|
||||
Msg("'%s': Invalid argument for argument %s ('%s' required)" % \
|
||||
(arg, arg_name, arg_type))
|
||||
sys.exit(1)
|
||||
|
||||
def convert_to_bool_maybe(arg, arg_type):
|
||||
|
|
@ -244,8 +244,8 @@ def usage(cmd):
|
|||
tool_usage(g.prog_name, cmd)
|
||||
|
||||
def hexdump(infile, cols=8, line_nums=True):
|
||||
print pretty_hexdump(get_data_from_file(infile,dash=True,silent=True),
|
||||
cols=cols, line_nums=line_nums)
|
||||
Msg(pretty_hexdump(get_data_from_file(infile,dash=True,silent=True),
|
||||
cols=cols, line_nums=line_nums))
|
||||
|
||||
def unhexdump(infile):
|
||||
sys.stdout.write(decode_pretty_hexdump(
|
||||
|
|
@ -281,7 +281,7 @@ def b58randenc():
|
|||
print_convert_results(r,enc,dec,"str")
|
||||
|
||||
def randhex(nbytes='32'):
|
||||
print ba.hexlify(get_random(int(nbytes)))
|
||||
Msg(ba.hexlify(get_random(int(nbytes))))
|
||||
|
||||
def randwif(compressed=False):
|
||||
r_hex = ba.hexlify(get_random(32))
|
||||
|
|
@ -314,22 +314,22 @@ def mn_rand256(wordlist="electrum"): do_random_mn(32,wordlist)
|
|||
def hex2mn(s,wordlist="electrum"):
|
||||
import mmgen.mnemonic
|
||||
wl = get_wordlist(wordlist)
|
||||
print " ".join(get_mnemonic_from_seed(ba.unhexlify(s), wl, wordlist))
|
||||
Msg(" ".join(get_mnemonic_from_seed(ba.unhexlify(s), wl, wordlist)))
|
||||
|
||||
def mn2hex(s,wordlist="electrum"):
|
||||
import mmgen.mnemonic
|
||||
wl = get_wordlist(wordlist)
|
||||
print ba.hexlify(get_seed_from_mnemonic(s.split(),wl,True))
|
||||
Msg(ba.hexlify(get_seed_from_mnemonic(s.split(),wl,True)))
|
||||
|
||||
def b32tohex(s):
|
||||
b32a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
||||
import mmgen.mnemonic
|
||||
print baseNtohex(32,s,b32a)
|
||||
Msg(baseNtohex(32,s,b32a))
|
||||
|
||||
def hextob32(s):
|
||||
b32a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
||||
import mmgen.mnemonic
|
||||
print "".join(hextobaseN(32,s,b32a))
|
||||
Msg("".join(hextobaseN(32,s,b32a)))
|
||||
|
||||
def mn_stats(wordlist="electrum"):
|
||||
l = get_wordlist(wordlist)
|
||||
|
|
@ -337,11 +337,11 @@ def mn_stats(wordlist="electrum"):
|
|||
|
||||
def mn_printlist(wordlist="electrum"):
|
||||
wl = get_wordlist(wordlist)
|
||||
print "\n".join(wl)
|
||||
Msg("\n".join(wl))
|
||||
|
||||
def id8(infile): print make_chksum_8(get_data_from_file(infile,dash=True,silent=True))
|
||||
def id6(infile): print make_chksum_6(get_data_from_file(infile,dash=True,silent=True))
|
||||
def str2id6(s): print make_chksum_6("".join(s.split()))
|
||||
def id8(infile): Msg(make_chksum_8(get_data_from_file(infile,dash=True,silent=True)))
|
||||
def id6(infile): Msg(make_chksum_6(get_data_from_file(infile,dash=True,silent=True)))
|
||||
def str2id6(s): Msg(make_chksum_6("".join(s.split())))
|
||||
|
||||
# List MMGen addresses and their balances:
|
||||
def listaddresses(minconf=1,showempty=False,pager=False):
|
||||
|
|
@ -391,7 +391,7 @@ def listaddresses(minconf=1,showempty=False,pager=False):
|
|||
|
||||
o = "\n".join(out)
|
||||
if pager: do_pager(o)
|
||||
else: print o
|
||||
else: Msg(o)
|
||||
|
||||
|
||||
def getbalance(minconf=1):
|
||||
|
|
@ -413,10 +413,10 @@ def getbalance(minconf=1):
|
|||
|
||||
fs = "{:12} {:<%s} {:<%s} {:<}" % (16,16)
|
||||
mc,lbl = str(minconf),"confirms"
|
||||
print fs.format("Wallet","Unconfirmed",
|
||||
"<%s %s"%(mc,lbl),">=%s %s"%(mc,lbl))
|
||||
Msg(fs.format("Wallet","Unconfirmed","<%s %s"%(mc,lbl),">=%s %s"%(mc,lbl)))
|
||||
for key in sorted(accts.keys()):
|
||||
print fs.format(key+":", *[str(trim_exponent(a))+" BTC" for a in accts[key]])
|
||||
Msg(fs.format(key+":", *[str(trim_exponent(a))+" BTC"
|
||||
for a in accts[key]]))
|
||||
|
||||
def txview(infile,pager=False,terse=False):
|
||||
c = connect_to_bitcoind()
|
||||
|
|
@ -434,38 +434,38 @@ def keyaddrfile_chksum(infile):
|
|||
AddrInfo(infile,has_keys=True)
|
||||
|
||||
def hexreverse(hex_str):
|
||||
print ba.hexlify(decode_pretty_hexdump(hex_str)[::-1])
|
||||
Msg(ba.hexlify(decode_pretty_hexdump(hex_str)[::-1]))
|
||||
|
||||
def hexlify(s):
|
||||
print ba.hexlify(s)
|
||||
Msg(ba.hexlify(s))
|
||||
|
||||
def sha256x2(s, file_input=False, hex_input=False):
|
||||
from hashlib import sha256
|
||||
if file_input: b = get_data_from_file(s)
|
||||
elif hex_input: b = decode_pretty_hexdump(s)
|
||||
else: b = s
|
||||
print sha256(sha256(b).digest()).hexdigest()
|
||||
Msg(sha256(sha256(b).digest()).hexdigest())
|
||||
|
||||
def hexaddr2addr(hexaddr):
|
||||
print bitcoin.hexaddr2addr(hexaddr)
|
||||
Msg(bitcoin.hexaddr2addr(hexaddr))
|
||||
|
||||
def addr2hexaddr(addr):
|
||||
print bitcoin.verify_addr(addr,return_hex=True)
|
||||
Msg(bitcoin.verify_addr(addr,return_hex=True))
|
||||
|
||||
def pubkey2hexaddr(pubkeyhex):
|
||||
print bitcoin.pubhex2hexaddr(pubkeyhex)
|
||||
Msg(bitcoin.pubhex2hexaddr(pubkeyhex))
|
||||
|
||||
def pubkey2addr(pubkeyhex):
|
||||
print bitcoin.hexaddr2addr(bitcoin.pubhex2hexaddr(pubkeyhex))
|
||||
Msg(bitcoin.hexaddr2addr(bitcoin.pubhex2hexaddr(pubkeyhex)))
|
||||
|
||||
def privhex2addr(privkeyhex,compressed=False):
|
||||
print bitcoin.privnum2addr(int(privkeyhex,16),compressed)
|
||||
Msg(bitcoin.privnum2addr(int(privkeyhex,16),compressed))
|
||||
|
||||
def wif2hex(wif,compressed=False):
|
||||
print bitcoin.wiftohex(wif,compressed)
|
||||
Msg(bitcoin.wiftohex(wif,compressed))
|
||||
|
||||
def hex2wif(hexpriv,compressed=False):
|
||||
print bitcoin.hextowif(hexpriv,compressed)
|
||||
Msg(bitcoin.hextowif(hexpriv,compressed))
|
||||
|
||||
|
||||
def encrypt(infile,outfile="",hash_preset=""):
|
||||
|
|
@ -603,4 +603,4 @@ def rand2file(outfile, nbytes, threads=4, silent=False):
|
|||
q2.join()
|
||||
f.close()
|
||||
|
||||
def bytespec(s): print parse_nbytes(s)
|
||||
def bytespec(s): Msg(parse_nbytes(s))
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ def normalize_btc_amt(amt):
|
|||
return False
|
||||
|
||||
if opt.debug:
|
||||
print "Decimal(amt): %s\nAs tuple: %s" % (amt,repr(ret.as_tuple()))
|
||||
Msg("Decimal(amt): %s\nAs tuple: %s" % (amt,repr(ret.as_tuple())))
|
||||
|
||||
if ret.as_tuple()[-1] < -8:
|
||||
msg("%s: Too many decimal places in amount" % amt)
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ def compare_checksums(chksum1, desc1, chksum2, desc2):
|
|||
return True
|
||||
else:
|
||||
if opt.debug:
|
||||
print \
|
||||
"ERROR!\nComputed checksum %s (%s) doesn't match checksum %s (%s)" \
|
||||
% (desc1,chksum1,desc2,chksum2)
|
||||
Msg(
|
||||
"ERROR: Computed checksum %s (%s) doesn't match checksum %s (%s)"
|
||||
% (desc1,chksum1,desc2,chksum2))
|
||||
return False
|
||||
|
||||
def get_default_wordlist():
|
||||
|
|
@ -289,7 +289,7 @@ def get_new_passphrase(what, passchg=False):
|
|||
for i in range(g.passwd_max_tries):
|
||||
pw = " ".join(_get_words_from_user("Enter {}: ".format(w)))
|
||||
pw2 = " ".join(_get_words_from_user("Repeat passphrase: "))
|
||||
if opt.debug: print "Passphrases: [%s] [%s]" % (pw,pw2)
|
||||
if opt.debug: Msg("Passphrases: [%s] [%s]" % (pw,pw2))
|
||||
if pw == pw2:
|
||||
vmsg("Passphrases match"); break
|
||||
else: msg("Passphrases do not match. Try again.")
|
||||
|
|
@ -378,7 +378,7 @@ def write_to_file_or_stdout(outfile, data, what="data"):
|
|||
from mmgen.bitcoin import b58decode_pad,b58encode_pad
|
||||
|
||||
def display_control_data(label,metadata,hash_preset,salt,enc_seed):
|
||||
print "WALLET DATA"
|
||||
Msg("WALLET DATA")
|
||||
fs = " {:18} {}"
|
||||
pw_empty = "yes" if metadata[3] == "E" else "no"
|
||||
for i in (
|
||||
|
|
@ -391,7 +391,7 @@ def display_control_data(label,metadata,hash_preset,salt,enc_seed):
|
|||
" ".join([str(i) for i in get_hash_params(hash_preset)]))),
|
||||
("Passphrase empty?", pw_empty.capitalize()),
|
||||
("Timestamp:", "%s UTC" % metadata[4]),
|
||||
): print fs.format(*i)
|
||||
): Msg(fs.format(*i))
|
||||
|
||||
fs = " {:6} {}"
|
||||
for i in (
|
||||
|
|
@ -401,7 +401,7 @@ def display_control_data(label,metadata,hash_preset,salt,enc_seed):
|
|||
("Encrypted seed:", ""),
|
||||
(" b58:", b58encode_pad(enc_seed)),
|
||||
(" hex:", hexlify(enc_seed))
|
||||
): print fs.format(*i)
|
||||
): Msg(fs.format(*i))
|
||||
|
||||
|
||||
def write_wallet_to_file(seed, passwd, key_id, salt, enc_seed):
|
||||
|
|
@ -480,7 +480,7 @@ def _check_chksum_6(chk,val,desc,infile):
|
|||
msg("Checksum: %s. Computed value: %s" % (chk,comp_chk))
|
||||
sys.exit(2)
|
||||
elif opt.debug:
|
||||
print "%s checksum passed: %s" % (desc.capitalize(),chk)
|
||||
Msg("%s checksum passed: %s" % (desc.capitalize(),chk))
|
||||
|
||||
|
||||
def get_data_from_wallet(infile,silent=False):
|
||||
|
|
@ -530,7 +530,7 @@ def get_data_from_wallet(infile,silent=False):
|
|||
def _get_words_from_user(prompt):
|
||||
# split() also strips
|
||||
words = my_raw_input(prompt, echo=opt.echo_passphrase).split()
|
||||
if opt.debug: print "Sanitized input: [%s]" % " ".join(words)
|
||||
if opt.debug: Msg("Sanitized input: [%s]" % " ".join(words))
|
||||
return words
|
||||
|
||||
|
||||
|
|
@ -540,7 +540,7 @@ def _get_words_from_file(infile,what):
|
|||
# split() also strips
|
||||
words = f.read().split()
|
||||
f.close()
|
||||
if opt.debug: print "Sanitized input: [%s]" % " ".join(words)
|
||||
if opt.debug: Msg("Sanitized input: [%s]" % " ".join(words))
|
||||
return words
|
||||
|
||||
|
||||
|
|
|
|||
40
test/test.py
40
test/test.py
|
|
@ -155,8 +155,8 @@ cmd_data = OrderedDict([
|
|||
['keyaddrgen', (1,'key-address file generation', [[["mmdat"],1]])],
|
||||
['txsign_keyaddr',(1,'transaction signing with key-address file', [[["akeys.mmenc","raw"],1]])],
|
||||
|
||||
['walletgen2',(2,'wallet generation (2)', [])],
|
||||
# ['walletgen2',(2,'wallet generation (2), 128-bit seed (WIP)', [])],
|
||||
# ['walletgen2',(2,'wallet generation (2)', [])],
|
||||
['walletgen2',(2,'wallet generation (2), 128-bit seed', [])],
|
||||
['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]])],
|
||||
|
|
@ -215,18 +215,18 @@ opts_data = {
|
|||
'desc': "Test suite for the MMGen suite",
|
||||
'usage':"[options] [command or metacommand]",
|
||||
'options': """
|
||||
-h, --help Print this help message
|
||||
-b, --buf-keypress Use buffered keypresses as with real human input
|
||||
-d, --debug Produce debugging output
|
||||
-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
|
||||
-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
|
||||
""",
|
||||
'notes': """
|
||||
|
||||
|
|
@ -238,6 +238,8 @@ cmd_args = opt.opts.init(opts_data)
|
|||
|
||||
if opt.system: sys.path.pop(0)
|
||||
|
||||
if opt.debug_scripts: os.environ["MMGEN_DEBUG"] = "1"
|
||||
|
||||
if opt.buf_keypress:
|
||||
send_delay = 0.3
|
||||
else:
|
||||
|
|
@ -651,9 +653,10 @@ class MMGenTestSuite(object):
|
|||
def generate_cmd_deps(self,fdeps):
|
||||
return [cfgs[str(n)]['dep_generators'][ext] for n,ext in fdeps]
|
||||
|
||||
def walletgen(self,name,brain=False):
|
||||
def walletgen(self,name,brain=False,seed_len=None):
|
||||
|
||||
args = ["-d",cfg['tmpdir'],"-p1","-r10"]
|
||||
if seed_len: args += ["-l",str(seed_len)]
|
||||
# if 'seed_len' in cfg: args += ["-l",cfg['seed_len']]
|
||||
if brain:
|
||||
bwf = os.path.join(cfg['tmpdir'],cfg['bw_filename'])
|
||||
|
|
@ -951,7 +954,7 @@ class MMGenTestSuite(object):
|
|||
ok()
|
||||
|
||||
def walletgen2(self,name):
|
||||
self.walletgen(name)
|
||||
self.walletgen(name,seed_len=128)
|
||||
|
||||
def addrgen2(self,name,walletfile):
|
||||
self.addrgen(name,walletfile)
|
||||
|
|
@ -1111,5 +1114,6 @@ except:
|
|||
raise
|
||||
|
||||
t = int(time.time()) - start_time
|
||||
msg(green(
|
||||
"All requested tests finished OK, elapsed time: %02i:%02i" % (t/60,t%60)))
|
||||
sys.stderr.write(green(
|
||||
"All requested tests finished OK, elapsed time: %02i:%02i\n"
|
||||
% (t/60,t%60)))
|
||||
|
|
|
|||
|
|
@ -78,12 +78,12 @@ opts_data = {
|
|||
'desc': "Test suite for the 'mmgen-tool' utility",
|
||||
'usage':"[options] [command]",
|
||||
'options': """
|
||||
-h, --help Print this help message
|
||||
-d, --debug Produce debugging output
|
||||
-l, --list-cmds List and describe the tests and commands in the test suite
|
||||
-s, --system Test scripts and modules installed on system rather than
|
||||
those in the repo root
|
||||
-v, --verbose Produce more verbose output
|
||||
-h, --help Print this help message
|
||||
-d, --debug-scripts Turn on debugging output in executed scripts
|
||||
-l, --list-cmds List and describe the tests and commands in the test suite
|
||||
-s, --system Test scripts and modules installed on system rather than
|
||||
those in the repo root
|
||||
-v, --verbose Produce more verbose output
|
||||
""",
|
||||
'notes': """
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ cmd_args = opt.opts.init(opts_data,add_opts=["exact_output"])
|
|||
|
||||
if opt.system: sys.path.pop(0)
|
||||
|
||||
env = os.environ
|
||||
if opt.debug_scripts: os.environ["MMGEN_DEBUG"] = "1"
|
||||
|
||||
if opt.debug: opt.verbose = True
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue