MoneroWalletOps: portability fixes

This commit is contained in:
The MMGen Project 2021-05-07 19:10:37 +00:00
commit 9dc8efe161
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2

View file

@ -32,6 +32,11 @@ NL = ('\n','\r\n')[g.platform=='win']
def _options_annot_str(l):
return "(valid options: '{}')".format("','".join(l))
def _create_argtuple(method,localvars):
co = method.__code__
args = co.co_varnames[1:co.co_argcount]
return namedtuple('cmd_args',args)(*(localvars[a] for a in args))
def _create_call_sig(cmd,parsed=False):
m = MMGenToolCmds[cmd]
@ -1007,6 +1012,25 @@ class MMGenToolCmdRPC(MMGenToolCmds):
msg("Address '{}' deleted from tracking wallet".format(ret))
return ret
from .obj import XMRAmt
def fmtXMRamt(amt):
return XMRAmt(amt,from_unit='min_coin_unit').fmt(fs='5.12',color=True)
def hlXMRamt(amt):
return XMRAmt(amt,from_unit='min_coin_unit').hl()
def make_uarg_info():
e = namedtuple('uarg_info_entry',['annot','pat'])
hp = r'(?:[^:]+):(?:\d+)'
return {
'daemon': e('HOST:PORT', hp),
'tx_relay_daemon': e('HOST:PORT[:PROXY_HOST:PROXY_PORT]', r'({p})(?::({p}))?'.format(p=hp)),
'wallets_sweep': e('SOURCE_WALLET_NUM:ACCOUNT[,DEST_WALLET_NUM]', r'(\d+):(\d+)(?:,(\d+))?'),
}
uarg_info = make_uarg_info()
class MMGenToolCmdMonero(MMGenToolCmds):
"""
Monero wallet operations
@ -1020,12 +1044,12 @@ class MMGenToolCmdMonero(MMGenToolCmds):
self,
op: str,
xmr_keyaddrfile: str,
blockheight: '(default: current height)' = 0,
restore_height = 0,
wallets: '(integer range or list, or sweep specifier)' = '',
start_wallet_daemon = True,
stop_wallet_daemon = True,
daemon: 'HOST:PORT' = '',
tx_relay_daemon: 'HOST:PORT[:PROXY_HOST:PROXY_PORT]' = '',
daemon: uarg_info['daemon'].annot = '',
tx_relay_daemon: uarg_info['tx_relay_daemon'].annot = '',
):
"""
@ -1072,7 +1096,29 @@ class MMGenToolCmdMonero(MMGenToolCmds):
wallet_exists = True
tx_relay = False
def __init__(self):
def check_uargs(self):
def check_host_arg(name):
val = getattr(uarg,name)
if not re.fullmatch(uarg_info[name].pat,val,re.ASCII):
die(1,'{!r}: invalid {!r} parameter: it must have format {!r}'.format(
val, name, uarg_info[name].annot ))
if uarg.op != 'create' and uarg.restore_height != 0:
die(1,"'restore_height' arg is supported only for create operation")
if uarg.restore_height < 0:
die(1,f"{uarg.restore_height}: invalid 'restore_height' arg (<0)")
if uarg.daemon:
check_host_arg('daemon')
if uarg.tx_relay_daemon:
if not self.tx_relay:
die(1,f"'tx_relay_daemon' arg is not recognized for operation {uarg.op!r}")
check_host_arg('tx_relay_daemon')
def __init__(self,uarg_tuple):
def wallet_exists(fn):
try: os.stat(fn)
@ -1088,8 +1134,13 @@ class MMGenToolCmdMonero(MMGenToolCmds):
elif not exists and self.wallet_exists:
die(1,f'Wallet {fn!r} not found!')
global uarg
uarg = uarg_tuple
self.check_uargs()
from .protocol import init_proto
self.kal = KeyAddrList(init_proto('xmr',network='mainnet'),xmr_keyaddrfile)
self.kal = KeyAddrList(init_proto('xmr',network='mainnet'),uarg.xmr_keyaddrfile)
self.create_addr_data()
check_wallets()
@ -1098,10 +1149,10 @@ class MMGenToolCmdMonero(MMGenToolCmds):
self.wd = MoneroWalletDaemon(
wallet_dir = opt.outdir or '.',
test_suite = g.test_suite,
daemon_addr = daemon or None,
daemon_addr = uarg.daemon or None,
)
if start_wallet_daemon:
if uarg.start_wallet_daemon:
self.wd.restart()
from .rpc import MoneroWalletRPCClient
@ -1115,18 +1166,18 @@ class MMGenToolCmdMonero(MMGenToolCmds):
self.post_init()
def create_addr_data(self):
if wallets:
idxs = AddrIdxList(wallets)
if uarg.wallets:
idxs = AddrIdxList(uarg.wallets)
self.addr_data = [d for d in self.kal.data if d.idx in idxs]
if len(self.addr_data) != len(idxs):
die(1,f'List {wallets!r} contains addresses not present in supplied key-address file')
die(1,f'List {uarg.wallets!r} contains addresses not present in supplied key-address file')
else:
self.addr_data = self.kal.data
def stop_daemons(self):
if stop_wallet_daemon:
if uarg.stop_wallet_daemon:
self.wd.stop()
if tx_relay_daemon:
if uarg.tx_relay_daemon:
self.wd2.stop()
def post_init(self): pass
@ -1168,7 +1219,7 @@ class MMGenToolCmdMonero(MMGenToolCmds):
filename = os.path.basename(fn),
password = d.wallet_passwd,
seed = baseconv.fromhex(d.sec,'xmrseed',tostr=True),
restore_height = blockheight,
restore_height = uarg.restore_height,
language = 'English' )
pp_msg(ret) if opt.debug else msg(' Address: {}'.format(ret['address']))
@ -1231,7 +1282,7 @@ class MMGenToolCmdMonero(MMGenToolCmds):
return True
def post_init(self):
host,port = daemon.split(':') if daemon else ('localhost',self.wd.daemon_port)
host,port = uarg.daemon.split(':') if uarg.daemon else ('localhost',self.wd.daemon_port)
from .rpc import MoneroRPCClient
self.dc = MoneroRPCClient(host=host, port=int(port), user=None, passwd=None)
self.accts_data = {}
@ -1265,13 +1316,10 @@ class MMGenToolCmdMonero(MMGenToolCmds):
tx_relay = True
def create_addr_data(self):
m = re.match('(\d+):(\d+)(?:,(\d+))?$',wallets,re.ASCII)
m = re.fullmatch(uarg_info['wallets_sweep'].pat,uarg.wallets,re.ASCII)
if not m:
die(1,
"{!r}: invalid 'wallets' arg: for sweep operation, it must have format {}".format(
wallets,
'SOURCE:ACCOUNT[,DEST]'
))
fs = "{!r}: invalid 'wallets' arg: for sweep operation, it must have format {!r}"
die(1,fs.format( uarg.wallets, uarg_info['wallets_sweep'].annot ))
def gen():
for i,k in ( (1,'source'), (3,'dest') ):
@ -1294,8 +1342,8 @@ class MMGenToolCmdMonero(MMGenToolCmds):
def post_init(self):
if tx_relay_daemon:
m = re.fullmatch(hostproxy_pat,tx_relay_daemon,re.ASCII)
if uarg.tx_relay_daemon:
m = re.fullmatch(uarg_info['tx_relay_daemon'].pat,uarg.tx_relay_daemon,re.ASCII)
from .daemon import MoneroWalletDaemon
self.wd2 = MoneroWalletDaemon(
@ -1306,7 +1354,7 @@ class MMGenToolCmdMonero(MMGenToolCmds):
rpc_port_shift = 16,
)
if start_wallet_daemon:
if uarg.start_wallet_daemon:
self.wd2.restart()
from .rpc import MoneroWalletRPCClient
@ -1368,7 +1416,7 @@ class MMGenToolCmdMonero(MMGenToolCmds):
if keypress_confirm('Relay sweep transaction?'):
w_desc = 'source'
if tx_relay_daemon:
if uarg.tx_relay_daemon:
await h.close_wallet('source')
self.c = self.c2
h = xmr_rpc_methods(self,self.source)
@ -1513,45 +1561,13 @@ class MMGenToolCmdMonero(MMGenToolCmds):
except:
print(ret)
def fmtXMRamt(amt):
from .obj import XMRAmt
return XMRAmt(amt,from_unit='min_coin_unit').fmt(fs='5.12',color=True)
def hlXMRamt(amt):
from .obj import XMRAmt
return XMRAmt(amt,from_unit='min_coin_unit').hl()
def check_args(localvars):
def check_host_arg(arg_name,pat):
val = localvars[arg_name]
if not re.fullmatch(pat,val,re.ASCII):
annot = MMGenToolCmdMonero.xmrwallet.__annotations__[arg_name]
die(1,f'{val!r}: invalid {arg_name!r} parameter: it must have format {annot!r}')
if blockheight < 0:
die(1,f"{blockheight}: invalid 'blockheight' arg (<0)")
if op not in MoneroWalletOps.ops:
die(1,f'{op!r}: unrecognized operation')
if op == 'sync' and blockheight != 0:
die(1,'Sync operation does not support blockheight arg')
if daemon:
check_host_arg('daemon',host_pat)
if tx_relay_daemon:
if not getattr(MoneroWalletOps,op).tx_relay:
die(1,f"'tx_relay_daemon' arg is not recognized for operation {op!r}")
check_host_arg('tx_relay_daemon',hostproxy_pat)
# start execution
host_pat = r'(?:[^:]+):(?:\d+)'
hostproxy_pat = r'({p})(?::({p}))?'.format(p=host_pat)
check_args(locals())
if op not in MoneroWalletOps.ops:
die(1,f'{op!r}: unrecognized operation')
m = getattr(MoneroWalletOps,op)()
m = getattr(MoneroWalletOps,op)(
_create_argtuple( MMGenToolCmdMonero.xmrwallet, locals() )
)
try:
if run_session(m.process_wallets()):