[xcm-emulator] Chains generic over Network & Integration tests restructure (#2092)

Closes:
- #1383 
- Declared chains can be now be imported and reused in a different
crate.
- Chain declaration are now generic over a generic type `N` (the
Network)
- #1389
- Solved #1383, chains and networks declarations can be restructure to
avoid having to compile all chains when running integrations tests where
are not needed.
- Chains are now declared on its own crate (removed from
`integration-tests-common`)
- Networks are now declared on its own crate (removed from
`integration-tests-common`)
    - Integration tests will import only the relevant Network crate
- `integration-tests-common` is renamed to
`emulated-integration-tests-common`

All this is necessary to be able to implement what is described here:
https://github.com/paritytech/roadmap/issues/56#issuecomment-1777010553

---------

Co-authored-by: command-bot <>
This commit is contained in:
Ignacio Palacios
2023-11-08 16:02:03 +01:00
committed by GitHub
parent 50390950d8
commit ffa0e30e58
79 changed files with 2674 additions and 2750 deletions
File diff suppressed because it is too large Load Diff
@@ -17,41 +17,22 @@ pub use codec::{Decode, Encode};
pub use paste;
pub use crate::{
constants::{PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD},
xcm_helpers::xcm_transact_unpaid_execution,
BridgeHubRococo, BridgeHubWococo,
xcm_helpers::xcm_transact_unpaid_execution, PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD,
};
// Substrate
pub use frame_support::{
assert_ok,
sp_runtime::AccountId32,
traits::fungibles::Inspect,
weights::{Weight, WeightMeter},
};
pub use pallet_assets;
pub use pallet_message_queue;
pub use pallet_xcm;
use sp_core::Get;
// Cumulus
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
LaneId, MessageKey, OutboundLaneData,
};
use bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatchResult;
pub use cumulus_pallet_parachain_system;
pub use cumulus_pallet_xcmp_queue;
pub use cumulus_primitives_core::{
relay_chain::HrmpChannelId, DmpMessageHandler, ParaId, XcmpMessageHandler,
};
use pallet_bridge_messages::{Config, Instance1, Instance2, OutboundLanes, Pallet};
pub use parachains_common::{AccountId, Balance};
pub use xcm_emulator::{
assert_expected_events, bx, helpers::weight_within_threshold, BridgeMessage,
BridgeMessageDispatchError, BridgeMessageHandler, Chain, Parachain, RelayChain, TestExt,
};
// Polkadot
pub use pallet_xcm;
pub use polkadot_runtime_parachains::{
dmp, hrmp,
inclusion::{AggregateMessageOrigin, UmpQueueId},
@@ -62,6 +43,28 @@ pub use xcm::{
DoubleEncoded,
};
// Cumulus
pub use cumulus_pallet_parachain_system;
pub use cumulus_pallet_xcmp_queue;
pub use cumulus_primitives_core::{
relay_chain::HrmpChannelId, DmpMessageHandler, ParaId, XcmpMessageHandler,
};
pub use parachains_common::{AccountId, Balance};
pub use xcm_emulator::{
assert_expected_events, bx, helpers::weight_within_threshold, BridgeMessage,
BridgeMessageDispatchError, BridgeMessageHandler, Chain, Network, Parachain, RelayChain,
TestExt,
};
// Bridges
use bp_messages::{
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
LaneId, MessageKey, OutboundLaneData,
};
use bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatchResult;
pub use pallet_bridge_messages::Instance2 as BridgeMessagesInstance2;
use pallet_bridge_messages::{Config, Instance1, OutboundLanes, Pallet};
pub struct BridgeHubMessageHandler<S, T, I> {
_marker: std::marker::PhantomData<(S, T, I)>,
}
@@ -80,14 +83,6 @@ impl From<u32> for LaneIdWrapper {
}
}
type BridgeHubRococoRuntime = <BridgeHubRococo as Chain>::Runtime;
type BridgeHubWococoRuntime = <BridgeHubWococo as Chain>::Runtime;
pub type RococoWococoMessageHandler =
BridgeHubMessageHandler<BridgeHubRococoRuntime, BridgeHubWococoRuntime, Instance2>;
pub type WococoRococoMessageHandler =
BridgeHubMessageHandler<BridgeHubWococoRuntime, BridgeHubRococoRuntime, Instance2>;
impl<S, T, I> BridgeMessageHandler for BridgeHubMessageHandler<S, T, I>
where
S: Config<Instance1>,
@@ -171,12 +166,12 @@ where
macro_rules! impl_accounts_helpers_for_relay_chain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Fund a set of accounts with a balance
pub fn fund_accounts(accounts: Vec<($crate::impls::AccountId, $crate::impls::Balance)>) {
<Self as $crate::impls::TestExt>::execute_with(|| {
for account in accounts {
$crate::impls::assert_ok!(<Self as [<$chain Pallet>]>::Balances::force_set_balance(
$crate::impls::assert_ok!(<Self as [<$chain RelayPallet>]>::Balances::force_set_balance(
<Self as $crate::impls::Chain>::RuntimeOrigin::root(),
account.0.into(),
account.1,
@@ -185,7 +180,7 @@ macro_rules! impl_accounts_helpers_for_relay_chain {
});
}
/// Fund a sovereign account based on its Parachain Id
pub fn fund_para_sovereign(amount: $crate::impls::Balance, para_id: $crate::impls::ParaId) -> sp_runtime::AccountId32 {
pub fn fund_para_sovereign(amount: $crate::impls::Balance, para_id: $crate::impls::ParaId) -> $crate::impls::AccountId32 {
let sovereign_account = <Self as $crate::impls::RelayChain>::sovereign_account_id_of_child_para(para_id);
Self::fund_accounts(vec![(sovereign_account.clone(), amount)]);
sovereign_account
@@ -199,15 +194,15 @@ macro_rules! impl_accounts_helpers_for_relay_chain {
macro_rules! impl_assert_events_helpers_for_relay_chain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
type [<$chain RuntimeEvent>] = <$chain as $crate::impls::Chain>::RuntimeEvent;
type [<$chain RuntimeEvent>]<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Asserts a dispatchable is completely executed and XCM sent
pub fn assert_xcm_pallet_attempted_complete(expected_weight: Option<$crate::impls::Weight>) {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::XcmPallet(
[<$chain RuntimeEvent>]::<N>::XcmPallet(
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) }
) => {
weight: $crate::impls::weight_within_threshold(
@@ -229,7 +224,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain {
Self,
vec![
// Dispatchable is properly executed and XCM message sent
[<$chain RuntimeEvent>]::XcmPallet(
[<$chain RuntimeEvent>]::<N>::XcmPallet(
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) }
) => {
weight: $crate::impls::weight_within_threshold(
@@ -248,7 +243,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::XcmPallet($crate::impls::pallet_xcm::Event::Sent { .. }) => {},
[<$chain RuntimeEvent>]::<N>::XcmPallet($crate::impls::pallet_xcm::Event::Sent { .. }) => {},
]
);
}
@@ -263,7 +258,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain {
Self,
vec![
// XCM is succesfully received and proccessed
[<$chain RuntimeEvent>]::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
origin: $crate::impls::AggregateMessageOrigin::Ump($crate::impls::UmpQueueId::Para(id)),
weight_used,
success,
@@ -289,7 +284,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain {
macro_rules! impl_hrmp_channels_helpers_for_relay_chain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Init open channel request with another Parachain
pub fn init_open_channel_call(
recipient_para_id: $crate::impls::ParaId,
@@ -329,7 +324,7 @@ macro_rules! impl_hrmp_channels_helpers_for_relay_chain {
let relay_root_origin = <Self as Chain>::RuntimeOrigin::root();
// Force process HRMP open channel requests without waiting for the next session
$crate::impls::assert_ok!(<Self as [<$chain Pallet>]>::Hrmp::force_process_hrmp_open(
$crate::impls::assert_ok!(<Self as [<$chain RelayPallet>]>::Hrmp::force_process_hrmp_open(
relay_root_origin,
0
));
@@ -353,7 +348,7 @@ macro_rules! impl_hrmp_channels_helpers_for_relay_chain {
macro_rules! impl_send_transact_helpers_for_relay_chain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// A root origin (as governance) sends `xcm::Transact` with `UnpaidExecution` and encoded `call` to child parachain.
pub fn send_unpaid_transact_to_parachain_as_root(
recipient: $crate::impls::ParaId,
@@ -367,7 +362,7 @@ macro_rules! impl_send_transact_helpers_for_relay_chain {
let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser);
// Send XCM `Transact`
$crate::impls::assert_ok!(<Self as [<$chain Pallet>]>::XcmPallet::send(
$crate::impls::assert_ok!(<Self as [<$chain RelayPallet>]>::XcmPallet::send(
root_origin,
bx!(destination.into()),
bx!(xcm),
@@ -384,12 +379,12 @@ macro_rules! impl_send_transact_helpers_for_relay_chain {
macro_rules! impl_accounts_helpers_for_parachain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Fund a set of accounts with a balance
pub fn fund_accounts(accounts: Vec<($crate::impls::AccountId, $crate::impls::Balance)>) {
<Self as $crate::impls::TestExt>::execute_with(|| {
for account in accounts {
$crate::impls::assert_ok!(<Self as [<$chain Pallet>]>::Balances::force_set_balance(
$crate::impls::assert_ok!(<Self as [<$chain ParaPallet>]>::Balances::force_set_balance(
<Self as $crate::impls::Chain>::RuntimeOrigin::root(),
account.0.into(),
account.1,
@@ -406,15 +401,15 @@ macro_rules! impl_accounts_helpers_for_parachain {
macro_rules! impl_assert_events_helpers_for_parachain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
type [<$chain RuntimeEvent>] = <$chain as $crate::impls::Chain>::RuntimeEvent;
type [<$chain RuntimeEvent>]<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Asserts a dispatchable is completely executed and XCM sent
pub fn assert_xcm_pallet_attempted_complete(expected_weight: Option<$crate::impls::Weight>) {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::PolkadotXcm(
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) }
) => {
weight: $crate::impls::weight_within_threshold(
@@ -436,7 +431,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
Self,
vec![
// Dispatchable is properly executed and XCM message sent
[<$chain RuntimeEvent>]::PolkadotXcm(
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) }
) => {
weight: $crate::impls::weight_within_threshold(
@@ -456,7 +451,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
Self,
vec![
// Execution fails in the origin with `Barrier`
[<$chain RuntimeEvent>]::PolkadotXcm(
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error(error) }
) => {
error: *error == expected_error.unwrap_or(*error),
@@ -470,7 +465,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::PolkadotXcm($crate::impls::pallet_xcm::Event::Sent { .. }) => {},
[<$chain RuntimeEvent>]::<N>::PolkadotXcm($crate::impls::pallet_xcm::Event::Sent { .. }) => {},
]
);
}
@@ -480,7 +475,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::ParachainSystem(
[<$chain RuntimeEvent>]::<N>::ParachainSystem(
$crate::impls::cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
) => {},
]
@@ -492,7 +487,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::MessageQueue(pallet_message_queue::Event::Processed {
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
success: true, weight_used: weight, ..
}) => {
weight: $crate::impls::weight_within_threshold(
@@ -512,7 +507,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::MessageQueue(pallet_message_queue::Event::Processed {
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
success: false, weight_used: weight, ..
}) => {
weight: $crate::impls::weight_within_threshold(
@@ -530,7 +525,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::MessageQueue($crate::impls::pallet_message_queue::Event::ProcessingFailed {
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::ProcessingFailed {
..
}) => {
@@ -544,7 +539,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
$crate::impls::assert_expected_events!(
Self,
vec![
[<$chain RuntimeEvent>]::MessageQueue(pallet_message_queue::Event::Processed { success: true, weight_used: weight, .. }
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed { success: true, weight_used: weight, .. }
) => {
weight: $crate::impls::weight_within_threshold(
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
@@ -561,10 +556,10 @@ macro_rules! impl_assert_events_helpers_for_parachain {
}
#[macro_export]
macro_rules! impl_assets_helpers_for_parachain {
macro_rules! impl_assets_helpers_for_system_parachain {
( $chain:ident, $relay_chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
impl<N: $crate::impls::Network> $chain<N> {
/// Returns the encoded call for `force_create` from the assets pallet
pub fn force_create_asset_call(
asset_id: u32,
@@ -607,19 +602,19 @@ macro_rules! impl_assets_helpers_for_parachain {
amount_to_mint: u128,
) {
<Self as $crate::impls::TestExt>::execute_with(|| {
$crate::impls::assert_ok!(<Self as [<$chain Pallet>]>::Assets::mint(
$crate::impls::assert_ok!(<Self as [<$chain ParaPallet>]>::Assets::mint(
signed_origin,
id.into(),
beneficiary.clone().into(),
amount_to_mint
));
type RuntimeEvent = <$chain as $crate::impls::Chain>::RuntimeEvent;
type RuntimeEvent<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
$crate::impls::assert_expected_events!(
Self,
vec![
RuntimeEvent::Assets($crate::impls::pallet_assets::Event::Issued { asset_id, owner, amount }) => {
RuntimeEvent::<N>::Assets($crate::impls::pallet_assets::Event::Issued { asset_id, owner, amount }) => {
asset_id: *asset_id == id,
owner: *owner == beneficiary.clone().into(),
amount: *amount == amount_to_mint,
@@ -664,28 +659,28 @@ macro_rules! impl_assets_helpers_for_parachain {
) {
use $crate::impls::{Parachain, Inspect, TestExt};
<$relay_chain>::send_unpaid_transact_to_parachain_as_root(
<$relay_chain<N>>::send_unpaid_transact_to_parachain_as_root(
Self::para_id(),
Self::force_create_asset_call(id, asset_owner.clone(), is_sufficient, min_balance),
);
// Receive XCM message in Assets Parachain
Self::execute_with(|| {
type RuntimeEvent = <$chain as $crate::impls::Chain>::RuntimeEvent;
type RuntimeEvent<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
Self::assert_dmp_queue_complete(dmp_weight_threshold);
$crate::impls::assert_expected_events!(
Self,
vec![
RuntimeEvent::Assets($crate::impls::pallet_assets::Event::ForceCreated { asset_id, owner }) => {
RuntimeEvent::<N>::Assets($crate::impls::pallet_assets::Event::ForceCreated { asset_id, owner }) => {
asset_id: *asset_id == id,
owner: *owner == asset_owner,
},
]
);
assert!(<Self as [<$chain Pallet>]>::Assets::asset_exists(id.into()));
assert!(<Self as [<$chain ParaPallet>]>::Assets::asset_exists(id.into()));
});
}
}
@@ -13,361 +13,161 @@
// See the License for the specific language governing permissions and
// limitations under the License.
pub mod constants;
pub mod impls;
pub mod macros;
pub mod xcm_helpers;
use constants::{
accounts::{ALICE, BOB},
asset_hub_rococo, asset_hub_westend, asset_hub_wococo, bridge_hub_rococo, bridge_hub_westend,
penpal, rococo, westend,
};
use impls::{RococoWococoMessageHandler, WococoRococoMessageHandler};
pub use paste;
pub use xcm_emulator;
// Substrate
use frame_support::traits::OnInitialize;
pub use pallet_balances;
pub use pallet_message_queue;
// Cumulus
pub use cumulus_pallet_xcmp_queue;
pub use xcm_emulator::Chain;
use xcm_emulator::{
decl_test_bridges, decl_test_networks, decl_test_parachains, decl_test_relay_chains,
decl_test_sender_receiver_accounts_parameter_types, DefaultParaMessageProcessor,
DefaultRelayMessageProcessor, Parachain, TestExt,
use grandpa::AuthorityId as GrandpaId;
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_consensus_babe::AuthorityId as BabeId;
use sp_core::{sr25519, storage::Storage, Pair, Public};
use sp_runtime::{
traits::{IdentifyAccount, Verify},
BuildStorage, MultiSignature,
};
// Polkadot
pub use pallet_xcm;
pub use xcm::prelude::{AccountId32, WeightLimit};
// Polakdot
use parachains_common::BlockNumber;
use polkadot_runtime_parachains::configuration::HostConfiguration;
use xcm;
decl_test_relay_chains! {
#[api_version(8)]
pub struct Westend {
genesis = westend::genesis(),
on_init = (),
runtime = westend_runtime,
core = {
MessageProcessor: DefaultRelayMessageProcessor<Westend>,
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: westend_runtime::XcmPallet,
Sudo: westend_runtime::Sudo,
Balances: westend_runtime::Balances,
Treasury: westend_runtime::Treasury,
AssetRate: westend_runtime::AssetRate,
}
},
#[api_version(8)]
pub struct Rococo {
genesis = rococo::genesis(),
on_init = (),
runtime = rococo_runtime,
core = {
MessageProcessor: DefaultRelayMessageProcessor<Rococo>,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
Balances: rococo_runtime::Balances,
Hrmp: rococo_runtime::Hrmp,
}
},
#[api_version(8)]
pub struct Wococo {
genesis = rococo::genesis(),
on_init = (),
runtime = rococo_runtime,
core = {
MessageProcessor: DefaultRelayMessageProcessor<Wococo>,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
Balances: rococo_runtime::Balances,
}
// Cumulus
use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId};
use polkadot_primitives::{AssignmentId, ValidatorId};
use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy;
pub const XCM_V2: u32 = 2;
pub const XCM_V3: u32 = 3;
pub const REF_TIME_THRESHOLD: u64 = 33;
pub const PROOF_SIZE_THRESHOLD: u64 = 33;
/// The default XCM version to set in genesis config.
pub const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION;
type AccountPublic = <MultiSignature as Verify>::Signer;
/// Helper function to generate a crypto pair from seed
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
TPublic::Pair::from_string(&format!("//{}", seed), None)
.expect("static values are valid; qed")
.public()
}
/// Helper function to generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}
pub fn get_host_config() -> HostConfiguration<BlockNumber> {
HostConfiguration {
max_upward_queue_count: 10,
max_upward_queue_size: 51200,
max_upward_message_size: 51200,
max_upward_message_num_per_candidate: 10,
max_downward_message_size: 51200,
hrmp_sender_deposit: 0,
hrmp_recipient_deposit: 0,
hrmp_channel_max_capacity: 1000,
hrmp_channel_max_message_size: 102400,
hrmp_channel_max_total_size: 102400,
hrmp_max_parachain_outbound_channels: 30,
hrmp_max_parachain_inbound_channels: 30,
..Default::default()
}
}
decl_test_parachains! {
// Westend Parachains
pub struct AssetHubWestend {
genesis = asset_hub_westend::genesis(),
on_init = {
asset_hub_westend_runtime::AuraExt::on_initialize(1);
},
runtime = asset_hub_westend_runtime,
core = {
XcmpMessageHandler: asset_hub_westend_runtime::XcmpQueue,
LocationToAccountId: asset_hub_westend_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_westend_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<AssetHubWestend>,
},
pallets = {
PolkadotXcm: asset_hub_westend_runtime::PolkadotXcm,
Balances: asset_hub_westend_runtime::Balances,
Assets: asset_hub_westend_runtime::Assets,
ForeignAssets: asset_hub_westend_runtime::ForeignAssets,
PoolAssets: asset_hub_westend_runtime::PoolAssets,
AssetConversion: asset_hub_westend_runtime::AssetConversion,
}
},
pub struct BridgeHubWestend {
genesis = bridge_hub_westend::genesis(),
on_init = {
bridge_hub_westend_runtime::AuraExt::on_initialize(1);
},
runtime = bridge_hub_westend_runtime,
core = {
XcmpMessageHandler: bridge_hub_westend_runtime::XcmpQueue,
LocationToAccountId: bridge_hub_westend_runtime::xcm_config::LocationToAccountId,
ParachainInfo: bridge_hub_westend_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<BridgeHubWestend>,
},
pallets = {
PolkadotXcm: bridge_hub_westend_runtime::PolkadotXcm,
Balances: bridge_hub_westend_runtime::Balances,
}
},
pub struct PenpalWestendA {
genesis = penpal::genesis(penpal::PARA_ID_A),
on_init = {
penpal_runtime::AuraExt::on_initialize(1);
},
runtime = penpal_runtime,
core = {
XcmpMessageHandler: penpal_runtime::XcmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
ParachainInfo: penpal_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<PenpalWestendA>,
},
pallets = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
Balances: penpal_runtime::Balances,
}
},
// Rococo Parachains
pub struct BridgeHubRococo {
genesis = bridge_hub_rococo::genesis(),
on_init = {
bridge_hub_rococo_runtime::AuraExt::on_initialize(1);
},
runtime = bridge_hub_rococo_runtime,
core = {
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<BridgeHubRococo>,
},
pallets = {
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
Balances: bridge_hub_rococo_runtime::Balances,
}
},
// AssetHubRococo
pub struct AssetHubRococo {
genesis = asset_hub_rococo::genesis(),
on_init = {
asset_hub_rococo_runtime::AuraExt::on_initialize(1);
},
runtime = asset_hub_rococo_runtime,
core = {
XcmpMessageHandler: asset_hub_rococo_runtime::XcmpQueue,
LocationToAccountId: asset_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_rococo_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<AssetHubRococo>,
},
pallets = {
PolkadotXcm: asset_hub_rococo_runtime::PolkadotXcm,
Assets: asset_hub_rococo_runtime::Assets,
ForeignAssets: asset_hub_rococo_runtime::ForeignAssets,
PoolAssets: asset_hub_rococo_runtime::PoolAssets,
AssetConversion: asset_hub_rococo_runtime::AssetConversion,
Balances: asset_hub_rococo_runtime::Balances,
}
},
pub struct PenpalRococoA {
genesis = penpal::genesis(penpal::PARA_ID_A),
on_init = {
penpal_runtime::AuraExt::on_initialize(1);
},
runtime = penpal_runtime,
core = {
XcmpMessageHandler: penpal_runtime::XcmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
ParachainInfo: penpal_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<PenpalRococoA>,
},
pallets = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
},
pub struct PenpalRococoB {
genesis = penpal::genesis(penpal::PARA_ID_B),
on_init = {
penpal_runtime::AuraExt::on_initialize(1);
},
runtime = penpal_runtime,
core = {
XcmpMessageHandler: penpal_runtime::XcmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
ParachainInfo: penpal_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<PenpalRococoB>,
},
pallets = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
},
// Wococo Parachains
pub struct BridgeHubWococo {
genesis = bridge_hub_rococo::genesis(),
on_init = {
bridge_hub_rococo_runtime::AuraExt::on_initialize(1);
// TODO: manage to set_wococo_flavor with `set_storage`
},
runtime = bridge_hub_rococo_runtime,
core = {
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<BridgeHubWococo>,
},
pallets = {
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
}
},
pub struct AssetHubWococo {
genesis = asset_hub_wococo::genesis(),
on_init = {
asset_hub_rococo_runtime::AuraExt::on_initialize(1);
// TODO: manage to set_wococo_flavor with `set_storage`
},
runtime = asset_hub_rococo_runtime,
core = {
XcmpMessageHandler: asset_hub_rococo_runtime::XcmpQueue,
LocationToAccountId: asset_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_rococo_runtime::ParachainInfo,
MessageProcessor: DefaultParaMessageProcessor<AssetHubWococo>,
},
pallets = {
PolkadotXcm: asset_hub_rococo_runtime::PolkadotXcm,
Assets: asset_hub_rococo_runtime::Assets,
ForeignAssets: asset_hub_rococo_runtime::ForeignAssets,
PoolAssets: asset_hub_rococo_runtime::PoolAssets,
AssetConversion: asset_hub_rococo_runtime::AssetConversion,
Balances: asset_hub_rococo_runtime::Balances,
}
/// Helper function used in tests to build the genesis storage using given RuntimeGenesisConfig and
/// code Used in `legacy_vs_json_check` submods to verify storage building with JSON patch against
/// building with RuntimeGenesisConfig struct.
pub fn build_genesis_storage_legacy(builder: &dyn BuildStorage, code: &[u8]) -> Storage {
let mut storage = builder.build_storage().unwrap();
storage
.top
.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code.into());
storage
}
pub mod accounts {
use super::*;
pub const ALICE: &str = "Alice";
pub const BOB: &str = "Bob";
pub const CHARLIE: &str = "Charlie";
pub const DAVE: &str = "Dave";
pub const EVE: &str = "Eve";
pub const FERDIE: &str = "Ferdei";
pub const ALICE_STASH: &str = "Alice//stash";
pub const BOB_STASH: &str = "Bob//stash";
pub const CHARLIE_STASH: &str = "Charlie//stash";
pub const DAVE_STASH: &str = "Dave//stash";
pub const EVE_STASH: &str = "Eve//stash";
pub const FERDIE_STASH: &str = "Ferdie//stash";
pub const FERDIE_BEEFY: &str = "Ferdie//stash";
pub fn init_balances() -> Vec<AccountId> {
vec![
get_account_id_from_seed::<sr25519::Public>(ALICE),
get_account_id_from_seed::<sr25519::Public>(BOB),
get_account_id_from_seed::<sr25519::Public>(CHARLIE),
get_account_id_from_seed::<sr25519::Public>(DAVE),
get_account_id_from_seed::<sr25519::Public>(EVE),
get_account_id_from_seed::<sr25519::Public>(FERDIE),
get_account_id_from_seed::<sr25519::Public>(ALICE_STASH),
get_account_id_from_seed::<sr25519::Public>(BOB_STASH),
get_account_id_from_seed::<sr25519::Public>(CHARLIE_STASH),
get_account_id_from_seed::<sr25519::Public>(DAVE_STASH),
get_account_id_from_seed::<sr25519::Public>(EVE_STASH),
get_account_id_from_seed::<sr25519::Public>(FERDIE_STASH),
]
}
}
decl_test_networks! {
pub struct WestendMockNet {
relay_chain = Westend,
parachains = vec![
AssetHubWestend,
BridgeHubWestend,
PenpalWestendA,
],
bridge = ()
},
pub struct RococoMockNet {
relay_chain = Rococo,
parachains = vec![
AssetHubRococo,
BridgeHubRococo,
PenpalRococoA,
PenpalRococoB,
],
bridge = RococoWococoMockBridge
},
pub struct WococoMockNet {
relay_chain = Wococo,
parachains = vec![
AssetHubWococo,
BridgeHubWococo,
],
bridge = WococoRococoMockBridge
pub mod collators {
use super::*;
pub fn invulnerables_asset_hub_polkadot() -> Vec<(AccountId, AssetHubPolkadotAuraId)> {
vec![
(
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_from_seed::<AssetHubPolkadotAuraId>("Alice"),
),
(
get_account_id_from_seed::<sr25519::Public>("Bob"),
get_from_seed::<AssetHubPolkadotAuraId>("Bob"),
),
]
}
pub fn invulnerables() -> Vec<(AccountId, AuraId)> {
vec![
(
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_from_seed::<AuraId>("Alice"),
),
(get_account_id_from_seed::<sr25519::Public>("Bob"), get_from_seed::<AuraId>("Bob")),
]
}
}
decl_test_bridges! {
pub struct RococoWococoMockBridge {
source = BridgeHubRococo,
target = BridgeHubWococo,
handler = RococoWococoMessageHandler
},
pub struct WococoRococoMockBridge {
source = BridgeHubWococo,
target = BridgeHubRococo,
handler = WococoRococoMessageHandler
pub mod validators {
use super::*;
pub fn initial_authorities() -> Vec<(
AccountId,
AccountId,
BabeId,
GrandpaId,
ImOnlineId,
ValidatorId,
AssignmentId,
AuthorityDiscoveryId,
)> {
vec![get_authority_keys_from_seed_no_beefy("Alice")]
}
}
// Westend implementation
impl_accounts_helpers_for_relay_chain!(Westend);
impl_assert_events_helpers_for_relay_chain!(Westend);
impl_send_transact_helpers_for_relay_chain!(Westend);
// Rococo implementation
impl_accounts_helpers_for_relay_chain!(Rococo);
impl_assert_events_helpers_for_relay_chain!(Rococo);
impl_hrmp_channels_helpers_for_relay_chain!(Rococo);
impl_send_transact_helpers_for_relay_chain!(Rococo);
// Wococo implementation
impl_accounts_helpers_for_relay_chain!(Wococo);
impl_assert_events_helpers_for_relay_chain!(Wococo);
impl_send_transact_helpers_for_relay_chain!(Wococo);
// AssetHubWestend implementation
impl_accounts_helpers_for_parachain!(AssetHubWestend);
impl_assets_helpers_for_parachain!(AssetHubWestend, Westend);
impl_assert_events_helpers_for_parachain!(AssetHubWestend);
// AssetHubRococo implementation
impl_accounts_helpers_for_parachain!(AssetHubRococo);
impl_assets_helpers_for_parachain!(AssetHubRococo, Rococo);
impl_assert_events_helpers_for_parachain!(AssetHubRococo);
// PenpalWestendA implementation
impl_assert_events_helpers_for_parachain!(PenpalWestendA);
// BridgeHubWestend implementation
impl_accounts_helpers_for_parachain!(BridgeHubWestend);
impl_assert_events_helpers_for_parachain!(BridgeHubWestend);
// BridgeHubRococo implementation
impl_accounts_helpers_for_parachain!(BridgeHubRococo);
impl_assert_events_helpers_for_parachain!(BridgeHubRococo);
// PenpalRococo implementations
impl_assert_events_helpers_for_parachain!(PenpalRococoA);
impl_assert_events_helpers_for_parachain!(PenpalRococoB);
decl_test_sender_receiver_accounts_parameter_types! {
// Relays
Westend { sender: ALICE, receiver: BOB },
Rococo { sender: ALICE, receiver: BOB },
Wococo { sender: ALICE, receiver: BOB },
// Asset Hubs
AssetHubWestend { sender: ALICE, receiver: BOB },
AssetHubRococo { sender: ALICE, receiver: BOB },
AssetHubWococo { sender: ALICE, receiver: BOB },
// Bridged Hubs
BridgeHubRococo { sender: ALICE, receiver: BOB },
BridgeHubWococo { sender: ALICE, receiver: BOB },
BridgeHubWestend { sender: ALICE, receiver: BOB },
// Penpals
PenpalWestendA { sender: ALICE, receiver: BOB },
PenpalRococoA { sender: ALICE, receiver: BOB },
PenpalRococoB { sender: ALICE, receiver: BOB }
}
@@ -13,28 +13,43 @@
// See the License for the specific language governing permissions and
// limitations under the License.
pub use paste;
// Substrate
pub use pallet_balances;
pub use pallet_message_queue;
pub use pallet_xcm;
// Polkadot
pub use xcm::prelude::{AccountId32, WeightLimit};
// Cumulus
pub use asset_test_utils;
pub use cumulus_pallet_xcmp_queue;
pub use xcm_emulator::Chain;
#[macro_export]
macro_rules! test_parachain_is_trusted_teleporter {
( $sender_para:ty, $sender_xcm_config:ty, vec![$( $receiver_para:ty ),+], ($assets:expr, $amount:expr) ) => {
$crate::paste::paste! {
$crate::macros::paste::paste! {
// init Origin variables
let sender = [<$sender_para Sender>]::get();
let mut para_sender_balance_before =
<$sender_para as $crate::Chain>::account_data_of(sender.clone()).free;
let origin = <$sender_para as $crate::Chain>::RuntimeOrigin::signed(sender.clone());
<$sender_para as $crate::macros::Chain>::account_data_of(sender.clone()).free;
let origin = <$sender_para as $crate::macros::Chain>::RuntimeOrigin::signed(sender.clone());
let fee_asset_item = 0;
let weight_limit = $crate::WeightLimit::Unlimited;
let weight_limit = $crate::macros::WeightLimit::Unlimited;
$(
{
// init Destination variables
let receiver = [<$receiver_para Receiver>]::get();
let para_receiver_balance_before =
<$receiver_para as $crate::Chain>::account_data_of(receiver.clone()).free;
<$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free;
let para_destination =
<$sender_para>::sibling_location_of(<$receiver_para>::para_id());
let beneficiary: MultiLocation =
$crate::AccountId32 { network: None, id: receiver.clone().into() }.into();
$crate::macros::AccountId32 { network: None, id: receiver.clone().into() }.into();
// Send XCM message from Origin Parachain
// We are only testing the limited teleport version, which should be ok since success will
@@ -49,19 +64,19 @@ macro_rules! test_parachain_is_trusted_teleporter {
weight_limit.clone(),
));
type RuntimeEvent = <$sender_para as $crate::Chain>::RuntimeEvent;
type RuntimeEvent = <$sender_para as $crate::macros::Chain>::RuntimeEvent;
assert_expected_events!(
$sender_para,
vec![
RuntimeEvent::PolkadotXcm(
$crate::pallet_xcm::Event::Attempted { outcome: Outcome::Complete { .. } }
$crate::macros::pallet_xcm::Event::Attempted { outcome: Outcome::Complete { .. } }
) => {},
RuntimeEvent::XcmpQueue(
$crate::cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
$crate::macros::cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }
) => {},
RuntimeEvent::Balances(
$crate::pallet_balances::Event::Withdraw { who: sender, amount }
$crate::macros::pallet_balances::Event::Withdraw { who: sender, amount }
) => {},
]
);
@@ -69,16 +84,16 @@ macro_rules! test_parachain_is_trusted_teleporter {
// Receive XCM message in Destination Parachain
<$receiver_para>::execute_with(|| {
type RuntimeEvent = <$receiver_para as $crate::Chain>::RuntimeEvent;
type RuntimeEvent = <$receiver_para as $crate::macros::Chain>::RuntimeEvent;
assert_expected_events!(
$receiver_para,
vec![
RuntimeEvent::Balances(
$crate::pallet_balances::Event::Deposit { who: receiver, .. }
$crate::macros::pallet_balances::Event::Deposit { who: receiver, .. }
) => {},
RuntimeEvent::MessageQueue(
$crate::pallet_message_queue::Event::Processed { success: true, .. }
$crate::macros::pallet_message_queue::Event::Processed { success: true, .. }
) => {},
]
);
@@ -86,11 +101,11 @@ macro_rules! test_parachain_is_trusted_teleporter {
// Check if balances are updated accordingly in Origin and Destination Parachains
let para_sender_balance_after =
<$sender_para as $crate::Chain>::account_data_of(sender.clone()).free;
<$sender_para as $crate::macros::Chain>::account_data_of(sender.clone()).free;
let para_receiver_balance_after =
<$receiver_para as $crate::Chain>::account_data_of(receiver.clone()).free;
<$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free;
let delivery_fees = <$sender_para>::execute_with(|| {
asset_test_utils::xcm_helpers::transfer_assets_delivery_fees::<
$crate::macros::asset_test_utils::xcm_helpers::transfer_assets_delivery_fees::<
<$sender_xcm_config as xcm_executor::Config>::XcmSender,
>($assets.clone(), fee_asset_item, weight_limit.clone(), beneficiary, para_destination)
});
@@ -99,7 +114,7 @@ macro_rules! test_parachain_is_trusted_teleporter {
assert!(para_receiver_balance_after > para_receiver_balance_before);
// Update sender balance
para_sender_balance_before = <$sender_para as $crate::Chain>::account_data_of(sender.clone()).free;
para_sender_balance_before = <$sender_para as $crate::macros::Chain>::account_data_of(sender.clone()).free;
}
)+
}
@@ -13,7 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Cumulus
use parachains_common::AccountId;
// Polkadot
use xcm::{prelude::*, DoubleEncoded};
/// Helper method to build a XCM with a `Transact` instruction and paying for its execution