referrerpolicy=no-referrer-when-downgrade

people_westend_runtime/
xcm_config.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::{
17	AccountId, AllPalletsWithSystem, Balance, Balances, ParachainInfo, ParachainSystem,
18	PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeHoldReason, RuntimeOrigin, WeightToFee,
19	XcmpQueue,
20};
21use crate::{TransactionByteFee, CENTS};
22use frame_support::{
23	parameter_types,
24	traits::{
25		fungible::HoldConsideration, tokens::imbalance::ResolveTo, ConstU32, Contains, Equals,
26		Everything, LinearStoragePrice, Nothing,
27	},
28};
29use frame_system::EnsureRoot;
30use pallet_collator_selection::StakingPotAccountId;
31use pallet_xcm::{AuthorizedAliasers, XcmPassthrough};
32use parachains_common::{
33	xcm_config::{
34		AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains,
35		ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains,
36	},
37	TREASURY_PALLET_ID,
38};
39use polkadot_parachain_primitives::primitives::Sibling;
40use sp_runtime::traits::AccountIdConversion;
41use testnet_parachains_constants::westend::locations::AssetHubLocation;
42use westend_runtime_constants::system_parachain::COLLECTIVES_ID;
43use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
44use xcm_builder::{
45	AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
46	AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
47	AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
48	DenyRecursively, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal,
49	DescribeFamily, DescribeTerminus, EnsureXcmOrigin, FrameTransactionalProcessor,
50	FungibleAdapter, HashedDescription, IsConcrete, LocationAsSuperuser, ParentAsSuperuser,
51	ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount, SiblingParachainAsNative,
52	SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
53	SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
54	WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
55};
56use xcm_executor::XcmExecutor;
57
58// Re-export
59pub use testnet_parachains_constants::westend::locations::GovernanceLocation;
60
61parameter_types! {
62	pub const RootLocation: Location = Location::here();
63	pub const RelayLocation: Location = Location::parent();
64	pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH));
65	pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
66	pub UniversalLocation: InteriorLocation =
67		[GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
68	pub const MaxInstructions: u32 = 100;
69	pub const MaxAssetsIntoHolding: u32 = 64;
70	pub FellowshipLocation: Location = Location::new(1, Parachain(COLLECTIVES_ID));
71	/// The asset ID for the asset that we use to pay for message delivery fees. Just WND.
72	pub FeeAssetId: AssetId = AssetId(RelayLocation::get());
73	/// The base fee for the message delivery fees.
74	pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3);
75	pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
76	pub RelayTreasuryLocation: Location =
77		(Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into();
78}
79
80pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
81	FeeAssetId,
82	BaseDeliveryFee,
83	TransactionByteFee,
84	ParachainSystem,
85>;
86
87pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
88	FeeAssetId,
89	BaseDeliveryFee,
90	TransactionByteFee,
91	XcmpQueue,
92>;
93
94/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
95/// when determining ownership of accounts for asset transacting and when attempting to use XCM
96/// `Transact` in order to determine the dispatch Origin.
97pub type LocationToAccountId = (
98	// The parent (Relay-chain) origin converts to the parent `AccountId`.
99	ParentIsPreset<AccountId>,
100	// Sibling parachain origins convert to AccountId via the `ParaId::into`.
101	SiblingParachainConvertsVia<Sibling, AccountId>,
102	// Straight up local `AccountId32` origins just alias directly to `AccountId`.
103	AccountId32Aliases<RelayNetwork, AccountId>,
104	// Here/local root location to `AccountId`.
105	HashedDescription<AccountId, DescribeTerminus>,
106	// Foreign locations alias into accounts according to a hash of their standard description.
107	HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
108);
109
110/// Means for transacting the native currency on this chain.
111pub type FungibleTransactor = FungibleAdapter<
112	// Use this currency:
113	Balances,
114	// Use this currency when it is a fungible asset matching the given location or name:
115	IsConcrete<RelayLocation>,
116	// Do a simple punn to convert an `AccountId32` `Location` into a native chain
117	// `AccountId`:
118	LocationToAccountId,
119	// Our chain's account ID type (we can't get away without mentioning it explicitly):
120	AccountId,
121	// We don't track any teleports of `Balances`.
122	(),
123>;
124
125/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
126/// ready for dispatching a transaction with XCM's `Transact`. There is an `OriginKind` that can
127/// bias the kind of local `Origin` it will become.
128pub type XcmOriginToTransactDispatchOrigin = (
129	// Governance location can gain root.
130	LocationAsSuperuser<Equals<GovernanceLocation>, RuntimeOrigin>,
131	// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
132	// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
133	// foreign chains who want to have a local sovereign account on this chain that they control.
134	SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
135	// Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
136	// recognized.
137	RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
138	// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
139	// recognized.
140	SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
141	// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
142	// transaction from the Root origin.
143	ParentAsSuperuser<RuntimeOrigin>,
144	// Native signed account converter; this just converts an `AccountId32` origin into a normal
145	// `RuntimeOrigin::Signed` origin of the same 32-byte value.
146	SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
147	// XCM origins can be represented natively under the XCM pallet's `Xcm` origin.
148	XcmPassthrough<RuntimeOrigin>,
149);
150
151pub struct LocalPlurality;
152impl Contains<Location> for LocalPlurality {
153	fn contains(location: &Location) -> bool {
154		matches!(location.unpack(), (0, [Plurality { .. }]))
155	}
156}
157
158pub struct ParentOrParentsPlurality;
159impl Contains<Location> for ParentOrParentsPlurality {
160	fn contains(location: &Location) -> bool {
161		matches!(location.unpack(), (1, []) | (1, [Plurality { .. }]))
162	}
163}
164
165pub struct FellowsPlurality;
166impl Contains<Location> for FellowsPlurality {
167	fn contains(location: &Location) -> bool {
168		matches!(
169			location.unpack(),
170			(1, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }])
171		)
172	}
173}
174
175pub type Barrier = TrailingSetTopicAsId<
176	DenyThenTry<
177		DenyRecursively<DenyReserveTransferToRelayChain>,
178		(
179			// Allow local users to buy weight credit.
180			TakeWeightCredit,
181			// Expected responses are OK.
182			AllowKnownQueryResponses<PolkadotXcm>,
183			WithComputedOrigin<
184				(
185					// If the message is one that immediately attempts to pay for execution, then
186					// allow it.
187					AllowTopLevelPaidExecutionFrom<Everything>,
188					// Parent, its pluralities (i.e. governance bodies), and the Fellows plurality
189					// get free execution.
190					AllowExplicitUnpaidExecutionFrom<(
191						ParentOrParentsPlurality,
192						FellowsPlurality,
193						Equals<GovernanceLocation>,
194					)>,
195					// Subscriptions for version tracking are OK.
196					AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
197					// HRMP notifications from the relay chain are OK.
198					AllowHrmpNotificationsFromRelayChain,
199				),
200				UniversalLocation,
201				ConstU32<8>,
202			>,
203		),
204	>,
205>;
206
207/// Locations that will not be charged fees in the executor, neither for execution nor delivery. We
208/// only waive fees for system functions, which these locations represent.
209pub type WaivedLocations = (
210	RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
211	Equals<RelayTreasuryLocation>,
212	Equals<RootLocation>,
213	LocalPlurality,
214);
215
216/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
217/// - WND with the parent Relay Chain and sibling parachains.
218pub type TrustedTeleporters = ConcreteAssetFromSystem<RelayLocation>;
219
220/// Defines origin aliasing rules for this chain.
221///
222/// - Allow any origin to alias into a child sub-location (equivalent to DescendOrigin),
223/// - Allow same accounts to alias into each other across system chains,
224/// - Allow AssetHub root to alias into anything,
225/// - Allow origins explicitly authorized to alias into target location.
226pub type TrustedAliasers = (
227	AliasChildLocation,
228	AliasAccountId32FromSiblingSystemChain,
229	AliasOriginRootUsingFilter<AssetHubLocation, Everything>,
230	AuthorizedAliasers<Runtime>,
231);
232
233pub struct XcmConfig;
234impl xcm_executor::Config for XcmConfig {
235	type RuntimeCall = RuntimeCall;
236	type XcmSender = XcmRouter;
237	type XcmEventEmitter = PolkadotXcm;
238	type AssetTransactor = FungibleTransactor;
239	type OriginConverter = XcmOriginToTransactDispatchOrigin;
240	// People does not recognize a reserve location for any asset. Users must teleport WND
241	// where allowed (e.g. with the Relay Chain).
242	type IsReserve = ();
243
244	type IsTeleporter = TrustedTeleporters;
245	type UniversalLocation = UniversalLocation;
246	type Barrier = Barrier;
247	type Weigher = WeightInfoBounds<
248		crate::weights::xcm::PeopleWestendXcmWeight<RuntimeCall>,
249		RuntimeCall,
250		MaxInstructions,
251	>;
252	type Trader = UsingComponents<
253		WeightToFee,
254		RelayLocation,
255		AccountId,
256		Balances,
257		ResolveTo<StakingPotAccountId<Runtime>, Balances>,
258	>;
259	type ResponseHandler = PolkadotXcm;
260	type AssetTrap = PolkadotXcm;
261	type AssetClaims = PolkadotXcm;
262	type SubscriptionService = PolkadotXcm;
263	type PalletInstancesInfo = AllPalletsWithSystem;
264	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
265	type AssetLocker = ();
266	type AssetExchanger = ();
267	type FeeManager = XcmFeeManagerFromComponents<
268		WaivedLocations,
269		SendXcmFeeToAccount<Self::AssetTransactor, TreasuryAccount>,
270	>;
271	type MessageExporter = ();
272	type UniversalAliases = Nothing;
273	type CallDispatcher = RuntimeCall;
274	type SafeCallFilter = Everything;
275	type Aliasers = TrustedAliasers;
276	type TransactionalProcessor = FrameTransactionalProcessor;
277	type HrmpNewChannelOpenRequestHandler = ();
278	type HrmpChannelAcceptedHandler = ();
279	type HrmpChannelClosingHandler = ();
280	type XcmRecorder = PolkadotXcm;
281}
282
283/// Converts a local signed origin into an XCM location. Forms the basis for local origins
284/// sending/executing XCMs.
285pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
286
287/// The means for routing XCM messages which are not for local execution into the right message
288/// queues.
289pub type XcmRouter = WithUniqueTopic<(
290	// Two routers - use UMP to communicate with the relay chain:
291	cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
292	// ..and XCMP to communicate with the sibling chains.
293	XcmpQueue,
294)>;
295
296parameter_types! {
297	pub const DepositPerItem: Balance = crate::deposit(1, 0);
298	pub const DepositPerByte: Balance = crate::deposit(0, 1);
299	pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::PolkadotXcm(pallet_xcm::HoldReason::AuthorizeAlias);
300}
301
302impl pallet_xcm::Config for Runtime {
303	type RuntimeEvent = RuntimeEvent;
304	// We want to disallow users sending (arbitrary) XCMs from this chain.
305	type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, ()>;
306	type XcmRouter = XcmRouter;
307	// We support local origins dispatching XCM executions.
308	type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
309	type XcmExecuteFilter = Everything;
310	type XcmExecutor = XcmExecutor<XcmConfig>;
311	type XcmTeleportFilter = Everything;
312	type XcmReserveTransferFilter = Nothing; // This parachain is not meant as a reserve location.
313	type Weigher = WeightInfoBounds<
314		crate::weights::xcm::PeopleWestendXcmWeight<RuntimeCall>,
315		RuntimeCall,
316		MaxInstructions,
317	>;
318	type UniversalLocation = UniversalLocation;
319	type RuntimeOrigin = RuntimeOrigin;
320	type RuntimeCall = RuntimeCall;
321	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
322	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
323	type Currency = Balances;
324	type CurrencyMatcher = ();
325	type TrustedLockers = ();
326	type SovereignAccountOf = LocationToAccountId;
327	type MaxLockers = ConstU32<8>;
328	type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
329	type AdminOrigin = EnsureRoot<AccountId>;
330	type MaxRemoteLockConsumers = ConstU32<0>;
331	type RemoteLockConsumerIdentifier = ();
332	// xcm_executor::Config::Aliasers also uses pallet_xcm::AuthorizedAliasers.
333	type AuthorizedAliasConsideration = HoldConsideration<
334		AccountId,
335		Balances,
336		AuthorizeAliasHoldReason,
337		LinearStoragePrice<DepositPerItem, DepositPerByte, Balance>,
338	>;
339}
340
341impl cumulus_pallet_xcm::Config for Runtime {
342	type RuntimeEvent = RuntimeEvent;
343	type XcmExecutor = XcmExecutor<XcmConfig>;
344}