difftreelog
wip import barrier from runtime.
in: master
1 file changed
runtime/common/config/xcm.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{18 traits::{19 Contains, tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get, Everything,20 fungibles,21 },22 weights::{Weight, WeightToFeePolynomial, WeightToFee},23 parameter_types, match_types,24};25use frame_system::EnsureRoot;26use sp_runtime::{27 traits::{Saturating, CheckedConversion, Zero},28 SaturatedConversion,29};30use pallet_xcm::XcmPassthrough;31use polkadot_parachain::primitives::Sibling;32use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};33use xcm::latest::{34 AssetId::{Concrete},35 Fungibility::Fungible as XcmFungible,36 MultiAsset, Error as XcmError,37};38use xcm_builder::{39 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,40 FixedWeightBounds, FungiblesAdapter, LocationInverter, NativeAsset, ParentAsSuperuser, RelayChainAsNative,41 SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,42 SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, ParentIsPreset,43};44use xcm_executor::{Config, XcmExecutor, Assets};45use xcm_executor::traits::{Convert as ConvertXcm, MatchesFungible, WeightTrader, FilterAssetLocation};46use pallet_foreing_assets::{47 AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, CurrencyId, NativeCurrency,48 UsingAnyCurrencyComponents, TryAsForeing, ForeignAssetId,49};50use sp_std::{borrow::Borrow, marker::PhantomData, vec, vec::Vec};51use crate::{52 Runtime, Call, Event, Origin, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, XcmpQueue53};54#[cfg(feature = "foreign-assets")]55use crate::ForeingAssets;5657use up_common::{58 types::{AccountId, Balance},59 constants::*,60};6162parameter_types! {63 pub const RelayLocation: MultiLocation = MultiLocation::parent();64 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;65 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();66 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();67}6869/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used70/// when determining ownership of accounts for asset transacting and when attempting to use XCM71/// `Transact` in order to determine the dispatch Origin.72pub type LocationToAccountId = (73 // The parent (Relay-chain) origin converts to the default `AccountId`.74 ParentIsPreset<AccountId>,75 // Sibling parachain origins convert to AccountId via the `ParaId::into`.76 SiblingParachainConvertsVia<Sibling, AccountId>,77 // Straight up local `AccountId32` origins just alias directly to `AccountId`.78 AccountId32Aliases<RelayNetwork, AccountId>,79);8081pub struct OnlySelfCurrency;82impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {83 fn matches_fungible(a: &MultiAsset) -> Option<B> {84 match (&a.id, &a.fun) {85 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),86 _ => None,87 }88 }89}9091/// Means for transacting assets on this chain.92pub type LocalAssetTransactor = CurrencyAdapter<93 // Use this currency:94 Balances,95 // Use this currency when it is a fungible asset matching the given location or name:96 OnlySelfCurrency,97 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:98 LocationToAccountId,99 // Our chain's account ID type (we can't get away without mentioning it explicitly):100 AccountId,101 // We don't track any teleports.102 (),103>;104105/// No local origins on this chain are allowed to dispatch XCM sends/executions.106pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);107108/// The means for routing XCM messages which are not for local execution into the right message109/// queues.110pub type XcmRouter = (111 // Two routers - use UMP to communicate with the relay chain:112 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,113 // ..and XCMP to communicate with the sibling chains.114 XcmpQueue,115);116117/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,118/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can119/// biases the kind of local `Origin` it will become.120pub type XcmOriginToTransactDispatchOrigin = (121 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location122 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for123 // foreign chains who want to have a local sovereign account on this chain which they control.124 SovereignSignedViaLocation<LocationToAccountId, Origin>,125 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when126 // recognised.127 RelayChainAsNative<RelayOrigin, Origin>,128 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when129 // recognised.130 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,131 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a132 // transaction from the Root origin.133 ParentAsSuperuser<Origin>,134 // Native signed account converter; this just converts an `AccountId32` origin into a normal135 // `Origin::Signed` origin of the same 32-byte value.136 SignedAccountId32AsNative<RelayNetwork, Origin>,137 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.138 XcmPassthrough<Origin>,139);140141parameter_types! {142 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.143 pub UnitWeightCost: Weight = 1_000_000;144 // 1200 UNIQUEs buy 1 second of weight.145 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);146 pub const MaxInstructions: u32 = 100;147}148149match_types! {150 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {151 MultiLocation { parents: 1, interior: Here } |152 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }153 };154}155156pub type Barrier = (157 TakeWeightCredit,158 AllowTopLevelPaidExecutionFrom<Everything>,159 // ^^^ Parent & its unit plurality gets free execution160);161162pub struct UsingOnlySelfCurrencyComponents<163 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,164 AssetId: Get<MultiLocation>,165 AccountId,166 Currency: CurrencyT<AccountId>,167 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,168>(169 Weight,170 Currency::Balance,171 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,172);173impl<174 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,175 AssetId: Get<MultiLocation>,176 AccountId,177 Currency: CurrencyT<AccountId>,178 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,179 > WeightTrader180 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>181{182 fn new() -> Self {183 Self(0, Zero::zero(), PhantomData)184 }185186 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {187 let amount = WeightToFee::weight_to_fee(&weight);188 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;189190 // location to this parachain through relay chain191 let option1: xcm::v1::AssetId = Concrete(MultiLocation {192 parents: 1,193 interior: X1(Parachain(ParachainInfo::parachain_id().into())),194 });195 // direct location196 let option2: xcm::v1::AssetId = Concrete(MultiLocation {197 parents: 0,198 interior: Here,199 });200201 let required = if payment.fungible.contains_key(&option1) {202 (option1, u128_amount).into()203 } else if payment.fungible.contains_key(&option2) {204 (option2, u128_amount).into()205 } else {206 (Concrete(MultiLocation::default()), u128_amount).into()207 };208209 let unused = payment210 .checked_sub(required)211 .map_err(|_| XcmError::TooExpensive)?;212 self.0 = self.0.saturating_add(weight);213 self.1 = self.1.saturating_add(amount);214 Ok(unused)215 }216217 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {218 let weight = weight.min(self.0);219 let amount = WeightToFee::weight_to_fee(&weight);220 self.0 -= weight;221 self.1 = self.1.saturating_sub(amount);222 let amount: u128 = amount.saturated_into();223 if amount > 0 {224 Some((AssetId::get(), amount).into())225 } else {226 None227 }228 }229}230impl<231 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,232 AssetId: Get<MultiLocation>,233 AccountId,234 Currency: CurrencyT<AccountId>,235 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,236 > Drop237 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>238{239 fn drop(&mut self) {240 OnUnbalanced::on_unbalanced(Currency::issue(self.1));241 }242}243244parameter_types! {245 pub CheckingAccount: AccountId = PolkadotXcm::check_account();246}247/// Allow checking in assets that have issuance > 0.248#[cfg(feature = "foreign-assets")]249pub struct NonZeroIssuance<AccountId, ForeingAssets>(PhantomData<(AccountId, ForeingAssets)>);250251#[cfg(feature = "foreign-assets")]252impl<AccountId, ForeingAssets> Contains<<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId>253for NonZeroIssuance<AccountId, ForeingAssets>254 where255 ForeingAssets: fungibles::Inspect<AccountId>,256{257 fn contains(id: &<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId) -> bool {258 !ForeingAssets::total_issuance(*id).is_zero()259 }260}261262#[cfg(feature = "foreign-assets")]263pub struct AsInnerId<AssetId, ConvertAssetId>(PhantomData<(AssetId, ConvertAssetId)>);264#[cfg(feature = "foreign-assets")]265impl<AssetId: Clone + PartialEq, ConvertAssetId: ConvertXcm<AssetId, AssetId>>266ConvertXcm<MultiLocation, AssetId> for AsInnerId<AssetId, ConvertAssetId>267 where268 AssetId: Borrow<AssetId>,269 AssetId: TryAsForeing<AssetId, ForeignAssetId>,270 AssetIds: Borrow<AssetId>,271{272 fn convert_ref(id: impl Borrow<MultiLocation>) -> Result<AssetId, ()> {273 let id = id.borrow();274275 log::trace!(276 target: "xcm::AsInnerId::Convert",277 "AsInnerId {:?}",278 id279 );280281 let parent = MultiLocation::parent();282 let here = MultiLocation::here();283 let self_location = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));284285 if *id == parent {286 return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent));287 }288289 if *id == here || *id == self_location {290 return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here));291 }292293 match XcmForeignAssetIdMapping::<Runtime>::get_currency_id(id.clone()) {294 Some(AssetIds::ForeignAssetId(foreign_asset_id)) => {295 ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(foreign_asset_id))296 }297 _ => ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(0)),298 }299 }300301 fn reverse_ref(what: impl Borrow<AssetId>) -> Result<MultiLocation, ()> {302 log::trace!(303 target: "xcm::AsInnerId::Reverse",304 "AsInnerId",305 );306307 let asset_id = what.borrow();308309 let parent_id =310 ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent)).unwrap();311 let here_id =312 ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here)).unwrap();313314 if asset_id.clone() == parent_id {315 return Ok(MultiLocation::parent());316 }317318 if asset_id.clone() == here_id {319 return Ok(MultiLocation::new(320 1,321 X1(Parachain(ParachainInfo::get().into())),322 ));323 }324325 match <AssetId as TryAsForeing<AssetId, ForeignAssetId>>::try_as_foreing(asset_id.clone()) {326 Some(fid) => match XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid) {327 Some(location) => Ok(location),328 None => Err(()),329 },330 None => Err(()),331 }332 }333}334335/// Means for transacting assets besides the native currency on this chain.336#[cfg(feature = "foreign-assets")]337pub type FungiblesTransactor = FungiblesAdapter<338 // Use this fungibles implementation:339 ForeingAssets,340 // Use this currency when it is a fungible asset matching the given location or name:341 ConvertedConcreteAssetId<AssetIds, Balance, AsInnerId<AssetIds, JustTry>, JustTry>,342 // Convert an XCM MultiLocation into a local account id:343 LocationToAccountId,344 // Our chain's account ID type (we can't get away without mentioning it explicitly):345 AccountId,346 // We only want to allow teleports of known assets. We use non-zero issuance as an indication347 // that this asset is known.348 NonZeroIssuance<AccountId, ForeingAssets>,349 // The account to use for tracking teleports.350 CheckingAccount,351>;352353/// Means for transacting assets on this chain.354#[cfg(feature = "foreign-assets")]355pub type AssetTransactors = FungiblesTransactor;356#[cfg(not(feature = "foreign-assets"))]357pub type AssetTransactors = LocalAssetTransactor;358359#[cfg(feature = "foreign-assets")]360pub struct AllAsset;361#[cfg(feature = "foreign-assets")]362impl FilterAssetLocation for AllAsset {363 fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {364 true365 }366}367368#[cfg(feature = "foreign-assets")]369pub type IsReserve = AllAsset;370#[cfg(not(feature = "foreign-assets"))]371pub type IsReserve = NativeAsset;372373#[cfg(feature = "foreign-assets")]374type Trader<T> =375 UsingAnyCurrencyComponents<376 pallet_configuration::WeightToFee<T, Balance>,377 RelayLocation, AccountId, Balances, ()>;378#[cfg(not(feature = "foreign-assets"))]379type Trader<T> = UsingOnlySelfCurrencyComponents<380 pallet_configuration::WeightToFee<T, Balance>,381 RelayLocation,382 AccountId,383 Balances,384 (),385>;386387pub struct XcmConfig<T>(PhantomData<T>);388impl<T> Config for XcmConfig<T>389where390 T: pallet_configuration::Config,391{392 type Call = Call;393 type XcmSender = XcmRouter;394 // How to withdraw and deposit an asset.395 type AssetTransactor = LocalAssetTransactor;396 type OriginConverter = XcmOriginToTransactDispatchOrigin;397 type IsReserve = IsReserve;398 type IsTeleporter = (); // Teleportation is disabled399 type LocationInverter = LocationInverter<Ancestry>;400 type Barrier = Barrier;401 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;402 type Trader = Trader<T>;403 type ResponseHandler = (); // Don't handle responses for now.404 type SubscriptionService = PolkadotXcm;405406 type AssetTrap = PolkadotXcm;407 type AssetClaims = PolkadotXcm;408}409410impl pallet_xcm::Config for Runtime {411 type Event = Event;412 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;413 type XcmRouter = XcmRouter;414 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;415 type XcmExecuteFilter = Everything;416 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;417 type XcmTeleportFilter = Everything;418 type XcmReserveTransferFilter = Everything;419 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;420 type LocationInverter = LocationInverter<Ancestry>;421 type Origin = Origin;422 type Call = Call;423 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;424 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;425}426427impl cumulus_pallet_xcm::Config for Runtime {428 type Event = Event;429 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;430}431432impl cumulus_pallet_xcmp_queue::Config for Runtime {433 type WeightInfo = ();434 type Event = Event;435 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;436 type ChannelInfo = ParachainSystem;437 type VersionWrapper = ();438 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;439 type ControllerOrigin = EnsureRoot<AccountId>;440 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;441}442443impl cumulus_pallet_dmp_queue::Config for Runtime {444 type Event = Event;445 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;446 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;447}4481// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{18 traits::{19 Contains, tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get, Everything,20 fungibles,21 },22 weights::{Weight, WeightToFeePolynomial, WeightToFee},23 parameter_types, match_types,24};25use frame_system::EnsureRoot;26use sp_runtime::{27 traits::{Saturating, CheckedConversion, Zero},28 SaturatedConversion,29};30use pallet_xcm::XcmPassthrough;31use polkadot_parachain::primitives::Sibling;32use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};33use xcm::latest::{34 AssetId::{Concrete},35 Fungibility::Fungible as XcmFungible,36 MultiAsset, Error as XcmError,37};38use xcm_builder::{39 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,40 FixedWeightBounds, FungiblesAdapter, LocationInverter, NativeAsset, ParentAsSuperuser, RelayChainAsNative,41 SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,42 SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, ParentIsPreset,43};44use xcm_executor::{Config, XcmExecutor, Assets};45use xcm_executor::traits::{Convert as ConvertXcm, MatchesFungible, WeightTrader, FilterAssetLocation};46use pallet_foreing_assets::{47 AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, CurrencyId, NativeCurrency,48 UsingAnyCurrencyComponents, TryAsForeing, ForeignAssetId,49};50use sp_std::{borrow::Borrow, marker::PhantomData, vec, vec::Vec};51use crate::{52 Runtime, Call, Event, Origin, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, XcmpQueue,53 xcm_config::Barrier54};55#[cfg(feature = "foreign-assets")]56use crate::ForeingAssets;5758use up_common::{59 types::{AccountId, Balance},60 constants::*,61};6263parameter_types! {64 pub const RelayLocation: MultiLocation = MultiLocation::parent();65 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;66 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();67 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();68}6970/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used71/// when determining ownership of accounts for asset transacting and when attempting to use XCM72/// `Transact` in order to determine the dispatch Origin.73pub type LocationToAccountId = (74 // The parent (Relay-chain) origin converts to the default `AccountId`.75 ParentIsPreset<AccountId>,76 // Sibling parachain origins convert to AccountId via the `ParaId::into`.77 SiblingParachainConvertsVia<Sibling, AccountId>,78 // Straight up local `AccountId32` origins just alias directly to `AccountId`.79 AccountId32Aliases<RelayNetwork, AccountId>,80);8182pub struct OnlySelfCurrency;83impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {84 fn matches_fungible(a: &MultiAsset) -> Option<B> {85 match (&a.id, &a.fun) {86 (Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),87 _ => None,88 }89 }90}9192/// Means for transacting assets on this chain.93pub type LocalAssetTransactor = CurrencyAdapter<94 // Use this currency:95 Balances,96 // Use this currency when it is a fungible asset matching the given location or name:97 OnlySelfCurrency,98 // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:99 LocationToAccountId,100 // Our chain's account ID type (we can't get away without mentioning it explicitly):101 AccountId,102 // We don't track any teleports.103 (),104>;105106/// No local origins on this chain are allowed to dispatch XCM sends/executions.107pub type LocalOriginToLocation = (SignedToAccountId32<Origin, AccountId, RelayNetwork>,);108109/// The means for routing XCM messages which are not for local execution into the right message110/// queues.111pub type XcmRouter = (112 // Two routers - use UMP to communicate with the relay chain:113 cumulus_primitives_utility::ParentAsUmp<ParachainSystem, ()>,114 // ..and XCMP to communicate with the sibling chains.115 XcmpQueue,116);117118/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,119/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can120/// biases the kind of local `Origin` it will become.121pub type XcmOriginToTransactDispatchOrigin = (122 // Sovereign account converter; this attempts to derive an `AccountId` from the origin location123 // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for124 // foreign chains who want to have a local sovereign account on this chain which they control.125 SovereignSignedViaLocation<LocationToAccountId, Origin>,126 // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when127 // recognised.128 RelayChainAsNative<RelayOrigin, Origin>,129 // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when130 // recognised.131 SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,132 // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a133 // transaction from the Root origin.134 ParentAsSuperuser<Origin>,135 // Native signed account converter; this just converts an `AccountId32` origin into a normal136 // `Origin::Signed` origin of the same 32-byte value.137 SignedAccountId32AsNative<RelayNetwork, Origin>,138 // Xcm origins can be represented natively under the Xcm pallet's Xcm origin.139 XcmPassthrough<Origin>,140);141142parameter_types! {143 // One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.144 pub UnitWeightCost: Weight = 1_000_000;145 // 1200 UNIQUEs buy 1 second of weight.146 pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), 1_200 * UNIQUE);147 pub const MaxInstructions: u32 = 100;148}149150match_types! {151 pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {152 MultiLocation { parents: 1, interior: Here } |153 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) }154 };155}156157/*158pub type Barrier = (159 TakeWeightCredit,160 AllowTopLevelPaidExecutionFrom<Everything>,161 // ^^^ Parent & its unit plurality gets free execution162);163 */164165pub struct UsingOnlySelfCurrencyComponents<166 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,167 AssetId: Get<MultiLocation>,168 AccountId,169 Currency: CurrencyT<AccountId>,170 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,171>(172 Weight,173 Currency::Balance,174 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,175);176impl<177 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,178 AssetId: Get<MultiLocation>,179 AccountId,180 Currency: CurrencyT<AccountId>,181 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,182 > WeightTrader183 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>184{185 fn new() -> Self {186 Self(0, Zero::zero(), PhantomData)187 }188189 fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {190 let amount = WeightToFee::weight_to_fee(&weight);191 let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;192193 // location to this parachain through relay chain194 let option1: xcm::v1::AssetId = Concrete(MultiLocation {195 parents: 1,196 interior: X1(Parachain(ParachainInfo::parachain_id().into())),197 });198 // direct location199 let option2: xcm::v1::AssetId = Concrete(MultiLocation {200 parents: 0,201 interior: Here,202 });203204 let required = if payment.fungible.contains_key(&option1) {205 (option1, u128_amount).into()206 } else if payment.fungible.contains_key(&option2) {207 (option2, u128_amount).into()208 } else {209 (Concrete(MultiLocation::default()), u128_amount).into()210 };211212 let unused = payment213 .checked_sub(required)214 .map_err(|_| XcmError::TooExpensive)?;215 self.0 = self.0.saturating_add(weight);216 self.1 = self.1.saturating_add(amount);217 Ok(unused)218 }219220 fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {221 let weight = weight.min(self.0);222 let amount = WeightToFee::weight_to_fee(&weight);223 self.0 -= weight;224 self.1 = self.1.saturating_sub(amount);225 let amount: u128 = amount.saturated_into();226 if amount > 0 {227 Some((AssetId::get(), amount).into())228 } else {229 None230 }231 }232}233impl<234 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,235 AssetId: Get<MultiLocation>,236 AccountId,237 Currency: CurrencyT<AccountId>,238 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,239 > Drop240 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>241{242 fn drop(&mut self) {243 OnUnbalanced::on_unbalanced(Currency::issue(self.1));244 }245}246247parameter_types! {248 pub CheckingAccount: AccountId = PolkadotXcm::check_account();249}250/// Allow checking in assets that have issuance > 0.251#[cfg(feature = "foreign-assets")]252pub struct NonZeroIssuance<AccountId, ForeingAssets>(PhantomData<(AccountId, ForeingAssets)>);253254#[cfg(feature = "foreign-assets")]255impl<AccountId, ForeingAssets> Contains<<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId>256for NonZeroIssuance<AccountId, ForeingAssets>257 where258 ForeingAssets: fungibles::Inspect<AccountId>,259{260 fn contains(id: &<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId) -> bool {261 !ForeingAssets::total_issuance(*id).is_zero()262 }263}264265#[cfg(feature = "foreign-assets")]266pub struct AsInnerId<AssetId, ConvertAssetId>(PhantomData<(AssetId, ConvertAssetId)>);267#[cfg(feature = "foreign-assets")]268impl<AssetId: Clone + PartialEq, ConvertAssetId: ConvertXcm<AssetId, AssetId>>269ConvertXcm<MultiLocation, AssetId> for AsInnerId<AssetId, ConvertAssetId>270 where271 AssetId: Borrow<AssetId>,272 AssetId: TryAsForeing<AssetId, ForeignAssetId>,273 AssetIds: Borrow<AssetId>,274{275 fn convert_ref(id: impl Borrow<MultiLocation>) -> Result<AssetId, ()> {276 let id = id.borrow();277278 log::trace!(279 target: "xcm::AsInnerId::Convert",280 "AsInnerId {:?}",281 id282 );283284 let parent = MultiLocation::parent();285 let here = MultiLocation::here();286 let self_location = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));287288 if *id == parent {289 return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent));290 }291292 if *id == here || *id == self_location {293 return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here));294 }295296 match XcmForeignAssetIdMapping::<Runtime>::get_currency_id(id.clone()) {297 Some(AssetIds::ForeignAssetId(foreign_asset_id)) => {298 ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(foreign_asset_id))299 }300 _ => ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(0)),301 }302 }303304 fn reverse_ref(what: impl Borrow<AssetId>) -> Result<MultiLocation, ()> {305 log::trace!(306 target: "xcm::AsInnerId::Reverse",307 "AsInnerId",308 );309310 let asset_id = what.borrow();311312 let parent_id =313 ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent)).unwrap();314 let here_id =315 ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here)).unwrap();316317 if asset_id.clone() == parent_id {318 return Ok(MultiLocation::parent());319 }320321 if asset_id.clone() == here_id {322 return Ok(MultiLocation::new(323 1,324 X1(Parachain(ParachainInfo::get().into())),325 ));326 }327328 match <AssetId as TryAsForeing<AssetId, ForeignAssetId>>::try_as_foreing(asset_id.clone()) {329 Some(fid) => match XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid) {330 Some(location) => Ok(location),331 None => Err(()),332 },333 None => Err(()),334 }335 }336}337338/// Means for transacting assets besides the native currency on this chain.339#[cfg(feature = "foreign-assets")]340pub type FungiblesTransactor = FungiblesAdapter<341 // Use this fungibles implementation:342 ForeingAssets,343 // Use this currency when it is a fungible asset matching the given location or name:344 ConvertedConcreteAssetId<AssetIds, Balance, AsInnerId<AssetIds, JustTry>, JustTry>,345 // Convert an XCM MultiLocation into a local account id:346 LocationToAccountId,347 // Our chain's account ID type (we can't get away without mentioning it explicitly):348 AccountId,349 // We only want to allow teleports of known assets. We use non-zero issuance as an indication350 // that this asset is known.351 NonZeroIssuance<AccountId, ForeingAssets>,352 // The account to use for tracking teleports.353 CheckingAccount,354>;355356/// Means for transacting assets on this chain.357#[cfg(feature = "foreign-assets")]358pub type AssetTransactors = FungiblesTransactor;359#[cfg(not(feature = "foreign-assets"))]360pub type AssetTransactors = LocalAssetTransactor;361362#[cfg(feature = "foreign-assets")]363pub struct AllAsset;364#[cfg(feature = "foreign-assets")]365impl FilterAssetLocation for AllAsset {366 fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {367 true368 }369}370371#[cfg(feature = "foreign-assets")]372pub type IsReserve = AllAsset;373#[cfg(not(feature = "foreign-assets"))]374pub type IsReserve = NativeAsset;375376#[cfg(feature = "foreign-assets")]377type Trader<T> =378 UsingAnyCurrencyComponents<379 pallet_configuration::WeightToFee<T, Balance>,380 RelayLocation, AccountId, Balances, ()>;381#[cfg(not(feature = "foreign-assets"))]382type Trader<T> = UsingOnlySelfCurrencyComponents<383 pallet_configuration::WeightToFee<T, Balance>,384 RelayLocation,385 AccountId,386 Balances,387 (),388>;389390pub struct XcmConfig<T>(PhantomData<T>);391impl<T> Config for XcmConfig<T>392where393 T: pallet_configuration::Config,394{395 type Call = Call;396 type XcmSender = XcmRouter;397 // How to withdraw and deposit an asset.398 type AssetTransactor = LocalAssetTransactor;399 type OriginConverter = XcmOriginToTransactDispatchOrigin;400 type IsReserve = IsReserve;401 type IsTeleporter = (); // Teleportation is disabled402 type LocationInverter = LocationInverter<Ancestry>;403 type Barrier = Barrier;404 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;405 type Trader = Trader<T>;406 type ResponseHandler = (); // Don't handle responses for now.407 type SubscriptionService = PolkadotXcm;408409 type AssetTrap = PolkadotXcm;410 type AssetClaims = PolkadotXcm;411}412413impl pallet_xcm::Config for Runtime {414 type Event = Event;415 type SendXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;416 type XcmRouter = XcmRouter;417 type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;418 type XcmExecuteFilter = Everything;419 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;420 type XcmTeleportFilter = Everything;421 type XcmReserveTransferFilter = Everything;422 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;423 type LocationInverter = LocationInverter<Ancestry>;424 type Origin = Origin;425 type Call = Call;426 const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;427 type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;428}429430impl cumulus_pallet_xcm::Config for Runtime {431 type Event = Event;432 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;433}434435impl cumulus_pallet_xcmp_queue::Config for Runtime {436 type WeightInfo = ();437 type Event = Event;438 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;439 type ChannelInfo = ParachainSystem;440 type VersionWrapper = ();441 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;442 type ControllerOrigin = EnsureRoot<AccountId>;443 type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;444}445446impl cumulus_pallet_dmp_queue::Config for Runtime {447 type Event = Event;448 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;449 type ExecuteOverweightOrigin = frame_system::EnsureRoot<AccountId>;450}451