Browse Source

rpc.py: improve host_path implementation

The MMGen Project 2 years ago
parent
commit
0b79234f48

+ 8 - 7
mmgen/base_proto/bitcoin/rpc.py

@@ -77,6 +77,7 @@ class BitcoinRPCClient(RPCClient,metaclass=AsyncInit):
 
 	auth_type = 'basic'
 	has_auth_cookie = True
+	wallet_path = '/'
 
 	async def __init__(self,proto,daemon,backend):
 
@@ -150,6 +151,13 @@ class BitcoinRPCClient(RPCClient,metaclass=AsyncInit):
 		if not self.chain == 'regtest':
 			await self.check_tracking_wallet()
 
+		# for regtest, wallet path must remain '/' until Carol’s user wallet has been created
+		if g.regtest_user:
+			self.wallet_path = f'/wallet/{g.regtest_user}'
+
+	def make_host_path(self,wallet):
+		return f'/wallet/{wallet}' if wallet else self.wallet_path
+
 	async def check_tracking_wallet(self,wallet_checked=[]):
 		if not wallet_checked:
 			wallets = await self.call('listwallets')
@@ -196,13 +204,6 @@ class BitcoinRPCClient(RPCClient,metaclass=AsyncInit):
 		fn = self.get_daemon_auth_cookie_fn()
 		return get_lines_from_file(fn,'cookie',quiet=True)[0] if os.access(fn,os.R_OK) else ''
 
-	@staticmethod
-	def make_host_path(wallet):
-		return (
-			'/wallet/{}'.format('bob' if g.bob else 'alice') if (g.bob or g.alice) else
-			'/wallet/{}'.format(wallet) if wallet else '/'
-		)
-
 	def info(self,info_id):
 
 		def segwit_is_active():

+ 3 - 0
mmgen/base_proto/ethereum/rpc.py

@@ -80,6 +80,9 @@ class EthereumRPCClient(RPCClient,metaclass=AsyncInit):
 			self.chainID = Int(ci,16)
 			self.chain = self.proto.chain_ids[self.chainID]
 
+	def make_host_path(self,wallet):
+		return ''
+
 	rpcmethods = (
 		'eth_blockNumber',
 		'eth_call',

+ 2 - 8
mmgen/base_proto/monero/rpc.py

@@ -18,7 +18,6 @@ class MoneroRPCClient(RPCClient):
 
 	auth_type = None
 	network_proto = 'https'
-	host_path = '/json_rpc'
 	verify_server = False
 
 	def __init__(self,host,port,user,passwd,test_connection=True,proxy=None,daemon=None):
@@ -49,7 +48,7 @@ class MoneroRPCClient(RPCClient):
 		return await self.process_http_resp(self.backend.run(
 			payload = {'id': 0, 'jsonrpc': '2.0', 'method': method, 'params': kwargs },
 			timeout = 3600, # allow enough time to sync ≈1,000,000 blocks
-			wallet = None
+			host_path = '/json_rpc'
 		))
 
 	rpcmethods = ( 'get_info', )
@@ -57,20 +56,15 @@ class MoneroRPCClient(RPCClient):
 class MoneroRPCClientRaw(MoneroRPCClient):
 
 	json_rpc = False
-	host_path = '/'
 
 	async def call(self,method,*params,**kwargs):
 		assert params == (), f'{type(self).__name__}.call() accepts keyword arguments only'
 		return await self.process_http_resp(self.backend.run(
 			payload = kwargs,
 			timeout = self.timeout,
-			wallet = method
+			host_path = f'/{method}'
 		))
 
-	@staticmethod
-	def make_host_path(arg):
-		return arg
-
 	async def do_stop_daemon(self,silent=False):
 		return await self.call('stop_daemon')
 

+ 13 - 19
mmgen/rpc.py

@@ -102,10 +102,9 @@ class RPCBackends:
 			self.host           = caller.host
 			self.port           = caller.port
 			self.proxy          = caller.proxy
-			self.url            = caller.url
+			self.host_url       = caller.host_url
 			self.timeout        = caller.timeout
 			self.http_hdrs      = caller.http_hdrs
-			self.make_host_path = caller.make_host_path
 			self.name           = type(self).__name__
 
 	class aiohttp(base):
@@ -124,10 +123,10 @@ class RPCBackends:
 			else:
 				self.auth = None
 
-		async def run(self,payload,timeout,wallet):
+		async def run(self,payload,timeout,host_path):
 			dmsg_rpc('\n    RPC PAYLOAD data (aiohttp) ==>\n{}\n',payload)
 			async with self.session.post(
-				url     = self.url + self.make_host_path(wallet),
+				url     = self.host_url + host_path,
 				auth    = self.auth,
 				data    = json.dumps(payload,cls=json_encoder),
 				timeout = timeout or self.timeout,
@@ -155,10 +154,10 @@ class RPCBackends:
 					'https': f'socks5h://{self.proxy}'
 				})
 
-		async def run(self,payload,timeout,wallet):
+		async def run(self,payload,timeout,host_path):
 			dmsg_rpc('\n    RPC PAYLOAD data (requests) ==>\n{}\n',payload)
 			res = self.session.post(
-				url     = self.url + self.make_host_path(wallet),
+				url     = self.host_url + host_path,
 				data    = json.dumps(payload,cls=json_encoder),
 				timeout = timeout or self.timeout,
 				verify  = False )
@@ -184,7 +183,7 @@ class RPCBackends:
 					'',
 					auth_str_b64 ))
 
