Exemplo n.º 1
0
def test_get_delayed_activation_exit_epoch(activation_exit_delay):
    epoch = random.randint(0, FAR_FUTURE_EPOCH)
    entry_exit_effect_epoch = get_delayed_activation_exit_epoch(
        epoch,
        activation_exit_delay,
    )
    assert entry_exit_effect_epoch == (epoch + 1 + activation_exit_delay)
Exemplo n.º 2
0
def test_activate_validator(is_genesis, filled_beacon_state, genesis_epoch,
                            slots_per_epoch, activation_exit_delay,
                            max_deposit_amount, config):
    validator_count = 10
    state = filled_beacon_state.copy(
        validator_registry=tuple(
            mock_validator(
                pubkey=index.to_bytes(48, 'little'),
                config=config,
                is_active=False,
            ) for index in range(validator_count)),
        validator_balances=(max_deposit_amount, ) * validator_count,
    )
    index = 1
    # Check that the `index`th validator in `state` is inactivated
    assert state.validator_registry[index].activation_epoch == FAR_FUTURE_EPOCH

    result_state = activate_validator(
        state=state,
        index=index,
        is_genesis=is_genesis,
        genesis_epoch=genesis_epoch,
        slots_per_epoch=slots_per_epoch,
        activation_exit_delay=activation_exit_delay,
    )

    if is_genesis:
        assert result_state.validator_registry[
            index].activation_epoch == genesis_epoch
    else:
        assert (result_state.validator_registry[index].activation_epoch ==
                get_delayed_activation_exit_epoch(
                    state.current_epoch(slots_per_epoch),
                    activation_exit_delay,
                ))
Exemplo n.º 3
0
def test_exit_validator(num_validators, activation_exit_delay, committee,
                        state_slot, exit_epoch, n_validators_state,
                        slots_per_epoch):
    # Unchanged
    state = n_validators_state.copy(slot=state_slot, )
    index = 1

    # Set validator `exit_epoch` prior to running `exit_validator`
    validator = state.validator_registry[index].copy(exit_epoch=exit_epoch, )
    state = state.update_validator_registry(
        validator_index=index,
        validator=validator,
    )
    result_state = exit_validator(
        state=state,
        index=index,
        slots_per_epoch=slots_per_epoch,
        activation_exit_delay=activation_exit_delay,
    )
    if validator.exit_epoch <= state.current_epoch(
            slots_per_epoch) + activation_exit_delay:
        assert state == result_state
        return
    else:
        assert validator.exit_epoch > state.current_epoch(
            slots_per_epoch) + activation_exit_delay
        result_validator = result_state.validator_registry[index]
        assert result_validator.exit_epoch == get_delayed_activation_exit_epoch(
            state.current_epoch(slots_per_epoch),
            activation_exit_delay,
        )
Exemplo n.º 4
0
def exit_validator(state: BeaconState,
                   index: ValidatorIndex,
                   slots_per_epoch: int,
                   activation_exit_delay: int) -> BeaconState:
    """
    Exit the validator with the given ``index``.
    Return the updated state (immutable).
    """
    validator = state.validator_registry[index]

    delayed_activation_exit_epoch = get_delayed_activation_exit_epoch(
        state.current_epoch(slots_per_epoch),
        activation_exit_delay,
    )

    # The following updates only occur if not previous exited
    if validator.exit_epoch <= delayed_activation_exit_epoch:
        return state

    validator = validator.copy(
        exit_epoch=delayed_activation_exit_epoch,
    )
    state = state.update_validator_registry(index, validator)

    return state
def test_process_ejections(genesis_state, config, activation_exit_delay):
    current_epoch = 8
    state = genesis_state.copy(
        slot=get_epoch_start_slot(current_epoch, config.SLOTS_PER_EPOCH),
    )
    delayed_activation_exit_epoch = get_delayed_activation_exit_epoch(
        current_epoch,
        activation_exit_delay,
    )

    ejecting_validator_index = 0
    validator = state.validator_registry[ejecting_validator_index]
    assert validator.is_active(current_epoch)
    assert validator.exit_epoch > delayed_activation_exit_epoch

    state = state.update_validator_balance(
        validator_index=ejecting_validator_index,
        balance=config.EJECTION_BALANCE - 1,
    )
    result_state = process_ejections(state, config)
    result_validator = result_state.validator_registry[ejecting_validator_index]
    assert result_validator.is_active(current_epoch)
    assert result_validator.exit_epoch == delayed_activation_exit_epoch
    # The ejecting validator will be inactive at the exit_epoch
    assert not result_validator.is_active(result_validator.exit_epoch)
    # Other validators are not ejected
    assert (
        result_state.validator_registry[ejecting_validator_index + 1].exit_epoch ==
        FAR_FUTURE_EPOCH
    )
Exemplo n.º 6
0
def validate_voluntary_exit_validator_exit_epoch(
        state: 'BeaconState', validator: 'ValidatorRecord',
        current_epoch: Epoch, slots_per_epoch: int,
        activation_exit_delay: int) -> None:
    current_epoch = state.current_epoch(slots_per_epoch)

    # Verify the validator has not yet exited
    delayed_activation_exit_epoch = get_delayed_activation_exit_epoch(
        current_epoch,
        activation_exit_delay,
    )
    if validator.exit_epoch <= delayed_activation_exit_epoch:
        raise ValidationError(
            f"validator.exit_epoch ({validator.exit_epoch}) should be greater than "
            f"delayed_activation_exit_epoch ({delayed_activation_exit_epoch})")
Exemplo n.º 7
0
def activate_validator(state: BeaconState, index: ValidatorIndex,
                       is_genesis: bool, genesis_epoch: Epoch,
                       slots_per_epoch: int,
                       activation_exit_delay: int) -> BeaconState:
    """
    Activate the validator with the given ``index``.
    Return the updated state (immutable).
    """
    # Update validator.activation_epoch
    validator = state.validator_registry[index].copy(
        activation_epoch=genesis_epoch
        if is_genesis else get_delayed_activation_exit_epoch(
            state.current_epoch(slots_per_epoch),
            activation_exit_delay,
        ))
    state = state.update_validator_registry(index, validator)

    return state
def test_update_validator_registry(n,
                                   n_validators_state,
                                   config,
                                   slots_per_epoch):
    validator_registry = list(n_validators_state.validator_registry)
    activating_index = n
    exiting_index = 0

    activating_validator = ValidatorRecord.create_pending_validator(
        pubkey=b'\x10' * 48,
        withdrawal_credentials=b'\x11' * 32,
    )

    exiting_validator = n_validators_state.validator_registry[exiting_index].copy(
        exit_epoch=FAR_FUTURE_EPOCH,
        initiated_exit=True,
    )

    validator_registry[exiting_index] = exiting_validator
    validator_registry.append(activating_validator)
    state = n_validators_state.copy(
        validator_registry=validator_registry,
        validator_balances=n_validators_state.validator_balances + (config.MAX_DEPOSIT_AMOUNT,),
    )

    state = update_validator_registry(state, config)

    entry_exit_effect_epoch = get_delayed_activation_exit_epoch(
        state.current_epoch(slots_per_epoch),
        config.ACTIVATION_EXIT_DELAY,
    )

    # Check if the activating_validator is activated
    assert state.validator_registry[activating_index].activation_epoch == entry_exit_effect_epoch
    # Check if the activating_validator is exited
    assert state.validator_registry[exiting_index].exit_epoch == entry_exit_effect_epoch