コード例 #1
0
def enable_claiming(general_config: GroupGeneralConfig,
                    worklock_options: WorkLockOptions,
                    force: bool,
                    hw_wallet: bool,
                    gas_limit: int):
    """Ensure correctness of WorkLock participants and enable allocation"""
    emitter, registry, blockchain = worklock_options.setup(general_config=general_config)
    bidder_address = worklock_options.get_bidder_address(emitter, registry)
    bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)

    whales = bidder.get_whales()
    if whales:
        headers = ("Participants that require correction", "Current bonus")
        columns = (whales.keys(), map(prettify_eth_amount, whales.values()))
        emitter.echo(tabulate.tabulate(dict(zip(headers, columns)), headers=headers, floatfmt="fancy_grid"))

        if not force:
            click.confirm(f"Confirm force refund to at least {len(whales)} participants using {bidder_address}?", abort=True)

        force_refund_receipt = bidder.force_refund()
        emitter.echo(WHALE_WARNING.format(number=len(whales)), color='green')

        paint_receipt_summary(receipt=force_refund_receipt,
                              emitter=emitter,
                              chain_name=bidder.staking_agent.blockchain.client.chain_name,
                              transaction_type=f"force-refund")
    else:
        emitter.echo(BIDS_VALID_NO_FORCE_REFUND_INDICATED, color='yellow')

    if not bidder.worklock_agent.bidders_checked():

        confirmation = gas_limit and force
        while not confirmation:
            if not gas_limit:
                min_gas = 180000
                gas_limit = click.prompt(PROMPT_BID_VERIFY_GAS_LIMIT.format(min_gas=min_gas), type=click.IntRange(min=min_gas))

            bidders_per_transaction = bidder.worklock_agent.estimate_verifying_correctness(gas_limit=gas_limit)

            if not force:
                message = CONFIRM_BID_VERIFICATION.format(bidder_address=bidder_address,
                                                          gas_limit=gas_limit,
                                                          bidders_per_transaction=bidders_per_transaction)
                confirmation = click.confirm(message)
                gas_limit = gas_limit if confirmation else None
            else:
                emitter.echo(VERIFICATION_ESTIMATES.format(gas_limit=gas_limit,
                                                           bidders_per_transaction=bidders_per_transaction))
                confirmation = True

        verification_receipts = bidder.verify_bidding_correctness(gas_limit=gas_limit)
        emitter.echo(COMPLETED_BID_VERIFICATION, color='green')

        for iteration, receipt in verification_receipts.items():
            paint_receipt_summary(receipt=receipt,
                                  emitter=emitter,
                                  chain_name=bidder.staking_agent.blockchain.client.chain_name,
                                  transaction_type=f"verify-correctness[{iteration}]")
    else:
        emitter.echo(BIDDERS_ALREADY_VERIFIED, color='yellow')
