def test_sync_committee_with_participating_withdrawable_member(spec, state):
    # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
    state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    # move forward via some blocks
    for _ in range(3):
        next_epoch_via_block(spec, state)

    committee_indices = compute_committee_indices(spec, state)
    rng = random.Random(1010)

    exited_index = _exit_validator_from_committee_and_transition_state(
        spec,
        state,
        committee_indices,
        rng,
        lambda v: v.withdrawable_epoch + 1,
    )

    current_epoch = spec.get_current_epoch(state)
    assert current_epoch > state.validators[exited_index].withdrawable_epoch

    block = build_empty_block_for_next_slot(spec, state)
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=[True] * len(committee_indices),
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            committee_indices,  # full committee signs
            block_root=block.parent_root,
        )
    )
    yield from run_sync_committee_processing(spec, state, block)
Exemplo n.º 2
0
def test_finality_rule_2(spec, state):
    # get past first two epochs that finality does not run on
    next_epoch_via_block(spec, state)
    next_epoch_via_block(spec, state)

    yield 'pre', state

    blocks = []
    for epoch in range(3):
        if epoch == 0:
            prev_state, new_blocks, state = next_epoch_with_attestations(
                spec, state, True, False)
            check_finality(spec, state, prev_state, True, False, False)
        elif epoch == 1:
            prev_state, new_blocks, state = next_epoch_with_attestations(
                spec, state, False, False)
            check_finality(spec, state, prev_state, False, True, False)
        elif epoch == 2:
            prev_state, new_blocks, state = next_epoch_with_attestations(
                spec, state, False, True)
            # finalized by rule 2
            check_finality(spec, state, prev_state, True, False, True)
            assert state.finalized_checkpoint == prev_state.previous_justified_checkpoint

        blocks += new_blocks

    yield 'blocks', blocks
    yield 'post', state
Exemplo n.º 3
0
def test_validator_withdrawal_reenable_after_custody_reveal(spec, state):
    transition_to_valid_shard_slot(spec, state)
    transition_to(spec, state, state.slot + 1)  # Make len(offset_slots) == 1
    spec.initiate_validator_exit(state, 0)
    assert state.validators[0].withdrawable_epoch < spec.FAR_FUTURE_EPOCH

    next_epoch_via_block(spec, state)

    assert state.validators[0].withdrawable_epoch == spec.FAR_FUTURE_EPOCH

    while spec.get_current_epoch(state) < state.validators[0].exit_epoch:
        next_epoch_via_block(spec, state)

    while (state.validators[0].next_custody_secret_to_reveal <=
           spec.get_custody_period_for_validator(
               0, state.validators[0].exit_epoch - 1)):
        custody_key_reveal = get_valid_custody_key_reveal(spec,
                                                          state,
                                                          validator_index=0)
        _, _, _ = run_custody_key_reveal_processing(spec, state,
                                                    custody_key_reveal)

    yield from run_process_custody_final_updates(spec, state)

    assert state.validators[0].withdrawable_epoch < spec.FAR_FUTURE_EPOCH
def test_current_filled(spec, state):
    next_epoch_via_block(spec, state)

    state.previous_epoch_participation = [0] * len(state.validators)
    state.current_epoch_participation = [get_full_flags(spec)] * len(
        state.validators)

    yield from run_process_participation_flag_updates(spec, state)
def test_reveal_from_past_epoch(spec, state):
    next_epoch_via_block(spec, state)
    randao_key_reveal = get_valid_early_derived_secret_reveal(
        spec, state,
        spec.get_current_epoch(state) - 1)

    yield from run_early_derived_secret_reveal_processing(
        spec, state, randao_key_reveal, False)
Exemplo n.º 6
0
def test_success_previous_epoch(spec, state):
    attestation = get_valid_attestation(spec,
                                        state,
                                        signed=True,
                                        on_time=False)
    next_epoch_via_block(spec, state)

    yield from run_attestation_processing(spec, state, attestation)
Exemplo n.º 7
0
def test_mismatched_target_and_slot(spec, state):
    next_epoch_via_block(spec, state)
    next_epoch_via_block(spec, state)

    attestation = get_valid_attestation(spec, state, on_time=False)
    attestation.data.slot = attestation.data.slot - spec.SLOTS_PER_EPOCH

    sign_attestation(spec, state, attestation)

    yield from run_attestation_processing(spec, state, attestation, False)
Exemplo n.º 8
0
def test_validator_withdrawal_suspend_after_chunk_challenge(spec, state):
    transition_to_valid_shard_slot(spec, state)
    transition_to(spec, state, state.slot + 1)  # Make len(offset_slots) == 1
    shard = 0
    offset_slots = spec.get_offset_slots(state, shard)
    shard_transition = get_sample_shard_transition(
        spec, state.slot, [2**15 // 3] * len(offset_slots))
    attestation = get_valid_on_time_attestation(
        spec,
        state,
        index=shard,
        signed=True,
        shard_transition=shard_transition)

    transition_to(spec, state,
                  state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)

    _, _, _ = run_attestation_processing(spec, state, attestation)

    validator_index = spec.get_beacon_committee(state, attestation.data.slot,
                                                attestation.data.index)[0]

    spec.initiate_validator_exit(state, validator_index)
    assert state.validators[
        validator_index].withdrawable_epoch < spec.FAR_FUTURE_EPOCH

    transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH)

    assert state.validators[
        validator_index].withdrawable_epoch == spec.FAR_FUTURE_EPOCH

    while spec.get_current_epoch(
            state) < state.validators[validator_index].exit_epoch:
        next_epoch_via_block(spec, state)

    while (state.validators[validator_index].next_custody_secret_to_reveal <=
           spec.get_custody_period_for_validator(
               validator_index,
               state.validators[validator_index].exit_epoch - 1)):
        custody_key_reveal = get_valid_custody_key_reveal(
            spec, state, validator_index=validator_index)
        _, _, _ = run_custody_key_reveal_processing(spec, state,
                                                    custody_key_reveal)

    next_epoch_via_block(spec, state)

    challenge = get_valid_chunk_challenge(spec, state, attestation,
                                          shard_transition)

    _, _, _ = run_chunk_challenge_processing(spec, state, challenge)

    yield from run_process_custody_final_updates(spec, state)

    assert state.validators[
        validator_index].withdrawable_epoch == spec.FAR_FUTURE_EPOCH
Exemplo n.º 9
0
def test_success_attestation_from_future(spec, state):
    # Transition state to future to enable generation of a "future" attestation
    future_state = state.copy()
    next_epoch_via_block(spec, future_state)
    # Generate slashing using the future state
    attester_slashing = get_valid_attester_slashing(
        spec,
        future_state,
        slot=state.slot + 5,  # Slot is in the future wrt `state`
        signed_1=True,
        signed_2=True)

    yield from run_attester_slashing_processing(spec, state, attester_slashing)
Exemplo n.º 10
0
def test_success_proposer_index_slashed(spec, state):
    # Transition past genesis slot because generally doesn't have a proposer
    next_epoch_via_block(spec, state)

    proposer_index = spec.get_beacon_proposer_index(state)
    attester_slashing = get_valid_attester_slashing_by_indices(
        spec,
        state,
        [proposer_index],
        signed_1=True,
        signed_2=True,
    )

    yield from run_attester_slashing_processing(spec, state, attester_slashing)
Exemplo n.º 11
0
def test_finality_rule_3(spec, state):
    """
    Test scenario described here
    https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892
    """
    # get past first two epochs that finality does not run on
    next_epoch_via_block(spec, state)
    next_epoch_via_block(spec, state)

    yield 'pre', state

    blocks = []
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, True, False, False)

    # In epoch N, JE is set to N, prev JE is set to N-1
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, True, True, True)

    # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, False, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, False, True, False)

    # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1.
    # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, False, True)
    blocks += new_blocks
    # rule 2
    check_finality(spec, state, prev_state, True, False, True)

    # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3.
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, True)
    blocks += new_blocks
    # rule 3
    check_finality(spec, state, prev_state, True, True, True)
    assert state.finalized_checkpoint == prev_state.current_justified_checkpoint

    yield 'blocks', blocks
    yield 'post', state
Exemplo n.º 12
0
def test_success_surround(spec, state):
    next_epoch_via_block(spec, state)

    state.current_justified_checkpoint.epoch += 1
    attester_slashing = get_valid_attester_slashing(spec,
                                                    state,
                                                    signed_1=False,
                                                    signed_2=True)
    att_1_data = get_attestation_1_data(spec, attester_slashing)
    att_2_data = get_attestation_2_data(spec, attester_slashing)

    # set attestion1 to surround attestation 2
    att_1_data.source.epoch = att_2_data.source.epoch - 1
    att_1_data.target.epoch = att_2_data.target.epoch + 1

    sign_indexed_attestation(spec, state, attester_slashing.attestation_1)

    yield from run_attester_slashing_processing(spec, state, attester_slashing)
Exemplo n.º 13
0
def test_inactivity_scores(spec, state):
    for _ in range(spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY + 2):
        next_epoch_via_block(spec, state)

    assert spec.is_in_inactivity_leak(state)
    previous_inactivity_scores = state.inactivity_scores.copy()

    yield 'pre', state

    # Block transition to next epoch
    block = build_empty_block(spec, state, slot=state.slot + spec.SLOTS_PER_EPOCH)
    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    for pre, post in zip(previous_inactivity_scores, state.inactivity_scores):
        assert post == pre + spec.INACTIVITY_SCORE_BIAS
