use crate::{
AccountId, AllPalletsWithSystem, AssetRegistry, Assets, Balance, Balances, DmpQueue,
ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
WeightToFee, XcmpQueue, MAXIMUM_BLOCK_WEIGHT,
};
use circuit_runtime_types::default_fee_per_second;
use cumulus_primitives_core::ParaId;
use cumulus_primitives_core::GetChannelInfo;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, ContainsPair, Currency, Everything, Get, Nothing, OnUnbalanced},
weights::Weight,
};
use frame_system::EnsureRoot;
use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use sp_std::{marker::PhantomData, vec::Vec};
use xcm::latest::prelude::*;
use parachains_common::AssetIdForTrustBackedAssets;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,
FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, IsConcrete, NativeAsset, NoChecking,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WithComputedOrigin,
};
use xcm_executor::{traits::JustTry, XcmExecutor};
use xcm_primitives::{AsAssetMultiLocation, ConvertedRegisteredAssetId};
parameter_types! {
pub const SelfGatewayId: [u8; 4] = [3, 3, 3, 3];
pub const XbiSovereign: AccountId = AccountId::new([68u8; 32]); }
parameter_types! {
pub ReserveBalanceCustodian: AccountId = PolkadotXcm::check_account();
pub NotificationWeight: Weight = Weight::from_parts(1, 0u64);
}
parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
pub const RelayAssetId: u32 = 1;
pub RelayNetwork: Option<NetworkId> = Some(NetworkId::Rococo);
pub const SelfLocation: MultiLocation = MultiLocation::here();
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub Ancestry: MultiLocation = Parachain(3334).into();
pub UniversalLocation: InteriorMultiLocation = (
GlobalConsensus(NetworkId::Rococo),
Parachain(ParachainInfo::parachain_id().into()),
).into();
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
pub AssetsPalletLocation: MultiLocation =
PalletInstance(12u8).into();
pub PlaceholderAccount: AccountId = PolkadotXcm::check_account();
}
pub type SovereignAccountOf = (
SiblingParachainConvertsVia<ParaId, AccountId>,
AccountId32Aliases<RelayNetwork, AccountId>,
);
parameter_types! {
pub MaxAssetsIntoHolding: u32 = 64;
}
pub type LocalAssetTransactor = CurrencyAdapter<
Balances,
IsConcrete<SelfLocation>,
LocationToAccountId,
AccountId,
(),
>;
pub type TrustBackedAssetsConvertedConcreteId =
assets_common::TrustBackedAssetsConvertedConcreteId<AssetsPalletLocation, Balance>;
pub type FungiblesTransactor = FungiblesAdapter<
Assets,
ConvertedRegisteredAssetId<
AssetIdForTrustBackedAssets,
Balance,
AsAssetMultiLocation<AssetIdForTrustBackedAssets, AssetRegistry>,
JustTry,
>,
LocationToAccountId,
AccountId,
NoChecking,
PlaceholderAccount,
>;
pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor);
match_types! {
pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here } |
MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }
};
}
pub type Barrier = TrailingSetTopicAsId<(
TakeWeightCredit,
AllowKnownQueryResponses<PolkadotXcm>,
WithComputedOrigin<
(
AllowTopLevelPaidExecutionFrom<Everything>,
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
AllowSubscriptionsFrom<ParentOrSiblings>,
),
UniversalLocation,
ConstU32<8>,
>,
)>;
parameter_types! {
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub SelfParaId: ParaId = ParaId::from(3334);
}
impl cumulus_pallet_parachain_system::Config for Runtime {
type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::AnyRelayNumber;
type DmpMessageHandler = DmpQueue;
type OnSystemEvent = ();
type OutboundXcmpMessageSource = XcmpQueue;
type ReservedDmpWeight = ReservedDmpWeight;
type ReservedXcmpWeight = ReservedXcmpWeight;
type RuntimeEvent = RuntimeEvent;
type SelfParaId = SelfParaId;
type XcmpMessageHandler = XcmpQueue;
}
impl GetChannelInfo for Runtime {
fn get_channel_max(_id: ParaId) -> Option<usize> {
None
}
fn get_channel_status(_id: ParaId) -> cumulus_primitives_core::ChannelStatus {
cumulus_primitives_core::ChannelStatus::Ready(200, 200)
}
}
impl parachain_info::Config for Runtime {}
impl cumulus_pallet_dmp_queue::Config for Runtime {
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
}
impl cumulus_pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
}
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
pub type LocationToAccountId = (
ParentIsPreset<AccountId>,
SiblingParachainConvertsVia<Sibling, AccountId>,
AccountId32Aliases<RelayNetwork, AccountId>,
);
pub type XcmOriginToTransactDispatchOrigin = (
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
ParentAsSuperuser<RuntimeOrigin>,
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
XcmPassthrough<RuntimeOrigin>,
);
parameter_types! {
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
pub const MaxInstructions: u32 = 100;
}
match_types! {
pub type ParentOrParentsPlurality: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here } |
MultiLocation { parents: 1, interior: X1(Plurality { .. }) }
};
pub type ParentOrSiblings: impl Contains<MultiLocation> = {
MultiLocation { parents: 1, interior: Here } |
MultiLocation { parents: 1, interior: X1(_) }
};
}
parameter_types! {
pub AssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000)));
pub const Native: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(MultiLocation::here()) });
pub AssetHubTrustedTeleporter: (MultiAssetFilter, MultiLocation) = (Native::get(), AssetHubLocation::get());
pub RUsdtPerSecond: (xcm::v3::AssetId, u128, u128) = (
MultiLocation::new(1, X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984))).into(),
default_fee_per_second() * 10,
0u128
);
pub RocPerSecond: (xcm::v3::AssetId, u128,u128) = (MultiLocation::new(1,Here).into(), default_fee_per_second() * 70, 0u128);
pub SelfReserve: MultiLocation = MultiLocation { parents:0, interior: Here };
}
pub struct ReserveAssetsFrom<T>(PhantomData<T>);
impl<T: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation> for ReserveAssetsFrom<T> {
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
let prefix = T::get();
log::trace!(target: "xcm::AssetsFrom", "prefix: {:?}, origin: {:?}, asset: {:?}", prefix, origin, asset);
&prefix == origin
}
}
pub struct OnlyTeleportNative;
impl Contains<(MultiLocation, Vec<MultiAsset>)> for OnlyTeleportNative {
fn contains(t: &(MultiLocation, Vec<MultiAsset>)) -> bool {
t.1.iter().any(|asset| {
log::trace!(target: "xcm::OnlyTeleportNative", "Asset to be teleported: {:?}", asset);
if let MultiAsset {
id: xcm::latest::AssetId::Concrete(asset_loc),
fun: Fungible(_a),
} = asset
{
match asset_loc {
MultiLocation {
parents: 0,
interior: Here,
} => true,
_ => false,
}
} else {
false
}
})
}
}
pub type NegativeImbalance<T> = <pallet_balances::Pallet<T> as Currency<
<T as frame_system::Config>::AccountId,
>>::NegativeImbalance;
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
pub struct ToAuthor<R>(PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToAuthor<R>
where
R: pallet_balances::Config + pallet_collator_selection::Config,
AccountIdOf<R>: From<polkadot_core_primitives::v2::AccountId>
+ Into<polkadot_core_primitives::v2::AccountId>,
<R as frame_system::Config>::RuntimeEvent: From<pallet_balances::Event<R>>,
{
fn on_nonzero_unbalanced(amount: NegativeImbalance<R>) {
let author = <pallet_collator_selection::Pallet<R>>::account_id();
<pallet_balances::Pallet<R>>::resolve_creating(&author, amount);
}
}
pub type Traders = (
FixedRateOfFungible<RUsdtPerSecond, ()>,
FixedRateOfFungible<RocPerSecond, ()>,
UsingComponents<WeightToFee, SelfReserve, AccountId, Balances, ToAuthor<Runtime>>,
);
pub type Reserves = (NativeAsset, ReserveAssetsFrom<AssetHubLocation>);
pub type TrustedTeleporters = (xcm_builder::Case<AssetHubTrustedTeleporter>,);
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type Aliasers = Nothing;
type AssetClaims = PolkadotXcm;
type AssetExchanger = ();
type AssetLocker = ();
type AssetTransactor = AssetTransactors;
type AssetTrap = PolkadotXcm;
type Barrier = Barrier;
type CallDispatcher = RuntimeCall;
type FeeManager = ();
type IsReserve = Reserves;
type IsTeleporter = TrustedTeleporters;
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type MessageExporter = ();
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type PalletInstancesInfo = AllPalletsWithSystem;
type ResponseHandler = PolkadotXcm;
type RuntimeCall = RuntimeCall;
type SafeCallFilter = Everything;
type SubscriptionService = PolkadotXcm;
type Trader = Traders;
type UniversalAliases = Nothing;
type UniversalLocation = UniversalLocation;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type XcmSender = XcmRouter;
}
pub type XcmRouter = (
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
XcmpQueue,
);
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
}
impl pallet_xcm::Config for Runtime {
type AdminOrigin = EnsureRoot<crate::AccountId>;
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
type Currency = Balances;
type CurrencyMatcher = ();
type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type MaxLockers = ConstU32<8>;
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
#[cfg(feature = "runtime-benchmarks")]
type ReachableDest = ReachableDest;
type RemoteLockConsumerIdentifier = ();
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, ()>;
type SovereignAccountOf = LocationToAccountId;
type TrustedLockers = ();
type UniversalLocation = UniversalLocation;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type WeightInfo = pallet_xcm::TestWeightInfo;
type XcmExecuteFilter = Nothing;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmReserveTransferFilter = Everything;
type XcmRouter = XcmRouter;
type XcmTeleportFilter = OnlyTeleportNative;
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
}
impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type ControllerOrigin = EnsureRoot<AccountId>;
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type PriceForSiblingDelivery = ();
type RuntimeEvent = RuntimeEvent;
type VersionWrapper = PolkadotXcm;
type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight<Runtime>;
type XcmExecutor = XcmExecutor<XcmConfig>;
}