pallet_session_validator_management/
session_manager.rs1#![cfg_attr(not(feature = "std"), no_std)]
44
45use crate::CommitteeMember;
46use core::marker::PhantomData;
47use derive_new::new;
48use frame_system::pallet_prelude::BlockNumberFor;
49use log::info;
50use pallet_partner_chains_session::SessionIndex;
51use sp_std::vec::Vec;
52
53#[derive(new)]
54pub struct ValidatorManagementSessionManager<T> {
56 _phantom: PhantomData<T>,
57}
58
59impl<T: crate::Config + pallet_session::Config>
60 pallet_partner_chains_session::SessionManager<T::AccountId, T::AuthorityKeys>
61 for ValidatorManagementSessionManager<T>
62{
63 fn new_session_genesis(
64 _new_index: SessionIndex,
65 ) -> Option<Vec<(T::AccountId, T::AuthorityKeys)>> {
66 Some(
67 crate::Pallet::<T>::current_committee_storage()
68 .committee
69 .into_iter()
70 .map(|member| (member.authority_id().into(), member.authority_keys()))
71 .collect::<Vec<_>>(),
72 )
73 }
74
75 fn new_session(new_index: SessionIndex) -> Option<Vec<(T::AccountId, T::AuthorityKeys)>> {
78 info!("New session {new_index}");
79 pallet_session::pallet::CurrentIndex::<T>::put(new_index);
80 Some(
81 crate::Pallet::<T>::rotate_committee_to_next_epoch()
82 .expect(
83 "Session should never end without current epoch validators defined. \
84 Check ShouldEndSession implementation or if it is used before starting new session",
85 )
86 .into_iter()
87 .map(|member| (member.authority_id().into(), member.authority_keys()))
88 .collect(),
89 )
90 }
91
92 fn end_session(end_index: SessionIndex) {
93 info!("End session {end_index}");
94 }
95
96 fn start_session(start_index: SessionIndex) {
98 let epoch_number = T::current_epoch_number();
99 info!("Start session {start_index}, epoch {epoch_number}");
100 }
101}
102
103impl<T, ScEpochNumber> pallet_partner_chains_session::ShouldEndSession<BlockNumberFor<T>>
106 for ValidatorManagementSessionManager<T>
107where
108 T: crate::Config<ScEpochNumber = ScEpochNumber>,
109 ScEpochNumber: Clone + PartialOrd,
110{
111 fn should_end_session(_n: BlockNumberFor<T>) -> bool {
112 let current_epoch_number = T::current_epoch_number();
113
114 current_epoch_number > crate::Pallet::<T>::current_committee_storage().epoch
115 && crate::Pallet::<T>::next_committee().is_some()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use crate::mock::mock_pallet::CurrentEpoch;
122 use crate::mock::*;
123 use crate::session_manager::*;
124 use crate::*;
125 use pallet_partner_chains_session::ShouldEndSession;
126 pub const IRRELEVANT: u64 = 2;
127
128 type Manager = ValidatorManagementSessionManager<Test>;
129
130 #[test]
131 fn should_end_session_if_last_one_ended_late_and_new_committee_is_defined() {
132 let current_committee_epoch = 100;
133 let current_committee = ids_and_keys_fn(&[ALICE]);
134 let next_committee_epoch = 102;
135 let next_committee = ids_and_keys_fn(&[BOB]);
136
137 new_test_ext().execute_with(|| {
138 CurrentCommittee::<Test>::put(CommitteeInfo {
139 epoch: current_committee_epoch,
140 committee: current_committee,
141 });
142 CurrentEpoch::<Test>::set(current_committee_epoch + 2);
143 assert!(!Manager::should_end_session(IRRELEVANT));
144 NextCommittee::<Test>::put(CommitteeInfo {
145 epoch: next_committee_epoch,
146 committee: next_committee,
147 });
148 assert!(Manager::should_end_session(IRRELEVANT));
149 });
150 }
151}