diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index b6f3ccd3901b..ce40c633388e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -474,6 +474,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 21368e9c2b4b..eb714533036a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -473,6 +473,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index d87ff9b43fef..629de51b9749 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -543,6 +543,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index ae3dbfa06cba..b140bacdfb9d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -520,6 +520,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index f4c62f212e8c..a04e10247149 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -265,6 +265,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 2951662a979b..a58543c541d0 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -275,6 +275,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = pallet_utility::weights::SubstrateWeight; } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index ae3ad93a9e85..7a79e9bf8365 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -585,6 +585,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 39ea39f25a8b..c5f1f8b9132a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -586,6 +586,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index dc5f2ac0997c..31deb27facda 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -528,6 +528,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 1b9a3b60a2c4..69ffcc3b72a3 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -527,6 +527,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/docker/dockerfiles/polkadot/polkadot_injected.Dockerfile b/docker/dockerfiles/polkadot/polkadot_injected.Dockerfile index 3dbede4966a8..a148275f132f 100644 --- a/docker/dockerfiles/polkadot/polkadot_injected.Dockerfile +++ b/docker/dockerfiles/polkadot/polkadot_injected.Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/parity/base-bin +FROM ubuntu:22.04 # metadata ARG VCS_REF @@ -22,6 +22,8 @@ ENV RUST_BACKTRACE 1 USER root WORKDIR /app +RUN useradd -ms /bin/sh parity + # add polkadot and polkadot-*-worker binaries to the docker image COPY bin/* /usr/local/bin/ COPY entrypoint.sh . diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index c832ace91c07..8cadb6cfcb4c 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -748,6 +748,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index f25ed33012a2..a83ded498f5c 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -985,6 +985,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = weights::pallet_utility::WeightInfo; } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index faffcd23fbcf..84b4670242d5 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -374,6 +374,7 @@ impl pallet_utility::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = pallet_utility::weights::SubstrateWeight; } diff --git a/substrate/frame/utility/README.md b/substrate/frame/utility/README.md index 0a6769ae1c7c..8dcd91984bac 100644 --- a/substrate/frame/utility/README.md +++ b/substrate/frame/utility/README.md @@ -22,6 +22,9 @@ This module contains two basic pieces of functionality: Since proxy filters are respected in all dispatches of this module, it should never need to be filtered by any proxy. +Pre- and post-hooks can be configured via `BatchHook` associated type. +They are triggered for each batch call: `batch`, `batch_all`, and `force_batch`. Use the unit type `()` if no behavior is required. + ## Interface ### Dispatchable Functions diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs index 26c38d1f0459..f1aa669b9e34 100644 --- a/substrate/frame/utility/src/lib.rs +++ b/substrate/frame/utility/src/lib.rs @@ -39,6 +39,10 @@ //! Since proxy filters are respected in all dispatches of this pallet, it should never need to be //! filtered by any proxy. //! +//! Pre- and post-hooks can be configured via `BatchHook` associated type. +//! They are triggered for each batch call: `batch`, `batch_all`, and `force_batch`. +//! Use the unit type `()` if no behavior is required. +//! //! ## Interface //! //! ### Dispatchable Functions @@ -68,9 +72,30 @@ use sp_core::TypeId; use sp_io::hashing::blake2_256; use sp_runtime::traits::{BadOrigin, Dispatchable, TrailingZeroInput}; pub use weights::WeightInfo; - pub use pallet::*; +/// Hooks that will be called for `batch` calls. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait BatchHook { + /// Will be called before a batch is executed. + fn on_batch_start() -> sp_runtime::DispatchResult; + /// Will be called after the batch was executed. + /// + /// Depending on the exact batch call used, it may not be called when a batch item failed. + fn on_batch_end() -> sp_runtime::DispatchResult; +} + +impl BatchHook for () { + fn on_batch_start() -> sp_runtime::DispatchResult { + Ok(()) + } + + fn on_batch_end() -> sp_runtime::DispatchResult { + Ok(()) + } + +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -100,6 +125,9 @@ pub mod pallet { Into<::RuntimeOrigin> + IsType<<::RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin>; + /// Hook to be called before any batch operation. + type BatchHook: BatchHook; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -196,6 +224,8 @@ pub mod pallet { return Err(BadOrigin.into()) } + T::BatchHook::on_batch_start()?; + let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::::TooManyCalls); @@ -225,6 +255,9 @@ pub mod pallet { Self::deposit_event(Event::ItemCompleted); } Self::deposit_event(Event::BatchCompleted); + + T::BatchHook::on_batch_end()?; + let base_weight = T::WeightInfo::batch(calls_len as u32); Ok(Some(base_weight.saturating_add(weight)).into()) } @@ -305,6 +338,8 @@ pub mod pallet { return Err(BadOrigin.into()) } + T::BatchHook::on_batch_start()?; + let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::::TooManyCalls); @@ -339,6 +374,9 @@ pub mod pallet { Self::deposit_event(Event::ItemCompleted); } Self::deposit_event(Event::BatchCompleted); + + T::BatchHook::on_batch_end()?; + let base_weight = T::WeightInfo::batch_all(calls_len as u32); Ok(Some(base_weight.saturating_add(weight)).into()) } @@ -401,6 +439,8 @@ pub mod pallet { return Err(BadOrigin.into()) } + T::BatchHook::on_batch_start()?; + let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::::TooManyCalls); @@ -431,6 +471,9 @@ pub mod pallet { } else { Self::deposit_event(Event::BatchCompleted); } + + T::BatchHook::on_batch_end()?; + let base_weight = T::WeightInfo::batch(calls_len as u32); Ok(Some(base_weight.saturating_add(weight)).into()) } diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index 274a90d77cf0..7cc0da7d22f7 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -222,6 +222,7 @@ impl Config for Test { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type BatchHook = (); type WeightInfo = (); }