polkadot_runtime_parachains/
session_info.rs1use crate::{
24 configuration, paras, scheduler, shared,
25 util::{take_active_subset, take_active_subset_and_inactive},
26};
27use alloc::vec::Vec;
28use frame_support::{
29 pallet_prelude::*,
30 traits::{OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification},
31};
32use frame_system::pallet_prelude::BlockNumberFor;
33use polkadot_primitives::{
34 AssignmentId, AuthorityDiscoveryId, ExecutorParams, SessionIndex, SessionInfo,
35};
36
37pub use pallet::*;
38
39pub mod migration;
40
41#[cfg(test)]
42mod tests;
43
44pub type AccountId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
46 <T as frame_system::Config>::AccountId,
47>>::ValidatorId;
48
49pub type IdentificationTuple<T> = (
52 AccountId<T>,
53 <<T as Config>::ValidatorSet as ValidatorSetWithIdentification<
54 <T as frame_system::Config>::AccountId,
55 >>::Identification,
56);
57
58#[frame_support::pallet]
59pub mod pallet {
60 use super::*;
61
62 #[pallet::pallet]
63 #[pallet::storage_version(migration::STORAGE_VERSION)]
64 #[pallet::without_storage_info]
65 pub struct Pallet<T>(_);
66
67 #[pallet::config]
68 pub trait Config:
69 frame_system::Config
70 + configuration::Config
71 + shared::Config
72 + paras::Config
73 + scheduler::Config
74 + AuthorityDiscoveryConfig
75 {
76 type ValidatorSet: ValidatorSetWithIdentification<Self::AccountId>;
80 }
81
82 #[pallet::storage]
86 pub(super) type AssignmentKeysUnsafe<T: Config> =
87 StorageValue<_, Vec<AssignmentId>, ValueQuery>;
88
89 #[pallet::storage]
91 pub type EarliestStoredSession<T: Config> = StorageValue<_, SessionIndex, ValueQuery>;
92
93 #[pallet::storage]
97 pub type Sessions<T: Config> = StorageMap<_, Identity, SessionIndex, SessionInfo>;
98
99 #[pallet::storage]
103 pub type AccountKeys<T: Config> = StorageMap<_, Identity, SessionIndex, Vec<AccountId<T>>>;
104
105 #[pallet::storage]
107 pub type SessionExecutorParams<T: Config> =
108 StorageMap<_, Identity, SessionIndex, ExecutorParams>;
109}
110
111pub trait AuthorityDiscoveryConfig {
114 fn authorities() -> Vec<AuthorityDiscoveryId>;
116}
117
118impl<T: pallet_authority_discovery::Config> AuthorityDiscoveryConfig for T {
119 fn authorities() -> Vec<AuthorityDiscoveryId> {
120 pallet_authority_discovery::Pallet::<T>::current_authorities().to_vec()
121 }
122}
123
124impl<T: Config> Pallet<T> {
125 pub(crate) fn initializer_on_new_session(
127 notification: &crate::initializer::SessionChangeNotification<BlockNumberFor<T>>,
128 ) {
129 let config = configuration::ActiveConfig::<T>::get();
130
131 let dispute_period = config.dispute_period;
132
133 let validators = notification.validators.clone().into();
134 let discovery_keys = <T as AuthorityDiscoveryConfig>::authorities();
135 let assignment_keys = AssignmentKeysUnsafe::<T>::get();
136 let active_set = shared::ActiveValidatorIndices::<T>::get();
137
138 let validator_groups = scheduler::ValidatorGroups::<T>::get();
139 let n_cores = validator_groups.len() as u32;
140 let zeroth_delay_tranche_width = config.zeroth_delay_tranche_width;
141 let relay_vrf_modulo_samples = config.relay_vrf_modulo_samples;
142 let n_delay_tranches = config.n_delay_tranches;
143 let no_show_slots = config.no_show_slots;
144 let needed_approvals = config.needed_approvals;
145
146 let new_session_index = notification.session_index;
147 let random_seed = notification.random_seed;
148 let old_earliest_stored_session = EarliestStoredSession::<T>::get();
149 let new_earliest_stored_session = new_session_index.saturating_sub(dispute_period);
150 let new_earliest_stored_session =
151 core::cmp::max(new_earliest_stored_session, old_earliest_stored_session);
152 if old_earliest_stored_session != 0 || Sessions::<T>::get(0).is_some() {
155 for idx in old_earliest_stored_session..new_earliest_stored_session {
156 Sessions::<T>::remove(&idx);
157 AccountKeys::<T>::remove(&idx);
160 SessionExecutorParams::<T>::remove(&idx);
161 }
162 EarliestStoredSession::<T>::set(new_earliest_stored_session);
164 } else {
165 EarliestStoredSession::<T>::set(new_session_index);
167 }
168
169 let account_ids = T::ValidatorSet::validators();
172 let active_account_ids = take_active_subset(&active_set, &account_ids);
173 AccountKeys::<T>::insert(&new_session_index, &active_account_ids);
174
175 let new_session_info = SessionInfo {
177 validators, discovery_keys: take_active_subset_and_inactive(&active_set, &discovery_keys),
179 assignment_keys: take_active_subset(&active_set, &assignment_keys),
180 validator_groups: validator_groups.into(),
181 n_cores,
182 zeroth_delay_tranche_width,
183 relay_vrf_modulo_samples,
184 n_delay_tranches,
185 no_show_slots,
186 needed_approvals,
187 active_validator_indices: active_set,
188 random_seed,
189 dispute_period,
190 };
191 Sessions::<T>::insert(&new_session_index, &new_session_info);
192
193 SessionExecutorParams::<T>::insert(&new_session_index, config.executor_params);
194 }
195
196 pub(crate) fn initializer_initialize(_now: BlockNumberFor<T>) -> Weight {
198 Weight::zero()
199 }
200
201 pub(crate) fn initializer_finalize() {}
203}
204
205impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
206 type Public = AssignmentId;
207}
208
209impl<T: pallet_session::Config + Config> OneSessionHandler<T::AccountId> for Pallet<T> {
210 type Key = AssignmentId;
211
212 fn on_genesis_session<'a, I: 'a>(_validators: I)
213 where
214 I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
215 {
216 }
217
218 fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued: I)
219 where
220 I: Iterator<Item = (&'a T::AccountId, Self::Key)>,
221 {
222 let assignment_keys: Vec<_> = validators.map(|(_, v)| v).collect();
223 AssignmentKeysUnsafe::<T>::set(assignment_keys);
224 }
225
226 fn on_disabled(_i: u32) {}
227}