docstr: Check if a route exists in self.node_routes
  - For HTTPNodeRoute: check based on protocol, host_or_ip (url) and port
  - For PythonNodeRoute: check if the route exists in the set of all node_routes
  Args:
      route: the route to be checked
  Returns:
      if the route exists, returns (True, index of the existed route in self.node_routes)
      if the route does not exist returns (False, None)
docstr_tok: ["Check","if","a","route","exists","in","self.node_routes","-","For","HTTPNodeRoute",":","check","based","on","protocol",",","host_or_ip","(","url",")","and","port","-","For","PythonNodeRoute",":","check","if","the","route","exists","in","the","set","of","all","node_routes","Args",":","route",":","the","route","to","be","checked","Returns",":","if","the","route","exists",",","returns","(","True",",","index","of","the","existed","route","in","self.node_routes",")","if","the","route","does","not","exist","returns","(","False",",","None",")"]
code: def existed_route(
      self, route: NodeRoute
  ) -> Tuple[bool, Optional[int]]:
      """Check if a route exists in self.node_routes
      - For HTTPNodeRoute: check based on protocol, host_or_ip (url) and port
      - For PythonNodeRoute: check if the route exists in the set of all node_routes
      Args:
          route: the route to be checked
      Returns:
          if the route exists, returns (True, index of the existed route in self.node_routes)
          if the route does not exist returns (False, None)
      """
      if isinstance(route, HTTPNodeRoute):
          for i, r in enumerate(self.node_routes):
              if (
                  (route.host_or_ip == r.host_or_ip)
                  and (route.port == r.port)
                  and (route.protocol == r.protocol)
              ):
                  return (True, i)
          return (False, None)
      else:  # PythonNodeRoute
          for i, r in enumerate(
              self.node_routes
          ):  # something went wrong here
              if (
                  (route.worker_settings.id == r.worker_settings.id)
                  and (
                      route.worker_settings.name
                      == r.worker_settings.name
                  )
                  and (
                      route.worker_settings.node_type
                      == r.worker_settings.node_type
                  )
                  and (
                      route.worker_settings.node_side_type
                      == r.worker_settings.node_side_type
                  )
                  and (
                      route.worker_settings.signing_key
                      == r.worker_settings.signing_key
                  )
              ):
                  return (True, i)
          return (False, None)
  
imports: from typing import List
  from typing import Optional
  from typing import Tuple
  from typing_extensions import Self
  from ...abstract_node import NodeType
  from ...client.client import SyftClient
  from ...node.credentials import SyftSigningKey
  from ...node.credentials import SyftVerifyKey
  from ...serde.serializable import serializable
  from ...service.response import SyftError
  from ...types.syft_object import SYFT_OBJECT_VERSION_1
  from ...types.syft_object import SyftObject
  from ...types.uid import UID
  from ..context import NodeServiceContext
  from ..metadata.node_metadata import NodeMetadataV3
  from .routes import HTTPNodeRoute
  from .routes import NodeRoute
  from .routes import NodeRouteType
  from .routes import connection_to_route
  from .routes import route_to_connection
label_desc: Use image node_id 3 for calling the NodePeer obj's underlying member method code with example usage: obj.existed_route(route) and returns: False,  None, False,  None, True,  i, True,  i