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 AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom,
69 AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteId,
70 DescribeAllTerminal, DescribeFamily, DescribeTerminus, EnsureXcmOrigin,
71 ExternalConsensusLocationsConverterFor, FixedWeightBounds, FrameTransactionalProcessor,
72 FungibleAdapter, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NativeAsset,
73 NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount,
74 SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
75 SignedToAccountId32, SingleAssetExchangeAdapter, SovereignSignedViaLocation, StartsWith,
76 TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
77 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 AllowSubscriptionsFrom<Everything>,
253 AllowHrmpNotificationsFromRelayChain,
255 ),
256 UniversalLocation,
257 ConstU32<8>,
258 >,
259)>;
260
261pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
263
264pub struct AssetPrefixFrom<Prefix, Origin>(PhantomData<(Prefix, Origin)>);
266impl<Prefix, Origin> ContainsPair<Asset, Location> for AssetPrefixFrom<Prefix, Origin>
267where
268 Prefix: Get<Location>,
269 Origin: Get<Location>,
270{
271 fn contains(asset: &Asset, origin: &Location) -> bool {
272 let loc = Origin::get();
273 &loc == origin &&
274 matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) }
275 if asset_loc.starts_with(&Prefix::get()))
276 }
277}
278
279type AssetsFrom<T> = AssetPrefixFrom<T, T>;
280
281pub const RESERVABLE_ASSET_ID: u32 = 1;
283pub const TELEPORTABLE_ASSET_ID: u32 = 2;
285
286pub const ASSETS_PALLET_ID: u8 = 50;
287pub const ASSET_HUB_ID: u32 = 1000;
288
289pub const USDT_ASSET_ID: u128 = 1984;
290
291parameter_types! {
292 pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]);
294 pub SystemAssetHubAssetsPalletLocation: Location =
296 Location::new(1, [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID)]);
297 pub AssetsPalletLocation: Location =
298 Location::new(0, [PalletInstance(ASSETS_PALLET_ID)]);
299 pub CheckingAccount: AccountId = PolkadotXcm::check_account();
300 pub LocalTeleportableToAssetHub: Location = Location::new(
301 0,
302 [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(TELEPORTABLE_ASSET_ID.into())]
303 );
304 pub LocalReservableFromAssetHub: Location = Location::new(
305 1,
306 [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID), GeneralIndex(RESERVABLE_ASSET_ID.into())]
307 );
308 pub UsdtFromAssetHub: Location = Location::new(
309 1,
310 [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID), GeneralIndex(USDT_ASSET_ID)],
311 );
312
313 pub storage CustomizableAssetFromSystemAssetHub: Location = SystemAssetHubLocation::get();
319}
320
321pub struct AssetFromChain<AssetLocation, Origin>(PhantomData<(AssetLocation, Origin)>);
323impl<AssetLocation: Get<Location>, Origin: Get<Location>> ContainsPair<Asset, Location>
324 for AssetFromChain<AssetLocation, Origin>
325{
326 fn contains(asset: &Asset, origin: &Location) -> bool {
327 log::trace!(target: "xcm::contains", "AssetFromChain asset: {:?}, origin: {:?}", asset, origin);
328 *origin == Origin::get() &&
329 matches!(asset.id.clone(), AssetId(id) if id == AssetLocation::get())
330 }
331}
332
333pub type TrustedReserves = (
334 NativeAsset,
335 ConcreteAssetFromSystem<RelayLocation>,
336 AssetsFrom<SystemAssetHubLocation>,
337 AssetPrefixFrom<CustomizableAssetFromSystemAssetHub, SystemAssetHubLocation>,
338);
339pub type TrustedTeleporters =
340 (AssetFromChain<LocalTeleportableToAssetHub, SystemAssetHubLocation>,);
341
342pub type TrustedAliasers = (
348 AliasChildLocation,
349 AliasOriginRootUsingFilter<SystemAssetHubLocation, Everything>,
350 AuthorizedAliasers<Runtime>,
351);
352
353pub type WaivedLocations = Equals<RootLocation>;
354pub type TrustBackedAssetsConvertedConcreteId =
356 assets_common::TrustBackedAssetsConvertedConcreteId<AssetsPalletLocation, Balance>;
357
358pub type PoolAssetsExchanger = SingleAssetExchangeAdapter<
363 crate::AssetConversion,
364 crate::NativeAndAssets,
365 (
366 TrustBackedAssetsAsLocation<
367 TrustBackedAssetsPalletLocation,
368 Balance,
369 xcm::latest::Location,
370 >,
371 ForeignAssetsConvertedConcreteId,
372 ),
373 AccountId,
374>;
375
376pub struct XcmConfig;
377impl xcm_executor::Config for XcmConfig {
378 type RuntimeCall = RuntimeCall;
379 type XcmSender = XcmRouter;
380 type XcmEventEmitter = PolkadotXcm;
381 type AssetTransactor = AssetTransactors;
383 type OriginConverter = XcmOriginToTransactDispatchOrigin;
384 type IsReserve = TrustedReserves;
385 type IsTeleporter = TrustedTeleporters;
387 type UniversalLocation = UniversalLocation;
388 type Barrier = Barrier;
389 type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
390 type Trader = (
391 UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToAuthor<Runtime>>,
392 cumulus_primitives_utility::SwapFirstAssetTrader<
393 RelayLocation,
394 crate::AssetConversion,
395 WeightToFee,
396 crate::NativeAndAssets,
397 (
398 TrustBackedAssetsAsLocation<
399 TrustBackedAssetsPalletLocation,
400 Balance,
401 xcm::latest::Location,
402 >,
403 ForeignAssetsConvertedConcreteId,
404 ),
405 ResolveAssetTo<StakingPot, crate::NativeAndAssets>,
406 AccountId,
407 >,
408 );
409 type ResponseHandler = PolkadotXcm;
410 type AssetTrap = PolkadotXcm;
411 type AssetClaims = PolkadotXcm;
412 type SubscriptionService = PolkadotXcm;
413 type PalletInstancesInfo = AllPalletsWithSystem;
414 type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
415 type AssetLocker = ();
416 type AssetExchanger = PoolAssetsExchanger;
417 type FeeManager = XcmFeeManagerFromComponents<
418 WaivedLocations,
419 SendXcmFeeToAccount<Self::AssetTransactor, TreasuryAccount>,
420 >;
421 type MessageExporter = ();
422 type UniversalAliases = Nothing;
423 type CallDispatcher = RuntimeCall;
424 type SafeCallFilter = Everything;
425 type Aliasers = TrustedAliasers;
426 type TransactionalProcessor = FrameTransactionalProcessor;
427 type HrmpNewChannelOpenRequestHandler = ();
428 type HrmpChannelAcceptedHandler = ();
429 type HrmpChannelClosingHandler = ();
430 type XcmRecorder = PolkadotXcm;
431}
432
433pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
435 AssetFeeAsExistentialDepositMultiplier<
436 Runtime,
437 WeightToFee,
438 pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto, ForeignAssetsInstance>,
439 ForeignAssetsInstance,
440 >;
441
442pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
445
446pub type PriceForParentDelivery =
447 ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
448
449pub type XcmRouter = WithUniqueTopic<(
452 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
454 XcmpQueue,
456)>;
457
458parameter_types! {
459 pub const DepositPerItem: Balance = deposit(1, 0);
460 pub const DepositPerByte: Balance = deposit(0, 1);
461 pub const AuthorizeAliasHoldReason: RuntimeHoldReason = RuntimeHoldReason::PolkadotXcm(pallet_xcm::HoldReason::AuthorizeAlias);
462}
463
464impl pallet_xcm::Config for Runtime {
465 type RuntimeEvent = RuntimeEvent;
466 type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
467 type XcmRouter = XcmRouter;
468 type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
469 type XcmExecuteFilter = Everything;
470 type XcmExecutor = XcmExecutor<XcmConfig>;
471 type XcmTeleportFilter = Everything;
472 type XcmReserveTransferFilter = Everything;
473 type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
474 type UniversalLocation = UniversalLocation;
475 type RuntimeOrigin = RuntimeOrigin;
476 type RuntimeCall = RuntimeCall;
477
478 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
479 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
481 type Currency = Balances;
482 type CurrencyMatcher = ();
483 type TrustedLockers = ();
484 type SovereignAccountOf = LocationToAccountId;
485 type MaxLockers = ConstU32<8>;
486 type WeightInfo = pallet_xcm::TestWeightInfo;
487 type AdminOrigin = EnsureRoot<AccountId>;
488 type MaxRemoteLockConsumers = ConstU32<0>;
489 type RemoteLockConsumerIdentifier = ();
490 type AuthorizedAliasConsideration = HoldConsideration<
492 AccountId,
493 Balances,
494 AuthorizeAliasHoldReason,
495 LinearStoragePrice<DepositPerItem, DepositPerByte, Balance>,
496 >;
497}
498
499impl cumulus_pallet_xcm::Config for Runtime {
500 type RuntimeEvent = RuntimeEvent;
501 type XcmExecutor = XcmExecutor<XcmConfig>;
502}
503
504pub struct XcmBenchmarkHelper;
506#[cfg(feature = "runtime-benchmarks")]
507impl pallet_assets::BenchmarkHelper<ForeignAssetsAssetId> for XcmBenchmarkHelper {
508 fn create_asset_id_parameter(id: u32) -> ForeignAssetsAssetId {
509 Location::new(1, [Parachain(id)])
510 }
511}