stop Monero coin and wallet daemons via RPC
This commit is contained in:
parent
236592c3a6
commit
35f9201174
8 changed files with 89 additions and 32 deletions
|
|
@ -306,6 +306,9 @@ class MoneroWalletDaemon(RPCDaemon):
|
|||
['--stagenet', self.network == 'testnet'],
|
||||
)
|
||||
|
||||
from .rpc import MoneroWalletRPCClient
|
||||
self.rpc = MoneroWalletRPCClient( daemon=self, test_connection=False )
|
||||
|
||||
class CoinDaemon(Daemon):
|
||||
networks = ('mainnet','testnet','regtest')
|
||||
cfg_file_hdr = ''
|
||||
|
|
@ -622,6 +625,15 @@ class monero_daemon(CoinDaemon):
|
|||
|
||||
def init_subclass(self):
|
||||
|
||||
from .rpc import MoneroRPCClientRaw
|
||||
self.rpc = MoneroRPCClientRaw(
|
||||
host = self.host,
|
||||
port = self.rpc_port,
|
||||
user = None,
|
||||
passwd = None,
|
||||
test_connection = False,
|
||||
daemon = self )
|
||||
|
||||
self.shared_args = list_gen(
|
||||
[f'--no-zmq'],
|
||||
[f'--p2p-bind-port={self.p2p_port}', self.p2p_port],
|
||||
|
|
|
|||
|
|
@ -234,4 +234,4 @@ try:
|
|||
except KeyboardInterrupt:
|
||||
ymsg('\nUser interrupt')
|
||||
finally:
|
||||
m.stop_daemons()
|
||||
run_session(m.stop_wallet_daemon())
|
||||
|
|
|
|||
32
mmgen/rpc.py
32
mmgen/rpc.py
|
|
@ -403,6 +403,23 @@ class RPCClient(MMGenObject):
|
|||
except: m = text
|
||||
raise RPCFailure(f'{s.value} {s.name}: {m}')
|
||||
|
||||
async def stop_daemon(self,quiet=False,silent=False):
|
||||
if self.daemon.state == 'ready':
|
||||
if not (quiet or silent):
|
||||
msg(f'Stopping {self.daemon.desc} on port {self.daemon.bind_port}')
|
||||
ret = await self.do_stop_daemon(silent=silent)
|
||||
if self.daemon.wait:
|
||||
self.daemon.wait_for_state('stopped')
|
||||
return ret
|
||||
else:
|
||||
if not (quiet or silent):
|
||||
msg(f'{self.daemon.desc} on port {self.daemon.bind_port} not running')
|
||||
return True
|
||||
|
||||
async def restart_daemon(self,quiet=False,silent=False):
|
||||
await self.stop_daemon(quiet=quiet,silent=silent)
|
||||
return self.daemon.start(silent=silent)
|
||||
|
||||
class BitcoinRPCClient(RPCClient,metaclass=AsyncInit):
|
||||
|
||||
auth_type = 'basic'
|
||||
|
|
@ -657,7 +674,7 @@ class MoneroRPCClient(RPCClient):
|
|||
host_path = '/json_rpc'
|
||||
verify_server = False
|
||||
|
||||
def __init__(self,host,port,user,passwd,test_connection=True,proxy=None):
|
||||
def __init__(self,host,port,user,passwd,test_connection=True,proxy=None,daemon=None):
|
||||
if proxy is not None:
|
||||
from .obj import IPPort
|
||||
self.proxy = IPPort(proxy)
|
||||
|
|
@ -673,6 +690,7 @@ class MoneroRPCClient(RPCClient):
|
|||
self.set_backend('curl')
|
||||
self.backend.exec_opts.remove('--silent')
|
||||
self.backend.exec_opts.append('--verbose')
|
||||
self.daemon = daemon
|
||||
|
||||
async def call(self,method,*params,**kwargs):
|
||||
assert params == (), f'{type(self).__name__}.call() accepts keyword arguments only'
|
||||
|
|
@ -701,7 +719,10 @@ class MoneroRPCClientRaw(MoneroRPCClient):
|
|||
def make_host_path(arg):
|
||||
return arg
|
||||
|
||||
rpcmethods = ( 'get_height', 'send_raw_transaction' )
|
||||
async def do_stop_daemon(self,silent=False):
|
||||
return await self.call('stop_daemon')
|
||||
|
||||
rpcmethods = ( 'get_height', 'send_raw_transaction', 'stop_daemon' )
|
||||
|
||||
class MoneroWalletRPCClient(MoneroRPCClient):
|
||||
|
||||
|
|
@ -731,6 +752,13 @@ class MoneroWalletRPCClient(MoneroRPCClient):
|
|||
'refresh', # start_height
|
||||
)
|
||||
|
||||
async def do_stop_daemon(self,silent=False):
|
||||
"""
|
||||
NB: the 'stop_wallet' RPC call closes the open wallet before shutting down the daemon,
|
||||
returning an error if no wallet is open
|
||||
"""
|
||||
return await self.call('stop_wallet')
|
||||
|
||||
class daemon_warning(oneshot_warning_group):
|
||||
|
||||
class geth:
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ class MoneroWalletOps:
|
|||
def post_main(self):
|
||||
pass
|
||||
|
||||
def stop_daemons(self): pass
|
||||
async def stop_wallet_daemon(self):
|
||||
pass
|
||||
|
||||
class wallet(base):
|
||||
|
||||
|
|
@ -338,10 +339,10 @@ class MoneroWalletOps:
|
|||
daemon_addr = uopt.daemon or None,
|
||||
)
|
||||
|
||||
if not uopt.no_start_wallet_daemon:
|
||||
self.wd.restart()
|
||||
self.c = MoneroWalletRPCClient(daemon=self.wd,test_connection=False)
|
||||
|
||||
self.c = MoneroWalletRPCClient(daemon=self.wd)
|
||||
if not uopt.no_start_wallet_daemon:
|
||||
run_session(self.c.restart_daemon())
|
||||
|
||||
def create_addr_data(self):
|
||||
if uarg.wallets:
|
||||
|
|
@ -352,11 +353,9 @@ class MoneroWalletOps:
|
|||
else:
|
||||
self.addr_data = self.kal.data
|
||||
|
||||
def stop_daemons(self):
|
||||
async def stop_wallet_daemon(self):
|
||||
if not uopt.no_stop_wallet_daemon:
|
||||
self.wd.stop()
|
||||
if uopt.tx_relay_daemon and hasattr(self,'wd2'):
|
||||
self.wd2.stop()
|
||||
await self.c.stop_daemon()
|
||||
|
||||
def get_wallet_fn(self,d):
|
||||
return os.path.join(
|
||||
|
|
@ -415,6 +414,12 @@ class MoneroWalletOps:
|
|||
await self.c.call('close_wallet')
|
||||
gmsg_r('done')
|
||||
|
||||
async def stop_wallet(self,desc):
|
||||
msg(f'Stopping {self.c.daemon.desc} on port {self.c.daemon.bind_port}')
|
||||
gmsg_r(f'\n Stopping {desc} wallet...')
|
||||
await self.c.stop_daemon(quiet=True) # closes wallet
|
||||
gmsg_r('done')
|
||||
|
||||
def print_accts(self,data,addrs_data,indent=' '):
|
||||
d = data['subaddress_accounts']
|
||||
msg('\n' + indent + f'Accounts of wallet {os.path.basename(self.fn)}:')
|
||||
|
|
@ -658,7 +663,9 @@ class MoneroWalletOps:
|
|||
t_elapsed // 60,
|
||||
t_elapsed % 60 ))
|
||||
|
||||
await self.c.call('close_wallet')
|
||||
if not last:
|
||||
await self.c.call('close_wallet')
|
||||
|
||||
return wallet_height >= chain_height
|
||||
|
||||
def post_main(self):
|
||||
|
|
@ -724,20 +731,19 @@ class MoneroWalletOps:
|
|||
|
||||
m = re.fullmatch(uarg_info['tx_relay_daemon'].pat,uopt.tx_relay_daemon,re.ASCII)
|
||||
|
||||
self.wd2 = MoneroWalletDaemon(
|
||||
wd2 = MoneroWalletDaemon(
|
||||
proto = self.proto,
|
||||
wallet_dir = uopt.wallet_dir or '.',
|
||||
test_suite = g.test_suite,
|
||||
daemon_addr = m[1],
|
||||
proxy = m[2],
|
||||
port_shift = 16 )
|
||||
proxy = m[2] )
|
||||
|
||||
if g.test_suite:
|
||||
self.wd2.usr_daemon_args = ['--daemon-ssl-allow-any-cert']
|
||||
wd2.usr_daemon_args = ['--daemon-ssl-allow-any-cert']
|
||||
|
||||
self.wd2.start()
|
||||
wd2.start()
|
||||
|
||||
self.c = MoneroWalletRPCClient(daemon=self.wd2)
|
||||
self.c = MoneroWalletRPCClient(daemon=wd2)
|
||||
|
||||
async def main(self):
|
||||
gmsg(f'\n{self.desc}ing account #{self.account} of wallet {self.source.idx}' + (
|
||||
|
|
@ -808,7 +814,7 @@ class MoneroWalletOps:
|
|||
elif keypress_confirm(f'Relay {self.name} transaction?'):
|
||||
w_desc = 'source'
|
||||
if uopt.tx_relay_daemon:
|
||||
await h.close_wallet('source')
|
||||
await h.stop_wallet('source')
|
||||
msg('')
|
||||
self.init_tx_relay_daemon()
|
||||
h = self.rpc(self,self.source)
|
||||
|
|
@ -816,11 +822,9 @@ class MoneroWalletOps:
|
|||
await h.open_wallet(w_desc,refresh=False)
|
||||
msg_r(f'\n Relaying {self.name} transaction...')
|
||||
await h.relay_tx(new_tx.data.metadata)
|
||||
await h.close_wallet(w_desc)
|
||||
|
||||
gmsg('\n\nAll done')
|
||||
else:
|
||||
await h.close_wallet('source')
|
||||
die(1,'\nExiting at user request')
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -55,7 +55,10 @@ def run(network_id=None,proto=None,daemon_id=None):
|
|||
for cmd in d.start_cmds if action == 'start' else [d.stop_cmd]:
|
||||
print(' '.join(cmd))
|
||||
else:
|
||||
d.cmd(action,quiet=opt.quiet)
|
||||
if action == 'stop' and hasattr(d,'rpc'):
|
||||
run_session(d.rpc.stop_daemon(quiet=opt.quiet))
|
||||
else:
|
||||
d.cmd(action,quiet=opt.quiet)
|
||||
|
||||
if 'all' in cmd_args or 'no_xmr' in cmd_args:
|
||||
if len(cmd_args) != 1:
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ class TestSuiteXMRWallet(TestSuiteBase):
|
|||
user = None,
|
||||
passwd = None,
|
||||
test_connection = False,
|
||||
daemon = md,
|
||||
)
|
||||
md_json_rpc = MoneroRPCClient(
|
||||
host = md.host,
|
||||
|
|
@ -228,6 +229,7 @@ class TestSuiteXMRWallet(TestSuiteBase):
|
|||
user = None,
|
||||
passwd = None,
|
||||
test_connection = False,
|
||||
daemon = md,
|
||||
)
|
||||
wd = MoneroWalletDaemon(
|
||||
proto = self.proto,
|
||||
|
|
@ -659,11 +661,7 @@ class TestSuiteXMRWallet(TestSuiteBase):
|
|||
|
||||
def stop_daemons(self):
|
||||
for v in self.users.values():
|
||||
if v.md.state != 'stopped':
|
||||
v.md.stop()
|
||||
|
||||
def start_wallet_daemons(self):
|
||||
self.users['miner'].wd.start()
|
||||
run_session(v.md_rpc.stop_daemon())
|
||||
|
||||
def stop_miner_wallet_daemon(self):
|
||||
self.users['miner'].wd.stop()
|
||||
run_session(self.users['miner'].wd_rpc.stop_daemon())
|
||||
|
|
|
|||
|
|
@ -82,7 +82,10 @@ def test_cmds(op):
|
|||
else:
|
||||
if opt.quiet:
|
||||
msg_r('.')
|
||||
getattr(d,op)(silent=opt.quiet)
|
||||
if op == 'stop' and hasattr(d,'rpc'):
|
||||
run_session(d.rpc.stop_daemon(quiet=opt.quiet))
|
||||
else:
|
||||
getattr(d,op)(silent=opt.quiet)
|
||||
|
||||
class unit_tests:
|
||||
|
||||
|
|
|
|||
|
|
@ -125,17 +125,26 @@ class unit_tests:
|
|||
md.start()
|
||||
wd.start()
|
||||
c = MoneroWalletRPCClient(daemon=wd)
|
||||
await c.call('get_version')
|
||||
fn = f'monero-{wd.network}-junk-wallet'
|
||||
qmsg(f'Creating {wd.network} wallet')
|
||||
await c.call(
|
||||
'restore_deterministic_wallet',
|
||||
filename = fn,
|
||||
password = 'foo',
|
||||
seed = baseconv.fromhex('beadface'*8,'xmrseed',tostr=True) )
|
||||
qmsg(f'Opening {wd.network} wallet')
|
||||
await c.call( 'open_wallet', filename=fn, password='foo' )
|
||||
|
||||
for md,wd in daemons:
|
||||
wd.wait = False
|
||||
wd.stop()
|
||||
await wd.rpc.stop_daemon()
|
||||
if not opt.no_daemon_stop:
|
||||
md.wait = False
|
||||
md.stop()
|
||||
await md.rpc.stop_daemon()
|
||||
|
||||
gmsg('OK')
|
||||
|
||||
from mmgen.baseconv import baseconv
|
||||
import shutil
|
||||
shutil.rmtree('test/trash2',ignore_errors=True)
|
||||
os.makedirs('test/trash2')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue