# Buggy code
def set_worker(
    click_config,
    # Worker Options
    poa,
    light,
    registry_filepath,
    config_file,
    provider_uri,
    staking_address,
    hw_wallet,
    beneficiary_address,
    allocation_filepath,
    worker_address,
    # Other options
    force,
):
    """
    Bond a worker to a staker.
    """

    ### Setup ###
    emitter = _setup_emitter(click_config)

    STAKEHOLDER, blockchain = _create_stakeholder(
        config_file,
        provider_uri,
        poa,
        light,
        registry_filepath,
        staking_address,
        beneficiary_address=beneficiary_address,
        allocation_filepath=allocation_filepath,
    )
    #############

    economics = STAKEHOLDER.economics

    client_account, staking_address = handle_client_account_for_staking(
        emitter=emitter,
        stakeholder=STAKEHOLDER,
        staking_address=staking_address,
        individual_allocation=STAKEHOLDER.individual_allocation,
        force=force,
    )

    if not worker_address:
        worker_address = click.prompt(
            "Enter worker address", type=EIP55_CHECKSUM_ADDRESS
        )

    # TODO: Check preconditions (e.g., minWorkerPeriods, already in use, etc)

    password = None
    if not hw_wallet and not blockchain.client.is_local:
        password = get_client_password(checksum_address=client_account)

    STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
    receipt = STAKEHOLDER.set_worker(worker_address=worker_address)

    # TODO: Double-check dates
    current_period = STAKEHOLDER.staking_agent.get_current_period()
    bonded_date = datetime_at_period(
        period=current_period, seconds_per_period=economics.seconds_per_period
    )
    min_worker_periods = STAKEHOLDER.staking_agent.staking_parameters()[7]
    release_period = current_period + min_worker_periods
    release_date = datetime_at_period(
        period=release_period,
        seconds_per_period=economics.seconds_per_period,
        start_of_period=True,
    )

    emitter.echo(
        f"\nWorker {worker_address} successfully bonded to staker {staking_address}",
        color="green",
    )
    paint_receipt_summary(
        emitter=emitter,
        receipt=receipt,
        chain_name=blockchain.client.chain_name,
        transaction_type="set_worker",
    )
    emitter.echo(f"Bonded at period #{current_period} ({bonded_date})", color="green")
    emitter.echo(
        f"This worker can be replaced or detached after period "
        f"#{release_period} ({release_date})",
        color="green",
    )


# Traceback (AttributeError)
____    __            __
/\  _`\ /\ \__        /\ \
\ \,\L\_\ \ ,_\    __ \ \ \/'\      __   _ __
\/_\__ \\ \ \/  /'__`\\ \ , <    /'__`\/\`'__\
/\ \L\ \ \ \_/\ \L\.\\ \ \\`\ /\  __/\ \ \/
\ `\____\ \__\ \__/.\_\ \_\ \_\ \____\\ \_\
\/_____/\/__/\/__/\/_/\/_/\/_/\/____/ \/_/

The Holder of Stakes.

======================================= Active Stakes =========================================

| ~ | Staker | Worker | # | Value    | Duration     | Enactment
|   | ------ | ------ | - | -------- | ------------ | -----------------------------------------
| 0 | 0xFD3D | 0x1368 | 0 | 15000 NU | 45 periods . | Aug 06 21:00:30 PDT - Sep 20 21:00:30 PDT
| 1 | 0xFD3D | 0x1368 | 1 | 100000 NU | 300 periods  | Oct 01 21:00:30 PDT - Jul 27 21:00:30 PDT
| 2 | 0x9CA6 | 0x3d51 | 0 | 175864.607570726413344034 NU | 33 periods . | Aug 25 21:00:30 PDT - Sep 27 21:00:30 PDT
| 3 | 0x9CA6 | 0x3d51 | 1 | 200000 NU | 365 periods  | Oct 01 21:00:30 PDT - Sep 30 21:00:30 PDT
| 4 | 0x26FD | 0x4801 | 0 | 50000 NU | 60 periods . | Sep 01 21:00:30 PDT - Oct 31 21:00:30 PDT

Select Stake: 4
Enter target value (must be less than or equal to 50000 NU): 40000
Enter number of periods to extend: 250
Traceback (most recent call last):
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/bin/nucypher", line 11, in <module>
load_entry_point('nucypher', 'console_scripts', 'nucypher')()
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/config.py", line 217, in wrapper
return func(config, *args, **kwargs)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/characters/stake.py", line 365, in stake
extension=extension)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/painting.py", line 406, in paint_staged_stake_division
new_end_period = original_stake.end_period + extension
AttributeError: 'Stake' object has no attribute 'end_period'
Sentry is attempting to send 0 pending error messages
Waiting up to 2.0 seconds
Press Ctrl-C to quit

# Fixed code
def set_worker(
    click_config,
    # Worker Options
    poa,
    light,
    registry_filepath,
    config_file,
    provider_uri,
    staking_address,
    hw_wallet,
    beneficiary_address,
    allocation_filepath,
    worker_address,
    # Other options
    force,
):
    """
    Bond a worker to a staker.
    """

    ### Setup ###
    emitter = _setup_emitter(click_config)

    STAKEHOLDER, blockchain = _create_stakeholder(
        config_file,
        provider_uri,
        poa,
        light,
        registry_filepath,
        staking_address,
        beneficiary_address=beneficiary_address,
        allocation_filepath=allocation_filepath,
    )
    #############

    economics = STAKEHOLDER.economics

    client_account, staking_address = handle_client_account_for_staking(
        emitter=emitter,
        stakeholder=STAKEHOLDER,
        staking_address=staking_address,
        individual_allocation=STAKEHOLDER.individual_allocation,
        force=force,
    )

    if not worker_address:
        worker_address = click.prompt(
            "Enter worker address", type=EIP55_CHECKSUM_ADDRESS
        )

    # TODO: Check preconditions (e.g., minWorkerPeriods, already in use, etc)

    password = None
    if not hw_wallet and not blockchain.client.is_local:
        password = get_client_password(checksum_address=client_account)

    # TODO: Double-check dates
    # Calculate release datetime
    current_period = STAKEHOLDER.staking_agent.get_current_period()
    bonded_date = datetime_at_period(
        period=current_period, seconds_per_period=economics.seconds_per_period
    )
    min_worker_periods = STAKEHOLDER.economics.minimum_worker_periods
    release_period = current_period + min_worker_periods
    release_date = datetime_at_period(
        period=release_period,
        seconds_per_period=economics.seconds_per_period,
        start_of_period=True,
    )

    click.confirm(
        f"Commit to bonding "
        f"worker {worker_address} to staker {client_account} "
        f"for a minimum of {STAKEHOLDER.economics.minimum_worker_periods} periods?",
        abort=True,
    )

    STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
    receipt = STAKEHOLDER.set_worker(worker_address=worker_address)

    # Report Success
    emitter.echo(
        f"\nWorker {worker_address} successfully bonded to staker {staking_address}",
        color="green",
    )
    paint_receipt_summary(
        emitter=emitter,
        receipt=receipt,
        chain_name=blockchain.client.chain_name,
        transaction_type="set_worker",
    )
    emitter.echo(f"Bonded at period #{current_period} ({bonded_date})", color="green")
    emitter.echo(
        f"This worker can be replaced or detached after period "
        f"#{release_period} ({release_date})",
        color="green",
    )