def test_pool_manager(geth_node, geth_coinbase, rpc_client, deployed_contracts):
    caller_pool = deployed_contracts.CallerPool

    deposit_amount = caller_pool.getMinimumBond.call() * 10
    # Put in our bond
    wait_for_transaction(
        rpc_client, caller_pool.depositBond.sendTransaction(value=deposit_amount)
    )

    pool_manager = PoolManager(caller_pool)

    assert pool_manager.in_any_pool is False

    pool_manager.monitor_async()

    wait_for_block(rpc_client, rpc_client.get_block_number() + 5, 180)

    first_pool_number = pool_manager.next_pool

    assert first_pool_number > 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_pool is True

    wait_for_block(rpc_client, first_pool_number + 5, 180)

    # Now leave the pool (like we got kicked out)

    wait_for_transaction(rpc_client, caller_pool.exitPool.sendTransaction())

    second_pool_number = pool_manager.next_pool
    assert second_pool_number > first_pool_number

    # we should not be in the next pool since we left it.
    assert pool_manager.in_next_pool is False

    wait_for_block(rpc_client, second_pool_number + 5, 180)

    # pool manager should have rejoined now that the next pool is live and we
    # aren't in a freeze.
    third_pool_number = pool_manager.next_pool
    assert third_pool_number > second_pool_number

    assert pool_manager.in_active_pool is False
    assert pool_manager.in_next_pool is True
def test_pool_manager(geth_node, geth_coinbase, rpc_client, deployed_contracts):
    caller_pool = deployed_contracts.CallerPool

    pool_manager = PoolManager(caller_pool)

    # should be no pools, nor anyone in them.
    assert pool_manager.active_pool == 0
    assert pool_manager.next_pool == 0
    assert pool_manager.in_any_pool is False
    assert pool_manager.in_next_pool is False
    assert pool_manager.in_active_pool is False

    # check permissions
    assert pool_manager.can_enter_pool is True
    assert pool_manager.can_exit_pool is False

    pool_manager.run_async()

    # Wait a few blocks for the pool manager to spin up.
    wait_for_block(rpc_client, rpc_client.get_block_number() + 5, 60)

    first_pool = pool_manager.next_pool

    # should have initiated joining the next pool but won't be in it yet.
    assert pool_manager.active_pool == 0
    assert first_pool > 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_pool is True
    assert pool_manager.in_active_pool is False

    # check permissions
    assert pool_manager.can_enter_pool is False
    assert pool_manager.can_exit_pool is False

    # Wait for the pool to become active.
    wait_for_block(rpc_client, first_pool)

    # we should now be in the active pool.
    assert pool_manager.active_pool == first_pool
    assert pool_manager.next_pool == 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_pool is False
    assert pool_manager.in_active_pool is True

    # check permissions
    assert pool_manager.can_enter_pool is False
    assert pool_manager.can_exit_pool is True

    # Now we manually remove ourselves.
    wait_for_transaction(rpc_client, caller_pool.exitPool.sendTransaction())

    second_pool_key = pool_manager.next_pool

    # New pool should have been formed.
    assert second_pool_key > first_pool

    # Current status should not have changed except that the next pool has now
    # been formed but we aren't in it.
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_pool is False
    assert pool_manager.in_active_pool is True

    # Wait for the next pool to become active plus a little.
    wait_for_block(rpc_client, second_pool_key + 5)

    # The manager should have rejoined.
    assert pool_manager.active_pool == second_pool_key
    assert False