def process_p2p_handshake(self, msg: bytes): cmd = self.get_protocol_command_for(msg) decoded_msg = cmd.decode(msg) decoded_msg = cast(Dict[str, Any], decoded_msg) if isinstance(cmd, Disconnect): # Peers may send a disconnect msg before they send the initial P2P handshake (e.g. when # they're not accepting more peers), so we special case that here because it's important # to distinguish this from a failed handshake (e.g. no matching protocols, etc). raise HandshakeFailure( "{} disconnected before completing handshake: {}".format( self, decoded_msg['reason_name'])) elif not isinstance(cmd, Hello): self.disconnect(DisconnectReason.other) raise HandshakeFailure( "Expected a Hello msg, got {}, disconnecting".format(cmd)) remote_capabilities = decoded_msg['capabilities'] self.sub_proto = self.select_sub_protocol(remote_capabilities) if self.sub_proto is None: self.disconnect(DisconnectReason.useless_peer) raise HandshakeFailure( "No matching capabilities between us ({}) and {} ({}), disconnecting" .format(self.capabilities, self.remote, remote_capabilities)) self.logger.debug( "Finished P2P handshake with %s, using sub-protocol %s", self.remote, self.sub_proto)
def process_handshake(self, decoded_msg: _DecodedMsgType) -> None: if decoded_msg['networkId'] != self.peer.network_id: self.logger.debug( "%s network (%s) does not match ours (%s), disconnecting", self.peer, decoded_msg['networkId'], self.peer.network_id) raise HandshakeFailure(DisconnectReason.other) if decoded_msg['genesisHash'] != self.peer.genesis.hash: self.logger.debug( "%s genesis (%s) does not match ours (%s), disconnecting", self.peer, encode_hex(decoded_msg['genesisHash']), self.peer.genesis.hex_hash) raise HandshakeFailure(DisconnectReason.other)
def process_p2p_handshake(self, cmd: protocol.Command, msg: protocol._DecodedMsgType) -> None: msg = cast(Dict[str, Any], msg) if not isinstance(cmd, Hello): self.disconnect(DisconnectReason.other) raise HandshakeFailure("Expected a Hello msg, got {}, disconnecting".format(cmd)) remote_capabilities = msg['capabilities'] self.sub_proto = self.select_sub_protocol(remote_capabilities) if self.sub_proto is None: self.disconnect(DisconnectReason.useless_peer) raise HandshakeFailure( "No matching capabilities between us ({}) and {} ({}), disconnecting".format( self.capabilities, self.remote, remote_capabilities)) self.logger.debug( "Finished P2P handshake with %s, using sub-protocol %s", self.remote, self.sub_proto)
def process_sub_proto_handshake( self, cmd: protocol.Command, msg: protocol._DecodedMsgType) -> None: if not isinstance(cmd, eth.Status): self.disconnect(DisconnectReason.other) raise HandshakeFailure( "Expected a ETH Status msg, got {}, disconnecting".format(cmd)) msg = cast(Dict[str, Any], msg) if msg['network_id'] != self.network_id: self.disconnect(DisconnectReason.other) raise HandshakeFailure( "{} network ({}) does not match ours ({}), disconnecting".format( self, msg['network_id'], self.network_id)) if msg['genesis_hash'] != self.genesis.hash: self.disconnect(DisconnectReason.other) raise HandshakeFailure( "{} genesis ({}) does not match ours ({}), disconnecting".format( self, encode_hex(msg['genesis_hash']), self.genesis.hex_hash))
def process_sub_proto_handshake( self, cmd: protocol.Command, msg: protocol._DecodedMsgType) -> None: if not isinstance(cmd, (les.Status, les.StatusV2)): self.disconnect(DisconnectReason.other) raise HandshakeFailure( "Expected a LES Status msg, got {}, disconnecting".format(cmd)) msg = cast(Dict[str, Any], msg) if msg['networkId'] != self.network_id: self.disconnect(DisconnectReason.other) raise HandshakeFailure( "{} network ({}) does not match ours ({}), disconnecting".format( self, msg['networkId'], self.network_id)) if msg['genesisHash'] != self.genesis.hash: self.disconnect(DisconnectReason.other) raise HandshakeFailure( "{} genesis ({}) does not match ours ({}), disconnecting".format( self, encode_hex(msg['genesisHash']), self.genesis.hex_hash)) # TODO: Disconnect if the remote doesn't serve headers. self.head_info = cmd.as_head_info(msg)
async def do_p2p_handshake(self): """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): # Peers sometimes send a disconnect msg before they send the initial P2P handshake. raise HandshakeFailure("{} disconnected before completing handshake: {}".format( self, msg['reason_name'])) self.process_p2p_handshake(cmd, msg)
def process_p2p_handshake(self, decoded_msg: protocol._DecodedMsgType) -> None: remote_capabilities = decoded_msg['capabilities'] self.match_protocols(remote_capabilities) if len(self.enabled_sub_protocols) == 0: self.logger.debug( "No matching capabilities between us (%s) and %s (%s), disconnecting", self.capabilities, self.remote, remote_capabilities) raise HandshakeFailure(DisconnectReason.useless_peer) else: self.logger.debug( "Finished P2P handshake with %s; matching protocols: %s", self.remote, [(p.name, p.version) for p in self.enabled_sub_protocols])
async def do_sub_proto_handshake(self): """Perform the handshake for the sub-protocol agreed with the remote peer. Raises HandshakeFailure if the handshake is not successful. """ self.send_sub_proto_handshake() cmd, msg = await self.read_msg() if isinstance(cmd, Disconnect): # Peers sometimes send a disconnect msg before they send the sub-proto handshake. raise HandshakeFailure( "{} disconnected before completing sub-proto handshake: {}".format( self, msg['reason_name'])) self.process_sub_proto_handshake(cmd, msg) self.logger.debug("Finished %s handshake with %s", self.sub_proto, self.remote)