referrerpolicy=no-referrer-when-downgrade

pallet_staking_async_ah_client/
benchmarking.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Benchmarking setup for pallet-staking-async-ah-client
19
20use super::*;
21use frame_benchmarking::v2::*;
22use frame_support::traits::Get;
23
24use sp_staking::SessionIndex;
25
26const SEED: u32 = 0;
27
28fn create_offenders<T: Config>(n: u32) -> Vec<T::AccountId> {
29	(0..n).map(|i| frame_benchmarking::account("offender", i, SEED)).collect()
30}
31
32fn create_buffered_offences<T: Config>(
33	_session: SessionIndex,
34	offenders: &[T::AccountId],
35) -> BTreeMap<T::AccountId, BufferedOffence<T::AccountId>> {
36	offenders
37		.iter()
38		.enumerate()
39		.map(|(i, offender)| {
40			let slash_fraction = sp_runtime::Perbill::from_percent(10 + (i % 90) as u32);
41			(offender.clone(), BufferedOffence { reporter: Some(offender.clone()), slash_fraction })
42		})
43		.collect()
44}
45
46fn setup_buffered_offences<T: Config>(n: u32) -> SessionIndex {
47	// Set the pallet to Buffered mode
48	Mode::<T>::put(OperatingMode::Buffered);
49
50	// Create offenders
51	let offenders = create_offenders::<T>(n);
52
53	// Use a specific session for testing
54	let session: SessionIndex = 42;
55
56	// Create buffered offences
57	let offences_map = create_buffered_offences::<T>(session, &offenders);
58
59	// Store the buffered offences
60	BufferedOffences::<T>::mutate(|buffered| {
61		buffered.insert(session, offences_map);
62	});
63
64	session
65}
66
67#[benchmarks]
68mod benchmarks {
69	use super::*;
70
71	#[benchmark]
72	fn process_buffered_offences(n: Linear<1, { T::MaxOffenceBatchSize::get() }>) {
73		// Setup: Create buffered offences and put pallet in Active mode
74		let session = setup_buffered_offences::<T>(n);
75
76		// Transition to Active mode to trigger processing
77		Mode::<T>::put(OperatingMode::Active);
78
79		// Verify offences exist before processing
80		assert!(BufferedOffences::<T>::get().contains_key(&session));
81
82		#[block]
83		{
84			Pallet::<T>::process_buffered_offences();
85		}
86
87		// Verify some offences were processed
88		// In a real scenario, either the session is gone or has fewer offences
89		let remaining_offences =
90			BufferedOffences::<T>::get().get(&session).map(|m| m.len()).unwrap_or(0);
91		let expected_remaining = if n > T::MaxOffenceBatchSize::get() {
92			(n - T::MaxOffenceBatchSize::get()) as usize
93		} else {
94			0
95		};
96		assert_eq!(remaining_offences, expected_remaining);
97	}
98
99	#[cfg(test)]
100	impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
101}