Beispiel #1
0
def test_process_crosslinks(genesis_state, config, success_in_previous_epoch,
                            success_in_current_epoch):
    shard_count = config.SHARD_COUNT
    current_slot = config.SLOTS_PER_EPOCH * 5 - 1
    current_epoch = compute_epoch_of_slot(current_slot, config.SLOTS_PER_EPOCH)
    assert current_epoch - 4 >= 0

    previous_crosslinks = tuple(
        Crosslink(
            shard=i,
            start_epoch=current_epoch - 4,
            end_epoch=current_epoch - 3,
        ) for i in range(shard_count))
    parent_crosslinks = tuple(
        Crosslink(
            shard=i,
            parent_root=previous_crosslinks[i].hash_tree_root,
            start_epoch=current_epoch - 2,
            end_epoch=current_epoch - 1,
        ) for i in range(shard_count))
    new_crosslinks = tuple(
        Crosslink(
            shard=i,
            parent_root=parent_crosslinks[i].hash_tree_root,
            start_epoch=current_epoch - 1,
            end_epoch=current_epoch,
        ) for i in range(shard_count))

    # generate expected state for correct crosslink generation
    state = genesis_state.copy(
        slot=current_slot,
        previous_crosslinks=previous_crosslinks,
        current_crosslinks=parent_crosslinks,
    )

    previous_epoch = current_epoch - 1

    expected_success_shards = set()
    previous_epoch_attestations = tuple(
        mk_all_pending_attestations_with_some_participation_in_epoch(
            state,
            previous_epoch,
            config,
            0.7 if success_in_previous_epoch else 0,
        ))
    if success_in_previous_epoch:
        for a in previous_epoch_attestations:
            expected_success_shards.add(a.data.crosslink.shard)

    current_epoch_attestations = tuple(
        mk_all_pending_attestations_with_some_participation_in_epoch(
            state,
            current_epoch,
            config,
            0.7 if success_in_current_epoch else 0,
        ))
    if success_in_current_epoch:
        for a in current_epoch_attestations:
            expected_success_shards.add(a.data.crosslink.shard)

    state = state.copy(
        previous_epoch_attestations=previous_epoch_attestations,
        current_epoch_attestations=current_epoch_attestations,
    )

    post_state = process_crosslinks(state, config)

    assert post_state.previous_crosslinks == state.current_crosslinks

    for shard in range(shard_count):
        crosslink = post_state.current_crosslinks[shard]
        if shard in expected_success_shards:
            if success_in_current_epoch:
                expected_crosslink = new_crosslinks[shard]
            else:
                expected_crosslink = parent_crosslinks[shard]
            assert crosslink == expected_crosslink
        else:
            # no change
            assert crosslink == state.current_crosslinks[shard]
def test_process_crosslinks(
        random,
        n_validators_state,
        config,
        slots_per_epoch,
        target_committee_size,
        shard_count,
        success_crosslink_in_cur_epoch,
        sample_attestation_data_params,
        sample_attestation_params):
    shard = 1
    crosslink_data_root = hash_eth2(b'crosslink_data_root')
    current_slot = config.SLOTS_PER_EPOCH * 2 - 1

    genesis_crosslinks = tuple([
        CrosslinkRecord(epoch=config.GENESIS_EPOCH, crosslink_data_root=ZERO_HASH32)
        for _ in range(shard_count)
    ])
    state = n_validators_state.copy(
        slot=current_slot,
        latest_crosslinks=genesis_crosslinks,
    )

    # Generate current epoch attestations
    cur_epoch_attestations = []
    for slot_in_cur_epoch in range(state.slot - config.SLOTS_PER_EPOCH, state.slot):
        if len(cur_epoch_attestations) > 0:
            break
        for committee, _shard in get_crosslink_committees_at_slot(
            state,
            slot_in_cur_epoch,
            CommitteeConfig(config),
        ):
            if _shard == shard:
                # Sample validators attesting to this shard.
                # Number of attesting validators sampled depends on `success_crosslink_in_cur_epoch`
                # if True, have >2/3 committee attest
                if success_crosslink_in_cur_epoch:
                    attesting_validators = random.sample(committee, (2 * len(committee) // 3 + 1))
                else:
                    attesting_validators = random.sample(committee, (2 * len(committee) // 3 - 1))
                # Generate the bitfield
                aggregation_bitfield = get_empty_bitfield(len(committee))
                for v_index in attesting_validators:
                    aggregation_bitfield = set_voted(
                        aggregation_bitfield, committee.index(v_index))
                # Generate the attestation
                cur_epoch_attestations.append(
                    Attestation(**sample_attestation_params).copy(
                        aggregation_bitfield=aggregation_bitfield,
                        data=AttestationData(**sample_attestation_data_params).copy(
                            slot=slot_in_cur_epoch,
                            shard=shard,
                            crosslink_data_root=crosslink_data_root,
                        ),
                    )
                )

    state = state.copy(
        latest_attestations=cur_epoch_attestations,
    )
    assert (state.latest_crosslinks[shard].epoch == config.GENESIS_EPOCH and
            state.latest_crosslinks[shard].crosslink_data_root == ZERO_HASH32)

    new_state = process_crosslinks(state, config)
    crosslink_record = new_state.latest_crosslinks[shard]
    if success_crosslink_in_cur_epoch:
        attestation = cur_epoch_attestations[0]
        assert (crosslink_record.epoch == slot_to_epoch(current_slot, slots_per_epoch) and
                crosslink_record.crosslink_data_root == attestation.data.crosslink_data_root and
                attestation.data.crosslink_data_root == crosslink_data_root)
    else:
        assert (crosslink_record.epoch == config.GENESIS_EPOCH and
                crosslink_record.crosslink_data_root == ZERO_HASH32)