Exemple #1
0
def scheduler():
    Alarm = get_contract('Alarm')
    CallerPool = get_contract('CallerPool')

    alarm = Alarm(alarm_address, rpc_client)
    caller_pool = CallerPool(alarm.getCallerPoolAddress.call(), rpc_client)

    block_sage = BlockSage(rpc_client)
    pool_manager = PoolManager(caller_pool, block_sage=block_sage)
    pool_manager.monitor_async()
    scheduler = Scheduler(alarm, pool_manager, block_sage=block_sage)

    scheduler.monitor_async()

    try:
        while scheduler._thread.is_alive():
            time.sleep(1)

    except KeyboardInterrupt:
        scheduler.stop()
        scheduler.block_sage.stop()
        scheduler.pool_manager.stop()
        for scheduled_call in scheduler.active_calls.values():
            scheduled_call.stop()
        scheduler._thread.join(5)
Exemple #2
0
def scheduler(address):
    """
    Run the call scheduler.
    """
    Alarm = get_contract('Alarm')

    alarm = Alarm(address, rpc_client)

    block_sage = BlockSage(rpc_client)
    pool_manager = PoolManager(alarm, block_sage=block_sage)
    pool_manager.monitor_async()
    scheduler = Scheduler(alarm, pool_manager, block_sage=block_sage)

    scheduler.monitor_async()

    try:
        while scheduler._thread.is_alive():
            time.sleep(1)

    except KeyboardInterrupt:
        scheduler.stop()
        scheduler.block_sage.stop()
        scheduler.pool_manager.stop()
        for scheduled_call in scheduler.active_calls.values():
            scheduled_call.stop()
        scheduler._thread.join(5)
Exemple #3
0
def scheduler(address):
    """
    Run the call scheduler.
    """
    Alarm = get_contract('Scheduler')

    alarm = Alarm(address, rpc_client)

    block_sage = BlockSage(rpc_client)
    pool_manager = PoolManager(alarm, block_sage=block_sage)
    pool_manager.monitor_async()
    scheduler = Scheduler(alarm, pool_manager, block_sage=block_sage)

    scheduler.monitor_async()

    try:
        while scheduler._thread.is_alive():
            time.sleep(1)

    except KeyboardInterrupt:
        scheduler.stop()
        scheduler.block_sage.stop()
        scheduler.pool_manager.stop()
        for scheduled_call in scheduler.active_calls.values():
            scheduled_call.stop()
        scheduler._thread.join(5)
Exemple #4
0
def pool_minimum(denomination, address):
    """
    Check the current minimum bond balance.
    """
    Alarm = get_contract('Alarm')
    alarm = Alarm(address, rpc_client)

    pool_manager = PoolManager(alarm)
    minimum_bond = pool_manager.minimum_bond
    click.echo("Minimum Bond: {0}".format(
        convert_wei_to_denomination(minimum_bond, denomination), ))
Exemple #5
0
def pool_balance(denomination, address):
    """
    Check your bond balance with the caller pool.
    """
    Alarm = get_contract('Alarm')
    alarm = Alarm(address, rpc_client)

    pool_manager = PoolManager(alarm)
    balance = pool_manager.bond_balance
    click.echo("Balance: {0}".format(
        convert_wei_to_denomination(balance, denomination), ))
Exemple #6
0
def pool_status(address):
    """
    Display some status information about the caller pools.
    """
    Alarm = get_contract('Scheduler')
    alarm = Alarm(address, rpc_client)
    pool_manager = PoolManager(alarm)

    status_msg = (
        "Current Block      : {b}\n"
        "Current Generation : {ap} - {ap_m} - ({ap_s})\n"
        "Next Generation    : {np} - {np_m} - ({np_s})"
    ).format(
        b=pool_manager.block_sage.current_block_number,
        ap=(pool_manager.current_generation_id or "N/A"),
        ap_m=pool_manager.get_generation_size(pool_manager.current_generation_id),
        ap_s="member" if pool_manager.in_current_generation else "not member",
        np=(pool_manager.next_generation_id or "N/A"),
        np_m=pool_manager.get_generation_size(pool_manager.next_generation_id),
        np_s="member" if pool_manager.in_next_generation else "not member",
    )
    click.echo(status_msg)
