Improve call, and usage in pallet utility (#9418)

* WIP

* WIP

* WIP

* add some tests and limit

* remove wip test

* fmt

* Update bin/node/runtime/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* fmt

* use primitives allocation limit

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Guillaume Thiolliere
2021-08-07 11:34:25 +02:00
committed by GitHub
parent 27d4177f93
commit 38db14089b
17 changed files with 197 additions and 92 deletions
+27 -2
View File
@@ -112,13 +112,33 @@ pub mod pallet {
ItemCompleted,
}
#[pallet::extra_constants]
impl<T: Config> Pallet<T> {
/// The limit on the number of batched calls.
fn batched_calls_limit() -> u32 {
let allocator_limit = sp_core::MAX_POSSIBLE_ALLOCATION;
let call_size = core::mem::size_of::<<T as Config>::Call>() as u32;
// The margin to take into account vec doubling capacity.
let margin_factor = 3;
allocator_limit / margin_factor / call_size
}
}
#[pallet::error]
pub enum Error<T> {
/// Too many calls batched.
TooManyCalls,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Send a batch of dispatch calls.
///
/// May be called from any origin.
///
/// - `calls`: The calls to be dispatched from the same origin.
/// - `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`).
@@ -156,6 +176,8 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let is_root = ensure_root(origin.clone()).is_ok();
let calls_len = calls.len();
ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::<T>::TooManyCalls);
// Track the actual weight of each of the batch calls.
let mut weight: Weight = 0;
for (index, call) in calls.into_iter().enumerate() {
@@ -234,7 +256,8 @@ pub mod pallet {
///
/// May be called from any origin.
///
/// - `calls`: The calls to be dispatched from the same origin.
/// - `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`).
@@ -267,6 +290,8 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let is_root = ensure_root(origin.clone()).is_ok();
let calls_len = calls.len();
ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::<T>::TooManyCalls);
// Track the actual weight of each of the batch calls.
let mut weight: Weight = 0;
for (index, call) in calls.into_iter().enumerate() {
+12
View File
@@ -66,6 +66,9 @@ pub mod example {
Ok(end_weight.into())
}
}
#[weight = 0]
fn big_variant(_origin, _arg: [u8; 400]) {}
}
}
}
@@ -588,3 +591,12 @@ fn batch_all_does_not_nest() {
assert_eq!(Balances::free_balance(2), 10);
});
}
#[test]
fn batch_limit() {
new_test_ext().execute_with(|| {
let calls = vec![Call::System(SystemCall::remark(vec![])); 40_000];
assert_noop!(Utility::batch(Origin::signed(1), calls.clone()), Error::<Test>::TooManyCalls);
assert_noop!(Utility::batch_all(Origin::signed(1), calls), Error::<Test>::TooManyCalls);
});
}