sp_session_validator_management/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
6#![deny(missing_docs)]
7
8extern crate alloc;
9
10use alloc::vec::Vec;
11#[cfg(feature = "std")]
12use core::str::FromStr;
13use parity_scale_codec::DecodeWithMemTracking;
14use scale_info::TypeInfo;
15use sidechain_domain::{
16 CandidateRegistrations, DParameter, EpochNonce, MainchainAddress, PermissionedCandidateData,
17 PolicyId, StakePoolPublicKey, byte_string::SizedByteString,
18};
19use sp_core::{Decode, Encode, MaxEncodedLen};
20use sp_inherents::{InherentIdentifier, IsFatalError};
21
22pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"/ariadne";
24
25#[derive(Encode, sp_runtime::RuntimeDebug, PartialEq, Eq)]
26#[cfg_attr(feature = "std", derive(Decode, thiserror::Error))]
27pub enum InherentError {
29 #[deprecated(
30 since = "1.5.0",
31 note = "Use InvalidValidatorsMatchingHash or InvalidValidatorsHashMismatch"
32 )]
33 #[cfg_attr(
34 feature = "std",
35 error("The validators in the block do not match the calculated validators")
36 )]
37 InvalidValidators,
39 #[cfg_attr(
40 feature = "std",
41 error("Candidates inherent required: committee needs to be stored one epoch in advance")
42 )]
43 CommitteeNeedsToBeStoredOneEpochInAdvance,
45 #[cfg_attr(
46 feature = "std",
47 error("The validators in the block do not match the calculated validators. Input data hash ({}) is valid.", .0.to_hex_string())
48 )]
49 InvalidValidatorsMatchingHash(SizedByteString<32>),
51 #[cfg_attr(
52 feature = "std",
53 error("The validators and input data hash in the block do not match the calculated values. Expected hash: {}, got: {}",
54 .0.to_hex_string(),
55 .1.to_hex_string())
56 )]
57 InvalidValidatorsHashMismatch(SizedByteString<32>, SizedByteString<32>),
59}
60
61impl IsFatalError for InherentError {
62 fn is_fatal_error(&self) -> bool {
63 true
64 }
65}
66
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68#[derive(
69 Clone,
70 Encode,
71 Decode,
72 DecodeWithMemTracking,
73 TypeInfo,
74 MaxEncodedLen,
75 Debug,
76 PartialEq,
77 Eq,
78 PartialOrd,
79 Ord,
80)]
81pub enum CommitteeMember<AuthorityId, AuthorityKeys> {
83 Permissioned {
85 id: AuthorityId,
87 keys: AuthorityKeys,
89 },
90 Registered {
92 id: AuthorityId,
94 keys: AuthorityKeys,
96 stake_pool_pub_key: StakePoolPublicKey,
98 },
99}
100
101impl<AuthorityId, AuthorityKeys> From<(AuthorityId, AuthorityKeys)>
102 for CommitteeMember<AuthorityId, AuthorityKeys>
103{
104 fn from((id, keys): (AuthorityId, AuthorityKeys)) -> Self {
105 Self::Permissioned { id, keys }
106 }
107}
108
109impl<AuthorityId, AuthorityKeys> CommitteeMember<AuthorityId, AuthorityKeys> {
110 pub fn permissioned(id: AuthorityId, keys: AuthorityKeys) -> Self {
112 Self::Permissioned { id, keys }
113 }
114
115 pub fn authority_id(&self) -> AuthorityId
117 where
118 AuthorityId: Clone,
119 {
120 match self {
121 Self::Permissioned { id, .. } => id.clone(),
122 Self::Registered { id, .. } => id.clone(),
123 }
124 }
125
126 pub fn authority_keys(&self) -> AuthorityKeys
128 where
129 AuthorityKeys: Clone,
130 {
131 match self {
132 Self::Permissioned { keys, .. } => keys.clone(),
133 Self::Registered { keys, .. } => keys.clone(),
134 }
135 }
136
137 pub fn map_authority_keys<NewKeys>(
139 self,
140 f: impl Fn(AuthorityKeys) -> NewKeys,
141 ) -> CommitteeMember<AuthorityId, NewKeys> {
142 match self {
143 Self::Permissioned { id, keys } => CommitteeMember::Permissioned { id, keys: f(keys) },
144 Self::Registered { id, keys, stake_pool_pub_key } => {
145 CommitteeMember::Registered { id, keys: f(keys), stake_pool_pub_key }
146 },
147 }
148 }
149}
150
151#[cfg(feature = "std")]
152impl From<InherentError> for sp_inherents::Error {
153 fn from(value: InherentError) -> Self {
154 sp_inherents::Error::Application(Box::from(value))
155 }
156}
157
158#[derive(Default, Debug, Clone, PartialEq, Eq, TypeInfo, Encode, Decode, MaxEncodedLen)]
159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
160pub struct MainChainScripts {
162 pub committee_candidate_address: MainchainAddress,
164 pub d_parameter_policy_id: PolicyId,
166 pub permissioned_candidates_policy_id: PolicyId,
168}
169
170#[cfg(feature = "std")]
171impl MainChainScripts {
172 pub fn read_from_env() -> Result<MainChainScripts, envy::Error> {
177 #[derive(serde::Serialize, serde::Deserialize)]
178 pub struct MainChainScriptsEnvConfig {
179 pub committee_candidate_address: String,
180 pub d_parameter_policy_id: PolicyId,
181 pub permissioned_candidates_policy_id: PolicyId,
182 }
183
184 let MainChainScriptsEnvConfig {
185 committee_candidate_address,
186 d_parameter_policy_id,
187 permissioned_candidates_policy_id,
188 } = envy::from_env::<MainChainScriptsEnvConfig>()?;
189
190 let committee_candidate_address = FromStr::from_str(&committee_candidate_address)
191 .map_err(|err| envy::Error::Custom(format!("Incorrect main chain address: {}", err)))?;
192
193 Ok(Self {
194 committee_candidate_address,
195 d_parameter_policy_id,
196 permissioned_candidates_policy_id,
197 })
198 }
199}
200
201#[derive(Clone, Debug, Encode, Decode, DecodeWithMemTracking, TypeInfo, PartialEq, Eq)]
204pub struct AuthoritySelectionInputs {
205 pub d_parameter: DParameter,
207 pub permissioned_candidates: Vec<PermissionedCandidateData>,
209 pub registered_candidates: Vec<CandidateRegistrations>,
211 pub epoch_nonce: EpochNonce,
213}
214
215sp_api::decl_runtime_apis! {
216 #[api_version(3)]
217 pub trait SessionValidatorManagementApi<
219 AuthorityId,
220 AuthorityKeys,
221 ScEpochNumber: parity_scale_codec::Encode + parity_scale_codec::Decode
222 > where
223 AuthorityId: Encode + Decode,
224 AuthorityKeys: Encode + Decode,
225 {
226 fn get_main_chain_scripts() -> MainChainScripts;
228 fn get_next_unset_epoch_number() -> ScEpochNumber;
230
231 #[changed_in(2)]
232 fn get_current_committee() -> (ScEpochNumber, sp_std::vec::Vec<CommitteeMember<AuthorityId, AuthorityKeys>>);
234 fn get_current_committee() -> (ScEpochNumber, sp_std::vec::Vec<CommitteeMember<AuthorityId, AuthorityKeys>>);
236
237 #[changed_in(2)]
238 fn get_next_committee() -> Option<(ScEpochNumber, sp_std::vec::Vec<CommitteeMember<AuthorityId, AuthorityKeys>>)>;
240 fn get_next_committee() -> Option<(ScEpochNumber, sp_std::vec::Vec<CommitteeMember<AuthorityId, AuthorityKeys>>)>;
242
243 #[changed_in(2)]
244 fn calculate_committee(
246 authority_selection_inputs: AuthoritySelectionInputs,
247 sidechain_epoch: ScEpochNumber
248 ) -> Option<sp_std::vec::Vec<(AuthorityId, AuthorityKeys)>>;
249
250 fn calculate_committee(
252 authority_selection_inputs: AuthoritySelectionInputs,
253 sidechain_epoch: ScEpochNumber
254 ) -> Option<sp_std::vec::Vec<CommitteeMember<AuthorityId, AuthorityKeys>>>;
255 }
256}