def test_get_inclusion_infos( monkeypatch, n, n_validators_state, config, slots_per_epoch, target_committee_size, shard_count, attestation_1_inclusion_slot, attestation_1_data_slot, attestation_2_inclusion_slot, attestation_2_data_slot, expected_inclusion_slot, expected_inclusion_distance, sample_attestation_data_params, sample_pending_attestation_record_params): participating_validator_index = 1 committee = (1, 2, 3) shard = 1 from eth2.beacon import committee_helpers def mock_get_crosslink_committees_at_slot(state, slot, committee_config, registry_change=False): return (( committee, shard, ), ) monkeypatch.setattr(committee_helpers, 'get_crosslink_committees_at_slot', mock_get_crosslink_committees_at_slot) aggregation_bitfield = get_empty_bitfield(target_committee_size) aggregation_bitfield = set_voted( aggregation_bitfield, committee.index(participating_validator_index)) previous_epoch_attestations = [ PendingAttestationRecord( **sample_pending_attestation_record_params).copy( data=AttestationData(**sample_attestation_data_params).copy( slot=attestation_1_data_slot, shard=shard, ), aggregation_bitfield=aggregation_bitfield, slot_included=attestation_1_inclusion_slot, ), PendingAttestationRecord( **sample_pending_attestation_record_params).copy( data=AttestationData(**sample_attestation_data_params).copy( slot=attestation_2_data_slot, shard=shard, ), aggregation_bitfield=aggregation_bitfield, slot_included=attestation_2_inclusion_slot, ), ] result = get_inclusion_infos( state=n_validators_state, attestations=previous_epoch_attestations, committee_config=CommitteeConfig(config), ) assert result[ participating_validator_index].inclusion_slot == expected_inclusion_slot assert result[ participating_validator_index].inclusion_distance == expected_inclusion_distance
def process_rewards_and_penalties(state: BeaconState, config: BeaconConfig) -> BeaconState: # Compute previous epoch active validator indices and the total balance they account for # for later use. previous_epoch_active_validator_indices = set( get_active_validator_indices( state.validator_registry, state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH))) previous_total_balance: Gwei = get_total_balance( state.validator_balances, tuple(previous_epoch_active_validator_indices), config.MAX_DEPOSIT_AMOUNT, ) # Compute previous epoch attester indices and the total balance they account for # for later use. previous_epoch_attestations = get_previous_epoch_attestations( state, config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH, ) previous_epoch_attester_indices = get_attester_indices_from_attesttion( state=state, attestations=previous_epoch_attestations, committee_config=CommitteeConfig(config), ) # Compute inclusion slot/distance of previous attestations for later use. inclusion_infos = get_inclusion_infos( state=state, attestations=previous_epoch_attestations, committee_config=CommitteeConfig(config), ) # Compute effective balance of each previous epoch active validator for later use effective_balances = { index: get_effective_balance( state.validator_balances, index, config.MAX_DEPOSIT_AMOUNT, ) for index in previous_epoch_active_validator_indices } # Compute base reward of each previous epoch active validator for later use _base_reward_quotient = (integer_squareroot(previous_total_balance) // config.BASE_REWARD_QUOTIENT) base_rewards = { index: get_base_reward( state=state, index=index, base_reward_quotient=_base_reward_quotient, max_deposit_amount=config.MAX_DEPOSIT_AMOUNT, ) for index in previous_epoch_active_validator_indices } # Initialize the reward (validator) received map rewards_received = { index: SignedGwei(0) for index in previous_epoch_active_validator_indices } # 1. Process rewards and penalties for justification and finalization rewards_received = pipe( rewards_received, _process_rewards_and_penalties_for_finality( state, config, previous_epoch_active_validator_indices, previous_total_balance, previous_epoch_attestations, previous_epoch_attester_indices, inclusion_infos, effective_balances, base_rewards, ), _process_rewards_and_penalties_for_attestation_inclusion( state, config, previous_epoch_attester_indices, inclusion_infos, base_rewards, ), _process_rewards_and_penalties_for_crosslinks( state, config, previous_epoch_attestations, effective_balances, base_rewards, )) # Apply the overall rewards/penalties for index in previous_epoch_active_validator_indices: state = state.update_validator_balance( index, # Prevent validator balance under flow max(state.validator_balances[index] + rewards_received[index], 0), ) return state
def process_rewards_and_penalties(state: BeaconState, config: Eth2Config) -> BeaconState: # Compute previous epoch active validator indices and the total balance they account for # for later use. previous_epoch_active_validator_indices = set( get_active_validator_indices( state.validator_registry, state.previous_epoch(config.SLOTS_PER_EPOCH))) previous_total_balance: Gwei = get_total_balance( state.validator_balances, tuple(previous_epoch_active_validator_indices), config.MAX_DEPOSIT_AMOUNT, ) # Compute previous epoch attester indices and the total balance they account for # for later use. previous_epoch_attestations = state.previous_epoch_attestations previous_epoch_attester_indices = get_attester_indices_from_attestations( state=state, attestations=previous_epoch_attestations, committee_config=CommitteeConfig(config), ) # Compute inclusion slot/distance of previous attestations for later use. inclusion_infos = get_inclusion_infos( state=state, attestations=previous_epoch_attestations, committee_config=CommitteeConfig(config), ) # Compute effective balance of each previous epoch active validator for later use effective_balances = { ValidatorIndex(index): get_effective_balance( state.validator_balances, ValidatorIndex(index), config.MAX_DEPOSIT_AMOUNT, ) for index in range(len(state.validator_registry)) } # Compute base reward of each previous epoch active validator for later use base_rewards = { ValidatorIndex(index): get_base_reward( state=state, index=ValidatorIndex(index), base_reward_quotient=config.BASE_REWARD_QUOTIENT, previous_total_balance=previous_total_balance, max_deposit_amount=config.MAX_DEPOSIT_AMOUNT, ) for index in range(len(state.validator_registry)) } # 1. Process rewards and penalties for justification and finalization finality_rewards, finality_penalties = _process_rewards_and_penalties_for_finality( state, config, previous_epoch_active_validator_indices, previous_total_balance, previous_epoch_attestations, previous_epoch_attester_indices, inclusion_infos, effective_balances, base_rewards, ) # 2. Process rewards and penalties for crosslinks crosslinks_rewards, crosslinks_penalties = _process_rewards_and_penalties_for_crosslinks( state, config, effective_balances, base_rewards, ) # Apply the overall rewards/penalties for index in range(len(state.validator_registry)): state = state.update_validator_balance( ValidatorIndex(index), # Prevent validator balance under flow max( (state.validator_balances[index] + finality_rewards[index] + crosslinks_rewards[index] - finality_penalties[index] - crosslinks_penalties[index]), 0, ), ) return state