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")
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")
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")
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
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
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