Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #219 #7407

Merged
merged 14 commits into from
Feb 18, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 1_745
.saturating_add(Weight::from_parts(6_562_902, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 3_765
.saturating_add(Weight::from_parts(6_028_416, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 1_601
.saturating_add(Weight::from_parts(5_138_293, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 1_601
.saturating_add(Weight::from_parts(5_138_293, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 1_395
.saturating_add(Weight::from_parts(5_000_971, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 1_621
.saturating_add(Weight::from_parts(3_312_302, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 740
.saturating_add(Weight::from_parts(2_800_888, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 3_915
.saturating_add(Weight::from_parts(4_372_646, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 7_605
.saturating_add(Weight::from_parts(4_306_193, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
5 changes: 5 additions & 0 deletions polkadot/runtime/rococo/src/weights/pallet_utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 460
.saturating_add(Weight::from_parts(3_173_577, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
5 changes: 5 additions & 0 deletions polkadot/runtime/westend/src/weights/pallet_utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
// Standard Error: 2_817
.saturating_add(Weight::from_parts(5_113_539, 0).saturating_mul(c.into()))
}

fn dispatch_as_fallible() -> Weight {
Default::default()
}

fn if_else() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
Expand Down
40 changes: 40 additions & 0 deletions prdoc/pr_7407.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
title: 'Fixes #219'
doc:
- audience: Runtime Dev
description: |-
Add a new extrinsic `dispatch_as_fallible`.

It's almost the same as `dispatch_as` but check the result of the call.

Closes #219.

And add more unit tests to cover `dispatch_as` and `dispatch_as_fallible`.

---

Polkadot address: 156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y
crates:
- name: asset-hub-rococo-runtime
bump: minor
- name: asset-hub-westend-runtime
bump: minor
- name: bridge-hub-rococo-runtime
bump: minor
- name: bridge-hub-westend-runtime
bump: minor
- name: collectives-westend-runtime
bump: minor
- name: coretime-rococo-runtime
bump: minor
- name: coretime-westend-runtime
bump: minor
- name: people-rococo-runtime
bump: minor
- name: people-westend-runtime
bump: minor
- name: rococo-runtime
bump: minor
- name: westend-runtime
bump: minor
- name: pallet-utility
bump: minor
12 changes: 12 additions & 0 deletions substrate/frame/utility/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ mod benchmark {
assert_last_event::<T>(Event::BatchCompleted.into());
}

#[benchmark]
fn dispatch_as_fallible() {
let caller = account("caller", SEED, SEED);
let call = Box::new(frame_system::Call::remark { remark: vec![] }.into());
let origin: T::RuntimeOrigin = RawOrigin::Signed(caller).into();
let pallets_origin = origin.caller().clone();
let pallets_origin = T::PalletsOrigin::from(pallets_origin);

#[extrinsic_call]
_(RawOrigin::Root, Box::new(pallets_origin), call);
}

#[benchmark]
fn if_else() {
// Failing main call.
Expand Down
28 changes: 28 additions & 0 deletions substrate/frame/utility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,34 @@ pub mod pallet {
post_info: Some(weight).into(),
})
}

/// Dispatches a function call with a provided origin.
///
/// Almost the same as [`Pallet::dispatch_as`] but forwards any error of the inner call.
///
/// The dispatch origin for this call must be _Root_.
#[pallet::call_index(7)]
#[pallet::weight({
let dispatch_info = call.get_dispatch_info();
(
T::WeightInfo::dispatch_as_fallible()
.saturating_add(dispatch_info.call_weight),
dispatch_info.class,
)
})]
pub fn dispatch_as_fallible(
origin: OriginFor<T>,
as_origin: Box<T::PalletsOrigin>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResult {
ensure_root(origin)?;

call.dispatch_bypass_filter((*as_origin).into()).map_err(|e| e.error)?;

Self::deposit_event(Event::DispatchedAs { result: Ok(()) });

Ok(())
}
}

impl<T: Config> Pallet<T> {
Expand Down
60 changes: 60 additions & 0 deletions substrate/frame/utility/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ fn call_foobar(err: bool, start_weight: Weight, end_weight: Option<Weight>) -> R
RuntimeCall::Example(ExampleCall::foobar { err, start_weight, end_weight })
}

fn utility_events() -> Vec<Event> {
System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| if let RuntimeEvent::Utility(inner) = e { Some(inner) } else { None })
.collect()
}

#[test]
fn as_derivative_works() {
new_test_ext().execute_with(|| {
Expand Down Expand Up @@ -916,6 +924,33 @@ fn with_weight_works() {
})
}

#[test]
fn dispatch_as_works() {
new_test_ext().execute_with(|| {
Balances::force_set_balance(RuntimeOrigin::root(), 666, 100).unwrap();
assert_eq!(Balances::free_balance(666), 100);
assert_eq!(Balances::free_balance(777), 0);
assert_ok!(Utility::dispatch_as(
RuntimeOrigin::root(),
Box::new(OriginCaller::system(frame_system::RawOrigin::Signed(666))),
Box::new(call_transfer(777, 100))
));
assert_eq!(Balances::free_balance(666), 0);
assert_eq!(Balances::free_balance(777), 100);

System::reset_events();
assert_ok!(Utility::dispatch_as(
RuntimeOrigin::root(),
Box::new(OriginCaller::system(frame_system::RawOrigin::Signed(777))),
Box::new(RuntimeCall::Timestamp(TimestampCall::set { now: 0 }))
));
assert_eq!(
utility_events(),
vec![Event::DispatchedAs { result: Err(DispatchError::BadOrigin) }]
);
})
}

#[test]
fn if_else_with_root_works() {
new_test_ext().execute_with(|| {
Expand Down Expand Up @@ -983,6 +1018,31 @@ fn if_else_successful_main_call() {
})
}

#[test]
fn dispatch_as_fallible_works() {
new_test_ext().execute_with(|| {
Balances::force_set_balance(RuntimeOrigin::root(), 666, 100).unwrap();
assert_eq!(Balances::free_balance(666), 100);
assert_eq!(Balances::free_balance(777), 0);
assert_ok!(Utility::dispatch_as_fallible(
RuntimeOrigin::root(),
Box::new(OriginCaller::system(frame_system::RawOrigin::Signed(666))),
Box::new(call_transfer(777, 100))
));
assert_eq!(Balances::free_balance(666), 0);
assert_eq!(Balances::free_balance(777), 100);

assert_noop!(
Utility::dispatch_as_fallible(
RuntimeOrigin::root(),
Box::new(OriginCaller::system(frame_system::RawOrigin::Signed(777))),
Box::new(RuntimeCall::Timestamp(TimestampCall::set { now: 0 }))
),
DispatchError::BadOrigin,
);
})
}

#[test]
fn if_else_failing_fallback_call() {
new_test_ext().execute_with(|| {
Expand Down
10 changes: 10 additions & 0 deletions substrate/frame/utility/src/weights.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading