referrerpolicy=no-referrer-when-downgrade

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, ConstU8, Contains,
27		Equals, Everything, LinearStoragePrice, Nothing,
28	},
29};
30use frame_system::EnsureRoot;
31use pallet_collator_selection::StakingPotAccountId;
32use pallet_xcm::{AuthorizedAliasers, XcmPassthrough};
33use parachains_common::xcm_config::{
34	AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains, ConcreteAssetFromSystem,
35	ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains,
36};
37use polkadot_parachain_primitives::primitives::Sibling;
38use polkadot_runtime_common::xcm_sender::ExponentialPrice;
39use testnet_parachains_constants::westend::locations::AssetHubLocation;
40use westend_runtime_constants::system_parachain::COLLECTIVES_ID;
41use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
42use xcm_builder::{
43	AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
44	AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
45	AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
46	DenyRecursively, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal,
47	DescribeFamily, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter,
48	HashedDescription, IsConcrete, IsParentsOnly, LocationAsSuperuser, NonFungibleAdapter,
49	ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount,
50	SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
51	SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
52	UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
53	XcmFeeManagerFromComponents,
54};
55use xcm_executor::XcmExecutor;
56
57// Re-export
58pub use testnet_parachains_constants::westend::locations::GovernanceLocation;
59
60parameter_types! {
61	pub const RootLocation: Location = Location::here();
62	pub const TokenRelayLocation: Location = Location::parent();
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}
73
74/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
75/// when determining ownership of accounts for asset transacting and when attempting to use XCM
76/// `Transact` in order to determine the dispatch Origin.
77pub type LocationToAccountId = (
78	// The parent (Relay-chain) origin converts to the parent `AccountId`.
79	ParentIsPreset<AccountId>,
80	// Sibling parachain origins convert to AccountId via the `ParaId::into`.
81	SiblingParachainConvertsVia<Sibling, AccountId>,
82	// Straight up local `AccountId32` origins just alias directly to `AccountId`.
83	AccountId32Aliases<RelayNetwork, AccountId>,
84	// Foreign locations alias into accounts according to a hash of their standard description.
85	HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
86);
87
88/// Means for transacting the native currency on this chain.
89pub type FungibleTransactor = FungibleAdapter<
90	// Use this currency:
91	Balances,
92	// Use this currency when it is a fungible asset matching the given location or name:
93	IsConcrete<TokenRelayLocation>,
94	// Do a simple punn to convert an `AccountId32` `Location` into a native chain
95	// `AccountId`:
96	LocationToAccountId,
97	// Our chain's `AccountId` type (we can't get away without mentioning it explicitly):
98	AccountId,
99	// We don't track any teleports of `Balances`.
100	(),
101>;
102
103/// Means for transacting coretime regions on this chain.
104pub type RegionTransactor = NonFungibleAdapter<
105	// Use this non-fungible implementation:
106	Broker,
107	// This adapter will handle coretime regions from the broker pallet.
108	IsConcrete<BrokerPalletLocation>,
109	// Convert an XCM Location into a local account id:
110	LocationToAccountId,
111	// Our chain's account ID type (we can't get away without mentioning it explicitly):
112	AccountId,
113	// We don't track any teleports.
114	(),
115>;
116
117/// Means for transacting assets on this chain.
118pub type AssetTransactors = (FungibleTransactor, RegionTransactor);
119
120/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
121/// ready for dispatching a transaction with XCM's `Transact`. There is an `OriginKind` that can
122/// bias the kind of local `Origin` it will become.
123pub type XcmOriginToTransactDispatchOrigin = (
124	// Governance location can gain root.
125	LocationAsSuperuser<Equals<GovernanceLocation>, RuntimeOrigin>,
126	// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
127	// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
128	// foreign chains who want to have a local sovereign account on this chain that they control.
129	SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
130	// Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
131	// recognized.
132	RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
133	// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
134	// recognized.
135	SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
136	// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
137	// transaction from the Root origin.
138	ParentAsSuperuser<RuntimeOrigin>,
139	// Native signed account converter; this just converts an `AccountId32` origin into a normal
140	// `RuntimeOrigin::Signed` origin of the same 32-byte value.
141	SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
142	// XCM origins can be represented natively under the XCM pallet's `Xcm` origin.
143	XcmPassthrough<RuntimeOrigin>,
144);
145
146pub struct FellowsPlurality;
147impl Contains<Location> for FellowsPlurality {
148	fn contains(location: &Location) -> bool {
149		matches!(
150			location.unpack(),
151			(1, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }])
152		)
153	}
154}
155
156pub type Barrier = TrailingSetTopicAsId<
157	DenyThenTry<
158		DenyRecursively<DenyReserveTransferToRelayChain>,
159		(
160			// Allow local users to buy weight credit.
161			TakeWeightCredit,
162			// Expected responses are OK.
163			AllowKnownQueryResponses<PolkadotXcm>,
164			WithComputedOrigin<
165				(
166					// If the message is one that immediately attempts to pay for execution, then
167					// allow it.
168					AllowTopLevelPaidExecutionFrom<Everything>,
169					// Parent, the Fellows plurality, and sibling system parachains get free
170					// execution.
171					AllowExplicitUnpaidExecutionFrom<
172						(
173							IsParentsOnly<ConstU8<1>>,
174							RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
175							FellowsPlurality,
176							Equals<GovernanceLocation>,
177						),
178						CheapTrustedAliasers,
179					>,
180					// Subscriptions for version tracking are OK.
181					AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
182					// HRMP notifications from the relay chain are OK.
183					AllowHrmpNotificationsFromRelayChain,
184				),
185				UniversalLocation,
186				ConstU32<8>,
187			>,
188		),
189	>,
190>;
191
192parameter_types! {
193	/// The accumulation account on this chain.
194	pub AccumulateAccount: AccountId = pallet_accumulate_and_forward::Pallet::<Runtime>::accumulation_account();
195	pub AccumulateForwardLocation: Location = {
196		AccountId32 { network: None, id: AccumulateAccount::get().into() }.into()
197	};
198}
199
200/// Locations that will not be charged fees in the executor, neither for execution nor delivery.
201/// We only waive fees for system functions, which these locations represent.
202pub type WaivedLocations = (
203	Equals<RootLocation>,
204	RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
205	Equals<AccumulateForwardLocation>,
206);
207
208/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
209/// - WND with the parent Relay Chain and sibling parachains.
210pub type TrustedTeleporters = ConcreteAssetFromSystem<TokenRelayLocation>;
211
212/// Aliasing rules that are pure computation and thus cheap enough to also be evaluated by
213/// barriers, before any payment is taken.
214///
215/// - Allow any origin to alias into a child sub-location (equivalent to DescendOrigin),
216/// - Allow same accounts to alias into each other across system chains,
217/// - Allow AssetHub root to alias into anything.
218///
219/// `AuthorizedAliasers` is deliberately NOT part of this: it reads storage, which is more than a
220/// barrier is allowed to cost.
221pub type CheapTrustedAliasers = (
222	AliasChildLocation,
223	AliasAccountId32FromSiblingSystemChain,
224	AliasOriginRootUsingFilter<AssetHubLocation, Everything>,
225);
226
227/// Defines origin aliasing rules for this chain. Used by the executor.
228///
229/// - Allow all the cheap aliasing rules also used by the barriers,
230/// - Allow origins explicitly authorized to alias into target location.
231pub type TrustedAliasers = (CheapTrustedAliasers, AuthorizedAliasers<Runtime>);
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 = AssetTransactors;
239	type OriginConverter = XcmOriginToTransactDispatchOrigin;
240	// Coretime chain does not recognize a reserve location for any asset. Users must teleport ROC
241	// where allowed (e.g. with the Relay Chain).
242	type IsReserve = ();
243	type IsTeleporter = TrustedTeleporters;
244	type UniversalLocation = UniversalLocation;
245	type Barrier = Barrier;
246	type Weigher = WeightInfoBounds<
247		crate::weights::xcm::CoretimeWestendXcmWeight<RuntimeCall>,
248		RuntimeCall,
249		MaxInstructions,
250	>;
251	// TODO: once DAP allocates collator budgets, redirect XCM execution fees to the accumulation
252	// account instead of StakingPot (use crate::DealWithFeesAccumulate as the OnUnbalanced
253	// handler).
254	type Trader = UsingComponents<
255		WeightToFee,
256		TokenRelayLocation,
257		AccountId,
258		Balances,
259		ResolveTo<StakingPotAccountId<Runtime>, Balances>,
260	>;
261	type ResponseHandler = PolkadotXcm;
262	type AssetTrap = PolkadotXcm;
263	type SubscriptionService = PolkadotXcm;
264	type PalletInstancesInfo = AllPalletsWithSystem;
265	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
266	type AssetLocker = ();
267	type AssetExchanger = ();
268	type FeeManager = XcmFeeManagerFromComponents<
269		WaivedLocations,
270		SendXcmFeeToAccount<Self::AssetTransactor, AccumulateAccount>,
271	>;
272	type MessageExporter = ();
273	type UniversalAliases = Nothing;
274	type CallDispatcher = RuntimeCall;
275	type SafeCallFilter = Everything;
276	type Aliasers = TrustedAliasers;
277	type TransactionalProcessor = FrameTransactionalProcessor;
278	type HrmpNewChannelOpenRequestHandler = ();
279	type HrmpChannelAcceptedHandler = ();
280	type HrmpChannelClosingHandler = ();
281	type XcmRecorder = PolkadotXcm;
282}
283
284/// Converts a local signed origin into an XCM location. Forms the basis for local origins
285/// sending/executing XCMs.
286pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
287
288pub type PriceForParentDelivery =
289	ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
290
291/// The means for routing XCM messages which are not for local execution into the right message
292/// queues.
293pub type XcmRouter = WithUniqueTopic<(
294	// Two routers - use UMP to communicate with the relay chain:
295	cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
296	// ..and XCMP to communicate with the sibling chains.
297	XcmpQueue,
298)>;
299
300parameter_types! {
301	pub const DepositPerItem: Balance = crate::deposit(1, 0);
302	pub const DepositPerByte: Balance = crate::deposit(0, 1);
303	pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::PolkadotXcm(pallet_xcm::HoldReason::AuthorizeAlias);
304}
305
306impl pallet_xcm::Config for Runtime {
307	type RuntimeEvent = RuntimeEvent;
308	// We want to disallow users sending (arbitrary) XCM programs from this chain.
309	type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, ()>;
310	type XcmRouter = XcmRouter;
311	// We support local origins dispatching XCM executions.
312	type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
313	type XcmExecuteFilter = Everything;
314	type XcmExecutor = XcmExecutor<XcmConfig>;
315	type XcmTeleportFilter = Everything;
316	type XcmReserveTransferFilter = Everything;
317	type Weigher = WeightInfoBounds<
318		crate::weights::xcm::CoretimeWestendXcmWeight<RuntimeCall>,
319		RuntimeCall,
320		MaxInstructions,
321	>;
322	type UniversalLocation = UniversalLocation;
323	type RuntimeOrigin = RuntimeOrigin;
324	type RuntimeCall = RuntimeCall;
325	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
326	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
327	type Currency = Balances;
328	type CurrencyMatcher = ();
329	type TrustedLockers = ();
330	type SovereignAccountOf = LocationToAccountId;
331	type MaxLockers = ConstU32<8>;
332	type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
333	type AdminOrigin = EnsureRoot<AccountId>;
334	type MaxRemoteLockConsumers = ConstU32<0>;
335	type RemoteLockConsumerIdentifier = ();
336	// xcm_executor::Config::Aliasers also uses pallet_xcm::AuthorizedAliasers.
337	type AuthorizedAliasConsideration = HoldConsideration<
338		AccountId,
339		Balances,
340		AuthorizeAliasHoldReason,
341		LinearStoragePrice<DepositPerItem, DepositPerByte, Balance>,
342	>;
343}
344
345impl cumulus_pallet_xcm::Config for Runtime {
346	type RuntimeEvent = RuntimeEvent;
347	type XcmExecutor = XcmExecutor<XcmConfig>;
348}