oasis_core_runtime/consensus/
scheduler.rs

1//! Scheduler structures.
2use anyhow::{anyhow, Result};
3
4use crate::{
5    common::{crypto::signature::PublicKey, namespace::Namespace},
6    consensus::beacon::EpochTime,
7};
8
9/// The role a given node plays in a committee.
10#[derive(
11    Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, cbor::Encode, cbor::Decode,
12)]
13#[repr(u8)]
14pub enum Role {
15    /// An invalid role (should never appear on the wire).
16    #[default]
17    Invalid = 0,
18    /// Indicates the node is a worker.
19    Worker = 1,
20    /// Indicates the node is a backup worker.
21    BackupWorker = 2,
22}
23
24/// A node participating in a committee.
25#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
26pub struct CommitteeNode {
27    /// The node's role in a committee.
28    pub role: Role,
29
30    /// The node's public key.
31    pub public_key: PublicKey,
32}
33
34/// The functionality a committee exists to provide.
35#[derive(
36    Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord, cbor::Encode, cbor::Decode,
37)]
38#[repr(u8)]
39pub enum CommitteeKind {
40    /// An invalid committee (should never appear on the wire).
41    #[default]
42    Invalid = 0,
43    /// A compute executor committee.
44    ComputeExecutor = 1,
45}
46
47/// A per-runtime (instance) committee.
48#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
49pub struct Committee {
50    /// The functionality a committee exists to provide.
51    pub kind: CommitteeKind,
52
53    /// The committee members.
54    pub members: Vec<CommitteeNode>,
55
56    /// The runtime ID that this committee is for.
57    pub runtime_id: Namespace,
58
59    /// The epoch for which the committee is valid.
60    pub valid_for: EpochTime,
61}
62
63impl Committee {
64    /// Returns committee nodes with Worker role.
65    pub fn workers(&self) -> Vec<&CommitteeNode> {
66        self.members
67            .iter()
68            .filter(|&member| member.role == Role::Worker)
69            .collect()
70    }
71
72    /// Returns the transaction scheduler of the provided committee based on the provided round.
73    pub fn transaction_scheduler(&self, round: u64) -> Result<&CommitteeNode> {
74        let workers = self.workers();
75        if workers.is_empty() {
76            return Err(anyhow!("GetTransactionScheduler: no workers in committee"));
77        }
78        let scheduler_idx = round as usize % workers.len();
79        let scheduler = workers[scheduler_idx];
80
81        Ok(scheduler)
82    }
83}