git.delta.rocks / unique-network / refs/commits / feb58b8452cd

difftreelog

feat scheduler v2, priority change

Daniel Shiposha2022-10-21parent: #f1b93a3.patch.diff
in: master

3 files changed

modifiedpallets/scheduler-v2/src/lib.rsdiffbeforeafterboth
--- 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<Self, H160>;
+
+		/// Required origin to set/change calls' priority.
+		type PrioritySetOrigin: EnsureOrigin<<Self as system::Config>::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<T::BlockNumber>,
@@ -448,15 +457,20 @@
 			origin: OriginFor<T>,
 			when: T::BlockNumber,
 			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
-			priority: schedule::Priority,
+			priority: Option<schedule::Priority>,
 			call: Box<<T as Config>::Call>,
 		) -> DispatchResult {
 			T::ScheduleOrigin::ensure_origin(origin.clone())?;
+
+			if priority.is_some() {
+				T::PrioritySetOrigin::ensure_origin(origin.clone())?;
+			}
+
 			let origin = <T as Config>::Origin::from(origin);
 			Self::do_schedule(
 				DispatchTime::At(when),
 				maybe_periodic,
-				priority,
+				priority.unwrap_or(LOWEST_PRIORITY),
 				origin.caller().clone(),
 				<ScheduledCall<T>>::new(*call)?,
 			)?;
@@ -479,16 +493,21 @@
 			id: TaskName,
 			when: T::BlockNumber,
 			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
-			priority: schedule::Priority,
+			priority: Option<schedule::Priority>,
 			call: Box<<T as Config>::Call>,
 		) -> DispatchResult {
 			T::ScheduleOrigin::ensure_origin(origin.clone())?;
+
+			if priority.is_some() {
+				T::PrioritySetOrigin::ensure_origin(origin.clone())?;
+			}
+
 			let origin = <T as Config>::Origin::from(origin);
 			Self::do_schedule_named(
 				id,
 				DispatchTime::At(when),
 				maybe_periodic,
-				priority,
+				priority.unwrap_or(LOWEST_PRIORITY),
 				origin.caller().clone(),
 				<ScheduledCall<T>>::new(*call)?,
 			)?;
@@ -514,15 +533,20 @@
 			origin: OriginFor<T>,
 			after: T::BlockNumber,
 			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
-			priority: schedule::Priority,
+			priority: Option<schedule::Priority>,
 			call: Box<<T as Config>::Call>,
 		) -> DispatchResult {
 			T::ScheduleOrigin::ensure_origin(origin.clone())?;
+
+			if priority.is_some() {
+				T::PrioritySetOrigin::ensure_origin(origin.clone())?;
+			}
+
 			let origin = <T as Config>::Origin::from(origin);
 			Self::do_schedule(
 				DispatchTime::After(after),
 				maybe_periodic,
-				priority,
+				priority.unwrap_or(LOWEST_PRIORITY),
 				origin.caller().clone(),
 				<ScheduledCall<T>>::new(*call)?,
 			)?;
@@ -540,21 +564,37 @@
 			id: TaskName,
 			after: T::BlockNumber,
 			maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
-			priority: schedule::Priority,
+			priority: Option<schedule::Priority>,
 			call: Box<<T as Config>::Call>,
 		) -> DispatchResult {
 			T::ScheduleOrigin::ensure_origin(origin.clone())?;
+
+			if priority.is_some() {
+				T::PrioritySetOrigin::ensure_origin(origin.clone())?;
+			}
+
 			let origin = <T as Config>::Origin::from(origin);
 			Self::do_schedule_named(
 				id,
 				DispatchTime::After(after),
 				maybe_periodic,
-				priority,
+				priority.unwrap_or(LOWEST_PRIORITY),
 				origin.caller().clone(),
 				<ScheduledCall<T>>::new(*call)?,
 			)?;
 			Ok(())
 		}
