예제 #1
0
    async def process_p2p_handshake(self, cmd: Command,
                                    msg: PayloadType) -> None:
        msg = cast(Dict[str, Any], msg)
        if not isinstance(cmd, Hello):
            await self.disconnect(DisconnectReason.bad_protocol)
            raise HandshakeFailure(
                f"Expected a Hello msg, got {cmd}, disconnecting")

        # limit number of chars to be displayed, and try to keep printable ones only
        # MAGIC 256: arbitrary, "should be enough for everybody"
        original_version = msg['client_version_string']
        client_version_string = original_version[:256] + (
            '...' if original_version[256:] else '')
        if client_version_string.isprintable():
            self.client_version_string = client_version_string.strip()
        else:
            self.client_version_string = repr(client_version_string)

        # Check whether to support Snappy Compression or not
        # based on other peer's p2p protocol version
        snappy_support = msg['version'] >= SNAPPY_PROTOCOL_VERSION

        if snappy_support:
            # Now update the base protocol to support snappy compression
            # This is needed so that Trinity is compatible with parity since
            # parity sends Ping immediately after Handshake
            self.base_protocol = P2PProtocol(
                self.transport,
                snappy_support=snappy_support,
                capabilities=self.capabilities,
                listen_port=self.listen_port,
            )

        remote_capabilities = msg['capabilities']
        matched_proto_classes = match_protocols_with_capabilities(
            self.supported_sub_protocols,
            remote_capabilities,
        )
        if len(matched_proto_classes) == 1:
            self.sub_proto = matched_proto_classes[0](
                self.transport,
                self.base_protocol.cmd_length,
                snappy_support,
            )
        elif len(matched_proto_classes) > 1:
            raise NotImplementedError(
                f"Peer {self.remote} connection matched on multiple protocols "
                f"{matched_proto_classes}.  Support for multiple protocols is not "
                f"yet supported")
        else:
            await self.disconnect(DisconnectReason.useless_peer)
            raise HandshakeFailure(
                f"No matching capabilities between us ({self.capabilities}) and {self.remote} "
                f"({remote_capabilities}), disconnecting")

        self.logger.debug(
            "Finished P2P handshake with %s, using sub-protocol %s",
            self.remote, self.sub_proto)
예제 #2
0
파일: helpers.py 프로젝트: s0b0lev/trinity
async def process_v4_p2p_handshake(self: BasePeer, cmd: protocol.Command,
                                   msg: protocol.Payload) -> None:
    """
    This function is the replacement to the existing process_p2p_handshake
    function.
    This is used to simulate the v4 P2PProtocol node.
    The only change that has been made is to remove the snappy support irrespective
    of whether the other client supports it or not.
    """
    msg = cast(Dict[str, Any], msg)
    if not isinstance(cmd, Hello):
        await self.disconnect(DisconnectReason.bad_protocol)
        raise HandshakeFailure(
            f"Expected a Hello msg, got {cmd}, disconnecting")

    # As far as a v4 P2PProtocol client is concerned,
    # it never support snappy compression
    snappy_support = False

    remote_capabilities = msg['capabilities']
    matched_proto_classes = match_protocols_with_capabilities(
        self.supported_sub_protocols,
        remote_capabilities,
    )
    if len(matched_proto_classes) == 1:
        self.sub_proto = matched_proto_classes[0](
            self.transport,
            self.base_protocol.cmd_length,
            snappy_support,
        )
    elif len(matched_proto_classes) > 1:
        raise NotImplementedError(
            f"Peer {self.remote} connection matched on multiple protocols "
            f"{matched_proto_classes}.  Support for multiple protocols is not "
            f"yet supported")
    else:
        await self.disconnect(DisconnectReason.useless_peer)
        raise HandshakeFailure(
            f"No matching capabilities between us ({self.capabilities}) and {self.remote} "
            f"({remote_capabilities}), disconnecting")

    self.logger.debug("Finished P2P handshake with %s, using sub-protocol %s",
                      self.remote, self.sub_proto)
예제 #3
0
def test_sub_protocol_selection(protocols, capabilities, expected):
    actual = match_protocols_with_capabilities(protocols, capabilities)
    assert actual == expected