Browse Source

'showbtcaddr' option added to 'mmgen-tool listaddresses'

philemon 9 years ago
parent
commit
20bff803fa
2 changed files with 47 additions and 31 deletions
  1. 44 28
      mmgen/tool.py
  2. 3 3
      test/test.py

+ 44 - 28
mmgen/tool.py

@@ -75,7 +75,7 @@ cmd_data = OrderedDict([
 	("mn_printlist", ['wordlist [str="electrum"]']),
 
 
-	("listaddresses",['minconf [int=1]','showempty [bool=False]','pager [bool=False]']),
+	("listaddresses",['minconf [int=1]','showempty [bool=False]','pager [bool=False]','showbtcaddr [bool=False]']),
 	("getbalance",   ['minconf [int=1]']),
 	("txview",       ['<{pnm} tx file> [str]','pager [bool=False]','terse [bool=False]'.format(pnm=pnm)]),
 
@@ -368,52 +368,68 @@ def id6(infile):
 def str2id6(s):  Msg(make_chksum_6("".join(s.split())))
 
 # List MMGen addresses and their balances:
-def listaddresses(minconf=1,showempty=False,pager=False):
+def listaddresses(minconf=1,showempty=False,pager=False,showbtcaddr=False):
 	from mmgen.tx import connect_to_bitcoind,trim_exponent,is_mmgen_addr
 	c = connect_to_bitcoind()
 
 	addrs = {}
+	from decimal import Decimal
+	total = Decimal('0')
 	for d in c.listunspent(0):
-		ma,comment = split2(d.account)
-		if is_mmgen_addr(ma) and d.confirmations >= minconf:
-			key = "_".join(ma.split(":"))
-			if key not in addrs: addrs[key] = [0,comment]
+		mmaddr,comment = split2(d.account)
+		if is_mmgen_addr(mmaddr) and d.confirmations >= minconf:
+			key = mmaddr.replace(':','_')
+			if key in addrs:
+				if addrs[key][2] != d.address:
+					die(2,'duplicate BTC address ({}) for this MMGen address! ({})'.format(
+							(d.address, addrs[key][2])))
+			else:
+				addrs[key] = [0,comment,d.address]
 			addrs[key][0] += d.amount
+			total += d.amount
 
+	# We use listaccounts only for empty addresses, as it shows false positive balances
 	if showempty:
-		# Show accts with not enough confirmations as empty!
-		# A feature, not a bug!
 		accts = c.listaccounts(minconf=0,includeWatchonly=True,as_dict=True)
-		for k in accts.keys():
-			ma,comment = split2(k)
-			if is_mmgen_addr(ma) and accts[k] == 0:
-				key = "_".join(ma.split(":"))
-				if key not in addrs: addrs[key] = [0,comment]
+		for a in accts:
+			mmaddr,comment = split2(a)
+			if is_mmgen_addr(mmaddr):
+				key = mmaddr.replace(':','_')
+				if key not in addrs:
+					if showbtcaddr:
+						tmp = c.getaddressesbyaccount(a)
+						if len(tmp) != 1:
+							die(2,"Account '%s' has more or less than one BTC address!" % a)
+						baddr = tmp[0]
+					else:
+						baddr = ''
+					addrs[key] = [0,comment,baddr]
 
 	if not addrs:
 		if showempty:
-			msg("No tracked addresses!")
+			msg('No tracked addresses!')
 		else:
-			msg("No addresses with balances!")
+			msg('No addresses with balances!')
 		sys.exit(1)
 
-	fs = "%-{}s  %-{}s   %s".format(
-		max([len(k) for k in addrs.keys()]),
-		max([len(str(addrs[k][1])) for k in addrs.keys()])
+	fs = '%-{}s %-{}s %-{}s %s'.format(
+		max(len(k) for k in addrs),
+		(0,36)[showbtcaddr],
+		max(len(addrs[k][1]) for k in addrs) + 1
 	)
-	out = [ fs % ("ADDRESS","COMMENT","BALANCE") ]
 
-	def s_mmgen(ma):
-		return "{}:{:>0{w}}".format(w=g.mmgen_idx_max_digits, *ma.split("_"))
+	def s_mmgen(key):
+		return '{}:{:>0{w}}'.format(w=g.mmgen_idx_max_digits, *key.split('_'))
 
-	old_sid = ""
-	for k in sorted(addrs.keys(),key=s_mmgen):
-		sid,num = k.split("_")
-		if old_sid and old_sid != sid: out.append("")
-		old_sid = sid
-		out.append(fs % (sid+":"+num, addrs[k][1], trim_exponent(addrs[k][0])))
+	out = []
+	for k in sorted(addrs,key=s_mmgen):
+		if out and k.split('_')[0] != out[-1].split(':')[0]: out.append('')
+		baddr = ' ' + addrs[k][2] if showbtcaddr else ''
+		out.append(fs % (k.replace('_',':'), baddr, addrs[k][1], trim_exponent(addrs[k][0])))
 
-	o = "\n".join(out)
+	o = (fs + '\n%s\nTOTAL: %s BTC') % (
+			'ADDRESS','','COMMENT','BALANCE', '\n'.join(out), trim_exponent(total)
+		)
 	if pager: do_pager(o)
 	else: Msg(o)
 

+ 3 - 3
test/test.py

@@ -292,9 +292,9 @@ cmd_group['ref'] = (
 	('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",pwfile],'new refwallet addr chksum')),
- 	('refkeyaddrgen',  (["mmdat",pwfile],'new refwallet key-addr chksum'))
+	('refwalletgen',   ([],'gen new refwallet')),
+	('refaddrgen',     (["mmdat",pwfile],'new refwallet addr chksum')),
+	('refkeyaddrgen',  (["mmdat",pwfile],'new refwallet key-addr chksum'))
 )
 
 # misc. saved reference data