Skip to main content

coretime_westend_runtime/
xcm_config.rs

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