1#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24use codec::{Decode, DecodeWithMemTracking, Encode};
25
26#[cfg(feature = "std")]
27use sp_api::ProvideRuntimeApi;
28#[cfg(feature = "std")]
29use sp_runtime::traits::Block as BlockT;
30
31use alloc::vec::Vec;
32use sp_staking::SessionIndex;
33use Debug;
34
35pub mod runtime_api;
36pub use runtime_api::*;
37
38pub type ValidatorCount = u32;
40
41#[derive(
43 Encode,
44 Decode,
45 DecodeWithMemTracking,
46 Clone,
47 Eq,
48 PartialEq,
49 Default,
50 Debug,
51 scale_info::TypeInfo,
52)]
53pub struct MembershipProof {
54 pub session: SessionIndex,
56 pub trie_nodes: Vec<Vec<u8>>,
58 pub validator_count: ValidatorCount,
60}
61
62pub trait GetSessionNumber {
68 fn session(&self) -> SessionIndex;
69}
70
71pub trait GetValidatorCount {
77 fn validator_count(&self) -> ValidatorCount;
78}
79
80impl GetSessionNumber for sp_core::Void {
81 fn session(&self) -> SessionIndex {
82 Default::default()
83 }
84}
85
86impl GetValidatorCount for sp_core::Void {
87 fn validator_count(&self) -> ValidatorCount {
88 Default::default()
89 }
90}
91
92impl GetSessionNumber for MembershipProof {
93 fn session(&self) -> SessionIndex {
94 self.session
95 }
96}
97
98impl GetValidatorCount for MembershipProof {
99 fn validator_count(&self) -> ValidatorCount {
100 self.validator_count
101 }
102}
103
104#[cfg(feature = "std")]
107pub fn generate_initial_session_keys<Block, T>(
108 client: std::sync::Arc<T>,
109 at: Block::Hash,
110 seeds: Vec<String>,
111 keystore: sp_keystore::KeystorePtr,
112) -> Result<(), sp_api::ApiError>
113where
114 Block: BlockT,
115 T: ProvideRuntimeApi<Block>,
116 T::Api: SessionKeys<Block>,
117{
118 use sp_api::{ApiError, ApiExt};
119
120 if seeds.is_empty() {
121 return Ok(())
122 }
123
124 let mut runtime_api = client.runtime_api();
125
126 let version = runtime_api.api_version::<dyn SessionKeys<Block>>(at)?.ok_or_else(|| {
127 ApiError::Application(Box::from("Could not find `SessionKeys` runtime api"))
128 })?;
129
130 runtime_api.register_extension(sp_keystore::KeystoreExt::from(keystore));
131
132 for seed in seeds {
133 let seed = Some(seed.as_bytes().to_vec());
134
135 if version < 2 {
136 #[allow(deprecated)]
137 runtime_api.generate_session_keys_before_version_2(at, seed.clone())?;
138 } else {
139 runtime_api.generate_session_keys(at, vec![], seed.clone())?;
141 }
142 }
143
144 Ok(())
145}