TwCtl: variable, attribute and key renames

- tw -> twctl
- wallet -> twctl
This commit is contained in:
The MMGen Project 2022-11-14 09:54:08 +00:00
commit 00a52b687d
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
25 changed files with 77 additions and 80 deletions

View file

@ -71,7 +71,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
def __new__(cls,proto,*args,**kwargs):
return MMGenObject.__new__(proto.base_proto_subclass(cls,'addrdata'))
async def __init__(self,proto,wallet=None):
async def __init__(self,proto,twctl=None):
from .rpc import rpc_init
from .tw.shared import TwLabel
from .globalvars import g
@ -79,7 +79,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
self.proto = proto
self.rpc = await rpc_init(proto)
self.al_ids = {}
twd = await self.get_tw_data(wallet)
twd = await self.get_tw_data(twctl)
out,i = {},0
for acct,addr_array in twd:
l = get_obj(TwLabel,proto=self.proto,text=acct,silent=True)

View file

@ -111,12 +111,12 @@ def parse_cmd_args(rpc,cmd_args):
return al,infile
def check_opts(tw):
def check_opts(twctl):
batch = bool(opt.batch)
rescan = bool(opt.rescan)
if rescan and not 'rescan' in tw.caps:
msg(f"‘--rescan’ ignored: not supported by {type(tw).__name__}")
if rescan and not 'rescan' in twctl.caps:
msg(f"‘--rescan’ ignored: not supported by {type(twctl).__name__}")
rescan = False
if rescan and not opt.quiet:
@ -126,8 +126,8 @@ def check_opts(tw):
default_yes = True ):
die(1,'Exiting at user request')
if batch and not 'batch' in tw.caps:
msg(f"‘--batch’ ignored: not supported by {type(tw).__name__}")
if batch and not 'batch' in twctl.caps:
msg(f"‘--batch’ ignored: not supported by {type(twctl).__name__}")
batch = False
return batch,rescan
@ -137,21 +137,21 @@ async def main():
if opt.token_addr:
proto.tokensym = 'foo' # hack to trigger 'Token' in proto.base_proto_subclass()
tw = await TwCtl(
twctl = await TwCtl(
proto = proto,
token_addr = opt.token_addr,
mode = 'i' )
if opt.token or opt.token_addr:
msg(f'Importing for token {tw.token.hl()} ({tw.token.hlc(proto.tokensym)})')
msg(f'Importing for token {twctl.token.hl()} ({twctl.token.hlc(proto.tokensym)})')
from .rpc import rpc_init
tw.rpc = await rpc_init(proto)
twctl.rpc = await rpc_init(proto)
for k,v in addrimport_msgs.items():
addrimport_msgs[k] = fmt(v,indent=' ',strip_char='\t').rstrip()
al,infile = parse_cmd_args(tw.rpc,cmd_args)
al,infile = parse_cmd_args(twctl.rpc,cmd_args)
qmsg(
f'OK. {al.num_addrs} addresses'
@ -161,7 +161,7 @@ async def main():
f'Importing {len(al.data)} address{suf(al.data,"es")} from {infile}'
+ (' (batch mode)' if opt.batch else '') )
batch,rescan = check_opts(tw)
batch,rescan = check_opts(twctl)
def gen_args_list(al):
_d = namedtuple('import_data',['addr','twmmid','comment'])
@ -173,12 +173,12 @@ async def main():
args_list = list(gen_args_list(al))
await tw.import_address_common( args_list, batch=batch )
await twctl.import_address_common( args_list, batch=batch )
if rescan:
await tw.rescan_addresses({a.addr for a in args_list})
await twctl.rescan_addresses({a.addr for a in args_list})
del tw
del twctl
cmd_args = opts.init(opts_data)
from .protocol import init_proto_from_opts

View file

@ -134,7 +134,7 @@ async def main():
tx = await BumpTX(
data = orig_tx.__dict__,
send = sign_and_send,
tw = await TwCtl(orig_tx.proto) if orig_tx.proto.tokensym else None )
twctl = await TwCtl(orig_tx.proto) if orig_tx.proto.tokensym else None )
from .rpc import rpc_init
tx.rpc = await rpc_init(tx.proto)

View file

@ -82,7 +82,6 @@ async def main():
proto = init_proto_from_opts(need_amt=True)
from .tx import NewTX
from .tw.ctl import TwCtl
tx1 = await NewTX(proto=proto)
from .rpc import rpc_init

View file

@ -122,8 +122,6 @@ from .tx.sign import *
seed_files = get_seed_files(opt,cmd_args)
async def main():
from .tw.ctl import TwCtl
from .protocol import init_proto_from_opts
proto = init_proto_from_opts(need_amt=True)

