use anyhow::{anyhow, Result};
use crate::{
common::{crypto::signature::PublicKey, namespace::Namespace},
consensus::beacon::EpochTime,
};
#[derive(
Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, cbor::Encode, cbor::Decode,
)]
#[repr(u8)]
pub enum Role {
#[default]
Invalid = 0,
Worker = 1,
BackupWorker = 2,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct CommitteeNode {
pub role: Role,
pub public_key: PublicKey,
}
#[derive(
Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, cbor::Encode, cbor::Decode,
)]
#[repr(u8)]
pub enum CommitteeKind {
#[default]
Invalid = 0,
ComputeExecutor = 1,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
pub struct Committee {
pub kind: CommitteeKind,
pub members: Vec<CommitteeNode>,
pub runtime_id: Namespace,
pub valid_for: EpochTime,
}
impl Committee {
pub fn workers(&self) -> Vec<&CommitteeNode> {
self.members
.iter()
.filter(|&member| member.role == Role::Worker)
.collect()
}
pub fn transaction_scheduler(&self, round: u64) -> Result<&CommitteeNode> {
let workers = self.workers();
if workers.is_empty() {
return Err(anyhow!("GetTransactionScheduler: no workers in committee"));
}
let scheduler_idx = round as usize % workers.len();
let scheduler = workers[scheduler_idx];
Ok(scheduler)
}
}