def test_get_shard_delta(genesis_state, expected_shard_delta, config): state = genesis_state epoch = state.current_epoch(config.SLOTS_PER_EPOCH) assert get_shard_delta(state, epoch, config) == expected_shard_delta
def _compute_next_start_shard(state: BeaconState, config: Eth2Config) -> Shard: current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH) return (state.start_shard + get_shard_delta( state, current_epoch, CommitteeConfig(config), )) % config.SHARD_COUNT
def mk_all_pending_attestations_with_some_participation_in_epoch( state: BeaconState, epoch: Epoch, config: Eth2Config, participation_ratio: float) -> Iterable[PendingAttestation]: return _mk_some_pending_attestations_with_some_participation_in_epoch( state, epoch, config, participation_ratio, get_shard_delta(state, epoch, CommitteeConfig(config)), )
def test_get_crosslink_committee(genesis_state, config): indices = tuple() for shard in range( get_shard_delta(genesis_state, config.GENESIS_EPOCH, CommitteeConfig(config))): some_committee = get_crosslink_committee( genesis_state, genesis_state.current_epoch(config.SLOTS_PER_EPOCH), genesis_state.start_shard + shard, CommitteeConfig(config), ) indices += tuple(some_committee) assert set(indices) == set(range(len(genesis_state.validators))) assert len(indices) == len(genesis_state.validators)
def test_process_rewards_and_penalties_for_crosslinks( genesis_state, config, slots_per_epoch, target_committee_size, shard_count, current_slot, num_attesting_validators, max_effective_balance, min_attestation_inclusion_delay, sample_attestation_data_params, sample_pending_attestation_record_params): state = genesis_state.copy(slot=current_slot, ) previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH) prev_epoch_start_slot = compute_start_slot_of_epoch( previous_epoch, slots_per_epoch) prev_epoch_crosslink_committees = [ get_crosslink_committees_at_slot( state, slot, CommitteeConfig(config), )[0] for slot in range(prev_epoch_start_slot, prev_epoch_start_slot + slots_per_epoch) ] # Record which validators attest during each slot for reward collation. each_slot_attestion_validators_list = [] epoch_start_shard = get_start_shard( state, previous_epoch, CommitteeConfig(config), ) shard_delta = get_shard_delta( state, previous_epoch, CommitteeConfig(config), ) a = epoch_start_shard b = epoch_start_shard + shard_delta if a > b: valid_shards_for_epoch = range(b, a) else: valid_shards_for_epoch = range(a, b) indices_to_check = set() previous_epoch_attestations = [] for committee, shard in prev_epoch_crosslink_committees: if shard not in valid_shards_for_epoch: continue for index in committee: indices_to_check.add(index) # Randomly sample `num_attesting_validators` validators # from the committee to attest in this slot. crosslink_attesting_validators = random.sample( committee, num_attesting_validators, ) each_slot_attestion_validators_list.append( crosslink_attesting_validators) participants_bitfield = get_empty_bitfield(len(committee)) for index in crosslink_attesting_validators: participants_bitfield = set_voted(participants_bitfield, committee.index(index)) previous_epoch_attestations.append( PendingAttestation( **sample_pending_attestation_record_params).copy( aggregation_bits=participants_bitfield, data=AttestationData( **sample_attestation_data_params).copy( target=Checkpoint(epoch=previous_epoch, ), crosslink=Crosslink( shard=shard, parent_root=Crosslink().hash_tree_root, ), ), )) state = state.copy( previous_epoch_attestations=tuple(previous_epoch_attestations), ) rewards_received, penalties_received = get_crosslink_deltas( state, config, ) expected_rewards_received = { index: 0 for index in range(len(state.validators)) } validator_balance = max_effective_balance for i in range(slots_per_epoch): crosslink_committee, shard = prev_epoch_crosslink_committees[i] if shard not in valid_shards_for_epoch: continue attesting_validators = each_slot_attestion_validators_list[i] total_attesting_balance = len(attesting_validators) * validator_balance total_committee_balance = len(crosslink_committee) * validator_balance for index in crosslink_committee: if index in attesting_validators: reward = get_base_reward( state=state, index=index, config=config, ) * total_attesting_balance // total_committee_balance expected_rewards_received[index] += reward else: penalty = get_base_reward( state=state, index=index, config=config, ) expected_rewards_received[index] -= penalty # Check the rewards/penalties match for index in range(len(state.validators)): if index not in indices_to_check: continue assert (rewards_received[index] - penalties_received[index] == expected_rewards_received[index])
def test_get_attestation_deltas(genesis_state, config, slots_per_epoch, target_committee_size, shard_count, min_attestation_inclusion_delay, inactivity_penalty_quotient, finalized_epoch, current_slot, sample_pending_attestation_record_params, sample_attestation_data_params): state = genesis_state.copy(slot=current_slot, finalized_checkpoint=Checkpoint( epoch=finalized_epoch, )) previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH) epoch_start_shard = get_start_shard( state, previous_epoch, CommitteeConfig(config), ) shard_delta = get_shard_delta( state, previous_epoch, CommitteeConfig(config), ) a = epoch_start_shard b = epoch_start_shard + shard_delta if a > b: valid_shards_for_epoch = range(b, a) else: valid_shards_for_epoch = range(a, b) indices_to_check = set() prev_epoch_start_slot = compute_start_slot_of_epoch( previous_epoch, slots_per_epoch) prev_epoch_attestations = tuple() for slot in range(prev_epoch_start_slot, prev_epoch_start_slot + slots_per_epoch): committee, shard = get_crosslink_committees_at_slot( state, slot, CommitteeConfig(config), )[0] if not committee: continue if shard not in valid_shards_for_epoch: continue participants_bitfield = get_empty_bitfield(len(committee)) for i, index in enumerate(committee): indices_to_check.add(index) participants_bitfield = set_voted(participants_bitfield, i) prev_epoch_attestations += (PendingAttestation( **sample_pending_attestation_record_params).copy( aggregation_bits=participants_bitfield, inclusion_delay=min_attestation_inclusion_delay, proposer_index=get_beacon_proposer_index( state.copy(slot=slot, ), CommitteeConfig(config), ), data=AttestationData(**sample_attestation_data_params).copy( crosslink=Crosslink(shard=shard, ), target=Checkpoint( epoch=previous_epoch, root=get_block_root( state, previous_epoch, config.SLOTS_PER_EPOCH, config.SLOTS_PER_HISTORICAL_ROOT, ), ), beacon_block_root=get_block_root_at_slot( state, slot, config.SLOTS_PER_HISTORICAL_ROOT, ), ), ), ) state = state.copy(previous_epoch_attestations=prev_epoch_attestations, ) rewards_received, penalties_received = get_attestation_deltas( state, config, ) # everyone attested, no penalties assert (sum(penalties_received) == 0) the_reward = rewards_received[0] # everyone performed the same, equal rewards assert (sum(rewards_received) // len(rewards_received) == the_reward)