async def connection(self, ws): data = {"service": self.service_name} payload = create_payload("register_service", data, self.service_name, "daemon") await ws.send_str(payload) while True: msg = await ws.receive() if msg.type == aiohttp.WSMsgType.TEXT: message = msg.data.strip() # self.log.info(f"received message: {message}") await self.safe_handle(ws, message) elif msg.type == aiohttp.WSMsgType.BINARY: self.log.debug("Received binary data") elif msg.type == aiohttp.WSMsgType.PING: self.log.debug("Ping received") await ws.pong() elif msg.type == aiohttp.WSMsgType.PONG: self.log.debug("Pong received") else: if msg.type == aiohttp.WSMsgType.CLOSE: self.log.debug("Closing RPC websocket") await ws.close() elif msg.type == aiohttp.WSMsgType.ERROR: self.log.error("Error during receive %s" % ws.exception()) elif msg.type == aiohttp.WSMsgType.CLOSED: pass break await ws.close()
async def _state_changed(self, service: str, state: str): if service not in self.connections: return message = None websockets = self.connections[service] if service == service_plotter: message = { "state": state, "queue": self.extract_plot_queue(), } if message is None: return response = create_payload("state_changed", message, service, "wallet_ui") for websocket in websockets: try: await websocket.send(response) except Exception as e: tb = traceback.format_exc() self.log.error(f"Unexpected exception trying to send to websocket: {e} {tb}") websockets.remove(websocket) await websocket.close()
async def _state_changed(self, service: str, message: Dict[str, Any]): """If id is None, send the whole state queue""" if service not in self.connections: return None websockets = self.connections[service] if message is None: return None response = create_payload("state_changed", message, service, "wallet_ui") for websocket in websockets: try: await websocket.send(response) except Exception as e: tb = traceback.format_exc() self.log.error(f"Unexpected exception trying to send to websocket: {e} {tb}") websockets.remove(websocket) await websocket.close()
async def _keyring_status_changed(self, keyring_status: Dict[str, Any], destination: str): """ Attempt to communicate with the GUI to inform it of any keyring status changes (e.g. keyring becomes unlocked or migration completes) """ websockets = self.connections.get("wallet_ui", None) if websockets is None: return None if keyring_status is None: return None response = create_payload("keyring_status_changed", keyring_status, "daemon", destination) for websocket in websockets: try: await websocket.send(response) except Exception as e: tb = traceback.format_exc() self.log.error(f"Unexpected exception trying to send to websocket: {e} {tb}") websockets.remove(websocket) await websocket.close()
async def test_daemon_simulation(self, simulation, get_daemon): node1, node2, _, _, _, _, _, _, _, server1 = simulation await server1.start_client(PeerInfo(self_hostname, uint16(21238))) async def num_connections(): count = len(node2.server.connection_by_type[NodeType.FULL_NODE].items()) return count await time_out_assert_custom_interval(60, 1, num_connections, 1) await time_out_assert(1500, node_height_at_least, True, node2, 1) session = aiohttp.ClientSession() ssl_context = b_tools.get_daemon_ssl_context() ws = await session.ws_connect( "wss://127.0.0.1:55401", autoclose=True, autoping=True, heartbeat=60, ssl_context=ssl_context, max_msg_size=100 * 1024 * 1024, ) service_name = "test_service_name" data = {"service": service_name} payload = create_payload("register_service", data, service_name, "daemon") await ws.send_str(payload) message_queue = asyncio.Queue() async def reader(ws, queue): while True: msg = await ws.receive() if msg.type == aiohttp.WSMsgType.TEXT: message = msg.data.strip() message = json.loads(message) await queue.put(message) elif msg.type == aiohttp.WSMsgType.PING: await ws.pong() elif msg.type == aiohttp.WSMsgType.PONG: continue else: if msg.type == aiohttp.WSMsgType.CLOSE: await ws.close() elif msg.type == aiohttp.WSMsgType.ERROR: await ws.close() elif msg.type == aiohttp.WSMsgType.CLOSED: pass break read_handler = asyncio.create_task(reader(ws, message_queue)) data = {} payload = create_payload("get_blockchain_state", data, service_name, "chia_full_node") await ws.send_str(payload) await asyncio.sleep(5) blockchain_state_found = False while not message_queue.empty(): message = await message_queue.get() if message["command"] == "get_blockchain_state": blockchain_state_found = True await ws.close() read_handler.cancel() assert blockchain_state_found
async def test_validate_keyring_passphrase_rpc(self, get_daemon_with_temp_keyring): local_b_tools: BlockTools = get_daemon_with_temp_keyring keychain = local_b_tools.local_keychain # When: the keychain has a master passphrase set keychain.set_master_passphrase( current_passphrase=DEFAULT_PASSPHRASE_IF_NO_MASTER_PASSPHRASE, new_passphrase="the correct passphrase" ) async def check_success_case(response: aiohttp.http_websocket.WSMessage): # Expect: JSON response assert response.type == aiohttp.WSMsgType.TEXT message = json.loads(response.data.strip()) # Expect: daemon handled the request assert message["ack"] is True # Expect: success flag is set to True assert message["data"]["success"] is True async def check_bad_passphrase_case(response: aiohttp.http_websocket.WSMessage): # Expect: JSON response assert response.type == aiohttp.WSMsgType.TEXT message = json.loads(response.data.strip()) # Expect: daemon handled the request assert message["ack"] is True # Expect: success flag is set to False assert message["data"]["success"] is False async def check_missing_passphrase_case(response: aiohttp.http_websocket.WSMessage): # Expect: JSON response assert response.type == aiohttp.WSMsgType.TEXT message = json.loads(response.data.strip()) # Expect: daemon handled the request assert message["ack"] is True # Expect: success flag is set to False assert message["data"]["success"] is False # Expect: error string is set assert message["data"]["error"] == "missing key" async def check_empty_passphrase_case(response: aiohttp.http_websocket.WSMessage): # Expect: JSON response assert response.type == aiohttp.WSMsgType.TEXT message = json.loads(response.data.strip()) # Expect: daemon handled the request assert message["ack"] is True # Expect: success flag is set to False assert message["data"]["success"] is False async with aiohttp.ClientSession() as session: async with session.ws_connect( "wss://127.0.0.1:55401", autoclose=True, autoping=True, heartbeat=60, ssl=local_b_tools.get_daemon_ssl_context(), max_msg_size=52428800, ) as ws: # When: using the correct passphrase await ws.send_str( create_payload("validate_keyring_passphrase", {"key": "the correct passphrase"}, "test", "daemon") ) # Expect: validation succeeds await check_success_case(await ws.receive()) # When: using the wrong passphrase await ws.send_str( create_payload("validate_keyring_passphrase", {"key": "the wrong passphrase"}, "test", "daemon") ) # Expect: validation failure await check_bad_passphrase_case(await ws.receive()) # When: not including the passphrase in the payload await ws.send_str(create_payload("validate_keyring_passphrase", {}, "test", "daemon")) # Expect: validation failure await check_missing_passphrase_case(await ws.receive()) # When: including an empty passphrase in the payload await ws.send_str(create_payload("validate_keyring_passphrase", {"key": ""}, "test", "daemon")) # Expect: validation failure await check_empty_passphrase_case(await ws.receive())