1use super::{
38 AccountId, AllPalletsWithSystem, AssetId as AssetIdPalletAssets, Assets, Authorship, Balance,
39 Balances, CollatorSelection, ForeignAssets, ForeignAssetsInstance, NonZeroIssuance,
40 ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
41 RuntimeHoldReason, RuntimeOrigin, WeightToFee, XcmpQueue,
42};
43use crate::{BaseDeliveryFee, FeeAssetId, TransactionByteFee};
44use assets_common::TrustBackedAssetsAsLocation;
45use core::marker::PhantomData;
46use frame_support::{
47 parameter_types,
48 traits::{
49 fungible::HoldConsideration, tokens::imbalance::ResolveAssetTo, ConstU32, Contains,
50 ContainsPair, Equals, Everything, EverythingBut, Get, LinearStoragePrice, Nothing,
51 PalletInfoAccess,
52 },
53 weights::Weight,
54};
55use frame_system::EnsureRoot;
56use pallet_xcm::{AuthorizedAliasers, XcmPassthrough};
57use parachains_common::{
58 xcm_config::{AssetFeeAsExistentialDepositMultiplier, ConcreteAssetFromSystem},
59 TREASURY_PALLET_ID,
60};
61use polkadot_parachain_primitives::primitives::Sibling;
62use polkadot_runtime_common::{impls::ToAuthor, xcm_sender::ExponentialPrice};
63use sp_runtime::traits::{AccountIdConversion, ConvertInto, Identity, TryConvertInto};
64use testnet_parachains_constants::westend::currency::deposit;
65use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH};
66use xcm_builder::{
67 AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter,
68 AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
69 AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
70 AsPrefixedGeneralIndex, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
71 DescribeTerminus, EnsureXcmOrigin, ExternalConsensusLocationsConverterFor, FixedWeightBounds,
72 FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, HashedDescription, IsConcrete,
73 LocalMint, NativeAsset, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
74 SendXcmFeeToAccount, SiblingParachainAsNative, SiblingParachainConvertsVia,
75 SignedAccountId32AsNative, SignedToAccountId32, SingleAssetExchangeAdapter,
76 SovereignSignedViaLocation, StartsWith, TakeWeightCredit, TrailingSetTopicAsId,
77 UsingComponents, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
78};
79use xcm_executor::{traits::JustTry, XcmExecutor};
80
81parameter_types! {
82 pub const RelayLocation: Location = Location::parent();
83 pub const PenpalNativeCurrency: Location = Location::here();
85 pub storage RelayNetworkId: NetworkId = NetworkId::ByGenesis(WESTEND_GENESIS_HASH);
89 pub RelayNetwork: Option<NetworkId> = Some(RelayNetworkId::get());
90 pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
91 pub UniversalLocation: InteriorLocation = [
92 GlobalConsensus(RelayNetworkId::get()),
93 Parachain(ParachainInfo::parachain_id().into())
94 ].into();
95 pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
96 pub StakingPot: AccountId = CollatorSelection::account_id();
97 pub TrustBackedAssetsPalletIndex: u8 = <Assets as PalletInfoAccess>::index() as u8;
98 pub TrustBackedAssetsPalletLocation: Location =
99 PalletInstance(TrustBackedAssetsPalletIndex::get()).into();
100}
101
102pub type LocationToAccountId = (
106 ParentIsPreset<AccountId>,
108 SiblingParachainConvertsVia<Sibling, AccountId>,
110 AccountId32Aliases<RelayNetwork, AccountId>,
112 HashedDescription<AccountId, (DescribeTerminus, DescribeFamily<DescribeAllTerminal>)>,
114 ExternalConsensusLocationsConverterFor<UniversalLocation, AccountId>,
116);
117
118pub type FungibleTransactor = FungibleAdapter<
120 Balances,
122 IsConcrete<PenpalNativeCurrency>,
124 LocationToAccountId,
126 AccountId,
128 (),
130>;
131
132pub type FungiblesTransactor = FungiblesAdapter<
134 Assets,
136 (
138 ConvertedConcreteId<
139 AssetIdPalletAssets,
140 Balance,
141 AsPrefixedGeneralIndex<AssetsPalletLocation, AssetIdPalletAssets, JustTry>,
142 JustTry,
143 >,
144 ConvertedConcreteId<
145 AssetIdPalletAssets,
146 Balance,
147 AsPrefixedGeneralIndex<
148 SystemAssetHubAssetsPalletLocation,
149 AssetIdPalletAssets,
150 JustTry,
151 >,
152 JustTry,
153 >,
154 ),
155 LocationToAccountId,
157 AccountId,
159 LocalMint<NonZeroIssuance<AccountId, Assets>>,
162 CheckingAccount,
164>;
165
166pub type ForeignAssetsAssetId = Location;
168pub type ForeignAssetsConvertedConcreteId = xcm_builder::MatchedConvertedConcreteId<
169 Location,
170 Balance,
171 EverythingBut<(
172 StartsWith<assets_common::matching::LocalLocationPattern>,
177 )>,
178 Identity,
179 TryConvertInto,
180>;
181
182pub type ForeignFungiblesTransactor = FungiblesAdapter<
184 ForeignAssets,
186 ForeignAssetsConvertedConcreteId,
188 LocationToAccountId,
190 AccountId,
192 NoChecking,
194 CheckingAccount,
196>;
197
198pub type AssetTransactors = (FungibleTransactor, ForeignFungiblesTransactor, FungiblesTransactor);
200
201pub type XcmOriginToTransactDispatchOrigin = (
205 SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
209 RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
212 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
215 ParentAsSuperuser<RuntimeOrigin>,
218 SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
221 XcmPassthrough<RuntimeOrigin>,
223);
224
225parameter_types! {
226 pub const RootLocation: Location = Location::here();
227 pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
229 pub const MaxInstructions: u32 = 100;
230 pub const MaxAssetsIntoHolding: u32 = 64;
231 pub XcmAssetFeesReceiver: Option<AccountId> = Authorship::author();
232}
233
234pub struct ParentOrParentsExecutivePlurality;
235impl Contains<Location> for ParentOrParentsExecutivePlurality {
236 fn contains(location: &Location) -> bool {
237 matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }]))
238 }
239}
240
241pub type Barrier = TrailingSetTopicAsId<(
242 TakeWeightCredit,
243 AllowKnownQueryResponses<PolkadotXcm>,
245 WithComputedOrigin<
247 (
248 AllowTopLevelPaidExecutionFrom<Everything>,
251 AllowExplicitUnpaidExecutionFrom<(ParentOrParentsExecutivePlurality,)>,
253 AllowSubscriptionsFrom<Everything>,
255 AllowHrmpNotificationsFromRelayChain,
257 ),
258 UniversalLocation,
259 ConstU32<8>,
260 >,
261)>;
262
263pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
265
266pub struct AssetPrefixFrom<Prefix, Origin>(PhantomData<(Prefix, Origin)>);
268impl<Prefix, Origin> ContainsPair<Asset, Location> for AssetPrefixFrom<Prefix, Origin>
269where
270 Prefix: Get<Location>,
271 Origin: Get<Location>,
272{
273 fn contains(asset: &Asset, origin: &Location) -> bool {
274 let loc = Origin::get();
275 &loc == origin &&
276 matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) }
277 if asset_loc.starts_with(&Prefix::get()))
278 }
279}
280
281type AssetsFrom<T> = AssetPrefixFrom<T, T>;
282
283pub const RESERVABLE_ASSET_ID: u32 = 1;
285pub const TELEPORTABLE_ASSET_ID: u32 = 2;
287
288pub const ASSETS_PALLET_ID: u8 = 50;
289pub const ASSET_HUB_ID: u32 = 1000;
290
291pub const USDT_ASSET_ID: u128 = 1984;
292
293parameter_types! {
294 pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]);
296 pub SystemAssetHubAssetsPalletLocation: Location =
298 Location::new(1, [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID)]);
299 pub AssetsPalletLocation: Location =
300 Location::new(0, [PalletInstance(ASSETS_PALLET_ID)]);
301 pub CheckingAccount: AccountId = PolkadotXcm::check_account();
302 pub LocalTeleportableToAssetHub: Location = Location::new(
303 0,
304 [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(TELEPORTABLE_ASSET_ID.into())]
305 );
306 pub LocalReservableFromAssetHub: Location = Location::new(
307 1,
308 [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID), GeneralIndex(RESERVABLE_ASSET_ID.into())]
309 );
310 pub UsdtFromAssetHub: Location = Location::new(
311 1,
312 [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID), GeneralIndex(USDT_ASSET_ID)],
313 );
314
315 pub storage CustomizableAssetFromSystemAssetHub: Location = SystemAssetHubLocation::get();
321
322 pub const NativeAssetId: AssetId = AssetId(Location::here());
323 pub const NativeAssetFilter: AssetFilter = Wild(AllOf { fun: WildFungible, id: NativeAssetId::get() });
324 pub AssetHubTrustedTeleporter: (AssetFilter, Location) = (NativeAssetFilter::get(), SystemAssetHubLocation::get());
325}
326
327pub struct AssetFromChain<AssetLocation, Origin>(PhantomData<(AssetLocation, Origin)>);
329impl<AssetLocation: Get<Location>, Origin: Get<Location>> ContainsPair<Asset, Location>
330 for AssetFromChain<AssetLocation, Origin>
331{
332 fn contains(asset: &Asset, origin: &Location) -> bool {
333 tracing::trace!(target: "xcm::contains", ?asset, ?origin, "AssetFromChain");
334 *origin == Origin::get() &&
335 matches!(asset.id.clone(), AssetId(id) if id == AssetLocation::get())
336 }
337}
338
339pub type TrustedReserves = (
340 NativeAsset,
341 ConcreteAssetFromSystem<RelayLocation>,
342 AssetsFrom<SystemAssetHubLocation>,
343 AssetPrefixFrom<CustomizableAssetFromSystemAssetHub, SystemAssetHubLocation>,
344);
345
346pub type TrustedTeleporters = (
347 AssetFromChain<LocalTeleportableToAssetHub, SystemAssetHubLocation>,
348 xcm_builder::Case<AssetHubTrustedTeleporter>,
351);
352
353pub type TrustedAliasers = (
359 AliasChildLocation,
360 AliasOriginRootUsingFilter<SystemAssetHubLocation, Everything>,
361 AuthorizedAliasers<Runtime>,
362);
363
364pub type WaivedLocations = Equals<RootLocation>;
365pub type TrustBackedAssetsConvertedConcreteId =
367 assets_common::TrustBackedAssetsConvertedConcreteId<AssetsPalletLocation, Balance>;
368
369pub type PoolAssetsExchanger = SingleAssetExchangeAdapter<
374 crate::AssetConversion,
375 crate::NativeAndAssets,
376 (
377 TrustBackedAssetsAsLocation<
378 TrustBackedAssetsPalletLocation,
379 Balance,
380 xcm::latest::Location,
381 >,
382 ForeignAssetsConvertedConcreteId,
383 ),
384 AccountId,
385>;
386
387pub struct XcmConfig;
388impl xcm_executor::Config for XcmConfig {
389 type RuntimeCall = RuntimeCall;
390 type XcmSender = XcmRouter;
391 type XcmEventEmitter = PolkadotXcm;
392 type AssetTransactor = AssetTransactors;
394 type OriginConverter = XcmOriginToTransactDispatchOrigin;
395 type IsReserve = TrustedReserves;
396 type IsTeleporter = TrustedTeleporters;
398 type UniversalLocation = UniversalLocation;
399 type Barrier = Barrier;
400 type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
401 type Trader = (
402 UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToAuthor<Runtime>>,
403 UsingComponents<WeightToFee, PenpalNativeCurrency, AccountId, Balances, ToAuthor<Runtime>>,
405 cumulus_primitives_utility::SwapFirstAssetTrader<
406 RelayLocation,
407 crate::AssetConversion,
408 WeightToFee,
409 crate::NativeAndAssets,
410 (
411 TrustBackedAssetsAsLocation<
412 TrustBackedAssetsPalletLocation,
413 Balance,
414 xcm::latest::Location,
415 >,
416 ForeignAssetsConvertedConcreteId,
417 ),
418 ResolveAssetTo<StakingPot, crate::NativeAndAssets>,
419 AccountId,
420 >,
421 );
422 type ResponseHandler = PolkadotXcm;
423 type AssetTrap = PolkadotXcm;
424 type AssetClaims = PolkadotXcm;
425 type SubscriptionService = PolkadotXcm;
426 type PalletInstancesInfo = AllPalletsWithSystem;
427 type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
428 type AssetLocker = ();
429 type AssetExchanger = PoolAssetsExchanger;
430 type FeeManager = XcmFeeManagerFromComponents<
431 WaivedLocations,
432 SendXcmFeeToAccount<Self::AssetTransactor, TreasuryAccount>,
433 >;
434 type MessageExporter = ();
435 type UniversalAliases = Nothing;
436 type CallDispatcher = RuntimeCall;
437 type SafeCallFilter = Everything;
438 type Aliasers = TrustedAliasers;
439 type TransactionalProcessor = FrameTransactionalProcessor;
440 type HrmpNewChannelOpenRequestHandler = ();
441 type HrmpChannelAcceptedHandler = ();
442 type HrmpChannelClosingHandler = ();
443 type XcmRecorder = PolkadotXcm;
444}
445
446pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
448 AssetFeeAsExistentialDepositMultiplier<
449 Runtime,
450 WeightToFee,
451 pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto, ForeignAssetsInstance>,
452 ForeignAssetsInstance,
453 >;
454
455pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
458
459pub type PriceForParentDelivery =
460 ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
461
462pub type XcmRouter = WithUniqueTopic<(
465 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
467 XcmpQueue,
469)>;
470
471parameter_types! {
472 pub const DepositPerItem: Balance = deposit(1, 0);
473 pub const DepositPerByte: Balance = deposit(0, 1);
474 pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::PolkadotXcm(pallet_xcm::HoldReason::AuthorizeAlias);
475}
476
477impl pallet_xcm::Config for Runtime {
478 type RuntimeEvent = RuntimeEvent;
479 type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
480 type XcmRouter = XcmRouter;
481 type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
482 type XcmExecuteFilter = Everything;
483 type XcmExecutor = XcmExecutor<XcmConfig>;
484 type XcmTeleportFilter = Everything;
485 type XcmReserveTransferFilter = Everything;
486 type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
487 type UniversalLocation = UniversalLocation;
488 type RuntimeOrigin = RuntimeOrigin;
489 type RuntimeCall = RuntimeCall;
490
491 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
492 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
494 type Currency = Balances;
495 type CurrencyMatcher = ();
496 type TrustedLockers = ();
497 type SovereignAccountOf = LocationToAccountId;
498 type MaxLockers = ConstU32<8>;
499 type WeightInfo = pallet_xcm::TestWeightInfo;
500 type AdminOrigin = EnsureRoot<AccountId>;
501 type MaxRemoteLockConsumers = ConstU32<0>;
502 type RemoteLockConsumerIdentifier = ();
503 type AuthorizedAliasConsideration = HoldConsideration<
505 AccountId,
506 Balances,
507 AuthorizeAliasHoldReason,
508 LinearStoragePrice<DepositPerItem, DepositPerByte, Balance>,
509 >;
510}
511
512impl cumulus_pallet_xcm::Config for Runtime {
513 type RuntimeEvent = RuntimeEvent;
514 type XcmExecutor = XcmExecutor<XcmConfig>;
515}
516
517pub struct XcmBenchmarkHelper;
519#[cfg(feature = "runtime-benchmarks")]
520impl pallet_assets::BenchmarkHelper<ForeignAssetsAssetId> for XcmBenchmarkHelper {
521 fn create_asset_id_parameter(id: u32) -> ForeignAssetsAssetId {
522 Location::new(1, [Parachain(id)])
523 }
524}