Bugfix: MMGen -> BTC map for outputs not included in tx
This commit is contained in:
parent
affacd5fc5
commit
a4998a9cbd
4 changed files with 71 additions and 49 deletions
8
MANIFEST
8
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue