rococo_runtime/
validator_manager.rs1use alloc::vec::Vec;
20use sp_staking::SessionIndex;
21
22pub use pallet::*;
23
24type Session<T> = pallet_session::Pallet<T>;
25
26#[frame_support::pallet]
27pub mod pallet {
28 use super::*;
29 use frame_support::{dispatch::DispatchResult, pallet_prelude::*, traits::EnsureOrigin};
30 use frame_system::pallet_prelude::*;
31
32 #[pallet::pallet]
33 #[pallet::without_storage_info]
34 pub struct Pallet<T>(_);
35
36 #[pallet::config]
38 pub trait Config: frame_system::Config + pallet_session::Config {
39 #[allow(deprecated)]
41 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
42
43 type PrivilegedOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;
45 }
46
47 #[pallet::event]
48 #[pallet::generate_deposit(pub(super) fn deposit_event)]
49 pub enum Event<T: Config> {
50 ValidatorsRegistered(Vec<T::ValidatorId>),
52 ValidatorsDeregistered(Vec<T::ValidatorId>),
54 }
55
56 #[pallet::storage]
58 pub(crate) type ValidatorsToRetire<T: Config> =
59 StorageValue<_, Vec<T::ValidatorId>, ValueQuery>;
60
61 #[pallet::storage]
63 pub(crate) type ValidatorsToAdd<T: Config> = StorageValue<_, Vec<T::ValidatorId>, ValueQuery>;
64
65 #[pallet::call]
66 impl<T: Config> Pallet<T> {
67 #[pallet::call_index(0)]
71 #[pallet::weight({100_000})]
72 pub fn register_validators(
73 origin: OriginFor<T>,
74 validators: Vec<T::ValidatorId>,
75 ) -> DispatchResult {
76 T::PrivilegedOrigin::ensure_origin(origin)?;
77
78 validators.clone().into_iter().for_each(|v| ValidatorsToAdd::<T>::append(v));
79
80 Self::deposit_event(Event::ValidatorsRegistered(validators));
81 Ok(())
82 }
83
84 #[pallet::call_index(1)]
88 #[pallet::weight({100_000})]
89 pub fn deregister_validators(
90 origin: OriginFor<T>,
91 validators: Vec<T::ValidatorId>,
92 ) -> DispatchResult {
93 T::PrivilegedOrigin::ensure_origin(origin)?;
94
95 validators.clone().into_iter().for_each(|v| ValidatorsToRetire::<T>::append(v));
96
97 Self::deposit_event(Event::ValidatorsDeregistered(validators));
98 Ok(())
99 }
100 }
101}
102
103impl<T: Config> pallet_session::SessionManager<T::ValidatorId> for Pallet<T> {
104 fn new_session(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
105 if new_index <= 1 {
106 return None
107 }
108
109 let mut validators = Session::<T>::validators();
110
111 ValidatorsToRetire::<T>::take().iter().for_each(|v| {
112 if let Some(pos) = validators.iter().position(|r| r == v) {
113 validators.swap_remove(pos);
114 }
115 });
116
117 ValidatorsToAdd::<T>::take().into_iter().for_each(|v| {
118 if !validators.contains(&v) {
119 validators.push(v);
120 }
121 });
122
123 Some(validators)
124 }
125
126 fn end_session(_: SessionIndex) {}
127
128 fn start_session(_start_index: SessionIndex) {}
129}
130
131impl<T: Config> pallet_session::historical::SessionManager<T::ValidatorId, ()> for Pallet<T> {
132 fn new_session(new_index: SessionIndex) -> Option<Vec<(T::ValidatorId, ())>> {
133 <Self as pallet_session::SessionManager<_>>::new_session(new_index)
134 .map(|r| r.into_iter().map(|v| (v, Default::default())).collect())
135 }
136
137 fn start_session(start_index: SessionIndex) {
138 <Self as pallet_session::SessionManager<_>>::start_session(start_index)
139 }
140
141 fn end_session(end_index: SessionIndex) {
142 <Self as pallet_session::SessionManager<_>>::end_session(end_index)
143 }
144}