Exemple #7
0
def pool_status():
    Alarm = get_contract('Alarm')
    alarm = Alarm(alarm_address, rpc_client)
    CallerPool = get_contract('CallerPool')

    caller_pool = CallerPool(alarm.getCallerPoolAddress.call(), rpc_client)

    pool_manager = PoolManager(caller_pool)

    status_msg = (
        "Current Block: {b}\n"
        "Active Pool: {ap} - {ap_m} - ({ap_s})\n"
        "Next Pool  : {np} - {np_m} - ({np_s})"
    ).format(
        b=pool_manager.block_sage.current_block_number,
        ap=(pool_manager.active_pool or "N/A"),
        ap_m=pool_manager.get_pool_size(pool_manager.active_pool),
        ap_s="member" if pool_manager.in_active_pool else "not member",
        np=(pool_manager.next_pool or "N/A"),
        np_m=pool_manager.get_pool_size(pool_manager.next_pool),
        np_s="member" if pool_manager.in_next_pool else "not member",
    )
    click.echo(status_msg)
Exemple #8
0
def pool_status(address):
    """
    Display some status information about the caller pools.
    """
    Alarm = get_contract('Alarm')
    alarm = Alarm(address, rpc_client)
    pool_manager = PoolManager(alarm)

    status_msg = ("Current Block      : {b}\n"
                  "Current Generation : {ap} - {ap_m} - ({ap_s})\n"
                  "Next Generation    : {np} - {np_m} - ({np_s})").format(
                      b=pool_manager.block_sage.current_block_number,
                      ap=(pool_manager.current_generation_id or "N/A"),
                      ap_m=pool_manager.get_generation_size(
                          pool_manager.current_generation_id),
                      ap_s="member"
                      if pool_manager.in_current_generation else "not member",
                      np=(pool_manager.next_generation_id or "N/A"),
                      np_m=pool_manager.get_generation_size(
                          pool_manager.next_generation_id),
                      np_s="member"
                      if pool_manager.in_next_generation else "not member",
                  )
    click.echo(status_msg)
Exemple #9
0
def test_scheduled_call_execution_without_pool(geth_node, geth_node_config, deploy_client, deployed_contracts, contracts):
    alarm = deployed_contracts.Alarm
    client_contract = deployed_contracts.SpecifyBlock

    deposit_amount = get_max_gas(deploy_client) * deploy_client.get_gas_price() * 20
    alarm.deposit.sendTransaction(client_contract._meta.address, value=deposit_amount)

    target_block = deploy_client.get_block_number() + 45

    txn_hash = client_contract.scheduleIt.sendTransaction(alarm._meta.address, target_block)
    wait_for_transaction(deploy_client, txn_hash)

    call_key = alarm.getLastCallKey()
    assert call_key is not None

    scheduled_call = ScheduledCall(alarm, call_key)
    block_sage = scheduled_call.block_sage
    pool_manager = PoolManager(alarm, block_sage=block_sage)

    time.sleep(1)

    assert pool_manager.in_any_pool is False
    scheduled_call.execute_async()

    # let the scheduled call do it's thing.
    assert block_sage.current_block_number < target_block

    wait_till = scheduled_call.target_block + 10
    wait_for_block(
        deploy_client,
        wait_till,
        2 * block_sage.estimated_time_to_block(wait_till),
    )

    for i in range(5):
        if scheduled_call.txn_hash:
            break
        time.sleep(block_sage.block_time)

    assert scheduled_call.txn_hash
    assert scheduled_call.txn_receipt
    assert scheduled_call.txn

    assert alarm.checkIfCalled(scheduled_call.call_key)
    assert scheduled_call.was_called
    assert scheduled_call.target_block <= scheduled_call.called_at_block
    assert scheduled_call.called_at_block <= scheduled_call.target_block + scheduled_call.grace_period
def test_scheduler(geth_node, geth_node_config, deploy_client,
                   deployed_contracts, contracts):
    block_sage = BlockSage(deploy_client)

    alarm = deployed_contracts.Alarm
    client_contract = deployed_contracts.SpecifyBlock

    deposit_amount = get_max_gas(
        deploy_client) * deploy_client.get_gas_price() * 20
    alarm.deposit.sendTransaction(client_contract._meta.address,
                                  value=deposit_amount)

    anchor_block = deploy_client.get_block_number()

    blocks = (1, 4, 4, 8, 30, 40, 50, 60)

    call_keys = []

    for n in blocks:
        wait_for_transaction(
            deploy_client,
            client_contract.scheduleIt.sendTransaction(alarm._meta.address,
                                                       anchor_block + 100 + n))

        last_call_key = alarm.getLastCallKey()
        assert last_call_key is not None

        call_keys.append(last_call_key)

    pool_manager = PoolManager(alarm, block_sage)
    scheduler = Scheduler(alarm, pool_manager, block_sage=block_sage)
    scheduler.monitor_async()

    final_block = anchor_block + 100 + 70
    wait_for_block(
        deploy_client,
        final_block,
        2 * block_sage.estimated_time_to_block(final_block),
    )

    scheduler.stop()
    block_sage.stop()

    results = [alarm.checkIfCalled(k) for k in call_keys]
    assert all(results)
