referrerpolicy=no-referrer-when-downgrade

rococo_runtime/
xcm_config.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! XCM configuration for Rococo.
18
19use super::{
20	parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, Fellows, ParaId, Runtime,
21	RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, Treasurer, Treasury, WeightToFee,
22	XcmPallet,
23};
24
25use crate::governance::StakingAdmin;
26
27use frame_support::{
28	parameter_types,
29	traits::{Contains, Disabled, Equals, Everything, Nothing},
30	weights::Weight,
31};
32use frame_system::EnsureRoot;
33use polkadot_runtime_common::{
34	xcm_sender::{ChildParachainRouter, ExponentialPrice},
35	ToAuthor,
36};
37use rococo_runtime_constants::{currency::CENTS, system_parachain::*};
38use sp_core::ConstU32;
39use xcm::latest::{prelude::*, ROCOCO_GENESIS_HASH};
40use xcm_builder::{
41	AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
42	AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
43	ChildParachainConvertsVia, DescribeAllTerminal, DescribeFamily, FixedWeightBounds,
44	FrameTransactionalProcessor, FungibleAdapter, HashedDescription, IsChildSystemParachain,
45	IsConcrete, MintLocation, OriginToPluralityVoice, SendXcmFeeToAccount,
46	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
47	TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
48	XcmFeeManagerFromComponents,
49};
50use xcm_executor::XcmExecutor;
51
52parameter_types! {
53	pub TokenLocation: Location = Here.into_location();
54	pub RootLocation: Location = Location::here();
55	pub const ThisNetwork: NetworkId = NetworkId::ByGenesis(ROCOCO_GENESIS_HASH);
56	pub UniversalLocation: InteriorLocation = ThisNetwork::get().into();
57	pub CheckAccount: AccountId = XcmPallet::check_account();
58	pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local);
59	pub TreasuryAccount: AccountId = Treasury::account_id();
60}
61
62pub type LocationConverter = (
63	// We can convert a child parachain using the standard `AccountId` conversion.
64	ChildParachainConvertsVia<ParaId, AccountId>,
65	// We can directly alias an `AccountId32` into a local account.
66	AccountId32Aliases<ThisNetwork, AccountId>,
67	// Foreign locations alias into accounts according to a hash of their standard description.
68	HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
69);
70
71/// Our asset transactor. This is what allows us to interest with the runtime facilities from the
72/// point of view of XCM-only concepts like `Location` and `Asset`.
73///
74/// Ours is only aware of the Balances pallet, which is mapped to `RocLocation`.
75pub type LocalAssetTransactor = FungibleAdapter<
76	// Use this currency:
77	Balances,
78	// Use this currency when it is a fungible asset matching the given location or name:
79	IsConcrete<TokenLocation>,
80	// We can convert the Locations with our converter above:
81	LocationConverter,
82	// Our chain's account ID type (we can't get away without mentioning it explicitly):
83	AccountId,
84	// We track our teleports in/out to keep total issuance correct.
85	LocalCheckAccount,
86>;
87
88/// The means that we convert the XCM message origin location into a local dispatch origin.
89type LocalOriginConverter = (
90	// A `Signed` origin of the sovereign account that the original location controls.
91	SovereignSignedViaLocation<LocationConverter, RuntimeOrigin>,
92	// A child parachain, natively expressed, has the `Parachain` origin.
93	ChildParachainAsNative<parachains_origin::Origin, RuntimeOrigin>,
94	// The AccountId32 location type can be expressed natively as a `Signed` origin.
95	SignedAccountId32AsNative<ThisNetwork, RuntimeOrigin>,
96);
97
98parameter_types! {
99	/// The amount of weight an XCM operation takes. This is a safe overestimate.
100	pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
101	/// The asset ID for the asset that we use to pay for message delivery fees.
102	pub FeeAssetId: AssetId = AssetId(TokenLocation::get());
103	/// The base fee for the message delivery fees.
104	pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3);
105}
106
107pub type PriceForChildParachainDelivery =
108	ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, Dmp>;
109
110/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our
111/// individual routers.
112pub type XcmRouter = WithUniqueTopic<
113	// Only one router so far - use DMP to communicate with child parachains.
114	ChildParachainRouter<Runtime, XcmPallet, PriceForChildParachainDelivery>,
115>;
116
117parameter_types! {
118	pub Roc: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) });
119	pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location();
120	pub Contracts: Location = Parachain(CONTRACTS_ID).into_location();
121	pub Encointer: Location = Parachain(ENCOINTER_ID).into_location();
122	pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location();
123	pub People: Location = Parachain(PEOPLE_ID).into_location();
124	pub Broker: Location = Parachain(BROKER_ID).into_location();
125	pub Tick: Location = Parachain(100).into_location();
126	pub Trick: Location = Parachain(110).into_location();
127	pub Track: Location = Parachain(120).into_location();
128	pub RocForTick: (AssetFilter, Location) = (Roc::get(), Tick::get());
129	pub RocForTrick: (AssetFilter, Location) = (Roc::get(), Trick::get());
130	pub RocForTrack: (AssetFilter, Location) = (Roc::get(), Track::get());
131	pub RocForAssetHub: (AssetFilter, Location) = (Roc::get(), AssetHub::get());
132	pub RocForContracts: (AssetFilter, Location) = (Roc::get(), Contracts::get());
133	pub RocForEncointer: (AssetFilter, Location) = (Roc::get(), Encointer::get());
134	pub RocForBridgeHub: (AssetFilter, Location) = (Roc::get(), BridgeHub::get());
135	pub RocForPeople: (AssetFilter, Location) = (Roc::get(), People::get());
136	pub RocForBroker: (AssetFilter, Location) = (Roc::get(), Broker::get());
137	pub const MaxInstructions: u32 = 100;
138	pub const MaxAssetsIntoHolding: u32 = 64;
139}
140pub type TrustedTeleporters = (
141	xcm_builder::Case<RocForTick>,
142	xcm_builder::Case<RocForTrick>,
143	xcm_builder::Case<RocForTrack>,
144	xcm_builder::Case<RocForAssetHub>,
145	xcm_builder::Case<RocForContracts>,
146	xcm_builder::Case<RocForEncointer>,
147	xcm_builder::Case<RocForBridgeHub>,
148	xcm_builder::Case<RocForPeople>,
149	xcm_builder::Case<RocForBroker>,
150);
151
152pub struct OnlyParachains;
153impl Contains<Location> for OnlyParachains {
154	fn contains(loc: &Location) -> bool {
155		matches!(loc.unpack(), (0, [Parachain(_)]))
156	}
157}
158
159pub struct LocalPlurality;
160impl Contains<Location> for LocalPlurality {
161	fn contains(loc: &Location) -> bool {
162		matches!(loc.unpack(), (0, [Plurality { .. }]))
163	}
164}
165
166/// The barriers one of which must be passed for an XCM message to be executed.
167pub type Barrier = TrailingSetTopicAsId<(
168	// Weight that is paid for may be consumed.
169	TakeWeightCredit,
170	// Expected responses are OK.
171	AllowKnownQueryResponses<XcmPallet>,
172	WithComputedOrigin<
173		(
174			// If the message is one that immediately attempts to pay for execution, then allow it.
175			AllowTopLevelPaidExecutionFrom<Everything>,
176			// Messages coming from system parachains need not pay for execution.
177			AllowExplicitUnpaidExecutionFrom<IsChildSystemParachain<ParaId>>,
178			// Subscriptions for version tracking are OK.
179			AllowSubscriptionsFrom<OnlyParachains>,
180		),
181		UniversalLocation,
182		ConstU32<8>,
183	>,
184)>;
185
186/// Locations that will not be charged fees in the executor, neither for execution nor delivery.
187/// We only waive fees for system functions, which these locations represent.
188pub type WaivedLocations = (SystemParachains, Equals<RootLocation>, LocalPlurality);
189
190pub struct XcmConfig;
191impl xcm_executor::Config for XcmConfig {
192	type RuntimeCall = RuntimeCall;
193	type XcmSender = XcmRouter;
194	type XcmEventEmitter = XcmPallet;
195	type AssetTransactor = LocalAssetTransactor;
196	type OriginConverter = LocalOriginConverter;
197	type IsReserve = ();
198	type IsTeleporter = TrustedTeleporters;
199	type UniversalLocation = UniversalLocation;
200	type Barrier = Barrier;
201	type Weigher = WeightInfoBounds<
202		crate::weights::xcm::RococoXcmWeight<RuntimeCall>,
203		RuntimeCall,
204		MaxInstructions,
205	>;
206	type Trader =
207		UsingComponents<WeightToFee, TokenLocation, AccountId, Balances, ToAuthor<Runtime>>;
208	type ResponseHandler = XcmPallet;
209	type AssetTrap = XcmPallet;
210	type AssetLocker = ();
211	type AssetExchanger = ();
212	type AssetClaims = XcmPallet;
213	type SubscriptionService = XcmPallet;
214	type PalletInstancesInfo = AllPalletsWithSystem;
215	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
216	type FeeManager = XcmFeeManagerFromComponents<
217		WaivedLocations,
218		SendXcmFeeToAccount<Self::AssetTransactor, TreasuryAccount>,
219	>;
220	type MessageExporter = ();
221	type UniversalAliases = Nothing;
222	type CallDispatcher = RuntimeCall;
223	type SafeCallFilter = Everything;
224	type Aliasers = Nothing;
225	type TransactionalProcessor = FrameTransactionalProcessor;
226	type HrmpNewChannelOpenRequestHandler = ();
227	type HrmpChannelAcceptedHandler = ();
228	type HrmpChannelClosingHandler = ();
229	type XcmRecorder = XcmPallet;
230}
231
232parameter_types! {
233	/// Collective pluralistic body.
234	pub const CollectiveBodyId: BodyId = BodyId::Unit;
235	/// StakingAdmin pluralistic body.
236	pub const StakingAdminBodyId: BodyId = BodyId::Defense;
237	/// Fellows pluralistic body.
238	pub const FellowsBodyId: BodyId = BodyId::Technical;
239	/// Treasury pluralistic body.
240	pub const TreasuryBodyId: BodyId = BodyId::Treasury;
241}
242
243/// Type to convert an `Origin` type value into a `Location` value which represents an interior
244/// location of this chain.
245pub type LocalOriginToLocation = (
246	// And a usual Signed origin to be used in XCM as a corresponding AccountId32
247	SignedToAccountId32<RuntimeOrigin, AccountId, ThisNetwork>,
248);
249
250/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value.
251pub type StakingAdminToPlurality =
252	OriginToPluralityVoice<RuntimeOrigin, StakingAdmin, StakingAdminBodyId>;
253
254/// Type to convert the Fellows origin to a Plurality `Location` value.
255pub type FellowsToPlurality = OriginToPluralityVoice<RuntimeOrigin, Fellows, FellowsBodyId>;
256
257/// Type to convert the Treasury origin to a Plurality `Location` value.
258pub type TreasurerToPlurality = OriginToPluralityVoice<RuntimeOrigin, Treasurer, TreasuryBodyId>;
259
260/// Type to convert a pallet `Origin` type value into a `Location` value which represents an
261/// interior location of this chain for a destination chain.
262pub type LocalPalletOriginToLocation = (
263	// StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value.
264	StakingAdminToPlurality,
265	// Fellows origin to be used in XCM as a corresponding Plurality `Location` value.
266	FellowsToPlurality,
267	// Treasurer origin to be used in XCM as a corresponding Plurality `Location` value.
268	TreasurerToPlurality,
269);
270
271impl pallet_xcm::Config for Runtime {
272	type RuntimeEvent = RuntimeEvent;
273	// Note that this configuration of `SendXcmOrigin` is different from the one present in
274	// production.
275	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<
276		RuntimeOrigin,
277		(LocalPalletOriginToLocation, LocalOriginToLocation),
278	>;
279	type XcmRouter = XcmRouter;
280	// Anyone can execute XCM messages locally.
281	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
282	type XcmExecuteFilter = Everything;
283	type XcmExecutor = XcmExecutor<XcmConfig>;
284	type XcmTeleportFilter = Everything;
285	// Anyone is able to use reserve transfers regardless of who they are and what they want to
286	// transfer.
287	type XcmReserveTransferFilter = Everything;
288	type Weigher = FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;
289	type UniversalLocation = UniversalLocation;
290	type RuntimeOrigin = RuntimeOrigin;
291	type RuntimeCall = RuntimeCall;
292	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
293	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
294	type Currency = Balances;
295	type CurrencyMatcher = IsConcrete<TokenLocation>;
296	type TrustedLockers = ();
297	type SovereignAccountOf = LocationConverter;
298	type MaxLockers = ConstU32<8>;
299	type MaxRemoteLockConsumers = ConstU32<0>;
300	type RemoteLockConsumerIdentifier = ();
301	type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
302	type AdminOrigin = EnsureRoot<AccountId>;
303	// Aliasing is disabled: xcm_executor::Config::Aliasers is set to `Nothing`.
304	type AuthorizedAliasConsideration = Disabled;
305}