diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 153d9cf49dcc0ab62b527cf352448039cf8db5ea..a9944199b8209d34f2db5cd567960d06cdeb3258 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -235,7 +235,7 @@ impl transaction_payment::Trait for Runtime { impl sudo::Trait for Runtime { type Event = Event; - type Proposal = Call; + type Call = Call; } /// Used for the module template in `./template.rs` diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index d80986c0df8ce6854c668ab6f6919bab89ac145c..1807952af6171924b193e0153e5070ae6b735eb0 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 219, - impl_version: 1, + spec_version: 220, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -442,7 +442,7 @@ impl pallet_contracts::Trait for Runtime { impl pallet_sudo::Trait for Runtime { type Event = Event; - type Proposal = Call; + type Call = Call; } /// A runtime transaction submitter. diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs index e69840e1586670d26e543468876b41524d38c288..8ee09ba223ab1a393fadb9ff41056dbac21c756b 100644 --- a/substrate/frame/sudo/src/lib.rs +++ b/substrate/frame/sudo/src/lib.rs @@ -90,8 +90,8 @@ use sp_runtime::{traits::{StaticLookup, Dispatchable}, DispatchError}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, - weights::SimpleDispatchInfo, }; +use frame_support::weights::{GetDispatchInfo, FunctionOf}; use frame_system::{self as system, ensure_signed}; pub trait Trait: frame_system::Trait { @@ -99,7 +99,7 @@ pub trait Trait: frame_system::Trait { type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>; /// A sudo-able call. - type Proposal: Parameter + Dispatchable<Origin=Self::Origin>; + type Call: Parameter + Dispatchable<Origin=Self::Origin> + GetDispatchInfo; } decl_module! { @@ -117,15 +117,19 @@ decl_module! { /// - O(1). /// - Limited storage reads. /// - One DB write (event). - /// - Unknown weight of derivative `proposal` execution. + /// - Weight of derivative `call` execution + 10,000. /// # </weight> - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] - fn sudo(origin, proposal: Box<T::Proposal>) { + #[weight = FunctionOf( + |args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().weight + 10_000, + |args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().class, + true + )] + fn sudo(origin, call: Box<<T as Trait>::Call>) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::<T>::RequireSudo); - let res = match proposal.dispatch(frame_system::RawOrigin::Root.into()) { + let res = match call.dispatch(frame_system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); @@ -165,17 +169,25 @@ decl_module! { /// - O(1). /// - Limited storage reads. /// - One DB write (event). - /// - Unknown weight of derivative `proposal` execution. + /// - Weight of derivative `call` execution + 10,000. /// # </weight> - #[weight = SimpleDispatchInfo::FixedOperational(0)] - fn sudo_as(origin, who: <T::Lookup as StaticLookup>::Source, proposal: Box<T::Proposal>) { + #[weight = FunctionOf( + |args: (&<T::Lookup as StaticLookup>::Source, &Box<<T as Trait>::Call>,)| { + args.1.get_dispatch_info().weight + 10_000 + }, + |args: (&<T::Lookup as StaticLookup>::Source, &Box<<T as Trait>::Call>,)| { + args.1.get_dispatch_info().class + }, + true + )] + fn sudo_as(origin, who: <T::Lookup as StaticLookup>::Source, call: Box<<T as Trait>::Call>) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::<T>::RequireSudo); let who = T::Lookup::lookup(who)?; - let res = match proposal.dispatch(frame_system::RawOrigin::Signed(who).into()) { + let res = match call.dispatch(frame_system::RawOrigin::Signed(who).into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); diff --git a/substrate/frame/support/src/weights.rs b/substrate/frame/support/src/weights.rs index 60f0d4a8b2b64b91edb4658295f1760993b5887d..c46cca683ba934172c08a3b5437d1a7e9457d077 100644 --- a/substrate/frame/support/src/weights.rs +++ b/substrate/frame/support/src/weights.rs @@ -234,32 +234,61 @@ impl SimpleDispatchInfo { /// A struct to represent a weight which is a function of the input arguments. The given items have /// the following types: /// -/// - `F`: a closure with the same argument list as the dispatched, wrapped in a tuple. -/// - `DispatchClass`: class of the dispatch. -/// - `bool`: whether this dispatch pays fee or not. -pub struct FunctionOf<F>(pub F, pub DispatchClass, pub bool); +/// - `WD`: a raw `Weight` value or a closure that returns a `Weight` with the same +/// argument list as the dispatched, wrapped in a tuple. +/// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass` +/// with the same argument list as the dispatched, wrapped in a tuple. +/// - `PF`: a `bool` for whether this dispatch pays fee or not or a closure that +/// returns a bool with the same argument list as the dispatched, wrapped in a tuple. +pub struct FunctionOf<WD, CD, PF>(pub WD, pub CD, pub PF); + +// `WeighData` as a raw value +impl<Args, CD, PF> WeighData<Args> for FunctionOf<Weight, CD, PF> { + fn weigh_data(&self, _: Args) -> Weight { + self.0 + } +} -impl<Args, F> WeighData<Args> for FunctionOf<F> -where - F : Fn(Args) -> Weight +// `WeighData` as a closure +impl<Args, WD, CD, PF> WeighData<Args> for FunctionOf<WD, CD, PF> where + WD : Fn(Args) -> Weight { fn weigh_data(&self, args: Args) -> Weight { (self.0)(args) } } -impl<Args, F> ClassifyDispatch<Args> for FunctionOf<F> { +// `ClassifyDispatch` as a raw value +impl<Args, WD, PF> ClassifyDispatch<Args> for FunctionOf<WD, DispatchClass, PF> { fn classify_dispatch(&self, _: Args) -> DispatchClass { - self.1.clone() + self.1 } } -impl<T, F> PaysFee<T> for FunctionOf<F> { - fn pays_fee(&self, _: T) -> bool { +// `ClassifyDispatch` as a raw value +impl<Args, WD, CD, PF> ClassifyDispatch<Args> for FunctionOf<WD, CD, PF> where + CD : Fn(Args) -> DispatchClass +{ + fn classify_dispatch(&self, args: Args) -> DispatchClass { + (self.1)(args) + } +} + +// `PaysFee` as a raw value +impl<Args, WD, CD> PaysFee<Args> for FunctionOf<WD, CD, bool> { + fn pays_fee(&self, _: Args) -> bool { self.2 } } +// `PaysFee` as a closure +impl<Args, WD, CD, PF> PaysFee<Args> for FunctionOf<WD, CD, PF> where + PF : Fn(Args) -> bool +{ + fn pays_fee(&self, args: Args) -> bool { + (self.2)(args) + } +} /// Implementation for unchecked extrinsic. impl<Address, Call, Signature, Extra> GetDispatchInfo