def initiate_validator_exit(state: BeaconState, index: ValidatorIndex, config: Eth2Config) -> BeaconState: """ Initiate exit for the validator with the given ``index``. Return the updated state (immutable). """ return state.update_validator_with_fn(index, initiate_exit_for_validator, state, config)
def initialize_beacon_state_from_eth1(*, eth1_block_hash: Hash32, eth1_timestamp: Timestamp, deposits: Sequence[Deposit], config: Eth2Config) -> BeaconState: state = BeaconState( genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp), eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)), latest_block_header=BeaconBlockHeader( body_root=BeaconBlockBody().hash_tree_root), randao_mixes=(eth1_block_hash, ) * config.EPOCHS_PER_HISTORICAL_VECTOR, config=config, ) # Process genesis deposits for index, deposit in enumerate(deposits): deposit_data_list = tuple(deposit.data for deposit in deposits[:index + 1]) state = state.copy(eth1_data=state.eth1_data.copy( deposit_root=ssz.get_hash_tree_root( deposit_data_list, ssz.List(DepositData, 2**DEPOSIT_CONTRACT_TREE_DEPTH), ))) state = process_deposit(state=state, deposit=deposit, config=config) # Process genesis activations for validator_index in range(len(state.validators)): validator_index = ValidatorIndex(validator_index) balance = state.balances[validator_index] effective_balance = calculate_effective_balance(balance, config) state = state.update_validator_with_fn( validator_index, lambda v, *_: v.copy(effective_balance=effective_balance)) if effective_balance == config.MAX_EFFECTIVE_BALANCE: state = state.update_validator_with_fn(validator_index, activate_validator, config.GENESIS_EPOCH) return state
def slash_validator(state: BeaconState, index: ValidatorIndex, config: Eth2Config, whistleblower_index: ValidatorIndex = None) -> BeaconState: """ Slash the validator with index ``index``. Exit the validator, penalize the validator, and reward the whistleblower. """ # NOTE: remove in phase 1 assert whistleblower_index is None slots_per_epoch = config.SLOTS_PER_EPOCH current_epoch = state.current_epoch(slots_per_epoch) state = initiate_validator_exit(state, index, config) state = state.update_validator_with_fn( index, _set_validator_slashed, current_epoch, config.EPOCHS_PER_SLASHINGS_VECTOR, ) slashed_balance = state.validators[index].effective_balance slashed_epoch = current_epoch % config.EPOCHS_PER_SLASHINGS_VECTOR state = state.copy(slashings=update_tuple_item_with_fn( state.slashings, slashed_epoch, lambda balance, slashed_balance: Gwei(balance + slashed_balance), slashed_balance, )) state = decrease_balance( state, index, slashed_balance // config.MIN_SLASHING_PENALTY_QUOTIENT) proposer_index = get_beacon_proposer_index(state, CommitteeConfig(config)) if whistleblower_index is None: whistleblower_index = proposer_index whistleblower_reward = Gwei(slashed_balance // config.WHISTLEBLOWER_REWARD_QUOTIENT) proposer_reward = Gwei(whistleblower_reward // config.PROPOSER_REWARD_QUOTIENT) state = increase_balance(state, proposer_index, proposer_reward) state = increase_balance( state, whistleblower_index, Gwei(whistleblower_reward - proposer_reward), ) return state
def get_genesis_beacon_state(*, genesis_deposits: Sequence[Deposit], genesis_time: Timestamp, genesis_eth1_data: Eth1Data, config: Eth2Config) -> BeaconState: state = BeaconState( genesis_time=genesis_time, eth1_data=genesis_eth1_data, latest_block_header=BeaconBlockHeader( body_root=BeaconBlockBody().root, ), config=config, ) # Process genesis deposits for deposit in genesis_deposits: state = process_deposit( state=state, deposit=deposit, config=config, ) # Process genesis activations for validator_index in range(len(state.validators)): validator_index = ValidatorIndex(validator_index) effective_balance = state.validators[validator_index].effective_balance is_enough_effective_balance = effective_balance >= config.MAX_EFFECTIVE_BALANCE if is_enough_effective_balance: state = state.update_validator_with_fn( validator_index, activate_validator, config.GENESIS_EPOCH, ) return genesis_state_with_active_index_roots( state, config, )