def process_validator_registry(state: BeaconState, config: BeaconConfig) -> BeaconState: state = state.copy( previous_epoch_calculation_slot=state.current_epoch_calculation_slot, previous_epoch_start_shard=state.current_epoch_start_shard, previous_epoch_randao_mix=state.current_epoch_randao_mix, ) need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config) if need_to_update: state = update_validator_registry(state) # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy( current_epoch_calculation_slot=state.slot, ) state = state.copy( current_epoch_start_shard=( state.current_epoch_start_shard + num_shards_in_committees ) % config.SHARD_COUNT, ) state = state.copy( current_epoch_randao_mix=get_randao_mix( state, state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD, config.LATEST_RANDAO_MIXES_LENGTH, ), ) else: epochs_since_last_registry_change = ( state.slot - state.validator_registry_update_slot ) // config.EPOCH_LENGTH if is_power_of_two(epochs_since_last_registry_change): # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy( current_epoch_calculation_slot=state.slot, ) state = state.copy( current_epoch_randao_mix=get_randao_mix( state, state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD, config.LATEST_RANDAO_MIXES_LENGTH, ), ) return state
def process_randao(state: BeaconState, block: BaseBeaconBlock, config: Eth2Config) -> BeaconState: proposer_index = get_beacon_proposer_index( state=state, slot=state.slot, committee_config=CommitteeConfig(config), ) proposer = state.validator_registry[proposer_index] epoch = state.current_epoch(config.SLOTS_PER_EPOCH) validate_randao_reveal( randao_reveal=block.randao_reveal, proposer_index=proposer_index, proposer_pubkey=proposer.pubkey, epoch=epoch, fork=state.fork, ) randao_mix_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH new_randao_mix = bitwise_xor( get_randao_mix( state=state, epoch=epoch, slots_per_epoch=config.SLOTS_PER_EPOCH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ), hash_eth2(block.randao_reveal), ) return state.copy(latest_randao_mixes=update_tuple_item( state.latest_randao_mixes, randao_mix_index, new_randao_mix, ), )
def process_randao(state: BeaconState, block: BaseBeaconBlock, config: Eth2Config) -> BeaconState: proposer_index = get_beacon_proposer_index( state=state, committee_config=CommitteeConfig(config)) epoch = state.current_epoch(config.SLOTS_PER_EPOCH) validate_randao_reveal( state=state, proposer_index=proposer_index, epoch=epoch, randao_reveal=block.body.randao_reveal, slots_per_epoch=config.SLOTS_PER_EPOCH, ) randao_mix_index = epoch % config.EPOCHS_PER_HISTORICAL_VECTOR new_randao_mix = bitwise_xor( get_randao_mix( state=state, epoch=epoch, epochs_per_historical_vector=config.EPOCHS_PER_HISTORICAL_VECTOR, ), hash_eth2(block.body.randao_reveal), ) return state.transform(("randao_mixes", randao_mix_index), new_randao_mix)
def process_final_updates(state: BeaconState, config: BeaconConfig) -> BeaconState: current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH) next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH) state = _update_latest_active_index_roots(state, CommitteeConfig(config)) state = state.copy( latest_slashed_balances=update_tuple_item( state.latest_slashed_balances, next_epoch % config.LATEST_SLASHED_EXIT_LENGTH, state.latest_slashed_balances[current_epoch % config.LATEST_SLASHED_EXIT_LENGTH], ), latest_randao_mixes=update_tuple_item( state.latest_randao_mixes, next_epoch % config.LATEST_SLASHED_EXIT_LENGTH, get_randao_mix( state=state, epoch=current_epoch, slots_per_epoch=config.SLOTS_PER_EPOCH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ), ), ) latest_attestations = tuple( filter( lambda attestation: (slot_to_epoch(attestation.data.slot, config.SLOTS_PER_EPOCH) >= current_epoch), state.latest_attestations)) state = state.copy(latest_attestations=latest_attestations, ) return state
def process_final_updates(state: BeaconState, config: BeaconConfig) -> BeaconState: current_epoch = state.current_epoch(config.EPOCH_LENGTH) next_epoch = state.next_epoch(config.EPOCH_LENGTH) state = state.copy( latest_penalized_balances=update_tuple_item( state.latest_penalized_balances, next_epoch % config.LATEST_PENALIZED_EXIT_LENGTH, state.latest_penalized_balances[ current_epoch % config.LATEST_PENALIZED_EXIT_LENGTH], ), latest_randao_mixes=update_tuple_item( state.latest_randao_mixes, next_epoch % config.LATEST_PENALIZED_EXIT_LENGTH, get_randao_mix( state=state, epoch=current_epoch, epoch_length=config.EPOCH_LENGTH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ), ), ) latest_attestations = tuple( filter( lambda attestation: (slot_to_epoch(attestation.data.slot, config. EPOCH_LENGTH) >= current_epoch), state.latest_attestations)) state = state.copy(latest_attestations=latest_attestations, ) return state
def process_final_updates(state: BeaconState, config: Eth2Config) -> BeaconState: current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH) next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH) state = _update_latest_active_index_roots(state, CommitteeConfig(config)) state = state.copy( latest_slashed_balances=update_tuple_item( state.latest_slashed_balances, next_epoch % config.LATEST_SLASHED_EXIT_LENGTH, state.latest_slashed_balances[current_epoch % config.LATEST_SLASHED_EXIT_LENGTH], ), latest_randao_mixes=update_tuple_item( state.latest_randao_mixes, next_epoch % config.LATEST_RANDAO_MIXES_LENGTH, get_randao_mix( state=state, epoch=current_epoch, slots_per_epoch=config.SLOTS_PER_EPOCH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ), ), ) state = _update_historical_roots(state, next_epoch, config) # Rotate current/previous epoch attestations state = state.copy( previous_epoch_attestations=state.current_epoch_attestations, current_epoch_attestations=(), ) return state
def _compute_next_randao_mixes(state: BeaconState, config: Eth2Config) -> Tuple[Hash32, ...]: current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH) next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH) return state.randao_mixes.set( next_epoch % config.EPOCHS_PER_HISTORICAL_VECTOR, get_randao_mix(state, current_epoch, config.EPOCHS_PER_HISTORICAL_VECTOR), )
def test_process_final_updates(genesis_state, state_slot, attestation_slot, len_latest_attestations, expected_result_len_latest_attestations, config, sample_attestation_params): state = genesis_state.copy( slot=state_slot, ) current_index = state.next_epoch(config.SLOTS_PER_EPOCH) % config.LATEST_SLASHED_EXIT_LENGTH previous_index = state.current_epoch(config.SLOTS_PER_EPOCH) % config.LATEST_SLASHED_EXIT_LENGTH # Assume `len_latest_attestations` attestations in state.latest_attestations # with attestation.data.slot = attestation_slot attestation = Attestation(**sample_attestation_params) latest_attestations = [ attestation.copy( data=attestation.data.copy( slot=attestation_slot ) ) for i in range(len_latest_attestations) ] # Fill latest_slashed_balances slashed_balance_of_previous_epoch = 100 latest_slashed_balances = update_tuple_item( state.latest_slashed_balances, previous_index, slashed_balance_of_previous_epoch, ) state = state.copy( latest_slashed_balances=latest_slashed_balances, latest_attestations=latest_attestations, ) result_state = process_final_updates(state, config) assert ( ( result_state.latest_slashed_balances[current_index] == slashed_balance_of_previous_epoch ) and ( result_state.latest_randao_mixes[current_index] == get_randao_mix( state=state, epoch=state.current_epoch(config.SLOTS_PER_EPOCH), slots_per_epoch=config.SLOTS_PER_EPOCH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ) ) ) assert len(result_state.latest_attestations) == expected_result_len_latest_attestations for attestation in result_state.latest_attestations: assert attestation.data.slot >= state_slot - config.SLOTS_PER_EPOCH