mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 05:07:55 +00:00
Add passthrough weight to Sudo (#4946)
* Add passthrough weight to Sudo * Bump spec version * Passthrough `pays_fee` * Sudo always pays fee * Use `FunctionOf` * Add support for closure in dispatch classification * Update docs
This commit is contained in:
@@ -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`
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
impl<Args, F> WeighData<Args> for FunctionOf<F>
|
||||
where
|
||||
F : Fn(Args) -> Weight
|
||||
// `WeighData` as a raw value
|
||||
impl<Args, CD, PF> WeighData<Args> for FunctionOf<Weight, CD, PF> {
|
||||
fn weigh_data(&self, _: Args) -> Weight {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
// `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
|
||||
|
||||
Reference in New Issue
Block a user