-		async def run(self,payload,timeout,wallet):
+		async def run(self,payload,timeout,host_path):
 			dmsg_rpc('\n    RPC PAYLOAD data (httplib) ==>\n{}\n',payload)
 
 			if timeout:
@@ -196,7 +195,7 @@ class RPCBackends:
 			try:
 				s.request(
 					method  = 'POST',
-					url     = self.make_host_path(wallet),
+					url     = host_path,
 					body    = json.dumps(payload,cls=json_encoder),
 					headers = self.http_hdrs )
 				r = s.getresponse() # => http.client.HTTPResponse instance
@@ -234,7 +233,7 @@ class RPCBackends:
 			self.exec_opts = list(gen_opts()) + ['--silent']
 			self.arg_max = 8192 # set way below system ARG_MAX, just to be safe
 
-		async def run(self,payload,timeout,wallet):
+		async def run(self,payload,timeout,host_path):
 			data = json.dumps(payload,cls=json_encoder)
 			if len(data) > self.arg_max:
 				return self.httplib(payload,timeout=timeout)
@@ -245,7 +244,7 @@ class RPCBackends:
 				'--connect-timeout', str(timeout or self.timeout),
 				'--write-out', '%{http_code}',
 				'--data-binary', data
-				] + self.exec_opts + [self.url + self.make_host_path(wallet)]
+				] + self.exec_opts + [self.host_url + host_path]
 
 			dmsg_rpc('    RPC curl exec data ==>\n{}\n',exec_cmd)
 
@@ -262,7 +261,6 @@ class RPCClient(MMGenObject):
 	auth_type = None
 	has_auth_cookie = False
 	network_proto = 'http'
-	host_path = ''
 	proxy = None
 
 	def __init__(self,host,port,test_connection=True):
@@ -282,16 +280,12 @@ class RPCClient(MMGenObject):
 				die( 'SocketError', f'Unable to connect to {host}:{port}' )
 
 		self.http_hdrs = { 'Content-Type': 'application/json' }
-		self.url = f'{self.network_proto}://{host}:{port}{self.host_path}'
+		self.host_url = f'{self.network_proto}://{host}:{port}'
 		self.host = host
 		self.port = port
 		self.timeout = g.http_timeout
 		self.auth = None
 
-	@staticmethod
-	def make_host_path(foo):
-		return ''
-
 	def set_backend(self,backend=None):
 		bn = backend or opt.rpc_backend
 		if bn == 'auto':
@@ -336,7 +330,7 @@ class RPCClient(MMGenObject):
 		return await self.process_http_resp(self.backend.run(
 			payload = {'id': 1, 'jsonrpc': '2.0', 'method': method, 'params': params },
 			timeout = timeout,
-			wallet  = wallet
+			host_path = self.make_host_path(wallet)
 		))
 
 	async def batch_call(self,method,param_list,timeout=None,wallet=None):
@@ -351,7 +345,7 @@ class RPCClient(MMGenObject):
 				'method': method,
 				'params': params } for n,params in enumerate(param_list,1) ],
 			timeout = timeout,
-			wallet  = wallet
+			host_path = self.make_host_path(wallet)
 		),batch=True)
 
 	async def gathered_call(self,method,args_list,timeout=None,wallet=None):
@@ -371,7 +365,7 @@ class RPCClient(MMGenObject):
 			tasks = [self.process_http_resp(self.backend.run(
 						payload = {'id': n, 'jsonrpc': '2.0', 'method': method, 'params': params },
 						timeout = timeout,
-						wallet  = wallet
+						host_path = self.make_host_path(wallet)
 					)) for n,(method,params)  in enumerate(cmd_list[cur_pos:chunk_size+cur_pos],1)]
 			ret.extend(await asyncio.gather(*tasks))
 			cur_pos += chunk_size

+ 24 - 1
test/unit_tests_d/ut_rpc.py

@@ -8,7 +8,7 @@ from mmgen.common import *
 from mmgen.protocol import init_proto
 from mmgen.rpc import rpc_init
 from mmgen.daemon import CoinDaemon
-from mmgen.base_proto.monero.rpc import MoneroWalletRPCClient
+from mmgen.base_proto.monero.rpc import MoneroRPCClient,MoneroRPCClientRaw,MoneroWalletRPCClient
 from mmgen.base_proto.monero.daemon import MoneroWalletDaemon
 
 def cfg_file_auth_test(proto,d):
@@ -147,6 +147,26 @@ class unit_tests:
 
 	def xmrwallet(self,name,ut):
 
+		async def test_monerod_rpc(md):
+			md_rpc = MoneroRPCClientRaw(
+				host   = md.host,
+				port   = md.rpc_port,
+				user   = None,
+				passwd = None,
+				test_connection = False,
+				daemon = md,
+			)
+			md_json_rpc = MoneroRPCClient(
+				host   = md.host,
+				port   = md.rpc_port,
+				user   = None,
+				passwd = None,
+				test_connection = False,
+				daemon = md,
+			)
+			await md_rpc.call('get_height')
+			await md_json_rpc.call('get_last_block_header')
+
 		async def run():
 			networks = init_proto('xmr').networks
 			daemons = [(
@@ -162,6 +182,9 @@ class unit_tests:
 				if not opt.no_daemon_autostart:
 					md.start()
 				wd.start()
+
+				await test_monerod_rpc(md)
+
 				c = MoneroWalletRPCClient(daemon=wd)
 				fn = f'monero-{wd.network}-junk-wallet'
 				qmsg(f'Creating {wd.network} wallet')