# Buggy code
def should_join_circuit(self, create_payload, previous_node_address):
    """
    Check whether we should join a circuit. Returns a future that fires with a boolean.
    """
    if self.settings.max_joined_circuits <= len(self.relay_from_to) + len(
        self.exit_sockets
    ):
        self.logger.warning(
            "too many relays (%d)", (len(self.relay_from_to) + len(self.exit_sockets))
        )
        return succeed(False)

    # Check whether we have a random open slot, if so, allocate this to this request.
    circuit_id = create_payload.circuit_id
    for index, slot in enumerate(self.random_slots):
        if not slot:
            self.random_slots[index] = circuit_id
            return succeed(True)

    # No random slots but this user might be allocated a competing slot.
    # Next, we request the token balance of the circuit initiator.
    balance_future = Future()
    self.request_cache.add(BalanceRequestCache(self, circuit_id, balance_future))

    # Temporarily add these values, otherwise we are unable to communicate with the previous hop.
    self.directions[circuit_id] = EXIT_NODE
    shared_secret, _, _ = self.crypto.generate_diffie_shared_secret(create_payload.key)
    self.relay_session_keys[circuit_id] = self.crypto.generate_session_keys(
        shared_secret
    )

    self.send_cell(
        Peer(create_payload.node_public_key, previous_node_address),
        "balance-request",
        BalanceRequestPayload(circuit_id),
    )

    self.directions.pop(circuit_id, None)
    self.relay_session_keys.pop(circuit_id, None)

    return balance_future


# Traceback (RuntimeError)
Traceback (most recent call last):
File "src\tribler-gui\tribler_gui\event_request_manager.py", line 116, in on_read_data
RuntimeError:
--LONG TEXT--
Traceback (most recent call last):
File "lib\asyncio\events.py", line 81, in _run
File "ipv8\messaging\anonymization\tunnel.py", line 149, in on_ip_address
asyncio.exceptions.CancelledError

--CONTEXT--
{'message': 'Exception in callback TunnelExitSocket.sendto.<locals>.on_ip_address(<Task cancell...unnel.py:171>>) at ipv8\\messaging\\anonymization\\tunnel.py:147', 'exception': CancelledError(), 'handle': <Handle TunnelExitSocket.sendto.<locals>.on_ip_address(<Task cancell...unnel.py:171>>) at ipv8\messaging\anonymization\tunnel.py:147>}

# Fixed code
def should_join_circuit(self, create_payload, previous_node_address):
    """
    Check whether we should join a circuit. Returns a future that fires with a boolean.
    """
    if self.settings.max_joined_circuits <= len(self.relay_from_to) + len(
        self.exit_sockets
    ):
        self.logger.warning(
            "too many relays (%d)", (len(self.relay_from_to) + len(self.exit_sockets))
        )
        return succeed(False)

    # Check whether we have a random open slot, if so, allocate this to this request.
    circuit_id = create_payload.circuit_id
    for index, slot in enumerate(self.random_slots):
        if not slot:
            self.random_slots[index] = circuit_id
            return succeed(True)

    # No random slots but this user might be allocated a competing slot.
    # Next, we request the token balance of the circuit initiator.
    balance_future = Future()
    self.request_cache.add(BalanceRequestCache(self, circuit_id, balance_future))

    # Temporarily add these values, otherwise we are unable to communicate with the previous hop.
    self.directions[circuit_id] = EXIT_NODE
    shared_secret, _, _ = self.crypto.generate_diffie_shared_secret(create_payload.key)
    self.relay_session_keys[circuit_id] = self.crypto.generate_session_keys(
        shared_secret
    )

    self.send_cell(
        Peer(create_payload.node_public_key, previous_node_address),
        BalanceRequestPayload(circuit_id),
    )

    self.directions.pop(circuit_id, None)
    self.relay_session_keys.pop(circuit_id, None)

    return balance_future