async def _do_p2p_handshake(transport: TransportAPI, capabilities: Capabilities, p2p_handshake_params: DevP2PHandshakeParams, base_protocol: BaseP2PProtocol) -> Tuple[(DevP2PReceipt, BaseP2PProtocol)]:
    (client_version_string, listen_port, p2p_version) = p2p_handshake_params
    base_protocol.send(Hello(HelloPayload(client_version_string=client_version_string, capabilities=capabilities, listen_port=listen_port, version=p2p_version, remote_public_key=transport.public_key.to_bytes())))
    async for (_, cmd) in stream_transport_messages(transport, base_protocol):
        if isinstance(cmd, Disconnect):
            if (cmd.payload == DisconnectReason.TOO_MANY_PEERS):
                raise HandshakeFailureTooManyPeers(f'Peer disconnected because it is already full')
        if (not isinstance(cmd, Hello)):
            raise HandshakeFailure(f'First message across the DevP2P connection must be a Hello msg, got {cmd}, disconnecting')
        protocol: BaseP2PProtocol
        if (base_protocol.version >= DEVP2P_V5):
            snappy_support = (cmd.payload.version >= DEVP2P_V5)
            if snappy_support:
                protocol = P2PProtocolV5(transport, command_id_offset=0, snappy_support=True)
            else:
                protocol = base_protocol
        else:
            protocol = base_protocol
        devp2p_receipt = DevP2PReceipt(protocol=protocol, version=cmd.payload.version, client_version_string=cmd.payload.client_version_string, capabilities=cmd.payload.capabilities, remote_public_key=cmd.payload.remote_public_key, listen_port=cmd.payload.listen_port)
        break
    else:
        raise HandshakeFailure('DevP2P message stream exited before finishing handshake')
    return (devp2p_receipt, protocol)
async def _do_p2p_handshake(transport: TransportAPI, capabilities: Capabilities, p2p_handshake_params: DevP2PHandshakeParams, base_protocol: BaseP2PProtocol) -> Tuple[(DevP2PReceipt, BaseP2PProtocol)]:
    (client_version_string, listen_port, p2p_version) = p2p_handshake_params
    base_protocol.send(Hello(HelloPayload(client_version_string=client_version_string, capabilities=capabilities, listen_port=listen_port, version=p2p_version, remote_public_key=transport.public_key.to_bytes())))
    async for (_, cmd) in stream_transport_messages(transport, base_protocol):
        if isinstance(cmd, Disconnect):
            if (cmd.payload == DisconnectReason.TOO_MANY_PEERS):
                raise HandshakeFailureTooManyPeers(f'Peer disconnected because it is already full')
        if (not isinstance(cmd, Hello)):
            raise HandshakeFailure(f'First message across the DevP2P connection must be a Hello msg, got {cmd}, disconnecting')
        protocol: BaseP2PProtocol
        if (base_protocol.version >= DEVP2P_V5):
            snappy_support = (cmd.payload.version >= DEVP2P_V5)
            if snappy_support:
                protocol = P2PProtocolV5(transport, command_id_offset=0, snappy_support=True)
            else:
                protocol = base_protocol
        else:
            protocol = base_protocol
        devp2p_receipt = DevP2PReceipt(protocol=protocol, version=cmd.payload.version, client_version_string=cmd.payload.client_version_string, capabilities=cmd.payload.capabilities, remote_public_key=cmd.payload.remote_public_key, listen_port=cmd.payload.listen_port)
        break
    else:
        raise HandshakeFailure('DevP2P message stream exited before finishing handshake')
    return (devp2p_receipt, protocol)