async def _connect_to_peers(self, random) -> None:
    next_feeler = self._poisson_next_send(((time.time() * 1000) * 1000), 240, random)
    retry_introducers = False
    introducer_attempts: int = 0
    dns_server_index: int = 0
    local_peerinfo: Optional[PeerInfo] = (await self.server.get_peer_info())
    last_timestamp_local_info: uint64 = uint64(int(time.time()))
    last_collision_timestamp = 0
    if (self.initial_wait > 0):
        (await asyncio.sleep(self.initial_wait))
    introducer_backoff = 1
    while (not self.is_closed):
        try:
            assert (self.address_manager is not None)
            size = (await self.address_manager.size())
            if ((size == 0) or retry_introducers):
                try:
                    (await asyncio.sleep(introducer_backoff))
                except asyncio.CancelledError:
                    return None
                if (((introducer_attempts % 3) == 0) and (len(self.dns_servers) > 0)):
                    dns_address = self.dns_servers[dns_server_index]
                    dns_server_index = ((dns_server_index + 1) % len(self.dns_servers))
                    (await self._query_dns(dns_address))
                else:
                    (await self._introducer_client())
                    try:
                        (await asyncio.sleep(5))
                    except asyncio.CancelledError:
                        return None
                retry_introducers = False
                introducer_attempts += 1
                if (introducer_backoff < 300):
                    introducer_backoff *= 2
                continue
            else:
                introducer_backoff = 1
            groups = set()
            full_node_connected = self.server.get_full_node_outgoing_connections()
            connected = [c.get_peer_info() for c in full_node_connected]
            connected = [c for c in connected if (c is not None)]
            for conn in full_node_connected:
                peer = conn.get_peer_info()
                if (peer is None):
                    continue
                group = peer.get_group()
                groups.add(group)
            is_feeler = False
            has_collision = False
            if (self._num_needed_peers() == 0):
                if (((time.time() * 1000) * 1000) > next_feeler):
                    next_feeler = self._poisson_next_send(((time.time() * 1000) * 1000), 240, random)
                    is_feeler = True
            (await self.address_manager.resolve_tried_collisions())
            tries = 0
            now = time.time()
            got_peer = False
            addr: Optional[PeerInfo] = None
            max_tries = 50
            if (len(groups) < 3):
                max_tries = 10
            elif (len(groups) <= 5):
                max_tries = 25
            select_peer_interval = max(0.1, (len(groups) * 0.25))
            while ((not got_peer) and (not self.is_closed)):
                self.log.debug(f'Address manager query count: {tries}. Query limit: {max_tries}')
                try:
                    (await asyncio.sleep(select_peer_interval))
                except asyncio.CancelledError:
                    return None
                tries += 1
                if (tries > max_tries):
                    addr = None
                    retry_introducers = True
                    break
                info: Optional[ExtendedPeerInfo] = (await self.address_manager.select_tried_collision())
                if ((info is None) or ((time.time() - last_collision_timestamp) <= 60)):
                    info = (await self.address_manager.select_peer(is_feeler))
                else:
                    has_collision = True
                    last_collision_timestamp = int(time.time())
                if (info is None):
                    if (not is_feeler):
                        retry_introducers = True
                    break
                addr = info.peer_info
                if has_collision:
                    break
                if ((addr is not None) and (not addr.is_valid())):
                    addr = None
                    continue
                if ((not is_feeler) and (addr.get_group() in groups)):
                    addr = None
                    continue
                if (addr in connected):
                    addr = None
                    continue
                if ((now - info.last_try) < 1800):
                    continue
                if (((time.time() - last_timestamp_local_info) > 1800) or (local_peerinfo is None)):
                    local_peerinfo = (await self.server.get_peer_info())
                    last_timestamp_local_info = uint64(int(time.time()))
                if ((local_peerinfo is not None) and (addr == local_peerinfo)):
                    continue
                got_peer = True
                self.log.debug(f'Addrman selected address: {addr}.')
            disconnect_after_handshake = is_feeler
            extra_peers_needed = self._num_needed_peers()
            if (extra_peers_needed == 0):
                disconnect_after_handshake = True
                retry_introducers = False
            self.log.debug(f'Num peers needed: {extra_peers_needed}')
            initiate_connection = ((extra_peers_needed > 0) or has_collision or is_feeler)
            connect_peer_interval = max(0.25, (len(groups) * 0.5))
            if (not initiate_connection):
                connect_peer_interval += 15
            connect_peer_interval = min(connect_peer_interval, self.peer_connect_interval)
            if ((addr is not None) and initiate_connection and (addr.host not in self.pending_outbound_connections)):
                if (len(self.pending_outbound_connections) >= MAX_CONCURRENT_OUTBOUND_CONNECTIONS):
                    self.log.debug('Max concurrent outbound connections reached. waiting')
                    (await asyncio.wait(self.pending_tasks, return_when=asyncio.FIRST_COMPLETED))
                self.pending_tasks.add(asyncio.create_task(self.start_client_async(addr, disconnect_after_handshake)))
            (await asyncio.sleep(connect_peer_interval))
            self.pending_task = set(filter((lambda t: (not t.done())), self.pending_tasks))
        except Exception as e:
            self.log.error(f'Exception in create outbound connections: {e}')
            self.log.error(f'Traceback: {traceback.format_exc()}')
