Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

4 changes: 3 additions & 1 deletion cumulus/xcm/xcm-emulator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pallet-balances.default-features = true
pallet-balances.workspace = true
pallet-message-queue.default-features = true
pallet-message-queue.workspace = true
pallet-timestamp.default-features = true
pallet-timestamp.workspace = true
parachains-common.default-features = true
parachains-common.workspace = true
paste = { workspace = true, default-features = true }
Expand All @@ -56,4 +58,4 @@ sp-tracing.workspace = true
xcm-executor.default-features = true
xcm-executor.workspace = true
xcm.default-features = true
xcm.workspace = true
xcm.workspace = true
Comment thread
bkontur marked this conversation as resolved.
Outdated
67 changes: 50 additions & 17 deletions cumulus/xcm/xcm-emulator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ pub use cumulus_primitives_core::AggregateMessageOrigin as CumulusAggregateMessa
pub use frame_support::{
assert_ok,
sp_runtime::{
traits::{Convert, Dispatchable, Header as HeaderT},
traits::{Convert, Dispatchable, Header as HeaderT, Zero},
Digest, DispatchResult,
},
traits::{
EnqueueMessage, ExecuteOverweightError, Get, Hooks, OnInitialize, OriginTrait,
ProcessMessage, ProcessMessageError, ServiceQueues,
EnqueueMessage, ExecuteOverweightError, Get, Hooks, OnFinalize, OnIdle, OnInitialize,
OriginTrait, ProcessMessage, ProcessMessageError, ServiceQueues,
},
weights::{Weight, WeightMeter},
};
pub use frame_system::{
pallet_prelude::BlockNumberFor, Config as SystemConfig, Pallet as SystemPallet,
limits::BlockWeights as BlockWeightsLimits, pallet_prelude::BlockNumberFor,
Config as SystemConfig, Pallet as SystemPallet,
};
pub use pallet_balances::AccountData;
pub use pallet_message_queue;
pub use pallet_timestamp::Call as TimestampCall;
pub use sp_arithmetic::traits::Bounded;
pub use sp_core::{
crypto::get_public_from_string_or_panic, parameter_types, sr25519, storage::Storage, Pair,
Expand All @@ -61,7 +63,9 @@ pub use sp_runtime::BoundedSlice;
pub use sp_tracing;

// Cumulus
pub use cumulus_pallet_parachain_system::Pallet as ParachainSystemPallet;
pub use cumulus_pallet_parachain_system::{
Call as ParachainSystemCall, Pallet as ParachainSystemPallet,
};
pub use cumulus_primitives_core::{
relay_chain::{BlockNumber as RelayBlockNumber, HeadData, HrmpChannelId},
AbridgedHrmpChannel, DmpMessageHandler, ParaId, PersistedValidationData, XcmpMessageHandler,
Expand Down Expand Up @@ -263,7 +267,7 @@ pub trait Parachain: Chain {
type ParachainInfo: Get<ParaId>;
type ParachainSystem;
type MessageProcessor: ProcessMessage + ServiceQueues;
type DigestProvider: sp_runtime::traits::Convert<BlockNumberFor<Self::Runtime>, Digest>;
type DigestProvider: Convert<BlockNumberFor<Self::Runtime>, Digest>;

fn init();

Expand Down Expand Up @@ -645,7 +649,8 @@ macro_rules! decl_test_parachains {
// We run an empty block during initialisation to open HRMP channels
// and have them ready for the next block
fn init() {
use $crate::{Chain, HeadData, Network, Hooks, Encode, Parachain, TestExt};
use $crate::{Chain, TestExt};

// Initialize the thread local variable
$crate::paste::paste! {
[<LOCAL_EXT_ $name:upper>].with(|v| *v.borrow_mut() = Self::build_new_ext($genesis));
Expand All @@ -659,7 +664,9 @@ macro_rules! decl_test_parachains {
}

fn new_block() {
use $crate::{Chain, Convert, HeadData, Network, Hooks, Encode, Parachain, TestExt};
use $crate::{
Dispatchable, Chain, Convert, TestExt, Zero,
};

let para_id = Self::para_id().into();

Expand All @@ -680,32 +687,58 @@ macro_rules! decl_test_parachains {
.clone()
);

// Initialze `System`.
let digest = <Self as Parachain>::DigestProvider::convert(block_number);

<Self as Chain>::System::initialize(&block_number, &parent_head_data.hash(), &digest);
<<Self as Parachain>::ParachainSystem as Hooks<$crate::BlockNumberFor<Self::Runtime>>>::on_initialize(block_number);

let _ = <Self as Parachain>::ParachainSystem::set_validation_data(
<Self as Chain>::RuntimeOrigin::none(),
N::hrmp_channel_parachain_inherent_data(para_id, relay_block_number, parent_head_data),
// Process `on_initialize` for all pallets except `System`.
let _ = $runtime::AllPalletsWithoutSystem::on_initialize(block_number);

// Process parachain inherents:

// 1. inherent: cumulus_pallet_parachain_system::Call::set_validation_data
let set_validation_data: <Self as Chain>::RuntimeCall = $crate::ParachainSystemCall::set_validation_data {
data: N::hrmp_channel_parachain_inherent_data(para_id, relay_block_number, parent_head_data),
}.into();
$crate::assert_ok!(
set_validation_data.dispatch(<Self as Chain>::RuntimeOrigin::none())
);

// 2. inherent: pallet_timestamp::Call::set (we expect the parachain has `pallet_timestamp`)
let timestamp_set: <Self as Chain>::RuntimeCall = $crate::TimestampCall::set {
// We need to satisfy `pallet_timestamp::on_finalize`.
now: Zero::zero(),
}.into();
$crate::assert_ok!(
timestamp_set.dispatch(<Self as Chain>::RuntimeOrigin::none())
);
});
}

fn finalize_block() {
use $crate::{Chain, Encode, Hooks, Network, Parachain, TestExt};
use $crate::{BlockWeightsLimits, Chain, OnFinalize, OnIdle, SystemConfig, TestExt, Weight};

Self::ext_wrapper(|| {
let block_number = <Self as Chain>::System::block_number();
<Self as Parachain>::ParachainSystem::on_finalize(block_number);

// Process `on_idle` for all pallets.
let weight = <Self as Chain>::System::block_weight();
let max_weight: Weight = <<<Self as Chain>::Runtime as SystemConfig>::BlockWeights as frame_support::traits::Get<BlockWeightsLimits>>::get().max_block;
let remaining_weight = max_weight.saturating_sub(weight.total());
if remaining_weight.all_gt(Weight::zero()) {
let _ = $runtime::AllPalletsWithSystem::on_idle(block_number, remaining_weight);
}

// Process `on_finalize` for all pallets except `System`.
$runtime::AllPalletsWithoutSystem::on_finalize(block_number);
});

Self::set_last_head();
}


fn set_last_head() {
use $crate::{Chain, Encode, HeadData, Network, Parachain, TestExt};
use $crate::{Chain, Encode, HeadData, TestExt};

let para_id = Self::para_id().into();

Expand Down Expand Up @@ -1157,7 +1190,7 @@ macro_rules! decl_test_networks {

$crate::ParachainInherentData {
validation_data: $crate::PersistedValidationData {
parent_head: Default::default(),
parent_head: parent_head_data.clone(),
relay_parent_number,
relay_parent_storage_root: relay_storage_root,
max_pov_size: Default::default(),
Expand Down
13 changes: 13 additions & 0 deletions prdoc/pr_8083.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: '`xcm-emulator` improved callback triggering (`on_initialize`, `on_finalize`,
`on_idle`, `OnSystemEvent`).'
doc:
- audience: Runtime Dev
description: |-
This PR fixes several issues related to `xcm-emulator`:
- Corrects parent head propagation to the `PersistedValidationData` and `OnSystemEvent` callback.
- Triggers `on_initialize` for all pallets, not just `ParachainSystem`.
- Triggers `on_finalize` for all pallets, not just `ParachainSystem`.
- Triggers `on_idle` for all parachain pallets.
crates:
- name: xcm-emulator
bump: minor