def test_scheduled_call_execution_with_pool(geth_node, geth_coinbase,
                                            geth_node_config, deploy_client,
                                            deployed_contracts, contracts):
    alarm = deployed_contracts.Alarm
    joiner = deployed_contracts.JoinsPool
    client_contract = deployed_contracts.SpecifyBlock

    coinbase = geth_coinbase

    block_sage = BlockSage(deploy_client)

    # Put in our deposit with the alarm contract.
    deposit_amount = get_max_gas(
        deploy_client) * deploy_client.get_gas_price() * 20
    alarm.deposit.sendTransaction(client_contract._meta.address,
                                  value=deposit_amount)

    wait_for_transaction(
        deploy_client,
        joiner.setCallerPool.sendTransaction(alarm._meta.address))

    assert alarm.getBondBalance(coinbase) == 0
    bond_amount = alarm.getMinimumBond() * 10
    # Put in our bond
    wait_for_transaction(deploy_client,
                         alarm.depositBond.sendTransaction(value=bond_amount))

    # Put the contract's bond in
    wait_for_transaction(
        deploy_client,
        deploy_client.send_transaction(to=joiner._meta.address,
                                       value=bond_amount))
    wait_for_transaction(deploy_client,
                         joiner.deposit.sendTransaction(bond_amount))

    # Both join the pool
    wait_for_transaction(deploy_client, joiner.enter.sendTransaction())
    wait_for_transaction(deploy_client, alarm.enterPool.sendTransaction())

    # New pool is formed but not active
    first_generation_id = alarm.getNextGenerationId()
    assert first_generation_id > 0

    # Go ahead and schedule the call.
    generation_start_at = alarm.getGenerationStartAt(first_generation_id)
    target_block = generation_start_at + 5

    txn_hash = client_contract.scheduleIt.sendTransaction(
        alarm._meta.address, target_block)
    wait_for_transaction(deploy_client, txn_hash)

    # Wait for the pool to become active
    wait_for_block(
        deploy_client,
        generation_start_at,
        2 * block_sage.estimated_time_to_block(generation_start_at),
    )

    # We should both be in the pool
    assert alarm.getCurrentGenerationId() == first_generation_id
    assert alarm.isInGeneration(joiner._meta.address,
                                first_generation_id) is True
    assert alarm.isInGeneration(coinbase, first_generation_id) is True

    call_key = alarm.getLastCallKey()
    assert call_key is not None

    scheduled_call = ScheduledCall(alarm, call_key, block_sage=block_sage)
    pool_manager = PoolManager(alarm, block_sage=block_sage)

    scheduled_call.execute_async()

    wait_for_block(
        deploy_client,
        scheduled_call.target_block,
        2 * block_sage.estimated_time_to_block(scheduled_call.target_block),
    )

    for i in range(alarm.getCallWindowSize() * 2):
        if scheduled_call.txn_hash:
            break
        time.sleep(block_sage.block_time)

    assert scheduled_call.txn_hash
    assert scheduled_call.txn_receipt
    assert scheduled_call.txn

    assert scheduled_call.was_called
    assert alarm.checkIfCalled(scheduled_call.call_key)
    assert scheduled_call.target_block <= scheduled_call.called_at_block
    assert scheduled_call.called_at_block <= scheduled_call.target_block + scheduled_call.grace_period
