referrerpolicy=no-referrer-when-downgrade

polkadot_node_primitives/approval/
criteria.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Assignment criteria VRF generation and checking interfaces.
18
19use crate::approval::{
20	v1::{DelayTranche, RelayVRFStory},
21	v2::{AssignmentCertV2, CoreBitfield},
22};
23use codec::{Decode, Encode};
24use polkadot_primitives::{
25	AssignmentId, CandidateHash, CoreIndex, GroupIndex, IndexedVec, SessionInfo, ValidatorIndex,
26};
27use sc_keystore::LocalKeystore;
28
29use std::collections::HashMap;
30
31/// Details pertaining to our assignment on a block.
32#[derive(Debug, Clone, Encode, Decode, PartialEq)]
33pub struct OurAssignment {
34	cert: AssignmentCertV2,
35	tranche: DelayTranche,
36	validator_index: ValidatorIndex,
37	// Whether the assignment has been triggered already.
38	triggered: bool,
39}
40
41impl OurAssignment {
42	/// Create a new `OurAssignment`.
43	pub fn new(
44		cert: AssignmentCertV2,
45		tranche: DelayTranche,
46		validator_index: ValidatorIndex,
47		triggered: bool,
48	) -> Self {
49		OurAssignment { cert, tranche, validator_index, triggered }
50	}
51	/// Returns a reference to the assignment cert.
52	pub fn cert(&self) -> &AssignmentCertV2 {
53		&self.cert
54	}
55
56	/// Returns the assignment cert.
57	pub fn into_cert(self) -> AssignmentCertV2 {
58		self.cert
59	}
60
61	/// Returns the delay tranche of the assignment.
62	pub fn tranche(&self) -> DelayTranche {
63		self.tranche
64	}
65
66	/// Returns the validator index of the assignment.
67	pub fn validator_index(&self) -> ValidatorIndex {
68		self.validator_index
69	}
70
71	/// Returns whether the assignment has been triggered.
72	pub fn triggered(&self) -> bool {
73		self.triggered
74	}
75
76	/// Marks the assignment as triggered.
77	pub fn mark_triggered(&mut self) {
78		self.triggered = true;
79	}
80}
81
82/// Information about the world assignments are being produced in.
83#[derive(Clone, Debug)]
84pub struct Config {
85	/// The assignment public keys for validators.
86	pub assignment_keys: Vec<AssignmentId>,
87	/// The groups of validators assigned to each core.
88	pub validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
89	/// The number of availability cores used by the protocol during this session.
90	pub n_cores: u32,
91	/// The zeroth delay tranche width.
92	pub zeroth_delay_tranche_width: u32,
93	/// The number of samples we do of `relay_vrf_modulo`.
94	pub relay_vrf_modulo_samples: u32,
95	/// The number of delay tranches in total.
96	pub n_delay_tranches: u32,
97}
98
99impl<'a> From<&'a SessionInfo> for Config {
100	fn from(s: &'a SessionInfo) -> Self {
101		Config {
102			assignment_keys: s.assignment_keys.clone(),
103			validator_groups: s.validator_groups.clone(),
104			n_cores: s.n_cores,
105			zeroth_delay_tranche_width: s.zeroth_delay_tranche_width,
106			relay_vrf_modulo_samples: s.relay_vrf_modulo_samples,
107			n_delay_tranches: s.n_delay_tranches,
108		}
109	}
110}
111
112/// A trait for producing and checking assignments.
113///
114/// Approval voting subsystem implements a a real implemention
115/// for it and tests use a mock implementation.
116pub trait AssignmentCriteria {
117	/// Compute the assignments for the given relay VRF story.
118	fn compute_assignments(
119		&self,
120		keystore: &LocalKeystore,
121		relay_vrf_story: RelayVRFStory,
122		config: &Config,
123		leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>,
124		enable_v2_assignments: bool,
125	) -> HashMap<CoreIndex, OurAssignment>;
126
127	/// Check the assignment cert for the given relay VRF story and returns the delay tranche.
128	fn check_assignment_cert(
129		&self,
130		claimed_core_bitfield: CoreBitfield,
131		validator_index: ValidatorIndex,
132		config: &Config,
133		relay_vrf_story: RelayVRFStory,
134		assignment: &AssignmentCertV2,
135		// Backing groups for each "leaving core".
136		backing_groups: Vec<GroupIndex>,
137	) -> Result<DelayTranche, InvalidAssignment>;
138}
139
140/// Assignment invalid.
141#[derive(Debug, Clone, Copy, PartialEq, Eq)]
142pub struct InvalidAssignment(pub InvalidAssignmentReason);
143
144impl std::fmt::Display for InvalidAssignment {
145	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
146		write!(f, "Invalid Assignment: {:?}", self.0)
147	}
148}
149
150impl std::error::Error for InvalidAssignment {}
151
152/// Failure conditions when checking an assignment cert.
153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154pub enum InvalidAssignmentReason {
155	/// The validator index is out of bounds.
156	ValidatorIndexOutOfBounds,
157	/// Sample index is out of bounds.
158	SampleOutOfBounds,
159	/// Core index is out of bounds.
160	CoreIndexOutOfBounds,
161	/// Invalid assignment key.
162	InvalidAssignmentKey,
163	/// Node is in backing group.
164	IsInBackingGroup,
165	/// Modulo core index mismatch.
166	VRFModuloCoreIndexMismatch,
167	/// Modulo output mismatch.
168	VRFModuloOutputMismatch,
169	/// Delay core index mismatch.
170	VRFDelayCoreIndexMismatch,
171	/// Delay output mismatch.
172	VRFDelayOutputMismatch,
173	/// Invalid arguments
174	InvalidArguments,
175	/// Assignment vrf check resulted in 0 assigned cores.
176	NullAssignment,
177}