async def _state_changed(self, *args):
        change = args[0]
        if self.websocket is None:
            return
        payloads: List[Dict] = await self.rpc_api._state_changed(*args)

        if change == "add_connection" or change == "close_connection":
            data = await self.get_connections({})
            if data is not None:

                payload = create_payload(
                    "get_connections",
                    data,
                    self.service_name,
                    "wallet_ui",
                    string=False,
                )
                payloads.append(payload)
        for payload in payloads:
            if "success" not in payload["data"]:
                payload["data"]["success"] = True
            try:
                await self.websocket.send_str(dict_to_json_str(payload))
            except Exception:
                tb = traceback.format_exc()
                self.log.warning(f"Sending data failed. Exception {tb}.")
Exemple #2
0
async def async_run_daemon(root_path):
    chia_init(root_path)
    config = load_config(root_path, "config.yaml")
    setproctitle("chia_daemon")
    initialize_logging("daemon", config["logging"], root_path)
    lockfile = singleton(daemon_launch_lock_path(root_path))
    crt_path = root_path / config["daemon_ssl"]["private_crt"]
    key_path = root_path / config["daemon_ssl"]["private_key"]
    ca_crt_path = root_path / config["private_ssl_ca"]["crt"]
    ca_key_path = root_path / config["private_ssl_ca"]["key"]
    sys.stdout.flush()
    json_msg = dict_to_json_str({
        "message": "cert_path",
        "success": True,
        "cert": f"{crt_path}",
        "key": f"{key_path}",
        "ca_crt": f"{ca_crt_path}",
    })
    sys.stdout.write("\n" + json_msg + "\n")
    sys.stdout.flush()
    if lockfile is None:
        print("daemon: already launching")
        return 2

    # TODO: clean this up, ensuring lockfile isn't removed until the listen port is open
    create_server_for_daemon(root_path)
    ws_server = WebSocketServer(root_path, ca_crt_path, ca_key_path, crt_path,
                                key_path)
    await ws_server.start()
Exemple #3
0
    async def message_for_service(self, message):
        destination = message["destination"]
        if destination in self.connections:
            socket = self.connections[destination]
            await socket.send(dict_to_json_str(message))

        return None
Exemple #4
0
    async def handle_message(
            self, websocket: WebSocketServerProtocol,
            message: Dict[str, Any]) -> Tuple[Optional[str], List[Any]]:
        """
        This function gets called when new message is received via websocket.
        """

        command = message["command"]
        destination = message["destination"]
        if destination != "daemon":
            destination = message["destination"]
            if destination in self.connections:
                sockets = self.connections[destination]
                return dict_to_json_str(message), sockets

            return None, []

        data = None
        if "data" in message:
            data = message["data"]

        commands_with_data = [
            "start_service",
            "start_plotting",
            "stop_plotting",
            "stop_service",
            "is_running",
            "register_service",
        ]
        if not isinstance(data, dict) and command in commands_with_data:
            response = {
                "success": False,
                "error": f'{command} requires "data"'
            }
        elif command == "ping":
            response = await ping()
        elif command == "start_service":
            response = await self.start_service(cast(Dict[str, Any], data))
        elif command == "start_plotting":
            response = await self.start_plotting(cast(Dict[str, Any], data))
        elif command == "stop_plotting":
            response = await self.stop_plotting(cast(Dict[str, Any], data))
        elif command == "stop_service":
            response = await self.stop_service(cast(Dict[str, Any], data))
        elif command == "is_running":
            response = await self.is_running(cast(Dict[str, Any], data))
        elif command == "exit":
            response = await self.stop()
        elif command == "register_service":
            response = await self.register_service(websocket,
                                                   cast(Dict[str, Any], data))
        else:
            self.log.error(f"UK>> {message}")
            response = {
                "success": False,
                "error": f"unknown_command {command}"
            }

        full_response = format_response(message, response)
        return full_response, [websocket]