View file

@ -26,7 +26,7 @@ class BitcoinTwAddrData(TwAddrData):
"""
}
async def get_tw_data(self,wallet=None):
async def get_tw_data(self,twctl=None):
vmsg('Getting address data from tracking wallet')
c = self.rpc
if 'label_api' in c.caps:

View file

@ -38,10 +38,10 @@ class BitcoinTwJSON(TwJSON):
@property
async def tracking_wallet_exists(self):
return await self.tw.rpc.check_or_create_daemon_wallet(wallet_create=False)
return await self.twctl.rpc.check_or_create_daemon_wallet(wallet_create=False)
async def create_tracking_wallet(self):
return await self.tw.rpc.check_or_create_daemon_wallet(wallet_create=True)
return await self.twctl.rpc.check_or_create_daemon_wallet(wallet_create=True)
async def get_entries(self):
entries_in = [self.entry_tuple_in(*e) for e in self.data['data']['entries']]
@ -56,7 +56,7 @@ class BitcoinTwJSON(TwJSON):
async def do_import(self,batch):
import_tuple = namedtuple('import_data',['addr','twmmid','comment'])
await self.tw.import_address_common(
await self.twctl.import_address_common(
[import_tuple(e.address, e.mmgen_id, e.comment) for e in self.entries],
batch = batch )
return [e.address for e in self.entries]

View file

@ -32,13 +32,13 @@ class EthereumTwAddrData(TwAddrData):
"""
}
async def get_tw_data(self,wallet=None):
async def get_tw_data(self,twctl=None):
from ...tw.ctl import TwCtl
from ...util import vmsg
vmsg('Getting address data from tracking wallet')
tw = (wallet or await TwCtl(self.proto)).mmid_ordered_dict
twctl = (twctl or await TwCtl(self.proto)).mmid_ordered_dict
# emulate the output of RPC 'listaccounts' and 'getaddressesbyaccount'
return [(mmid+' '+d['comment'],[d['addr']]) for mmid,d in list(tw.items())]
return [(mmid+' '+d['comment'],[d['addr']]) for mmid,d in list(twctl.items())]
class EthereumTokenTwAddrData(EthereumTwAddrData):
pass

View file

@ -74,7 +74,7 @@ Actions: [q]uit, r[e]draw, [D]elete address, add [l]abel:
addrs = {}
for label,addr in await self.get_addr_label_pairs():
bal = await self.wallet.get_balance(addr)
bal = await self.twctl.get_balance(addr)
addrs[label.mmid] = {
'addr': addr,
'amt': bal,

View file

@ -31,11 +31,11 @@ class EthereumTwGetBalance(TwGetBalance):
}
async def __init__(self,proto,*args,**kwargs):
self.wallet = await TwCtl(proto,mode='w')
self.twctl = await TwCtl(proto,mode='w')
await super().__init__(proto,*args,**kwargs)
async def create_data(self):
in_data = self.wallet.mmid_ordered_dict
in_data = self.twctl.mmid_ordered_dict
for d in in_data:
if d.type == 'mmgen':
label = d.obj.sid
@ -44,12 +44,12 @@ class EthereumTwGetBalance(TwGetBalance):
else:
label = 'Non-MMGen'
amt = await self.wallet.get_balance(in_data[d]['addr'])
amt = await self.twctl.get_balance(in_data[d]['addr'])
self.data['TOTAL']['ge_minconf'] += amt
self.data[label]['ge_minconf'] += amt
del self.wallet
del self.twctl
class EthereumTokenTwGetBalance(EthereumTwGetBalance):
pass

View file

