difftreelog
fix priority benchmarks
in: master
1 file changed
pallets/scheduler-v2/src/benchmarking.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original license:18// This file is part of Substrate.1920// Copyright (C) 2020-2022 Parity Technologies (UK) Ltd.21// SPDX-License-Identifier: Apache-2.02223// Licensed under the Apache License, Version 2.0 (the "License");24// you may not use this file except in compliance with the License.25// You may obtain a copy of the License at26//27// http://www.apache.org/licenses/LICENSE-2.028//29// Unless required by applicable law or agreed to in writing, software30// distributed under the License is distributed on an "AS IS" BASIS,31// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.32// See the License for the specific language governing permissions and33// limitations under the License.3435//! Scheduler pallet benchmarking.3637use super::*;38use frame_benchmarking::{account, benchmarks};39use frame_support::{40 ensure,41 traits::{schedule::Priority, PreimageRecipient},42};43use frame_system::RawOrigin;44use sp_std::{prelude::*, vec};4546use crate::{Pallet as Scheduler, ScheduledCall, EncodedCall};47use frame_system::Call as SystemCall;4849const SEED: u32 = 0;5051const BLOCK_NUMBER: u32 = 2;5253type SystemOrigin<T> = <T as frame_system::Config>::Origin;5455/// Add `n` items to the schedule.56///57/// For `resolved`:58/// - `59/// - `None`: aborted (hash without preimage)60/// - `Some(true)`: hash resolves into call if possible, plain call otherwise61/// - `Some(false)`: plain call62fn fill_schedule<T: Config>(when: T::BlockNumber, n: u32) -> Result<(), &'static str> {63 let t = DispatchTime::At(when);64 let origin: <T as Config>::PalletsOrigin = frame_system::RawOrigin::Root.into();65 for i in 0..n {66 let call = make_call::<T>(None);67 let period = Some(((i + 100).into(), 100));68 let name = u32_to_name(i);69 Scheduler::<T>::do_schedule_named(name, t, period, 0, origin.clone(), call)?;70 }71 ensure!(72 Agenda::<T>::get(when).len() == n as usize,73 "didn't fill schedule"74 );75 Ok(())76}7778fn u32_to_name(i: u32) -> TaskName {79 i.using_encoded(blake2_256)80}8182fn make_task<T: Config>(83 periodic: bool,84 named: bool,85 signed: bool,86 maybe_lookup_len: Option<u32>,87 priority: Priority,88) -> ScheduledOf<T> {89 let call = make_call::<T>(maybe_lookup_len);90 let maybe_periodic = match periodic {91 true => Some((100u32.into(), 100)),92 false => None,93 };94 let maybe_id = match named {95 true => Some(u32_to_name(0)),96 false => None,97 };98 let origin = make_origin::<T>(signed);99 Scheduled {100 maybe_id,101 priority,102 call,103 maybe_periodic,104 origin,105 _phantom: PhantomData,106 }107}108109fn bounded<T: Config>(len: u32) -> Option<ScheduledCall<T>> {110 let call = <<T as Config>::Call>::from(SystemCall::remark {111 remark: vec![0; len as usize],112 });113 ScheduledCall::new(call).ok()114}115116fn make_call<T: Config>(maybe_lookup_len: Option<u32>) -> ScheduledCall<T> {117 let bound = EncodedCall::bound() as u32;118 let mut len = match maybe_lookup_len {119 Some(len) => {120 len.min(<T::Preimages as PreimageRecipient<T::Hash>>::MaxSize::get() - 2)121 .max(bound) - 3122 }123 None => bound.saturating_sub(4),124 };125126 loop {127 let c = match bounded::<T>(len) {128 Some(x) => x,129 None => {130 len -= 1;131 continue;132 }133 };134 if c.lookup_needed() == maybe_lookup_len.is_some() {135 break c;136 }137 if maybe_lookup_len.is_some() {138 len += 1;139 } else {140 if len > 0 {141 len -= 1;142 } else {143 break c;144 }145 }146 }147}148149fn make_origin<T: Config>(signed: bool) -> <T as Config>::PalletsOrigin {150 match signed {151 true => frame_system::RawOrigin::Signed(account("origin", 0, SEED)).into(),152 false => frame_system::RawOrigin::Root.into(),153 }154}155156fn dummy_counter() -> WeightCounter {157 WeightCounter {158 used: Weight::zero(),159 limit: Weight::MAX,160 }161}162163benchmarks! {164 // `service_agendas` when no work is done.165 service_agendas_base {166 let now = T::BlockNumber::from(BLOCK_NUMBER);167 IncompleteSince::<T>::put(now - One::one());168 }: {169 Scheduler::<T>::service_agendas(&mut dummy_counter(), now, 0);170 } verify {171 assert_eq!(IncompleteSince::<T>::get(), Some(now - One::one()));172 }173174 // `service_agenda` when no work is done.175 service_agenda_base {176 let now = BLOCK_NUMBER.into();177 let s in 0 .. T::MaxScheduledPerBlock::get();178 fill_schedule::<T>(now, s)?;179 let mut executed = 0;180 }: {181 Scheduler::<T>::service_agenda(&mut dummy_counter(), &mut executed, now, now, 0);182 } verify {183 assert_eq!(executed, 0);184 }185186 // `service_task` when the task is a non-periodic, non-named, non-fetched call which is not187 // dispatched (e.g. due to being overweight).188 service_task_base {189 let now = BLOCK_NUMBER.into();190 let task = make_task::<T>(false, false, false, None, 0);191 // prevent any tasks from actually being executed as we only want the surrounding weight.192 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() };193 }: {194 let result = Scheduler::<T>::service_task(&mut counter, now, now, 0, true, task);195 } verify {196 //assert_eq!(result, Ok(()));197 }198199 // `service_task` when the task is a non-periodic, non-named, fetched call (with a known200 // preimage length) and which is not dispatched (e.g. due to being overweight).201 service_task_fetched {202 let s in (EncodedCall::bound() as u32) .. (<T::Preimages as PreimageRecipient<T::Hash>>::MaxSize::get());203 let now = BLOCK_NUMBER.into();204 let task = make_task::<T>(false, false, false, Some(s), 0);205 // prevent any tasks from actually being executed as we only want the surrounding weight.206 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() };207 }: {208 let result = Scheduler::<T>::service_task(&mut counter, now, now, 0, true, task);209 } verify {210 }211212 // `service_task` when the task is a non-periodic, named, non-fetched call which is not213 // dispatched (e.g. due to being overweight).214 service_task_named {215 let now = BLOCK_NUMBER.into();216 let task = make_task::<T>(false, true, false, None, 0);217 // prevent any tasks from actually being executed as we only want the surrounding weight.218 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() };219 }: {220 let result = Scheduler::<T>::service_task(&mut counter, now, now, 0, true, task);221 } verify {222 }223224 // `service_task` when the task is a periodic, non-named, non-fetched call which is not225 // dispatched (e.g. due to being overweight).226 service_task_periodic {227 let now = BLOCK_NUMBER.into();228 let task = make_task::<T>(true, false, false, None, 0);229 // prevent any tasks from actually being executed as we only want the surrounding weight.230 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::zero() };231 }: {232 let result = Scheduler::<T>::service_task(&mut counter, now, now, 0, true, task);233 } verify {234 }235236 // `execute_dispatch` when the origin is `Signed`, not counting the dispatable's weight.237 execute_dispatch_signed {238 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::MAX };239 let origin = make_origin::<T>(true);240 let call = T::Preimages::realize(&make_call::<T>(None)).unwrap().0;241 }: {242 assert!(Scheduler::<T>::execute_dispatch(&mut counter, origin, call).is_ok());243 }244 verify {245 }246247 // `execute_dispatch` when the origin is not `Signed`, not counting the dispatable's weight.248 execute_dispatch_unsigned {249 let mut counter = WeightCounter { used: Weight::zero(), limit: Weight::MAX };250 let origin = make_origin::<T>(false);251 let call = T::Preimages::realize(&make_call::<T>(None)).unwrap().0;252 }: {253 assert!(Scheduler::<T>::execute_dispatch(&mut counter, origin, call).is_ok());254 }255 verify {256 }257258 schedule {259 let s in 0 .. (T::MaxScheduledPerBlock::get() - 1);260 let when = BLOCK_NUMBER.into();261 let periodic = Some((T::BlockNumber::one(), 100));262 let priority = 0;263 // Essentially a no-op call.264 let call = Box::new(SystemCall::set_storage { items: vec![] }.into());265266 fill_schedule::<T>(when, s)?;267 }: _(RawOrigin::Root, when, periodic, priority, call)268 verify {269 ensure!(270 Agenda::<T>::get(when).len() == (s + 1) as usize,271 "didn't add to schedule"272 );273 }274275 cancel {276 let s in 1 .. T::MaxScheduledPerBlock::get();277 let when = BLOCK_NUMBER.into();278279 fill_schedule::<T>(when, s)?;280 assert_eq!(Agenda::<T>::get(when).len(), s as usize);281 let schedule_origin = T::ScheduleOrigin::successful_origin();282 }: _<SystemOrigin<T>>(schedule_origin, when, 0)283 verify {284 ensure!(285 Lookup::<T>::get(u32_to_name(0)).is_none(),286 "didn't remove from lookup"287 );288 // Removed schedule is NONE289 ensure!(290 Agenda::<T>::get(when)[0].is_none(),291 "didn't remove from schedule"292 );293 }294295 schedule_named {296 let s in 0 .. (T::MaxScheduledPerBlock::get() - 1);297 let id = u32_to_name(s);298 let when = BLOCK_NUMBER.into();299 let periodic = Some((T::BlockNumber::one(), 100));300 let priority = 0;301 // Essentially a no-op call.302 let call = Box::new(SystemCall::set_storage { items: vec![] }.into());303304 fill_schedule::<T>(when, s)?;305 }: _(RawOrigin::Root, id, when, periodic, priority, call)306 verify {307 ensure!(308 Agenda::<T>::get(when).len() == (s + 1) as usize,309 "didn't add to schedule"310 );311 }312313 cancel_named {314 let s in 1 .. T::MaxScheduledPerBlock::get();315 let when = BLOCK_NUMBER.into();316317 fill_schedule::<T>(when, s)?;318 }: _(RawOrigin::Root, u32_to_name(0))319 verify {320 ensure!(321 Lookup::<T>::get(u32_to_name(0)).is_none(),322 "didn't remove from lookup"323 );324 // Removed schedule is NONE325 ensure!(326 Agenda::<T>::get(when)[0].is_none(),327 "didn't remove from schedule"328 );329 }330331 // impl_benchmark_test_suite!(Scheduler, crate::mock::new_test_ext(), crate::mock::Test);332}