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