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
2 changes: 1 addition & 1 deletion frame/support/src/traits/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub trait OriginTrait: Sized {
type Call;

/// The caller origin, overarching type of all pallets origins.
type PalletsOrigin;
type PalletsOrigin: Clone;
xlc marked this conversation as resolved.
Show resolved Hide resolved

/// The AccountId used across the system.
type AccountId;
Expand Down
8 changes: 8 additions & 0 deletions frame/utility/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,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();
xlc marked this conversation as resolved.
Show resolved Hide resolved
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);
}
40 changes: 40 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),
}

#[pallet::extra_constants]
Expand Down Expand Up @@ -323,6 +330,39 @@ 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)
// AccountData for inner call origin accountdata.
.saturating_add(T::DbWeight::get().reads_writes(1, 1)),
xlc marked this conversation as resolved.
Show resolved Hide resolved
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
7 changes: 7 additions & 0 deletions frame/utility/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ 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.
Expand All @@ -66,6 +67,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Standard Error: 3_000
.saturating_add((7_251_000 as Weight).saturating_mul(c as Weight))
}
fn dispatch_as() -> Weight {
(4_030_000 as Weight)
}
}

// For backwards compatibility and tests
Expand All @@ -83,4 +87,7 @@ impl WeightInfo for () {
// Standard Error: 3_000
.saturating_add((7_251_000 as Weight).saturating_mul(c as Weight))
}
fn dispatch_as() -> Weight {
(4_030_000 as Weight)
}
}