예제 #1
0
def test_initiate_validator_exit(genesis_state, is_already_exited, config):
    state = genesis_state
    index = random.choice(range(len(state.validators)))
    validator = state.validators[index]
    assert not validator.slashed
    assert validator.activation_epoch == config.GENESIS_EPOCH
    assert validator.activation_eligibility_epoch == config.GENESIS_EPOCH
    assert validator.exit_epoch == FAR_FUTURE_EPOCH
    assert validator.withdrawable_epoch == FAR_FUTURE_EPOCH

    if is_already_exited:
        churn_limit = get_validator_churn_limit(state, config)
        exit_queue_epoch = _compute_exit_queue_epoch(state, churn_limit,
                                                     config)
        validator = validator.copy(
            exit_epoch=exit_queue_epoch,
            withdrawable_epoch=exit_queue_epoch +
            config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY,
        )

    exited_validator = initiate_exit_for_validator(validator, state, config)

    if is_already_exited:
        assert exited_validator == validator
    else:
        churn_limit = get_validator_churn_limit(state, config)
        exit_queue_epoch = _compute_exit_queue_epoch(state, churn_limit,
                                                     config)
        assert exited_validator.exit_epoch == exit_queue_epoch
        assert exited_validator.withdrawable_epoch == (
            exit_queue_epoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
예제 #2
0
def process_registry_updates(state: BeaconState,
                             config: Eth2Config) -> BeaconState:
    new_state = state
    for index in range(len(state.validators)):
        new_state = _process_activation_eligibility_or_ejections(
            new_state, index, config)

    # Queue validators eligible for activation and not yet dequeued for activation
    activation_queue = sorted(
        (index for index, validator in enumerate(new_state.validators)
         if validator.is_eligible_for_activation(state)),
        # Order by the sequence of activation_eligibility_epoch setting and then index
        key=lambda index: (
            new_state.validators[index].activation_eligibility_epoch,
            index,
        ),
    )

    # Dequeued validators for activation up to churn limit
    for index in activation_queue[:get_validator_churn_limit(state, config)]:
        new_state = new_state.transform(
            ("validators", index),
            _update_validator_activation_epoch(state, config))

    return new_state
예제 #3
0
def process_registry_updates(state: BeaconState, config: Eth2Config) -> BeaconState:
    new_validators = tuple(
        _process_activation_eligibility_or_ejections(state, validator, config)
        for validator in state.validators
    )

    activation_exit_epoch = compute_activation_exit_epoch(
        state.finalized_checkpoint.epoch, config.ACTIVATION_EXIT_DELAY
    )
    activation_queue = sorted(
        (
            index
            for index, validator in enumerate(new_validators)
            if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH
            and validator.activation_epoch >= activation_exit_epoch
        ),
        key=lambda index: new_validators[index].activation_eligibility_epoch,
    )

    for index in activation_queue[: get_validator_churn_limit(state, config)]:
        new_validators = update_tuple_item_with_fn(
            new_validators, index, _update_validator_activation_epoch(state, config)
        )

    return state.copy(validators=new_validators)
예제 #4
0
def initiate_exit_for_validator(validator: Validator, state: BeaconState,
                                config: Eth2Config) -> Validator:
    """
    Performs the mutations to ``validator`` used to initiate an exit.
    More convenient given our immutability patterns compared to ``initiate_validator_exit``.
    """
    if validator.exit_epoch != FAR_FUTURE_EPOCH:
        return validator

    churn_limit = get_validator_churn_limit(state, config)
    exit_queue_epoch = _compute_exit_queue_epoch(state, churn_limit, config)

    return validator.copy(
        exit_epoch=exit_queue_epoch,
        withdrawable_epoch=Epoch(exit_queue_epoch +
                                 config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY),
    )
예제 #5
0
def process_registry_updates(state: BeaconState,
                             config: Eth2Config) -> BeaconState:
    new_validators = state.validators
    for index, validator in enumerate(state.validators):
        new_validator = _process_activation_eligibility_or_ejections(
            state, validator, config)
        new_validators = new_validators.set(index, new_validator)

    activation_exit_epoch = compute_activation_exit_epoch(
        state.finalized_checkpoint.epoch, config.MAX_SEED_LOOKAHEAD)
    activation_queue = sorted(
        (index for index, validator in enumerate(new_validators)
         if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH
         and validator.activation_epoch >= activation_exit_epoch),
        key=lambda index: new_validators[index].activation_eligibility_epoch,
    )

    for index in activation_queue[:get_validator_churn_limit(state, config)]:
        new_validators = new_validators.transform(
            (index, ), _update_validator_activation_epoch(state, config))

    return state.set("validators", new_validators)
def test_get_validator_churn_limit(genesis_state, expected_churn_limit,
                                   config):
    assert get_validator_churn_limit(genesis_state,
                                     config) == expected_churn_limit