Exemple #5
0
def format_response(incoming_msg: Dict[str, Any], response_data: Dict[str, Any]) -> str:
    """
    Formats the response into standard format.
    """
    response = {
        "command": incoming_msg["command"],
        "ack": True,
        "data": response_data,
        "request_id": incoming_msg["request_id"],
        "destination": incoming_msg["origin"],
        "origin": incoming_msg["destination"],
    }

    json_str = dict_to_json_str(response)
    return json_str
Exemple #6
0
def create_payload(
    command: str, data: Dict[str, Any], origin: str, destination: str, string=True
):
    response = {
        "command": command,
        "ack": False,
        "data": data,
        "request_id": token_bytes().hex(),
        "destination": destination,
        "origin": origin,
    }

    if string:
        json_str = dict_to_json_str(response)
        return json_str
    else:
        return response
    async def handle_message(self, websocket,
                             message) -> Tuple[Optional[str], List[Any]]:
        """
        This function gets called when new message is received via websocket.
        """

        command = message["command"]
        destination = message["destination"]
        if destination != "daemon":
            destination = message["destination"]
            if destination in self.connections:
                sockets = self.connections[destination]
                return dict_to_json_str(message), sockets

            return None, []

        data = None
        if "data" in message:
            data = message["data"]
        if command == "ping":
            response = await ping()
        elif command == "start_service":
            response = await self.start_service(data)
        elif command == "start_plotting":
            response = await self.start_plotting(data)
        elif command == "stop_plotting":
            response = await self.stop_plotting(data)
        elif command == "stop_service":
            response = await self.stop_service(data)
        elif command == "is_running":
            response = await self.is_running(data)
        elif command == "exit":
            response = await self.stop()
        elif command == "register_service":
            response = await self.register_service(websocket, data)
        else:
            self.log.error(f"UK>> {message}")
            response = {
                "success": False,
                "error": f"unknown_command {command}"
            }

        full_response = format_response(message, response)
        return full_response, [websocket]
    async def coin_added(self, coin: Coin, height: int, header_hash: bytes32,
                         removals: List[Coin]):
        """ Notification from wallet state manager that wallet has been received. """
        self.log.info(f"CC wallet has been notified that {coin} was added")

        search_for_parent: bool = True

        inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
        lineage_proof = Program.to((
            1,
            [
                coin.parent_coin_info,
                inner_puzzle.get_tree_hash(),
                coin.amount,
            ],
        ))
        await self.add_lineage(coin.name(), lineage_proof)

        for name, lineage_proofs in self.cc_info.lineage_proofs:
            if coin.parent_coin_info == name:
                search_for_parent = False
                break

        if search_for_parent:
            data: Dict[str, Any] = {
                "data": {
                    "action_data": {
                        "api_name": "request_generator",
                        "height": height,
                        "header_hash": header_hash,
                    }
                }
            }

            data_str = dict_to_json_str(data)
            await self.wallet_state_manager.create_action(
                name="request_generator",
                wallet_id=self.wallet_info.id,
                type=self.wallet_info.type,
                callback="generator_received",
                done=False,
                data=data_str,
            )
Exemple #9
0
    async def _get(self, request):
        request_id = request["request_id"]
        self._request_dict[request_id] = asyncio.Event()
        string = dict_to_json_str(request)
        asyncio.ensure_future(self.websocket.send(string))

        async def timeout():
            await asyncio.sleep(30)
            if request_id in self._request_dict:
                print("Error, timeout.")
                self._request_dict[request_id].set()

        asyncio.ensure_future(timeout())
        await self._request_dict[request_id].wait()
        if request_id in self.response_dict:
            response = self.response_dict[request_id]
            self.response_dict.pop(request_id)
        else:
            response = None
        self._request_dict.pop(request_id)

        return response
Exemple #10
0
def create_payload(command: str, data: Dict[str, Any], origin: str,
                   destination: str) -> str:
    response = create_payload_dict(command, data, origin, destination)
    return dict_to_json_str(response)