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

Utility: add more tests for batch/batchAll/forceBatch #12506

Merged
merged 16 commits into from
Oct 28, 2022
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions frame/utility/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sp-std = { version = "4.0.0", default-features = false, path = "../../primitives

[dev-dependencies]
pallet-balances = { version = "4.0.0-dev", path = "../balances" }
pallet-timestamp = { version = "4.0.0-dev", path = "../timestamp" }
sp-core = { version = "6.0.0", path = "../../primitives/core" }

[features]
Expand Down
12 changes: 6 additions & 6 deletions frame/utility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
/// Send a batch of dispatch calls.
///
/// May be called from any origin.
/// May be called from either the root or a signed origin.
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
///
/// - `calls`: The calls to be dispatched from the same origin. The number of call must not
/// exceed the constant: `batched_calls_limit` (available in constant metadata).
///
/// If origin is root then call are dispatch without checking origin filter. (This includes
/// bypassing `frame_system::Config::BaseCallFilter`).
/// If origin is root then the calls are dispatched without checking origin filter. (This
/// includes bypassing `frame_system::Config::BaseCallFilter`).
///
/// # <weight>
/// - Complexity: O(C) where C is the number of calls to be batched.
Expand Down Expand Up @@ -291,13 +291,13 @@ pub mod pallet {
/// Send a batch of dispatch calls and atomically execute them.
/// The whole transaction will rollback and fail if any of the calls failed.
///
/// May be called from any origin.
/// May be called from either the root or a signed origin.
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
///
/// - `calls`: The calls to be dispatched from the same origin. The number of call must not
/// exceed the constant: `batched_calls_limit` (available in constant metadata).
///
/// If origin is root then call are dispatch without checking origin filter. (This includes
/// bypassing `frame_system::Config::BaseCallFilter`).
/// If origin is root then the calls are dispatched without checking origin filter. (This
/// includes bypassing `frame_system::Config::BaseCallFilter`).
///
/// # <weight>
/// - Complexity: O(C) where C is the number of calls to be batched.
Expand Down
61 changes: 61 additions & 0 deletions frame/utility/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ frame_support::construct_runtime!(
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Timestamp: pallet_timestamp::{Call, Inherent},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
Utility: utility::{Pallet, Call, Event},
Example: example::{Pallet, Call},
Expand Down Expand Up @@ -140,6 +141,13 @@ impl pallet_balances::Config for Test {
type AccountStore = System;
type WeightInfo = ();
}

impl pallet_timestamp::Config for Test {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = ConstU64<3>;
type WeightInfo = ();
}
parameter_types! {
pub const MultisigDepositBase: u64 = 1;
pub const MultisigDepositFactor: u64 = 1;
Expand Down Expand Up @@ -175,6 +183,7 @@ type UtilityCall = crate::Call<Test>;

use frame_system::Call as SystemCall;
use pallet_balances::{Call as BalancesCall, Error as BalancesError};
use pallet_timestamp::Call as TimestampCall;

pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
Expand Down Expand Up @@ -679,3 +688,55 @@ fn none_origin_does_not_work() {
assert_noop!(Utility::batch_all(RuntimeOrigin::none(), vec![]), BadOrigin);
})
}

#[test]
fn batch_doesnt_work_with_inherents() {
new_test_ext().execute_with(|| {
// fails because inherents expect the origin to be none.
assert_ok!(Utility::batch(
RuntimeOrigin::signed(1),
vec![RuntimeCall::Timestamp(TimestampCall::set { now: 42 }),]
));
System::assert_last_event(
utility::Event::BatchInterrupted {
index: 0,
error: frame_system::Error::<Test>::CallFiltered.into(),
}
.into(),
);
})
}

#[test]
fn force_batch_doesnt_work_with_inherents() {
new_test_ext().execute_with(|| {
// fails because inherents expect the origin to be none.
assert_ok!(Utility::force_batch(
RuntimeOrigin::root(),
vec![RuntimeCall::Timestamp(TimestampCall::set { now: 42 }),]
));
System::assert_last_event(utility::Event::BatchCompletedWithErrors.into());
})
}

#[test]
fn batch_all_doesnt_work_with_inherents() {
new_test_ext().execute_with(|| {
let batch_all = RuntimeCall::Utility(UtilityCall::batch_all {
calls: vec![RuntimeCall::Timestamp(TimestampCall::set { now: 42 })],
});
let info = batch_all.get_dispatch_info();

// fails because inherents expect the origin to be none.
assert_noop!(
batch_all.dispatch(RuntimeOrigin::signed(1)),
DispatchErrorWithPostInfo {
post_info: PostDispatchInfo {
actual_weight: Some(info.weight),
pays_fee: Pays::Yes
},
error: frame_system::Error::<Test>::CallFiltered.into(),
}
);
})
}