Exemplo n.º 14
0
def test_proposer_after_inactive_index(spec, state):
    # disable some low validator index to check after for
    inactive_index = 10
    state.validators[inactive_index].exit_epoch = spec.get_current_epoch(state)

    # skip forward, get brand new proposers
    next_epoch_via_block(spec, state)
    next_epoch_via_block(spec, state)
    while True:
        proposer_index = spec.get_beacon_proposer_index(state)
        if proposer_index > inactive_index:
            # found a proposer that has a higher index than a disabled validator
            yield 'pre', state
            # test if the proposer can be recognized correctly after the inactive validator
            signed_block = state_transition_and_sign_block(spec, state, build_empty_block_for_next_slot(spec, state))
            yield 'blocks', [signed_block]
            yield 'post', state
            break
        next_slot(spec, state)
Exemplo n.º 15
0
def test_finality_rule_4(spec, state):
    # get past first two epochs that finality does not run on
    next_epoch_via_block(spec, state)
    next_epoch_via_block(spec, state)

    yield 'pre', state

    blocks = []
    for epoch in range(2):
        prev_state, new_blocks, state = next_epoch_with_attestations(
            spec, state, True, False)
        blocks += new_blocks

        if epoch == 0:
            check_finality(spec, state, prev_state, True, False, False)
        elif epoch == 1:
            # rule 4 of finality
            check_finality(spec, state, prev_state, True, True, True)
            assert state.finalized_checkpoint == prev_state.current_justified_checkpoint

    yield 'blocks', blocks
    yield 'post', state
def test_sync_committee_with_nonparticipating_exited_member(spec, state):
    # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
    state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    # move forward via some blocks
    for _ in range(3):
        next_epoch_via_block(spec, state)

    committee_indices = compute_committee_indices(spec, state)
    rng = random.Random(1010)

    exited_index = _exit_validator_from_committee_and_transition_state(
        spec,
        state,
        committee_indices,
        rng,
        lambda v: v.exit_epoch,
    )
    exited_pubkey = state.validators[exited_index].pubkey

    current_epoch = spec.get_current_epoch(state)
    assert current_epoch < state.validators[exited_index].withdrawable_epoch

    exited_committee_index = state.current_sync_committee.pubkeys.index(exited_pubkey)
    block = build_empty_block_for_next_slot(spec, state)
    committee_bits = [i != exited_committee_index for i in committee_indices]
    committee_indices = [index for index in committee_indices if index != exited_committee_index]
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=committee_bits,
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            committee_indices,  # with exited validator removed
            block_root=block.parent_root,
        )
    )
    yield from run_sync_committee_processing(spec, state, block)
Exemplo n.º 17
0
def test_transition_with_no_attestations_until_after_fork(
        state, fork_epoch, spec, post_spec, pre_tag, post_tag):
    """
    Transition from the initial ``state`` to the ``fork_epoch`` with no attestations,
    then transition forward with enough attestations to finalize the fork epoch.
    """
    yield "pre", state

    assert spec.get_current_epoch(state) < fork_epoch

    # regular state transition until fork:
    to_slot = fork_epoch * spec.SLOTS_PER_EPOCH - 1
    blocks = []
    blocks.extend([
        pre_tag(block)
        for block in _state_transition_across_slots(spec, state, to_slot)
    ])

    # irregular state transition to handle fork:
    state, block = _do_altair_fork(state, spec, post_spec, fork_epoch)
    blocks.append(post_tag(block))

    # continue regular state transition but add attestations
    # for enough epochs to finalize the ``fork_epoch``
    block = next_epoch_via_block(post_spec, state)
    blocks.append(post_tag(sign_block(post_spec, state, block)))
    for _ in range(4):
        _, blocks_in_epoch, state = next_slots_with_attestations(
            post_spec,
            state,
            post_spec.SLOTS_PER_EPOCH,
            False,
            True,
        )
        blocks.extend([post_tag(block) for block in blocks_in_epoch])

    assert state.slot % post_spec.SLOTS_PER_EPOCH == 0
    assert post_spec.get_current_epoch(state) == fork_epoch + 5

    assert state.current_justified_checkpoint.epoch == fork_epoch + 3
    assert state.finalized_checkpoint.epoch == fork_epoch + 1

    yield "blocks", blocks
    yield "post", state
Exemplo n.º 18
0
def test_random_inactivity_scores_full_participation(spec, state):
    next_epoch_via_block(spec, state)
    set_full_participation(spec, state)
    randomize_inactivity_scores(spec, state, rng=Random(33333))
    yield from run_process_inactivity_updates(spec, state)
