Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xcm emulator nits #1649

Merged
merged 17 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 13 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
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ fn limited_reserve_transfer_asset_from_system_para_to_para() {
ASSET_MIN_BALANCE,
true,
AssetHubWestendSender::get(),
Some(Weight::from_parts(1_019_445_000, 200_000)),
ASSET_MIN_BALANCE * 1000000,
);

Expand Down Expand Up @@ -387,6 +388,7 @@ fn reserve_transfer_asset_from_system_para_to_para() {
ASSET_MIN_BALANCE,
true,
AssetHubWestendSender::get(),
Some(Weight::from_parts(1_019_445_000, 200_000)),
ASSET_MIN_BALANCE * 1000000,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,16 @@
use crate::*;

/// Relay Chain should be able to execute `Transact` instructions in System Parachain
/// when `OriginKind::Superuser` and signer is `sudo`
/// when `OriginKind::Superuser`.
#[test]
fn send_transact_sudo_from_relay_to_system_para_works() {
// Init tests variables
let root_origin = <Westend as Chain>::RuntimeOrigin::root();
let system_para_destination = Westend::child_location_of(AssetHubWestend::para_id()).into();
let asset_owner: AccountId = AssetHubWestendSender::get().into();
let xcm = AssetHubWestend::force_create_asset_xcm(
OriginKind::Superuser,
fn send_transact_as_superuser_from_relay_to_system_para_works() {
AssetHubWestend::do_force_create_asset_from_relay_as_root(
ASSET_ID,
asset_owner.clone(),
ASSET_MIN_BALANCE,
true,
1000,
);
// Send XCM message from Relay Chain
Westend::execute_with(|| {
assert_ok!(<Westend as WestendPallet>::XcmPallet::send(
root_origin,
bx!(system_para_destination),
bx!(xcm),
));

Westend::assert_xcm_pallet_sent();
});

// Receive XCM message in Assets Parachain
AssetHubWestend::execute_with(|| {
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;

AssetHubWestend::assert_dmp_queue_complete(Some(Weight::from_parts(
1_019_445_000,
200_000,
)));

assert_expected_events!(
AssetHubWestend,
vec![
RuntimeEvent::Assets(pallet_assets::Event::ForceCreated { asset_id, owner }) => {
asset_id: *asset_id == ASSET_ID,
owner: *owner == asset_owner,
},
]
);

assert!(<AssetHubWestend as AssetHubWestendPallet>::Assets::asset_exists(ASSET_ID));
});
AssetHubWestendSender::get().into(),
Some(Weight::from_parts(1_019_445_000, 200_000)),
)
}

/// Parachain should be able to send XCM paying its fee with sufficient asset
Expand All @@ -78,6 +42,7 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
ASSET_MIN_BALANCE,
true,
para_sovereign_account.clone(),
Some(Weight::from_parts(1_019_445_000, 200_000)),
ASSET_MIN_BALANCE * 1000000000,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,22 @@ fn relay_sets_system_para_xcm_supported_version() {
#[test]
fn system_para_sets_relay_xcm_supported_version() {
// Init test variables
let sudo_origin = <Westend as Chain>::RuntimeOrigin::root();
let parent_location = AssetHubWestend::parent_location();
let system_para_destination: VersionedMultiLocation =
Westend::child_location_of(AssetHubWestend::para_id()).into();
let call = <AssetHubWestend as Chain>::RuntimeCall::PolkadotXcm(pallet_xcm::Call::<
<AssetHubWestend as Chain>::Runtime,
>::force_xcm_version {
location: bx!(parent_location),
version: XCM_V3,
})
.encode()
.into();
let origin_kind = OriginKind::Superuser;

let xcm = xcm_transact_unpaid_execution(call, origin_kind);

// System Parachain sets supported version for Relay Chain throught it
Westend::execute_with(|| {
assert_ok!(<Westend as WestendPallet>::XcmPallet::send(
sudo_origin,
bx!(system_para_destination),
bx!(xcm),
));
let force_xcm_version_call =
<AssetHubWestend as Chain>::RuntimeCall::PolkadotXcm(pallet_xcm::Call::<
<AssetHubWestend as Chain>::Runtime,
>::force_xcm_version {
location: bx!(parent_location),
version: XCM_V3,
})
bkontur marked this conversation as resolved.
Show resolved Hide resolved
.encode()
.into();

Westend::assert_xcm_pallet_sent();
});
// System Parachain sets supported version for Relay Chain through it
Westend::send_unpaid_transact_to_parachain_as_root(
AssetHubWestend::para_id(),
force_xcm_version_call,
);

// System Parachain receive the XCM message
AssetHubWestend::execute_with(|| {
Expand Down
98 changes: 62 additions & 36 deletions cumulus/parachains/integration-tests/emulated/common/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub use polkadot_runtime_parachains::{
inclusion::{AggregateMessageOrigin, UmpQueueId},
};
pub use xcm::{
prelude::{OriginKind, Outcome, VersionedXcm, Weight},
prelude::{MultiLocation, OriginKind, Outcome, VersionedXcm, Weight},
v3::Error,
DoubleEncoded,
};
Expand All @@ -80,21 +80,11 @@ impl From<u32> for LaneIdWrapper {
type BridgeHubRococoRuntime = <BridgeHubRococo as Chain>::Runtime;
type BridgeHubWococoRuntime = <BridgeHubWococo as Chain>::Runtime;

// TODO: uncomment when https://github.com/paritytech/polkadot-sdk/pull/1352 is merged
// type BridgeHubPolkadotRuntime = <BridgeHubPolkadot as Chain>::Runtime;
// type BridgeHubKusamaRuntime = <BridgeHubKusama as Chain>::Runtime;

pub type RococoWococoMessageHandler =
BridgeHubMessageHandler<BridgeHubRococoRuntime, BridgeHubWococoRuntime, Instance2>;
pub type WococoRococoMessageHandler =
BridgeHubMessageHandler<BridgeHubWococoRuntime, BridgeHubRococoRuntime, Instance2>;

// TODO: uncomment when https://github.com/paritytech/polkadot-sdk/pull/1352 is merged
// pub type PolkadotKusamaMessageHandler
// = BridgeHubMessageHandler<BridgeHubPolkadotRuntime, BridgeHubKusamaRuntime, Instance1>;
// pub type KusamaPolkadotMessageHandler
// = BridgeHubMessageHandler<BridgeHubKusamaRuntime, BridgeHubPolkadoRuntime, Instance1>;

impl<S, T, I> BridgeMessageHandler for BridgeHubMessageHandler<S, T, I>
where
S: Config<Instance1>,
Expand Down Expand Up @@ -356,6 +346,37 @@ macro_rules! impl_hrmp_channels_helpers_for_relay_chain {
};
}

#[macro_export]
macro_rules! impl_send_transact_helpers_for_relay_chain {
( $chain:ident ) => {
$crate::impls::paste::paste! {
impl $chain {
/// 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,
call: $crate::impls::DoubleEncoded<()>
) {
use $crate::impls::{bx, Chain, RelayChain};

<Self as $crate::impls::TestExt>::execute_with(|| {
let root_origin = <Self as Chain>::RuntimeOrigin::root();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we assuming that is going to be always root? Someone would like to test sending a Transact with different origin. I think we should either accept origin as an extra argument for send_transact_to_parachain or rename method to send_transact_to_parachain_as_sudo (better the first option)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is meant for governance-like calls from relay to para with RuntimeOrigin::root() and UnpaidExecution not to repeat the same code everywhere:

/// A root origin (as governance) sends `xcm::Transact` with encoded `call` to child parachain.

If we want it make it more general, then yes origin and also some "switch" for UnpaidExecution/BuyExecution wrapper should be added as a parameter. Then we should add it as a generic helper function for Chain trait.

I think, for me, send_transact_to_parachain_as_sudo means more like there is pallet_sudo which is not the case.

I am inclined to keep it as it is :).
Anyway, anybody else can still create whatever scenario with [<$chain Pallet>]>::XcmPallet::send.

@NachoPal wdyt?

Copy link
Contributor

@NachoPal NachoPal Oct 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realise about the hardcoded UnpaidExcution. Are there cases where an UnpaidExecution is going to work with a different origin than Superuser? If not then I do not see it necessary to have it as function argument.

Sorry, I sometimes use sudo and root interchangeably. If it is meant to be for governance-like calls (root) then we can do:

pub fn send_transact_to_parachain_as_root(
					recipient: $crate::impls::ParaId,
					call: $crate::impls::DoubleEncoded<()>
				)

What I am trying to avoid is to impl a method that is only meant to work for root, UnpaidExecution and Origin::Superuser with a so generic name - send_transact_to_parachain - (even if it is properly documented)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I renamed to send_unpaid_transact_to_parachain_as_root, please, check here: c30119c
I also was able to reuse do_force_create_asset_from_relay_as_root for force_create_and_mint_asset, which looks also much clear now

let destination: $crate::impls::MultiLocation = <Self as RelayChain>::child_location_of(recipient);
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(
root_origin,
bx!(destination.into()),
bx!(xcm),
));
Self::assert_xcm_pallet_sent();
});
}
}
}
};
}

#[macro_export]
macro_rules! impl_accounts_helpers_for_parachain {
( $chain:ident ) => {
Expand Down Expand Up @@ -600,53 +621,58 @@ macro_rules! impl_assets_helpers_for_parachain {
min_balance: u128,
is_sufficient: bool,
asset_owner: $crate::impls::AccountId,
dmp_weight_threshold: Option<$crate::impls::Weight>,
amount_to_mint: u128,
) {
use $crate::impls::{bx, Chain, RelayChain, Parachain, Inspect, TestExt};
// Init values for Relay Chain
let root_origin = <$relay_chain as Chain>::RuntimeOrigin::root();
let destination = <$relay_chain>::child_location_of(<$chain>::para_id());
let xcm = Self::force_create_asset_xcm(
$crate::impls::OriginKind::Superuser,
use $crate::impls::Chain;

// Force create asset
Self::do_force_create_asset_from_relay_as_root(
NachoPal marked this conversation as resolved.
Show resolved Hide resolved
id,
asset_owner.clone(),
is_sufficient,
min_balance,
is_sufficient,
asset_owner.clone(),
dmp_weight_threshold
);

<$relay_chain>::execute_with(|| {
$crate::impls::assert_ok!(<$relay_chain as [<$relay_chain Pallet>]>::XcmPallet::send(
root_origin,
bx!(destination.into()),
bx!(xcm),
));
// Mint asset for System Parachain's sender
let signed_origin = <Self as Chain>::RuntimeOrigin::signed(asset_owner.clone());
Self::mint_asset(signed_origin, id, asset_owner, amount_to_mint);
}

<$relay_chain>::assert_xcm_pallet_sent();
});
/// Relay Chain sends `Transact` instruction with `force_create_asset` to Parachain with `Assets` instance of `pallet_assets` .
pub fn do_force_create_asset_from_relay_as_root(
NachoPal marked this conversation as resolved.
Show resolved Hide resolved
id: u32,
min_balance: u128,
is_sufficient: bool,
asset_owner: $crate::impls::AccountId,
dmp_weight_threshold: Option<$crate::impls::Weight>,
) {
use $crate::impls::{Parachain, Inspect, TestExt};

Self::execute_with(|| {
Self::assert_dmp_queue_complete(Some($crate::impls::Weight::from_parts(1_019_445_000, 200_000)));
<$relay_chain>::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;

Self::assert_dmp_queue_complete(dmp_weight_threshold);

$crate::impls::assert_expected_events!(
Self,
vec![
// Asset has been created
RuntimeEvent::Assets($crate::impls::pallet_assets::Event::ForceCreated { asset_id, owner }) => {
asset_id: *asset_id == id,
owner: *owner == asset_owner.clone(),
owner: *owner == asset_owner,
},
]
);

assert!(<Self as [<$chain Pallet>]>::Assets::asset_exists(id.into()));
});

let signed_origin = <Self as Chain>::RuntimeOrigin::signed(asset_owner.clone());

// Mint asset for System Parachain's sender
Self::mint_asset(signed_origin, id, asset_owner, amount_to_mint);
}
}
}
Expand Down
14 changes: 3 additions & 11 deletions cumulus/parachains/integration-tests/emulated/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,30 +250,22 @@ decl_test_bridges! {
target = BridgeHubRococo,
handler = WococoRococoMessageHandler
}
// TODO: uncomment when https://github.com/paritytech/polkadot-sdk/pull/1352 is merged
// pub struct PolkadotKusamaMockBridge {
// source = BridgeHubPolkadot,
// target = BridgeHubKusama,
// handler = PolkadotKusamaMessageHandler
// },
// pub struct KusamaPolkadotMockBridge {
// source = BridgeHubKusama,
// target = BridgeHubPolkadot,
// handler = KusamaPolkadotMessageHandler
// }
}

// 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_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);
Expand Down