Esempio n. 1
0
    async def _state_changed(self, *args):
        change = args[0]
        if self.websocket is None:
            return None
        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_dict(
                    "get_connections",
                    data,
                    self.service_name,
                    "wallet_ui",
                )
                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}.")
Esempio n. 2
0
async def async_run_daemon(root_path: Path) -> int:
    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()
    assert ws_server.websocket_server is not None
    await ws_server.websocket_server.wait_closed()
    log.info("Daemon WebSocketServer closed")
    return 0
Esempio n. 3
0
    async def handle_message(
            self, websocket: WebSocketServerProtocol,
            message: WsRpcMessage) -> 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 = message["data"]
        commands_with_data = [
            "start_service",
            "start_plotting",
            "stop_plotting",
            "stop_service",
            "is_running",
            "register_service",
        ]
        if len(data) == 0 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))
        elif command == "get_status":
            response = self.get_status()
        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]
Esempio n. 4
0
def format_response(incoming_msg: WsRpcMessage,
                    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
Esempio n. 5
0
    async def coin_added(self, coin: Coin, header_hash: bytes32,
                         removals: List[Coin], height: uint32):
        """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, True)

        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_puzzle_solution",
                        "height": height,
                        "coin_name": coin.parent_coin_info,
                        "received_coin": coin.name(),
                    }
                }
            }

            data_str = dict_to_json_str(data)
            await self.wallet_state_manager.create_action(
                name="request_puzzle_solution",
                wallet_id=self.id(),
                wallet_type=self.type(),
                callback="puzzle_solution_received",
                done=False,
                data=data_str,
                in_transaction=True,
            )
Esempio n. 6
0
    async def _get(self, request: WsRpcMessage) -> WsRpcMessage:
        request_id = request["request_id"]
        self._request_dict[request_id] = asyncio.Event()
        string = dict_to_json_str(request)
        asyncio.create_task(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.create_task(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
Esempio n. 7
0
async def async_run_daemon(root_path: Path, wait_for_unlock: bool = False) -> int:
    # When wait_for_unlock is true, we want to skip the check_keys() call in chia_init
    # since it might be necessary to wait for the GUI to unlock the keyring first.
    chia_init(root_path, should_check_keys=(not wait_for_unlock))
    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, run_check_keys_on_unlock=wait_for_unlock
    )
    await ws_server.start()
    assert ws_server.websocket_server is not None
    await ws_server.websocket_server.wait_closed()
    log.info("Daemon WebSocketServer closed")
    # sys.stdout.close()
    return 0
Esempio n. 8
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)