def test_previous_epoch_zeroed(spec, state):
    next_epoch_via_block(spec, state)
    random_flags(spec, state, 13, previous=False)
    state.previous_epoch_participation = [0] * len(state.validators)
    yield from run_process_participation_flag_updates(spec, state)
Exemplo n.º 20
0
def _run_transition_test_with_attestations(state,
                                           fork_epoch,
                                           spec,
                                           post_spec,
                                           pre_tag,
                                           post_tag,
                                           participation_fn=None,
                                           expect_finality=True):
    yield "pre", state

    current_epoch = spec.get_current_epoch(state)
    assert current_epoch < fork_epoch
    assert current_epoch == spec.GENESIS_EPOCH

    # skip genesis epoch to avoid dealing with some edge cases...
    block = next_epoch_via_block(spec, state)

    # regular state transition until fork:
    fill_cur_epoch = False
    fill_prev_epoch = True
    blocks = [pre_tag(sign_block(spec, state, block))]
    current_epoch = spec.get_current_epoch(state)
    for _ in range(current_epoch, fork_epoch - 1):
        _, blocks_in_epoch, state = next_slots_with_attestations(
            spec,
            state,
            spec.SLOTS_PER_EPOCH,
            fill_cur_epoch,
            fill_prev_epoch,
            participation_fn=participation_fn,
        )
        blocks.extend([pre_tag(block) for block in blocks_in_epoch])

    _, blocks_in_epoch, state = next_slots_with_attestations(
        spec,
        state,
        spec.SLOTS_PER_EPOCH - 1,
        fill_cur_epoch,
        fill_prev_epoch,
        participation_fn=participation_fn,
    )
    blocks.extend([pre_tag(block) for block in blocks_in_epoch])
    assert spec.get_current_epoch(state) == fork_epoch - 1
    assert (state.slot + 1) % spec.SLOTS_PER_EPOCH == 0

    # irregular state transition to handle fork:
    state, block = _do_altair_fork(state, spec, post_spec, fork_epoch)
    blocks.append(post_tag(block))

    # continue regular state transition with new spec into next epoch
    for _ in range(4):
        _, blocks_in_epoch, state = next_slots_with_attestations(
            post_spec,
            state,
            post_spec.SLOTS_PER_EPOCH,
            fill_cur_epoch,
            fill_prev_epoch,
            participation_fn=participation_fn,
        )
        blocks.extend([post_tag(block) for block in blocks_in_epoch])

    assert state.slot % post_spec.SLOTS_PER_EPOCH == 0
    assert post_spec.get_current_epoch(state) == fork_epoch + 4

    if expect_finality:
        assert state.current_justified_checkpoint.epoch == fork_epoch + 2
        assert state.finalized_checkpoint.epoch == fork_epoch
    else:
        assert state.current_justified_checkpoint.epoch == spec.GENESIS_EPOCH
        assert state.finalized_checkpoint.epoch == spec.GENESIS_EPOCH

    assert len(blocks) == (fork_epoch + 3) * post_spec.SLOTS_PER_EPOCH + 1
    assert len(blocks) == len(set(blocks))

    blocks_without_attestations = [
        block for block in blocks if len(block.message.body.attestations) == 0
    ]
    assert len(blocks_without_attestations) == 2
    slots_without_attestations = [
        b.message.slot for b in blocks_without_attestations
    ]

    assert set(slots_without_attestations) == set(
        [spec.SLOTS_PER_EPOCH, fork_epoch * spec.SLOTS_PER_EPOCH])

    yield "blocks", blocks
    yield "post", state
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
def test_slightly_larger_random(spec, state):
    next_epoch_via_block(spec, state)
    random_flags(spec, state, 14)
    yield from run_process_participation_flag_updates(spec, state)
def test_random_0(spec, state):
    next_epoch_via_block(spec, state)
    random_flags(spec, state, 100)
    yield from run_process_participation_flag_updates(spec, state)
Exemplo n.º 24
0
def test_all_zero_inactivity_scores_random_participation(spec, state):
    next_epoch_via_block(spec, state)
    state.inactivity_scores = [0] * len(state.validators)
    randomize_attestation_participation(spec, state, rng=Random(5555))
    yield from run_process_inactivity_updates(spec, state)
Exemplo n.º 25
0
def test_fork_next_epoch_with_block(spec, phases, state):
    next_epoch_via_block(spec, state)
    yield from run_fork_test(phases[ALTAIR], state)
Exemplo n.º 26
0
def test_all_zero_inactivity_scores_full_participation(spec, state):
    next_epoch_via_block(spec, state)
    set_full_participation(spec, state)
    state.inactivity_scores = [0] * len(state.validators)
    yield from run_process_inactivity_updates(spec, state)