diff --git a/MANIFEST b/MANIFEST index e3fe6d56..2255fca7 100644 --- a/MANIFEST +++ b/MANIFEST @@ -11,7 +11,6 @@ mmgen-txsign mmgen-walletchk mmgen-walletgen setup.py -mmgen/Opts.py mmgen/__init__.py mmgen/addr.py mmgen/bitcoin.py @@ -32,13 +31,13 @@ mmgen/main_walletgen.py mmgen/mn_electrum.py mmgen/mn_tirosh.py mmgen/mnemonic.py +mmgen/opt.py +mmgen/opts.py mmgen/term.py mmgen/test.py mmgen/tool.py mmgen/tx.py mmgen/util.py -mmgen/opt/Opts.py -mmgen/opt/__init__.py mmgen/rpc/__init__.py mmgen/rpc/config.py mmgen/rpc/connection.py @@ -46,6 +45,9 @@ mmgen/rpc/data.py mmgen/rpc/exceptions.py mmgen/rpc/proxy.py mmgen/rpc/util.py +mmgen/share/Opts.py +mmgen/share/__init__.py test/__init__.py +test/gentest.py test/test.py test/tooltest.py diff --git a/mmgen/addr.py b/mmgen/addr.py index ac33f5b7..b0a2e092 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -208,8 +208,10 @@ def _parse_keyaddr_file(infile): class AddrInfoList(object): - def __init__(self,addrinfo=None): + def __init__(self,addrinfo=None,bitcoind_connection=None): self.data = {} + if bitcoind_connection: + self.add_wallet_data(bitcoind_connection) def seed_ids(self): return self.data.keys() @@ -219,6 +221,28 @@ class AddrInfoList(object): if sid in self.data: return self.data[sid] + def add_wallet_data(self,c): + vmsg_r("Getting account data from wallet...") + data,accts,i = {},c.listaccounts(minconf=0,includeWatchonly=True),0 + for acct in accts: + ma,comment = parse_mmgen_label(acct) + if ma: + i += 1 + addrlist = c.getaddressesbyaccount(acct) + if len(addrlist) != 1: + msg(wmsg['too_many_acct_addresses'] % acct) + sys.exit(2) + seed_id,idx = ma.split(":") + if seed_id not in data: + data[seed_id] = [] + a = AddrInfoEntry() + a.idx,a.addr,a.comment = \ + int(idx),unicode(addrlist[0]),unicode(comment) + data[seed_id].append(a) + vmsg("%s %s addresses found, %s accounts total" % (i,g.proj_name,len(accts))) + for sid in data: + self.add(AddrInfo(sid=sid,adata=data[sid])) + def add(self,addrinfo): if type(addrinfo) == AddrInfo: self.data[addrinfo.seed_id] = addrinfo @@ -235,17 +259,23 @@ class AddrInfoList(object): class AddrInfoEntry(object): - def __init__(self): - pass + def __init__(self): pass class AddrInfo(object): - def __init__(self,addrfile="",has_keys=False): + def __init__(self,addrfile="",has_keys=False,sid="",adata=[]): self.has_keys=has_keys if addrfile: f = _parse_keyaddr_file if has_keys else _parse_addrfile sid,adata = f(addrfile) - self.initialize(sid,adata) + elif sid and adata: # data from wallet + pass + elif sid or adata: + die(3,"Must specify address file, or seed_id + adata") + else: + return + + self.initialize(sid,adata) def initialize(self,seed_id,addrdata): if seed_id in self.__dict__: @@ -297,11 +327,10 @@ class AddrInfo(object): sys.exit(2) def make_reverse_dict(self,btcaddrs): - d = {} + d,b = {},btcaddrs for e in self.addrdata: try: - i = btcaddrs.index(e.addr) - d[btcaddrs[i]] = ("%s:%s"%(self.seed_id,e.idx),e.comment) + d[b[b.index(e.addr)]] = ("%s:%s"%(self.seed_id,e.idx),e.comment) except: pass return d diff --git a/mmgen/main_txcreate.py b/mmgen/main_txcreate.py index 84906723..a0d4d27e 100755 --- a/mmgen/main_txcreate.py +++ b/mmgen/main_txcreate.py @@ -277,24 +277,6 @@ def select_outputs(unspent,prompt): return selected -def get_acct_data_from_wallet(c,acct_data): - # acct_data is global object initialized by caller - vmsg_r("Getting account data from wallet...") - accts,i = c.listaccounts(minconf=0,includeWatchonly=True),0 - for acct in accts: - ma,comment = parse_mmgen_label(acct) - if ma: - i += 1 - addrlist = c.getaddressesbyaccount(acct) - if len(addrlist) != 1: - msg(wmsg['too_many_acct_addresses'] % acct) - sys.exit(2) - seed_id,idx = ma.split(":") - if seed_id not in acct_data: - acct_data[seed_id] = {} - acct_data[seed_id][idx] = (addrlist[0],comment) - vmsg("%s %s addresses found, %s accounts total" % (i,g.proj_name,len(accts))) - def mmaddr2btcaddr_unspent(unspent,mmaddr): vmsg_r("Searching for {g.proj_name} address {m} in wallet...".format(g=g,m=mmaddr)) m = [u for u in unspent if u.mmid == mmaddr] @@ -309,15 +291,17 @@ def mmaddr2btcaddr_unspent(unspent,mmaddr): sys.exit() -def mmaddr2btcaddr(c,mmaddr,acct_data,ail): +def mmaddr2btcaddr(c,mmaddr,ail_w,ail_f): # assume mmaddr has already been checked - if not acct_data: get_acct_data_from_wallet(c,acct_data) - btcaddr = mmaddr2btcaddr_addrdata(mmaddr,acct_data,"wallet")[0] -# btcaddr,comment = mmaddr2btcaddr_unspent(us,mmaddr) + sid,idx = mmaddr.split(":") + btcaddr = "" + + if sid in ail_w.seed_ids(): + btcaddr = ail_w.addrinfo(sid).btcaddr(int(idx)) + if not btcaddr: - if ail: - sid,idx = mmaddr.split(":") - btcaddr = ail.addrinfo(sid).btcaddr(int(idx)) + if ail_f and sid in ail_f.seed_ids(): + btcaddr = ail_f.addrinfo(sid).btcaddr(int(idx)) if btcaddr: msg(wmsg['addr_in_addrfile_only'].format(mmgenaddr=mmaddr)) if not keypress_confirm("Continue anyway?"): @@ -332,6 +316,13 @@ def mmaddr2btcaddr(c,mmaddr,acct_data,ail): return btcaddr +def make_b2m_map(inputs_data,tx_out,ail_w,ail_f): + d = dict([(d['address'], (d['mmid'],d['comment'])) + for d in inputs_data if d['mmid']]) + d.update(ail_w.make_reverse_dict(tx_out.keys())) + d.update(ail_f.make_reverse_dict(tx_out.keys())) + return d + cmd_args = opt.opts.init(opts_data) if opt.comment_file: @@ -342,16 +333,18 @@ c = connect_to_bitcoind() if not opt.info: do_license_msg(immed=True) - tx_out,acct_data,change_addr = {},{},"" - from mmgen.addr import AddrInfo,AddrInfoList - ail = AddrInfoList() + tx_out,change_addr = {},"" addrfiles = [a for a in cmd_args if get_extension(a) == g.addrfile_ext] cmd_args = set(cmd_args) - set(addrfiles) + from mmgen.addr import AddrInfo,AddrInfoList + ail_f = AddrInfoList() for a in addrfiles: check_infile(a) - ail.add(AddrInfo(a)) + ail_f.add(AddrInfo(a)) + + ail_w = AddrInfoList(bitcoind_connection=c) for a in cmd_args: if "," in a: @@ -359,7 +352,7 @@ if not opt.info: if is_btc_addr(a1): btcaddr = a1 elif is_mmgen_addr(a1): - btcaddr = mmaddr2btcaddr(c,a1,acct_data,ail) + btcaddr = mmaddr2btcaddr(c,a1,ail_w,ail_f) else: msg("%s: unrecognized subargument in argument '%s'" % (a1,a)) sys.exit(2) @@ -376,7 +369,7 @@ if not opt.info: (change_addr, a)) sys.exit(2) change_addr = a if is_btc_addr(a) else \ - mmaddr2btcaddr(c,a,acct_data,ail) + mmaddr2btcaddr(c,a,ail_w,ail_f) tx_out[change_addr] = 0 else: msg("%s: unrecognized argument" % a) @@ -474,13 +467,7 @@ tx_id = make_chksum_6(unhexlify(tx_hex)).upper() metadata = tx_id, amt, make_timestamp() sel_unspent = [i.__dict__ for i in sel_unspent] -def make_b2m_map(inputs_data,tx_out): - m = [(d['address'],(d['mmid'],d['comment'])) for d in inputs_data if d['mmid']] - d = ail.make_reverse_dict(tx_out.keys()) - d.update(m) - return d - -b2m_map = make_b2m_map(sel_unspent,tx_out) +b2m_map = make_b2m_map(sel_unspent,tx_out,ail_w,ail_f) prompt_and_view_tx_data(c,"View decoded transaction?", sel_unspent,tx_hex,b2m_map,comment,metadata) diff --git a/mmgen/util.py b/mmgen/util.py index c867c8ad..8493d9a8 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -58,6 +58,10 @@ def Vmsg(s): def Vmsg_r(s): if opt.verbose: sys.stdout.write(s) +def die(ev,s): + sys.stderr.write(s+"\n"); sys.exit(ev) +def Die(ev,s): + sys.stdout.write(s+"\n"); sys.exit(ev) def msgrepr(*args): for d in args: