'Handler for the remove event of a tunnel. This function will attempt to create a block for the amounts that
were transferred using the tunnel.
:param subject: Category of the notifier event
:param change_type: Type of the notifier event
:param tunnel: The tunnel that was removed (closed)
:param candidate: The dispersy candidate with whom this node has interacted in the tunnel'

@blocking_call_on_reactor_thread
def on_tunnel_remove(self, subject, change_type, tunnel, candidate):

    from Tribler.community.tunnel.tunnel_community import Circuit, RelayRoute, TunnelExitSocket
    assert (isinstance(tunnel, Circuit) or isinstance(tunnel, RelayRoute) or isinstance(tunnel, TunnelExitSocket)), 'on_tunnel_remove()    was    called    with    an    object    that    is    not    a    Circuit,    RelayRoute    or    TunnelExitSocket'
    assert (isinstance(tunnel.bytes_up, int) and isinstance(tunnel.bytes_down, int)), 'tunnel    instance    must    provide    byte    counts    in    int'
    up = tunnel.bytes_up
    down = tunnel.bytes_down
    pk = candidate.get_member().public_key
    if ((up + down) >= MIN_TRANSACTION_SIZE):
        if ((up > down) or ((up == down) and (self.my_member.public_key > pk))):
            self.register_task(('sign_%s' % tunnel.circuit_id), reactor.callLater(self.SIGN_DELAY, self.sign_block, candidate, pk, {'up': tunnel.bytes_up, 'down': tunnel.bytes_down}))
        else:
            pend = self.pending_bytes.get(pk)
            if (not pend):
                task = self.register_task(('cleanup_pending_%s' % tunnel.circuit_id), reactor.callLater((2 * 60), self.cleanup_pending, pk))
                self.pending_bytes[pk] = PendingBytes(up, down, task)
            else:
                pend.add(up, down)
