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 get_shuffling(*, seed: Hash32, validators: Sequence['ValidatorRecord'], epoch: EpochNumber, epoch_length: int, target_committee_size: int, shard_count: int) -> Tuple[Iterable[ValidatorIndex], ...]: """ Shuffle ``validators`` into crosslink committees seeded by ``seed`` and ``epoch``. Return a list of ``committee_per_epoch`` committees where each committee is itself a list of validator indices. If ``get_shuffling(seed, validators, epoch)`` returns some value ``x`` for some ``epoch <= get_current_epoch(state) + ENTRY_EXIT_DELAY``, it should return the same value ``x`` for the same ``seed`` and ``epoch`` and possible future modifications of ``validators`` forever in phase 0, and until the ~1 year deletion delay in phase 2 and in the future. """ active_validator_indices = get_active_validator_indices(validators, epoch) committees_per_epoch = get_epoch_committee_count( len(active_validator_indices), shard_count, epoch_length, target_committee_size, ) # Shuffle seed = bitwise_xor(seed, Hash32(epoch.to_bytes(32, byteorder="big"))) shuffled_active_validator_indices = shuffle(active_validator_indices, seed) # Split the shuffled list into committees_per_epoch pieces return tuple( split( shuffled_active_validator_indices, committees_per_epoch, ))
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 get_shuffling(*, seed: Hash32, validators: Sequence['ValidatorRecord'], slot: SlotNumber, epoch_length: int, target_committee_size: int, shard_count: int) -> Tuple[Iterable[ValidatorIndex], ...]: """ Shuffle ``validators`` into crosslink committees seeded by ``seed`` and ``slot``. Return a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each committee is itself a list of validator indices. If ``get_shuffling(seed, validators, slot)`` returns some value ``x``, it should return the same value ``x`` for the same seed and slot and possible future modifications of validators forever in phase 0, and until the ~1 year deletion delay in phase 2 and in the future. """ # Normalizes slot to start of epoch boundary slot = SlotNumber(slot - slot % epoch_length) active_validator_indices = get_active_validator_indices(validators, slot) committees_per_slot = get_committee_count_per_slot( len(active_validator_indices), shard_count, epoch_length, target_committee_size, ) # Shuffle seed = bitwise_xor(seed, Hash32(slot.to_bytes(32, byteorder="big"))) shuffled_active_validator_indices = shuffle(active_validator_indices, seed) # Split the shuffled list into epoch_length * committees_per_slot pieces return tuple( split( shuffled_active_validator_indices, committees_per_slot * epoch_length, ))
def test_bitwise_xor_success(a, b, result): assert bitwise_xor(a, b) == result