def test_no_winning_root(spec, state):
    if not is_full_crosslink(spec, state):
        # Skip this test
        return

    state, shard, target_shard_slot = get_initial_env(spec,
                                                      state,
                                                      target_len_offset_slot=1)
    init_slot = state.slot

    # Create SignedShardBlock at init_slot
    shard_block = build_shard_block(spec,
                                    state,
                                    shard,
                                    slot=init_slot,
                                    body=get_sample_shard_block_body(
                                        spec, is_max=True),
                                    signed=True)

    # Transition state to target shard slot
    transition_to(spec, state, target_shard_slot)

    # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1`
    shard_transitions = get_shard_transitions(spec, state,
                                              {shard: [shard_block]})
    shard_transition = shard_transitions[shard]
    committee_index = get_committee_index_of_shard(spec, state, state.slot,
                                                   shard)
    attestation = get_valid_attestation(
        spec,
        state,
        index=committee_index,
        shard_transition=shard_transition,
        # Decrease attested participants to 1/3 committee
        filter_participant_set=lambda committee: set(
            list(committee)[:len(committee) // 3]),
        signed=True,
        on_time=True,
    )

    next_slot(spec, state)

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

    _, winning_roots = spec.get_shard_winning_roots(state, [attestation])
    assert len(winning_roots) == 0

    # No winning root, shard_transitions[shard] is empty
    shard_transitions = [spec.ShardTransition()] * spec.MAX_SHARDS
    pre_shard_states = state.shard_states.copy()
    yield from run_shard_transitions_processing(spec, state, shard_transitions,
                                                [attestation])

    for pending_attestation in state.current_epoch_attestations:
        assert bool(pending_attestation.crosslink_success) is False

    assert state.shard_states == pre_shard_states
def test_wrong_shard_transition_root(spec, state):
    if not is_full_crosslink(spec, state):
        # Skip this test
        return

    state, shard, target_shard_slot = get_initial_env(spec,
                                                      state,
                                                      target_len_offset_slot=1)
    init_slot = state.slot

    # Create SignedShardBlock at init_slot
    shard_block = build_shard_block(spec,
                                    state,
                                    shard,
                                    slot=init_slot,
                                    body=get_sample_shard_block_body(
                                        spec, is_max=True),
                                    signed=True)

    # Transition state to target shard slot
    transition_to(spec, state, target_shard_slot)

    # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1`
    shard_transitions = get_shard_transitions(spec, state,
                                              {shard: [shard_block]})
    shard_transition = shard_transitions[shard]
    wrong_shard_transition = shard_transition.copy()
    wrong_shard_transition.shard_states[
        shard].gasprice = shard_transition.shard_states[shard].gasprice + 1
    committee_index = get_committee_index_of_shard(spec, state, state.slot,
                                                   shard)
    attestation = get_valid_attestation(
        spec,
        state,
        index=committee_index,
        shard_transition=wrong_shard_transition,
        signed=True,
        on_time=True,
    )
    attestations = [attestation]

    next_slot(spec, state)

    run_attestation_processing(spec, state, attestation)

    # Check if winning root != shard_transition.hash_tree_root()
    _, winning_roots = spec.get_shard_winning_roots(state, attestations)
    assert len(winning_roots) == 1
    shard_transition = shard_transitions[shard]
    assert winning_roots[0] != shard_transition.hash_tree_root()

    yield from run_shard_transitions_processing(spec,
                                                state,
                                                shard_transitions,
                                                attestations,
                                                valid=False)
Пример #3
0
def run_successful_crosslink_tests(spec, state, target_len_offset_slot):
    state, shard, target_shard_slot = get_initial_env(spec, state,
                                                      target_len_offset_slot)
    init_slot = state.slot

    # Create SignedShardBlock at init_slot
    shard_block = build_shard_block(spec,
                                    state,
                                    shard,
                                    slot=init_slot,
                                    body=get_sample_shard_block_body(
                                        spec, is_max=True),
                                    signed=True)

    # Transition state to target shard slot
    transition_to(spec, state, target_shard_slot)

    # Create a shard_transitions that would be included at beacon block `target_shard_slot + 1`
    shard_block_dict = {shard: [shard_block]}
    attestations, shard_transitions = get_attestations_and_shard_transitions(
        spec, state, shard_block_dict)

    next_slot(spec, state)

    for attestation in attestations:
        _, _, _ = run_attestation_processing(spec, state, attestation)

    _, winning_roots = spec.get_shard_winning_roots(state, attestations)
    assert len(winning_roots) == 1
    shard_transition = shard_transitions[shard]
    assert winning_roots[0] == shard_transition.hash_tree_root()

    pre_gasprice = state.shard_states[shard].gasprice
    pre_shard_states = state.shard_states.copy()
    yield from run_shard_transitions_processing(spec, state, shard_transitions,
                                                attestations)

    for index, shard_state in enumerate(state.shard_states):
        if index == shard:
            assert shard_state != pre_shard_states[index]
            assert shard_state == shard_transition.shard_states[
                len(shard_transition.shard_states) - 1]
            assert shard_state.latest_block_root == shard_block.message.hash_tree_root(
            )
            if target_len_offset_slot == 1:
                assert shard_state.gasprice > pre_gasprice
        else:
            assert shard_state == pre_shard_states[index]

    for pending_attestation in state.current_epoch_attestations:
        assert bool(pending_attestation.crosslink_success) is True
def run_basic_crosslink_tests(spec, state, target_len_offset_slot, valid=True):
    state = transition_to_valid_shard_slot(spec, state)
    # At the beginning, let `x = state.slot`, `state.shard_states[shard].slot == x - 1`
    slot_x = state.slot
    committee_index = spec.CommitteeIndex(0)
    shard = spec.compute_shard_from_committee_index(state, committee_index, state.slot)
    assert state.shard_states[shard].slot == slot_x - 1

    # Create SignedShardBlock
    body = b'\x56' * spec.MAX_SHARD_BLOCK_SIZE
    shard_block = build_shard_block(spec, state, shard, body=body, signed=True)
    shard_blocks = [shard_block]
    # Create a shard_transitions that would be included at beacon block `state.slot + target_len_offset_slot`
    shard_transitions = build_shard_transitions_till_slot(
        spec,
        state,
        shard_blocks={shard: shard_blocks},
        on_time_slot=state.slot + target_len_offset_slot,
    )
    shard_transition = shard_transitions[shard]
    # Create an attestation that would be included at beacon block `state.slot + target_len_offset_slot`
    attestation = build_attestation_with_shard_transition(
        spec,
        state,
        index=committee_index,
        on_time_slot=state.slot + target_len_offset_slot,
        shard_transition=shard_transition,
    )
    pre_gasprice = state.shard_states[shard].gasprice

    transition_to(spec, state, state.slot + target_len_offset_slot)
    pre_shard_state = state.shard_states[shard]

    yield from run_shard_transitions_processing(spec, state, shard_transitions, [attestation], valid=valid)

    if valid:
        # After state transition,
        assert state.slot == slot_x + target_len_offset_slot
        shard_state = state.shard_states[shard]
        assert shard_state != pre_shard_state
        assert shard_state == shard_transition.shard_states[len(shard_transition.shard_states) - 1]

        if target_len_offset_slot == 1:
            assert shard_state.gasprice > pre_gasprice