Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Scheduler to Support Relay Chain Block Number Provider #6362

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -604,11 +604,13 @@ parameter_types! {
#[cfg(not(feature = "runtime-benchmarks"))]
parameter_types! {
pub const MaxScheduledPerBlock: u32 = 50;
pub const MaxScheduledBlocks: u32 = 50;
}

#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub const MaxScheduledPerBlock: u32 = 200;
pub const MaxScheduledBlocks: u32 = 200;
}

impl pallet_scheduler::Config for Runtime {
Expand All @@ -622,6 +624,8 @@ impl pallet_scheduler::Config for Runtime {
type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
type OriginPrivilegeCmp = EqualOrGreatestRootCmp;
type Preimages = Preimage;
type BlockNumberProvider = frame_system::Pallet<Runtime>;
type MaxScheduledBlocks = MaxScheduledBlocks;
}

parameter_types! {
Expand Down
3 changes: 3 additions & 0 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
BlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
pub const MaxScheduledBlocks: u32 = 50;
pub const NoPreimagePostponement: Option<u32> = Some(10);
}

Expand Down Expand Up @@ -331,6 +332,8 @@ impl pallet_scheduler::Config for Runtime {
type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
type OriginPrivilegeCmp = OriginPrivilegeCmp;
type Preimages = Preimage;
type BlockNumberProvider = frame_system::Pallet<Runtime>;
type MaxScheduledBlocks = MaxScheduledBlocks;
}

parameter_types! {
Expand Down
3 changes: 3 additions & 0 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ parameter_types! {
pub MaximumSchedulerWeight: frame_support::weights::Weight = Perbill::from_percent(80) *
BlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
pub const MaxScheduledBlocks: u32 = 50;
pub const NoPreimagePostponement: Option<u32> = Some(10);
}

Expand All @@ -247,6 +248,8 @@ impl pallet_scheduler::Config for Runtime {
type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
type OriginPrivilegeCmp = frame_support::traits::EqualPrivilegeOnly;
type Preimages = Preimage;
type BlockNumberProvider = frame_system::Pallet<Runtime>;
type MaxScheduledBlocks = MaxScheduledBlocks;
}

parameter_types! {
Expand Down
5 changes: 5 additions & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ impl pallet_scheduler::Config for Runtime {
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type Preimages = Preimage;
type BlockNumberProvider = frame_system::Pallet<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type MaxScheduledBlocks = ConstU32<512>;
#[cfg(not(feature = "runtime-benchmarks"))]
type MaxScheduledBlocks = ConstU32<50>;
}

impl pallet_glutton::Config for Runtime {
Expand Down
2 changes: 2 additions & 0 deletions substrate/frame/democracy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ impl pallet_scheduler::Config for Test {
type WeightInfo = ();
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type Preimages = ();
type BlockNumberProvider = frame_system::Pallet<Test>;
type MaxScheduledBlocks = ConstU32<100>;
}

#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
Expand Down
2 changes: 2 additions & 0 deletions substrate/frame/referenda/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ impl pallet_scheduler::Config for Test {
type WeightInfo = ();
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type Preimages = Preimage;
type BlockNumberProvider = frame_system::Pallet<Test>;
type MaxScheduledBlocks = ConstU32<100>;
}
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
impl pallet_balances::Config for Test {
Expand Down
74 changes: 54 additions & 20 deletions substrate/frame/scheduler/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ use alloc::vec;
use frame_benchmarking::v1::{account, benchmarks, BenchmarkError};
use frame_support::{
ensure,
testing_prelude::*,
traits::{schedule::Priority, BoundedInline},
weights::WeightMeter,
};
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use frame_system::RawOrigin;

use crate::Pallet as Scheduler;
use frame_system::{Call as SystemCall, EventRecord};

const SEED: u32 = 0;

const BLOCK_NUMBER: u32 = 2;
fn block_number<T: Config>() -> u32 {
T::MaxScheduledBlocks::get()
}

type SystemOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;

Expand All @@ -44,6 +47,15 @@ fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
assert_eq!(event, &system_event);
}

fn fill_queue<T: Config>(n: u32) {
let mut vec = Vec::<BlockNumberFor<T>>::new();
for i in 0..n {
vec.push(i.into());
}
let bounded_vec = BoundedVec::try_from(vec).unwrap();
Queue::<T>::put::<BoundedVec<_, _>>(bounded_vec);
}

/// Add `n` items to the schedule.
///
/// For `resolved`:
Expand All @@ -52,7 +64,7 @@ fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
/// - `Some(true)`: hash resolves into call if possible, plain call otherwise
/// - `Some(false)`: plain call
fn fill_schedule<T: Config>(
when: frame_system::pallet_prelude::BlockNumberFor<T>,
when: BlockNumberFor<T>,
n: u32,
) -> Result<(), &'static str> {
let t = DispatchTime::At(when);
Expand Down Expand Up @@ -137,17 +149,19 @@ fn make_origin<T: Config>(signed: bool) -> <T as Config>::PalletsOrigin {
benchmarks! {
// `service_agendas` when no work is done.
service_agendas_base {
let now = BlockNumberFor::<T>::from(BLOCK_NUMBER);
IncompleteSince::<T>::put(now - One::one());
let now = BlockNumberFor::<T>::from(block_number::<T>());
Queue::<T>::put::<BoundedVec<_, _>>(bounded_vec![now + One::one()]);
}: {
Scheduler::<T>::service_agendas(&mut WeightMeter::new(), now, 0);
} verify {
assert_eq!(IncompleteSince::<T>::get(), Some(now - One::one()));
let expected: BoundedVec<BlockNumberFor<T>, T::MaxScheduledBlocks> =
bounded_vec![now + One::one()];
assert_eq!(Queue::<T>::get(), expected);
}

// `service_agenda` when no work is done.
service_agenda_base {
let now = BLOCK_NUMBER.into();
let now = block_number::<T>().into();
let s in 0 .. T::MaxScheduledPerBlock::get();
fill_schedule::<T>(now, s)?;
let mut executed = 0;
Expand All @@ -160,7 +174,7 @@ benchmarks! {
// `service_task` when the task is a non-periodic, non-named, non-fetched call which is not
// dispatched (e.g. due to being overweight).
service_task_base {
let now = BLOCK_NUMBER.into();
let now = block_number::<T>().into();
let task = make_task::<T>(false, false, false, None, 0);
// prevent any tasks from actually being executed as we only want the surrounding weight.
let mut counter = WeightMeter::with_limit(Weight::zero());
Expand All @@ -178,7 +192,7 @@ benchmarks! {
}]
service_task_fetched {
let s in (BoundedInline::bound() as u32) .. (T::Preimages::MAX_LENGTH as u32);
let now = BLOCK_NUMBER.into();
let now = block_number::<T>().into();
let task = make_task::<T>(false, false, false, Some(s), 0);
// prevent any tasks from actually being executed as we only want the surrounding weight.
let mut counter = WeightMeter::with_limit(Weight::zero());
Expand All @@ -190,7 +204,7 @@ benchmarks! {
// `service_task` when the task is a non-periodic, named, non-fetched call which is not
// dispatched (e.g. due to being overweight).
service_task_named {
let now = BLOCK_NUMBER.into();
let now = block_number::<T>().into();
let task = make_task::<T>(false, true, false, None, 0);
// prevent any tasks from actually being executed as we only want the surrounding weight.
let mut counter = WeightMeter::with_limit(Weight::zero());
Expand All @@ -202,7 +216,7 @@ benchmarks! {
// `service_task` when the task is a periodic, non-named, non-fetched call which is not
// dispatched (e.g. due to being overweight).
service_task_periodic {
let now = BLOCK_NUMBER.into();
let now = block_number::<T>().into();
let task = make_task::<T>(true, false, false, None, 0);
// prevent any tasks from actually being executed as we only want the surrounding weight.
let mut counter = WeightMeter::with_limit(Weight::zero());
Expand Down Expand Up @@ -235,26 +249,32 @@ benchmarks! {

schedule {
let s in 0 .. (T::MaxScheduledPerBlock::get() - 1);
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();
let periodic = Some((BlockNumberFor::<T>::one(), 100));
let priority = 0;
// Essentially a no-op call.
let call = Box::new(SystemCall::set_storage { items: vec![] }.into());

fill_schedule::<T>(when, s)?;
fill_queue::<T>(T::MaxScheduledBlocks::get() - 1);
}: _(RawOrigin::Root, when, periodic, priority, call)
verify {
ensure!(
Agenda::<T>::get(when).len() == (s + 1) as usize,
"didn't add to schedule"
);
ensure!(
Queue::<T>::get().len() == T::MaxScheduledBlocks::get() as usize,
"didn't add to queue"
);
}

cancel {
let s in 1 .. T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = (block_number::<T>() - 1).into();

fill_schedule::<T>(when, s)?;
fill_queue::<T>(T::MaxScheduledBlocks::get());
assert_eq!(Agenda::<T>::get(when).len(), s as usize);
let schedule_origin =
T::ScheduleOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
Expand All @@ -273,31 +293,41 @@ benchmarks! {
s > 1 || Agenda::<T>::get(when).len() == 0,
"remove from schedule if only 1 task scheduled for `when`"
);
ensure!(
s > 1 || Queue::<T>::get().len() == T::MaxScheduledBlocks::get() as usize - 1,
"didn't remove from queue"
);
}

schedule_named {
let s in 0 .. (T::MaxScheduledPerBlock::get() - 1);
let id = u32_to_name(s);
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();
let periodic = Some((BlockNumberFor::<T>::one(), 100));
let priority = 0;
// Essentially a no-op call.
let call = Box::new(SystemCall::set_storage { items: vec![] }.into());

fill_schedule::<T>(when, s)?;
fill_queue::<T>(T::MaxScheduledBlocks::get() - 1);
}: _(RawOrigin::Root, id, when, periodic, priority, call)
verify {
ensure!(
Agenda::<T>::get(when).len() == (s + 1) as usize,
"didn't add to schedule"
);
ensure!(
Queue::<T>::get().len() == T::MaxScheduledBlocks::get() as usize,
"didn't add to queue"
);
}

cancel_named {
let s in 1 .. T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = (block_number::<T>() - 1).into();

fill_schedule::<T>(when, s)?;
fill_queue::<T>(T::MaxScheduledBlocks::get());
}: _(RawOrigin::Root, u32_to_name(0))
verify {
ensure!(
Expand All @@ -313,11 +343,15 @@ benchmarks! {
s > 1 || Agenda::<T>::get(when).len() == 0,
"remove from schedule if only 1 task scheduled for `when`"
);
ensure!(
s > 1 || Queue::<T>::get().len() == T::MaxScheduledBlocks::get() as usize - 1,
"didn't remove from queue"
);
}

schedule_retry {
let s in 1 .. T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();

fill_schedule::<T>(when, s)?;
let name = u32_to_name(s - 1);
Expand All @@ -341,7 +375,7 @@ benchmarks! {

set_retry {
let s = T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();

fill_schedule::<T>(when, s)?;
let name = u32_to_name(s - 1);
Expand All @@ -361,7 +395,7 @@ benchmarks! {

set_retry_named {
let s = T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();

fill_schedule::<T>(when, s)?;
let name = u32_to_name(s - 1);
Expand All @@ -381,7 +415,7 @@ benchmarks! {

cancel_retry {
let s = T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();

fill_schedule::<T>(when, s)?;
let name = u32_to_name(s - 1);
Expand All @@ -399,7 +433,7 @@ benchmarks! {

cancel_retry_named {
let s = T::MaxScheduledPerBlock::get();
let when = BLOCK_NUMBER.into();
let when = block_number::<T>().into();

fill_schedule::<T>(when, s)?;
let name = u32_to_name(s - 1);
Expand Down
Loading
Loading