async def handle_message( triple: Tuple[ChiaConnection, Message, PeerConnections], api: Any ) -> AsyncGenerator[Tuple[ChiaConnection, OutboundMessage, PeerConnections], None]: """ Async generator which takes messages, parses, them, executes the right api function, and yields responses (to same connection, propagated, etc). """ connection, full_message, global_connections = triple try: if len(full_message.function) == 0 or full_message.function.startswith( "_"): # This prevents remote calling of private methods that start with "_" raise ProtocolError(Err.INVALID_PROTOCOL_MESSAGE, [full_message.function]) connection.log.info( f"<- {full_message.function} from peer {connection.get_peername()}" ) if full_message.function == "ping": ping_msg = Ping(full_message.data["nonce"]) assert connection.connection_type outbound_message = OutboundMessage( connection.connection_type, Message("pong", Pong(ping_msg.nonce)), Delivery.RESPOND, ) yield connection, outbound_message, global_connections return elif full_message.function == "pong": return f_with_peer_name = getattr(api, full_message.function + "_with_peer_name", None) if f_with_peer_name is not None: result = f_with_peer_name(full_message.data, connection.get_peername()) else: f = getattr(api, full_message.function, None) if f is None: raise ProtocolError(Err.INVALID_PROTOCOL_MESSAGE, [full_message.function]) result = f(full_message.data) if isinstance(result, AsyncGenerator): async for outbound_message in result: yield connection, outbound_message, global_connections else: await result except Exception: tb = traceback.format_exc() connection.log.error(f"Error, closing connection {connection}. {tb}") # TODO: Exception means peer gave us invalid information, so ban this peer. global_connections.close(connection)
async def handle_message( self, pair: Tuple[Connection, Message], api: Any ) -> AsyncGenerator[Tuple[Connection, OutboundMessage], None]: """ Async generator which takes messages, parses, them, executes the right api function, and yields responses (to same connection, propagated, etc). """ connection, full_message = pair try: if len(full_message.function ) == 0 or full_message.function.startswith("_"): # This prevents remote calling of private methods that start with "_" raise InvalidProtocolMessage(full_message.function) log.info( f"<- {full_message.function} from peer {connection.get_peername()}" ) if full_message.function == "ping": ping_msg = Ping(full_message.data["nonce"]) assert connection.connection_type yield connection, OutboundMessage( connection.connection_type, Message("pong", Pong(ping_msg.nonce)), Delivery.RESPOND, ) return elif full_message.function == "pong": return f = getattr(api, full_message.function) if f is None: raise InvalidProtocolMessage(full_message.function) result = f(full_message.data) if isinstance(result, AsyncGenerator): async for outbound_message in result: yield connection, outbound_message else: await result except Exception as e: log.error(f"Error {type(e)} {e}, closing connection {connection}") self.global_connections.close(connection)