示例#1
0
    def update_last_known_state(self, chain_id: int, version: int,
                                timestamp_usecs: int) -> None:
        """update last known server state

        Raises InvalidServerResponse if given chain_id mismatches with previous value

        Raises StaleResponseError if version or timestamp_usecs is less than previous values
        """

        curr = self._last_known_server_state
        if curr.chain_id != -1 and curr.chain_id != chain_id:
            raise InvalidServerResponse(
                f"last known chain id {curr.chain_id}, "
                f"but got {chain_id}")
        if curr.version > version:
            raise StaleResponseError(
                f"last known version {curr.version} > {version}")
        if curr.timestamp_usecs > timestamp_usecs:
            raise StaleResponseError(
                f"last known timestamp_usecs {curr.timestamp_usecs} > {timestamp_usecs}"
            )

        self._last_known_server_state = State(
            chain_id=chain_id,
            version=version,
            timestamp_usecs=timestamp_usecs,
        )
示例#2
0
    async def _send_http_request(
        self,
        url: str,
        request: typing.Dict[str, typing.Any],
        ignore_stale_response: bool,
    ) -> typing.Dict[str, typing.Any]:
        self._logger.debug("http request body: %s", request)
        headers = {"User-Agent": USER_AGENT_HTTP_HEADER}
        async with self._session.post(url, json=request,
                                      headers=headers) as response:
            self._logger.debug("http response body: %s", response.text)
            response.raise_for_status()
            try:
                json = await response.json()
            except ValueError as e:
                raise InvalidServerResponse(
                    f"Parse response as json failed: {e}, response: {response.text}"
                )

        # check stable response before check jsonrpc error
        try:
            self.update_last_known_state(
                json.get("diem_chain_id"),
                json.get("diem_ledger_version"),
                json.get("diem_ledger_timestampusec"),
            )
        except StaleResponseError as e:
            if not ignore_stale_response:
                raise e

        return json
示例#3
0
    def execute_without_retry(
        self,
        method: str,
        params: typing.List[typing.Any],  # pyre-ignore
        result_parser: typing.Optional[typing.Callable] = None,  # pyre-ignore
        ignore_stale_response: typing.Optional[bool] = None,
    ):
        """execute JSON-RPC method call without retry any error.


        Raises InvalidServerResponse if server response does not match
        [JSON-RPC SPEC 2.0](https://www.jsonrpc.org/specification), or response result can't be parsed.

        Raises StaleResponseError if ignore_stale_response is True, otherwise ignores it and continue.

        Raises JsonRpcError if server JSON-RPC response with error object.

        Raises NetworkError if send http request failed, or received server response status is not 200.
        """

        request = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": method,
            "params": params or [],
        }
        try:
            json = self._rs.send_request(self, request, ignore_stale_response
                                         or False)
            if "error" in json:
                err = json["error"]
                raise JsonRpcError(f"{err}")

            if "result" in json:
                if result_parser:
                    return result_parser(json["result"])
                return

            raise InvalidServerResponse(
                f"No error or result in response: {json}")
        except requests.RequestException as e:
            raise NetworkError(
                f"Error in connecting to server: {e}\nPlease retry...")
        except parser.ParseError as e:
            raise InvalidServerResponse(
                f"Parse result failed: {e}, response: {json}")