use crate::primitives::*;
use crate::{Config, BeaconState, Error, utils};
pub struct CommitteeAssignment {
pub validators: Vec<u64>,
pub shard: u64,
pub slot: u64,
}
impl<C: Config> BeaconState<C> {
pub fn committee_assignment(
&self,
epoch: u64,
validator_index: u64
) -> Result<Option<CommitteeAssignment>, Error> {
let next_epoch = self.current_epoch() + 1;
if epoch > next_epoch {
return Err(Error::EpochOutOfRange)
}
let committees_per_slot =
self.committee_count(epoch) / C::slots_per_epoch();
let epoch_start_slot = utils::start_slot_of_epoch::<C>(epoch);
for slot in epoch_start_slot..(epoch_start_slot + C::slots_per_epoch()) {
let offset = committees_per_slot *
(slot % C::slots_per_epoch());
let slot_start_shard =
(self.start_shard(epoch)? + offset) % C::shard_count();
for i in 0..committees_per_slot {
let shard = (slot_start_shard + i) % C::shard_count();
let committee = self.crosslink_committee(epoch, shard)?;
if committee.contains(&validator_index) {
return Ok(Some(CommitteeAssignment {
validators: committee,
shard, slot,
}))
}
}
}
Ok(None)
}
pub fn validator_pubkey(&self, index: u64) -> Option<ValidatorId> {
if index as usize >= self.validators.len() {
return None
}
let validator = &self.validators[index as usize];
Some(validator.pubkey.clone())
}
pub fn validator_index(&self, pubkey: &ValidatorId) -> Option<u64> {
let validator_pubkeys = self.validators.iter()
.map(|v| v.pubkey.clone()).collect::<Vec<_>>();
validator_pubkeys.iter().position(|v| v == pubkey).map(|v| v as u64)
}
}