frequency_runtime/xcm/
weigher.rs

1use frame_support::{parameter_types, BoundedVec};
2use sp_runtime::Vec;
3use staging_xcm::{
4	latest::{prelude::*, AssetTransferFilter},
5	DoubleEncoded,
6};
7use staging_xcm_builder::WeightInfoBounds;
8
9use crate::xcm::MaxAssetsIntoHolding;
10
11use crate::{Runtime, RuntimeCall};
12use common_runtime::weights::{
13	pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight,
14	pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric,
15};
16use frame_support::weights::Weight;
17
18parameter_types! {
19	pub const MaxInstructions: u32 = 20;
20}
21
22const MAX_ASSETS: u64 = 3;
23
24impl WeighAssets for AssetFilter {
25	fn weigh_assets(&self, weight: Weight) -> Weight {
26		match self {
27			Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64),
28			Self::Wild(asset) => match asset {
29				All => weight.saturating_mul(MAX_ASSETS),
30				AllOf { fun, .. } => match fun {
31					WildFungibility::Fungible => weight,
32					// Magic number 2 has to do with the fact that we could have up to 2 times
33					// MaxAssetsIntoHolding in the worst-case scenario.
34					WildFungibility::NonFungible =>
35						weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64),
36				},
37				AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min((*count as u64).max(1))),
38				AllOfCounted { count, .. } =>
39					weight.saturating_mul(MAX_ASSETS.min((*count as u64).max(1))),
40			},
41		}
42	}
43}
44
45trait WeighAssets {
46	fn weigh_assets(&self, weight: Weight) -> Weight;
47}
48
49impl WeighAssets for Assets {
50	fn weigh_assets(&self, weight: Weight) -> Weight {
51		weight.saturating_mul(self.inner().iter().count() as u64)
52	}
53}
54
55pub struct FrequencyXcmWeight<Call>(core::marker::PhantomData<Call>);
56impl<Call> XcmWeightInfo<Call> for FrequencyXcmWeight<Call> {
57	fn withdraw_asset(assets: &Assets) -> Weight {
58		assets.weigh_assets(XcmFungibleWeight::<Runtime>::withdraw_asset())
59	}
60
61	fn reserve_asset_deposited(assets: &Assets) -> Weight {
62		assets.weigh_assets(XcmFungibleWeight::<Runtime>::reserve_asset_deposited())
63	}
64
65	fn receive_teleported_asset(assets: &Assets) -> Weight {
66		assets.weigh_assets(XcmFungibleWeight::<Runtime>::receive_teleported_asset())
67	}
68
69	fn query_response(
70		_query_id: &u64,
71		_response: &Response,
72		_max_weight: &Weight,
73		_querier: &Option<Location>,
74	) -> Weight {
75		XcmGeneric::<Runtime>::query_response()
76	}
77
78	fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight {
79		assets.weigh_assets(XcmFungibleWeight::<Runtime>::transfer_asset())
80	}
81
82	fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
83		assets.weigh_assets(XcmFungibleWeight::<Runtime>::transfer_reserve_asset())
84	}
85
86	fn transact(
87		_origin_type: &OriginKind,
88		_fallback_max_weight: &Option<Weight>,
89		_call: &DoubleEncoded<Call>,
90	) -> Weight {
91		// Frequency does not support transact calls
92		Weight::MAX
93	}
94
95	fn hrmp_new_channel_open_request(
96		_sender: &u32,
97		_max_message_size: &u32,
98		_max_capacity: &u32,
99	) -> Weight {
100		// XCM Executor does not currently support HRMP channel operations
101		Weight::MAX
102	}
103
104	fn hrmp_channel_accepted(_recipient: &u32) -> Weight {
105		// XCM Executor does not currently support HRMP channel operations
106		Weight::MAX
107	}
108
109	fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight {
110		// XCM Executor does not currently support HRMP channel operations
111		Weight::MAX
112	}
113
114	fn clear_origin() -> Weight {
115		XcmGeneric::<Runtime>::clear_origin()
116	}
117
118	fn descend_origin(_who: &InteriorLocation) -> Weight {
119		XcmGeneric::<Runtime>::descend_origin()
120	}
121
122	fn report_error(_query_response_info: &QueryResponseInfo) -> Weight {
123		XcmGeneric::<Runtime>::report_error()
124	}
125
126	fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight {
127		assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_asset())
128	}
129
130	fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
131		assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_reserve_asset())
132	}
133
134	fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight {
135		// Frequency does not support exchange calls
136		Weight::MAX
137	}
138
139	fn initiate_reserve_withdraw(
140		assets: &AssetFilter,
141		_reserve: &Location,
142		_xcm: &Xcm<()>,
143	) -> Weight {
144		assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_reserve_withdraw())
145	}
146
147	fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
148		assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_teleport())
149	}
150
151	fn initiate_transfer(
152		_dest: &Location,
153		remote_fees: &Option<AssetTransferFilter>,
154		_preserve_origin: &bool,
155		assets: &BoundedVec<AssetTransferFilter, MaxAssetTransferFilters>,
156		_xcm: &Xcm<()>,
157	) -> Weight {
158		let base_weight = XcmFungibleWeight::<Runtime>::initiate_transfer();
159		let mut weight = if let Some(remote_fees) = remote_fees {
160			let fees = remote_fees.inner();
161			fees.weigh_assets(base_weight)
162		} else {
163			base_weight
164		};
165		for asset_filter in assets {
166			let assets = asset_filter.inner();
167			let extra = assets.weigh_assets(XcmFungibleWeight::<Runtime>::initiate_transfer());
168			weight = weight.saturating_add(extra);
169		}
170		weight
171	}
172
173	fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight {
174		XcmGeneric::<Runtime>::report_holding()
175	}
176
177	fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight {
178		XcmGeneric::<Runtime>::buy_execution()
179	}
180
181	fn pay_fees(_asset: &Asset) -> Weight {
182		XcmGeneric::<Runtime>::pay_fees()
183	}
184
185	fn refund_surplus() -> Weight {
186		XcmGeneric::<Runtime>::refund_surplus()
187	}
188
189	fn set_error_handler(_xcm: &Xcm<Call>) -> Weight {
190		XcmGeneric::<Runtime>::set_error_handler()
191	}
192
193	fn set_appendix(_xcm: &Xcm<Call>) -> Weight {
194		XcmGeneric::<Runtime>::set_appendix()
195	}
196
197	fn clear_error() -> Weight {
198		XcmGeneric::<Runtime>::clear_error()
199	}
200
201	fn set_hints(hints: &BoundedVec<Hint, HintNumVariants>) -> Weight {
202		let mut weight = Weight::zero();
203		for hint in hints {
204			match hint {
205				AssetClaimer { .. } => {
206					weight = weight.saturating_add(XcmGeneric::<Runtime>::asset_claimer());
207				},
208			}
209		}
210		weight
211	}
212
213	fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight {
214		XcmGeneric::<Runtime>::claim_asset()
215	}
216
217	fn trap(_code: &u64) -> Weight {
218		XcmGeneric::<Runtime>::trap()
219	}
220
221	fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> Weight {
222		XcmGeneric::<Runtime>::subscribe_version()
223	}
224
225	fn unsubscribe_version() -> Weight {
226		XcmGeneric::<Runtime>::unsubscribe_version()
227	}
228
229	fn burn_asset(assets: &Assets) -> Weight {
230		assets.weigh_assets(XcmGeneric::<Runtime>::burn_asset())
231	}
232
233	fn expect_asset(assets: &Assets) -> Weight {
234		assets.weigh_assets(XcmGeneric::<Runtime>::expect_asset())
235	}
236
237	fn expect_origin(_origin: &Option<Location>) -> Weight {
238		XcmGeneric::<Runtime>::expect_origin()
239	}
240
241	fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight {
242		XcmGeneric::<Runtime>::expect_error()
243	}
244
245	fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight {
246		XcmGeneric::<Runtime>::expect_transact_status()
247	}
248
249	fn query_pallet(_module_name: &Vec<u8>, _response_info: &QueryResponseInfo) -> Weight {
250		XcmGeneric::<Runtime>::query_pallet()
251	}
252
253	fn expect_pallet(
254		_index: &u32,
255		_name: &Vec<u8>,
256		_module_name: &Vec<u8>,
257		_crate_major: &u32,
258		_min_crate_minor: &u32,
259	) -> Weight {
260		XcmGeneric::<Runtime>::expect_pallet()
261	}
262
263	fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight {
264		XcmGeneric::<Runtime>::report_transact_status()
265	}
266
267	fn clear_transact_status() -> Weight {
268		XcmGeneric::<Runtime>::clear_transact_status()
269	}
270
271	fn universal_origin(_: &Junction) -> Weight {
272		// Frequency does not support universal_origin calls
273		Weight::MAX
274	}
275
276	fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight {
277		Weight::MAX
278	}
279
280	fn lock_asset(_: &Asset, _: &Location) -> Weight {
281		// Frequency does not support lock_asset calls
282		Weight::MAX
283	}
284
285	fn unlock_asset(_: &Asset, _: &Location) -> Weight {
286		// Frequency does not support unlock_asset calls
287		Weight::MAX
288	}
289
290	fn note_unlockable(_: &Asset, _: &Location) -> Weight {
291		// Frequency does not support note_unlockable calls
292		Weight::MAX
293	}
294
295	fn request_unlock(_: &Asset, _: &Location) -> Weight {
296		// Frequency does not support request_unlock calls
297		Weight::MAX
298	}
299
300	fn set_fees_mode(_: &bool) -> Weight {
301		XcmGeneric::<Runtime>::set_fees_mode()
302	}
303
304	fn set_topic(_topic: &[u8; 32]) -> Weight {
305		XcmGeneric::<Runtime>::set_topic()
306	}
307
308	fn clear_topic() -> Weight {
309		XcmGeneric::<Runtime>::clear_topic()
310	}
311
312	fn alias_origin(_: &Location) -> Weight {
313		// Frequency does not support alias_origin calls
314		Weight::MAX
315	}
316
317	fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
318		XcmGeneric::<Runtime>::unpaid_execution()
319	}
320
321	fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
322		// Frequency does not support execute_with_origin calls
323		Weight::MAX
324	}
325}
326
327/// The XCM weigher used to estimate total weight for execution
328pub type Weigher = WeightInfoBounds<FrequencyXcmWeight<RuntimeCall>, RuntimeCall, MaxInstructions>;