Browse Source

daemon.py: add RPCDaemon class, related fixes, cleanups

The MMGen Project 3 years ago
parent
commit
13f2bf597b
5 changed files with 72 additions and 57 deletions
  1. 29 20
      mmgen/daemon.py
  2. 6 0
      mmgen/protocol.py
  3. 8 9
      mmgen/xmrwallet.py
  4. 3 4
      test/test_py_d/ts_xmrwallet.py
  5. 26 24
      test/unit_tests_d/ut_rpc.py

+ 29 - 20
mmgen/daemon.py

@@ -243,14 +243,26 @@ class Daemon(MMGenObject):
 			else:
 			else:
 				msg(f'Cannot remove {self.datadir!r} - daemon is not stopped')
 				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'
 	exec_fn = 'monero-wallet-rpc'
 	coin = 'XMR'
 	coin = 'XMR'
 	new_console_mswin = True
 	new_console_mswin = True
 	ps_pid_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,
 			test_suite  = False,
 			host        = None,
 			host        = None,
 			user        = None,
 			user        = None,
@@ -258,20 +270,20 @@ class MoneroWalletDaemon(Daemon):
 			daemon_addr = None,
 			daemon_addr = None,
 			proxy       = None,
 			proxy       = None,
 			port_shift  = None,
 			port_shift  = None,
-			datadir     = None,
-			testnet     = False ):
+			datadir     = None ):
+
+		self.proto = proto
+		self.test_suite = test_suite
 
 
 		super().__init__()
 		super().__init__()
+
+		self.network = proto.network
 		self.platform = g.platform
 		self.platform = g.platform
 		self.wallet_dir = wallet_dir
 		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:
 		if port_shift:
 			self.rpc_port += 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}'
 		id_str = f'{self.exec_fn}-{self.bind_port}'
 		self.datadir = os.path.join(datadir or ('','test')[test_suite], self.exec_fn)
 		self.datadir = os.path.join(datadir or ('','test')[test_suite], self.exec_fn)
 		self.pidfile = os.path.join(self.datadir,id_str+'.pid')
 		self.pidfile = os.path.join(self.datadir,id_str+'.pid')
@@ -279,7 +291,7 @@ class MoneroWalletDaemon(Daemon):
 
 
 		self.proxy = proxy
 		self.proxy = proxy
 		self.daemon_addr = daemon_addr
 		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':
 		if self.platform == 'win':
 			self.use_pidfile = False
 			self.use_pidfile = False
@@ -308,7 +320,7 @@ class MoneroWalletDaemon(Daemon):
 			[f'--proxy={self.proxy}',                self.proxy],
 			[f'--proxy={self.proxy}',                self.proxy],
 			[f'--pidfile={self.pidfile}',            self.platform == 'linux'],
 			[f'--pidfile={self.pidfile}',            self.platform == 'linux'],
 			['--detach',                             not 'no_daemonize' in self.opts],
 			['--detach',                             not 'no_daemonize' in self.opts],
-			['--stagenet',                           testnet],
+			['--stagenet',                           self.network == 'testnet'],
 		)
 		)
 
 
 		self.usr_daemon_args = []
 		self.usr_daemon_args = []
@@ -376,7 +388,6 @@ class CoinDaemon(Daemon):
 		me = Daemon.__new__(globals()[daemon_id + '_daemon'])
 		me = Daemon.__new__(globals()[daemon_id + '_daemon'])
 		assert network in me.networks, f'{network!r}: unsupported network for daemon {daemon_id}'
 		assert network in me.networks, f'{network!r}: unsupported network for daemon {daemon_id}'
 		me.network = network
 		me.network = network
-		me.network_id = network_id
 		me.coin = coin
 		me.coin = coin
 		me.coin_name = cls.coins[coin].coin_name
 		me.coin_name = cls.coins[coin].coin_name
 		me.id = daemon_id
 		me.id = daemon_id
@@ -449,7 +460,10 @@ class CoinDaemon(Daemon):
 		self.init_rpc_port(test_suite,port_shift)
 		self.init_rpc_port(test_suite,port_shift)
 
 
 		self.pidfile = '{}/{}-daemon-{}.pid'.format(self.datadir,self.network,self.rpc_port)
 		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()
 		self.subclass_init()
 
 
 	def init_rpc_port(self,test_suite,port_shift):
 	def init_rpc_port(self,test_suite,port_shift):
@@ -578,19 +592,14 @@ class monero_daemon(CoinDaemon):
 	}
 	}
 
 
 	def subclass_init(self):
 	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':
 		if self.platform == 'win':
 			self.use_pidfile = False
 			self.use_pidfile = False
 
 
 		self.shared_args = list_gen(
 		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'--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'],
 			['--stagenet', self.network == 'testnet'],
 		)
 		)
 
 

+ 6 - 0
mmgen/protocol.py

@@ -68,6 +68,7 @@ def _b58chk_decode(s):
 	return out[:-4]
 	return out[:-4]
 
 
 _finfo = namedtuple('fork_info',['height','hash','name','replayable'])
 _finfo = namedtuple('fork_info',['height','hash','name','replayable'])
+_nw = namedtuple('coin_networks',['mainnet','testnet','regtest'])
 
 
 class CoinProtocol(MMGenObject):
 class CoinProtocol(MMGenObject):
 
 
