pallet_session_benchmarking/
inner.rs1use alloc::vec::Vec;
22use sp_runtime::traits::{One, StaticLookup};
23
24use frame_benchmarking::v2::*;
25use frame_support::{
26 assert_ok,
27 traits::{Get, KeyOwnerProofSystem, OnInitialize},
28};
29use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
30use pallet_session::{historical::Pallet as Historical, Pallet as Session, *};
31use pallet_staking::{
32 benchmarking::create_validator_with_nominators, testing_utils::create_validators,
33 MaxNominationsOf, RewardDestination,
34};
35
36const MAX_VALIDATORS: u32 = 1000;
37
38pub struct Pallet<T: Config>(pallet_session::Pallet<T>);
39pub trait Config:
41 pallet_session::Config + pallet_session::historical::Config + pallet_staking::Config
42{
43 fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>);
49}
50
51impl<T: Config> OnInitialize<BlockNumberFor<T>> for Pallet<T> {
52 fn on_initialize(n: BlockNumberFor<T>) -> frame_support::weights::Weight {
53 pallet_session::Pallet::<T>::on_initialize(n)
54 }
55}
56
57#[benchmarks]
58mod benchmarks {
59 use super::*;
60
61 #[benchmark]
62 fn set_keys() -> Result<(), BenchmarkError> {
63 let n = MaxNominationsOf::<T>::get();
64 let (v_stash, _) = create_validator_with_nominators::<T>(
65 n,
66 MaxNominationsOf::<T>::get(),
67 false,
68 true,
69 RewardDestination::Staked,
70 )?;
71 let v_controller = pallet_staking::Pallet::<T>::bonded(&v_stash).ok_or("not stash")?;
72
73 let (keys, proof) = T::generate_session_keys_and_proof(v_controller.clone());
74 let v_controller_key = frame_system::Account::<T>::hashed_key_for(&v_controller);
76 frame_benchmarking::benchmarking::add_to_whitelist(v_controller_key.into());
77 assert_ok!(Session::<T>::ensure_can_pay_key_deposit(&v_controller));
78
79 #[extrinsic_call]
80 _(RawOrigin::Signed(v_controller), keys, proof);
81
82 Ok(())
83 }
84
85 #[benchmark]
86 fn purge_keys() -> Result<(), BenchmarkError> {
87 let n = MaxNominationsOf::<T>::get();
88 let (v_stash, _) = create_validator_with_nominators::<T>(
89 n,
90 MaxNominationsOf::<T>::get(),
91 false,
92 true,
93 RewardDestination::Staked,
94 )?;
95 let v_controller = pallet_staking::Pallet::<T>::bonded(&v_stash).ok_or("not stash")?;
96 let (keys, proof) = T::generate_session_keys_and_proof(v_controller.clone());
97 assert_ok!(Session::<T>::ensure_can_pay_key_deposit(&v_controller));
98 Session::<T>::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?;
99 let v_controller_key = frame_system::Account::<T>::hashed_key_for(&v_controller);
101 frame_benchmarking::benchmarking::add_to_whitelist(v_controller_key.into());
102
103 #[extrinsic_call]
104 _(RawOrigin::Signed(v_controller));
105
106 Ok(())
107 }
108
109 #[benchmark(extra)]
110 fn check_membership_proof_current_session(n: Linear<2, MAX_VALIDATORS>) {
111 let (key, key_owner_proof1) = check_membership_proof_setup::<T>(n);
112 let key_owner_proof2 = key_owner_proof1.clone();
113
114 #[block]
115 {
116 Historical::<T>::check_proof(key, key_owner_proof1);
117 }
118
119 assert!(Historical::<T>::check_proof(key, key_owner_proof2).is_some());
120 }
121
122 #[benchmark(extra)]
123 fn check_membership_proof_historical_session(n: Linear<2, MAX_VALIDATORS>) {
124 let (key, key_owner_proof1) = check_membership_proof_setup::<T>(n);
125
126 Session::<T>::rotate_session();
129
130 let key_owner_proof2 = key_owner_proof1.clone();
131
132 #[block]
133 {
134 Historical::<T>::check_proof(key, key_owner_proof1);
135 }
136
137 assert!(Historical::<T>::check_proof(key, key_owner_proof2).is_some());
138 }
139
140 impl_benchmark_test_suite!(
141 Pallet,
142 crate::mock::new_test_ext(),
143 crate::mock::Test,
144 extra = false
145 );
146}
147
148fn check_membership_proof_setup<T: Config>(
152 n: u32,
153) -> ((sp_runtime::KeyTypeId, &'static [u8; 32]), sp_session::MembershipProof) {
154 pallet_staking::ValidatorCount::<T>::put(n);
155
156 for (n, who) in create_validators::<T>(n, 1000).unwrap().into_iter().enumerate() {
158 use rand::{RngCore, SeedableRng};
159
160 let validator = T::Lookup::lookup(who).unwrap();
161 let controller = pallet_staking::Pallet::<T>::bonded(&validator).unwrap();
162
163 let _keys = {
164 let mut keys = [0u8; 128];
165
166 if n > 0 {
168 let mut rng = rand::rngs::StdRng::seed_from_u64(n as u64);
169 rng.fill_bytes(&mut keys);
170 }
171
172 keys
173 };
174
175 let (keys, proof) = T::generate_session_keys_and_proof(controller.clone());
178
179 Session::<T>::set_keys(RawOrigin::Signed(controller).into(), keys, proof).unwrap();
180 }
181
182 Pallet::<T>::on_initialize(frame_system::pallet_prelude::BlockNumberFor::<T>::one());
183
184 while Validators::<T>::get().len() < n as usize {
186 Session::<T>::rotate_session();
187 }
188
189 let key = (sp_runtime::KeyTypeId(*b"babe"), &[0u8; 32]);
190
191 (key, Historical::<T>::prove(key).unwrap())
192}