use super::{
AccountId, AllPalletsWithSystem, AssetId, Assets, AstarAssetLocationIdConverter, Balance,
Balances, DealWithFees, MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime,
RuntimeCall, RuntimeEvent, RuntimeOrigin, TreasuryAccountId, XcAssetConfig, XcmWeightToFee,
XcmpQueue,
};
use crate::weights;
use frame_support::{
parameter_types,
traits::{ConstU32, Contains, Everything, Nothing},
weights::Weight,
};
use frame_system::EnsureRoot;
use sp_runtime::traits::{Convert, MaybeEquivalence};
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use frame_support::traits::TransformOrigin;
use parachains_common::message_queue::ParaIdToSibling;
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
use xcm::latest::prelude::*;
use xcm_builder::{
Account32Hash, AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowUnpaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FrameTransactionalProcessor,
FungibleAdapter, FungiblesAdapter, IsConcrete, NoChecking, ParentAsSuperuser, ParentIsPreset,
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
UsingComponents, WeightInfoBounds,
};
use xcm_executor::{
traits::{JustTry, WithOriginFilter},
XcmExecutor,
};
use orml_xcm_support::DisabledParachainFee;
use astar_primitives::xcm::{
AbsoluteAndRelativeReserveProvider, AccountIdToMultiLocation, AllowTopLevelPaidExecutionFrom,
FixedRateOfForeignAsset, ReserveAssetFilter, XcmFungibleFeeHandler,
};
parameter_types! {
pub RelayNetwork: Option<NetworkId> = Some(NetworkId::Polkadot);
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorLocation =
[GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into();
pub AstarLocation: Location = Here.into_location();
pub DummyCheckingAccount: AccountId = PolkadotXcm::check_account();
}
pub type LocationToAccountId = (
ParentIsPreset<AccountId>,
SiblingParachainConvertsVia<polkadot_parachain::primitives::Sibling, AccountId>,
AccountId32Aliases<RelayNetwork, AccountId>,
Account32Hash<RelayNetwork, AccountId>,
);
pub type CurrencyTransactor = FungibleAdapter<
Balances,
IsConcrete<AstarLocation>,
LocationToAccountId,
AccountId,
(),
>;
pub type FungiblesTransactor = FungiblesAdapter<
Assets,
ConvertedConcreteId<AssetId, Balance, AstarAssetLocationIdConverter, JustTry>,
LocationToAccountId,
AccountId,
NoChecking,
DummyCheckingAccount,
>;
pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor);
pub type XcmOriginToTransactDispatchOrigin = (
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
ParentAsSuperuser<RuntimeOrigin>,
pallet_xcm::XcmPassthrough<RuntimeOrigin>,
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
);
parameter_types! {
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 4 * 1024);
pub const MaxInstructions: u32 = 100;
}
pub struct ParentOrParentsPlurality;
impl Contains<Location> for ParentOrParentsPlurality {
fn contains(location: &Location) -> bool {
matches!(location.unpack(), (1, []) | (1, [Plurality { .. }]))
}
}
pub struct SafeCallFilter;
impl SafeCallFilter {
pub fn allow_base_call(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::System(..)
| RuntimeCall::Identity(..)
| RuntimeCall::Balances(..)
| RuntimeCall::Vesting(..)
| RuntimeCall::DappStaking(..)
| RuntimeCall::Assets(..)
| RuntimeCall::PolkadotXcm(..)
| RuntimeCall::Session(..)
| RuntimeCall::Proxy(
pallet_proxy::Call::add_proxy { .. }
| pallet_proxy::Call::remove_proxy { .. }
| pallet_proxy::Call::remove_proxies { .. }
| pallet_proxy::Call::create_pure { .. }
| pallet_proxy::Call::kill_pure { .. }
| pallet_proxy::Call::announce { .. }
| pallet_proxy::Call::remove_announcement { .. }
| pallet_proxy::Call::reject_announcement { .. },
)
| RuntimeCall::Multisig(
pallet_multisig::Call::approve_as_multi { .. }
| pallet_multisig::Call::cancel_as_multi { .. },
) => true,
_ => false,
}
}
pub fn allow_composite_call(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::Proxy(pallet_proxy::Call::proxy { call, .. }) => {
Self::allow_base_call(call)
}
RuntimeCall::Proxy(pallet_proxy::Call::proxy_announced { call, .. }) => {
Self::allow_base_call(call)
}
RuntimeCall::Utility(pallet_utility::Call::batch { calls, .. }) => {
calls.iter().all(|call| Self::allow_base_call(call))
}
RuntimeCall::Utility(pallet_utility::Call::batch_all { calls, .. }) => {
calls.iter().all(|call| Self::allow_base_call(call))
}
RuntimeCall::Utility(pallet_utility::Call::as_derivative { call, .. }) => {
Self::allow_base_call(call)
}
RuntimeCall::Multisig(pallet_multisig::Call::as_multi_threshold_1 { call, .. }) => {
Self::allow_base_call(call)
}
RuntimeCall::Multisig(pallet_multisig::Call::as_multi { call, .. }) => {
Self::allow_base_call(call)
}
_ => false,
}
}
}
impl Contains<RuntimeCall> for SafeCallFilter {
fn contains(call: &RuntimeCall) -> bool {
Self::allow_base_call(call) || Self::allow_composite_call(call)
}
}
pub type XcmBarrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
AllowKnownQueryResponses<PolkadotXcm>,
AllowSubscriptionsFrom<Everything>,
);
pub type AstarXcmFungibleFeeHandler = XcmFungibleFeeHandler<
AccountId,
ConvertedConcreteId<AssetId, Balance, AstarAssetLocationIdConverter, JustTry>,
Assets,
TreasuryAccountId,
>;
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter;
type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = ReserveAssetFilter;
type IsTeleporter = ();
type UniversalLocation = UniversalLocation;
type Barrier = XcmBarrier;
type Weigher = Weigher;
type Trader = (
UsingComponents<XcmWeightToFee, AstarLocation, AccountId, Balances, DealWithFees>,
FixedRateOfForeignAsset<XcAssetConfig, AstarXcmFungibleFeeHandler>,
);
type ResponseHandler = PolkadotXcm;
type AssetTrap = PolkadotXcm;
type AssetClaims = PolkadotXcm;
type SubscriptionService = PolkadotXcm;
type PalletInstancesInfo = AllPalletsWithSystem;
type MaxAssetsIntoHolding = ConstU32<64>;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
type SafeCallFilter = SafeCallFilter;
type Aliasers = Nothing;
type TransactionalProcessor = FrameTransactionalProcessor;
type HrmpNewChannelOpenRequestHandler = ();
type HrmpChannelAcceptedHandler = ();
type HrmpChannelClosingHandler = ();
type XcmRecorder = PolkadotXcm;
}
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
pub type XcmRouter = (
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
XcmpQueue,
);
pub type Weigher =
WeightInfoBounds<weights::xcm::XcmWeight<Runtime, RuntimeCall>, RuntimeCall, MaxInstructions>;
impl pallet_xcm::Config for Runtime {
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
type RuntimeEvent = RuntimeEvent;
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type XcmRouter = XcmRouter;
type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type XcmExecuteFilter = Nothing;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type Weigher = Weigher;
type UniversalLocation = UniversalLocation;
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; type Currency = Balances;
type CurrencyMatcher = ();
type TrustedLockers = ();
type SovereignAccountOf = LocationToAccountId;
type MaxLockers = ConstU32<0>;
type WeightInfo = weights::pallet_xcm::SubstrateWeight<Runtime>;
type MaxRemoteLockConsumers = ConstU32<0>;
type RemoteLockConsumerIdentifier = ();
type AdminOrigin = EnsureRoot<AccountId>;
}
impl cumulus_pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
}
impl cumulus_pallet_xcmp_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
type MaxInboundSuspended = ConstU32<1_000>;
type MaxActiveOutboundChannels = ConstU32<128>;
type MaxPageSize = ConstU32<{ 128 * 1024 }>;
type ControllerOrigin = EnsureRoot<AccountId>;
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
type PriceForSiblingDelivery = NoPriceForMessageDelivery<ParaId>;
type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
pub AstarLocationAbsolute: Location = Location {
parents: 1,
interior: Parachain(ParachainInfo::parachain_id().into()).into()
};
pub const MaxAssetsForTransfer: usize = 2;
}
pub struct AssetIdConvert;
impl Convert<AssetId, Option<Location>> for AssetIdConvert {
fn convert(asset_id: AssetId) -> Option<Location> {
AstarAssetLocationIdConverter::convert_back(&asset_id)
}
}
impl orml_xtokens::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type CurrencyId = AssetId;
type CurrencyIdConvert = AssetIdConvert;
type AccountIdToLocation = AccountIdToMultiLocation;
type SelfLocation = AstarLocation;
type XcmExecutor = XcmExecutor<XcmConfig>;
type Weigher = Weigher;
type BaseXcmWeight = UnitWeightCost;
type UniversalLocation = UniversalLocation;
type MaxAssetsForTransfer = MaxAssetsForTransfer;
type MinXcmFee = DisabledParachainFee;
type LocationsFilter = Everything;
type ReserveProvider = AbsoluteAndRelativeReserveProvider<AstarLocationAbsolute>;
type RateLimiter = ();
type RateLimiterId = ();
}