# Buggy code
async def do_p2p_handshake(self) -> None:
    """Perform the handshake for the P2P base protocol.

    Raises HandshakeFailure if the handshake is not successful.
    """
    self.base_protocol.send_handshake()

    try:
        cmd, msg = await self.read_msg()
    except rlp.DecodingError:
        raise HandshakeFailure("Got invalid rlp data during handshake")
    except MalformedMessage as e:
        raise HandshakeFailure("Got malformed message during handshake") from e

    if isinstance(cmd, Disconnect):
        msg = cast(Dict[str, Any], msg)
        # Peers sometimes send a disconnect msg before they send the initial P2P handshake.
        if msg["reason"] == DisconnectReason.too_many_peers.value:
            raise TooManyPeersFailure(f"{self} disconnected from us before handshake")
        raise HandshakeFailure(
            f"{self} disconnected before completing sub-proto handshake: {msg['reason_name']}"
        )
    await self.process_p2p_handshake(cmd, msg)


# Traceback (snappy.CompressedLengthError)
b'\x1b[1m\x1b[31m   ERROR  02-19 09:50:08           ETHPeerPool  Unexpected error during auth/p2p handshake with <Node(0x865a63255b3bb68023b6bffd5095118fcc13e79dcf014fe4e47e065c350c7cc72af2e53eff895f11ba1bbb6a2b33271c1116ee870f266618eadfc2e78aa7349c@52.176.100.77:30303)>\n'
b'Traceback (most recent call last):\n'
b'  File "/home/circleci/repo/p2p/peer_pool.py", line 255, in connect\n'
b'    peer = await self.wait(handshake(remote, self.get_peer_factory()))\n'
b'  File "/home/circleci/repo/p2p/cancellable.py", line 20, in wait\n'
b'    return await self.wait_first(awaitable, token=token, timeout=timeout)\n'
b'  File "/home/circleci/repo/p2p/cancellable.py", line 42, in wait_first\n'
b'    return await token_chain.cancellable_wait(*awaitables, timeout=timeout)\n'
b'  File "/home/circleci/repo/.tox/py36-long_run_integration/lib/python3.6/site-packages/cancel_token/token.py", line 152, in cancellable_wait\n'
b'    return done.pop().result()\n'
b'  File "/home/circleci/repo/p2p/peer.py", line 128, in handshake\n'
b'    await peer.do_sub_proto_handshake()\n'
b'  File "/home/circleci/repo/p2p/peer.py", line 321, in do_sub_proto_handshake\n'
b'    cmd, msg = await self.read_msg()\n'
b'  File "/home/circleci/repo/p2p/peer.py", line 460, in read_msg\n'
b'    decoded_msg = cast(Dict[str, Any], cmd.decode(msg))\n'
b'  File "/home/circleci/repo/p2p/p2p_proto.py", line 78, in decode\n'
b'    raw_decoded = cast(Dict[str, int], super().decode(data))\n'
b'  File "/home/circleci/repo/p2p/protocol.py", line 123, in decode\n'
b'    encoded_payload = self.decompress_payload(compressed_payload)\n'
b'  File "/home/circleci/repo/p2p/protocol.py", line 130, in decompress_payload\n'
b'    return snappy.decompress(raw_payload)\n'
b'  File "/home/circleci/repo/.tox/py36-long_run_integration/lib/python3.6/site-packages/snappy/snappy.py", line 92, in uncompress\n'
b'    return _uncompress(data)\n'
b'snappy.CompressedLengthError: Can not calculate uncompressed length\x1b[0m\n'

# Fixed code
async def do_p2p_handshake(self) -> None:
    """Perform the handshake for the P2P base protocol.

    Raises HandshakeFailure if the handshake is not successful.
    """
    self.base_protocol.send_handshake()

    cmd, msg = await self.read_msg()

    if isinstance(cmd, Disconnect):
        msg = cast(Dict[str, Any], msg)
        # Peers sometimes send a disconnect msg before they send the initial P2P handshake.
        if msg["reason"] == DisconnectReason.too_many_peers.value:
            raise TooManyPeersFailure(f"{self} disconnected from us before handshake")
        raise HandshakeFailure(
            f"{self} disconnected before completing sub-proto handshake: {msg['reason_name']}"
        )
    await self.process_p2p_handshake(cmd, msg)