12345678910111213141516171819202122232425262728293031323334353637use super::*;38use frame_benchmarking::{benchmarks, account};39use frame_support::{40 ensure,41 traits::{OnInitialize},42};43use frame_system::RawOrigin;44use sp_runtime::traits::Hash;45use sp_std::{prelude::*, vec};4647use crate::Pallet as Scheduler;48use frame_system::Pallet as System;49use frame_support::traits::Currency;5051const BLOCK_NUMBER: u32 = 2;5253545556575859fn fill_schedule<T: Config>(60 when: T::BlockNumber,61 n: u32,62 periodic: bool,63 resolved: Option<bool>,64) -> Result<(), &'static str> {6566 let t = DispatchTime::At(when);67 let caller = account("user", 0, 1);68 69 70 T::Currency::make_free_balance_be(&caller, T::Currency::minimum_balance());7172 for i in 0..n {73 let (call, hash) = call_and_hash::<T>(i);74 let call_or_hash = match resolved {75 Some(_) => call.into(),76 None => CallOrHashOf::<T>::Hash(hash),77 };78 let period = match periodic {79 true => Some(((i + 100).into(), 100)),80 false => None,81 };8283 let slice_id: [u8; 4] = i.encode().try_into().unwrap();84 let mut id: [u8; 16] = [0; 16];85 id[..4].clone_from_slice(&slice_id);8687 let origin = frame_system::RawOrigin::Signed(caller.clone()).into();88 Scheduler::<T>::do_schedule_named(89 id,90 t,91 period,92 0,93 origin,94 call_or_hash,95 )?;96 }97 ensure!(98 Agenda::<T>::get(when).len() == n as usize,99 "didn't fill schedule"100 );101 Ok(())102}103104fn call_and_hash<T: Config>(i: u32) -> (<T as Config>::Call, T::Hash) {105 106 let call: <T as Config>::Call = frame_system::Call::remark { remark: i.encode() }.into();107 let hash = T::Hashing::hash_of(&call);108 (call, hash)109}110111benchmarks! {112 on_initialize_periodic_named_resolved {113 let s in 1 .. T::MaxScheduledPerBlock::get();114 let when = BLOCK_NUMBER.into();115 fill_schedule::<T>(when, s, true, Some(true))?;116 }: { Scheduler::<T>::on_initialize(BLOCK_NUMBER.into()); }117 verify {118 assert_eq!(System::<T>::event_count(), s);119 for i in 0..s {120 assert_eq!(Agenda::<T>::get(when + (i + 100).into()).len(), 1 as usize);121 }122 }123124 on_initialize_named_resolved {125 let s in 1 .. T::MaxScheduledPerBlock::get();126 let when = BLOCK_NUMBER.into();127 fill_schedule::<T>(when, s, false, Some(true))?;128 }: { Scheduler::<T>::on_initialize(BLOCK_NUMBER.into()); }129 verify {130 assert_eq!(System::<T>::event_count(), s);131 assert!(Agenda::<T>::iter().count() == 0);132 }133134 on_initialize_periodic_resolved {135 let s in 1 .. T::MaxScheduledPerBlock::get();136 let when = BLOCK_NUMBER.into();137 fill_schedule::<T>(when, s, true, Some(true))?;138 }: { Scheduler::<T>::on_initialize(BLOCK_NUMBER.into()); }139 verify {140 assert_eq!(System::<T>::event_count(), s );141 for i in 0..s {142 assert_eq!(Agenda::<T>::get(when + (i + 100).into()).len(), 1 as usize);143 }144 }145146 on_initialize_resolved {147 let s in 1 .. T::MaxScheduledPerBlock::get();148 let when = BLOCK_NUMBER.into();149 fill_schedule::<T>(when, s, false, Some(true))?;150 }: { Scheduler::<T>::on_initialize(BLOCK_NUMBER.into()); }151 verify {152 assert_eq!(System::<T>::event_count(), s);153 assert!(Agenda::<T>::iter().count() == 0);154 }155156 schedule_named {157 let caller: T::AccountId = account("user", 0, 1);158 let origin: RawOrigin<T::AccountId> = frame_system::RawOrigin::Signed(caller.clone());159 let s in 0 .. T::MaxScheduledPerBlock::get();160 let slice_id: [u8; 4] = s.encode().try_into().unwrap();161 let mut id: [u8; 16] = [0; 16];162 id[..4].clone_from_slice(&slice_id);163 let when = BLOCK_NUMBER.into();164 let periodic = Some((T::BlockNumber::one(), 100));165 let priority = 0;166 167 let inner_call = frame_system::Call::set_storage { items: vec![] }.into();168 let call = Box::new(CallOrHashOf::<T>::Value(inner_call));169 fill_schedule::<T>(when, s, true, Some(false))?;170 }: _(origin, id, when, periodic, priority, call)171 verify {172 ensure!(173 Agenda::<T>::get(when).len() == (s + 1) as usize,174 "didn't add to schedule"175 );176 }177178 cancel_named {179 let caller: T::AccountId = account("user", 0, 1);180 let origin: RawOrigin<T::AccountId> = frame_system::RawOrigin::Signed(caller.clone());181 let s in 1 .. T::MaxScheduledPerBlock::get();182 let when = BLOCK_NUMBER.into();183 let id = 0.encode().try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);184 fill_schedule::<T>(when, s, true, Some(false))?;185 }: _(origin, id)186 verify {187 ensure!(188 Lookup::<T>::get(id).is_none(),189 "didn't remove from lookup"190 );191 192 ensure!(193 Agenda::<T>::get(when)[0].is_none(),194 "didn't remove from schedule"195 );196 }197198 impl_benchmark_test_suite!(Scheduler, crate::mock::new_test_ext(), crate::mock::Test);199}