async def _connect_to_peers(self, random) -> None:
    next_feeler = self._poisson_next_send(((time.time() * 1000) * 1000), 240, random)
    retry_introducers = False
    introducer_attempts: int = 0
    dns_server_index: int = 0
    local_peerinfo: Optional[PeerInfo] = (await self.server.get_peer_info())
    last_timestamp_local_info: uint64 = uint64(int(time.time()))
    last_collision_timestamp = 0
    if (self.initial_wait > 0):
        (await asyncio.sleep(self.initial_wait))
    introducer_backoff = 1
    while (not self.is_closed):
        try:
            assert (self.address_manager is not None)
            size = (await self.address_manager.size())
            if ((size == 0) or retry_introducers):
                try:
                    (await asyncio.sleep(introducer_backoff))
                except asyncio.CancelledError:
                    return None
                if (((introducer_attempts % 3) == 0) and (len(self.dns_servers) > 0)):
                    dns_address = self.dns_servers[dns_server_index]
                    dns_server_index = ((dns_server_index + 1) % len(self.dns_servers))
                    (await self._query_dns(dns_address))
                else:
                    (await self._introducer_client())
                    try:
                        (await asyncio.sleep(5))
                    except asyncio.CancelledError:
                        return None
                retry_introducers = False
                introducer_attempts += 1
                if (introducer_backoff < 300):
                    introducer_backoff *= 2
                continue
            else:
                introducer_backoff = 1
            groups = set()
            full_node_connected = self.server.get_full_node_outgoing_connections()
            connected = [c.get_peer_info() for c in full_node_connected]
            connected = [c for c in connected if (c is not None)]
            for conn in full_node_connected:
                peer = conn.get_peer_info()
                if (peer is None):
                    continue
                group = peer.get_group()
                groups.add(group)
            is_feeler = False
            has_collision = False
            if (self._num_needed_peers() == 0):
                if (((time.time() * 1000) * 1000) > next_feeler):
                    next_feeler = self._poisson_next_send(((time.time() * 1000) * 1000), 240, random)
                    is_feeler = True
            (await self.address_manager.resolve_tried_collisions())
            tries = 0
            now = time.time()
            got_peer = False
            addr: Optional[PeerInfo] = None
            max_tries = 50
            if (len(groups) < 3):
                max_tries = 10
            elif (len(groups) <= 5):
                max_tries = 25
            select_peer_interval = max(0.1, (len(groups) * 0.25))
            while ((not got_peer) and (not self.is_closed)):
                self.log.debug(f'Address manager query count: {tries}. Query limit: {max_tries}')
                try:
                    (await asyncio.sleep(select_peer_interval))
                except asyncio.CancelledError:
                    return None
                tries += 1
                if (tries > max_tries):
                    addr = None
                    retry_introducers = True
                    break
                info: Optional[ExtendedPeerInfo] = (await self.address_manager.select_tried_collision())
                if ((info is None) or ((time.time() - last_collision_timestamp) <= 60)):
                    info = (await self.address_manager.select_peer(is_feeler))
                else:
                    has_collision = True
                    last_collision_timestamp = int(time.time())
                if (info is None):
                    if (not is_feeler):
                        retry_introducers = True
                    break
                addr = info.peer_info
                if has_collision:
                    break
                if ((addr is not None) and (not addr.is_valid())):
                    addr = None
                    continue
                if ((not is_feeler) and (addr.get_group() in groups)):
                    addr = None
                    continue
                if (addr in connected):
                    addr = None
                    continue
                if ((now - info.last_try) < 1800):
                    continue
                if (((time.time() - last_timestamp_local_info) > 1800) or (local_peerinfo is None)):
                    local_peerinfo = (await self.server.get_peer_info())
                    last_timestamp_local_info = uint64(int(time.time()))
                if ((local_peerinfo is not None) and (addr == local_peerinfo)):
                    continue
                got_peer = True
                self.log.debug(f'Addrman selected address: {addr}.')
            disconnect_after_handshake = is_feeler
            extra_peers_needed = self._num_needed_peers()
            if (extra_peers_needed == 0):
                disconnect_after_handshake = True
                retry_introducers = False
            self.log.debug(f'Num peers needed: {extra_peers_needed}')
            initiate_connection = ((extra_peers_needed > 0) or has_collision or is_feeler)
            connect_peer_interval = max(0.25, (len(groups) * 0.5))
            if (not initiate_connection):
                connect_peer_interval += 15
            connect_peer_interval = min(connect_peer_interval, self.peer_connect_interval)
            if ((addr is not None) and initiate_connection and (addr.host not in self.pending_outbound_connections)):
                if (len(self.pending_outbound_connections) >= MAX_CONCURRENT_OUTBOUND_CONNECTIONS):
                    self.log.debug('Max concurrent outbound connections reached. waiting')
                    (await asyncio.wait(self.pending_tasks, return_when=asyncio.FIRST_COMPLETED))
                self.pending_tasks.add(asyncio.create_task(self.start_client_async(addr, disconnect_after_handshake)))
            (await asyncio.sleep(connect_peer_interval))
            self.pending_task = set(filter((lambda t: (not t.done())), self.pending_tasks))
        except Exception as e:
            self.log.error(f'Exception in create outbound connections: {e}')
            self.log.error(f'Traceback: {traceback.format_exc()}')