referrerpolicy=no-referrer-when-downgrade

asset_hub_westend_runtime/weights/xcm/
mod.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16mod pallet_xcm_benchmarks_fungible;
17mod pallet_xcm_benchmarks_generic;
18
19use crate::{
20	xcm_config::{ERC20TransferGasLimit, MaxAssetsIntoHolding},
21	Runtime,
22};
23use alloc::vec::Vec;
24use assets_common::IsLocalAccountKey20;
25use frame_support::{traits::Contains, weights::Weight};
26use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight;
27use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric;
28use sp_runtime::BoundedVec;
29use xcm::{
30	latest::{prelude::*, AssetTransferFilter},
31	DoubleEncoded,
32};
33
34trait WeighAssets {
35	fn weigh_assets(&self, weight: Weight) -> Weight;
36}
37
38const MAX_ASSETS: u64 = 100;
39
40impl WeighAssets for AssetFilter {
41	fn weigh_assets(&self, weight: Weight) -> Weight {
42		match self {
43			Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64),
44			Self::Wild(asset) => match asset {
45				All => weight.saturating_mul(MAX_ASSETS),
46				AllOf { fun, .. } => match fun {
47					WildFungibility::Fungible => weight,
48					// Magic number 2 has to do with the fact that we could have up to 2 times
49					// MaxAssetsIntoHolding in the worst-case scenario.
50					WildFungibility::NonFungible =>
51						weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64),
52				},
53				AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min((*count as u64).max(1))),
54				AllOfCounted { count, .. } =>
55					weight.saturating_mul(MAX_ASSETS.min((*count as u64).max(1))),
56			},
57		}
58	}
59}
60
61trait WeighAsset {
62	/// Return one worst-case estimate: `weight`, or another.
63	fn weigh_asset(&self, weight: Weight) -> Weight;
64}
65
66impl WeighAsset for Asset {
67	fn weigh_asset(&self, weight: Weight) -> Weight {
68		// If the asset is a smart contract ERC20, then we know the gas limit,
69		// else we return the weight that was passed in, that's already
70		// the worst case for non-ERC20 assets.
71		if IsLocalAccountKey20::contains(&self.id.0) {
72			ERC20TransferGasLimit::get()
73		} else {
74			weight
75		}
76	}
77}
78
79impl WeighAssets for Assets {
80	fn weigh_assets(&self, weight: Weight) -> Weight {
81		// We start with zero.
82		let mut final_weight = Weight::zero();
83		// For each asset, we add weight depending on the type of asset.
84		for asset in self.inner().iter() {
85			final_weight = final_weight.saturating_add(asset.weigh_asset(weight));
86		}
87		final_weight
88	}
89}
90
91pub struct AssetHubWestendXcmWeight<Call>(core::marker::PhantomData<Call>);
92impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
93	fn withdraw_asset(assets: &Assets) -> Weight {
94		assets.weigh_assets(XcmFungibleWeight::<Runtime>::withdraw_asset())
95	}
96	fn reserve_asset_deposited(assets: &Assets) -> Weight {
97		assets.weigh_assets(XcmFungibleWeight::<Runtime>::reserve_asset_deposited())
98	}
99	fn receive_teleported_asset(assets: &Assets) -> Weight {
100		assets.weigh_assets(XcmFungibleWeight::<Runtime>::receive_teleported_asset())
101	}
102	fn query_response(
103		_query_id: &u64,
104		_response: &Response,
105		_max_weight: &Weight,
106		_querier: &Option<Location>,
107	) -> Weight {
108		XcmGeneric::<Runtime>::query_response()
109	}
110	fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight {
111		assets.weigh_assets(XcmFungibleWeight::<Runtime>::transfer_asset())
112	}
113	fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
114		assets.weigh_assets(XcmFungibleWeight::<Runtime>::transfer_reserve_asset())
115	}
116	fn transact(
117		_origin_type: &OriginKind,
118		_fallback_max_weight: &Option<Weight>,
119		_call: &DoubleEncoded<Call>,
120	) -> Weight {
121		XcmGeneric::<Runtime>::transact()
122	}
123	fn hrmp_new_channel_open_request(
124		_sender: &u32,
125		_max_message_size: &u32,
126		_max_capacity: &u32,
127	) -> Weight {
128		// XCM Executor does not currently support HRMP channel operations
129		Weight::MAX
130	}
131	fn hrmp_channel_accepted(_recipient: &u32) -> Weight {
132		// XCM Executor does not currently support HRMP channel operations
133		Weight::MAX
134	}
135	fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight {
136		// XCM Executor does not currently support HRMP channel operations
137		Weight::MAX
138	}
139	fn clear_origin() -> Weight {
140		XcmGeneric::<Runtime>::clear_origin()
141	}
142	fn descend_origin(_who: &InteriorLocation) -> Weight {
143		XcmGeneric::<Runtime>::descend_origin()
144	}
145	fn report_error(_query_response_info: &QueryResponseInfo) -> Weight {
146		XcmGeneric::<Runtime>::report_error()
147	}
148
149	fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight {
150		assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_asset())
151	}
152	fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
153		assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_reserve_asset())
154	}
155	fn exchange_asset(give: &AssetFilter, receive: &Assets, _maximal: &bool) -> Weight {
156		let base_weight = XcmGeneric::<Runtime>::exchange_asset();
157		let give_weight = give.weigh_assets(base_weight);
158		let receive_weight = receive.weigh_assets(base_weight);
159		give_weight.max(receive_weight)
160	}
161	fn initiate_reserve_withdraw(
162		assets: &AssetFilter,
163		_reserve: &Location,
164		_xcm: &Xcm<()>,
165	) -> Weight {
166		assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_reserve_withdraw())
167	}
168	fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
169		assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_teleport())
170	}
171	fn initiate_transfer(
172		_dest: &Location,
173		remote_fees: &Option<AssetTransferFilter>,
174		_preserve_origin: &bool,
175		assets: &BoundedVec<AssetTransferFilter, MaxAssetTransferFilters>,
176		_xcm: &Xcm<()>,
177	) -> Weight {
178		let base_weight = XcmFungibleWeight::<Runtime>::initiate_transfer();
179		let mut weight = if let Some(remote_fees) = remote_fees {
180			let fees = remote_fees.inner();
181			fees.weigh_assets(base_weight)
182		} else {
183			base_weight
184		};
185		for asset_filter in assets {
186			let assets = asset_filter.inner();
187			let extra = assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_transfer());
188			weight = weight.saturating_add(extra);
189		}
190		weight
191	}
192	fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight {
193		XcmGeneric::<Runtime>::report_holding()
194	}
195	fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight {
196		XcmGeneric::<Runtime>::buy_execution()
197	}
198	fn pay_fees(_asset: &Asset) -> Weight {
199		XcmGeneric::<Runtime>::pay_fees()
200	}
201	fn refund_surplus() -> Weight {
202		XcmGeneric::<Runtime>::refund_surplus()
203	}
204	fn set_error_handler(_xcm: &Xcm<Call>) -> Weight {
205		XcmGeneric::<Runtime>::set_error_handler()
206	}
207	fn set_appendix(_xcm: &Xcm<Call>) -> Weight {
208		XcmGeneric::<Runtime>::set_appendix()
209	}
210	fn clear_error() -> Weight {
211		XcmGeneric::<Runtime>::clear_error()
212	}
213	fn set_hints(hints: &BoundedVec<Hint, HintNumVariants>) -> Weight {
214		let mut weight = Weight::zero();
215		for hint in hints {
216			match hint {
217				AssetClaimer { .. } => {
218					weight = weight.saturating_add(XcmGeneric::<Runtime>::asset_claimer());
219				},
220			}
221		}
222		weight
223	}
224	fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight {
225		XcmGeneric::<Runtime>::claim_asset()
226	}
227	fn trap(_code: &u64) -> Weight {
228		XcmGeneric::<Runtime>::trap()
229	}
230	fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight {
231		XcmGeneric::<Runtime>::subscribe_version()
232	}
233	fn unsubscribe_version() -> Weight {
234		XcmGeneric::<Runtime>::unsubscribe_version()
235	}
236	fn burn_asset(assets: &Assets) -> Weight {
237		assets.weigh_assets(XcmGeneric::<Runtime>::burn_asset())
238	}
239	fn expect_asset(assets: &Assets) -> Weight {
240		assets.weigh_assets(XcmGeneric::<Runtime>::expect_asset())
241	}
242	fn expect_origin(_origin: &Option<Location>) -> Weight {
243		XcmGeneric::<Runtime>::expect_origin()
244	}
245	fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
246		XcmGeneric::<Runtime>::expect_error()
247	}
248	fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
249		XcmGeneric::<Runtime>::expect_transact_status()
250	}
251	fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
252		XcmGeneric::<Runtime>::query_pallet()
253	}
254	fn expect_pallet(
255		_index: &u32,
256		_name: &Vec<u8>,
257		_module_name: &Vec<u8>,
258		_crate_major: &u32,
259		_min_crate_minor: &u32,
260	) -> Weight {
261		XcmGeneric::<Runtime>::expect_pallet()
262	}
263	fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight {
264		XcmGeneric::<Runtime>::report_transact_status()
265	}
266	fn clear_transact_status() -> Weight {
267		XcmGeneric::<Runtime>::clear_transact_status()
268	}
269	fn universal_origin(_: &Junction) -> Weight {
270		XcmGeneric::<Runtime>::universal_origin()
271	}
272	fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight {
273		Weight::MAX
274	}
275	fn lock_asset(_: &Asset, _: &Location) -> Weight {
276		Weight::MAX
277	}
278	fn unlock_asset(_: &Asset, _: &Location) -> Weight {
279		Weight::MAX
280	}
281	fn note_unlockable(_: &Asset, _: &Location) -> Weight {
282		Weight::MAX
283	}
284	fn request_unlock(_: &Asset, _: &Location) -> Weight {
285		Weight::MAX
286	}
287	fn set_fees_mode(_: &bool) -> Weight {
288		XcmGeneric::<Runtime>::set_fees_mode()
289	}
290	fn set_topic(_topic: &[u8; 32]) -> Weight {
291		XcmGeneric::<Runtime>::set_topic()
292	}
293	fn clear_topic() -> Weight {
294		XcmGeneric::<Runtime>::clear_topic()
295	}
296	fn alias_origin(_: &Location) -> Weight {
297		XcmGeneric::<Runtime>::alias_origin()
298	}
299	fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
300		XcmGeneric::<Runtime>::unpaid_execution()
301	}
302	fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
303		XcmGeneric::<Runtime>::execute_with_origin()
304	}
305}