referrerpolicy=no-referrer-when-downgrade

cumulus_pallet_xcmp_queue/
weights_ext.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
16//! Weight-related utilities.
17
18use crate::weights::WeightInfo;
19
20use frame_support::{traits::BatchFootprint, weights::Weight};
21use sp_runtime::SaturatedConversion;
22
23pub(crate) fn get_average_page_pos(max_message_len: u32) -> u32 {
24	max_message_len / 2
25}
26
27/// Extended weight info.
28pub trait WeightInfoExt: WeightInfo {
29	fn uncached_enqueue_xcmp_messages() -> Weight {
30		Self::enqueue_n_full_pages(0)
31	}
32
33	fn enqueue_xcmp_messages(
34		first_page_pos: u32,
35		batch_footprint: &BatchFootprint,
36		is_first_sender_batch: bool,
37	) -> Weight {
38		let message_count = batch_footprint.msgs_count.saturated_into();
39		let size_in_bytes = batch_footprint.size_in_bytes.saturated_into();
40
41		// The cost of adding `n` empty pages on the message queue.
42		let pages_overhead = {
43			let full_message_overhead = Self::enqueue_n_full_pages(1)
44				.saturating_sub(Self::enqueue_n_empty_xcmp_messages(1));
45			let n_full_messages_overhead =
46				full_message_overhead.saturating_mul(batch_footprint.new_pages_count as u64);
47
48			Self::enqueue_n_full_pages(batch_footprint.new_pages_count)
49				.saturating_sub(Self::enqueue_n_full_pages(0))
50				.saturating_sub(n_full_messages_overhead)
51		};
52
53		// The overhead of enqueueing `n` empty messages on the message queue.
54		let messages_overhead = {
55			Self::enqueue_n_empty_xcmp_messages(message_count)
56				.saturating_sub(Self::enqueue_n_empty_xcmp_messages(0))
57		};
58
59		// The overhead of enqueueing `n` bytes on the message queue.
60		let bytes_overhead = {
61			Self::enqueue_n_bytes_xcmp_message(size_in_bytes)
62				.saturating_sub(Self::enqueue_n_bytes_xcmp_message(0))
63		};
64
65		// If the messages are not added to the beginning of the first page, the page will be
66		// decoded and re-encoded once. Let's account for this.
67		let pos_overhead = {
68			let mut pos_overhead = Self::enqueue_empty_xcmp_message_at(first_page_pos)
69				.saturating_sub(Self::enqueue_empty_xcmp_message_at(0));
70			// We need to account for the PoV size of the first page in the message queue only the
71			// first time when we access it.
72			if !is_first_sender_batch {
73				pos_overhead = pos_overhead.set_proof_size(0);
74			}
75			pos_overhead
76		};
77
78		pages_overhead
79			.saturating_add(messages_overhead)
80			.saturating_add(bytes_overhead)
81			.saturating_add(pos_overhead)
82	}
83
84	fn check_accuracy<MaxMessageLen: bounded_collections::Get<u32>>(err_margin: f64) {
85		assert!(err_margin < 1f64);
86
87		let estimated_weight =
88			Self::uncached_enqueue_xcmp_messages().saturating_add(Self::enqueue_xcmp_messages(
89				get_average_page_pos(MaxMessageLen::get()),
90				&BatchFootprint { msgs_count: 1000, size_in_bytes: 3000, new_pages_count: 0 },
91				true,
92			));
93		let actual_weight = Self::enqueue_1000_small_xcmp_messages();
94
95		// Check that the ref_time diff is less than err_margin
96		approx::assert_relative_eq!(
97			estimated_weight.ref_time() as f64,
98			actual_weight.ref_time() as f64,
99			max_relative = err_margin
100		);
101	}
102}
103
104impl<T: WeightInfo> WeightInfoExt for T {}