@@ -96,6 +97,7 @@ class CoinProtocol(MMGenObject):
 			self.cls_name   = type(self).__name__
 			self.cls_name   = type(self).__name__
 			self.testnet    = network in ('testnet','regtest')
 			self.testnet    = network in ('testnet','regtest')
 			self.regtest    = network == '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() + {
 			self.network_id = coin.lower() + {
 				'mainnet': '',
 				'mainnet': '',
 				'testnet': '_tn',
 				'testnet': '_tn',
@@ -204,6 +206,7 @@ class CoinProtocol(MMGenObject):
 		All Bitcoin code and chain forks inherit from this class
 		All Bitcoin code and chain forks inherit from this class
 		"""
 		"""
 		mod_clsname     = 'Bitcoin'
 		mod_clsname     = 'Bitcoin'
+		network_names   = _nw('mainnet','testnet','regtest')
 		addr_ver_bytes  = { '00': 'p2pkh', '05': 'p2sh' }
 		addr_ver_bytes  = { '00': 'p2pkh', '05': 'p2sh' }
 		addr_len        = 20
 		addr_len        = 20
 		wif_ver_num     = { 'std': '80' }
 		wif_ver_num     = { 'std': '80' }
@@ -376,6 +379,7 @@ class CoinProtocol(MMGenObject):
 
 
 	class Ethereum(DummyWIF,Secp256k1):
 	class Ethereum(DummyWIF,Secp256k1):
 
 
+		network_names = _nw('mainnet','testnet','devnet')
 		addr_len      = 20
 		addr_len      = 20
 		mmtypes       = ('E',)
 		mmtypes       = ('E',)
 		dfl_mmtype    = 'E'
 		dfl_mmtype    = 'E'
@@ -460,6 +464,8 @@ class CoinProtocol(MMGenObject):
 
 
 	# https://github.com/monero-project/monero/blob/master/src/cryptonote_config.h
 	# https://github.com/monero-project/monero/blob/master/src/cryptonote_config.h
 	class Monero(DummyWIF,Base):
 	class Monero(DummyWIF,Base):
+
+		network_names  = _nw('mainnet','stagenet',None)
 		base_coin      = 'XMR'
 		base_coin      = 'XMR'
 		addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub' }
 		addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub' }
 		addr_len       = 68
 		addr_len       = 68

+ 8 - 9
mmgen/xmrwallet.py

@@ -331,10 +331,10 @@ class MoneroWalletOps:
 			check_wallets()
 			check_wallets()
 
 
 			self.wd = MoneroWalletDaemon(
 			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,
 				daemon_addr = uopt.daemon or None,
-				testnet = g.testnet,
 			)
 			)
 
 
 			if not uopt.no_start_wallet_daemon:
 			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)
 			m = re.fullmatch(uarg_info['tx_relay_daemon'].pat,uopt.tx_relay_daemon,re.ASCII)
 
 
 			self.wd2 = MoneroWalletDaemon(
 			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],
 				daemon_addr = m[1],
-				proxy = m[2],
-				port_shift = 16,
-				testnet = g.testnet,
-			)
+				proxy       = m[2],
+				port_shift  = 16 )
 
 
 			if g.test_suite:
 			if g.test_suite:
 				self.wd2.usr_daemon_args = ['--daemon-ssl-allow-any-cert']
 				self.wd2.usr_daemon_args = ['--daemon-ssl-allow-any-cert']

+ 3 - 4
test/test_py_d/ts_xmrwallet.py

@@ -227,14 +227,13 @@ class TestSuiteXMRWallet(TestSuiteBase):
 				test_connection = False,
 				test_connection = False,
 			)
 			)
 			wd = MoneroWalletDaemon(
 			wd = MoneroWalletDaemon(
-				user = 'foo',
-				passwd = 'bar',
+				proto      = self.proto,
 				wallet_dir = udir,
 				wallet_dir = udir,
-				test_suite = True,
+				user       = 'foo',
+				passwd     = 'bar',
 				port_shift = shift,
 				port_shift = shift,
 				datadir    = os.path.join('test','daemons'),
 				datadir    = os.path.join('test','daemons'),
 				daemon_addr = f'127.0.0.1:{md.rpc_port}',
 				daemon_addr = f'127.0.0.1:{md.rpc_port}',
-				testnet = True
 			)
 			)
 			wd_rpc = MoneroWalletRPCClient(
 			wd_rpc = MoneroWalletRPCClient(
 				host   = wd.host,
 				host   = wd.host,

+ 26 - 24
test/unit_tests_d/ut_rpc.py

@@ -108,32 +108,34 @@ class unit_tests:
 	def xmr_wallet(self,name,ut):
 	def xmr_wallet(self,name,ut):
 
 
 		async def run():
 		async def run():
-			md = CoinDaemon('xmr',test_suite=True)
-			if not opt.no_daemon_autostart:
-				md.start()
-
-			wd = MoneroWalletDaemon(
-				wallet_dir = 'test/trash',
-				passwd     = 'ut_rpc_passw0rd',
-				test_suite = True )
-			wd.start()
-
-			c = MoneroWalletRPCClient(
-				host   = wd.host,
-				port   = wd.rpc_port,
-				user   = wd.user,
-				passwd = wd.passwd )
-
-			await c.call('get_version')
+			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) ]
+
+			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')
+
+			for md,wd in daemons:
+				wd.wait = False
+				wd.stop()
+				if not opt.no_daemon_stop:
+					md.wait = False
+					md.stop()
 
 
 			gmsg('OK')
 			gmsg('OK')
 
 
-			wd.wait = False
-			wd.stop()
-
-			if not opt.no_daemon_stop:
-				md.wait = False
-				md.stop()
-
 		run_session(run())
 		run_session(run())
 		return True
 		return True