referrerpolicy=no-referrer-when-downgrade

polkadot_test_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
17use frame_support::{
18	parameter_types,
19	traits::{Disabled, Everything, Get, Nothing},
20	weights::Weight,
21};
22use frame_system::EnsureRoot;
23use polkadot_runtime_common::xcm_sender::{ChildParachainRouter, PriceForMessageDelivery};
24use polkadot_runtime_parachains::FeeTracker;
25use xcm::latest::prelude::*;
26use xcm_builder::{
27	AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, FrameTransactionalProcessor,
28	SignedAccountId32AsNative, SignedToAccountId32, WithUniqueTopic,
29};
30use xcm_executor::{
31	traits::{TransactAsset, WeightTrader},
32	AssetsInHolding,
33};
34
35parameter_types! {
36	pub const BaseXcmWeight: xcm::latest::Weight = Weight::from_parts(1_000, 1_000);
37	pub const AnyNetwork: Option<NetworkId> = None;
38	pub const MaxInstructions: u32 = 100;
39	pub const MaxAssetsIntoHolding: u32 = 16;
40	pub const UniversalLocation: xcm::latest::InteriorLocation = xcm::latest::Junctions::Here;
41	pub TokenLocation: Location = Here.into_location();
42	pub FeeAssetId: AssetId = AssetId(TokenLocation::get());
43}
44
45/// Type to convert an `Origin` type value into a `Location` value which represents an interior
46/// location of this chain.
47pub type LocalOriginToLocation = (
48	// And a usual Signed origin to be used in XCM as a corresponding AccountId32
49	SignedToAccountId32<crate::RuntimeOrigin, crate::AccountId, AnyNetwork>,
50);
51
52/// Implementation of [`PriceForMessageDelivery`], returning a different price
53/// based on whether a message contains a reanchored asset or not.
54/// This implementation ensures that messages with non-reanchored assets return higher
55/// prices than messages with reanchored assets.
56/// Useful for `deposit_reserve_asset_works_for_any_xcm_sender` integration test.
57pub struct TestDeliveryPrice<A, F>(core::marker::PhantomData<(A, F)>);
58impl<A: Get<AssetId>, F: FeeTracker> PriceForMessageDelivery for TestDeliveryPrice<A, F> {
59	type Id = F::Id;
60
61	fn price_for_delivery(_: Self::Id, msg: &Xcm<()>) -> Assets {
62		let base_fee: super::Balance = 1_000_000;
63
64		let parents = msg.iter().find_map(|xcm| match xcm {
65			ReserveAssetDeposited(assets) => {
66				let AssetId(location) = &assets.inner().first().unwrap().id;
67				Some(location.parents)
68			},
69			_ => None,
70		});
71
72		// If no asset is found, price defaults to `base_fee`.
73		let amount = base_fee
74			.saturating_add(base_fee.saturating_mul(parents.unwrap_or(0) as super::Balance));
75
76		(A::get(), amount).into()
77	}
78}
79
80pub type PriceForChildParachainDelivery = TestDeliveryPrice<FeeAssetId, super::Dmp>;
81
82/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our
83/// individual routers.
84pub type XcmRouter = WithUniqueTopic<
85	// Only one router so far - use DMP to communicate with child parachains.
86	ChildParachainRouter<super::Runtime, super::Xcm, PriceForChildParachainDelivery>,
87>;
88
89pub type Barrier = AllowUnpaidExecutionFrom<Everything>;
90
91pub struct DummyAssetTransactor;
92impl TransactAsset for DummyAssetTransactor {
93	fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult {
94		Ok(())
95	}
96
97	fn withdraw_asset(
98		_what: &Asset,
99		_who: &Location,
100		_maybe_context: Option<&XcmContext>,
101	) -> Result<AssetsInHolding, XcmError> {
102		let asset: Asset = (Parent, 100_000).into();
103		Ok(asset.into())
104	}
105}
106
107#[derive(Clone)]
108pub struct DummyWeightTrader;
109impl WeightTrader for DummyWeightTrader {
110	fn new() -> Self {
111		DummyWeightTrader
112	}
113
114	fn buy_weight(
115		&mut self,
116		_weight: Weight,
117		_payment: AssetsInHolding,
118		_context: &XcmContext,
119	) -> Result<AssetsInHolding, XcmError> {
120		Ok(AssetsInHolding::default())
121	}
122}
123
124type OriginConverter = (
125	pallet_xcm::XcmPassthrough<super::RuntimeOrigin>,
126	SignedAccountId32AsNative<AnyNetwork, super::RuntimeOrigin>,
127);
128
129pub struct XcmConfig;
130impl xcm_executor::Config for XcmConfig {
131	type RuntimeCall = super::RuntimeCall;
132	type XcmSender = XcmRouter;
133	type XcmEventEmitter = super::Xcm;
134	type AssetTransactor = DummyAssetTransactor;
135	type OriginConverter = OriginConverter;
136	type IsReserve = ();
137	type IsTeleporter = ();
138	type UniversalLocation = UniversalLocation;
139	type Barrier = Barrier;
140	type Weigher = FixedWeightBounds<BaseXcmWeight, super::RuntimeCall, MaxInstructions>;
141	type Trader = DummyWeightTrader;
142	type ResponseHandler = super::Xcm;
143	type AssetTrap = super::Xcm;
144	type AssetLocker = ();
145	type AssetExchanger = ();
146	type AssetClaims = super::Xcm;
147	type SubscriptionService = super::Xcm;
148	type PalletInstancesInfo = ();
149	type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
150	type FeeManager = ();
151	type MessageExporter = ();
152	type UniversalAliases = Nothing;
153	type CallDispatcher = super::RuntimeCall;
154	type SafeCallFilter = Everything;
155	type Aliasers = Nothing;
156	type TransactionalProcessor = FrameTransactionalProcessor;
157	type HrmpNewChannelOpenRequestHandler = ();
158	type HrmpChannelAcceptedHandler = ();
159	type HrmpChannelClosingHandler = ();
160	type XcmRecorder = ();
161}
162
163impl pallet_xcm::Config for crate::Runtime {
164	// The config types here are entirely configurable, since the only one that is sorely needed
165	// is `XcmExecutor`, which will be used in unit tests located in xcm-executor.
166	type RuntimeEvent = crate::RuntimeEvent;
167	type ExecuteXcmOrigin = EnsureXcmOrigin<crate::RuntimeOrigin, LocalOriginToLocation>;
168	type UniversalLocation = UniversalLocation;
169	type SendXcmOrigin = EnsureXcmOrigin<crate::RuntimeOrigin, LocalOriginToLocation>;
170	type Weigher = FixedWeightBounds<BaseXcmWeight, crate::RuntimeCall, MaxInstructions>;
171	type XcmRouter = XcmRouter;
172	type XcmExecuteFilter = Everything;
173	type XcmExecutor = xcm_executor::XcmExecutor<XcmConfig>;
174	type XcmTeleportFilter = Everything;
175	type XcmReserveTransferFilter = Everything;
176	type RuntimeOrigin = crate::RuntimeOrigin;
177	type RuntimeCall = crate::RuntimeCall;
178	const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
179	type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
180	type Currency = crate::Balances;
181	type CurrencyMatcher = ();
182	type TrustedLockers = ();
183	type SovereignAccountOf = ();
184	type MaxLockers = frame_support::traits::ConstU32<8>;
185	type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
186	type RemoteLockConsumerIdentifier = ();
187	type WeightInfo = pallet_xcm::TestWeightInfo;
188	type AdminOrigin = EnsureRoot<crate::AccountId>;
189	// Aliasing is disabled: xcm_executor::Config::Aliasers is set to `Nothing`.
190	type AuthorizedAliasConsideration = Disabled;
191}