From 13f2bf597b99eea99047c6114df7a85c6f7e3cc9 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 2 Aug 2021 19:47:41 +0000 Subject: [PATCH] daemon.py: add RPCDaemon class, related fixes, cleanups --- mmgen/daemon.py | 49 ++++++++++++++++++++-------------- mmgen/protocol.py | 6 +++++ mmgen/xmrwallet.py | 17 ++++++------ test/test_py_d/ts_xmrwallet.py | 7 +++-- test/unit_tests_d/ut_rpc.py | 46 ++++++++++++++++--------------- 5 files changed, 70 insertions(+), 55 deletions(-) diff --git a/mmgen/daemon.py b/mmgen/daemon.py index 35a3267b..f0d3797f 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -243,14 +243,26 @@ class Daemon(MMGenObject): else: msg(f'Cannot remove {self.datadir!r} - daemon is not stopped') -class MoneroWalletDaemon(Daemon): +class RPCDaemon(Daemon): + def __init__(self): + super().__init__() + self.desc = '{} {} {}RPC daemon'.format( + self.rpc_type, + getattr(self.proto.network_names,self.proto.network), + 'test suite ' if self.test_suite else '' ) + +class MoneroWalletDaemon(RPCDaemon): + + master_daemon = 'monero_daemon' + rpc_type = 'Monero wallet' exec_fn = 'monero-wallet-rpc' coin = 'XMR' new_console_mswin = True ps_pid_mswin = True + rpc_ports = _nw(13131, 13141, None) # testnet is non-standard - def __init__(self, wallet_dir, + def __init__(self, proto, wallet_dir, test_suite = False, host = None, user = None, @@ -258,20 +270,20 @@ class MoneroWalletDaemon(Daemon): daemon_addr = None, proxy = None, port_shift = None, - datadir = None, - testnet = False ): + datadir = None ): + + self.proto = proto + self.test_suite = test_suite super().__init__() + + self.network = proto.network self.platform = g.platform self.wallet_dir = wallet_dir - self.rpc_port = 13142 if test_suite else 13131 + self.rpc_port = getattr(self.rpc_ports,self.network) + (11 if test_suite else 0) if port_shift: self.rpc_port += port_shift - self.desc = 'Monero wallet {} {}RPC daemon'.format( - 'testnet' if testnet else 'mainnet', - 'test suite ' if test_suite else '' ) - id_str = f'{self.exec_fn}-{self.bind_port}' self.datadir = os.path.join(datadir or ('','test')[test_suite], self.exec_fn) self.pidfile = os.path.join(self.datadir,id_str+'.pid') @@ -279,7 +291,7 @@ class MoneroWalletDaemon(Daemon): self.proxy = proxy self.daemon_addr = daemon_addr - self.daemon_port = None if daemon_addr else CoinDaemon('xmr',test_suite=test_suite).rpc_port + self.daemon_port = None if daemon_addr else CoinDaemon(proto=proto,test_suite=test_suite).rpc_port if self.platform == 'win': self.use_pidfile = False @@ -308,7 +320,7 @@ class MoneroWalletDaemon(Daemon): [f'--proxy={self.proxy}', self.proxy], [f'--pidfile={self.pidfile}', self.platform == 'linux'], ['--detach', not 'no_daemonize' in self.opts], - ['--stagenet', testnet], + ['--stagenet', self.network == 'testnet'], ) self.usr_daemon_args = [] @@ -376,7 +388,6 @@ class CoinDaemon(Daemon): me = Daemon.__new__(globals()[daemon_id + '_daemon']) assert network in me.networks, f'{network!r}: unsupported network for daemon {daemon_id}' me.network = network - me.network_id = network_id me.coin = coin me.coin_name = cls.coins[coin].coin_name me.id = daemon_id @@ -449,7 +460,10 @@ class CoinDaemon(Daemon): self.init_rpc_port(test_suite,port_shift) self.pidfile = '{}/{}-daemon-{}.pid'.format(self.datadir,self.network,self.rpc_port) - self.desc = '{} {} {}daemon'.format(self.coind_name,self.network,'test suite ' if test_suite else '') + self.desc = '{} {} {}daemon'.format( + self.coind_name, + getattr(self.proto.network_names,self.network), + 'test suite ' if test_suite else '' ) self.subclass_init() def init_rpc_port(self,test_suite,port_shift): @@ -578,19 +592,14 @@ class monero_daemon(CoinDaemon): } def subclass_init(self): - if self.network == 'testnet': - self.desc = 'Monero stagenet {}daemon'.format('test suite ' if self.test_suite else '') - - self.p2p_port = self.rpc_port - 1 - self.zmq_port = self.rpc_port + 1 if self.platform == 'win': self.use_pidfile = False self.shared_args = list_gen( - [f'--p2p-bind-port={self.p2p_port}'], + [f'--p2p-bind-port={self.rpc_port-1}'], [f'--rpc-bind-port={self.rpc_port}'], - [f'--zmq-rpc-bind-port={self.zmq_port}'], + [f'--zmq-rpc-bind-port={self.rpc_port+1}'], ['--stagenet', self.network == 'testnet'], ) diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 85353dcd..3d168b1f 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -68,6 +68,7 @@ def _b58chk_decode(s): return out[:-4] _finfo = namedtuple('fork_info',['height','hash','name','replayable']) +_nw = namedtuple('coin_networks',['mainnet','testnet','regtest']) class CoinProtocol(MMGenObject): @@ -96,6 +97,7 @@ class CoinProtocol(MMGenObject): self.cls_name = type(self).__name__ self.testnet = network in ('testnet','regtest') self.regtest = network == 'regtest' + self.networks = tuple(k for k,v in self.network_names._asdict().items() if v) self.network_id = coin.lower() + { 'mainnet': '', 'testnet': '_tn', @@ -204,6 +206,7 @@ class CoinProtocol(MMGenObject): All Bitcoin code and chain forks inherit from this class """ mod_clsname = 'Bitcoin' + network_names = _nw('mainnet','testnet','regtest') addr_ver_bytes = { '00': 'p2pkh', '05': 'p2sh' } addr_len = 20 wif_ver_num = { 'std': '80' } @@ -376,6 +379,7 @@ class CoinProtocol(MMGenObject): class Ethereum(DummyWIF,Secp256k1): + network_names = _nw('mainnet','testnet','devnet') addr_len = 20 mmtypes = ('E',) dfl_mmtype = 'E' @@ -460,6 +464,8 @@ class CoinProtocol(MMGenObject): # https://github.com/monero-project/monero/blob/master/src/cryptonote_config.h class Monero(DummyWIF,Base): + + network_names = _nw('mainnet','stagenet',None) base_coin = 'XMR' addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub' } addr_len = 68 diff --git a/mmgen/xmrwallet.py b/mmgen/xmrwallet.py index a4e74c93..003cc9d2 100755 --- a/mmgen/xmrwallet.py +++ b/mmgen/xmrwallet.py @@ -331,10 +331,10 @@ class MoneroWalletOps: check_wallets() self.wd = MoneroWalletDaemon( - wallet_dir = uopt.wallet_dir or '.', - test_suite = g.test_suite, + proto = self.proto, + wallet_dir = uopt.wallet_dir or '.', + test_suite = g.test_suite, daemon_addr = uopt.daemon or None, - testnet = g.testnet, ) if not uopt.no_start_wallet_daemon: @@ -721,13 +721,12 @@ class MoneroWalletOps: m = re.fullmatch(uarg_info['tx_relay_daemon'].pat,uopt.tx_relay_daemon,re.ASCII) self.wd2 = MoneroWalletDaemon( - wallet_dir = uopt.wallet_dir or '.', - test_suite = g.test_suite, + proto = self.proto, + wallet_dir = uopt.wallet_dir or '.', + test_suite = g.test_suite, daemon_addr = m[1], - proxy = m[2], - port_shift = 16, - testnet = g.testnet, - ) + proxy = m[2], + port_shift = 16 ) if g.test_suite: self.wd2.usr_daemon_args = ['--daemon-ssl-allow-any-cert'] diff --git a/test/test_py_d/ts_xmrwallet.py b/test/test_py_d/ts_xmrwallet.py index 1d65129f..8806715d 100755 --- a/test/test_py_d/ts_xmrwallet.py +++ b/test/test_py_d/ts_xmrwallet.py @@ -227,14 +227,13 @@ class TestSuiteXMRWallet(TestSuiteBase): test_connection = False, ) wd = MoneroWalletDaemon( - user = 'foo', - passwd = 'bar', + proto = self.proto, wallet_dir = udir, - test_suite = True, + user = 'foo', + passwd = 'bar', port_shift = shift, datadir = os.path.join('test','daemons'), daemon_addr = f'127.0.0.1:{md.rpc_port}', - testnet = True ) wd_rpc = MoneroWalletRPCClient( host = wd.host, diff --git a/test/unit_tests_d/ut_rpc.py b/test/unit_tests_d/ut_rpc.py index bd52909c..c34064b9 100755 --- a/test/unit_tests_d/ut_rpc.py +++ b/test/unit_tests_d/ut_rpc.py @@ -108,32 +108,34 @@ class unit_tests: def xmr_wallet(self,name,ut): async def run(): - md = CoinDaemon('xmr',test_suite=True) - if not opt.no_daemon_autostart: - md.start() + networks = init_proto('xmr').networks + daemons = [( + CoinDaemon(proto=proto), + MoneroWalletDaemon( + proto = proto, + wallet_dir = 'test/trash', + passwd = 'ut_rpc_passw0rd' ) + ) for proto in (init_proto('xmr',network=network) for network in networks) ] - wd = MoneroWalletDaemon( - wallet_dir = 'test/trash', - passwd = 'ut_rpc_passw0rd', - test_suite = True ) - wd.start() + for md,wd in daemons: + if not opt.no_daemon_autostart: + md.start() + wd.start() + c = MoneroWalletRPCClient( + host = wd.host, + port = wd.rpc_port, + user = wd.user, + passwd = wd.passwd ) + await c.call('get_version') - c = MoneroWalletRPCClient( - host = wd.host, - port = wd.rpc_port, - user = wd.user, - passwd = wd.passwd ) - - await c.call('get_version') + for md,wd in daemons: + wd.wait = False + wd.stop() + if not opt.no_daemon_stop: + md.wait = False + md.stop() gmsg('OK') - wd.wait = False - wd.stop() - - if not opt.no_daemon_stop: - md.wait = False - md.stop() - run_session(run()) return True