Exemple #12
0
    help="Deposit the bond amount in wei into the CallerPool",
)
@click.option(
    '--address',
    '-a',
    default=DEFAULT_ADDRESS,
    help="Return the current bond balance from the caller pool.",
)
@click.argument('value', type=click.INT)
def pool_deposit(async, address, value):
    """
    Deposit an amount in wei into your caller pool bond balance.
    """
    Alarm = get_contract('Alarm')
    alarm = Alarm(address, rpc_client)
    pool_manager = PoolManager(alarm)

    msg = (
        "Do you want to deposit {0} into the bond balance for the CallerPool "
        "contract at `{1}` for the address `{2}`").format(
            value, alarm._meta.address, pool_manager.coinbase)

    if click.confirm(msg):
        txn_hash = alarm.depositBond.sendTransaction(value=value)
    else:
        click.echo("Deposit cancelled")
        click.exit(1)

    if async:
        wait_for_transaction(rpc_client, txn_hash)
        click.echo(
def test_pool_manager(deploy_client, deployed_contracts):
    scheduler = deployed_contracts.Scheduler

    deposit_amount = scheduler.getMinimumBond.call() * 10

    # Put in our bond
    deploy_client.wait_for_transaction(
        scheduler.depositBond.sendTransaction(value=deposit_amount)
    )

    pool_manager = PoolManager(scheduler)
    block_sage = pool_manager.block_sage

    # should be no pools, nor anyone in them.
    assert pool_manager.current_generation_id == 0
    assert pool_manager.next_generation_id == 0
    assert pool_manager.in_any_pool is False
    assert pool_manager.in_next_generation is False
    assert pool_manager.in_current_generation is False

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

    pool_manager.monitor_async()

    # Wait a few blocks for the pool manager to spin up.
    for _ in range(5):
        deploy_client.evm.mine()
        time.sleep(1)

    first_generation_id = pool_manager.next_generation_id

    # should have initiated joining the next pool but won't be in it yet.
    assert pool_manager.current_generation_id == 0
    assert first_generation_id > 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_generation is True
    assert pool_manager.in_current_generation 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.
    deploy_client.wait_for_block(pool_manager.next_generation_start_at)

    # we should now be in the active pool.
    assert pool_manager.current_generation_id == first_generation_id
    assert pool_manager.next_generation_id == 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_generation is False
    assert pool_manager.in_current_generation 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.
    deploy_client.wait_for_transaction(scheduler.exitPool.sendTransaction())

    second_generation_id = pool_manager.next_generation_id

    # New pool should have been formed.
    assert second_generation_id > first_generation_id

    # 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_generation is False
    assert pool_manager.in_current_generation is True

    # Wait for the next pool to become active plus a little.
    first_generation_end = scheduler.getGenerationEndAt(first_generation_id)
    deploy_client.wait_for_block(
        first_generation_end,
        block_sage.estimated_time_to_block(first_generation_end) * 2,
    )

    # The manager should have rejoined.
    assert pool_manager.current_generation_id == second_generation_id
Exemple #14
0
def test_pool_manager(deploy_client, deployed_contracts):
    alarm = deployed_contracts.Alarm
    coinbase = deploy_client.get_coinbase()

    deposit_amount = alarm.getMinimumBond.call() * 10

    # Put in our bond
    wait_for_transaction(
        deploy_client, alarm.depositBond.sendTransaction(value=deposit_amount))

    pool_manager = PoolManager(alarm)
    block_sage = pool_manager.block_sage

    # should be no pools, nor anyone in them.
    assert pool_manager.current_generation_id == 0
    assert pool_manager.next_generation_id == 0
    assert pool_manager.in_any_pool is False
    assert pool_manager.in_next_generation is False
    assert pool_manager.in_current_generation is False

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

    pool_manager.monitor_async()

    # Wait a few blocks for the pool manager to spin up.
    for _ in range(5):
        deploy_client.evm.mine()

    time.sleep(5)

    first_generation_id = pool_manager.next_generation_id

    # should have initiated joining the next pool but won't be in it yet.
    assert pool_manager.current_generation_id == 0
    assert first_generation_id > 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_generation is True
    assert pool_manager.in_current_generation 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.
    for _ in range(deploy_client.get_block_number(),
                   pool_manager.next_generation_start_at):

        deploy_client.evm.mine()

    # we should now be in the active pool.
    assert pool_manager.current_generation_id == first_generation_id
    assert pool_manager.next_generation_id == 0
    assert pool_manager.in_any_pool is True
    assert pool_manager.in_next_generation is False
    assert pool_manager.in_current_generation 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(deploy_client, alarm.exitPool.sendTransaction())

    second_generation_id = pool_manager.next_generation_id

    # New pool should have been formed.
    assert second_generation_id > first_generation_id

    # 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_generation is False
    assert pool_manager.in_current_generation is True

    # Wait for the next pool to become active plus a little.
    first_generation_end = alarm.getGenerationEndAt(first_generation_id)
    deploy_client.wait_for_block(
        first_generation_end,
        block_sage.estimated_time_to_block(first_generation_end) * 2,
    )

    # The manager should have rejoined.
    assert pool_manager.current_generation_id == second_generation_id