コード例 #2
0
def test_enable_claiming(click_runner,
                         mocker,
                         mock_worklock_agent,
                         surrogate_bidder,
                         token_economics,
                         mock_testerchain):

    # Spy on the corresponding CLI function we are testing
    mock_force_refund = mocker.spy(Bidder, 'force_refund')
    mock_verify = mocker.spy(Bidder, 'verify_bidding_correctness')
    mock_get_whales = mocker.spy(Bidder, 'get_whales')

    # Cancellation window is closed
    now = mock_testerchain.get_blocktime()
    sometime_later = now+(3600*30)
    mocker.patch.object(BlockchainInterface, 'get_blocktime', return_value=sometime_later)

    # Prepare bidders
    bidders = mock_testerchain.client.accounts[0:10]
    num_bidders = len(bidders)
    bonus_lot_value = token_economics.worklock_supply - token_economics.minimum_allowed_locked * num_bidders

    bids_before = [to_wei(50_000, 'ether')]
    min_bid_eth_value = to_wei(1, 'ether')
    max_bid_eth_value = to_wei(10, 'ether')
    for i in range(num_bidders - 1):
        bids_before.append(random.randrange(min_bid_eth_value, max_bid_eth_value))
    bonus_eth_supply_before = sum(bids_before) - token_economics.worklock_min_allowed_bid * num_bidders

    bids_after = [min_bid_eth_value] * num_bidders
    bonus_eth_supply_after = 0

    min_bid = min(bids_before)
    bidder_to_exclude = bids_before.index(min_bid)
    bidders_to_check = bidders.copy()
    del bidders_to_check[bidder_to_exclude]

    mock_worklock_agent.get_bonus_eth_supply.side_effect = [bonus_eth_supply_before, bonus_eth_supply_after, bonus_eth_supply_after]
    mock_worklock_agent.get_bonus_lot_value.return_value = bonus_lot_value
    mock_worklock_agent.get_bidders.return_value = bidders
    mock_worklock_agent.get_deposited_eth.side_effect = [*bids_before, *bids_after, *bids_after]
    mock_worklock_agent.bidders_checked.side_effect = [False, False, False, False, True]
    mock_worklock_agent.next_bidder_to_check.side_effect = [0, num_bidders // 2, num_bidders]
    mock_worklock_agent.estimate_verifying_correctness.side_effect = [3, 6]

    command = ('enable-claiming',
               '--participant-address', surrogate_bidder.checksum_address,
               '--provider', MOCK_PROVIDER_URI,
               '--signer', MOCK_PROVIDER_URI,
               '--network', TEMPORARY_DOMAIN)

    gas_limit_1 = 200000
    gas_limit_2 = 300000
    user_input = '\n'.join((INSECURE_DEVELOPMENT_PASSWORD, YES, str(gas_limit_1), NO, str(gas_limit_2), YES))
    result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
    assert result.exit_code == 0
    confirmation = CONFIRM_BID_VERIFICATION.format(bidder_address=surrogate_bidder.checksum_address,
                                                   gas_limit=gas_limit_1,
                                                   bidders_per_transaction=3)
    assert confirmation in result.output
    confirmation = CONFIRM_BID_VERIFICATION.format(bidder_address=surrogate_bidder.checksum_address,
                                                   gas_limit=gas_limit_2,
                                                   bidders_per_transaction=6)
    assert confirmation in result.output

    # Bidder
    mock_force_refund.assert_called_once()
    mock_verify.assert_called_once()
    mock_get_whales.assert_called()
    assert_successful_transaction_echo(bidder_address=surrogate_bidder.checksum_address, cli_output=result.output)

    # Manual checking of force_refund tx because of unpredictable order of actual bidders_to_check array
    transaction_executions = mock_worklock_agent.force_refund.call_args_list
    assert len(transaction_executions) == 1
    _agent_args, agent_kwargs = transaction_executions[0]
    checksum_address, addresses = agent_kwargs.values()
    assert checksum_address == surrogate_bidder.checksum_address
    assert sorted(addresses) == sorted(bidders_to_check)

    mock_worklock_agent.verify_bidding_correctness.assert_has_calls([
        call(checksum_address=surrogate_bidder.checksum_address, gas_limit=gas_limit_2),
        call(checksum_address=surrogate_bidder.checksum_address, gas_limit=gas_limit_2)
    ])
    mock_worklock_agent.assert_only_transactions([mock_worklock_agent.force_refund,
                                                  mock_worklock_agent.verify_bidding_correctness])

    # Calls
    mock_worklock_agent.estimate_verifying_correctness.assert_has_calls([
        call(gas_limit=gas_limit_1),
        call(gas_limit=gas_limit_2)
    ])
    mock_worklock_agent.get_bidders.assert_called()
    mock_worklock_agent.get_bonus_lot_value.assert_called()
    mock_worklock_agent.get_bonus_eth_supply.assert_called()
    mock_worklock_agent.next_bidder_to_check.assert_called()
    mock_worklock_agent.get_deposited_eth.assert_called()