From a8adb8d551e2a7401fbc3098774a603ee6f6fd74 Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Fri, 21 Oct 2022 06:15:45 +0000 Subject: [PATCH] feat: scheduler v2, priority change --- --- a/pallets/scheduler-v2/src/lib.rs +++ b/pallets/scheduler-v2/src/lib.rs @@ -79,7 +79,7 @@ use frame_support::{ dispatch::{DispatchError, DispatchResult, Dispatchable, GetDispatchInfo, Parameter}, traits::{ - schedule::{self, DispatchTime}, + schedule::{self, DispatchTime, LOWEST_PRIORITY}, EnsureOrigin, Get, IsType, OriginTrait, PrivilegeCmp, StorageVersion, PreimageRecipient, ConstU32, UnfilteredDispatchable, }, @@ -354,6 +354,9 @@ /// The helper type used for custom transaction fee logic. type CallExecutor: DispatchCall; + + /// Required origin to set/change calls' priority. + type PrioritySetOrigin: EnsureOrigin<::Origin>; } #[pallet::storage] @@ -388,6 +391,12 @@ id: Option<[u8; 32]>, result: DispatchResult, }, + /// Scheduled task's priority has changed + PriorityChanged { + when: T::BlockNumber, + index: u32, + priority: schedule::Priority, + }, /// The call for the provided hash was not found so the task has been aborted. CallUnavailable { task: TaskAddress, @@ -448,15 +457,20 @@ origin: OriginFor, when: T::BlockNumber, maybe_periodic: Option>, - priority: schedule::Priority, + priority: Option, call: Box<::Call>, ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; + + if priority.is_some() { + T::PrioritySetOrigin::ensure_origin(origin.clone())?; + } + let origin = ::Origin::from(origin); Self::do_schedule( DispatchTime::At(when), maybe_periodic, - priority, + priority.unwrap_or(LOWEST_PRIORITY), origin.caller().clone(), >::new(*call)?, )?; @@ -479,16 +493,21 @@ id: TaskName, when: T::BlockNumber, maybe_periodic: Option>, - priority: schedule::Priority, + priority: Option, call: Box<::Call>, ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; + + if priority.is_some() { + T::PrioritySetOrigin::ensure_origin(origin.clone())?; + } + let origin = ::Origin::from(origin); Self::do_schedule_named( id, DispatchTime::At(when), maybe_periodic, - priority, + priority.unwrap_or(LOWEST_PRIORITY), origin.caller().clone(), >::new(*call)?, )?; @@ -514,15 +533,20 @@ origin: OriginFor, after: T::BlockNumber, maybe_periodic: Option>, - priority: schedule::Priority, + priority: Option, call: Box<::Call>, ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; + + if priority.is_some() { + T::PrioritySetOrigin::ensure_origin(origin.clone())?; + } + let origin = ::Origin::from(origin); Self::do_schedule( DispatchTime::After(after), maybe_periodic, - priority, + priority.unwrap_or(LOWEST_PRIORITY), origin.caller().clone(), >::new(*call)?, )?; @@ -540,21 +564,37 @@ id: TaskName, after: T::BlockNumber, maybe_periodic: Option>, - priority: schedule::Priority, + priority: Option, call: Box<::Call>, ) -> DispatchResult { T::ScheduleOrigin::ensure_origin(origin.clone())?; + + if priority.is_some() { + T::PrioritySetOrigin::ensure_origin(origin.clone())?; + } + let origin = ::Origin::from(origin); Self::do_schedule_named( id, DispatchTime::After(after), maybe_periodic, - priority, + priority.unwrap_or(LOWEST_PRIORITY), origin.caller().clone(), >::new(*call)?, )?; Ok(()) } + + #[pallet::weight(::WeightInfo::change_named_priority(T::MaxScheduledPerBlock::get()))] + pub fn change_named_priority( + origin: OriginFor, + id: TaskName, + priority: schedule::Priority, + ) -> DispatchResult { + T::PrioritySetOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_change_named_priority(origin.caller().clone(), id, priority) + } } } @@ -730,6 +770,37 @@ } }) } + + fn do_change_named_priority( + origin: T::PalletsOrigin, + id: TaskName, + priority: schedule::Priority, + ) -> DispatchResult { + match Lookup::::get(id) { + Some((when, index)) => { + let i = index as usize; + Agenda::::try_mutate(when, |agenda| { + if let Some(Some(s)) = agenda.get_mut(i) { + if matches!( + T::OriginPrivilegeCmp::cmp_privilege(&origin, &s.origin), + Some(Ordering::Less) | None + ) { + return Err(BadOrigin.into()); + } + + s.priority = priority; + Self::deposit_event(Event::PriorityChanged { + when, + index, + priority, + }); + } + Ok(()) + }) + } + None => Err(Error::::NotFound.into()), + } + } } enum ServiceTaskError { --- a/pallets/scheduler-v2/src/weights.rs +++ b/pallets/scheduler-v2/src/weights.rs @@ -75,6 +75,7 @@ fn cancel(s: u32, ) -> Weight; fn schedule_named(s: u32, ) -> Weight; fn cancel_named(s: u32, ) -> Weight; + fn change_named_priority(s: u32, ) -> Weight; } /// Weights for pallet_scheduler using the Substrate node and recommended hardware. @@ -161,6 +162,16 @@ .saturating_add(T::DbWeight::get().reads(2 as u64)) .saturating_add(T::DbWeight::get().writes(2 as u64)) } + + // Storage: Scheduler Lookup (r:1 w:1) + // Storage: Scheduler Agenda (r:1 w:1) + fn change_named_priority(s: u32, ) -> Weight { + Weight::from_ref_time(8_642_000) + // Standard Error: 0 + .saturating_add(Weight::from_ref_time(431_000).saturating_mul(s as u64)) + .saturating_add(T::DbWeight::get().reads(2 as u64)) + .saturating_add(T::DbWeight::get().writes(2 as u64)) + } } // For backwards compatibility and tests @@ -246,4 +257,14 @@ .saturating_add(RocksDbWeight::get().reads(2 as u64)) .saturating_add(RocksDbWeight::get().writes(2 as u64)) } + + // Storage: Scheduler Lookup (r:1 w:1) + // Storage: Scheduler Agenda (r:1 w:1) + fn change_named_priority(s: u32, ) -> Weight { + Weight::from_ref_time(8_642_000) + // Standard Error: 0 + .saturating_add(Weight::from_ref_time(431_000).saturating_mul(s as u64)) + .saturating_add(RocksDbWeight::get().reads(2 as u64)) + .saturating_add(RocksDbWeight::get().writes(2 as u64)) + } } --- a/runtime/common/config/pallets/scheduler.rs +++ b/runtime/common/config/pallets/scheduler.rs @@ -99,4 +99,5 @@ type WeightInfo = (); type Preimages = (); type CallExecutor = SchedulerPaymentExecutor; + type PrioritySetOrigin = EnsureRoot; } -- gitstuff