polkadot_runtime_common/auctions/
benchmarking.rs1#![cfg(feature = "runtime-benchmarks")]
20use super::{Pallet as Auctions, *};
21use frame_support::{
22 assert_ok,
23 traits::{EnsureOrigin, OnInitialize},
24};
25use frame_system::RawOrigin;
26use polkadot_runtime_parachains::paras;
27use sp_runtime::{traits::Bounded, SaturatedConversion};
28
29use frame_benchmarking::v2::*;
30
31fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
32 let events = frame_system::Pallet::<T>::events();
33 let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
34 let frame_system::EventRecord { event, .. } = &events[events.len() - 1];
36 assert_eq!(event, &system_event);
37}
38
39fn fill_winners<T: Config + paras::Config>(lease_period_index: LeasePeriodOf<T>) {
40 let auction_index = AuctionCounter::<T>::get();
41 let minimum_balance = CurrencyOf::<T>::minimum_balance();
42
43 for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 {
44 let owner = account("owner", n, 0);
45 let worst_validation_code = T::Registrar::worst_validation_code();
46 let worst_head_data = T::Registrar::worst_head_data();
47 CurrencyOf::<T>::make_free_balance_be(&owner, BalanceOf::<T>::max_value());
48
49 assert!(T::Registrar::register(
50 owner,
51 ParaId::from(n),
52 worst_head_data,
53 worst_validation_code
54 )
55 .is_ok());
56 }
57 assert_ok!(paras::Pallet::<T>::add_trusted_validation_code(
58 frame_system::Origin::<T>::Root.into(),
59 T::Registrar::worst_validation_code(),
60 ));
61
62 T::Registrar::execute_pending_transitions();
63
64 for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 {
65 let bidder = account("bidder", n, 0);
66 CurrencyOf::<T>::make_free_balance_be(&bidder, BalanceOf::<T>::max_value());
67
68 let slot_range = SlotRange::n((n - 1) as u8).unwrap();
69 let (start, end) = slot_range.as_pair();
70
71 assert!(Auctions::<T>::bid(
72 RawOrigin::Signed(bidder).into(),
73 ParaId::from(n),
74 auction_index,
75 lease_period_index + start.into(), lease_period_index + end.into(), minimum_balance.saturating_mul(n.into()), )
79 .is_ok());
80 }
81}
82
83#[benchmarks(
84 where T: pallet_babe::Config + paras::Config,
85 )]
86mod benchmarks {
87 use super::*;
88
89 #[benchmark]
90 fn new_auction() -> Result<(), BenchmarkError> {
91 let duration = BlockNumberFor::<T>::max_value();
92 let lease_period_index = LeasePeriodOf::<T>::max_value();
93 let origin =
94 T::InitiateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
95
96 #[extrinsic_call]
97 _(origin as T::RuntimeOrigin, duration, lease_period_index);
98
99 assert_last_event::<T>(
100 Event::<T>::AuctionStarted {
101 auction_index: AuctionCounter::<T>::get(),
102 lease_period: LeasePeriodOf::<T>::max_value(),
103 ending: BlockNumberFor::<T>::max_value(),
104 }
105 .into(),
106 );
107
108 Ok(())
109 }
110
111 #[benchmark]
113 fn bid() -> Result<(), BenchmarkError> {
114 let (_, offset) = T::Leaser::lease_period_length();
116 frame_system::Pallet::<T>::set_block_number(offset + One::one());
117
118 let duration = BlockNumberFor::<T>::max_value();
120 let lease_period_index = LeasePeriodOf::<T>::zero();
121 let origin = T::InitiateOrigin::try_successful_origin()
122 .expect("InitiateOrigin has no successful origin required for the benchmark");
123 Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
124
125 let para = ParaId::from(0);
126 let new_para = ParaId::from(1_u32);
127
128 let owner = account("owner", 0, 0);
130 CurrencyOf::<T>::make_free_balance_be(&owner, BalanceOf::<T>::max_value());
131 let worst_head_data = T::Registrar::worst_head_data();
132 let worst_validation_code = T::Registrar::worst_validation_code();
133 T::Registrar::register(
134 owner.clone(),
135 para,
136 worst_head_data.clone(),
137 worst_validation_code.clone(),
138 )?;
139 T::Registrar::register(owner, new_para, worst_head_data, worst_validation_code.clone())?;
140 assert_ok!(paras::Pallet::<T>::add_trusted_validation_code(
141 frame_system::Origin::<T>::Root.into(),
142 worst_validation_code,
143 ));
144
145 T::Registrar::execute_pending_transitions();
146
147 let auction_index = AuctionCounter::<T>::get();
149 let first_slot = AuctionInfo::<T>::get().unwrap().0;
150 let last_slot = first_slot + 3u32.into();
151 let first_amount = CurrencyOf::<T>::minimum_balance();
152 let first_bidder: T::AccountId = account("first_bidder", 0, 0);
153 CurrencyOf::<T>::make_free_balance_be(&first_bidder, BalanceOf::<T>::max_value());
154 Auctions::<T>::bid(
155 RawOrigin::Signed(first_bidder.clone()).into(),
156 para,
157 auction_index,
158 first_slot,
159 last_slot,
160 first_amount,
161 )?;
162
163 let caller: T::AccountId = whitelisted_caller();
164 CurrencyOf::<T>::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
165 let bigger_amount = CurrencyOf::<T>::minimum_balance().saturating_mul(10u32.into());
166 assert_eq!(CurrencyOf::<T>::reserved_balance(&first_bidder), first_amount);
167
168 #[extrinsic_call]
169 _(
170 RawOrigin::Signed(caller.clone()),
171 new_para,
172 auction_index,
173 first_slot,
174 last_slot,
175 bigger_amount,
176 );
177
178 assert_eq!(CurrencyOf::<T>::reserved_balance(&caller), bigger_amount);
181
182 Ok(())
183 }
184
185 #[benchmark]
188 fn on_initialize() -> Result<(), BenchmarkError> {
189 let (lease_length, offset) = T::Leaser::lease_period_length();
191 frame_system::Pallet::<T>::set_block_number(offset + One::one());
192
193 let duration: BlockNumberFor<T> = lease_length / 2u32.into();
195 let lease_period_index = LeasePeriodOf::<T>::zero();
196 let now = frame_system::Pallet::<T>::block_number();
197 let origin = T::InitiateOrigin::try_successful_origin()
198 .expect("InitiateOrigin has no successful origin required for the benchmark");
199 Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
200
201 fill_winners::<T>(lease_period_index);
202
203 for winner in Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap().iter() {
204 assert!(winner.is_some());
205 }
206
207 let winning_data = Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap();
208 for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() {
210 Winning::<T>::insert(BlockNumberFor::<T>::from(i), winning_data.clone());
211 }
212
213 frame_system::Pallet::<T>::set_block_number(duration + now + T::EndingPeriod::get());
215
216 {
218 pallet_babe::EpochStart::<T>::set((Zero::zero(), u32::MAX.into()));
219 pallet_babe::Pallet::<T>::on_initialize(duration + now + T::EndingPeriod::get());
220 let authorities = pallet_babe::Pallet::<T>::authorities();
221 if !authorities.is_empty() {
223 pallet_babe::Pallet::<T>::enact_epoch_change(
224 authorities.clone(),
225 authorities,
226 None,
227 );
228 }
229 }
230
231 #[block]
232 {
233 Auctions::<T>::on_initialize(duration + now + T::EndingPeriod::get());
234 }
235
236 let auction_index = AuctionCounter::<T>::get();
237 assert_last_event::<T>(Event::<T>::AuctionClosed { auction_index }.into());
238 assert!(Winning::<T>::iter().count().is_zero());
239
240 Ok(())
241 }
242
243 #[benchmark]
245 fn cancel_auction() -> Result<(), BenchmarkError> {
246 let (lease_length, offset) = T::Leaser::lease_period_length();
248 frame_system::Pallet::<T>::set_block_number(offset + One::one());
249
250 let duration: BlockNumberFor<T> = lease_length / 2u32.into();
252 let lease_period_index = LeasePeriodOf::<T>::zero();
253 let origin = T::InitiateOrigin::try_successful_origin()
254 .expect("InitiateOrigin has no successful origin required for the benchmark");
255 Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
256
257 fill_winners::<T>(lease_period_index);
258
259 let winning_data = Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap();
260 for winner in winning_data.iter() {
261 assert!(winner.is_some());
262 }
263
264 for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() {
266 Winning::<T>::insert(BlockNumberFor::<T>::from(i), winning_data.clone());
267 }
268 assert!(AuctionInfo::<T>::get().is_some());
269
270 #[extrinsic_call]
271 _(RawOrigin::Root);
272
273 assert!(AuctionInfo::<T>::get().is_none());
274 Ok(())
275 }
276
277 impl_benchmark_test_suite!(
278 Auctions,
279 crate::integration_tests::new_test_ext(),
280 crate::integration_tests::Test,
281 );
282}