diff --git a/frame/scheduler/src/benchmarking.rs b/frame/scheduler/src/benchmarking.rs index 563a1ba89c86f..47375658fb9bc 100644 --- a/frame/scheduler/src/benchmarking.rs +++ b/frame/scheduler/src/benchmarking.rs @@ -25,7 +25,7 @@ use frame_system::RawOrigin; use frame_support::{ensure, traits::OnInitialize}; use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; -use crate::Module as Scheduler; +use crate::Pallet as Scheduler; use frame_system::Pallet as System; const BLOCK_NUMBER: u32 = 2; diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 5332aedf7f136..006ab5a0f2d75 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -16,15 +16,15 @@ // limitations under the License. //! # Scheduler -//! A module for scheduling dispatches. +//! A Pallet for scheduling dispatches. //! //! - [`Config`] //! - [`Call`] -//! - [`Module`] +//! - [`Pallet`] //! //! ## Overview //! -//! This module exposes capabilities for scheduling dispatches to occur at a +//! This Pallet exposes capabilities for scheduling dispatches to occur at a //! specified block number or at a specified period. These scheduled dispatches //! may be named or anonymous and may be canceled. //! @@ -58,47 +58,13 @@ use sp_std::{prelude::*, marker::PhantomData, borrow::Borrow}; use codec::{Encode, Decode, Codec}; use sp_runtime::{RuntimeDebug, traits::{Zero, One, BadOrigin, Saturating}}; use frame_support::{ - decl_module, decl_storage, decl_event, decl_error, IterableStorageMap, dispatch::{Dispatchable, DispatchError, DispatchResult, Parameter}, traits::{Get, schedule::{self, DispatchTime}, OriginTrait, EnsureOrigin, IsType}, weights::{GetDispatchInfo, Weight}, }; use frame_system::{self as system, ensure_signed}; pub use weights::WeightInfo; - -/// Our pallet's configuration trait. All our types and constants go in here. If the -/// pallet is dependent on specific other pallets, then their configuration traits -/// should be added to our implied traits list. -/// -/// `system::Config` should always be included in our implied traits. -pub trait Config: system::Config { - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// The aggregated origin which the dispatch will take. - type Origin: OriginTrait - + From + IsType<::Origin>; - - /// The caller origin, overarching type of all pallets origins. - type PalletsOrigin: From> + Codec + Clone + Eq; - - /// The aggregated call type. - type Call: Parameter + Dispatchable::Origin> + GetDispatchInfo + From>; - - /// The maximum weight that may be scheduled per block for any dispatchables of less priority - /// than `schedule::HARD_DEADLINE`. - type MaximumWeight: Get; - - /// Required origin to schedule or cancel calls. - type ScheduleOrigin: EnsureOrigin<::Origin>; - - /// The maximum number of scheduled calls in the queue for a single block. - /// Not strictly enforced, but used for weight estimation. - type MaxScheduledPerBlock: Get; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} +pub use pallet::*; /// Just a simple index for naming period tasks. pub type PeriodicIndex = u32; @@ -132,7 +98,8 @@ pub struct ScheduledV2 { } /// The current version of Scheduled struct. -pub type Scheduled = ScheduledV2; +pub type Scheduled = + ScheduledV2; // A value placed in storage that represents the current version of the Scheduler storage. // This value is used by the `on_runtime_upgrade` logic to determine whether we run @@ -149,35 +116,87 @@ impl Default for Releases { } } -decl_storage! { - trait Store for Module as Scheduler { - /// Items to be executed, indexed by the block number that they should be executed on. - pub Agenda: map hasher(twox_64_concat) T::BlockNumber - => Vec::Call, T::BlockNumber, T::PalletsOrigin, T::AccountId>>>; - - /// Lookup from identity to the block number and index of the task. - Lookup: map hasher(twox_64_concat) Vec => Option>; - - /// Storage version of the pallet. - /// - /// New networks start with last version. - StorageVersion build(|_| Releases::V2): Releases; +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// `system::Config` should always be included in our implied traits. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// The aggregated origin which the dispatch will take. + type Origin: OriginTrait + + From + + IsType<::Origin>; + + /// The caller origin, overarching type of all pallets origins. + type PalletsOrigin: From> + Codec + Clone + Eq; + + /// The aggregated call type. + type Call: Parameter + + Dispatchable::Origin> + + GetDispatchInfo + + From>; + + /// The maximum weight that may be scheduled per block for any dispatchables of less priority + /// than `schedule::HARD_DEADLINE`. + type MaximumWeight: Get; + + /// Required origin to schedule or cancel calls. + type ScheduleOrigin: EnsureOrigin<::Origin>; + + /// The maximum number of scheduled calls in the queue for a single block. + /// Not strictly enforced, but used for weight estimation. + type MaxScheduledPerBlock: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } -} -decl_event!( - pub enum Event where ::BlockNumber { + /// Items to be executed, indexed by the block number that they should be executed on. + #[pallet::storage] + pub type Agenda = StorageMap< + _, + Twox64Concat, + T::BlockNumber, + Vec::Call, T::BlockNumber, T::PalletsOrigin, T::AccountId>>>, + ValueQuery, + >; + + /// Lookup from identity to the block number and index of the task. + #[pallet::storage] + pub(crate) type Lookup = + StorageMap<_, Twox64Concat, Vec, TaskAddress>; + + /// Storage version of the pallet. + /// + /// New networks start with last version. + #[pallet::storage] + pub(crate) type StorageVersion = StorageValue<_, Releases, ValueQuery>; + + /// Events type. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::BlockNumber = "BlockNumber", TaskAddress = "TaskAddress")] + pub enum Event { /// Scheduled some task. \[when, index\] - Scheduled(BlockNumber, u32), + Scheduled(T::BlockNumber, u32), /// Canceled some task. \[when, index\] - Canceled(BlockNumber, u32), + Canceled(T::BlockNumber, u32), /// Dispatched some task. \[task, id, result\] - Dispatched(TaskAddress, Option>, DispatchResult), + Dispatched(TaskAddress, Option>, DispatchResult), } -); -decl_error! { - pub enum Error for Module { + #[pallet::error] + pub enum Error { /// Failed to schedule a call FailedToSchedule, /// Cannot find the scheduled call. @@ -187,14 +206,135 @@ decl_error! { /// Reschedule failed because it does not change scheduled time. RescheduleNoChange, } -} -decl_module! { - /// Scheduler module declaration. - pub struct Module for enum Call where origin: ::Origin { - type Error = Error; - fn deposit_event() = default; + #[pallet::genesis_config] + pub struct GenesisConfig; + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self + } + } + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + StorageVersion::::put(Releases::V2); + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { + /// Execute the scheduled calls + /// + /// # + /// - S = Number of already scheduled calls + /// - N = Named scheduled calls + /// - P = Periodic Calls + /// - Base Weight: 9.243 + 23.45 * S µs + /// - DB Weight: + /// - Read: Agenda + Lookup * N + Agenda(Future) * P + /// - Write: Agenda + Lookup * N + Agenda(future) * P + /// # + fn on_initialize(now: T::BlockNumber) -> Weight { + let limit = T::MaximumWeight::get(); + let mut queued = Agenda::::take(now) + .into_iter() + .enumerate() + .filter_map(|(index, s)| s.map(|inner| (index as u32, inner))) + .collect::>(); + if queued.len() as u32 > T::MaxScheduledPerBlock::get() { + log::warn!( + target: "runtime::scheduler", + "Warning: This block has more items queued in Scheduler than \ + expected from the runtime configuration. An update might be needed." + ); + } + queued.sort_by_key(|(_, s)| s.priority); + let base_weight: Weight = T::DbWeight::get().reads_writes(1, 2); // Agenda + Agenda(next) + let mut total_weight: Weight = 0; + queued + .into_iter() + .enumerate() + .scan(base_weight, |cumulative_weight, (order, (index, s))| { + *cumulative_weight = + cumulative_weight.saturating_add(s.call.get_dispatch_info().weight); + + let origin = + <::Origin as From>::from(s.origin.clone()) + .into(); + + if ensure_signed(origin).is_ok() { + // AccountData for inner call origin accountdata. + *cumulative_weight = + cumulative_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + } + + if s.maybe_id.is_some() { + // Remove/Modify Lookup + *cumulative_weight = + cumulative_weight.saturating_add(T::DbWeight::get().writes(1)); + } + if s.maybe_periodic.is_some() { + // Read/Write Agenda for future block + *cumulative_weight = + cumulative_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + } + + Some((order, index, *cumulative_weight, s)) + }) + .filter_map(|(order, index, cumulative_weight, mut s)| { + // We allow a scheduled call if any is true: + // - It's priority is `HARD_DEADLINE` + // - It does not push the weight past the limit. + // - It is the first item in the schedule + if s.priority <= schedule::HARD_DEADLINE + || cumulative_weight <= limit + || order == 0 + { + let r = s.call.clone().dispatch(s.origin.clone().into()); + let maybe_id = s.maybe_id.clone(); + if let &Some((period, count)) = &s.maybe_periodic { + if count > 1 { + s.maybe_periodic = Some((period, count - 1)); + } else { + s.maybe_periodic = None; + } + let next = now + period; + // If scheduled is named, place it's information in `Lookup` + if let Some(ref id) = s.maybe_id { + let next_index = Agenda::::decode_len(now + period).unwrap_or(0); + Lookup::::insert(id, (next, next_index as u32)); + } + Agenda::::append(next, Some(s)); + } else { + if let Some(ref id) = s.maybe_id { + Lookup::::remove(id); + } + } + Self::deposit_event(Event::Dispatched( + (now, index), + maybe_id, + r.map(|_| ()).map_err(|e| e.error), + )); + total_weight = cumulative_weight; + None + } else { + Some(Some(s)) + } + }) + .for_each(|unused| { + let next = now + One::one(); + Agenda::::append(next, unused); + }); + + total_weight + } + } + + #[pallet::call] + impl Pallet { /// Anonymously schedule a task. /// /// # @@ -205,16 +345,24 @@ decl_module! { /// - Write: Agenda /// - Will use base weight of 25 which should be good for up to 30 scheduled calls /// # - #[weight = T::WeightInfo::schedule(T::MaxScheduledPerBlock::get())] - fn schedule(origin, + #[pallet::weight(::WeightInfo::schedule(T::MaxScheduledPerBlock::get()))] + pub(crate) fn schedule( + origin: OriginFor, when: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, call: Box<::Call>, - ) { + ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); - Self::do_schedule(DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call)?; + Self::do_schedule( + DispatchTime::At(when), + maybe_periodic, + priority, + origin.caller().clone(), + *call, + )?; + Ok(()) } /// Cancel an anonymously scheduled task. @@ -227,11 +375,12 @@ decl_module! { /// - Write: Agenda, Lookup /// - Will use base weight of 100 which should be good for up to 30 scheduled calls /// # - #[weight = T::WeightInfo::cancel(T::MaxScheduledPerBlock::get())] - fn cancel(origin, when: T::BlockNumber, index: u32) { + #[pallet::weight(::WeightInfo::cancel(T::MaxScheduledPerBlock::get()))] + pub(crate) fn cancel(origin: OriginFor, when: T::BlockNumber, index: u32) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); Self::do_cancel(Some(origin.caller().clone()), (when, index))?; + Ok(()) } /// Schedule a named task. @@ -244,19 +393,26 @@ decl_module! { /// - Write: Agenda, Lookup /// - Will use base weight of 35 which should be good for more than 30 scheduled calls /// # - #[weight = T::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())] - fn schedule_named(origin, + #[pallet::weight(::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))] + pub(crate) fn schedule_named( + origin: OriginFor, id: Vec, when: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, call: Box<::Call>, - ) { + ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); Self::do_schedule_named( - id, DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call + id, + DispatchTime::At(when), + maybe_periodic, + priority, + origin.caller().clone(), + *call, )?; + Ok(()) } /// Cancel a named scheduled task. @@ -269,11 +425,12 @@ decl_module! { /// - Write: Agenda, Lookup /// - Will use base weight of 100 which should be good for up to 30 scheduled calls /// # - #[weight = T::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get())] - fn cancel_named(origin, id: Vec) { + #[pallet::weight(::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get()))] + pub(crate) fn cancel_named(origin: OriginFor, id: Vec) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); Self::do_cancel_named(Some(origin.caller().clone()), id)?; + Ok(()) } /// Anonymously schedule a task after a delay. @@ -281,18 +438,24 @@ decl_module! { /// # /// Same as [`schedule`]. /// # - #[weight = T::WeightInfo::schedule(T::MaxScheduledPerBlock::get())] - fn schedule_after(origin, + #[pallet::weight(::WeightInfo::schedule(T::MaxScheduledPerBlock::get()))] + pub(crate) fn schedule_after( + origin: OriginFor, after: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, call: Box<::Call>, - ) { + ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); Self::do_schedule( - DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call + DispatchTime::After(after), + maybe_periodic, + priority, + origin.caller().clone(), + *call, )?; + Ok(()) } /// Schedule a named task after a delay. @@ -300,128 +463,36 @@ decl_module! { /// # /// Same as [`schedule_named`]. /// # - #[weight = T::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())] - fn schedule_named_after(origin, + #[pallet::weight(::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))] + pub(crate) fn schedule_named_after( + origin: OriginFor, id: Vec, after: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, call: Box<::Call>, - ) { + ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; let origin = ::Origin::from(origin); Self::do_schedule_named( - id, DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call + id, + DispatchTime::After(after), + maybe_periodic, + priority, + origin.caller().clone(), + *call, )?; - } - - /// Execute the scheduled calls - /// - /// # - /// - S = Number of already scheduled calls - /// - N = Named scheduled calls - /// - P = Periodic Calls - /// - Base Weight: 9.243 + 23.45 * S µs - /// - DB Weight: - /// - Read: Agenda + Lookup * N + Agenda(Future) * P - /// - Write: Agenda + Lookup * N + Agenda(future) * P - /// # - fn on_initialize(now: T::BlockNumber) -> Weight { - let limit = T::MaximumWeight::get(); - let mut queued = Agenda::::take(now).into_iter() - .enumerate() - .filter_map(|(index, s)| s.map(|inner| (index as u32, inner))) - .collect::>(); - if queued.len() as u32 > T::MaxScheduledPerBlock::get() { - log::warn!( - target: "runtime::scheduler", - "Warning: This block has more items queued in Scheduler than \ - expected from the runtime configuration. An update might be needed." - ); - } - queued.sort_by_key(|(_, s)| s.priority); - let base_weight: Weight = T::DbWeight::get().reads_writes(1, 2); // Agenda + Agenda(next) - let mut total_weight: Weight = 0; - queued.into_iter() - .enumerate() - .scan(base_weight, |cumulative_weight, (order, (index, s))| { - *cumulative_weight = cumulative_weight - .saturating_add(s.call.get_dispatch_info().weight); - - let origin = <::Origin as From>::from( - s.origin.clone() - ).into(); - - if ensure_signed(origin).is_ok() { - // AccountData for inner call origin accountdata. - *cumulative_weight = cumulative_weight - .saturating_add(T::DbWeight::get().reads_writes(1, 1)); - } - - if s.maybe_id.is_some() { - // Remove/Modify Lookup - *cumulative_weight = cumulative_weight.saturating_add(T::DbWeight::get().writes(1)); - } - if s.maybe_periodic.is_some() { - // Read/Write Agenda for future block - *cumulative_weight = cumulative_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - } - - Some((order, index, *cumulative_weight, s)) - }) - .filter_map(|(order, index, cumulative_weight, mut s)| { - // We allow a scheduled call if any is true: - // - It's priority is `HARD_DEADLINE` - // - It does not push the weight past the limit. - // - It is the first item in the schedule - if s.priority <= schedule::HARD_DEADLINE || cumulative_weight <= limit || order == 0 { - let r = s.call.clone().dispatch(s.origin.clone().into()); - let maybe_id = s.maybe_id.clone(); - if let &Some((period, count)) = &s.maybe_periodic { - if count > 1 { - s.maybe_periodic = Some((period, count - 1)); - } else { - s.maybe_periodic = None; - } - let next = now + period; - // If scheduled is named, place it's information in `Lookup` - if let Some(ref id) = s.maybe_id { - let next_index = Agenda::::decode_len(now + period).unwrap_or(0); - Lookup::::insert(id, (next, next_index as u32)); - } - Agenda::::append(next, Some(s)); - } else { - if let Some(ref id) = s.maybe_id { - Lookup::::remove(id); - } - } - Self::deposit_event(RawEvent::Dispatched( - (now, index), - maybe_id, - r.map(|_| ()).map_err(|e| e.error) - )); - total_weight = cumulative_weight; - None - } else { - Some(Some(s)) - } - }) - .for_each(|unused| { - let next = now + One::one(); - Agenda::::append(next, unused); - }); - - total_weight + Ok(()) } } } -impl Module { +impl Pallet { /// Migrate storage format from V1 to V2. /// Return true if migration is performed. pub fn migrate_v1_to_t2() -> bool { - if StorageVersion::get() == Releases::V1 { - StorageVersion::put(Releases::V2); + if StorageVersion::::get() == Releases::V1 { + StorageVersion::::put(Releases::V2); Agenda::::translate::< Vec::Call, T::BlockNumber>>>, _ @@ -471,11 +542,11 @@ impl Module { DispatchTime::At(x) => x, // The current block has already completed it's scheduled tasks, so // Schedule the task at lest one block after this current block. - DispatchTime::After(x) => now.saturating_add(x).saturating_add(One::one()) + DispatchTime::After(x) => now.saturating_add(x).saturating_add(One::one()), }; if when <= now { - return Err(Error::::TargetBlockNumberInPast.into()) + return Err(Error::::TargetBlockNumberInPast.into()); } Ok(when) @@ -486,7 +557,7 @@ impl Module { maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call + call: ::Call, ) -> Result, DispatchError> { let when = Self::resolve_time(when)?; @@ -496,7 +567,12 @@ impl Module { // Remove one from the number of repetitions since we will schedule one now. .map(|(p, c)| (p, c - 1)); let s = Some(Scheduled { - maybe_id: None, priority, call, maybe_periodic, origin, _phantom: PhantomData::::default(), + maybe_id: None, + priority, + call, + maybe_periodic, + origin, + _phantom: PhantomData::::default(), }); Agenda::::append(when, s); let index = Agenda::::decode_len(when).unwrap_or(1) as u32 - 1; @@ -507,34 +583,33 @@ impl Module { expected from the runtime configuration. An update might be needed.", ); } - Self::deposit_event(RawEvent::Scheduled(when, index)); + Self::deposit_event(Event::Scheduled(when, index)); Ok((when, index)) } fn do_cancel( origin: Option, - (when, index): TaskAddress + (when, index): TaskAddress, ) -> Result<(), DispatchError> { - let scheduled = Agenda::::try_mutate( - when, - |agenda| { - agenda.get_mut(index as usize) - .map_or(Ok(None), |s| -> Result>, DispatchError> { - if let (Some(ref o), Some(ref s)) = (origin, s.borrow()) { - if *o != s.origin { - return Err(BadOrigin.into()); - } - }; - Ok(s.take()) - }) - }, - )?; + let scheduled = Agenda::::try_mutate(when, |agenda| { + agenda.get_mut(index as usize).map_or( + Ok(None), + |s| -> Result>, DispatchError> { + if let (Some(ref o), Some(ref s)) = (origin, s.borrow()) { + if *o != s.origin { + return Err(BadOrigin.into()); + } + }; + Ok(s.take()) + }, + ) + })?; if let Some(s) = scheduled { if let Some(id) = s.maybe_id { Lookup::::remove(id); } - Self::deposit_event(RawEvent::Canceled(when, index)); + Self::deposit_event(Event::Canceled(when, index)); Ok(()) } else { Err(Error::::NotFound)? @@ -559,8 +634,8 @@ impl Module { })?; let new_index = Agenda::::decode_len(new_time).unwrap_or(1) as u32 - 1; - Self::deposit_event(RawEvent::Canceled(when, index)); - Self::deposit_event(RawEvent::Scheduled(new_time, new_index)); + Self::deposit_event(Event::Canceled(when, index)); + Self::deposit_event(Event::Scheduled(new_time, new_index)); Ok((new_time, new_index)) } @@ -575,7 +650,7 @@ impl Module { ) -> Result, DispatchError> { // ensure id it is unique if Lookup::::contains_key(&id) { - return Err(Error::::FailedToSchedule)? + return Err(Error::::FailedToSchedule)?; } let when = Self::resolve_time(when)?; @@ -587,7 +662,12 @@ impl Module { .map(|(p, c)| (p, c - 1)); let s = Scheduled { - maybe_id: Some(id.clone()), priority, call, maybe_periodic, origin, _phantom: Default::default() + maybe_id: Some(id.clone()), + priority, + call, + maybe_periodic, + origin, + _phantom: Default::default(), }; Agenda::::append(when, Some(s)); let index = Agenda::::decode_len(when).unwrap_or(1) as u32 - 1; @@ -600,7 +680,7 @@ impl Module { } let address = (when, index); Lookup::::insert(&id, &address); - Self::deposit_event(RawEvent::Scheduled(when, index)); + Self::deposit_event(Event::Scheduled(when, index)); Ok(address) } @@ -620,7 +700,7 @@ impl Module { } Ok(()) })?; - Self::deposit_event(RawEvent::Canceled(when, index)); + Self::deposit_event(Event::Canceled(when, index)); Ok(()) } else { Err(Error::::NotFound)? @@ -634,33 +714,38 @@ impl Module { ) -> Result, DispatchError> { let new_time = Self::resolve_time(new_time)?; - Lookup::::try_mutate_exists(id, |lookup| -> Result, DispatchError> { - let (when, index) = lookup.ok_or(Error::::NotFound)?; + Lookup::::try_mutate_exists( + id, + |lookup| -> Result, DispatchError> { + let (when, index) = lookup.ok_or(Error::::NotFound)?; - if new_time == when { - return Err(Error::::RescheduleNoChange.into()); - } + if new_time == when { + return Err(Error::::RescheduleNoChange.into()); + } - Agenda::::try_mutate(when, |agenda| -> DispatchResult { - let task = agenda.get_mut(index as usize).ok_or(Error::::NotFound)?; - let task = task.take().ok_or(Error::::NotFound)?; - Agenda::::append(new_time, Some(task)); + Agenda::::try_mutate(when, |agenda| -> DispatchResult { + let task = agenda.get_mut(index as usize).ok_or(Error::::NotFound)?; + let task = task.take().ok_or(Error::::NotFound)?; + Agenda::::append(new_time, Some(task)); - Ok(()) - })?; + Ok(()) + })?; - let new_index = Agenda::::decode_len(new_time).unwrap_or(1) as u32 - 1; - Self::deposit_event(RawEvent::Canceled(when, index)); - Self::deposit_event(RawEvent::Scheduled(new_time, new_index)); + let new_index = Agenda::::decode_len(new_time).unwrap_or(1) as u32 - 1; + Self::deposit_event(Event::Canceled(when, index)); + Self::deposit_event(Event::Scheduled(new_time, new_index)); - *lookup = Some((new_time, new_index)); + *lookup = Some((new_time, new_index)); - Ok((new_time, new_index)) - }) + Ok((new_time, new_index)) + }, + ) } } -impl schedule::Anon::Call, T::PalletsOrigin> for Module { +impl schedule::Anon::Call, T::PalletsOrigin> + for Pallet +{ type Address = TaskAddress; fn schedule( @@ -668,7 +753,7 @@ impl schedule::Anon::Call, T::PalletsOr maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call + call: ::Call, ) -> Result { Self::do_schedule(when, maybe_periodic, priority, origin, call) } @@ -685,11 +770,16 @@ impl schedule::Anon::Call, T::PalletsOr } fn next_dispatch_time((when, index): Self::Address) -> Result { - Agenda::::get(when).get(index as usize).ok_or(()).map(|_| when) + Agenda::::get(when) + .get(index as usize) + .ok_or(()) + .map(|_| when) } } -impl schedule::Named::Call, T::PalletsOrigin> for Module { +impl schedule::Named::Call, T::PalletsOrigin> + for Pallet +{ type Address = TaskAddress; fn schedule_named( @@ -715,7 +805,9 @@ impl schedule::Named::Call, T::PalletsO } fn next_dispatch_time(id: Vec) -> Result { - Lookup::::get(id).and_then(|(when, index)| Agenda::::get(when).get(index as usize).map(|_| when)).ok_or(()) + Lookup::::get(id) + .and_then(|(when, index)| Agenda::::get(when).get(index as usize).map(|_| when)) + .ok_or(()) } } @@ -723,24 +815,28 @@ impl schedule::Named::Call, T::PalletsO mod tests { use super::*; + use crate as scheduler; use frame_support::{ - parameter_types, assert_ok, ord_parameter_types, - assert_noop, assert_err, Hashable, - traits::{OnInitialize, OnFinalize, Filter}, + assert_err, assert_noop, assert_ok, ord_parameter_types, parameter_types, + traits::{Filter, OnFinalize, OnInitialize}, weights::constants::RocksDbWeight, + Hashable, }; + use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, + Perbill, }; - use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; use substrate_test_utils::assert_eq_uvec; - use crate as scheduler; - mod logger { + // Logger module to track execution. + #[frame_support::pallet] + pub mod logger { use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; use std::cell::RefCell; thread_local! { @@ -749,37 +845,43 @@ mod tests { pub fn log() -> Vec<(OriginCaller, u32)> { LOG.with(|log| log.borrow().clone()) } - pub trait Config: system::Config { - type Event: From + Into<::Event>; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; } - decl_event! { - pub enum Event { - Logged(u32, Weight), - } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + Logged(u32, Weight), } - decl_module! { - pub struct Module for enum Call - where - origin: ::Origin, - ::Origin: OriginTrait - { - fn deposit_event() = default; - - #[weight = *weight] - fn log(origin, i: u32, weight: Weight) { - Self::deposit_event(Event::Logged(i, weight)); - LOG.with(|log| { - log.borrow_mut().push((origin.caller().clone(), i)); - }) - } - #[weight = *weight] - fn log_without_filter(origin, i: u32, weight: Weight) { - Self::deposit_event(Event::Logged(i, weight)); - LOG.with(|log| { - log.borrow_mut().push((origin.caller().clone(), i)); - }) - } + #[pallet::call] + impl Pallet where ::Origin: OriginTrait { + #[pallet::weight(*weight)] + fn log(origin: OriginFor, i: u32, weight: Weight) -> DispatchResult { + Self::deposit_event(Event::Logged(i, weight)); + LOG.with(|log| { + log.borrow_mut().push((origin.caller().clone(), i)); + }); + Ok(()) + } + + #[pallet::weight(*weight)] + fn log_without_filter(origin: OriginFor, i: u32, weight: Weight) -> DispatchResult { + Self::deposit_event(Event::Logged(i, weight)); + LOG.with(|log| { + log.borrow_mut().push((origin.caller().clone(), i)); + }); + Ok(()) } } } @@ -794,7 +896,7 @@ mod tests { UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, - Logger: logger::{Pallet, Call, Event}, + Logger: logger::{Pallet, Call, Event}, Scheduler: scheduler::{Pallet, Call, Storage, Event}, } ); @@ -803,7 +905,7 @@ mod tests { pub struct BaseFilter; impl Filter for BaseFilter { fn filter(call: &Call) -> bool { - !matches!(call, Call::Logger(logger::Call::log(_, _))) + !matches!(call, Call::Logger(LoggerCall::log(_, _))) } } @@ -859,6 +961,8 @@ mod tests { type WeightInfo = (); } + pub type LoggerCall = logger::Call; + pub fn new_test_ext() -> sp_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() @@ -879,8 +983,10 @@ mod tests { #[test] fn basic_scheduling_works() { new_test_ext().execute_with(|| { - let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + let call = Call::Logger(LoggerCall::log(42, 1000)); + assert!(!::BaseCallFilter::filter( + &call + )); assert_ok!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call)); run_to_block(3); assert!(logger::log().is_empty()); @@ -895,8 +1001,10 @@ mod tests { fn schedule_after_works() { new_test_ext().execute_with(|| { run_to_block(2); - let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + let call = Call::Logger(LoggerCall::log(42, 1000)); + assert!(!::BaseCallFilter::filter( + &call + )); // This will schedule the call 3 blocks after the next block... so block 3 + 3 = 6 assert_ok!(Scheduler::do_schedule(DispatchTime::After(3), None, 127, root(), call)); run_to_block(5); @@ -912,7 +1020,7 @@ mod tests { fn schedule_after_zero_works() { new_test_ext().execute_with(|| { run_to_block(2); - let call = Call::Logger(logger::Call::log(42, 1000)); + let call = Call::Logger(LoggerCall::log(42, 1000)); assert!(!::BaseCallFilter::filter(&call)); assert_ok!(Scheduler::do_schedule(DispatchTime::After(0), None, 127, root(), call)); // Will trigger on the next block. @@ -941,16 +1049,22 @@ mod tests { run_to_block(9); assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); run_to_block(10); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); + assert_eq!( + logger::log(), + vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)] + ); run_to_block(100); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); + assert_eq!( + logger::log(), + vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)] + ); }); } #[test] fn reschedule_works() { new_test_ext().execute_with(|| { - let call = Call::Logger(logger::Call::log(42, 1000)); + let call = Call::Logger(LoggerCall::log(42, 1000)); assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call).unwrap(), (4, 0)); @@ -975,7 +1089,7 @@ mod tests { #[test] fn reschedule_named_works() { new_test_ext().execute_with(|| { - let call = Call::Logger(logger::Call::log(42, 1000)); + let call = Call::Logger(LoggerCall::log(42, 1000)); assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), None, 127, root(), call @@ -1002,7 +1116,7 @@ mod tests { #[test] fn reschedule_named_perodic_works() { new_test_ext().execute_with(|| { - let call = Call::Logger(logger::Call::log(42, 1000)); + let call = Call::Logger(LoggerCall::log(42, 1000)); assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), Some((3, 3)), 127, root(), call @@ -1041,10 +1155,10 @@ mod tests { new_test_ext().execute_with(|| { // at #4. Scheduler::do_schedule_named( - 1u32.encode(), DispatchTime::At(4), None, 127, root(), Call::Logger(logger::Call::log(69, 1000)) + 1u32.encode(), DispatchTime::At(4), None, 127, root(), Call::Logger(LoggerCall::log(69, 1000)) ).unwrap(); let i = Scheduler::do_schedule( - DispatchTime::At(4), None, 127, root(), Call::Logger(logger::Call::log(42, 1000)) + DispatchTime::At(4), None, 127, root(), Call::Logger(LoggerCall::log(42, 1000)) ).unwrap(); run_to_block(3); assert!(logger::log().is_empty()); @@ -1065,8 +1179,9 @@ mod tests { Some((3, 3)), 127, root(), - Call::Logger(logger::Call::log(42, 1000)) - ).unwrap(); + Call::Logger(LoggerCall::log(42, 1000)), + ) + .unwrap(); // same id results in error. assert!(Scheduler::do_schedule_named( 1u32.encode(), @@ -1074,12 +1189,19 @@ mod tests { None, 127, root(), - Call::Logger(logger::Call::log(69, 1000)) - ).is_err()); + Call::Logger(LoggerCall::log(69, 1000)) + ) + .is_err()); // different id is ok. Scheduler::do_schedule_named( - 2u32.encode(), DispatchTime::At(8), None, 127, root(), Call::Logger(logger::Call::log(69, 1000)) - ).unwrap(); + 2u32.encode(), + DispatchTime::At(8), + None, + 127, + root(), + Call::Logger(LoggerCall::log(69, 1000)), + ) + .unwrap(); run_to_block(3); assert!(logger::log().is_empty()); run_to_block(4); @@ -1099,13 +1221,14 @@ mod tests { None, 127, root(), - Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(42, MaximumSchedulerWeight::get() / 2)) )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), None, 127, - root(), Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + root(), + Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2)) )); // 69 and 42 do not fit together run_to_block(4); @@ -1123,14 +1246,14 @@ mod tests { None, 0, root(), - Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(42, MaximumSchedulerWeight::get() / 2)) )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), None, 0, root(), - Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2)) )); // With base weights, 69 and 42 should not fit together, but do because of hard deadlines run_to_block(4); @@ -1146,14 +1269,14 @@ mod tests { None, 1, root(), - Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(42, MaximumSchedulerWeight::get() / 2)) )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), None, 0, root(), - Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2)) )); run_to_block(4); assert_eq!(logger::log(), vec![(root(), 69u32), (root(), 42u32)]); @@ -1167,19 +1290,22 @@ mod tests { DispatchTime::At(4), None, 255, - root(), Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3)) + root(), + Call::Logger(LoggerCall::log(42, MaximumSchedulerWeight::get() / 3)) )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), None, 127, - root(), Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + root(), + Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2)) )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), None, 126, - root(), Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2)) + root(), + Call::Logger(LoggerCall::log(2600, MaximumSchedulerWeight::get() / 2)) )); // 2600 does not fit with 69 or 42, but has higher priority, so will go through @@ -1187,32 +1313,39 @@ mod tests { assert_eq!(logger::log(), vec![(root(), 2600u32)]); // 69 and 42 fit together run_to_block(5); - assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]); + assert_eq!( + logger::log(), + vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)] + ); }); } #[test] fn on_initialize_weight_is_correct() { new_test_ext().execute_with(|| { - let base_weight: Weight = ::DbWeight::get().reads_writes(1, 2); + let base_weight: Weight = + ::DbWeight::get().reads_writes(1, 2); let base_multiplier = 0; let named_multiplier = ::DbWeight::get().writes(1); - let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); + let periodic_multiplier = + ::DbWeight::get().reads_writes(1, 1); // Named - assert_ok!( - Scheduler::do_schedule_named( - 1u32.encode(), DispatchTime::At(1), None, 255, root(), - Call::Logger(logger::Call::log(3, MaximumSchedulerWeight::get() / 3)) - ) - ); + assert_ok!(Scheduler::do_schedule_named( + 1u32.encode(), + DispatchTime::At(1), + None, + 255, + root(), + Call::Logger(LoggerCall::log(3, MaximumSchedulerWeight::get() / 3)) + )); // Anon Periodic assert_ok!(Scheduler::do_schedule( DispatchTime::At(1), Some((1000, 3)), 128, root(), - Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3)) + Call::Logger(LoggerCall::log(42, MaximumSchedulerWeight::get() / 3)) )); // Anon assert_ok!(Scheduler::do_schedule( @@ -1220,33 +1353,57 @@ mod tests { None, 127, root(), - Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2)) )); // Named Periodic assert_ok!(Scheduler::do_schedule_named( - 2u32.encode(), DispatchTime::At(1), Some((1000, 3)), 126, root(), - Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2))) - ); + 2u32.encode(), + DispatchTime::At(1), + Some((1000, 3)), + 126, + root(), + Call::Logger(LoggerCall::log(2600, MaximumSchedulerWeight::get() / 2)) + )); // Will include the named periodic only let actual_weight = Scheduler::on_initialize(1); let call_weight = MaximumSchedulerWeight::get() / 2; assert_eq!( - actual_weight, call_weight + base_weight + base_multiplier + named_multiplier + periodic_multiplier + actual_weight, + call_weight + + base_weight + base_multiplier + + named_multiplier + periodic_multiplier ); assert_eq!(logger::log(), vec![(root(), 2600u32)]); // Will include anon and anon periodic let actual_weight = Scheduler::on_initialize(2); let call_weight = MaximumSchedulerWeight::get() / 2 + MaximumSchedulerWeight::get() / 3; - assert_eq!(actual_weight, call_weight + base_weight + base_multiplier * 2 + periodic_multiplier); - assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]); + assert_eq!( + actual_weight, + call_weight + base_weight + base_multiplier * 2 + periodic_multiplier + ); + assert_eq!( + logger::log(), + vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)] + ); // Will include named only let actual_weight = Scheduler::on_initialize(3); let call_weight = MaximumSchedulerWeight::get() / 3; - assert_eq!(actual_weight, call_weight + base_weight + base_multiplier + named_multiplier); - assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32), (root(), 3u32)]); + assert_eq!( + actual_weight, + call_weight + base_weight + base_multiplier + named_multiplier + ); + assert_eq!( + logger::log(), + vec![ + (root(), 2600u32), + (root(), 69u32), + (root(), 42u32), + (root(), 3u32) + ] + ); // Will contain none let actual_weight = Scheduler::on_initialize(4); @@ -1257,9 +1414,16 @@ mod tests { #[test] fn root_calls_works() { new_test_ext().execute_with(|| { - let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); - let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); - assert_ok!(Scheduler::schedule_named(Origin::root(), 1u32.encode(), 4, None, 127, call)); + let call = Box::new(Call::Logger(LoggerCall::log(69, 1000))); + let call2 = Box::new(Call::Logger(LoggerCall::log(42, 1000))); + assert_ok!(Scheduler::schedule_named( + Origin::root(), + 1u32.encode(), + 4, + None, + 127, + call + )); assert_ok!(Scheduler::schedule(Origin::root(), 4, None, 127, call2)); run_to_block(3); // Scheduled calls are in the agenda. @@ -1278,8 +1442,8 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(3); - let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); - let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); + let call = Box::new(Call::Logger(LoggerCall::log(69, 1000))); + let call2 = Box::new(Call::Logger(LoggerCall::log(42, 1000))); assert_err!( Scheduler::schedule_named(Origin::root(), 1u32.encode(), 2, None, 127, call), @@ -1301,17 +1465,31 @@ mod tests { #[test] fn should_use_orign() { new_test_ext().execute_with(|| { - let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); - let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); - assert_ok!( - Scheduler::schedule_named(system::RawOrigin::Signed(1).into(), 1u32.encode(), 4, None, 127, call) - ); - assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2)); + let call = Box::new(Call::Logger(LoggerCall::log(69, 1000))); + let call2 = Box::new(Call::Logger(LoggerCall::log(42, 1000))); + assert_ok!(Scheduler::schedule_named( + system::RawOrigin::Signed(1).into(), + 1u32.encode(), + 4, + None, + 127, + call + )); + assert_ok!(Scheduler::schedule( + system::RawOrigin::Signed(1).into(), + 4, + None, + 127, + call2 + )); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(4).len(), 2); assert!(logger::log().is_empty()); - assert_ok!(Scheduler::cancel_named(system::RawOrigin::Signed(1).into(), 1u32.encode())); + assert_ok!(Scheduler::cancel_named( + system::RawOrigin::Signed(1).into(), + 1u32.encode() + )); assert_ok!(Scheduler::cancel(system::RawOrigin::Signed(1).into(), 4, 1)); // Scheduled calls are made NONE, so should not effect state run_to_block(100); @@ -1322,37 +1500,73 @@ mod tests { #[test] fn should_check_orign() { new_test_ext().execute_with(|| { - let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); - let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); + let call = Box::new(Call::Logger(LoggerCall::log(69, 1000))); + let call2 = Box::new(Call::Logger(LoggerCall::log(42, 1000))); + assert_noop!( + Scheduler::schedule_named( + system::RawOrigin::Signed(2).into(), + 1u32.encode(), + 4, + None, + 127, + call + ), + BadOrigin + ); assert_noop!( - Scheduler::schedule_named(system::RawOrigin::Signed(2).into(), 1u32.encode(), 4, None, 127, call), + Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, None, 127, call2), BadOrigin ); - assert_noop!(Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, None, 127, call2), BadOrigin); }); } #[test] fn should_check_orign_for_cancel() { new_test_ext().execute_with(|| { - let call = Box::new(Call::Logger(logger::Call::log_without_filter(69, 1000))); - let call2 = Box::new(Call::Logger(logger::Call::log_without_filter(42, 1000))); - assert_ok!( - Scheduler::schedule_named(system::RawOrigin::Signed(1).into(), 1u32.encode(), 4, None, 127, call) - ); - assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2)); + let call = Box::new(Call::Logger(LoggerCall::log_without_filter(69, 1000))); + let call2 = Box::new(Call::Logger(LoggerCall::log_without_filter(42, 1000))); + assert_ok!(Scheduler::schedule_named( + system::RawOrigin::Signed(1).into(), + 1u32.encode(), + 4, + None, + 127, + call + )); + assert_ok!(Scheduler::schedule( + system::RawOrigin::Signed(1).into(), + 4, + None, + 127, + call2 + )); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(4).len(), 2); assert!(logger::log().is_empty()); - assert_noop!(Scheduler::cancel_named(system::RawOrigin::Signed(2).into(), 1u32.encode()), BadOrigin); - assert_noop!(Scheduler::cancel(system::RawOrigin::Signed(2).into(), 4, 1), BadOrigin); - assert_noop!(Scheduler::cancel_named(system::RawOrigin::Root.into(), 1u32.encode()), BadOrigin); - assert_noop!(Scheduler::cancel(system::RawOrigin::Root.into(), 4, 1), BadOrigin); + assert_noop!( + Scheduler::cancel_named(system::RawOrigin::Signed(2).into(), 1u32.encode()), + BadOrigin + ); + assert_noop!( + Scheduler::cancel(system::RawOrigin::Signed(2).into(), 4, 1), + BadOrigin + ); + assert_noop!( + Scheduler::cancel_named(system::RawOrigin::Root.into(), 1u32.encode()), + BadOrigin + ); + assert_noop!( + Scheduler::cancel(system::RawOrigin::Root.into(), 4, 1), + BadOrigin + ); run_to_block(5); assert_eq!( logger::log(), - vec![(system::RawOrigin::Signed(1).into(), 69u32), (system::RawOrigin::Signed(1).into(), 42u32)] + vec![ + (system::RawOrigin::Signed(1).into(), 69u32), + (system::RawOrigin::Signed(1).into(), 42u32) + ] ); }); } @@ -1366,98 +1580,97 @@ mod tests { Some(ScheduledV1 { maybe_id: None, priority: i as u8 + 10, - call: Call::Logger(logger::Call::log(96, 100)), + call: Call::Logger(LoggerCall::log(96, 100)), maybe_periodic: None, }), None, Some(ScheduledV1 { maybe_id: Some(b"test".to_vec()), priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), + call: Call::Logger(LoggerCall::log(69, 1000)), maybe_periodic: Some((456u64, 10)), }), ]; - frame_support::migration::put_storage_value( - b"Scheduler", - b"Agenda", - &k, - old, - ); + frame_support::migration::put_storage_value(b"Scheduler", b"Agenda", &k, old); } - assert_eq!(StorageVersion::get(), Releases::V1); + assert_eq!(StorageVersion::::get(), Releases::V1); assert!(Scheduler::migrate_v1_to_t2()); - assert_eq_uvec!(Agenda::::iter().collect::>(), vec![ - ( - 0, - vec![ - Some(ScheduledV2 { - maybe_id: None, - priority: 10, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: root(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: root(), - _phantom: PhantomData::::default(), - }), - ]), - ( - 1, - vec![ - Some(ScheduledV2 { - maybe_id: None, - priority: 11, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: root(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: root(), - _phantom: PhantomData::::default(), - }), - ] - ), - ( - 2, - vec![ - Some(ScheduledV2 { - maybe_id: None, - priority: 12, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: root(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: root(), - _phantom: PhantomData::::default(), - }), - ] - ) - ]); - - assert_eq!(StorageVersion::get(), Releases::V2); + assert_eq_uvec!( + Agenda::::iter().collect::>(), + vec![ + ( + 0, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 10, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ] + ), + ( + 1, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 11, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ] + ), + ( + 2, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 12, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ] + ) + ] + ); + + assert_eq!(StorageVersion::::get(), Releases::V2); }); } @@ -1470,7 +1683,7 @@ mod tests { Some(Scheduled { maybe_id: None, priority: i as u8 + 10, - call: Call::Logger(logger::Call::log(96, 100)), + call: Call::Logger(LoggerCall::log(96, 100)), origin: 3u32, maybe_periodic: None, _phantom: Default::default(), @@ -1480,17 +1693,12 @@ mod tests { maybe_id: Some(b"test".to_vec()), priority: 123, origin: 2u32, - call: Call::Logger(logger::Call::log(69, 1000)), + call: Call::Logger(LoggerCall::log(69, 1000)), maybe_periodic: Some((456u64, 10)), _phantom: Default::default(), }), ]; - frame_support::migration::put_storage_value( - b"Scheduler", - b"Agenda", - &k, - old, - ); + frame_support::migration::put_storage_value(b"Scheduler", b"Agenda", &k, old); } impl Into for u32 { @@ -1505,73 +1713,77 @@ mod tests { Scheduler::migrate_origin::(); - assert_eq_uvec!(Agenda::::iter().collect::>(), vec![ - ( - 0, - vec![ - Some(ScheduledV2::<_, _, OriginCaller, u64> { - maybe_id: None, - priority: 10, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: system::RawOrigin::Root.into(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: system::RawOrigin::None.into(), - _phantom: PhantomData::::default(), - }), - ]), - ( - 1, - vec![ - Some(ScheduledV2 { - maybe_id: None, - priority: 11, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: system::RawOrigin::Root.into(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: system::RawOrigin::None.into(), - _phantom: PhantomData::::default(), - }), - ] - ), - ( - 2, - vec![ - Some(ScheduledV2 { - maybe_id: None, - priority: 12, - call: Call::Logger(logger::Call::log(96, 100)), - maybe_periodic: None, - origin: system::RawOrigin::Root.into(), - _phantom: PhantomData::::default(), - }), - None, - Some(ScheduledV2 { - maybe_id: Some(b"test".to_vec()), - priority: 123, - call: Call::Logger(logger::Call::log(69, 1000)), - maybe_periodic: Some((456u64, 10)), - origin: system::RawOrigin::None.into(), - _phantom: PhantomData::::default(), - }), - ] - ) - ]); + assert_eq_uvec!( + Agenda::::iter().collect::>(), + vec![ + ( + 0, + vec![ + Some(ScheduledV2::<_, _, OriginCaller, u64> { + maybe_id: None, + priority: 10, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: system::RawOrigin::Root.into(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: system::RawOrigin::None.into(), + _phantom: PhantomData::::default(), + }), + ] + ), + ( + 1, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 11, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: system::RawOrigin::Root.into(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: system::RawOrigin::None.into(), + _phantom: PhantomData::::default(), + }), + ] + ), + ( + 2, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 12, + call: Call::Logger(LoggerCall::log(96, 100)), + maybe_periodic: None, + origin: system::RawOrigin::Root.into(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(LoggerCall::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: system::RawOrigin::None.into(), + _phantom: PhantomData::::default(), + }), + ] + ) + ] + ); }); } }