def get_validator_duties(self, public_keys: Collection[BLSPubkey], epoch: Epoch) -> Iterable[ValidatorDuty]: if epoch < GENESIS_EPOCH: return () current_tick = self.clock.compute_current_tick() state = advance_state_to_slot(self.chain, current_tick.slot) for public_key in public_keys: validator_index = state.get_validator_index_for_public_key( public_key) try: committee_assignment = get_committee_assignment( state, self.eth2_config, epoch, validator_index) except NoCommitteeAssignment: continue if is_proposer(state, validator_index, self.eth2_config): # TODO (ralexstokes) clean this up! if state.slot != 0: block_proposal_slot = state.slot else: block_proposal_slot = Slot((1 << 64) - 1) else: # NOTE: temporary sentinel value for "no slot" # The API has since been updated w/ much better ergonomics block_proposal_slot = Slot((1 << 64) - 1) yield ValidatorDuty( public_key, committee_assignment.slot, committee_assignment.committee_index, block_proposal_slot, )
def _get_slot_with_validator_selected(candidate_indices, state, config): epoch = state.current_epoch(config.SLOTS_PER_EPOCH) epoch_start_slot = compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH) for index in candidate_indices: try: for slot in range(epoch_start_slot, epoch_start_slot + config.SLOTS_PER_EPOCH): state = state.copy(slot=slot) if is_proposer(state, index, config): return slot, index except NoCommitteeAssignment: continue raise Exception( "Check the parameters of the genesis state; the above code should return" " some proposer if the set of ``candidate_indices`` is big enough." )