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