예제 #1
0
def test_full_random_without_leak_and_current_exit_0(spec, state):
    """
    This test specifically ensures a validator exits in the current epoch
    to ensure rewards are handled properly in this case.
    """
    rng = Random(1011)
    randomize_state(spec, state, rng)
    assert spec.is_in_inactivity_leak(state)
    patch_state_to_non_leaking(spec, state)
    assert not spec.is_in_inactivity_leak(state)
    target_validators = get_unslashed_exited_validators(spec, state)
    assert len(target_validators) != 0

    # move forward some epochs to process attestations added
    # by ``randomize_state`` before we exit validators in
    # what will be the current epoch
    for _ in range(2):
        next_epoch(spec, state)

    current_epoch = spec.get_current_epoch(state)
    for index in target_validators:
        # patch exited validators to exit in the current epoch
        validator = state.validators[index]
        validator.exit_epoch = current_epoch
        validator.withdrawable_epoch = current_epoch + spec.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY

    # re-randomize attestation participation for the current epoch
    randomize_attestation_participation(spec, state, rng)

    assert has_active_balance_differential(spec, state)
    yield from rewards_helpers.run_deltas(spec, state)
예제 #2
0
def test_full_random_without_leak_0(spec, state):
    rng = Random(1010)
    randomize_state(spec, state, rng)
    assert spec.is_in_inactivity_leak(state)
    patch_state_to_non_leaking(spec, state)
    assert not spec.is_in_inactivity_leak(state)
    target_validators = get_unslashed_exited_validators(spec, state)
    assert len(target_validators) != 0
    assert has_active_balance_differential(spec, state)
    yield from rewards_helpers.run_deltas(spec, state)
예제 #3
0
def test_full_random_4(spec, state):
    """
    Ensure a rewards test with some exited (but not slashed) validators.
    """
    rng = Random(5050)
    randomize_state(spec, state, rng)
    assert spec.is_in_inactivity_leak(state)
    target_validators = get_unslashed_exited_validators(spec, state)
    assert len(target_validators) != 0
    assert has_active_balance_differential(spec, state)
    yield from rewards_helpers.run_deltas(spec, state)
예제 #4
0
def test_slashings_with_random_state(spec, state):
    rng = Random(9998)
    randomize_state(spec, state, rng)

    pre_balances = state.balances.copy()

    target_validators = get_unslashed_exited_validators(spec, state)
    assert len(target_validators) != 0
    assert has_active_balance_differential(spec, state)

    slashed_indices = _setup_process_slashings_test(
        spec, state, not_slashable_set=target_validators)

    # ensure no accidental slashings of protected set...
    current_target_validators = get_unslashed_exited_validators(spec, state)
    assert len(current_target_validators) != 0
    assert current_target_validators == target_validators

    yield from run_process_slashings(spec, state)

    for i in slashed_indices:
        assert state.balances[i] < pre_balances[i]
