# Copyright (c) 2016-2017, Neil Booth # # All rights reserved. # # See the file "LICENCE" for information about the copyright # and warranty status of this software. from aiorpcx import _version as aiorpcx_version import electrumx from electrumx.lib.server_base import ServerBase from electrumx.lib.tasks import Tasks from electrumx.lib.util import version_string from electrumx.server.chain_state import ChainState from electrumx.server.peers import PeerManager from electrumx.server.session import SessionManager class Controller(ServerBase): '''Manages server initialisation and stutdown. Servers are started once the mempool is synced after the block processor first catches up with the daemon. ''' AIORPCX_MIN = (0, 5, 6) def __init__(self, env): '''Initialize everything that doesn't require the event loop.''' super().__init__(env) if aiorpcx_version < self.AIORPCX_MIN: raise RuntimeError('ElectrumX requires aiorpcX >= ' f'{version_string(self.AIORPCX_MIN)}') min_str, max_str = env.coin.SESSIONCLS.protocol_min_max_strings() self.logger.info(f'software version: {electrumx.version}') self.logger.info(f'aiorpcX version: {version_string(aiorpcx_version)}') self.logger.info(f'supported protocol versions: {min_str}-{max_str}') self.logger.info(f'event loop policy: {env.loop_policy}') self.tasks = Tasks() self.chain_state = ChainState(env, self.tasks, self.shutdown_event) self.peer_mgr = PeerManager(env, self.tasks, self.chain_state) self.session_mgr = SessionManager(env, self.tasks, self.chain_state, self.peer_mgr) async def start_servers(self): '''Start the RPC server and wait for the mempool to synchronize. Then start the peer manager and serving external clients. ''' self.session_mgr.start_rpc_server() await self.chain_state.wait_for_mempool() self.peer_mgr.start_peer_discovery() self.session_mgr.start_serving() async def shutdown(self): '''Perform the shutdown sequence.''' # Not certain of ordering here self.tasks.cancel_all() await self.session_mgr.shutdown() await self.tasks.wait() # Finally shut down the block processor and executor (FIXME) self.chain_state.bp.shutdown(self.tasks.executor)