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