Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

implement dispatch_as #9934

Merged
merged 11 commits into from
Nov 4, 2021
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ impl pallet_randomness_collective_flip::Config for Runtime {}
impl pallet_utility::Config for Runtime {
type Event = Event;
type Call = Call;
type PalletsOrigin = OriginCaller;
type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
}

Expand Down
1 change: 1 addition & 0 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ impl pallet_timestamp::Config for Test {
impl pallet_utility::Config for Test {
type Event = Event;
type Call = Call;
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
}
parameter_types! {
Expand Down
1 change: 1 addition & 0 deletions frame/proxy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl pallet_balances::Config for Test {
impl pallet_utility::Config for Test {
type Event = Event;
type Call = Call;
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
}
parameter_types! {
Expand Down
9 changes: 9 additions & 0 deletions frame/utility/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) {
}

benchmarks! {
where_clause { where <T::Origin as frame_support::traits::OriginTrait>::PalletsOrigin: Clone }
batch {
let c in 0 .. 1000;
let mut calls: Vec<<T as Config>::Call> = Vec::new();
Expand Down Expand Up @@ -64,5 +65,13 @@ benchmarks! {
assert_last_event::<T>(Event::BatchCompleted.into())
}

dispatch_as {
let caller = account("caller", SEED, SEED);
let call = Box::new(frame_system::Call::remark { remark: vec![] }.into());
let origin: T::Origin = RawOrigin::Signed(caller).into();
let pallets_origin: <T::Origin as frame_support::traits::OriginTrait>::PalletsOrigin = origin.caller().clone();
let pallets_origin = Into::<T::PalletsOrigin>::into(pallets_origin.clone());
}: _(RawOrigin::Root, Box::new(pallets_origin), call)

impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test);
}
38 changes: 38 additions & 0 deletions frame/utility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ pub mod pallet {
+ IsSubType<Call<Self>>
+ IsType<<Self as frame_system::Config>::Call>;

/// The caller origin, overarching type of all pallets origins.
type PalletsOrigin: Parameter +
Into<<Self as frame_system::Config>::Origin> +
IsType<<<Self as frame_system::Config>::Origin as frame_support::traits::OriginTrait>::PalletsOrigin>;

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
Expand All @@ -110,6 +115,8 @@ pub mod pallet {
BatchCompleted,
/// A single item within a Batch of dispatches has completed with no error.
ItemCompleted,
/// A call was dispatched. \[result\]
DispatchedAs(DispatchResult),
}

// Align the call size to 1KB. As we are currently compiling the runtime for native/wasm
Expand Down Expand Up @@ -342,6 +349,37 @@ pub mod pallet {
let base_weight = T::WeightInfo::batch_all(calls_len as u32);
Ok(Some(base_weight + weight).into())
}

/// Dispatches a function call with a provided origin.
///
/// The dispatch origin for this call must be _Root_.
///
/// # <weight>
/// - O(1).
/// - Limited storage reads.
/// - One DB write (event).
/// - Weight of derivative `call` execution + T::WeightInfo::dispatch_as().
/// # </weight>
#[pallet::weight({
let dispatch_info = call.get_dispatch_info();
(
T::WeightInfo::dispatch_as()
.saturating_add(dispatch_info.weight),
dispatch_info.class,
)
})]
pub fn dispatch_as(
origin: OriginFor<T>,
as_origin: Box<T::PalletsOrigin>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to box it? It wasn't boxed before you added the benchmark. We should solve it there when possible.

Copy link
Contributor Author

@xlc xlc Oct 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is generally good idea to box big data structure in call parameter to avoid increase the Call enum size. the same reason box is used elsewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I thought it was related to the benchmarks. Didn't know that this is a big argument, though.

call: Box<<T as Config>::Call>,
) -> DispatchResult {
ensure_root(origin)?;

let res = call.dispatch_bypass_filter((*as_origin).into());

Self::deposit_event(Event::DispatchedAs(res.map(|_| ()).map_err(|e| e.error)));
Ok(())
}
}
}

Expand Down
1 change: 1 addition & 0 deletions frame/utility/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ impl Contains<Call> for TestBaseCallFilter {
impl Config for Test {
type Event = Event;
type Call = Call;
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
}

Expand Down
33 changes: 20 additions & 13 deletions frame/utility/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! Autogenerated weights for pallet_utility
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2021-08-07, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2021-10-30, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128

// Executed Command:
Expand Down Expand Up @@ -48,39 +48,46 @@ pub trait WeightInfo {
fn batch(c: u32, ) -> Weight;
fn as_derivative() -> Weight;
fn batch_all(c: u32, ) -> Weight;
fn dispatch_as() -> Weight;
}

/// Weights for pallet_utility using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
fn batch(c: u32, ) -> Weight {
(30_319_000 as Weight)
(18_293_000 as Weight)
// Standard Error: 3_000
.saturating_add((6_759_000 as Weight).saturating_mul(c as Weight))
.saturating_add((5_530_000 as Weight).saturating_mul(c as Weight))
}
fn as_derivative() -> Weight {
(4_030_000 as Weight)
(3_387_000 as Weight)
}
fn batch_all(c: u32, ) -> Weight {
(26_621_000 as Weight)
// Standard Error: 3_000
.saturating_add((7_251_000 as Weight).saturating_mul(c as Weight))
(19_223_000 as Weight)
// Standard Error: 4_000
.saturating_add((5_998_000 as Weight).saturating_mul(c as Weight))
}
fn dispatch_as() -> Weight {
(14_340_000 as Weight)
}
}

// For backwards compatibility and tests
impl WeightInfo for () {
fn batch(c: u32, ) -> Weight {
(30_319_000 as Weight)
(18_293_000 as Weight)
// Standard Error: 3_000
.saturating_add((6_759_000 as Weight).saturating_mul(c as Weight))
.saturating_add((5_530_000 as Weight).saturating_mul(c as Weight))
}
fn as_derivative() -> Weight {
(4_030_000 as Weight)
(3_387_000 as Weight)
}
fn batch_all(c: u32, ) -> Weight {
(26_621_000 as Weight)
// Standard Error: 3_000
.saturating_add((7_251_000 as Weight).saturating_mul(c as Weight))
(19_223_000 as Weight)
// Standard Error: 4_000
.saturating_add((5_998_000 as Weight).saturating_mul(c as Weight))
}
fn dispatch_as() -> Weight {
(14_340_000 as Weight)
}
}