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)