diff --git a/Cargo.lock b/Cargo.lock index 05800e3468718..68b8bbae80f40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3763,6 +3763,7 @@ dependencies = [ "pallet-broker", "pallet-identity", "pallet-message-queue", + "pallet-xcm", "polkadot-runtime-common", "polkadot-runtime-parachains", "sp-runtime 31.0.1", diff --git a/cumulus/parachains/common/src/xcm_config.rs b/cumulus/parachains/common/src/xcm_config.rs index 7c58a2b2405c7..3e149098027bb 100644 --- a/cumulus/parachains/common/src/xcm_config.rs +++ b/cumulus/parachains/common/src/xcm_config.rs @@ -144,13 +144,44 @@ impl Contains for ParentRelayOrSiblingParachains { } } +/// Filter to check if a given `target` location represents the same AccountId32 as `origin`, +/// but coming from another sibling system chain. +/// +/// This type should only be used within the context of a parachain, to allow accounts on system +/// chains to Alias to the same accounts on the local chain. +pub struct AliasAccountId32FromSiblingSystemChain; +impl ContainsPair for AliasAccountId32FromSiblingSystemChain { + fn contains(origin: &Location, target: &Location) -> bool { + let result = match origin.unpack() { + // `origin` is AccountId32 on sibling system parachain + (1, [Parachain(para_id), AccountId32 { network: _, id: origin }]) + if ParaId::from(*para_id).is_system() => + { + match target.unpack() { + // `target` is local AccountId32 and matches `origin` remote account + (0, [AccountId32 { network: _, id: target }]) => target.eq(origin), + _ => false, + } + }, + _ => false, + }; + log::trace!( + target: "xcm::contains", + "AliasAccountId32FromSiblingSystemChain origin: {:?}, target: {:?}, result {:?}", + origin, target, result, + ); + result + } +} + #[cfg(test)] mod tests { use frame_support::{parameter_types, traits::Contains}; use super::{ - AllSiblingSystemParachains, Asset, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, - Here, Location, PalletInstance, Parachain, Parent, + AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains, Asset, + ConcreteAssetFromSystem, ContainsPair, GeneralIndex, Here, Location, PalletInstance, + Parachain, Parent, }; use polkadot_primitives::LOWEST_PUBLIC_ID; use xcm::latest::prelude::*; @@ -221,4 +252,54 @@ mod tests { // when used with non-parachain assert!(!AllSiblingSystemParachains::contains(&Location::new(1, [OnlyChild]))); } + + #[test] + fn alias_accountid32_from_sibling_system_parachains() { + let acc_42 = AccountId32 { network: None, id: [42u8; 32] }; + let acc_13 = AccountId32 { network: None, id: [13u8; 32] }; + // origin acc_42 on sibling system parachain aliases into local acc_42 + assert!(AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(0, [acc_42]) + )); + // if target is not local account, always fails + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(0, []) + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(0, [Parachain(1)]) + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(0, [GeneralIndex(42)]) + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(1, [acc_42]) + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_42]), + &Location::new(2, [acc_42]) + )); + // origin acc_13 on sibling system parachain CANNOT alias into local acc_42 + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(1), acc_13]), + &Location::new(0, [acc_42]) + )); + // origin acc_42 on sibling non-system parachain CANNOT alias into local acc_42 + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(1, [Parachain(LOWEST_PUBLIC_ID.into()), acc_42]), + &Location::new(0, [acc_42]) + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(0, [acc_13]), + &Location::new(0, [acc_13]), + )); + assert!(!AliasAccountId32FromSiblingSystemChain::contains( + &Location::new(0, [acc_42]), + &Location::new(1, [Parachain(1), acc_42]), + )); + } } diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index 7fe753cdbf8b4..383e6864d788e 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -745,3 +745,80 @@ macro_rules! test_xcm_fee_querying_apis_work_for_asset_hub { } }; } + +#[macro_export] +macro_rules! test_cross_chain_alias { + ( vec![$( ($sender_para:ty, $receiver_para:ty, $is_teleport:expr, $expected_success:expr) ),+], $origin:expr, $target:expr, $fees:expr ) => { + $crate::macros::paste::paste! { + use xcm::latest::AssetTransferFilter; + $( + { + let para_destination = <$sender_para>::sibling_location_of(<$receiver_para>::para_id()); + let account: AccountId = $origin.clone().into(); + $sender_para::fund_accounts(vec![(account.clone(), $fees * 10)]); + let total_fees: Asset = (Location::parent(), $fees).into(); + let fees: Asset = (Location::parent(), $fees / 2).into(); + + let remote_fees = if $is_teleport { + Some(AssetTransferFilter::Teleport(fees.clone().into())) + } else { + let source_para_sa = <$receiver_para>::sovereign_account_id_of( + <$receiver_para>::sibling_location_of(<$sender_para>::para_id()), + ); + $receiver_para::fund_accounts(vec![(source_para_sa, $fees * 10)]); + Some(AssetTransferFilter::ReserveWithdraw(fees.clone().into())) + }; + <$sender_para>::execute_with(|| { + type RuntimeEvent = <$sender_para as $crate::macros::Chain>::RuntimeEvent; + let xcm_message = Xcm::<()>(vec![ + WithdrawAsset(total_fees.into()), + PayFees { asset: fees.clone() }, + InitiateTransfer { + destination: para_destination, + remote_fees, + preserve_origin: true, + assets: BoundedVec::new(), + remote_xcm: Xcm(vec![ + // try to alias into `account` + AliasOrigin($target.clone().into()), + RefundSurplus, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: $target.clone().into(), + }, + ]), + }, + RefundSurplus, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: account.clone().into() }, + ]); + + let signed_origin = <$sender_para as Chain>::RuntimeOrigin::signed(account.into()); + assert_ok!(<$sender_para as [<$sender_para Pallet>]>::PolkadotXcm::execute( + signed_origin, + bx!(xcm::VersionedXcm::from(xcm_message.into())), + Weight::MAX + )); + assert_expected_events!( + $sender_para, + vec![ + RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + <$receiver_para>::execute_with(|| { + type RuntimeEvent = <$receiver_para as $crate::macros::Chain>::RuntimeEvent; + assert_expected_events!( + $receiver_para, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { + success, .. + }) => { success: *success == $expected_success, }, + ] + ); + }); + } + )+ + } + }; +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs index 6356e48f0e1a4..1cb148e05f847 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs @@ -63,10 +63,12 @@ mod imports { genesis::{AssetHubWestendAssetOwner, ED as ASSET_HUB_WESTEND_ED}, AssetHubWestendParaPallet as AssetHubWestendPallet, }, - bridge_hub_westend_emulated_chain::bridge_hub_westend_runtime::xcm_config::{ - self as bhw_xcm_config, + bridge_hub_westend_emulated_chain::{ + bridge_hub_westend_runtime::xcm_config::{self as bhw_xcm_config}, + BridgeHubWestendParaPallet as BridgeHubWestendPallet, }, collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet, + coretime_westend_emulated_chain::CoretimeWestendParaPallet as CoretimeWestendPallet, penpal_emulated_chain::{ penpal_runtime::xcm_config::{ CustomizableAssetFromSystemAssetHub as PenpalCustomizableAssetFromSystemAssetHub, @@ -78,6 +80,7 @@ mod imports { PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner, PenpalBParaPallet as PenpalBPallet, }, + people_westend_emulated_chain::PeopleWestendParaPallet as PeopleWestendPallet, westend_emulated_chain::{ genesis::ED as WESTEND_ED, westend_runtime::{ @@ -94,10 +97,12 @@ mod imports { AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaReceiver as BridgeHubWestendReceiver, - CollectivesWestendPara as CollectivesWestend, PenpalAPara as PenpalA, - PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender, - PenpalBPara as PenpalB, PenpalBParaReceiver as PenpalBReceiver, WestendRelay as Westend, - WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender, + CollectivesWestendPara as CollectivesWestend, CoretimeWestendPara as CoretimeWestend, + PenpalAPara as PenpalA, PenpalAParaReceiver as PenpalAReceiver, + PenpalAParaSender as PenpalASender, PenpalBPara as PenpalB, + PenpalBParaReceiver as PenpalBReceiver, PeopleWestendPara as PeopleWestend, + WestendRelay as Westend, WestendRelayReceiver as WestendReceiver, + WestendRelaySender as WestendSender, }; pub const ASSET_ID: u32 = 3; diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/aliases.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/aliases.rs new file mode 100644 index 0000000000000..6dbcc1edb5163 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/aliases.rs @@ -0,0 +1,181 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to XCM aliasing. + +use crate::imports::*; +use emulated_integration_tests_common::{macros::AccountId, test_cross_chain_alias}; +use frame_support::{traits::ContainsPair, BoundedVec}; +use xcm::latest::Junctions::*; + +const DENIED: bool = false; + +const TELEPORT_FEES: bool = true; +const RESERVE_TRANSFER_FEES: bool = false; + +#[test] +fn account_on_sibling_syschain_aliases_into_same_local_account() { + // origin and target are the same account on different chains + let origin: AccountId = [1; 32].into(); + let target = origin.clone(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // On Asset Hub we don't want to support aliasing from other chains: + // - there is no real world demand for it, the direction is usually reversed, users already have + // accounts on AH and want to use them cross-chain on other chains, + // - without real world demand, it's better to keep AH permissions as tight as possible. + // Aliasing same account doesn't work on AH. + test_cross_chain_alias!( + vec![ + // between BH and AH: denied + (BridgeHubWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Collectives and AH: denied + (CollectivesWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Coretime and AH: denied + (CoretimeWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between People and AH: denied + (PeopleWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Penpal and AH: denied + (PenpalA, AssetHubWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn account_on_sibling_syschain_cannot_alias_into_different_local_account() { + // origin and target are different accounts on different chains + let origin: AccountId = [1; 32].into(); + let target: AccountId = [2; 32].into(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing different account on different chains + test_cross_chain_alias!( + vec![ + // between BH and AH: denied + (BridgeHubWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Collectives and AH: denied + (CollectivesWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Coretime and AH: denied + (CoretimeWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between People and AH: denied + (PeopleWestend, AssetHubWestend, TELEPORT_FEES, DENIED), + // between Penpal and AH: denied + (PenpalA, AssetHubWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn aliasing_child_locations() { + use AssetHubWestendXcmConfig as XcmConfig; + // Allows aliasing descendant of origin. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(1, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(1, X3([Parachain(8), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Does not allow if not descendant. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(0, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} + +#[test] +fn asset_hub_root_aliases_anything() { + use AssetHubWestendXcmConfig as XcmConfig; + + // Does not allow local/AH root to alias other locations. + let origin = Location::new(1, X1([Parachain(1000)].into())); + + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X3([Parachain(42), PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other AH locations cannot alias anything. + let origin = Location::new(1, X2([Parachain(1000), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X2([Parachain(1000), PalletInstance(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new( + 1, + X2([Parachain(1000), AccountId32 { network: None, id: [1u8; 32] }].into()), + ); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other root locations cannot alias anything. + let origin = Location::new(1, Here); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + let origin = Location::new(0, Here); + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1001)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1002)].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs index 576c44fc542fd..181fc2c4290f8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/mod.rs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod aliases; mod claim_assets; mod fellowship_treasury; mod hybrid_transfers; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 1a7d57561a662..6afa790cfce09 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -50,7 +50,8 @@ mod imports { AssetHubWestendParaPallet as AssetHubWestendPallet, }, bridge_hub_westend_emulated_chain::{ - genesis::ED as BRIDGE_HUB_WESTEND_ED, BridgeHubWestendExistentialDeposit, + bridge_hub_westend_runtime, genesis::ED as BRIDGE_HUB_WESTEND_ED, + BridgeHubWestendExistentialDeposit, BridgeHubWestendParaPallet as BridgeHubWestendPallet, BridgeHubWestendRuntimeOrigin, BridgeHubWestendXcmConfig, }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/aliases.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/aliases.rs new file mode 100644 index 0000000000000..45c72a9ee388f --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/aliases.rs @@ -0,0 +1,165 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to XCM aliasing. + +use crate::imports::*; +use bridge_hub_westend_runtime::xcm_config::XcmConfig; +use emulated_integration_tests_common::{macros::AccountId, test_cross_chain_alias}; +use frame_support::{traits::ContainsPair, BoundedVec}; +use xcm::latest::Junctions::*; + +const DENIED: bool = false; + +const TELEPORT_FEES: bool = true; +const RESERVE_TRANSFER_FEES: bool = false; + +#[test] +fn account_on_sibling_syschain_aliases_into_same_local_account() { + // origin and target are the same account on different chains + let origin: AccountId = [1; 32].into(); + let target = origin.clone(); + let fees = WESTEND_ED * 10; + + PenpalB::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // On Bridge Hub we don't want to support aliasing from other chains: there is no real world + // demand for it, only low-level power users (like relayers) directly interact with Bridge + // Hub. They don't need aliasing to operate cross-chain they can operate locally. + // Aliasing same account doesn't work on BH. + test_cross_chain_alias!( + vec![ + // between AH and BH: denied + (AssetHubWestend, BridgeHubWestend, TELEPORT_FEES, DENIED), + // between Penpal and BH: denied + (PenpalB, BridgeHubWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn account_on_sibling_syschain_cannot_alias_into_different_local_account() { + // origin and target are different accounts on different chains + let origin: AccountId = [1; 32].into(); + let target: AccountId = [2; 32].into(); + let fees = WESTEND_ED * 10; + + PenpalB::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing different account on different chains + test_cross_chain_alias!( + vec![ + // between AH and BH: denied + (AssetHubWestend, BridgeHubWestend, TELEPORT_FEES, DENIED), + // between Penpal and BH: denied + (PenpalB, BridgeHubWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn aliasing_child_locations() { + // Bridge Hub doesn't allow aliasing descendant of origin. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(1, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(1, X3([Parachain(8), PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + // Does not allow if not descendant. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(0, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} + +#[test] +fn asset_hub_root_aliases_anything() { + // Does not allow AH root to alias other locations. + let origin = Location::new(1, X1([Parachain(1000)].into())); + + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X3([Parachain(42), PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other AH locations cannot alias anything. + let origin = Location::new(1, X2([Parachain(1000), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X2([Parachain(1000), PalletInstance(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new( + 1, + X2([Parachain(1000), AccountId32 { network: None, id: [1u8; 32] }].into()), + ); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other root locations cannot alias anything. + let origin = Location::new(1, Here); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + let origin = Location::new(0, Here); + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1001)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1002)].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index 2c5a2e649fabe..7363373d0dd81 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -15,6 +15,7 @@ use crate::imports::*; +mod aliases; mod asset_transfers; mod claim_assets; mod register_bridged_assets; diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs index e2048b62c3112..43f03a7013889 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs @@ -20,6 +20,7 @@ pub use emulated_integration_tests_common::{ test_parachain_is_trusted_teleporter, xcm_emulator::{assert_expected_events, bx, Chain, Parachain, RelayChain as Relay, TestExt}, }; +pub use frame_support::assert_ok; pub use westend_system_emulated_network::{ asset_hub_westend_emulated_chain::{ asset_hub_westend_runtime::xcm_config::{ @@ -29,6 +30,7 @@ pub use westend_system_emulated_network::{ genesis::ED as ASSET_HUB_WESTEND_ED, AssetHubWestendParaPallet as AssetHubWestendPallet, }, + bridge_hub_westend_emulated_chain::BridgeHubWestendParaPallet as BridgeHubWestendPallet, collectives_westend_emulated_chain::{ collectives_westend_runtime::{ fellowship as collectives_fellowship, @@ -37,6 +39,12 @@ pub use westend_system_emulated_network::{ genesis::ED as COLLECTIVES_WESTEND_ED, CollectivesWestendParaPallet as CollectivesWestendPallet, }, + coretime_westend_emulated_chain::{ + coretime_westend_runtime::ExistentialDeposit as CoretimeWestendExistentialDeposit, + CoretimeWestendParaPallet as CoretimeWestendPallet, + }, + penpal_emulated_chain::{PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner}, + people_westend_emulated_chain::PeopleWestendParaPallet as PeopleWestendPallet, westend_emulated_chain::{ genesis::ED as WESTEND_ED, westend_runtime::{ @@ -46,10 +54,12 @@ pub use westend_system_emulated_network::{ WestendRelayPallet as WestendPallet, }, AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver, - AssetHubWestendParaSender as AssetHubWestendSender, + AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend, CollectivesWestendPara as CollectivesWestend, CollectivesWestendParaReceiver as CollectivesWestendReceiver, - CollectivesWestendParaSender as CollectivesWestendSender, WestendRelay as Westend, + CollectivesWestendParaSender as CollectivesWestendSender, + CoretimeWestendPara as CoretimeWestend, PenpalAPara as PenpalA, + PeopleWestendPara as PeopleWestend, WestendRelay as Westend, WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/aliases.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/aliases.rs new file mode 100644 index 0000000000000..220b7e8f77d49 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/aliases.rs @@ -0,0 +1,177 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to XCM aliasing. + +use crate::*; +use emulated_integration_tests_common::{macros::AccountId, test_cross_chain_alias}; +use frame_support::{traits::ContainsPair, BoundedVec}; +use xcm::latest::Junctions::*; + +const ALLOWED: bool = true; +const DENIED: bool = false; + +const TELEPORT_FEES: bool = true; +const RESERVE_TRANSFER_FEES: bool = false; + +#[test] +fn account_on_sibling_syschain_aliases_into_same_local_account() { + // origin and target are the same account on different chains + let origin: AccountId = [1; 32].into(); + let target = origin.clone(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing same account on different chains + test_cross_chain_alias!( + vec![ + // between AH and Collectives: allowed + (AssetHubWestend, CollectivesWestend, TELEPORT_FEES, ALLOWED), + // between BH and Collectives: allowed + (BridgeHubWestend, CollectivesWestend, TELEPORT_FEES, ALLOWED), + // between Coretime and Collectives: allowed + (CoretimeWestend, CollectivesWestend, TELEPORT_FEES, ALLOWED), + // between People and Collectives: allowed + (PeopleWestend, CollectivesWestend, TELEPORT_FEES, ALLOWED), + // between Penpal and Collectives: denied + (PenpalA, CollectivesWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn account_on_sibling_syschain_cannot_alias_into_different_local_account() { + // origin and target are different accounts on different chains + let origin: AccountId = [1; 32].into(); + let target: AccountId = [2; 32].into(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing different account on different chains + test_cross_chain_alias!( + vec![ + // between AH and Collectives: denied + (AssetHubWestend, CollectivesWestend, TELEPORT_FEES, DENIED), + // between BH and Collectives: denied + (BridgeHubWestend, CollectivesWestend, TELEPORT_FEES, DENIED), + // between Coretime and Collectives: denied + (CoretimeWestend, CollectivesWestend, TELEPORT_FEES, DENIED), + // between People and Collectives: denied + (PeopleWestend, CollectivesWestend, TELEPORT_FEES, DENIED), + // between Penpal and Collectives: denied + (PenpalA, CollectivesWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn aliasing_child_locations() { + use CollectivesWestendXcmConfig as XcmConfig; + // Allows aliasing descendant of origin. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(1, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(1, X3([Parachain(8), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Does not allow if not descendant. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(0, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} + +#[test] +fn asset_hub_root_aliases_anything() { + use CollectivesWestendXcmConfig as XcmConfig; + // Allows AH root to alias anything. + let origin = Location::new(1, X1([Parachain(1000)].into())); + + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X3([Parachain(42), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Other AH locations cannot alias anything. + let origin = Location::new(1, X2([Parachain(1000), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X2([Parachain(1000), PalletInstance(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new( + 1, + X2([Parachain(1000), AccountId32 { network: None, id: [1u8; 32] }].into()), + ); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other root locations cannot alias anything. + let origin = Location::new(1, Here); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + let origin = Location::new(0, Here); + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1001)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1002)].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs index ef4e4885183d0..a3fa1ce3e2f37 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod aliases; mod fellowship; mod fellowship_salary; mod fellowship_treasury; diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/Cargo.toml index 9f0eadf136501..8dbbd38cdded3 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/Cargo.toml @@ -15,6 +15,7 @@ pallet-balances = { workspace = true } pallet-broker = { workspace = true, default-features = true } pallet-identity = { workspace = true } pallet-message-queue = { workspace = true } +pallet-xcm = { workspace = true } sp-runtime = { workspace = true } # Polkadot diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/lib.rs index 4fb619aba3d39..44efa40e4ea6e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/lib.rs @@ -27,13 +27,22 @@ mod imports { assert_expected_events, bx, Chain, Parachain, TestExt, }; pub use westend_system_emulated_network::{ + asset_hub_westend_emulated_chain::AssetHubWestendParaPallet as AssetHubWestendPallet, + bridge_hub_westend_emulated_chain::BridgeHubWestendParaPallet as BridgeHubWestendPallet, + collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet, coretime_westend_emulated_chain::{ + self, coretime_westend_runtime::ExistentialDeposit as CoretimeWestendExistentialDeposit, CoretimeWestendParaPallet as CoretimeWestendPallet, }, - CoretimeWestendPara as CoretimeWestend, + penpal_emulated_chain::{PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner}, + people_westend_emulated_chain::PeopleWestendParaPallet as PeopleWestendPallet, + westend_emulated_chain::genesis::ED as WESTEND_ED, + AssetHubWestendPara as AssetHubWestend, BridgeHubWestendPara as BridgeHubWestend, + CollectivesWestendPara as CollectivesWestend, CoretimeWestendPara as CoretimeWestend, CoretimeWestendParaReceiver as CoretimeWestendReceiver, - CoretimeWestendParaSender as CoretimeWestendSender, WestendRelay as Westend, + CoretimeWestendParaSender as CoretimeWestendSender, PenpalAPara as PenpalA, + PeopleWestendPara as PeopleWestend, WestendRelay as Westend, }; } diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/aliases.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/aliases.rs new file mode 100644 index 0000000000000..ccaf53a8d0993 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/aliases.rs @@ -0,0 +1,176 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to XCM aliasing. + +use crate::imports::*; +use coretime_westend_emulated_chain::coretime_westend_runtime::xcm_config::XcmConfig; +use emulated_integration_tests_common::{macros::AccountId, test_cross_chain_alias}; +use frame_support::{traits::ContainsPair, BoundedVec}; +use xcm::latest::Junctions::*; + +const ALLOWED: bool = true; +const DENIED: bool = false; + +const TELEPORT_FEES: bool = true; +const RESERVE_TRANSFER_FEES: bool = false; + +#[test] +fn account_on_sibling_syschain_aliases_into_same_local_account() { + // origin and target are the same account on different chains + let origin: AccountId = [1; 32].into(); + let target = origin.clone(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing same account on different chains + test_cross_chain_alias!( + vec![ + // between AH and Coretime: allowed + (AssetHubWestend, CoretimeWestend, TELEPORT_FEES, ALLOWED), + // between BH and Coretime: allowed + (BridgeHubWestend, CoretimeWestend, TELEPORT_FEES, ALLOWED), + // between Collectives and Coretime: allowed + (CollectivesWestend, CoretimeWestend, TELEPORT_FEES, ALLOWED), + // between People and Coretime: allowed + (PeopleWestend, CoretimeWestend, TELEPORT_FEES, ALLOWED), + // between Penpal and Coretime: denied + (PenpalA, CoretimeWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn account_on_sibling_syschain_cannot_alias_into_different_local_account() { + // origin and target are different accounts on different chains + let origin: AccountId = [1; 32].into(); + let target: AccountId = [2; 32].into(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing different account on different chains + test_cross_chain_alias!( + vec![ + // between AH and Coretime: denied + (AssetHubWestend, CoretimeWestend, TELEPORT_FEES, DENIED), + // between BH and Coretime: denied + (BridgeHubWestend, CoretimeWestend, TELEPORT_FEES, DENIED), + // between Collectives and Coretime: denied + (CollectivesWestend, CoretimeWestend, TELEPORT_FEES, DENIED), + // between People and Coretime: denied + (PeopleWestend, CoretimeWestend, TELEPORT_FEES, DENIED), + // between Penpal and Coretime: denied + (PenpalA, CoretimeWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn aliasing_child_locations() { + // Allows aliasing descendant of origin. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(1, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(1, X3([Parachain(8), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Does not allow if not descendant. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(0, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} + +#[test] +fn asset_hub_root_aliases_anything() { + // Allows AH root to alias anything. + let origin = Location::new(1, X1([Parachain(1000)].into())); + + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X3([Parachain(42), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Other AH locations cannot alias anything. + let origin = Location::new(1, X2([Parachain(1000), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X2([Parachain(1000), PalletInstance(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new( + 1, + X2([Parachain(1000), AccountId32 { network: None, id: [1u8; 32] }].into()), + ); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other root locations cannot alias anything. + let origin = Location::new(1, Here); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + let origin = Location::new(0, Here); + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1001)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1002)].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/mod.rs index bb0387a4b3502..9257cb2d904f8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/mod.rs @@ -13,5 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod aliases; mod claim_assets; mod coretime_interface; diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/lib.rs index 59d87e1ea3f03..6223af15b849c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/lib.rs @@ -30,9 +30,14 @@ mod imports { pub use parachains_common::Balance; pub use westend_system_emulated_network::{ self, + asset_hub_westend_emulated_chain::AssetHubWestendParaPallet as AssetHubWestendPallet, + bridge_hub_westend_emulated_chain::BridgeHubWestendParaPallet as BridgeHubWestendPallet, + collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet, + coretime_westend_emulated_chain::CoretimeWestendParaPallet as CoretimeWestendPallet, + penpal_emulated_chain::{PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner}, people_westend_emulated_chain::{ people_westend_runtime::{ - xcm_config::XcmConfig as PeopleWestendXcmConfig, + self, xcm_config::XcmConfig as PeopleWestendXcmConfig, ExistentialDeposit as PeopleWestendExistentialDeposit, }, PeopleWestendParaPallet as PeopleWestendPallet, @@ -41,7 +46,10 @@ mod imports { genesis::ED as WESTEND_ED, westend_runtime::xcm_config::XcmConfig as WestendXcmConfig, WestendRelayPallet as WestendPallet, }, - PeopleWestendPara as PeopleWestend, PeopleWestendParaReceiver as PeopleWestendReceiver, + AssetHubWestendPara as AssetHubWestend, BridgeHubWestendPara as BridgeHubWestend, + CollectivesWestendPara as CollectivesWestend, CoretimeWestendPara as CoretimeWestend, + PenpalAPara as PenpalA, PeopleWestendPara as PeopleWestend, + PeopleWestendParaReceiver as PeopleWestendReceiver, PeopleWestendParaSender as PeopleWestendSender, WestendRelay as Westend, WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/aliases.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/aliases.rs new file mode 100644 index 0000000000000..511602ecd9770 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/aliases.rs @@ -0,0 +1,177 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to XCM aliasing. + +use crate::imports::*; +use emulated_integration_tests_common::{macros::AccountId, test_cross_chain_alias}; +use frame_support::{traits::ContainsPair, BoundedVec}; +use xcm::latest::Junctions::*; + +const ALLOWED: bool = true; +const DENIED: bool = false; + +const TELEPORT_FEES: bool = true; +const RESERVE_TRANSFER_FEES: bool = false; + +#[test] +fn account_on_sibling_syschain_aliases_into_same_local_account() { + // origin and target are the same account on different chains + let origin: AccountId = [1; 32].into(); + let target = origin.clone(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing same account on different chains + test_cross_chain_alias!( + vec![ + // between AH and People: allowed + (AssetHubWestend, PeopleWestend, TELEPORT_FEES, ALLOWED), + // between BH and People: allowed + (BridgeHubWestend, PeopleWestend, TELEPORT_FEES, ALLOWED), + // between Collectives and People: allowed + (CollectivesWestend, PeopleWestend, TELEPORT_FEES, ALLOWED), + // between Coretime and People: allowed + (CoretimeWestend, PeopleWestend, TELEPORT_FEES, ALLOWED), + // between Penpal and People: denied + (PenpalA, PeopleWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn account_on_sibling_syschain_cannot_alias_into_different_local_account() { + // origin and target are different accounts on different chains + let origin: AccountId = [1; 32].into(); + let target: AccountId = [2; 32].into(); + let fees = WESTEND_ED * 10; + + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + Location::parent(), + origin.clone(), + fees * 10, + ); + + // Aliasing different account on different chains + test_cross_chain_alias!( + vec![ + // between AH and People: denied + (AssetHubWestend, PeopleWestend, TELEPORT_FEES, DENIED), + // between BH and People: denied + (BridgeHubWestend, PeopleWestend, TELEPORT_FEES, DENIED), + // between Collectives and People: denied + (CollectivesWestend, PeopleWestend, TELEPORT_FEES, DENIED), + // between Coretime and People: denied + (CoretimeWestend, PeopleWestend, TELEPORT_FEES, DENIED), + // between Penpal and People: denied + (PenpalA, PeopleWestend, RESERVE_TRANSFER_FEES, DENIED) + ], + origin, + target, + fees + ); +} + +#[test] +fn aliasing_child_locations() { + use PeopleWestendXcmConfig as XcmConfig; + // Allows aliasing descendant of origin. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(1, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(1, X3([Parachain(8), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Does not allow if not descendant. + let origin = Location::new(1, X1([PalletInstance(8)].into())); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = + Location::new(0, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(8)].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + let target = Location::new(0, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} + +#[test] +fn asset_hub_root_aliases_anything() { + use PeopleWestendXcmConfig as XcmConfig; + // Allows AH root to alias anything. + let origin = Location::new(1, X1([Parachain(1000)].into())); + + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X1([AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = + Location::new(1, X2([Parachain(8), AccountId32 { network: None, id: [1u8; 32] }].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(1, X3([Parachain(42), PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(::Aliasers::contains(&origin, &target)); + + // Other AH locations cannot alias anything. + let origin = Location::new(1, X2([Parachain(1000), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X2([Parachain(1000), PalletInstance(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new( + 1, + X2([Parachain(1000), AccountId32 { network: None, id: [1u8; 32] }].into()), + ); + assert!(!::Aliasers::contains(&origin, &target)); + + // Other root locations cannot alias anything. + let origin = Location::new(1, Here); + let target = Location::new(2, X1([GlobalConsensus(Ethereum { chain_id: 1 })].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(2, X2([GlobalConsensus(Polkadot), Parachain(1000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let target = Location::new(0, X2([PalletInstance(8), GeneralIndex(9)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + + let origin = Location::new(0, Here); + let target = Location::new(1, X1([Parachain(2000)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1001)].into())); + assert!(!::Aliasers::contains(&origin, &target)); + let origin = Location::new(1, X1([Parachain(1002)].into())); + assert!(!::Aliasers::contains(&origin, &target)); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/identity.rs new file mode 100644 index 0000000000000..cbe66d330b90c --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/identity.rs @@ -0,0 +1,108 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests related to cross-chain identity operations. + +use crate::imports::*; +use codec::Encode; +use emulated_integration_tests_common::accounts::ALICE; +use frame_support::BoundedVec; +use pallet_identity::Data; +use people_westend_runtime::people::{IdentityField, IdentityInfo}; +use xcm::latest::AssetTransferFilter; + +#[test] +fn set_identity_cross_chain() { + type Identity = ::Identity; + + let asset_hub_westend_alice = AssetHubWestend::account_id_of(ALICE); + let people_westend_alice = PeopleWestend::account_id_of(ALICE); + AssetHubWestend::fund_accounts(vec![(asset_hub_westend_alice.clone(), WESTEND_ED * 10000)]); + PeopleWestend::fund_accounts(vec![(people_westend_alice.clone(), WESTEND_ED * 10000)]); + + PeopleWestend::execute_with(|| { + // No identity for Alice + assert!(!Identity::has_identity(&people_westend_alice, IdentityField::Email as u64)); + }); + + let destination = AssetHubWestend::sibling_location_of(PeopleWestend::para_id()); + let total_fees: Asset = (Location::parent(), WESTEND_ED * 1000).into(); + let fees: Asset = (Location::parent(), WESTEND_ED * 500).into(); + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + let identity_info = IdentityInfo { + email: Data::Raw(b"test@test.io".to_vec().try_into().unwrap()), + ..Default::default() + }; + // Set Alice identity on People from Alice on AH + let set_identity_call = + ::RuntimeCall::Identity(pallet_identity::Call::< + ::Runtime, + >::set_identity { + info: bx!(identity_info), + }); + let xcm_message = Xcm::<()>(vec![ + WithdrawAsset(total_fees.into()), + PayFees { asset: fees.clone() }, + InitiateTransfer { + destination, + remote_fees: Some(AssetTransferFilter::Teleport(fees.clone().into())), + preserve_origin: true, + assets: BoundedVec::new(), + remote_xcm: Xcm(vec![ + // try to alias into `Alice` account local to People chain + AliasOrigin(people_westend_alice.clone().into()), + // set identity for the local Alice account + Transact { + origin_kind: OriginKind::SovereignAccount, + call: set_identity_call.encode().into(), + fallback_max_weight: None, + }, + RefundSurplus, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: people_westend_alice.clone().into(), + }, + ]), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + RefundSurplus, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: asset_hub_westend_alice.clone().into(), + }, + ]); + + let signed_origin = + ::RuntimeOrigin::signed(asset_hub_westend_alice); + assert_ok!(::PolkadotXcm::execute( + signed_origin, + bx!(xcm::VersionedXcm::from(xcm_message.into())), + Weight::MAX + )); + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + PeopleWestend::execute_with(|| { + // Verify Alice on People now has identity + assert!(Identity::has_identity(&people_westend_alice, IdentityField::Email as u64)); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/mod.rs index b9ad9e3db467f..8b7470a567ef2 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/mod.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod aliases; mod claim_assets; mod governance; +mod identity; mod teleport; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index 897352369671c..3706bfe22a3c8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -264,8 +264,7 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { XcmGeneric::::clear_topic() } fn alias_origin(_: &Location) -> Weight { - // XCM Executor does not currently support alias origin operations - Weight::MAX + XcmGeneric::::alias_origin() } fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 4a3eed179a7cc..041afda4493bd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -373,4 +373,11 @@ impl WeightInfo { // Minimum execution time: 1_074_000 picoseconds. Weight::from_parts(1_225_000, 0) } + pub fn alias_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_050_000 picoseconds. + Weight::from_parts(1_135_000, 0) + } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index 07b6e563969f3..112c1740d7d31 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -26,8 +26,8 @@ use frame_system::EnsureRoot; use pallet_collator_selection::StakingPotAccountId; use pallet_xcm::XcmPassthrough; use parachains_common::xcm_config::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, - RelayOrOtherSystemParachains, + AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains, ConcreteAssetFromSystem, + ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, }; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; @@ -186,9 +186,13 @@ pub type WaivedLocations = ( /// - DOT with the parent Relay Chain and sibling parachains. pub type TrustedTeleporters = ConcreteAssetFromSystem; -/// We allow locations to alias into their own child locations, as well as -/// AssetHub to alias into anything. -pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); +/// We allow locations to alias into their own child locations, allow AssetHub root to alias into +/// anything, and allow same accounts to alias into each other across system chains. +pub type Aliasers = ( + AliasChildLocation, + AliasOriginRootUsingFilter, + AliasAccountId32FromSiblingSystemChain, +); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index c8322573b4692..6b88669f18f62 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -29,8 +29,8 @@ use pallet_collator_selection::StakingPotAccountId; use pallet_xcm::XcmPassthrough; use parachains_common::{ xcm_config::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, - RelayOrOtherSystemParachains, + AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains, + ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, }, TREASURY_PALLET_ID, }; @@ -197,9 +197,13 @@ pub type WaivedLocations = ( Equals, ); -/// We allow locations to alias into their own child locations, as well as -/// AssetHub to alias into anything. -pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); +/// We allow locations to alias into their own child locations, allow AssetHub root to alias into +/// anything, and allow same accounts to alias into each other across system chains. +pub type Aliasers = ( + AliasChildLocation, + AliasOriginRootUsingFilter, + AliasAccountId32FromSiblingSystemChain, +); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 2e78772ca7c30..7a07153aa8fd7 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -27,8 +27,8 @@ use pallet_collator_selection::StakingPotAccountId; use pallet_xcm::XcmPassthrough; use parachains_common::{ xcm_config::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, - RelayOrOtherSystemParachains, + AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains, + ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, }, TREASURY_PALLET_ID, }; @@ -201,9 +201,13 @@ pub type WaivedLocations = ( LocalPlurality, ); -/// We allow locations to alias into their own child locations, as well as -/// AssetHub to alias into anything. -pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); +/// We allow locations to alias into their own child locations, allow AssetHub root to alias into +/// anything, and allow same accounts to alias into each other across system chains. +pub type Aliasers = ( + AliasChildLocation, + AliasOriginRootUsingFilter, + AliasAccountId32FromSiblingSystemChain, +); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 06617822857d3..0718a82b158d1 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -53,7 +53,10 @@ use frame_support::{ }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; -use parachains_common::{xcm_config::AssetFeeAsExistentialDepositMultiplier, TREASURY_PALLET_ID}; +use parachains_common::{ + xcm_config::{AssetFeeAsExistentialDepositMultiplier, ConcreteAssetFromSystem}, + TREASURY_PALLET_ID, +}; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::{impls::ToAuthor, xcm_sender::ExponentialPrice}; use sp_runtime::traits::{AccountIdConversion, ConvertInto, Identity, TryConvertInto}; @@ -272,17 +275,6 @@ where type AssetsFrom = AssetPrefixFrom; -/// Asset filter that allows native/relay asset if coming from a certain location. -pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &Asset, origin: &Location) -> bool { - let loc = T::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } - if *asset_loc == Location::from(Parent)) - } -} - // This asset can be added to AH as Asset and reserved transfer between Penpal and AH pub const RESERVABLE_ASSET_ID: u32 = 1; // This asset can be added to AH as ForeignAsset and teleported between Penpal and AH @@ -337,8 +329,8 @@ impl, Origin: Get> ContainsPair, AssetsFrom, - NativeAssetFrom, AssetPrefixFrom, ); pub type TrustedTeleporters = diff --git a/prdoc/pr_7983.prdoc b/prdoc/pr_7983.prdoc new file mode 100644 index 0000000000000..3ba1ef29e4fe4 --- /dev/null +++ b/prdoc/pr_7983.prdoc @@ -0,0 +1,32 @@ +title: '[XCM] allow signed account to be aliased between system chains' +doc: +- audience: Runtime Dev + description: |- + New alias filter available `AliasAccountId32FromSiblingSystemChain`: + that allows account `X` on a system chain to alias itself on another chain where the filter is installed. + Enables UX improvements like configuring other chains to allow signed account on AH to operate over XCM on another chain using the same signed account on the remote chain (rather than use a sovereign account). +- audience: Runtime User + description: |- + Aliasing configuration change for system chains: + - Asset Hub: does not allow same account aliasing: there is no real world demand for it, the direction is usually reversed, users already have accounts on AH and want to use them cross-chain on other chains. Without real world demand, it's better to keep AH permissions as tight as possible. + - Bridge Hub: does not allow same account aliasing: there is no real world demand for it, only low-level power users (like relayers) directly interact with Bridge Hub. They don't need aliasing to operate cross-chain they can operate locally. + - Collectives: allows account A on a sibling system chain to alias into the local account A. + - Coretime: allows account A on a sibling system chain to alias into the local account A. + - People: allows account A on a sibling system chain to alias into the local account A. + Practical example showcased with new configuration: + `Alice` on AssetHub can set identity for `Alice` on People over XCM. +crates: +- name: parachains-common + bump: patch +- name: people-westend-runtime + bump: major +- name: emulated-integration-tests-common + bump: patch +- name: penpal-runtime + bump: major +- name: coretime-westend-runtime + bump: major +- name: collectives-westend-runtime + bump: major +- name: bridge-hub-westend-runtime + bump: major