diff --git a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs index 67877a05c79a..5eeeeead1400 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs @@ -69,6 +69,7 @@ impl pallet_message_queue::Config for Test { type HeapSize = HeapSize; type MaxStale = MaxStale; type ServiceWeight = ServiceWeight; + type IdleMaxServiceWeight = (); type QueuePausedQuery = (); } diff --git a/bridges/snowbridge/pallets/system/src/mock.rs b/bridges/snowbridge/pallets/system/src/mock.rs index 0312456c9823..687072a49e2e 100644 --- a/bridges/snowbridge/pallets/system/src/mock.rs +++ b/bridges/snowbridge/pallets/system/src/mock.rs @@ -148,6 +148,7 @@ impl pallet_message_queue::Config for Test { type HeapSize = HeapSize; type MaxStale = MaxStale; type ServiceWeight = ServiceWeight; + type IdleMaxServiceWeight = (); type QueuePausedQuery = (); } diff --git a/cumulus/pallets/parachain-system/src/mock.rs b/cumulus/pallets/parachain-system/src/mock.rs index 0b1d536ba7cd..fe89dfe68c67 100644 --- a/cumulus/pallets/parachain-system/src/mock.rs +++ b/cumulus/pallets/parachain-system/src/mock.rs @@ -125,6 +125,7 @@ impl pallet_message_queue::Config for Test { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MaxWeight; + type IdleMaxServiceWeight = (); type WeightInfo = (); } 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 689d8d56c48b..293416ab2a9a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -660,6 +660,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl parachain_info::Config for Runtime {} 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 48106b5f302d..e92e801e9f52 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -641,6 +641,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} 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 3980fa0d501a..f0aa4f8e91cc 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 @@ -387,6 +387,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} 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 9bdea6b9a7dd..3b759301d0ed 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 @@ -348,6 +348,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index d3f588bf25ff..e1c2e1a6237b 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -423,6 +423,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index e1586c7d9b29..ec0a5f6fc96c 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -318,6 +318,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 86eb5cdfcaf5..67f486893532 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -301,6 +301,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl parachain_info::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index c31e474cc2f1..609ea5a38a89 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -301,6 +301,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl parachain_info::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index cee17cdc7b05..ca1a915ba740 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -212,6 +212,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl parachain_info::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index cd5f1ad32728..7c9427a24939 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -282,6 +282,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; type WeightInfo = weights::pallet_message_queue::WeightInfo; } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index e840a40f5acd..3e331e5e8ebf 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -282,6 +282,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; type WeightInfo = weights::pallet_message_queue::WeightInfo; } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index 0f4957fd802b..ad79d6849bd5 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -232,6 +232,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 1d404feac3db..0a55d2dcfe53 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -540,6 +540,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index c60061419817..034d16267d45 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -320,6 +320,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); } impl cumulus_pallet_aura_ext::Config for Runtime {} diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index 7ed62a392e4e..461b9f4b431a 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -365,6 +365,7 @@ impl pallet_message_queue::Config for Test { type HeapSize = ConstU32<65536>; type MaxStale = ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); } parameter_types! { diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 8c8abe97ede2..c41ffdbe72db 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -987,6 +987,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = MessageQueueHeapSize; type MaxStale = MessageQueueMaxStale; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; #[cfg(not(feature = "runtime-benchmarks"))] type MessageProcessor = MessageProcessor; #[cfg(feature = "runtime-benchmarks")] diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 02397f35368e..e6381513170f 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1190,6 +1190,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = MessageQueueHeapSize; type MaxStale = MessageQueueMaxStale; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = MessageQueueServiceWeight; #[cfg(not(feature = "runtime-benchmarks"))] type MessageProcessor = MessageProcessor; #[cfg(feature = "runtime-benchmarks")] diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 377c77f30a47..286d0038e187 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -275,6 +275,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = MessageQueueHeapSize; type MaxStale = MessageQueueMaxStale; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); type MessageProcessor = MessageProcessor; type QueueChangeHandler = (); type QueuePausedQuery = (); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index 3224df66cbe5..6790b535d169 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -232,6 +232,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = MessageQueueHeapSize; type MaxStale = MessageQueueMaxStale; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); #[cfg(not(feature = "runtime-benchmarks"))] type MessageProcessor = MessageProcessor; #[cfg(feature = "runtime-benchmarks")] diff --git a/prdoc/pr_3844.prdoc b/prdoc/pr_3844.prdoc new file mode 100644 index 000000000000..a92092f91b20 --- /dev/null +++ b/prdoc/pr_3844.prdoc @@ -0,0 +1,25 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Add the ability for MessageQueue to process enqueued messages on idle + +doc: + - audience: Runtime Dev + description: | + Add the option to use remaining weight on idle for processing enqueued messages. + This will increase the chances of the messages enqueued during inherent extrinsics to be processed in the same block. + New config types is added on the message-queue `Config` trait: + - `IdleMaxServiceWeight` + + example: + ```rust + parameter_types! { + // The maximum weight to be used from remaining weight for processing enqueued messages on idle + pub const IdleMaxServiceWeight: Weight = Some(Weight); + } + + type IdleMaxServiceWeight = IdleMaxServiceWeight; // or `()` to not use this feature + ``` + +crates: + - name: pallet-message-queue diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index ca7e14f6eb16..a9606ac0bb75 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1303,6 +1303,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = ConstU32<{ 64 * 1024 }>; type MaxStale = ConstU32<128>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); } parameter_types! { diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index e2a8d3d1337b..470304ed357e 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -225,6 +225,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = MessageQueueHeapSize; type MaxStale = MessageQueueMaxStale; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); type MessageProcessor = MessageProcessor; type QueueChangeHandler = (); type WeightInfo = (); diff --git a/substrate/frame/message-queue/src/integration_test.rs b/substrate/frame/message-queue/src/integration_test.rs index 26a330cc88e8..14b8d2217eb2 100644 --- a/substrate/frame/message-queue/src/integration_test.rs +++ b/substrate/frame/message-queue/src/integration_test.rs @@ -73,6 +73,7 @@ impl Config for Test { type HeapSize = HeapSize; type MaxStale = MaxStale; type ServiceWeight = ServiceWeight; + type IdleMaxServiceWeight = (); } /// Simulates heavy usage by enqueueing and processing large amounts of messages. diff --git a/substrate/frame/message-queue/src/lib.rs b/substrate/frame/message-queue/src/lib.rs index 93cd760eeb96..ec85c785f79e 100644 --- a/substrate/frame/message-queue/src/lib.rs +++ b/substrate/frame/message-queue/src/lib.rs @@ -525,12 +525,21 @@ pub mod pallet { type MaxStale: Get; /// The amount of weight (if any) which should be provided to the message queue for - /// servicing enqueued items. + /// servicing enqueued items `on_initialize`. /// /// This may be legitimately `None` in the case that you will call - /// `ServiceQueues::service_queues` manually. + /// `ServiceQueues::service_queues` manually or set [`Self::IdleMaxServiceWeight`] to have + /// it run in `on_idle`. #[pallet::constant] type ServiceWeight: Get>; + + /// The maximum amount of weight (if any) to be used from remaining weight `on_idle` which + /// should be provided to the message queue for servicing enqueued items `on_idle`. + /// Useful for parachains to process messages at the same block they are received. + /// + /// If `None`, it will not call `ServiceQueues::service_queues` in `on_idle`. + #[pallet::constant] + type IdleMaxServiceWeight: Get>; } #[pallet::event] @@ -643,6 +652,15 @@ pub mod pallet { } } + fn on_idle(_n: BlockNumberFor, remaining_weight: Weight) -> Weight { + if let Some(weight_limit) = T::IdleMaxServiceWeight::get() { + // Make use of the remaining weight to process enqueued messages. + Self::service_queues(weight_limit.min(remaining_weight)) + } else { + Weight::zero() + } + } + #[cfg(feature = "try-runtime")] fn try_state(_: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { Self::do_try_state() diff --git a/substrate/frame/message-queue/src/mock.rs b/substrate/frame/message-queue/src/mock.rs index f22f318b8ef1..1281de6b0a66 100644 --- a/substrate/frame/message-queue/src/mock.rs +++ b/substrate/frame/message-queue/src/mock.rs @@ -56,6 +56,7 @@ impl Config for Test { type HeapSize = HeapSize; type MaxStale = MaxStale; type ServiceWeight = ServiceWeight; + type IdleMaxServiceWeight = ServiceWeight; } /// Mocked `WeightInfo` impl with allows to set the weight per call. diff --git a/substrate/frame/message-queue/src/tests.rs b/substrate/frame/message-queue/src/tests.rs index 1f6e7777f012..d6788847d571 100644 --- a/substrate/frame/message-queue/src/tests.rs +++ b/substrate/frame/message-queue/src/tests.rs @@ -1838,3 +1838,45 @@ fn with_service_mutex_works() { with_service_mutex(|| called = 3).unwrap(); assert_eq!(called, 3); } + +#[test] +fn process_enqueued_on_idle() { + use MessageOrigin::*; + build_and_execute::(|| { + // Some messages enqueued on previous block. + MessageQueue::enqueue_messages(vec![msg("a"), msg("ab"), msg("abc")].into_iter(), Here); + assert_eq!(BookStateFor::::iter().count(), 1); + + // Process enqueued messages from previous block. + Pallet::::on_initialize(1); + assert_eq!( + MessagesProcessed::take(), + vec![(b"a".to_vec(), Here), (b"ab".to_vec(), Here), (b"abc".to_vec(), Here),] + ); + + MessageQueue::enqueue_messages(vec![msg("x"), msg("xy"), msg("xyz")].into_iter(), There); + assert_eq!(BookStateFor::::iter().count(), 2); + + // Enough weight to process on idle. + Pallet::::on_idle(1, Weight::from_parts(100, 100)); + assert_eq!( + MessagesProcessed::take(), + vec![(b"x".to_vec(), There), (b"xy".to_vec(), There), (b"xyz".to_vec(), There)] + ); + }) +} + +#[test] +fn process_enqueued_on_idle_requires_enough_weight() { + use MessageOrigin::*; + build_and_execute::(|| { + Pallet::::on_initialize(1); + + MessageQueue::enqueue_messages(vec![msg("x"), msg("xy"), msg("xyz")].into_iter(), There); + assert_eq!(BookStateFor::::iter().count(), 1); + + // Not enough weight to process on idle. + Pallet::::on_idle(1, Weight::from_parts(0, 0)); + assert_eq!(MessagesProcessed::take(), vec![]); + }) +} diff --git a/templates/parachain/runtime/src/lib.rs b/templates/parachain/runtime/src/lib.rs index ad21b79a5b1b..88b0f5a14749 100644 --- a/templates/parachain/runtime/src/lib.rs +++ b/templates/parachain/runtime/src/lib.rs @@ -414,6 +414,7 @@ impl pallet_message_queue::Config for Runtime { type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; + type IdleMaxServiceWeight = (); } impl cumulus_pallet_aura_ext::Config for Runtime {}