*TrackingWallet refactor

MMGenTrackingWallet now split into:

- TwUnspentOutputs, for unspent outputs display
- TrackingWallet, for label and other operations

EthereumTrackingWallet is now subclassed from TrackingWallet
This commit is contained in:
The MMGen Project 2018-05-26 11:19:17 +00:00
commit 795b5d8b62
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
4 changed files with 87 additions and 87 deletions

View file

@ -20,12 +20,14 @@
altcoins.eth.tw: ETH tracking wallet functions and methods for the MMGen suite
"""
import json
from mmgen.common import *
from mmgen.obj import *
import json
from mmgen.tw import TrackingWallet,TwAddrList
from mmgen.addr import AddrData
# No file locking - 2 processes accessing the wallet at the same time will corrupt it
class EthereumTrackingWallet(object):
class EthereumTrackingWallet(TrackingWallet):
data_dir = os.path.join(g.altcoin_data_dir,'eth')
tw_file = os.path.join(data_dir,'tracking-wallet.json')
@ -89,19 +91,16 @@ class EthereumTrackingWallet(object):
from collections import OrderedDict
return OrderedDict(map(lambda x: (x['mmid'],{'addr':x['addr'],'comment':x['comment']}), self.sorted_list()))
@classmethod
def import_label(cls,coinaddr,lbl):
tw = cls()
for addr,d in tw.data.items():
def import_label(self,coinaddr,lbl):
for addr,d in self.data.items():
if addr == coinaddr:
d['comment'] = lbl.comment
tw.write()
self.write()
return None
else: # emulate RPC library
return ('rpcfail',(None,2,"Address '{}' not found in tracking wallet".format(coinaddr)))
from mmgen.tw import TwAddrList
class EthereumTwAddrList(TwAddrList):
def __init__(self,usr_addr_list,minconf,showempty,showbtcaddrs,all_labels):
@ -126,7 +125,6 @@ class EthereumTwAddrList(TwAddrList):
self[label.mmid]['amt'] += bal
self.total += bal
from mmgen.addr import AddrData
class EthereumAddrData(AddrData):
@classmethod

View file

@ -713,8 +713,8 @@ def Txview(*infiles,**kwargs):
def Twview(pager=False,reverse=False,wide=False,minconf=1,sort='age',show_days=True,show_mmid=True):
rpc_init()
from mmgen.tw import MMGenTrackingWallet
tw = MMGenTrackingWallet(minconf=minconf)
from mmgen.tw import TwUnspentOutputs
tw = TwUnspentOutputs(minconf=minconf)
tw.do_sort(sort,reverse=reverse)
tw.show_days = show_days
tw.show_mmid = show_mmid
@ -723,7 +723,8 @@ def Twview(pager=False,reverse=False,wide=False,minconf=1,sort='age',show_days=T
def Add_label(mmaddr_or_coin_addr,label):
rpc_init()
from mmgen.tw import MMGenTrackingWallet
MMGenTrackingWallet.add_label(mmaddr_or_coin_addr,label,on_fail='raise')
from mmgen.tw import TrackingWallet
TrackingWallet().add_label(mmaddr_or_coin_addr,label,on_fail='raise')
def Remove_label(mmaddr_or_coin_addr): Add_label(mmaddr_or_coin_addr,'')
def Remove_label(mmaddr_or_coin_addr):
Add_label(mmaddr_or_coin_addr,'')

View file

@ -26,7 +26,7 @@ from mmgen.tx import is_mmgen_id
CUR_HOME,ERASE_ALL = '\033[H','\033[0J'
class MMGenTrackingWallet(MMGenObject):
class TwUnspentOutputs(MMGenObject):
class MMGenTwOutputList(list,MMGenObject): pass
@ -280,7 +280,7 @@ Display options: show [D]ays, [g]roup, show [m]mgen addr, r[e]draw screen
idx,lbl = self.get_idx_and_label_from_user()
if idx:
e = self.unspent[idx-1]
if type(self).add_label(e.twmmid,lbl,addr=e.addr):
if TrackingWallet().add_label(e.twmmid,lbl,addr=e.addr):
self.get_unspent_data()
self.do_sort()
msg(u'{}\n{}\n{}'.format(self.fmt_display,prompt,p))
@ -312,75 +312,6 @@ Display options: show [D]ays, [g]roup, show [m]mgen addr, r[e]draw screen
self.display()
msg(prompt)
@classmethod
def import_label(cls,coinaddr,lbl):
# NOTE: this works because importaddress() removes the old account before
# associating the new account with the address.
# Will be replaced by setlabel() with new RPC label API
# RPC args: addr,label,rescan[=true],p2sh[=none]
return g.rpch.importaddress(coinaddr,lbl,False,on_fail='return')
# returns on failure
@classmethod
def add_label(cls,arg1,label='',addr=None,silent=False,on_fail='return'):
from mmgen.tx import is_mmgen_id,is_coin_addr
mmaddr,coinaddr = None,None
if is_coin_addr(addr or arg1):
coinaddr = CoinAddr(addr or arg1,on_fail='return')
if is_mmgen_id(arg1):
mmaddr = TwMMGenID(arg1)
if mmaddr and not coinaddr:
from mmgen.addr import AddrData
coinaddr = AddrData(source='tw').mmaddr2coinaddr(mmaddr)
try:
if not is_mmgen_id(arg1):
assert coinaddr,u"Invalid coin address for this chain: {}".format(arg1)
assert coinaddr,u"{pn} address '{ma}' not found in tracking wallet"
assert coinaddr.is_in_tracking_wallet(),u"Address '{ca}' not found in tracking wallet"
except Exception as e:
msg(e[0].format(pn=g.proj_name,ma=mmaddr,ca=coinaddr))
return False
# Allow for the possibility that BTC addr of MMGen addr was entered.
# Do reverse lookup, so that MMGen addr will not be marked as non-MMGen.
if not mmaddr:
from mmgen.addr import AddrData
mmaddr = AddrData(source='tw').coinaddr2mmaddr(coinaddr)
if not mmaddr: mmaddr = '{}:{}'.format(g.proto.base_coin.lower(),coinaddr)
mmaddr = TwMMGenID(mmaddr)
cmt = TwComment(label,on_fail=on_fail)
if cmt in (False,None): return False
lbl = TwLabel(mmaddr + ('',' '+cmt)[bool(cmt)],on_fail=on_fail)
if g.coin == 'ETH':
from mmgen.altcoins.eth.tw import EthereumTrackingWallet
cls = EthereumTrackingWallet
ret = cls.import_label(coinaddr,lbl)
from mmgen.rpc import rpc_error,rpc_errmsg
if rpc_error(ret):
msg('From {}: {}'.format(g.proto.daemon_name,rpc_errmsg(ret)))
if not silent:
msg('Label could not be {}'.format(('removed','added')[bool(label)]))
return False
else:
m = mmaddr.type.replace('mmg','MMG')
a = mmaddr.replace(g.proto.base_coin.lower()+':','')
s = '{} address {} in tracking wallet'.format(m,a)
if label: msg(u"Added label '{}' to {}".format(label,s))
else: msg(u'Removed label from {}'.format(s))
return True
@classmethod
def remove_label(cls,mmaddr): cls.add_label(mmaddr,'')
class TwAddrList(MMGenDict):
def __new__(cls,*args,**kwargs):
@ -504,3 +435,73 @@ class TwAddrList(MMGenDict):
))
return '\n'.join(out + ['\nTOTAL: {} {}'.format(self.total.hl(color=True),g.coin)])
class TrackingWallet(MMGenObject):
def __new__(cls,*args,**kwargs):
if g.coin == 'ETH':
from mmgen.altcoins.eth.tw import EthereumTrackingWallet
cls = EthereumTrackingWallet
return MMGenObject.__new__(cls,*args,**kwargs)
def import_label(self,coinaddr,lbl):
# NOTE: this works because importaddress() removes the old account before
# associating the new account with the address.
# Will be replaced by setlabel() with new RPC label API
# RPC args: addr,label,rescan[=true],p2sh[=none]
return g.rpch.importaddress(coinaddr,lbl,False,on_fail='return')
# returns on failure
def add_label(self,arg1,label='',addr=None,silent=False,on_fail='return'):
from mmgen.tx import is_mmgen_id,is_coin_addr
mmaddr,coinaddr = None,None
if is_coin_addr(addr or arg1):
coinaddr = CoinAddr(addr or arg1,on_fail='return')
if is_mmgen_id(arg1):
mmaddr = TwMMGenID(arg1)
if mmaddr and not coinaddr:
from mmgen.addr import AddrData
coinaddr = AddrData(source='tw').mmaddr2coinaddr(mmaddr)
try:
if not is_mmgen_id(arg1):
assert coinaddr,u"Invalid coin address for this chain: {}".format(arg1)
assert coinaddr,u"{pn} address '{ma}' not found in tracking wallet"
assert coinaddr.is_in_tracking_wallet(),u"Address '{ca}' not found in tracking wallet"
except Exception as e:
msg(e[0].format(pn=g.proj_name,ma=mmaddr,ca=coinaddr))
return False
# Allow for the possibility that BTC addr of MMGen addr was entered.
# Do reverse lookup, so that MMGen addr will not be marked as non-MMGen.
if not mmaddr:
from mmgen.addr import AddrData
mmaddr = AddrData(source='tw').coinaddr2mmaddr(coinaddr)
if not mmaddr: mmaddr = '{}:{}'.format(g.proto.base_coin.lower(),coinaddr)
mmaddr = TwMMGenID(mmaddr)
cmt = TwComment(label,on_fail=on_fail)
if cmt in (False,None): return False
lbl = TwLabel(mmaddr + ('',' '+cmt)[bool(cmt)],on_fail=on_fail)
ret = self.import_label(coinaddr,lbl)
from mmgen.rpc import rpc_error,rpc_errmsg
if rpc_error(ret):
msg('From {}: {}'.format(g.proto.daemon_name,rpc_errmsg(ret)))
if not silent:
msg('Label could not be {}'.format(('removed','added')[bool(label)]))
return False
else:
m = mmaddr.type.replace('mmg','MMG')
a = mmaddr.replace(g.proto.base_coin.lower()+':','')
s = '{} address {} in tracking wallet'.format(m,a)
if label: msg(u"Added label '{}' to {}".format(label,s))
else: msg(u'Removed label from {}'.format(s))
return True
def remove_label(self,mmaddr): self.add_label(mmaddr,'')

View file

@ -1195,8 +1195,8 @@ class MMGenTX(MMGenObject):
do_license_msg()
from mmgen.tw import MMGenTrackingWallet
tw = MMGenTrackingWallet(minconf=opt.minconf)
from mmgen.tw import TwUnspentOutputs
tw = TwUnspentOutputs(minconf=opt.minconf)
tw.view_and_sort(self)
tw.display_total()