Пример #1
0
    async def process_sub_proto_handshake(self, cmd: Command,
                                          msg: _DecodedMsgType) -> None:
        if not isinstance(cmd, Status):
            await self.disconnect(DisconnectReason.subprotocol_error)
            raise HandshakeFailure(
                f"Expected a ETH Status msg, got {cmd}, disconnecting")

        msg = cast(Dict[str, Any], msg)

        self.head_td = msg['td']
        self.head_hash = msg['best_hash']
        self.network_id = msg['network_id']
        self.genesis_hash = msg['genesis_hash']

        if msg['network_id'] != self.local_network_id:
            await self.disconnect(DisconnectReason.useless_peer)
            raise WrongNetworkFailure(
                f"{self} network ({msg['network_id']}) does not match ours "
                f"({self.local_network_id}), disconnecting")

        local_genesis_hash = await self._get_local_genesis_hash()
        if msg['genesis_hash'] != local_genesis_hash:
            await self.disconnect(DisconnectReason.useless_peer)
            raise WrongGenesisFailure(
                f"{self} genesis ({encode_hex(msg['genesis_hash'])}) does not "
                f"match ours ({local_genesis_hash}), disconnecting")
Пример #2
0
    async def process_sub_proto_handshake(self, cmd: CommandAPI,
                                          msg: Payload) -> None:
        if not isinstance(cmd, (Status, StatusV2)):
            await self.disconnect(DisconnectReason.subprotocol_error)
            raise HandshakeFailure(
                f"Expected a LES Status msg, got {cmd}, disconnecting")

        msg = cast(Dict[str, Any], msg)

        self.head_td = msg['headTd']
        self.head_hash = msg['headHash']
        self.head_number = msg['headNum']
        self.network_id = msg['networkId']
        self.genesis_hash = msg['genesisHash']

        if msg['networkId'] != self.local_network_id:
            await self.disconnect(DisconnectReason.useless_peer)
            raise WrongNetworkFailure(
                f"{self} network ({msg['networkId']}) does not match ours "
                f"({self.local_network_id}), disconnecting")

        local_genesis_hash = await self._get_local_genesis_hash()
        if msg['genesisHash'] != local_genesis_hash:
            await self.disconnect(DisconnectReason.useless_peer)
            raise WrongGenesisFailure(
                f"{self} genesis ({encode_hex(msg['genesisHash'])}) does not "
                f"match ours ({local_genesis_hash}), disconnecting")

        # Eventually we might want to keep connections to peers where we are the only side serving
        # data, but right now both our chain syncer and the Peer.boot() method expect the remote
        # to reply to header requests, so if they don't we simply disconnect here.
        if 'serveHeaders' not in msg:
            await self.disconnect(DisconnectReason.useless_peer)
            raise HandshakeFailure(
                f"{self} doesn't serve headers, disconnecting")
Пример #3
0
def validate_base_receipt(
        remote: NodeAPI, receipt: Union[ETHV63HandshakeReceipt,
                                        ETHHandshakeReceipt],
        handshake_params: Union[StatusV63Payload, StatusPayload]) -> None:
    if receipt.handshake_params.network_id != handshake_params.network_id:
        raise WrongNetworkFailure(
            f"{remote} network "
            f"({receipt.handshake_params.network_id}) does not match ours "
            f"({handshake_params.network_id}), disconnecting")

    if receipt.handshake_params.genesis_hash != handshake_params.genesis_hash:
        raise WrongGenesisFailure(
            f"{remote} genesis "
            f"({encode_hex(receipt.handshake_params.genesis_hash)}) does "
            f"not match ours ({encode_hex(handshake_params.genesis_hash)}), "
            f"disconnecting")
Пример #4
0
    async def do_handshake(
            self, multiplexer: MultiplexerAPI,
            protocol: Union[LESProtocolV1,
                            LESProtocolV2]) -> LESHandshakeReceipt:
        """Perform the handshake for the sub-protocol agreed with the remote peer.

        Raises HandshakeFailure if the handshake is not successful.
        """

        protocol.send(protocol.status_command_type(self.handshake_params))

        async for cmd in multiplexer.stream_protocol_messages(protocol):
            if not isinstance(cmd, (StatusV1, StatusV2)):
                raise HandshakeFailure(
                    f"Expected a LES Status msg, got {cmd}, disconnecting")

            if cmd.payload.network_id != self.handshake_params.network_id:
                raise WrongNetworkFailure(
                    f"{multiplexer.remote} network "
                    f"({cmd.payload.network_id}) does not match ours "
                    f"({self.handshake_params.network_id}), disconnecting")

            if cmd.payload.genesis_hash != self.handshake_params.genesis_hash:
                raise WrongGenesisFailure(
                    f"{multiplexer.remote} genesis "
                    f"({encode_hex(cmd.payload.genesis_hash)}) does "
                    f"not match ours "
                    f"({encode_hex(self.handshake_params.genesis_hash)}), "
                    f"disconnecting")

            # Eventually we might want to keep connections to peers where we
            # are the only side serving data, but right now both our chain
            # syncer and the Peer.boot() method expect the remote to reply to
            # header requests, so if they don't we simply disconnect here.
            if cmd.payload.serve_headers is False:
                raise HandshakeFailure(
                    f"{multiplexer.remote} doesn't serve headers, disconnecting"
                )

            receipt = LESHandshakeReceipt(protocol, cmd.payload)
            break
        else:
            raise HandshakeFailure(
                "Message stream exited before finishing handshake")

        return receipt
