sp_session_validator_management/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
3#![deny(missing_docs)]
4
5#[cfg(feature = "std")]
6use core::str::FromStr;
7
8use scale_info::TypeInfo;
9use sidechain_domain::{MainchainAddress, PolicyId, byte_string::SizedByteString};
10use sp_core::{Decode, Encode, MaxEncodedLen};
11use sp_inherents::{InherentIdentifier, IsFatalError};
12
13pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"/ariadne";
15
16#[derive(Encode, sp_runtime::RuntimeDebug, PartialEq, Eq)]
17#[cfg_attr(feature = "std", derive(Decode, thiserror::Error))]
18pub enum InherentError {
20 #[deprecated(
21 since = "1.5.0",
22 note = "Use InvalidValidatorsMatchingHash or InvalidValidatorsHashMismatch"
23 )]
24 #[cfg_attr(
25 feature = "std",
26 error("The validators in the block do not match the calculated validators")
27 )]
28 InvalidValidators,
30 #[cfg_attr(
31 feature = "std",
32 error("Candidates inherent required: committee needs to be stored one epoch in advance")
33 )]
34 CommitteeNeedsToBeStoredOneEpochInAdvance,
36 #[cfg_attr(
37 feature = "std",
38 error("The validators in the block do not match the calculated validators. Input data hash ({}) is valid.", .0.to_hex_string())
39 )]
40 InvalidValidatorsMatchingHash(SizedByteString<32>),
42 #[cfg_attr(
43 feature = "std",
44 error("The validators and input data hash in the block do not match the calculated values. Expected hash: {}, got: {}",
45 .0.to_hex_string(),
46 .1.to_hex_string())
47 )]
48 InvalidValidatorsHashMismatch(SizedByteString<32>, SizedByteString<32>),
50}
51
52impl IsFatalError for InherentError {
53 fn is_fatal_error(&self) -> bool {
54 true
55 }
56}
57
58pub trait CommitteeMember {
60 type AuthorityId;
62 type AuthorityKeys;
64 fn authority_id(&self) -> Self::AuthorityId;
66 fn authority_keys(&self) -> Self::AuthorityKeys;
68}
69impl<AuthorityId: Clone, AuthorityKeys: Clone> CommitteeMember for (AuthorityId, AuthorityKeys) {
70 type AuthorityId = AuthorityId;
71 type AuthorityKeys = AuthorityKeys;
72 fn authority_id(&self) -> AuthorityId {
73 self.0.clone()
74 }
75 fn authority_keys(&self) -> AuthorityKeys {
76 self.1.clone()
77 }
78}
79
80#[cfg(feature = "std")]
81impl From<InherentError> for sp_inherents::Error {
82 fn from(value: InherentError) -> Self {
83 sp_inherents::Error::Application(Box::from(value))
84 }
85}
86
87#[derive(Default, Debug, Clone, PartialEq, Eq, TypeInfo, Encode, Decode, MaxEncodedLen)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89pub struct MainChainScripts {
91 pub committee_candidate_address: MainchainAddress,
93 pub d_parameter_policy_id: PolicyId,
95 pub permissioned_candidates_policy_id: PolicyId,
97}
98
99#[cfg(feature = "std")]
100impl MainChainScripts {
101 pub fn read_from_env() -> Result<MainChainScripts, envy::Error> {
106 #[derive(serde::Serialize, serde::Deserialize)]
107 pub struct MainChainScriptsEnvConfig {
108 pub committee_candidate_address: String,
109 pub d_parameter_policy_id: PolicyId,
110 pub permissioned_candidates_policy_id: PolicyId,
111 }
112
113 let MainChainScriptsEnvConfig {
114 committee_candidate_address,
115 d_parameter_policy_id,
116 permissioned_candidates_policy_id,
117 } = envy::from_env::<MainChainScriptsEnvConfig>()?;
118
119 let committee_candidate_address = FromStr::from_str(&committee_candidate_address)
120 .map_err(|err| envy::Error::Custom(format!("Incorrect main chain address: {}", err)))?;
121
122 Ok(Self {
123 committee_candidate_address,
124 d_parameter_policy_id,
125 permissioned_candidates_policy_id,
126 })
127 }
128}
129
130sp_api::decl_runtime_apis! {
131 #[api_version(2)]
132 pub trait SessionValidatorManagementApi<
134 CommitteeMember: parity_scale_codec::Decode + parity_scale_codec::Encode + crate::CommitteeMember,
135 AuthoritySelectionInputs: parity_scale_codec::Encode,
136 ScEpochNumber: parity_scale_codec::Encode + parity_scale_codec::Decode
137 > where
138 CommitteeMember::AuthorityId: Encode + Decode,
139 CommitteeMember::AuthorityKeys: Encode + Decode,
140 {
141 fn get_main_chain_scripts() -> MainChainScripts;
143 fn get_next_unset_epoch_number() -> ScEpochNumber;
145
146 #[changed_in(2)]
147 fn get_current_committee() -> (ScEpochNumber, sp_std::vec::Vec<CommitteeMember::AuthorityId>);
149 fn get_current_committee() -> (ScEpochNumber, sp_std::vec::Vec<CommitteeMember>);
151
152 #[changed_in(2)]
153 fn get_next_committee() -> Option<(ScEpochNumber, sp_std::vec::Vec<CommitteeMember::AuthorityId>)>;
155 fn get_next_committee() -> Option<(ScEpochNumber, sp_std::vec::Vec<CommitteeMember>)>;
157
158 #[changed_in(2)]
159 fn calculate_committee(
161 authority_selection_inputs: AuthoritySelectionInputs,
162 sidechain_epoch: ScEpochNumber
163 ) -> Option<sp_std::vec::Vec<(CommitteeMember::AuthorityId, CommitteeMember::AuthorityKeys)>>;
164
165 fn calculate_committee(
167 authority_selection_inputs: AuthoritySelectionInputs,
168 sidechain_epoch: ScEpochNumber
169 ) -> Option<sp_std::vec::Vec<CommitteeMember>>;
170 }
171}