// Copyright 2017-2023 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Polkadot is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . mod pallet_xcm_benchmarks_fungible; mod pallet_xcm_benchmarks_generic; use crate::Runtime; use frame_support::weights::Weight; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; /// Types of asset supported by the Rococo runtime. pub enum AssetTypes { /// An asset backed by `pallet-balances`. Balances, /// Unknown asset. Unknown, } impl From<&MultiAsset> for AssetTypes { fn from(asset: &MultiAsset) -> Self { match asset { MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } trait WeighMultiAssets { fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; } // Rococo only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() .into_iter() .map(From::from) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, }) .fold(Weight::zero(), |acc, x| acc.saturating_add(x)), // We don't support any NFTs on Rococo, so these two variants will always match // only 1 kind of fungible asset. Self::Wild(AllOf { .. } | AllOfCounted { .. }) => balances_weight, Self::Wild(AllCounted(count)) => balances_weight.saturating_mul(MAX_ASSETS.min(*count as u64)), Self::Wild(All) => balances_weight.saturating_mul(MAX_ASSETS), } } } impl WeighMultiAssets for MultiAssets { fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, }) .fold(Weight::zero(), |acc, x| acc.saturating_add(x)) } } pub struct RococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for RococoXcmWeight { fn withdraw_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) } fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) } fn receive_teleported_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) } fn transfer_reserve_asset( assets: &MultiAssets, _dest: &MultiLocation, _xcm: &Xcm<()>, ) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, _require_weight_at_most: &Weight, _call: &DoubleEncoded, ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( _sender: &u32, _max_message_size: &u32, _max_capacity: &u32, ) -> Weight { // XCM Executor does not currently support HRMP channel operations Weight::MAX } fn hrmp_channel_accepted(_recipient: &u32) -> Weight { // XCM Executor does not currently support HRMP channel operations Weight::MAX } fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { // XCM Executor does not currently support HRMP channel operations Weight::MAX } fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } fn descend_origin(_who: &InteriorMultiLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) } fn deposit_reserve_asset( assets: &MultiAssetFilter, _dest: &MultiLocation, _xcm: &Xcm<()>, ) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) } fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { // Rococo does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( assets: &MultiAssetFilter, _reserve: &MultiLocation, _xcm: &Xcm<()>, ) -> Weight { assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) } fn initiate_teleport( assets: &MultiAssetFilter, _dest: &MultiLocation, _xcm: &Xcm<()>, ) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) } fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { XcmGeneric::::report_holding() } fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { XcmGeneric::::refund_surplus() } fn set_error_handler(_xcm: &Xcm) -> Weight { XcmGeneric::::set_error_handler() } fn set_appendix(_xcm: &Xcm) -> Weight { XcmGeneric::::set_appendix() } fn clear_error() -> Weight { XcmGeneric::::clear_error() } fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { XcmGeneric::::trap() } fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight { XcmGeneric::::subscribe_version() } fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } fn burn_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmGeneric::::burn_asset()) } fn expect_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmGeneric::::expect_asset()) } fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { XcmGeneric::::expect_error() } fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { XcmGeneric::::expect_transact_status() } fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::query_pallet() } fn expect_pallet( _index: &u32, _name: &Vec, _module_name: &Vec, _crate_major: &u32, _min_crate_minor: &u32, ) -> Weight { XcmGeneric::::expect_pallet() } fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_transact_status() } fn clear_transact_status() -> Weight { XcmGeneric::::clear_transact_status() } fn universal_origin(_: &Junction) -> Weight { // Rococo does not currently support universal origin operations Weight::MAX } fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX // todo fix } fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { XcmGeneric::::set_fees_mode() } fn set_topic(_topic: &[u8; 32]) -> Weight { XcmGeneric::::set_topic() } fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } fn alias_origin(_: &MultiLocation) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); }