Пример #5
0
    async def do_handshake(self,
                           multiplexer: MultiplexerAPI,
                           protocol: ProtocolAPI) -> ETHHandshakeReceipt:
        """Perform the handshake for the sub-protocol agreed with the remote peer.

        Raises HandshakeFailure if the handshake is not successful.
        """
        protocol = cast(ETHProtocol, protocol)
        protocol.send_handshake(self.handshake_params)

        async for cmd, msg in multiplexer.stream_protocol_messages(protocol):
            if not isinstance(cmd, Status):
                raise HandshakeFailure(f"Expected a ETH Status msg, got {cmd}, disconnecting")

            msg = cast(Dict[str, Any], msg)

            remote_params = ETHHandshakeParams(
                version=msg['protocol_version'],
                network_id=msg['network_id'],
                total_difficulty=msg['td'],
                head_hash=msg['best_hash'],
                genesis_hash=msg['genesis_hash'],
            )
            receipt = ETHHandshakeReceipt(protocol, remote_params)

            if receipt.handshake_params.network_id != self.handshake_params.network_id:
                raise WrongNetworkFailure(
                    f"{multiplexer.remote} network "
                    f"({receipt.handshake_params.network_id}) does not match ours "
                    f"({self.handshake_params.network_id}), disconnecting"
                )

            if receipt.handshake_params.genesis_hash != self.handshake_params.genesis_hash:
                raise WrongGenesisFailure(
                    f"{multiplexer.remote} genesis "
                    f"({encode_hex(receipt.handshake_params.genesis_hash)}) does "
                    f"not match ours ({encode_hex(self.handshake_params.genesis_hash)}), "
                    f"disconnecting"
                )

            break
        else:
            raise HandshakeFailure("Message stream exited before finishing handshake")

        return receipt
Пример #6
0
    async def do_handshake(self,
                           multiplexer: MultiplexerAPI,
                           protocol: ProtocolAPI) -> LESHandshakeReceipt:
        """Perform the handshake for the sub-protocol agreed with the remote peer.

        Raises HandshakeFailure if the handshake is not successful.
        """
        protocol = cast(AnyLESProtocol, protocol)
        protocol.send_handshake(self.handshake_params)

        async for cmd, msg in multiplexer.stream_protocol_messages(protocol):
            if not isinstance(cmd, (Status, StatusV2)):
                raise HandshakeFailure(f"Expected a LES Status msg, got {cmd}, disconnecting")

            msg = cast(Dict[str, Any], msg)

            remote_params = LESHandshakeParams(
                version=msg['protocolVersion'],
                network_id=msg['networkId'],
                head_td=msg['headTd'],
                head_hash=msg['headHash'],
                head_num=msg['headNum'],
                genesis_hash=msg['genesisHash'],
                serve_headers=('serveHeaders' in msg),
                serve_chain_since=msg.get('serveChainSince'),
                serve_state_since=msg.get('serveStateSince'),
                serve_recent_chain=msg.get('serveRecentChain'),
                serve_recent_state=msg.get('serveRecentState'),
                tx_relay=('txRelay' in msg),
                flow_control_bl=msg.get('flowControl/BL'),
                flow_control_mcr=msg.get('flowControl/MRC'),
                flow_control_mrr=msg.get('flowControl/MRR'),
                announce_type=msg.get('announceType'),  # TODO: only in StatusV2
            )

            if remote_params.network_id != self.handshake_params.network_id:
                raise WrongNetworkFailure(
                    f"{multiplexer.remote} network "
                    f"({remote_params.network_id}) does not match ours "
                    f"({self.handshake_params.network_id}), disconnecting"
                )

            if remote_params.genesis_hash != self.handshake_params.genesis_hash:
                raise WrongGenesisFailure(
                    f"{multiplexer.remote} genesis "
                    f"({encode_hex(remote_params.genesis_hash)}) does "
                    f"not match ours "
                    f"({encode_hex(self.handshake_params.genesis_hash)}), "
                    f"disconnecting"
                )

            # Eventually we might want to keep connections to peers where we
            # are the only side serving data, but right now both our chain
            # syncer and the Peer.boot() method expect the remote to reply to
            # header requests, so if they don't we simply disconnect here.
            if remote_params.serve_headers is False:
                raise HandshakeFailure(f"{multiplexer.remote} doesn't serve headers, disconnecting")

            receipt = LESHandshakeReceipt(protocol, remote_params)
            break
        else:
            raise HandshakeFailure("Message stream exited before finishing handshake")

        return receipt