diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs index 51b6543bae82..b05fd39fa9d0 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 08b2f520c4b9..99a5b5c61506 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -452,8 +452,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// Converts a local signed origin into an XCM location. -/// Forms the basis for local origins sending/executing XCMs. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type PriceForParentDelivery = diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs index be3d7661ab3c..65943a0d6bc2 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index b4e938f1f8b5..34aa50bcb029 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -15,10 +15,10 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, - CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, - ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, - XcmpQueue, + CollatorSelection, DepositPerByte, DepositPerItem, FeeAssetId, ForeignAssets, + ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, + RuntimeCall, RuntimeEvent, RuntimeHoldReason, RuntimeOrigin, ToRococoXcmRouter, + TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, XcmpQueue, }; use assets_common::{ matching::{FromSiblingParachain, IsForeignConcreteAsset, ParentLocation}, @@ -27,12 +27,13 @@ use assets_common::{ use frame_support::{ parameter_types, traits::{ + fungible::HoldConsideration, tokens::imbalance::{ResolveAssetTo, ResolveTo}, - ConstU32, Contains, Equals, Everything, PalletInfoAccess, + ConstU32, Contains, Equals, Everything, LinearStoragePrice, PalletInfoAccess, }, }; use frame_system::EnsureRoot; -use pallet_xcm::XcmPassthrough; +use pallet_xcm::{AuthorizedAliasers, XcmPassthrough}; use parachains_common::{ xcm_config::{ AllSiblingSystemParachains, AssetFeeAsExistentialDepositMultiplier, @@ -353,6 +354,12 @@ pub type TrustedTeleporters = ( IsForeignConcreteAsset>>, ); +/// Defines origin aliasing rules for this chain. +/// +/// - Allow any origin to alias into a child sub-location (equivalent to DescendOrigin), +/// - Allow origins explicitly authorized by the alias target location. +pub type TrustedAliasers = (AliasChildLocation, AuthorizedAliasers); + /// Asset converter for pool assets. /// Used to convert one asset to another, when there is a pool available between the two. /// This type thus allows paying fees with any asset as long as there is a pool between said @@ -465,8 +472,7 @@ impl xcm_executor::Config for XcmConfig { (bridging::to_rococo::UniversalAliases, bridging::to_ethereum::UniversalAliases); type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - // We allow any origin to alias into a child sub-location (equivalent to DescendOrigin). - type Aliasers = AliasChildLocation; + type Aliasers = TrustedAliasers; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); @@ -474,7 +480,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// Local origins on this chain are allowed to dispatch XCM sends/executions. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type PriceForParentDelivery = @@ -504,6 +511,10 @@ pub type XcmRouter = WithUniqueTopic<( >, )>; +parameter_types! { + pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::PolkadotXcm(pallet_xcm::HoldReason::AuthorizeAlias); +} + impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SendXcmOrigin = EnsureXcmOrigin; @@ -532,6 +543,12 @@ impl pallet_xcm::Config for Runtime { type AdminOrigin = EnsureRoot; type MaxRemoteLockConsumers = ConstU32<0>; type RemoteLockConsumerIdentifier = (); + type Consideration = HoldConsideration< + AccountId, + Balances, + AuthorizeAliasHoldReason, + LinearStoragePrice, + >; } impl cumulus_pallet_xcm::Config for Runtime { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 5d0f843554a1..e64a365ca5bd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -43,6 +43,7 @@ use frame_support::{ fungibles::{ Create, Inspect as FungiblesInspect, InspectEnumerable, Mutate as FungiblesMutate, }, + ContainsPair, }, weights::{Weight, WeightToFee as WeightToFeeT}, }; @@ -54,7 +55,7 @@ use std::{convert::Into, ops::Mul}; use testnet_parachains_constants::westend::{consensus::*, currency::UNITS, fee::WeightToFee}; use xcm::latest::{ prelude::{Assets as XcmAssets, *}, - ROCOCO_GENESIS_HASH, + ROCOCO_GENESIS_HASH, WESTEND_GENESIS_HASH, }; use xcm_builder::WithLatestLocationConverter; use xcm_executor::traits::{ConvertLocation, JustTry, WeightTrader}; @@ -136,6 +137,7 @@ fn setup_pool_for_paying_fees_with_foreign_assets( #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -194,6 +196,7 @@ fn test_buy_and_refund_weight_in_native() { #[test] fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -303,6 +306,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { #[test] fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -413,6 +417,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { #[test] fn test_asset_xcm_take_first_trader() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -491,6 +496,7 @@ fn test_asset_xcm_take_first_trader() { #[test] fn test_foreign_asset_xcm_take_first_trader() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -572,6 +578,7 @@ fn test_foreign_asset_xcm_take_first_trader() { #[test] fn test_asset_xcm_take_first_trader_with_refund() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -651,6 +658,7 @@ fn test_asset_xcm_take_first_trader_with_refund() { #[test] fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_ed() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -703,6 +711,7 @@ fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_e #[test] fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -767,6 +776,7 @@ fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { #[test] fn test_asset_xcm_take_first_trader_not_possible_for_non_sufficient_assets() { ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -828,6 +838,7 @@ fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; ExtBuilder::::default() + .with_tracing() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( AccountId::from(ALICE), @@ -942,6 +953,92 @@ fn test_assets_balances_api_works() { }); } +#[test] +fn authorized_aliases_work() { + ExtBuilder::::default() + .with_tracing() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let alice: AccountId = ALICE.into(); + let local_alice = Location::new( + 0, + AccountId32 { network: Some(ByGenesis(WESTEND_GENESIS_HASH)), id: ALICE }, + ); + let alice_on_sibling_para = + Location::new(1, [Parachain(42), AccountId32 { network: None, id: ALICE }]); + let alice_on_relay = Location::new(1, AccountId32 { network: None, id: ALICE }); + let bob_on_relay = Location::new(1, AccountId32 { network: None, id: [42_u8; 32] }); + + // neither `alice_on_sibling_para`, `alice_on_relay`, `bob_on_relay` are allowed to + // alias into `local_alice` + for aliaser in [&alice_on_sibling_para, &alice_on_relay, &bob_on_relay] { + assert!(!::Aliasers::contains( + aliaser, + &local_alice + )); + } + + // Alice explicitly authorizes `alice_on_sibling_para` to alias her local account + assert_ok!(PolkadotXcm::add_authorized_alias( + RuntimeHelper::origin_of(alice.clone()), + Box::new(alice_on_sibling_para.clone().into()), + None + )); + + // `alice_on_sibling_para` now explicitly allowed to alias into `local_alice` + assert!(::Aliasers::contains( + &alice_on_sibling_para, + &local_alice + )); + // as expected, `alice_on_relay` and `bob_on_relay` still can't alias into `local_alice` + for aliaser in [&alice_on_relay, &bob_on_relay] { + assert!(!::Aliasers::contains( + aliaser, + &local_alice + )); + } + + // Alice explicitly authorizes `alice_on_relay` to alias her local account + assert_ok!(PolkadotXcm::add_authorized_alias( + RuntimeHelper::origin_of(alice.clone()), + Box::new(alice_on_relay.clone().into()), + None + )); + // Now both `alice_on_relay` and `alice_on_sibling_para` can alias into her local + // account + for aliaser in [&alice_on_relay, &alice_on_sibling_para] { + assert!(::Aliasers::contains( + aliaser, + &local_alice + )); + } + + // Alice removes authorization for `alice_on_relay` to alias her local account + assert_ok!(PolkadotXcm::remove_authorized_alias( + RuntimeHelper::origin_of(alice.clone()), + Box::new(alice_on_relay.clone().into()) + )); + + // `alice_on_relay` no longer allowed to alias into `local_alice` + assert!(!::Aliasers::contains( + &alice_on_relay, + &local_alice + )); + + // `alice_on_sibling_para` still allowed to alias into `local_alice` + assert!(::Aliasers::contains( + &alice_on_sibling_para, + &local_alice + )); + }) +} + asset_test_utils::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs index a732e1a57343..ce572fa16356 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index b37945317f6c..828d4b7486f8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -239,8 +239,8 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM location. -/// Forms the basis for local origins sending/executing XCMs. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs index a78ff2355efa..19ecbfb5727e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs index befb63ef9709..f2c32e31aa2a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs @@ -233,8 +233,8 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM location. -/// Forms the basis for local origins sending/executing XCMs. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs index 5d427d850046..043710b0d7ab 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w: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 56ef2e8ba02f..8d378ac3f400 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -235,8 +235,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// Converts a local signed origin into an XCM location. -/// Forms the basis for local origins sending/executing XCMs. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type PriceForParentDelivery = diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs index 532ad4ff4ce0..930e83ac84d6 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs @@ -210,8 +210,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// Converts a local signed origin into an XCM location. -/// Forms the basis for local origins sending/executing XCMs. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type PriceForParentDelivery = diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs index 7fb492173dad..9997422961fd 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs index fa588e982f09..42ef5c2b4071 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs index fabce29b5fd9..5a9c069c2e07 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs index c337289243b7..5307360e2713 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs @@ -48,6 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `498` + // Estimated: `3963` + // Minimum execution time: 19_789_000 picoseconds. + Weight::from_parts(20_317_000, 3963) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AuthorizedAliases` (r:1 w:1) + /// Proof: `PolkadotXcm::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `537` + // Estimated: `4002` + // Minimum execution time: 20_805_000 picoseconds. + Weight::from_parts(21_481_000, 4002) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 10481d5d2ebc..e2b010c3227d 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -426,7 +426,8 @@ pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger = ForeignAssetsInstance, >; -/// No local origins on this chain are allowed to dispatch XCM sends/executions. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type PriceForParentDelivery = diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 42556e0b493c..49637284eaef 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -498,7 +498,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// Local origins on this chain are allowed to dispatch XCM sends/executions. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs index d5cf33515e6b..06ebd68a19c5 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -348,4 +348,26 @@ impl pallet_xcm::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AuthorizedAliases` (r:1 w:1) + /// Proof: `XcmPallet::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `361` + // Estimated: `3826` + // Minimum execution time: 15_975_000 picoseconds. + Weight::from_parts(16_398_000, 3826) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `XcmPallet::AuthorizedAliases` (r:1 w:1) + /// Proof: `XcmPallet::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `400` + // Estimated: `3865` + // Minimum execution time: 17_326_000 picoseconds. + Weight::from_parts(17_622_000, 3865) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/weights/pallet_xcm.rs b/polkadot/runtime/westend/src/weights/pallet_xcm.rs index 10725cecf249..aaeb0438520e 100644 --- a/polkadot/runtime/westend/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/westend/src/weights/pallet_xcm.rs @@ -348,4 +348,26 @@ impl pallet_xcm::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AuthorizedAliases` (r:1 w:1) + /// Proof: `XcmPallet::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn add_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `361` + // Estimated: `3826` + // Minimum execution time: 15_975_000 picoseconds. + Weight::from_parts(16_398_000, 3826) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `XcmPallet::AuthorizedAliases` (r:1 w:1) + /// Proof: `XcmPallet::AuthorizedAliases` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn remove_authorized_alias() -> Weight { + // Proof Size summary in bytes: + // Measured: `400` + // Estimated: `3865` + // Minimum execution time: 17_326_000 picoseconds. + Weight::from_parts(17_622_000, 3865) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index f8bb2676de3f..0c2c131945dd 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -239,7 +239,8 @@ parameter_types! { pub type GeneralAdminToPlurality = OriginToPluralityVoice; -/// location of this chain. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = ( GeneralAdminToPlurality, // And a usual Signed origin to be used in XCM as a corresponding AccountId32 diff --git a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/parachain/xcm_config.rs b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/parachain/xcm_config.rs index 0180354458ce..388849213ad2 100644 --- a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/parachain/xcm_config.rs +++ b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/parachain/xcm_config.rs @@ -146,6 +146,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = (); } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; impl pallet_xcm::Config for Runtime { diff --git a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/relay_chain/xcm_config.rs b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/relay_chain/xcm_config.rs index 06b00c39e8a0..d6b4396f26f4 100644 --- a/polkadot/xcm/docs/src/cookbook/relay_token_transactor/relay_chain/xcm_config.rs +++ b/polkadot/xcm/docs/src/cookbook/relay_token_transactor/relay_chain/xcm_config.rs @@ -119,6 +119,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = (); } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; impl pallet_xcm::Config for Runtime { diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index e493d4838f5c..77555abfcb2e 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -28,7 +28,7 @@ type RuntimeOrigin = ::RuntimeOrigin; pub struct Pallet(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. -pub trait Config: crate::Config { +pub trait Config: crate::Config + pallet_balances::Config { /// Helper that ensures successful delivery for extrinsics/benchmarks which need `SendXcm`. type DeliveryHelper: EnsureDelivery; @@ -276,7 +276,7 @@ benchmarks! { let loc = VersionedLocation::from(Location::from(Parent)); SupportedVersion::::insert(old_version, loc, old_version); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); } migrate_version_notifiers { @@ -284,7 +284,7 @@ benchmarks! { let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifiers::::insert(old_version, loc, 0); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); } already_notified_target { @@ -295,7 +295,7 @@ benchmarks! { let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), current_version)); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); } notify_current_targets { @@ -307,7 +307,7 @@ benchmarks! { let old_version = current_version - 1; VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), old_version)); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero()); } notify_target_migration_fail { @@ -323,7 +323,7 @@ benchmarks! { let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, bad_location, (0, Weight::zero(), current_version)); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); } migrate_version_notify_targets { @@ -332,7 +332,7 @@ benchmarks! { let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), current_version)); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); } migrate_and_notify_old_targets { @@ -343,7 +343,7 @@ benchmarks! { let old_version = T::AdvertisedXcmVersion::get() - 1; VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), old_version)); }: { - crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); + crate::Pallet::::lazy_migration(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); } new_query { @@ -385,6 +385,60 @@ benchmarks! { let versioned_assets = VersionedAssets::from(Assets::from(asset)); }: _>(claim_origin.into(), Box::new(versioned_assets), Box::new(VersionedLocation::from(claim_location))) + add_authorized_alias { + let who: T::AccountId = whitelisted_caller(); + let origin = RawOrigin::Signed(who.clone()); + let origin_location: VersionedLocation = T::ExecuteXcmOrigin::try_origin(origin.clone().into()) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?.into(); + + // Give some multiple of ED + let balance = T::ExistentialDeposit::get() * 10u32.into(); + let _ = + as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance); + + let mut existing_aliases = BoundedVec::::new(); + // prepopulate list with `max-1` aliases to benchmark worst case + for i in 1..MaxAuthorizedAliases::get() { + let alias = Location::new(1, [Parachain(i), AccountId32 { network: None, id: [42_u8; 32] }]).into(); + let aliaser = OriginAliaser { location: alias, expiry: None }; + existing_aliases.try_push(aliaser).unwrap() + } + let ticket = TicketOf::::new(&who, aliasers_footprint(existing_aliases.len())).unwrap(); + let entry = AuthorizedAliasesEntry { aliasers: existing_aliases, ticket }; + AuthorizedAliases::::insert(&origin_location, entry); + + // now benchmark adding new alias + let aliaser: VersionedLocation = + Location::new(1, [Parachain(1234), AccountId32 { network: None, id: [42_u8; 32] }]).into(); + }: _(origin, Box::new(aliaser), None) + + remove_authorized_alias { + let who: T::AccountId = whitelisted_caller(); + let origin = RawOrigin::Signed(who.clone()); + let origin_location: VersionedLocation = T::ExecuteXcmOrigin::try_origin(origin.clone().into()) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?.into(); + + // Give some multiple of ED + let balance = T::ExistentialDeposit::get() * 10u32.into(); + let _ = + as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance); + + let mut existing_aliases = BoundedVec::::new(); + // prepopulate list with `max` aliases to benchmark worst case + for i in 1..MaxAuthorizedAliases::get()+1 { + let alias = Location::new(1, [Parachain(i), AccountId32 { network: None, id: [42_u8; 32] }]).into(); + let aliaser = OriginAliaser { location: alias, expiry: None }; + existing_aliases.try_push(aliaser).unwrap() + } + let ticket = TicketOf::::new(&who, aliasers_footprint(existing_aliases.len())).unwrap(); + let entry = AuthorizedAliasesEntry { aliasers: existing_aliases, ticket }; + AuthorizedAliases::::insert(&origin_location, entry); + + // now benchmark removing an alias + let aliaser_to_remove: VersionedLocation = + Location::new(1, [Parachain(1), AccountId32 { network: None, id: [42_u8; 32] }]).into(); + }: _(origin, Box::new(aliaser_to_remove)) + impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext_with_balances(Vec::new()), diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 5e0512c6a9fd..7f24d143477d 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -38,8 +38,8 @@ use frame_support::{ }, pallet_prelude::*, traits::{ - Contains, ContainsPair, Currency, Defensive, EnsureOrigin, Get, LockableCurrency, - OriginTrait, WithdrawReasons, + Consideration, Contains, ContainsPair, Currency, Defensive, EnsureOrigin, Footprint, Get, + LockableCurrency, OriginTrait, WithdrawReasons, }, PalletId, }; @@ -51,7 +51,7 @@ use sp_runtime::{ AccountIdConversion, BadOrigin, BlakeTwo256, BlockNumberProvider, Dispatchable, Hash, Saturating, Zero, }, - Either, RuntimeDebug, + Either, RuntimeDebug, SaturatedConversion, }; use xcm::{latest::QueryResponseInfo, prelude::*}; use xcm_builder::{ @@ -98,6 +98,8 @@ pub trait WeightInfo { fn new_query() -> Weight; fn take_response() -> Weight; fn claim_assets() -> Weight; + fn add_authorized_alias() -> Weight; + fn remove_authorized_alias() -> Weight; } /// fallback implementation @@ -182,6 +184,32 @@ impl WeightInfo for TestWeightInfo { fn claim_assets() -> Weight { Weight::from_parts(100_000_000, 0) } + + fn add_authorized_alias() -> Weight { + Weight::from_parts(100_000, 0) + } + + fn remove_authorized_alias() -> Weight { + Weight::from_parts(100_000, 0) + } +} + +/// Entry of an authorized aliaser for a local origin. The aliaser `location` is only authorized +/// until its inner `expiry` block number. +#[derive(Clone, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +pub(crate) struct OriginAliaser { + pub(crate) location: VersionedLocation, + pub(crate) expiry: Option, +} + +#[derive(Clone, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)] +pub(crate) struct AuthorizedAliasesEntry> { + pub(crate) aliasers: BoundedVec, + pub(crate) ticket: Ticket, +} + +pub(crate) fn aliasers_footprint(aliasers_count: usize) -> Footprint { + Footprint::from_parts(aliasers_count, OriginAliaser::max_encoded_len()) } #[frame_support::pallet] @@ -200,6 +228,10 @@ pub mod pallet { /// An implementation of `Get` which just returns the latest XCM version which we can /// support. pub const CurrentXcmVersion: u32 = XCM_VERSION; + + #[derive(Debug, TypeInfo)] + /// The maximum number of distinct locations allowed as authorized aliases for a local origin. + pub const MaxAuthorizedAliases: u32 = 10; } const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); @@ -211,6 +243,7 @@ pub mod pallet { pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + pub type TicketOf = ::Consideration; #[pallet::config] /// The module configuration trait. @@ -225,6 +258,9 @@ pub mod pallet { /// The `Asset` matcher for `Currency`. type CurrencyMatcher: MatchesFungible>; + /// A means of providing some cost while data is stored on-chain. + type Consideration: Consideration; + /// Required origin for sending XCM messages. If successful, it resolves to `Location` /// which exists as an interior location within this chain's XCM context. type SendXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; @@ -518,6 +554,13 @@ pub mod pallet { } } + /// A reason for this pallet placing a hold on funds. + #[pallet::composite_enum] + pub enum HoldReason { + /// The funds are held as storage deposit for an authorized alias. + AuthorizeAlias, + } + #[pallet::error] pub enum Error { /// The desired destination was unreachable, generally because there is a no way of routing @@ -575,6 +618,12 @@ pub mod pallet { /// Local XCM execution incomplete. #[codec(index = 24)] LocalExecutionIncomplete, + /// Too many locations authorized to alias origin. + #[codec(index = 25)] + TooManyAuthorizedAliases, + /// Expiry block number is in the past. + #[codec(index = 26)] + ExpiresInPast, } impl From for Error { @@ -596,7 +645,7 @@ pub mod pallet { } /// The status of a query. - #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum QueryStatus { /// The query was sent but no response has yet been received. Pending { @@ -633,6 +682,7 @@ pub mod pallet { MigrateVersionNotifiers, NotifyCurrentTargets(Option>), MigrateAndNotifyOldTargets, + RemoveExpiredAliasAuthorizations, } impl Default for VersionMigrationStage { @@ -794,6 +844,18 @@ pub mod pallet { #[pallet::storage] pub(crate) type RecordedXcm = StorageValue<_, Xcm<()>>; + /// Map of authorized aliasers of local origins. Each local location can authorize a list of + /// other locations to alias into it. Each aliaser is only valid until its inner `expiry` + /// block number. + #[pallet::storage] + pub(super) type AuthorizedAliases = StorageMap< + _, + Blake2_128Concat, + VersionedLocation, + AuthorizedAliasesEntry, MaxAuthorizedAliases>, + OptionQuery, + >; + #[pallet::genesis_config] pub struct GenesisConfig { #[serde(skip)] @@ -822,7 +884,7 @@ pub mod pallet { if let Some(migration) = CurrentMigration::::get() { // Consume 10% of block at most let max_weight = T::BlockWeights::get().max_block / 10; - let (w, maybe_migration) = Self::check_xcm_version_change(migration, max_weight); + let (w, maybe_migration) = Self::lazy_migration(migration, max_weight); if maybe_migration.is_none() { Self::deposit_event(Event::VersionMigrationFinished { version: XCM_VERSION }); } @@ -1426,6 +1488,98 @@ pub mod pallet { weight_limit, ) } + + /// Authorize another `aliaser` location to alias into the local `origin` making this call. + /// The `aliaser` is only authorized until the provided `expiry` block number. + /// + /// Usually useful to allow your local account to be aliased into from a remote location + /// also under your control (like your account on another chain). + /// + /// WARNING: make sure the caller `origin` (you) trusts the `aliaser` location to act in + /// their/your name. Once authorized using this call, the `aliaser` can freely impersonate + /// `origin` in XCM programs executed on the local chain. + #[pallet::call_index(14)] + pub fn add_authorized_alias( + origin: OriginFor, + aliaser: Box, + expires: Option, + ) -> DispatchResult { + let signed_origin = ensure_signed(origin.clone())?; + let origin_location: Location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let aliaser: Location = (*aliaser).try_into().map_err(|()| Error::::BadVersion)?; + tracing::debug!(target: "xcm::pallet_xcm::add_authorized_alias", ?origin_location, ?aliaser, ?expires); + ensure!(origin_location != aliaser, Error::::BadLocation); + if let Some(expiry) = expires { + ensure!( + expiry > frame_system::Pallet::::block_number().saturated_into::(), + Error::::ExpiresInPast + ); + } + let versioned_origin = VersionedLocation::from(origin_location); + let versioned_aliaser = VersionedLocation::from(aliaser); + + let entry = if let Some(entry) = AuthorizedAliases::::get(&versioned_origin) { + // entry already exists, update it + let (mut aliasers, mut ticket) = (entry.aliasers, entry.ticket); + if let Some(aliaser) = + aliasers.iter_mut().find(|aliaser| aliaser.location == versioned_aliaser) + { + // if the aliaser already exists, just update its expiry block + aliaser.expiry = expires; + } else { + // if it doesn't, we try to add it + let aliaser = OriginAliaser { location: versioned_aliaser, expiry: expires }; + aliasers.try_push(aliaser).map_err(|_| Error::::TooManyAuthorizedAliases)?; + // we try to update the ticket (the storage deposit) + ticket = ticket.update(&signed_origin, aliasers_footprint(aliasers.len()))?; + } + AuthorizedAliasesEntry { aliasers, ticket } + } else { + // add new entry with its first alias + let ticket = TicketOf::::new(&signed_origin, aliasers_footprint(1))?; + let aliaser = OriginAliaser { location: versioned_aliaser, expiry: expires }; + let mut aliasers = BoundedVec::::new(); + aliasers.try_push(aliaser).map_err(|_| Error::::TooManyAuthorizedAliases)?; + AuthorizedAliasesEntry { aliasers, ticket } + }; + + // write to storage + AuthorizedAliases::::insert(&versioned_origin, entry); + Ok(()) + } + + /// Remove a previously authorized `aliaser` from the list of locations that can alias into + /// the local `origin` making this call. + #[pallet::call_index(15)] + pub fn remove_authorized_alias( + origin: OriginFor, + aliaser: Box, + ) -> DispatchResult { + let signed_origin = ensure_signed(origin.clone())?; + let origin_location: Location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let to_remove: Location = (*aliaser).try_into().map_err(|()| Error::::BadVersion)?; + tracing::debug!(target: "xcm::pallet_xcm::add_authorized_alias", ?origin_location, ?to_remove); + ensure!(origin_location != to_remove, Error::::BadLocation); + let versioned_origin = VersionedLocation::from(origin_location); + let versioned_to_remove = VersionedLocation::from(to_remove); + if let Some(entry) = AuthorizedAliases::::get(&versioned_origin) { + let (mut aliasers, mut ticket) = (entry.aliasers, entry.ticket); + let old_len = aliasers.len(); + aliasers.retain(|alias| versioned_to_remove.ne(&alias.location)); + let new_len = aliasers.len(); + if new_len > 0 { + // remove entry altogether and return all storage deposit + ticket.drop(&signed_origin)?; + AuthorizedAliases::::remove(&versioned_origin); + } else if old_len != new_len { + // update aliasers and storage deposit + ticket = ticket.update(&signed_origin, aliasers_footprint(new_len))?; + let entry = AuthorizedAliasesEntry { aliasers, ticket }; + AuthorizedAliases::::insert(&versioned_origin, entry); + } + } + Ok(()) + } } } @@ -2264,7 +2418,7 @@ impl Pallet { /// Will always make progress, and will do its best not to use much more than `weight_cutoff` /// in doing so. - pub(crate) fn check_xcm_version_change( + pub(crate) fn lazy_migration( mut stage: VersionMigrationStage, weight_cutoff: Weight, ) -> (Weight, Option) { @@ -2417,6 +2571,44 @@ impl Pallet { } } } + stage = RemoveExpiredAliasAuthorizations; + } + if stage == RemoveExpiredAliasAuthorizations { + let block_num = frame_system::Pallet::::block_number().saturated_into::(); + let mut writes = 0; + // need to iterate keys and modify map in separate steps to avoid undefined behavior + let keys: Vec = AuthorizedAliases::::iter_keys().collect(); + weight_used.saturating_add(T::DbWeight::get().reads(keys.len() as u64)); + for key in keys { + if let Some(entry) = AuthorizedAliases::::get(&key) { + let (mut aliases, ticket) = (entry.aliasers, entry.ticket); + let Some(who) = Location::try_from(key.clone()) + .ok() + .and_then(|key| T::SovereignAccountOf::convert_location(&key)) + else { + continue + }; + let old_len = aliases.len(); + aliases.retain(|aliaser| { + aliaser.expiry.map(|expiry| expiry > block_num).unwrap_or(true) + }); + let new_len = aliases.len(); + if new_len > 0 { + // remove entry altogether and return all storage deposit + let _ = ticket.drop(&who); + AuthorizedAliases::::remove(&key); + writes = writes + 2; + } else if old_len != new_len { + // update aliasers and storage deposit + if let Ok(ticket) = ticket.update(&who, aliasers_footprint(new_len)) { + let entry = AuthorizedAliasesEntry { aliasers: aliases, ticket }; + AuthorizedAliases::::insert(&key, entry); + writes = writes + 2; + } + } + } + } + weight_used.saturating_add(T::DbWeight::get().writes(writes)); } (weight_used, None) } @@ -3430,6 +3622,37 @@ where } } +/// Filter for `(origin: Location, target: Location)` to find whether `target` has explicitly +/// authorized `origin` to alias it. +/// +/// Note: users can authorize other locations to alias them by using +/// `pallet_xcm::add_authorized_alias()`. +pub struct AuthorizedAliasers(PhantomData); +impl + Clone, T: Config> ContainsPair for AuthorizedAliasers { + fn contains(origin: &L, target: &L) -> bool { + let origin: VersionedLocation = origin.clone().into(); + let target: VersionedLocation = target.clone().into(); + tracing::trace!(target: "xcm::pallet_xcm::AuthorizedAliasers::contains", ?origin, ?target); + // return true if the `origin` has been explicitly authorized by `target` as aliaser, and + // the authorization has not expired + AuthorizedAliases::::get(&target) + .map(|authorized| { + let current_block = + frame_system::Pallet::::block_number().saturated_into::(); + authorized + .aliasers + .iter() + .find(|&aliaser| { + let not_expired = + aliaser.expiry.map(|expiry| expiry < current_block).unwrap_or(true); + not_expired && aliaser.location == origin + }) + .is_some() + }) + .unwrap_or(false) + } +} + /// Filter for `Location` to find those which represent a strict majority approval of an /// identified plurality. /// diff --git a/polkadot/xcm/pallet-xcm/src/migration.rs b/polkadot/xcm/pallet-xcm/src/migration.rs index 80154f57ddfb..f43719ef9b99 100644 --- a/polkadot/xcm/pallet-xcm/src/migration.rs +++ b/polkadot/xcm/pallet-xcm/src/migration.rs @@ -170,6 +170,48 @@ pub mod data { } } + /// Implementation of `NeedsMigration` for `AuthorizedAliases` data. + impl, T: Config> NeedsMigration + for (&VersionedLocation, AuthorizedAliasesEntry, M>, PhantomData) + { + type MigratedData = (VersionedLocation, AuthorizedAliasesEntry, M>); + + fn needs_migration(&self, _: XcmVersion) -> bool { + self.0.identify_version() < XCM_VERSION || + self.1 + .aliasers + .iter() + .any(|alias| alias.location.identify_version() < XCM_VERSION) + } + + fn try_migrate(self, _: XcmVersion) -> Result, ()> { + if !self.needs_migration(XCM_VERSION) { + return Ok(None) + } + + let key = if self.0.identify_version() < XCM_VERSION { + let Ok(converted_key) = self.0.clone().into_version(XCM_VERSION) else { + return Err(()) + }; + converted_key + } else { + self.0.clone() + }; + + let mut new_aliases = BoundedVec::::new(); + let (aliasers, ticket) = (self.1.aliasers, self.1.ticket); + for alias in aliasers { + let OriginAliaser { mut location, expiry } = alias.clone(); + if location.identify_version() < XCM_VERSION { + location = location.into_version(XCM_VERSION)?; + } + new_aliases.try_push(OriginAliaser { location, expiry }).map_err(|_| ())?; + } + + Ok(Some((key, AuthorizedAliasesEntry { aliasers: new_aliases, ticket }))) + } + } + impl Pallet { /// Migrates relevant data to the `required_xcm_version`. pub(crate) fn migrate_data_to_xcm_version( @@ -323,6 +365,38 @@ pub mod data { >(&old_key, &new_key); weight.saturating_add(T::DbWeight::get().writes(1)); } + + // check and migrate `AuthorizedAliases` + let aliases_to_migrate = AuthorizedAliases::::iter().filter_map(|(id, data)| { + weight.saturating_add(T::DbWeight::get().reads(1)); + match (&id, data, PhantomData::).try_migrate(required_xcm_version) { + Ok(Some((new_id, new_data))) => Some((id, new_id, new_data)), + Ok(None) => None, + Err(_) => { + tracing::error!( + target: LOG_TARGET, + ?id, + ?required_xcm_version, + "`AuthorizedAliases` cannot be migrated!" + ); + None + }, + } + }); + let mut count = 0; + for (old_id, new_id, new_data) in aliases_to_migrate { + tracing::info!( + target: LOG_TARGET, + ?new_id, + ?new_data, + "Migrating `AuthorizedAliases`" + ); + AuthorizedAliases::::remove(old_id); + AuthorizedAliases::::insert(new_id, new_data); + count = count + 1; + } + // two writes per key, one to remove old entry, one to write new entry + weight.saturating_add(T::DbWeight::get().writes(count * 2)); } } } diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 8d0476b0e70d..e7a756add549 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -19,8 +19,8 @@ pub use core::cell::RefCell; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstU128, ConstU32, Contains, Equals, Everything, EverythingBut, - Nothing, + fungible::HoldConsideration, AsEnsureOriginWithArg, ConstU128, ConstU32, Contains, Equals, + Everything, EverythingBut, Footprint, Nothing, }, weights::Weight, }; @@ -28,7 +28,10 @@ use frame_system::EnsureRoot; use polkadot_parachain_primitives::primitives::Id as ParaId; use polkadot_runtime_parachains::origin; use sp_core::H256; -use sp_runtime::{traits::IdentityLookup, AccountId32, BuildStorage}; +use sp_runtime::{ + traits::{Convert, IdentityLookup}, + AccountId32, BuildStorage, +}; use xcm::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, @@ -518,10 +521,20 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = XcmPallet; } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; parameter_types! { pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 4; + pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::XcmPallet(pallet_xcm::HoldReason::AuthorizeAlias); +} + +pub struct ConvertDeposit; +impl Convert for ConvertDeposit { + fn convert(a: Footprint) -> u128 { + (a.count * 2 + a.size) as u128 + } } pub struct XcmTeleportFiltered; @@ -556,6 +569,8 @@ impl pallet_xcm::Config for Test { type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>; type RemoteLockConsumerIdentifier = (); type WeightInfo = TestWeightInfo; + type Consideration = + HoldConsideration; } impl origin::Config for Test {} diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index 350530f7711f..9dd42999774f 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -1058,7 +1058,7 @@ fn subscription_side_upgrades_work_with_multistage_notify() { let mut counter = 0; while let Some(migration) = maybe_migration.take() { counter += 1; - let (_, m) = XcmPallet::check_xcm_version_change(migration, Weight::zero()); + let (_, m) = XcmPallet::lazy_migration(migration, Weight::zero()); maybe_migration = m; } assert_eq!(counter, 4); @@ -1211,7 +1211,7 @@ fn multistage_migration_works() { let mut weight_used = Weight::zero(); while let Some(migration) = maybe_migration.take() { counter += 1; - let (w, m) = XcmPallet::check_xcm_version_change(migration, Weight::zero()); + let (w, m) = XcmPallet::lazy_migration(migration, Weight::zero()); maybe_migration = m; weight_used.saturating_accrue(w); } diff --git a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs index e6fe8e45c265..2f0287c3c2b7 100644 --- a/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs +++ b/polkadot/xcm/xcm-builder/src/asset_exchange/single_asset_adapter/mock.rs @@ -290,6 +290,8 @@ parameter_types! { pub const NoNetwork: Option = None; } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountIndex64; impl pallet_xcm::Config for Runtime { diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 26ea226313f0..e4771a185cf7 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -160,6 +160,8 @@ impl MaybeEquivalence } } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; pub type LocalAssetsTransactor = FungiblesAdapter< Assets, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 0468b0a5410c..2a0148d409c5 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -197,6 +197,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = XcmPallet; } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; impl pallet_xcm::Config for Runtime { diff --git a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs index f0a5be908f69..23c760ec9a6d 100644 --- a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs +++ b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs @@ -332,6 +332,8 @@ where } } +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountIndex64; impl pallet_xcm::Config for TestRuntime { diff --git a/prdoc/pr_6336.prdoc b/prdoc/pr_6336.prdoc new file mode 100644 index 000000000000..5edf7ed01b22 --- /dev/null +++ b/prdoc/pr_6336.prdoc @@ -0,0 +1,58 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "pallet-xcm: add support to authorize aliases" + +doc: + - audience: Runtime User + description: | + Added new `add_authorized_alias()` and `remove_authorized_alias()` calls to `pallet-xcm`. + These can be used by a "caller" to explicitly authorize another location to alias into the "caller" origin. + Usually useful to allow one's local account to be aliased into from a remote location also under + one's control (one's account on another chain). + WARNING: make sure that you as the caller `origin` trust the `aliaser` location to act in your name on this + chain. Once authorized using this call, the `aliaser` can freely impersonate `origin` in XCM programs + executed on the local chain. + + - audience: Runtime Dev + description: | + Added `AuthorizedAliasers` type exposed by `pallet-xcm`, that acts as a filter for explicitly authorized + aliases using `pallet-xcm::add_authorized_alias()` and `pallet-xcm::remove_authorized_alias()`. + Runtime developers can simply plug this `pallet-xcm::AuthorizedAliasers` type in their runtime's `XcmConfig`, + specifically in `::Aliasers`. + +crates: + - name: pallet-xcm + bump: minor + - name: staging-xcm-builder + bump: none + - name: xcm-runtime-apis + bump: none + - name: westend-runtime + bump: none + - name: rococo-runtime + bump: none + - name: asset-hub-rococo-runtime + bump: none + - name: asset-hub-westend-runtime + bump: none + - name: bridge-hub-rococo-runtime + bump: none + - name: bridge-hub-westend-runtime + bump: none + - name: collectives-westend-runtime + bump: none + - name: coretime-rococo-runtime + bump: none + - name: coretime-westend-runtime + bump: none + - name: people-rococo-runtime + bump: none + - name: people-westend-runtime + bump: none + - name: penpal-runtime + bump: none + - name: contracts-rococo-runtime + bump: none + - name: rococo-parachain-runtime + bump: none diff --git a/templates/parachain/runtime/src/configs/xcm_config.rs b/templates/parachain/runtime/src/configs/xcm_config.rs index 3da3b711f4ff..09e8e3bfef1b 100644 --- a/templates/parachain/runtime/src/configs/xcm_config.rs +++ b/templates/parachain/runtime/src/configs/xcm_config.rs @@ -150,7 +150,8 @@ impl xcm_executor::Config for XcmConfig { type XcmRecorder = PolkadotXcm; } -/// No local origins on this chain are allowed to dispatch XCM sends/executions. +/// Converts a local signed origin into an XCM location. Forms the basis for local origins +/// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; /// The means for routing XCM messages which are not for local execution into the right message