Exemplo n.º 1
0
 def _call(self, method: str, *args: Any) -> Any:
     """Call the remote bitcoin node RPC with a method and parameters
     Args:
         method: The bitcoin json rpc method to call
         args: The arbitrary arguments for the method (in order)
     Returns:
         The result from the rpc call
     Raises:
         exceptions.InterchainConnectionError: If the remote call returned an error
     """
     # Note: Even though sending json, documentation still says to use text/plain content type header
     # https://bitcoin.org/en/developer-reference#remote-procedure-calls-rpcs
     r = requests.post(
         self.rpc_address,
         json={
             "method": method,
             "params": list(args),
             "id": "1",
             "jsonrpc": "1.0"
         },
         headers={
             "Authorization": f"Basic {self.authorization}",
             "Content-Type": "text/plain"
         },
         timeout=20,
     )
     if r.status_code != 200:
         raise exceptions.InterchainConnectionError(
             f"Error from bitcoin node with http status code {r.status_code} | {r.text}"
         )
     response = r.json()
     if response.get("error") or response.get("errors"):
         raise exceptions.InterchainConnectionError(
             f"The RPC call got an error response: {response}")
     return response["result"]
Exemplo n.º 2
0
 def ping(self) -> None:
     """Ping this network to check if the given node is reachable and authorization is correct (raises exception if not)"""
     response_rpc = self._call_node_rpc("status", {}).json()
     response_api = self._call_node_api("tokens/BNB").json()
     if response_rpc.get("error") or response_api.get("error"):
         raise exceptions.InterchainConnectionError(
             f"[BINANCE] Node ping checks failed!")
Exemplo n.º 3
0
 def _call_node_api(self, path: str) -> Any:
     full_address = f"{self.node_url}:{self.api_port}/api/v1/{path}"
     try:
         response = requests.get(full_address, timeout=10)
     except Exception as e:
         raise exceptions.InterchainConnectionError(f"Error sending get request to binance node: {e}")
     _log.debug(f"Binance <- {response.status_code} {response.text}")
     return response
Exemplo n.º 4
0
 def _call_node_rpc(self, method: str, params: Dict[str, Any]) -> Any:
     full_address = f"{self.node_url}:{self.rpc_port}/"
     body = {"method": method, "jsonrpc": "2.0", "params": params, "id": "dontcare"}
     _log.debug(f"Binance RPC: -> {full_address} {body}")
     try:
         response = requests.post(full_address, json=body, timeout=10)
     except Exception as e:
         raise exceptions.InterchainConnectionError(f"Error sending post request to binance node: {e}")
     _log.debug(f"Binance <- {response.status_code} {response.text}")
     return response
Exemplo n.º 5
0
 def _fetch_account(self):
     """Fetch the account metadata for an address
     Returns:
         response containing account metadata
     """
     _log.info(f"[BINANCE] Fetching address metadata for {self.address}")
     path = f"account/{self.address}"  # params expected inside path string
     try:
         response = self._call_node_api(path)
         if response.status_code == 404:
             _log.warning("[BINANCE] 404 response from Binance node:")
             _log.warning("[BINANCE] Address not found -- likely has zero funds.")
             raise exceptions.BadRequest("[BINANCE] Error fetching metadata from 'account' endpoint.")
         return response.json()
     except exceptions.InterchainConnectionError:
         _log.warning("[BINANCE] Non 200 response from Binance node.")
         _log.warning("[BINANCE] May have been a 500 Bad Request or a 404 Not Found.")
         raise exceptions.InterchainConnectionError("[BINANCE] Error fetching metadata from 'account' endpoint.")