referrerpolicy=no-referrer-when-downgrade

cumulus_pallet_xcmp_queue/
weights_ext.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Weight-related utilities.

use crate::weights::WeightInfo;

use frame_support::weights::Weight;
use sp_runtime::SaturatedConversion;

/// Extended weight info.
pub trait WeightInfoExt: WeightInfo {
	fn uncached_enqueue_xcmp_messages() -> Weight {
		Self::enqueue_n_full_pages(0)
	}

	fn enqueue_xcmp_messages(
		new_pages_count: u32,
		message_count: usize,
		size_in_bytes: usize,
	) -> Weight {
		let message_count = message_count.saturated_into();
		let size_in_bytes = size_in_bytes.saturated_into();

		// The cost of adding `n` empty pages on the message queue.
		let pages_overhead = {
			let full_message_overhead = Self::enqueue_n_full_pages(1)
				.saturating_sub(Self::enqueue_n_empty_xcmp_messages(1));
			let n_full_messages_overhead =
				full_message_overhead.saturating_mul(new_pages_count as u64);

			Self::enqueue_n_full_pages(new_pages_count)
				.saturating_sub(Self::enqueue_n_full_pages(0))
				.saturating_sub(n_full_messages_overhead)
		};

		// The overhead of enqueueing `n` empty messages on the message queue.
		let messages_overhead = {
			Self::enqueue_n_empty_xcmp_messages(message_count)
				.saturating_sub(Self::enqueue_n_empty_xcmp_messages(0))
		};

		// The overhead of enqueueing `n` bytes on the message queue.
		let bytes_overhead = {
			Self::enqueue_n_bytes_xcmp_message(size_in_bytes)
				.saturating_sub(Self::enqueue_n_bytes_xcmp_message(0))
		};

		pages_overhead.saturating_add(messages_overhead).saturating_add(bytes_overhead)
	}
}

impl<T: WeightInfo> WeightInfoExt for T {}

#[cfg(feature = "std")]
pub fn check_weight_info_ext_accuracy<T: WeightInfoExt>(err_margin: u8) {
	assert!(err_margin < 100);
	let err_margin = err_margin as u64;

	let estimated_weight =
		T::uncached_enqueue_xcmp_messages().saturating_add(T::enqueue_xcmp_messages(1, 1000, 3000));
	let actual_weight = T::enqueue_1000_small_xcmp_messages();

	// Check that the ref_time diff is less than {err_margin}%
	let diff_ref_time = estimated_weight.ref_time().abs_diff(actual_weight.ref_time());
	assert!(diff_ref_time < estimated_weight.ref_time() * err_margin / 100);
	assert!(diff_ref_time < actual_weight.ref_time() * err_margin / 100);

	// The proof sizes should be the same
	assert_eq!(estimated_weight.proof_size(), actual_weight.proof_size());
}

#[cfg(test)]
mod tests {
	use super::*;

	#[test]
	fn weight_info_ext_accuracy_is_high() {
		check_weight_info_ext_accuracy::<()>(5);
	}
}