def test_random_with_exits_without_duplicates(spec, state):
    rng = random.Random(1502)
    randomize_state(spec,
                    state,
                    rng=rng,
                    exit_fraction=0.1,
                    slash_fraction=0.0)
    target_validators = get_unslashed_exited_validators(spec, state)
    assert len(target_validators) != 0
    assert has_active_balance_differential(spec, state)
    yield from _test_harness_for_randomized_test_case(
        spec,
        state,
        participation_fn=lambda comm: rng.sample(comm,
                                                 len(comm) // 2),
    )
예제 #6
0
def ensure_state_has_validators_across_lifecycle(spec, state):
    """
    Scan the validator registry to ensure there is at least 1 validator
    for each of the following lifecycle states:
        1. Pending / deposited
        2. Active
        3. Exited (but not slashed)
        4. Slashed
    """
    has_pending = any(
        filter(spec.is_eligible_for_activation_queue, state.validators))

    current_epoch = spec.get_current_epoch(state)
    has_active = any(
        filter(lambda v: spec.is_active_validator(v, current_epoch),
               state.validators))

    has_exited = any(get_unslashed_exited_validators(spec, state))

    has_slashed = any(filter(lambda v: v.slashed, state.validators))

    return has_pending and has_active and has_exited and has_slashed
def _exit_validator_from_committee_and_transition_state(spec,
                                                        state,
                                                        committee_indices,
                                                        rng,
                                                        target_epoch_provider,
                                                        withdrawable_offset=1):
    exited_validator_index = rng.sample(committee_indices, 1)[0]
    validator = state.validators[exited_validator_index]
    current_epoch = spec.get_current_epoch(state)
    validator.exit_epoch = current_epoch
    validator.withdrawable_epoch = validator.exit_epoch + withdrawable_offset

    target_epoch = target_epoch_provider(state.validators[exited_validator_index])
    target_slot = target_epoch * spec.SLOTS_PER_EPOCH
    transition_to(spec, state, target_slot)

    exited_validator_indices = get_unslashed_exited_validators(spec, state)
    assert exited_validator_index in exited_validator_indices
    exited_pubkey = state.validators[exited_validator_index].pubkey
    assert exited_pubkey in state.current_sync_committee.pubkeys

    return exited_validator_index
def test_balance_threshold_with_exited_validators(spec, state):
    """
    This test exercises a very specific failure mode where
    exited validators are incorrectly included in the total active balance
    when weighing justification.
    """
    rng = Random(133333)
    # move past genesis conditions
    for _ in range(3):
        next_epoch_via_block(spec, state)

    # mock attestation helper requires last slot of epoch
    for _ in range(spec.SLOTS_PER_EPOCH - 1):
        next_slot(spec, state)

    # Step 1: Exit ~1/2 vals in current epoch
    epoch = spec.get_current_epoch(state)
    for index in spec.get_active_validator_indices(state, epoch):
        if rng.choice([True, False]):
            continue

        validator = state.validators[index]
        validator.exit_epoch = epoch
        validator.withdrawable_epoch = epoch + 1
        validator.withdrawable_epoch = validator.exit_epoch + spec.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY

    exited_validators = get_unslashed_exited_validators(spec, state)
    assert len(exited_validators) != 0

    source = state.current_justified_checkpoint
    target = spec.Checkpoint(epoch=epoch,
                             root=spec.get_block_root(state, epoch))
    add_mock_attestations(
        spec,
        state,
        epoch,
        source,
        target,
        sufficient_support=False,
    )

    if not is_post_altair(spec):
        current_attestations = spec.get_matching_target_attestations(
            state, epoch)
        total_active_balance = spec.get_total_active_balance(state)
        current_target_balance = spec.get_attesting_balance(
            state, current_attestations)
        # Check we will not justify the current checkpoint
        does_justify = current_target_balance * 3 >= total_active_balance * 2
        assert not does_justify
        # Ensure we would have justified the current checkpoint w/ the exited validators
        current_exited_balance = spec.get_total_balance(
            state, exited_validators)
        does_justify = (current_target_balance +
                        current_exited_balance) * 3 >= total_active_balance * 2
        assert does_justify
    else:
        current_indices = spec.get_unslashed_participating_indices(
            state, spec.TIMELY_TARGET_FLAG_INDEX, epoch)
        total_active_balance = spec.get_total_active_balance(state)
        current_target_balance = spec.get_total_balance(state, current_indices)
        # Check we will not justify the current checkpoint
        does_justify = current_target_balance * 3 >= total_active_balance * 2
        assert not does_justify
        # Ensure we would have justified the current checkpoint w/ the exited validators
        current_exited_balance = spec.get_total_balance(
            state, exited_validators)
        does_justify = (current_target_balance +
                        current_exited_balance) * 3 >= total_active_balance * 2
        assert does_justify

    yield from run_process_just_and_fin(spec, state)

    assert state.current_justified_checkpoint.epoch != epoch