Ejemplo n.º 1
0
def claim(general_config: GroupGeneralConfig, worklock_options: WorkLockOptions, force: bool, hw_wallet: bool):
    """Claim tokens for your escrow, and start staking them"""
    emitter, registry, blockchain = worklock_options.setup(general_config=general_config)
    worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)  # type: WorkLockAgent
    if not worklock_agent.is_claiming_available():
        emitter.echo(CLAIMING_NOT_AVAILABLE, color='red')
        raise click.Abort()

    bidder_address = worklock_options.get_bidder_address(emitter, registry)
    bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)

    unspent_bid = bidder.available_compensation
    if unspent_bid:
        emitter.echo(WORKLOCK_ADDITIONAL_COMPENSATION_AVAILABLE.format(amount=prettify_eth_amount(unspent_bid)))
        if not force:
            message = CONFIRM_REQUEST_WORKLOCK_COMPENSATION.format(bidder_address=bidder_address)
            click.confirm(message, abort=True)
        emitter.echo(REQUESTING_WORKLOCK_COMPENSATION)
        receipt = bidder.withdraw_compensation()
        paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)

    has_claimed = bidder.has_claimed
    if bool(has_claimed):
        emitter.echo(CLAIM_ALREADY_PLACED.format(bidder_address=bidder.checksum_address), color='red')
        raise click.Abort()

    tokens = NU.from_nunits(bidder.available_claim)
    emitter.echo(AVAILABLE_CLAIM_NOTICE.format(tokens=tokens), color='green', bold=True)
    if not force:
        lock_duration = bidder.worklock_agent.worklock_parameters()[-2]
        emitter.echo(WORKLOCK_CLAIM_ADVISORY.format(lock_duration=lock_duration), color='blue')
        click.confirm(CONFIRM_WORKLOCK_CLAIM.format(bidder_address=bidder_address), abort=True)
    emitter.echo(SUBMITTING_WORKLOCK_CLAIM)

    receipt = bidder.claim()
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    paint_worklock_claim(emitter=emitter,
                         bidder_address=bidder_address,
                         network=worklock_options.network,
                         provider_uri=worklock_options.provider_uri)
def test_initial_claim(click_runner,
                       mocker,
                       mock_worklock_agent,
                       surrogate_bidder):

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

    # First, let's test that if claiming is not available, command fails
    mock_worklock_agent.is_claiming_available.return_value = False
    result = click_runner.invoke(worklock, command, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False)
    assert result.exit_code == 1
    assert CLAIMING_NOT_AVAILABLE in result.output

    # Let's continue with our test and try the command again. But don't forget to restore the previous mock
    mock_worklock_agent.is_claiming_available.return_value = True

    # Spy on the corresponding CLI function we are testing
    mock_withdraw_compensation = mocker.spy(Bidder, 'withdraw_compensation')
    mock_claim = mocker.spy(Bidder, 'claim')

    # TODO: Test this functionality in isolation
    mocker.patch.object(Bidder, '_ensure_cancellation_window')

    # Bidder has not claimed yet
    mocker.patch.object(
        Bidder, 'has_claimed',
        new_callable=mocker.PropertyMock,
        return_value=False
    )

    # Customize mock worklock agent method worklock parameters so position -2 returns lock periods
    mock_worklock_agent.worklock_parameters.return_value = [0xAA, 0xBB, 30, 0xCC]

    user_input = '\n'.join((INSECURE_DEVELOPMENT_PASSWORD, YES, YES))
    result = click_runner.invoke(worklock, command, input=user_input, catch_exceptions=False)
    assert result.exit_code == 0

    assert CONFIRM_REQUEST_WORKLOCK_COMPENSATION.format(bidder_address=bidder_address) in result.output
    assert WORKLOCK_CLAIM_ADVISORY.format(lock_duration=30) in result.output
    assert CONFIRM_WORKLOCK_CLAIM.format(bidder_address=bidder_address) in result.output

    mock_worklock_agent.claim.assert_called_once_with(checksum_address=bidder_address)

    # Bidder
    mock_withdraw_compensation.assert_called_once()
    mock_claim.assert_called_once()
    assert_successful_transaction_echo(bidder_address=bidder_address, cli_output=result.output)

    # Transactions
    mock_worklock_agent.withdraw_compensation.assert_called_with(checksum_address=bidder_address)
    mock_worklock_agent.claim.assert_called_with(checksum_address=bidder_address)

    # Calls
    expected_calls = (mock_worklock_agent.get_deposited_eth,
                      mock_worklock_agent.eth_to_tokens)
    for expected_call in expected_calls:
        expected_call.assert_called()