+
+		#[pallet::weight(<T as Config>::WeightInfo::change_named_priority(T::MaxScheduledPerBlock::get()))]
+		pub fn change_named_priority(
+			origin: OriginFor<T>,
+			id: TaskName,
+			priority: schedule::Priority,
+		) -> DispatchResult {
+			T::PrioritySetOrigin::ensure_origin(origin.clone())?;
+			let origin = <T as Config>::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::<T>::get(id) {
+			Some((when, index)) => {
+				let i = index as usize;
+				Agenda::<T>::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::<T>::NotFound.into()),
+		}
+	}
 }
 
 enum ServiceTaskError {
modifiedpallets/scheduler-v2/src/weights.rsdiffbeforeafterboth
--- 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))
+	}
 }
modifiedruntime/common/config/pallets/scheduler.rsdiffbeforeafterboth
before · runtime/common/config/pallets/scheduler.rs
1// 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/>.1617use frame_support::{18	traits::{PrivilegeCmp, EnsureOrigin},19	weights::Weight,20	parameter_types,21};22use frame_system::{EnsureRoot, RawOrigin};23use sp_runtime::Perbill;24use core::cmp::Ordering;25use codec::Decode;26use crate::{27	runtime_common::{scheduler::SchedulerPaymentExecutor, config::substrate::RuntimeBlockWeights},28	Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, OriginCaller, Balances,29};30use pallet_unique_scheduler_v2::ScheduledEnsureOriginSuccess;31use up_common::types::AccountId;3233parameter_types! {34	pub MaximumSchedulerWeight: Weight = Perbill::from_percent(50) *35		RuntimeBlockWeights::get().max_block;36	pub const MaxScheduledPerBlock: u32 = 50;3738	pub const NoPreimagePostponement: Option<u32> = Some(10);39	pub const Preimage: Option<u32> = Some(10);40}4142pub struct EnsureSignedOrRoot<AccountId>(sp_std::marker::PhantomData<AccountId>);43impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId: Decode>44	EnsureOrigin<O> for EnsureSignedOrRoot<AccountId>45{46	type Success = ScheduledEnsureOriginSuccess<AccountId>;47	fn try_origin(o: O) -> Result<Self::Success, O> {48		o.into().and_then(|o| match o {49			RawOrigin::Root => Ok(ScheduledEnsureOriginSuccess::Root),50			RawOrigin::Signed(who) => Ok(ScheduledEnsureOriginSuccess::Signed(who)),51			r => Err(O::from(r)),52		})53	}54}5556pub struct EqualOrRootOnly;57impl PrivilegeCmp<OriginCaller> for EqualOrRootOnly {58	fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {59		use RawOrigin::*;6061		let left = left.clone().try_into().ok()?;62		let right = right.clone().try_into().ok()?;6364		match (left, right) {65			(Root, Root) => Some(Ordering::Equal),66			(Root, _) => Some(Ordering::Greater),67			(_, Root) => Some(Ordering::Less),68			lr @ _ => (lr.0 == lr.1).then(|| Ordering::Equal),69		}70	}71}7273// impl pallet_unique_scheduler::Config for Runtime {74// 	type RuntimeEvent = RuntimeEvent;75// 	type RuntimeOrigin = RuntimeOrigin;76// 	type Currency = Balances;77// 	type PalletsOrigin = OriginCaller;78// 	type RuntimeCall = RuntimeCall;79// 	type MaximumWeight = MaximumSchedulerWeight;80// 	type ScheduleOrigin = EnsureSignedOrRoot<AccountId>;81// 	type PrioritySetOrigin = EnsureRoot<AccountId>;82// 	type MaxScheduledPerBlock = MaxScheduledPerBlock;83// 	type WeightInfo = ();84// 	type CallExecutor = SchedulerPaymentExecutor;85// 	type OriginPrivilegeCmp = EqualOrRootOnly;86// 	type PreimageProvider = ();87// 	type NoPreimagePostponement = NoPreimagePostponement;88// }8990impl pallet_unique_scheduler_v2::Config for Runtime {91	type Event = Event;92	type Origin = Origin;93	type PalletsOrigin = OriginCaller;94	type Call = Call;95	type MaximumWeight = MaximumSchedulerWeight;96	type ScheduleOrigin = EnsureSignedOrRoot<AccountId>;97	type OriginPrivilegeCmp = EqualOrRootOnly;98	type MaxScheduledPerBlock = MaxScheduledPerBlock;99	type WeightInfo = ();100	type Preimages = ();101	type CallExecutor = SchedulerPaymentExecutor;102}