--- a/runtime/common/config/pallets/scheduler.rs +++ b/runtime/common/config/pallets/scheduler.rs @@ -14,13 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -use frame_support::{traits::EqualPrivilegeOnly, weights::Weight, parameter_types}; -use frame_system::EnsureSigned; +use frame_support::{traits::{PrivilegeCmp, EnsureOrigin}, weights::Weight, parameter_types}; +use frame_system::{EnsureRoot, RawOrigin}; use sp_runtime::Perbill; +use core::cmp::Ordering; +use codec::Decode; use crate::{ runtime_common::{scheduler::SchedulerPaymentExecutor, config::substrate::RuntimeBlockWeights}, Runtime, Call, Event, Origin, OriginCaller, Balances, }; +use pallet_unique_scheduler::ScheduledEnsureOriginSuccess; use up_common::types::AccountId; parameter_types! { @@ -32,6 +35,36 @@ pub const Preimage: Option = Some(10); } +pub struct EnsureSignedOrRoot(sp_std::marker::PhantomData); +impl, O>> + From>, AccountId: Decode> + EnsureOrigin for EnsureSignedOrRoot { + type Success = ScheduledEnsureOriginSuccess; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::Root => Ok(ScheduledEnsureOriginSuccess::Root), + RawOrigin::Signed(who) => Ok(ScheduledEnsureOriginSuccess::Signed(who)), + r => Err(O::from(r)), + }) + } +} + +pub struct EqualOrRootOnly; +impl PrivilegeCmp for EqualOrRootOnly { + fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option { + use RawOrigin::*; + + let left = left.clone().try_into().ok()?; + let right = right.clone().try_into().ok()?; + + match (left, right) { + (Root, Root) => Some(Ordering::Equal), + (Root, _) => Some(Ordering::Greater), + (_, Root) => Some(Ordering::Less), + lr @ _ => (lr.0 == lr.1).then(|| Ordering::Equal) + } + } +} + impl pallet_unique_scheduler::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; @@ -39,11 +72,12 @@ type PalletsOrigin = OriginCaller; type RuntimeCall = RuntimeCall; type MaximumWeight = MaximumSchedulerWeight; - type ScheduleOrigin = EnsureSigned; + type ScheduleOrigin = EnsureSignedOrRoot; + type PrioritySetOrigin = EnsureRoot; type MaxScheduledPerBlock = MaxScheduledPerBlock; type WeightInfo = (); type CallExecutor = SchedulerPaymentExecutor; - type OriginPrivilegeCmp = EqualPrivilegeOnly; + type OriginPrivilegeCmp = EqualOrRootOnly; type PreimageProvider = (); type NoPreimagePostponement = NoPreimagePostponement; } --- a/runtime/common/scheduler.rs +++ b/runtime/common/scheduler.rs @@ -74,7 +74,7 @@ sp_runtime::AccountId32: From<::AccountId>, { fn dispatch_call( - signer: ::AccountId, + signer: Option<::AccountId>, call: ::Call, ) -> Result< Result>, @@ -82,17 +82,19 @@ > { let dispatch_info = call.get_dispatch_info(); let len = call.encoded_size(); + + let signed = match signer { + Some(signer) => fp_self_contained::CheckedSignature::Signed(signer.clone().into(), get_signed_extras(signer.into())), + None => fp_self_contained::CheckedSignature::Unsigned, + }; + let extrinsic = fp_self_contained::CheckedExtrinsic::< AccountId, Call, SignedExtraScheduler, SelfContainedSignedInfo, > { - signed: fp_self_contained::CheckedSignature::< - AccountId, - SignedExtraScheduler, - SelfContainedSignedInfo, - >::Signed(signer.clone().into(), get_signed_extras(signer.into())), + signed, function: call.into(), };