rpc.py: improve host_path implementation

This commit is contained in:
The MMGen Project 2022-05-28 19:41:43 +00:00
commit 0b79234f48
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
5 changed files with 50 additions and 35 deletions

View file

@ -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():

View file

@ -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',

View file

@ -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')

View file

@ -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

View file

@ -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')