@ -52,7 +52,7 @@ class EthereumTwJSON(TwJSON):
@property
async def tracking_wallet_exists(self):
return bool(self.tw.data['accounts'] or self.tw.data['tokens'])
return bool(self.twctl.data['accounts'] or self.twctl.data['tokens'])
async def create_tracking_wallet(self):
return True
@ -99,13 +99,13 @@ class EthereumTwJSON(TwJSON):
else:
yield ('params', {'symbol':d.symbol,'decimals':d.decimals})
self.tw.data = { # keys must be in correct order
self.twctl.data = { # keys must be in correct order
'coin': self.coin.upper(),
'network': self.network.upper(),
'accounts': dict(gen_data(self.entries['accounts'])),
'tokens': {k:dict(gen_data(v)) for k,v in self.entries['tokens'].items()},
}
self.tw.write(quiet=False)
self.twctl.write(quiet=False)
class Export(TwJSON.Export,Base):
@ -121,7 +121,7 @@ class EthereumTwJSON(TwJSON):
yield self.entry_tuple_in(TwMMGenID(self.proto,v['mmid']), k, v['comment'])
def gen_token_data():
for token_addr,token_data in self.tw.data['tokens'].items():
for token_addr,token_data in self.twctl.data['tokens'].items():
yield (
token_addr,
sorted(
@ -132,7 +132,7 @@ class EthereumTwJSON(TwJSON):
return {
'accounts': sorted(
gen_data(self.tw.data['accounts']),
gen_data(self.twctl.data['accounts']),
key = lambda x: x.mmgen_id.sort_key ),
'tokens': dict(sorted(gen_token_data()))
}

View file

@ -24,7 +24,7 @@ class EthereumTwRPC(TwRPC):
ret = [(
TwLabel( self.proto, mmid + ' ' + d['comment'] ),
CoinAddr( self.proto, d['addr'] )
) for mmid,d in self.wallet.mmid_ordered_dict.items() ]
) for mmid,d in self.twctl.mmid_ordered_dict.items() ]
if twmmid:
ret = [e for e in ret if e[0].mmid == twmmid]

View file

@ -101,13 +101,13 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
super().do_sort(key=key,reverse=reverse)
async def get_rpc_data(self):
wl = self.wallet.sorted_list
wl = self.twctl.sorted_list
if self.addrs:
wl = [d for d in wl if d['addr'] in self.addrs]
return [{
'account': TwLabel(self.proto,d['mmid']+' '+d['comment']),
'address': d['addr'],
'amount': await self.wallet.get_balance(d['addr']),
'amount': await self.twctl.get_balance(d['addr']),
'confirmations': 0, # TODO
} for d in wl]
@ -118,9 +118,9 @@ class EthereumTokenTwUnspentOutputs(EthereumTwUnspentOutputs):
async def __init__(self,proto,*args,**kwargs):
await super().__init__(proto,*args,**kwargs)
self.proto.tokensym = self.wallet.symbol
self.proto.tokensym = self.twctl.symbol
async def get_data(self,*args,**kwargs):
await super().get_data(*args,**kwargs)
for e in self.data:
e.amt2 = await self.wallet.get_eth_balance(e.addr)
e.amt2 = await self.twctl.get_eth_balance(e.addr)

View file

@ -175,7 +175,7 @@ class TokenNew(TokenBase,New):
async def make_txobj(self): # called by create_serialized()
await super().make_txobj()
t = Token(self.proto,self.tw.token,self.tw.decimals)
t = Token(self.proto,self.twctl.token,self.twctl.decimals)
o = self.txobj
o['token_addr'] = t.addr
o['decimals'] = t.decimals
@ -189,14 +189,14 @@ class TokenNew(TokenBase,New):
# token transaction, so check both eth and token balances
# TODO: add test with insufficient funds
async def precheck_sufficient_funds(self,inputs_sum,sel_unspent,outputs_sum):
eth_bal = await self.tw.get_eth_balance(sel_unspent[0].addr)
eth_bal = await self.twctl.get_eth_balance(sel_unspent[0].addr)
if eth_bal == 0: # we don't know the fee yet
msg('This account has no ether to pay for the transaction fee!')
return False
return await super().precheck_sufficient_funds(inputs_sum,sel_unspent,outputs_sum)
async def get_funds_left(self,fee,outputs_sum):
return ( await self.tw.get_eth_balance(self.inputs[0].addr) ) - fee
return ( await self.twctl.get_eth_balance(self.inputs[0].addr) ) - fee
def final_inputs_ok_msg(self,funds_left):
token_bal = (

View file

@ -75,9 +75,9 @@ class TokenOnlineSigned(TokenSigned,OnlineSigned):
from ..contract import Token
d = OnlineSigned.parse_txfile_serialized_data(self)
o = self.txobj
assert self.tw.token == o['to']
assert self.twctl.token == o['to']
o['token_addr'] = TokenAddr(self.proto,o['to'])
o['decimals'] = self.tw.decimals
o['decimals'] = self.twctl.decimals
t = Token(self.proto,o['token_addr'],o['decimals'])
o['amt'] = t.transferdata2amt(o['data'])
o['token_to'] = t.transferdata2sendaddr(o['data'])

View file

@ -64,8 +64,8 @@ class tool_cmd(tool_cmd_base):
else:
ret = await obj.format('detail' if detail else 'squeezed')
if hasattr(obj,'wallet'):
del obj.wallet
if hasattr(obj,'twctl'):
del obj.twctl
return ret

View file

@ -115,15 +115,15 @@ class TwCtl(MMGenObject,metaclass=AsyncInit):
# ensure that wallet file is written when user exits via KeyboardInterrupt:
if self.mode == 'w':
import atexit
def del_tw(tw):
dmsg(f'Running exit handler del_tw() for {tw!r}')
del tw
atexit.register(del_tw,self)
def del_twctl(twctl):
dmsg(f'Running exit handler del_twctl() for {twctl!r}')
del twctl
atexit.register(del_twctl,self)
def __del__(self):
"""
TwCtl instances opened in write or import mode must be explicitly destroyed with 'del
twuo.twctl' and the like to ensure the instance is deleted and wallet is written before
TwCtl instances opened in write or import mode must be explicitly destroyed with del
twuo.twctl and the like to ensure the instance is deleted and wallet is written before
global vars are destroyed by the interpreter at shutdown.
Not that this code can only be debugged by examining the program output, as exceptions
@ -221,7 +221,7 @@ class TwCtl(MMGenObject,metaclass=AsyncInit):
return None
from .rpc import TwRPC
pairs = await TwRPC(proto=self.proto,rpc=self.rpc,wallet=self).get_addr_label_pairs(twmmid)
pairs = await TwRPC(proto=self.proto,rpc=self.rpc,twctl=self).get_addr_label_pairs(twmmid)
if not pairs:
msg(f'MMGen address {twmmid!r} not found in tracking wallet')
@ -272,7 +272,7 @@ class TwCtl(MMGenObject,metaclass=AsyncInit):
if await self.set_label(res.coinaddr,lbl):
# redundant paranoia step:
from .rpc import TwRPC
pairs = await TwRPC(proto=self.proto,rpc=self.rpc,wallet=self).get_addr_label_pairs(res.twmmid)
pairs = await TwRPC(proto=self.proto,rpc=self.rpc,twctl=self).get_addr_label_pairs(res.twmmid)
assert pairs[0][0].comment == comment, f'{pairs[0][0].comment!r} != {comment!r}'
desc = '{} address {} in tracking wallet'.format(

View file

@ -66,7 +66,7 @@ class TwJSON:
super().__init__(proto)
self.tw = await TwCtl( proto, mode='i', rpc_ignore_wallet=True )
self.twctl = await TwCtl( proto, mode='i', rpc_ignore_wallet=True )
def check_network(data):
coin,network = data['network'].split('_')
@ -102,13 +102,13 @@ class TwJSON:
addrs = await self.do_import(batch)
await self.tw.rescan_addresses(addrs)
await self.twctl.rescan_addresses(addrs)
async def check_and_create_wallet(self):
if await self.tracking_wallet_exists:
die(3,
f'Existing {self.tw.rpc.daemon.desc} wallet detected!\n' +
f'Existing {self.twctl.rpc.daemon.desc} wallet detected!\n' +
'It must be moved, or backed up and securely deleted, before running this command' )
msg('\n'+fmt(self.info_msg.strip(),indent=' '))
@ -132,7 +132,7 @@ class TwJSON:
if not include_amts:
self.keys.remove('amount')
self.tw = await TwCtl( proto )
self.twctl = await TwCtl( proto )
self.entries = await self.get_entries()
@ -140,7 +140,7 @@ class TwJSON:
'id': 'mmgen_tracking_wallet',
'version': 1,
'network': f'{self.coin}_{self.network}',
'blockheight': self.tw.rpc.blockcount,
'blockheight': self.twctl.rpc.blockcount,
'time': make_timestamp(),
'mappings_checksum': self.mappings_chksum,
'entries_keys': self.keys,

View file

@ -19,7 +19,7 @@ class TwRPC:
def __new__(cls,proto,*args,**kwargs):
return MMGenObject.__new__(proto.base_proto_subclass(cls,'tw.rpc'))
def __init__(self,proto,rpc,wallet):
def __init__(self,proto,rpc,twctl):
self.proto = proto
self.rpc = rpc
self.wallet = wallet
self.twctl = twctl

View file

@ -120,7 +120,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
self.rpc = await rpc_init(proto)
if self.has_wallet:
from .ctl import TwCtl
self.wallet = await TwCtl(proto,mode='w')
self.twctl = await TwCtl(proto,mode='w')
self.amt_keys = {'amt':'iwidth','amt2':'iwidth2'} if self.has_amt2 else {'amt':'iwidth'}
@property
@ -476,7 +476,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
if not keypress_confirm(
f'Refreshing tracking wallet {parent.item_desc} #{idx}. Is this what you want?'):
return 'redo'
await parent.wallet.get_balance( parent.disp_data[idx-1].addr, force_rpc=True )
await parent.twctl.get_balance( parent.disp_data[idx-1].addr, force_rpc=True )
await parent.get_data()
parent.oneshot_msg = yellow(f'{parent.proto.dcoin} balance for account #{idx} refreshed\n\n')
@ -486,7 +486,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
'Removing {} {} from tracking wallet. Is this what you want?'.format(
parent.item_desc, red(f'#{idx}') )):
return 'redo'
if await parent.wallet.remove_address( parent.disp_data[idx-1].addr ):
if await parent.twctl.remove_address( parent.disp_data[idx-1].addr ):
await parent.get_data()
parent.oneshot_msg = yellow(f'{capfirst(parent.item_desc)} #{idx} removed\n\n')
else:
@ -496,7 +496,7 @@ class TwView(MMGenObject,metaclass=AsyncInit):
async def a_comment_add(self,parent,idx):
async def do_comment_add(comment):
if await parent.wallet.set_comment( entry.twmmid, comment, entry.addr ):
if await parent.twctl.set_comment( entry.twmmid, comment, entry.addr ):
entry.comment = comment
parent.oneshot_msg = yellow('Label {a} {b}{c}\n\n'.format(
a = 'for' if cur_comment and comment else 'added to' if comment else 'removed from',

View file

@ -68,11 +68,11 @@ async def _get_obj_async( _clsname, _modname, *args, **kwargs ):
# NB: tracking wallet needed to retrieve the 'symbol' and 'decimals' parameters of token addr
# (see twctl:import_token()).
# No tracking wallet required for the Unsigned and Signed(data=unsigned.__dict__) classes used
# during signing.
# No twctl required for the Unsigned and Signed(data=unsigned.__dict__) classes used during
# signing.
if proto and proto.tokensym and clsname in ('New','OnlineSigned'):
from ..tw.ctl import TwCtl
kwargs['tw'] = await TwCtl(proto)
kwargs['twctl'] = await TwCtl(proto)
return _base_proto_subclass( clsname, modname, proto )(*args,**kwargs)

View file

@ -114,7 +114,7 @@ class Base(MMGenObject):
self.outputs = self.OutputList(self)
self.name = type(self).__name__
self.proto = kwargs.get('proto')
self.tw = kwargs.get('tw')
self.twctl = kwargs.get('twctl')
@property
def coin(self):

View file

@ -27,7 +27,7 @@ class Completed(Base):
super().__init__(*args,**kwargs)
if data:
data['tw'] = self.tw
data['twctl'] = self.twctl
self.__dict__ = data
self.name = type(self).__name__
else:

View file

@ -224,7 +224,7 @@ class New(Base):
check_infile(a)
ad_f.add(AddrList(self.proto,a))
ad_w = await TwAddrData(self.proto,wallet=self.tw)
ad_w = await TwAddrData(self.proto,twctl=self.twctl)
self.process_cmd_args(cmd_args,ad_f,ad_w)
@ -345,7 +345,7 @@ class New(Base):
self.twuo.display_total()
if do_info:
del self.twuo.wallet
del self.twuo.twctl
sys.exit(0)
outputs_sum = self.sum_outputs()
@ -378,5 +378,5 @@ class New(Base):
if not opt.yes:
new.info.view_with_prompt('View transaction details?')
del new.twuo.wallet
del new.twuo.twctl
return new

View file

@ -1323,12 +1323,12 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
async def twmove(self):
self.spawn('',msg_only=True)
from mmgen.tw.ctl import TwCtl
tw = await TwCtl(self.proto)
twctl = await TwCtl(self.proto)
imsg(f'Moving tracking wallet')
bakfile = tw.tw_fn + '.bak.json'
bakfile = twctl.tw_fn + '.bak.json'
if os.path.exists(bakfile):
os.unlink(bakfile)
os.rename( tw.tw_fn, bakfile )
os.rename( twctl.tw_fn, bakfile )
return 'ok'
def twimport(self,add_args=[],expect_str=None):
@ -1355,8 +1355,8 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared):
async def twcompare(self):
self.spawn('',msg_only=True)
from mmgen.tw.ctl import TwCtl
tw = await TwCtl(self.proto)
fn = tw.tw_fn
twctl = await TwCtl(self.proto)
fn = twctl.tw_fn
imsg(f'Comparing imported tracking wallet with original')
data = [json.dumps(json.loads(read_from_file(f)),sort_keys=True) for f in (fn,fn+'.bak.json')]
cmp_or_die(*data,'tracking wallets')