Beispiel #1
0
def normalize_and_validate_kv_pairs(
    params: Any, ) -> Iterable[Tuple[bytes, Optional[bytes]]]:
    if not params:
        raise RPCError("Missing parameters.")

    for kv_pair in params:
        if len(kv_pair) != 2:
            raise RPCError(f"Invalid kv_pair length: {len(kv_pair)}.")

        raw_key, raw_value = kv_pair
        if not is_hex(raw_key):
            raise RPCError(
                f"Key: {raw_key} is type: {type(raw_key)}. Keys must be hex-encoded strings."
            )
        key = to_bytes(hexstr=raw_key)

        value: Union[bytes, None]
        if not raw_value:
            value = None
        elif is_integer(raw_value):
            value = to_bytes(raw_value)
        elif is_text(raw_value) and is_hex(raw_value):
            value = to_bytes(hexstr=raw_value)
        else:
            raise RPCError(f"Value: {raw_value} is type: {type(raw_value)}. "
                           "Values must be hex-str, integer, or None.")

        yield key, value
Beispiel #2
0
def validate_and_extract_destination(
        value: Any) -> Tuple[NodeID, Optional[Endpoint]]:
    node_id: NodeID
    endpoint: Optional[Endpoint]

    if is_hex_node_id(value):
        node_id = NodeID(decode_hex(value))
        endpoint = None
    elif value.startswith("enode://"):
        raw_node_id, _, raw_endpoint = value[8:].partition("@")

        validate_hex_node_id(raw_node_id)
        validate_endpoint(raw_endpoint)

        node_id = NodeID(decode_hex(raw_node_id))

        raw_ip_address, _, raw_port = raw_endpoint.partition(":")
        ip_address = ipaddress.ip_address(raw_ip_address)
        port = int(raw_port)
        endpoint = Endpoint(ip_address.packed, port)
    elif value.startswith("enr:"):
        enr = ENR.from_repr(value)
        node_id = enr.node_id
        endpoint = Endpoint.from_enr(enr)
    else:
        raise RPCError(f"Unrecognized node identifier: {value}")

    return node_id, endpoint
Beispiel #3
0
    async def do_call(self, params: ContentKey) -> str:
        content_key = params

        content: bytes

        try:
            content = self._network.pinned_content_storage.get_content(
                content_key)
        except ContentNotFound:
            pass
        else:
            return encode_hex(content)

        try:
            content = self._network.commons_content_storage.get_content(
                content_key)
        except ContentNotFound:
            pass
        else:
            return encode_hex(content)

        try:
            proof = await self._network.get_content(content_key)
        except trio.TooSlowError as err:
            raise RPCError(
                f"Timeout retrieving content: content_key={content_key.hex()}"
            ) from err
        else:
            return encode_hex(proof.get_content())
Beispiel #4
0
 async def do_call(self, params: ContentKey) -> str:
     content_key = params
     try:
         content = self._content_storage.get_content(content_key)
     except ContentNotFound as err:
         raise RPCError(str(err)) from err
     else:
         return encode_hex(content)
Beispiel #5
0
def validate_and_normalize_distances(value: Any) -> Tuple[int, ...]:
    if _is_valid_distance(value):
        return (value, )
    elif (is_list_like(value) and value
          and all(_is_valid_distance(element) for element in value)):
        return tuple(value)
    else:
        raise RPCError(
            f"Distances must be either a single integer distance or a non-empty list of "
            f"distances: {value}")
Beispiel #6
0
    def extract_params(
            self, request: RPCRequest) -> Tuple[NodeID, Optional[Endpoint]]:
        try:
            raw_params = request["params"]
        except KeyError as err:
            raise RPCError(f"Missiing call params: {err}")

        if len(raw_params) != 1:
            raise RPCError(f"`ddht_ping` endpoint expects a single parameter: "
                           f"Got {len(raw_params)} params: {raw_params}")

        value = raw_params[0]

        node_id: NodeID
        endpoint: Optional[Endpoint]

        if is_hex_node_id(value):
            node_id = NodeID(decode_hex(value))
            endpoint = None
        elif value.startswith("enode://"):
            raw_node_id, _, raw_endpoint = value[8:].partition("@")

            validate_hex_node_id(raw_node_id)
            validate_endpoint(raw_endpoint)

            node_id = NodeID(decode_hex(raw_node_id))

            raw_ip_address, _, raw_port = raw_endpoint.partition(":")
            ip_address = ipaddress.ip_address(raw_ip_address)
            port = int(raw_port)
            endpoint = Endpoint(ip_address.packed, port)
        elif value.startswith("enr:"):
            enr = ENR.from_repr(value)
            node_id = enr.node_id
            endpoint = Endpoint.from_enr(enr)
        else:
            raise RPCError(f"Unrecognized node identifier: {value}")

        return node_id, endpoint
Beispiel #7
0
def validate_endpoint(value: Any) -> None:
    if not is_endpoint(value):
        raise RPCError(f"Invalid Endpoint: {value}")
Beispiel #8
0
def validate_hex_node_id(value: Any) -> None:
    if not is_hex_node_id(value):
        raise RPCError(f"Invalid NodeID: {value}")
Beispiel #9
0
def validate_params_length(params: List[Any], length: int) -> None:
    if len(params) != length:
        raise RPCError(
            f"Endpoint expects {length} params: length={len(params)} "
            f"params={params}")
Beispiel #10
0
def validate_and_convert_hexstr(*args: Any) -> Iterable[bytes]:
    for value in args:
        try:
            yield to_bytes(hexstr=value)
        except TypeError:
            raise RPCError(f"Invalid hexstr parameter: {value}")
Beispiel #11
0
 async def do_call(self, params: ContentKey) -> None:
     content_key = params
     try:
         self._content_storage.delete_content(content_key)
     except ContentNotFound as err:
         raise RPCError(str(err)) from err
Beispiel #12
0
 def extract_params(self, request: RPCRequest) -> None:
     if request.get("params"):
         raise RPCError(f"Unexpected RPC params: {request['params']}")
     return None