Refactoring Checkpoint: (WIP)
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
// 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.
|
||||
|
||||
//! Benchmarking setup for pezcumulus-pezpallet-xcmp-queue
|
||||
|
||||
use crate::{weights_ext::get_average_page_pos, *};
|
||||
|
||||
use alloc::vec;
|
||||
use codec::DecodeAll;
|
||||
use pezframe_benchmarking::v2::*;
|
||||
use pezframe_support::{assert_ok, traits::Hooks};
|
||||
use pezframe_system::RawOrigin;
|
||||
use xcm::MAX_INSTRUCTIONS_TO_DECODE;
|
||||
|
||||
#[benchmarks]
|
||||
mod benchmarks {
|
||||
use super::*;
|
||||
|
||||
/// Modify any of the `QueueConfig` fields with a new `u32` value.
|
||||
///
|
||||
/// Used as weight for:
|
||||
/// - update_suspend_threshold
|
||||
/// - update_drop_threshold
|
||||
/// - update_resume_threshold
|
||||
#[benchmark]
|
||||
fn set_config_with_u32() {
|
||||
#[extrinsic_call]
|
||||
Pallet::<T>::update_resume_threshold(RawOrigin::Root, 1);
|
||||
}
|
||||
|
||||
/// Add a XCMP message of `n` bytes to the message queue.
|
||||
///
|
||||
/// The message will be added on a new page and also, the `BookState` will be added
|
||||
/// to the ready ring.
|
||||
#[benchmark]
|
||||
fn enqueue_n_bytes_xcmp_message(n: Linear<0, { MaxXcmpMessageLenOf::<T>::get() }>) {
|
||||
#[cfg(test)]
|
||||
{
|
||||
mock::EnqueuedMessages::set(vec![]);
|
||||
}
|
||||
|
||||
let msg = BoundedVec::try_from(vec![0; n as usize]).unwrap();
|
||||
|
||||
#[cfg(not(test))]
|
||||
let fp_before = T::XcmpQueue::footprint(0.into());
|
||||
#[block]
|
||||
{
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&[msg.as_bounded_slice()],
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let fp_after = T::XcmpQueue::footprint(0.into());
|
||||
assert_eq!(fp_after.ready_pages, fp_before.ready_pages + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add `n` XCMP message of 0 bytes to the message queue.
|
||||
///
|
||||
/// Only for the first message a new page will be created and the `BookState` will be added
|
||||
/// to the ready ring.
|
||||
#[benchmark]
|
||||
fn enqueue_n_empty_xcmp_messages(n: Linear<0, 1000>) {
|
||||
#[cfg(test)]
|
||||
{
|
||||
mock::EnqueuedMessages::set(vec![]);
|
||||
<QueueConfig<T>>::set(QueueConfigData {
|
||||
suspend_threshold: 1100,
|
||||
drop_threshold: 1100,
|
||||
resume_threshold: 1100,
|
||||
});
|
||||
}
|
||||
|
||||
let msg = BoundedVec::new();
|
||||
let msgs = vec![msg.as_bounded_slice(); n as usize];
|
||||
|
||||
#[cfg(not(test))]
|
||||
let fp_before = T::XcmpQueue::footprint(0.into());
|
||||
#[block]
|
||||
{
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&msgs,
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let fp_after = T::XcmpQueue::footprint(0.into());
|
||||
if !msgs.is_empty() {
|
||||
assert_eq!(fp_after.ready_pages, fp_before.ready_pages + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add an XCMP message of 0 bytes to the message queue at the provided position
|
||||
/// on an existing page.
|
||||
#[benchmark(pov_mode = Measured)]
|
||||
fn enqueue_empty_xcmp_message_at(
|
||||
n: Linear<0, { crate::MaxXcmpMessageLenOf::<T>::get() - 10 }>,
|
||||
) {
|
||||
#[cfg(test)]
|
||||
{
|
||||
mock::EnqueuedMessages::set(vec![]);
|
||||
}
|
||||
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&[BoundedVec::try_from(vec![0; n as usize]).unwrap().as_bounded_slice()],
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
|
||||
#[cfg(not(test))]
|
||||
let fp_before = T::XcmpQueue::footprint(0.into());
|
||||
#[block]
|
||||
{
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&[BoundedVec::new().as_bounded_slice()],
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let fp_after = T::XcmpQueue::footprint(0.into());
|
||||
assert_eq!(fp_after.ready_pages, fp_before.ready_pages);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add `n` pages to the message queue.
|
||||
///
|
||||
/// We add one page by enqueueing a maximal size message which fills it.
|
||||
#[benchmark]
|
||||
fn enqueue_n_full_pages(n: Linear<0, 100>) {
|
||||
#[cfg(test)]
|
||||
{
|
||||
mock::EnqueuedMessages::set(vec![]);
|
||||
}
|
||||
<QueueConfig<T>>::set(QueueConfigData {
|
||||
suspend_threshold: 200,
|
||||
drop_threshold: 200,
|
||||
resume_threshold: 200,
|
||||
});
|
||||
|
||||
let max_msg_len = MaxXcmpMessageLenOf::<T>::get() as usize;
|
||||
let mut msgs = vec![];
|
||||
for _i in 0..n {
|
||||
let msg = BoundedVec::try_from(vec![0; max_msg_len]).unwrap();
|
||||
msgs.push(msg);
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
let fp_before = T::XcmpQueue::footprint(0.into());
|
||||
#[block]
|
||||
{
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&msgs.iter().map(|msg| msg.as_bounded_slice()).collect::<Vec<_>>(),
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let fp_after = T::XcmpQueue::footprint(0.into());
|
||||
assert_eq!(fp_after.ready_pages, fp_before.ready_pages + n);
|
||||
}
|
||||
}
|
||||
|
||||
#[benchmark(pov_mode = Measured)]
|
||||
fn enqueue_1000_small_xcmp_messages() {
|
||||
#[cfg(test)]
|
||||
{
|
||||
<QueueConfig<T>>::set(QueueConfigData {
|
||||
suspend_threshold: 1100,
|
||||
drop_threshold: 1100,
|
||||
resume_threshold: 1100,
|
||||
});
|
||||
}
|
||||
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&[BoundedVec::try_from(vec![
|
||||
0;
|
||||
get_average_page_pos(MaxXcmpMessageLenOf::<T>::get())
|
||||
as usize
|
||||
])
|
||||
.unwrap()
|
||||
.as_bounded_slice()],
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
|
||||
let mut msgs = vec![];
|
||||
for _i in 0..1000 {
|
||||
msgs.push(BoundedVec::try_from(vec![0; 3]).unwrap());
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
let fp_before = T::XcmpQueue::footprint(0.into());
|
||||
#[block]
|
||||
{
|
||||
assert_ok!(Pallet::<T>::enqueue_xcmp_messages(
|
||||
0.into(),
|
||||
&msgs.iter().map(|msg| msg.as_bounded_slice()).collect::<Vec<_>>(),
|
||||
true,
|
||||
&mut WeightMeter::new()
|
||||
));
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
{
|
||||
let fp_after = T::XcmpQueue::footprint(0.into());
|
||||
assert_eq!(fp_after.ready_pages, fp_before.ready_pages);
|
||||
}
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn suspend_channel() {
|
||||
let para = 123.into();
|
||||
let data = ChannelSignal::Suspend.encode();
|
||||
|
||||
#[block]
|
||||
{
|
||||
ChannelSignal::decode_all(&mut &data[..]).unwrap();
|
||||
Pallet::<T>::suspend_channel(para);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
OutboundXcmpStatus::<T>::get()
|
||||
.iter()
|
||||
.find(|p| p.recipient == para)
|
||||
.unwrap()
|
||||
.state,
|
||||
OutboundState::Suspended
|
||||
);
|
||||
}
|
||||
|
||||
#[benchmark]
|
||||
fn resume_channel() {
|
||||
let para = 123.into();
|
||||
let data = ChannelSignal::Resume.encode();
|
||||
|
||||
Pallet::<T>::suspend_channel(para);
|
||||
|
||||
#[block]
|
||||
{
|
||||
ChannelSignal::decode_all(&mut &data[..]).unwrap();
|
||||
Pallet::<T>::resume_channel(para);
|
||||
}
|
||||
|
||||
assert!(
|
||||
OutboundXcmpStatus::<T>::get().iter().all(|p| p.recipient != para),
|
||||
"No messages in the channel; therefore removed."
|
||||
);
|
||||
}
|
||||
|
||||
/// Split a singular XCM.
|
||||
#[benchmark]
|
||||
fn take_first_concatenated_xcm(
|
||||
n: Linear<0, { MAX_INSTRUCTIONS_TO_DECODE as u32 - MAX_XCM_DECODE_DEPTH }>,
|
||||
) {
|
||||
let mut xcm = Xcm::<T>(vec![ClearOrigin; n as usize]);
|
||||
for _ in 0..MAX_XCM_DECODE_DEPTH - 1 {
|
||||
xcm = Xcm::<T>(vec![Instruction::SetAppendix(xcm)]);
|
||||
}
|
||||
let data = VersionedXcm::<T>::from(xcm).encode();
|
||||
|
||||
#[block]
|
||||
{
|
||||
Pallet::<T>::take_first_concatenated_xcm(&mut &data[..], &mut WeightMeter::new())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Benchmark the migration for a maximal sized message.
|
||||
#[benchmark]
|
||||
fn on_idle_good_msg() {
|
||||
use migration::v3;
|
||||
|
||||
let block = 5;
|
||||
let para = ParaId::from(4);
|
||||
let message = vec![123u8; MaxXcmpMessageLenOf::<T>::get() as usize];
|
||||
let message_metadata = vec![(block, XcmpMessageFormat::ConcatenatedVersionedXcm)];
|
||||
|
||||
v3::InboundXcmpMessages::<T>::insert(para, block, message);
|
||||
v3::InboundXcmpStatus::<T>::set(Some(vec![v3::InboundChannelDetails {
|
||||
sender: para,
|
||||
state: v3::InboundState::Ok,
|
||||
message_metadata,
|
||||
}]));
|
||||
|
||||
#[block]
|
||||
{
|
||||
Pallet::<T>::on_idle(0u32.into(), Weight::MAX);
|
||||
}
|
||||
}
|
||||
|
||||
/// Benchmark the migration with a 64 KiB message that will not be possible to enqueue.
|
||||
#[benchmark]
|
||||
fn on_idle_large_msg() {
|
||||
use migration::v3;
|
||||
|
||||
let block = 5;
|
||||
let para = ParaId::from(4);
|
||||
let message = vec![123u8; 1 << 16]; // 64 KiB message
|
||||
let message_metadata = vec![(block, XcmpMessageFormat::ConcatenatedVersionedXcm)];
|
||||
|
||||
v3::InboundXcmpMessages::<T>::insert(para, block, message);
|
||||
v3::InboundXcmpStatus::<T>::set(Some(vec![v3::InboundChannelDetails {
|
||||
sender: para,
|
||||
state: v3::InboundState::Ok,
|
||||
message_metadata,
|
||||
}]));
|
||||
|
||||
#[block]
|
||||
{
|
||||
Pallet::<T>::on_idle(0u32.into(), Weight::MAX);
|
||||
}
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
|
||||
}
|
||||
Reference in New Issue
Block a user