use super::{
AccountId, AllPalletsWithSystem, Balance, Balances, MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm,
Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, XcmpQueue,
};
use crate::{constants::RuntimeBlockWeights, implementations::ToAuthor, pallets_system::TransactionByteFee};
use cumulus_primitives_core::{
AggregateMessageOrigin, AssetId,
Junction::{PalletInstance, Parachain},
Junctions::{self, Here, X1},
Location, NetworkId, ParaId,
};
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Everything, Nothing, PalletInfoAccess, TransformOrigin},
weights::{IdentityFee, Weight},
};
use frame_system::EnsureRoot;
use pallet_xcm::XcmPassthrough;
use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};
use polkadot_parachain_primitives::primitives::Sibling;
use polkadot_runtime_common::xcm_sender::ExponentialPrice;
use sp_runtime::Perbill;
use sp_std::sync::Arc;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset,
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds,
WithComputedOrigin,
};
use xcm_executor::XcmExecutor;
#[cfg(feature = "runtime-benchmarks")]
use {
crate::{
constants::{EXISTENTIAL_DEPOSIT, NODL},
pallets_system::ExistentialDeposit,
System,
},
cumulus_primitives_core::{Asset, Assets, Fungible, Junction, Parent, ParentThen, Response},
frame_benchmarking::BenchmarkError,
sp_std::{boxed::Box, vec},
};
pub type LocationToAccountId = (
ParentIsPreset<AccountId>,
SiblingParachainConvertsVia<Sibling, AccountId>,
AccountId32Aliases<RelayNetwork, AccountId>,
);
match_types! {
pub type ParentOrSiblings: impl Contains<Location> = {
Location { parents: 1, interior: Here } |
Location { parents: 1, interior: X1(_) }
};
}
pub type Barrier = (
TakeWeightCredit,
AllowKnownQueryResponses<PolkadotXcm>,
WithComputedOrigin<
(
AllowTopLevelPaidExecutionFrom<Everything>,
AllowSubscriptionsFrom<ParentOrSiblings>,
),
UniversalLocation,
ConstU32<8>,
>,
);
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
pub type XcmRouter = (
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, ()>,
XcmpQueue,
);
parameter_types! {
pub RelayLocation: Location = Location::parent();
pub NodlLocation: Location = Location {
parents:0,
interior: Junctions::X1(Arc::new([PalletInstance(<Balances as PalletInfoAccess>::index() as u8)]))
};
pub const RelayNetwork: Option<NetworkId> = None;
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: Junctions = Parachain(ParachainInfo::parachain_id().into()).into();
}
pub type XcmOriginToTransactDispatchOrigin = (
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
XcmPassthrough<RuntimeOrigin>,
);
pub type CurrencyTransactor = FungibleAdapter<
Balances,
IsConcrete<NodlLocation>,
LocationToAccountId,
AccountId,
(),
>;
parameter_types! {
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 8;
}
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter;
type AssetTransactor = CurrencyTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = ();
type UniversalLocation = UniversalLocation;
type Barrier = Barrier;
type Weigher = WeightInfoBounds<crate::weights::NodleXcmWeight<RuntimeCall>, RuntimeCall, MaxInstructions>;
type Trader = UsingComponents<IdentityFee<Balance>, NodlLocation, AccountId, Balances, ToAuthor>;
type ResponseHandler = PolkadotXcm;
type AssetTrap = PolkadotXcm;
type AssetClaims = PolkadotXcm;
type SubscriptionService = PolkadotXcm;
type PalletInstancesInfo = AllPalletsWithSystem;
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = RuntimeCall;
type SafeCallFilter = Everything;
type Aliasers = Nothing;
type TransactionalProcessor = FrameTransactionalProcessor;
type HrmpNewChannelOpenRequestHandler = ();
type HrmpChannelAcceptedHandler = ();
type HrmpChannelClosingHandler = ();
type XcmRecorder = PolkadotXcm;
}
impl pallet_xcm::Config for Runtime {
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 = WeightInfoBounds<crate::weights::NodleXcmWeight<RuntimeCall>, RuntimeCall, MaxInstructions>;
type UniversalLocation = UniversalLocation;
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
type Currency = Balances;
type CurrencyMatcher = ();
type TrustedLockers = ();
type SovereignAccountOf = LocationToAccountId;
type MaxLockers = ConstU32<8>;
type AdminOrigin = EnsureRoot<AccountId>;
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
type MaxRemoteLockConsumers = ConstU32<0>;
type RemoteLockConsumerIdentifier = ();
}
parameter_types! {
pub FeeAssetId: AssetId = AssetId(NodlLocation::get());
pub const BaseDeliveryFee: u128 = crate::constants::POLKADOT_CENT.saturating_mul(3);
}
pub type PriceForSiblingParachainDelivery =
ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, XcmpQueue>;
impl cumulus_pallet_xcmp_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
type MaxActiveOutboundChannels = ConstU32<128>;
type MaxPageSize = ConstU32<{ 103 * 1024 }>;
type ControllerOrigin = EnsureRoot<AccountId>;
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
type WeightInfo = crate::weights::cumulus_pallet_xcmp_queue::WeightInfo<Self>;
type PriceForSiblingDelivery = PriceForSiblingParachainDelivery;
type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
type MaxInboundSuspended = sp_core::ConstU32<1_000>;
}
impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime {
type ChannelList = ParachainSystem;
}
impl cumulus_pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
}
parameter_types! {
pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
}
impl pallet_message_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = crate::weights::pallet_message_queue::WeightInfo<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type MessageProcessor =
pallet_message_queue::mock_helpers::NoopMessageProcessor<cumulus_primitives_core::AggregateMessageOrigin>;
#[cfg(not(feature = "runtime-benchmarks"))]
type MessageProcessor =
xcm_builder::ProcessXcmMessage<AggregateMessageOrigin, xcm_executor::XcmExecutor<XcmConfig>, RuntimeCall>;
type Size = u32;
type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>;
type MaxStale = sp_core::ConstU32<8>;
type ServiceWeight = MessageQueueServiceWeight;
type IdleMaxServiceWeight = ();
}
#[cfg(feature = "runtime-benchmarks")]
pub type PriceForParentDelivery = ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
#[cfg(feature = "runtime-benchmarks")]
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
NodlLocation::get(),
ExistentialDeposit::get()
).into());
pub const RandomParaId: ParaId = ParaId::new(43211234);
}
#[cfg(feature = "runtime-benchmarks")]
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = (
cumulus_primitives_utility::ToParentDeliveryHelper<XcmConfig, ExistentialDepositAsset, ()>,
polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
XcmConfig,
ExistentialDepositAsset,
PriceForSiblingParachainDelivery,
RandomParaId,
ParachainSystem,
>,
);
fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
None
}
fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(RandomParaId::get().into());
Some((
Asset {
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(NodlLocation::get()),
},
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}
fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
let dest = Parent.into();
let fee_amount = EXISTENTIAL_DEPOSIT;
let fee_asset: Asset = (NodlLocation::get(), fee_amount).into();
let who = frame_benchmarking::whitelisted_caller();
let balance = fee_amount + EXISTENTIAL_DEPOSIT * 1000;
let _ = <Balances as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);
assert_eq!(Balances::free_balance(&who), balance);
let asset_amount = 100000u128;
let asset_location = NodlLocation::get();
let transfer_asset: Asset = (asset_location, asset_amount).into();
let assets: Assets = vec![fee_asset.clone(), transfer_asset].into();
let fee_index = 0;
let verify = Box::new(move || {
assert!(Balances::free_balance(&who) <= balance - fee_amount);
});
Some((assets, fee_index as u32, dest, verify))
}
fn get_asset() -> Asset {
Asset {
id: AssetId(NodlLocation::get()),
fun: Fungible(ExistentialDeposit::get()),
}
}
}
#[cfg(feature = "runtime-benchmarks")]
impl frame_system_benchmarking::Config for Runtime {
fn setup_set_code_requirements(code: &sp_std::vec::Vec<u8>) -> Result<(), BenchmarkError> {
ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
Ok(())
}
fn verify_set_code() {
System::assert_last_event(cumulus_pallet_parachain_system::Event::<Runtime>::ValidationFunctionStored.into());
}
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub const TrustedTeleporter: Option<(Location, Asset)> = Some((
Location::parent(),
Asset{ id: AssetId(Location::parent()), fun: Fungible(100) }
));
pub const CheckedAccount: Option<(AccountId, Location)> = None;
pub const TrustedReserve: Option<(Location, Asset)> = None;
}
#[cfg(feature = "runtime-benchmarks")]
impl pallet_xcm_benchmarks::generic::Config for Runtime {
type RuntimeCall = RuntimeCall;
type TransactAsset = Balances;
fn fee_asset() -> Result<Asset, BenchmarkError> {
let assets: Asset = (AssetId(NodlLocation::get()), 1_000_000 * NODL).into();
Ok(assets)
}
fn worst_case_response() -> (u64, Response) {
(0u64, Response::Version(Default::default()))
}
fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> {
Err(BenchmarkError::Skip)
}
fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
Err(BenchmarkError::Skip)
}
fn export_message_origin_and_destination() -> Result<(Location, NetworkId, Junctions), BenchmarkError> {
Err(BenchmarkError::Skip)
}
fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> {
Ok((
Location::parent(),
frame_system::Call::remark_with_event { remark: vec![] }.into(),
))
}
fn subscribe_origin() -> Result<Location, BenchmarkError> {
Ok(Location::parent())
}
fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> {
let origin = Location::parent();
let assets: Assets = (AssetId(NodlLocation::get()), 10_000_000 * NODL).into();
let ticket = Location {
parents: 0,
interior: Here,
};
Ok((origin, ticket, assets))
}
fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> {
Err(BenchmarkError::Skip)
}
fn alias_origin() -> Result<(Location, Location), BenchmarkError> {
Err(BenchmarkError::Skip)
}
}
#[cfg(feature = "runtime-benchmarks")]
impl pallet_xcm_benchmarks::fungible::Config for Runtime {
type TransactAsset = Balances;
type CheckedAccount = ();
type TrustedTeleporter = TrustedTeleporter;
type TrustedReserve = TrustedReserve;
fn get_asset() -> Asset {
Asset {
id: AssetId(NodlLocation::get()),
fun: Fungible(NODL),
}
}
}
#[cfg(feature = "runtime-benchmarks")]
impl pallet_xcm_benchmarks::Config for Runtime {
type XcmConfig = XcmConfig;
type AccountIdConverter = LocationToAccountId;
type DeliveryHelper =
cumulus_primitives_utility::ToParentDeliveryHelper<XcmConfig, ExistentialDepositAsset, PriceForParentDelivery>;
fn valid_destination() -> Result<Location, BenchmarkError> {
Ok(RelayLocation::get())
}
fn worst_case_holding(_depositable_count: u32) -> Assets {
vec![Asset {
id: AssetId(NodlLocation::get()),
fun: Fungible(1_000_000 * NODL),
}]
.into()
}
}