use crate::approval::{
v1::{DelayTranche, RelayVRFStory},
v2::{AssignmentCertV2, CoreBitfield},
};
use codec::{Decode, Encode};
use polkadot_primitives::{
AssignmentId, CandidateHash, CoreIndex, GroupIndex, IndexedVec, SessionInfo, ValidatorIndex,
};
use sc_keystore::LocalKeystore;
use std::collections::HashMap;
#[derive(Debug, Clone, Encode, Decode, PartialEq)]
pub struct OurAssignment {
cert: AssignmentCertV2,
tranche: DelayTranche,
validator_index: ValidatorIndex,
triggered: bool,
}
impl OurAssignment {
pub fn new(
cert: AssignmentCertV2,
tranche: DelayTranche,
validator_index: ValidatorIndex,
triggered: bool,
) -> Self {
OurAssignment { cert, tranche, validator_index, triggered }
}
pub fn cert(&self) -> &AssignmentCertV2 {
&self.cert
}
pub fn into_cert(self) -> AssignmentCertV2 {
self.cert
}
pub fn tranche(&self) -> DelayTranche {
self.tranche
}
pub fn validator_index(&self) -> ValidatorIndex {
self.validator_index
}
pub fn triggered(&self) -> bool {
self.triggered
}
pub fn mark_triggered(&mut self) {
self.triggered = true;
}
}
#[derive(Clone, Debug)]
pub struct Config {
pub assignment_keys: Vec<AssignmentId>,
pub validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
pub n_cores: u32,
pub zeroth_delay_tranche_width: u32,
pub relay_vrf_modulo_samples: u32,
pub n_delay_tranches: u32,
}
impl<'a> From<&'a SessionInfo> for Config {
fn from(s: &'a SessionInfo) -> Self {
Config {
assignment_keys: s.assignment_keys.clone(),
validator_groups: s.validator_groups.clone(),
n_cores: s.n_cores,
zeroth_delay_tranche_width: s.zeroth_delay_tranche_width,
relay_vrf_modulo_samples: s.relay_vrf_modulo_samples,
n_delay_tranches: s.n_delay_tranches,
}
}
}
pub trait AssignmentCriteria {
fn compute_assignments(
&self,
keystore: &LocalKeystore,
relay_vrf_story: RelayVRFStory,
config: &Config,
leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
enable_v2_assignments: bool,
) -> HashMap<CoreIndex, OurAssignment>;
fn check_assignment_cert(
&self,
claimed_core_bitfield: CoreBitfield,
validator_index: ValidatorIndex,
config: &Config,
relay_vrf_story: RelayVRFStory,
assignment: &AssignmentCertV2,
backing_groups: Vec<GroupIndex>,
) -> Result<DelayTranche, InvalidAssignment>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct InvalidAssignment(pub InvalidAssignmentReason);
impl std::fmt::Display for InvalidAssignment {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Invalid Assignment: {:?}", self.0)
}
}
impl std::error::Error for InvalidAssignment {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InvalidAssignmentReason {
ValidatorIndexOutOfBounds,
SampleOutOfBounds,
CoreIndexOutOfBounds,
InvalidAssignmentKey,
IsInBackingGroup,
VRFModuloCoreIndexMismatch,
VRFModuloOutputMismatch,
VRFDelayCoreIndexMismatch,
VRFDelayOutputMismatch,
InvalidArguments,
NullAssignment,
}