Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update HRMP pallet benchmarking to use benchmarks v2 #1676

Merged
merged 9 commits into from
Sep 22, 2023
131 changes: 86 additions & 45 deletions polkadot/runtime/parachains/src/hrmp/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

#![cfg(feature = "runtime-benchmarks")]

use crate::{
configuration::Pallet as Configuration,
hrmp::{Pallet as Hrmp, *},
paras::{Pallet as Paras, ParaKind, ParachainsCache},
shared::Pallet as Shared,
};
use frame_benchmarking::v2::*;
use frame_support::{assert_ok, traits::Currency};

type BalanceOf<T> =
Expand Down Expand Up @@ -138,10 +141,12 @@ static_assertions::const_assert!(MAX_UNIQUE_CHANNELS < PREFIX_0);
static_assertions::const_assert!(HRMP_MAX_INBOUND_CHANNELS_BOUND < PREFIX_0);
static_assertions::const_assert!(HRMP_MAX_OUTBOUND_CHANNELS_BOUND < PREFIX_0);

frame_benchmarking::benchmarks! {
where_clause { where <T as frame_system::Config>::RuntimeOrigin: From<crate::Origin> }
#[benchmarks(where <T as frame_system::Config>::RuntimeOrigin: From<crate::Origin>)]
mod benchmarks {
use super::*;

hrmp_init_open_channel {
#[benchmark]
fn hrmp_init_open_channel () {
let sender_id: ParaId = 1u32.into();
let sender_origin: crate::Origin = 1u32.into();

Expand All @@ -155,45 +160,57 @@ frame_benchmarking::benchmarks! {

let capacity = Configuration::<T>::config().hrmp_channel_max_capacity;
let message_size = Configuration::<T>::config().hrmp_channel_max_message_size;
}: _(sender_origin, recipient_id, capacity, message_size)
verify {

#[extrinsic_call]
_(sender_origin, recipient_id, capacity, message_size);

assert_last_event::<T>(
Event::<T>::OpenChannelRequested(sender_id, recipient_id, capacity, message_size).into()
);
}

hrmp_accept_open_channel {
#[benchmark]
fn hrmp_accept_open_channel () {
let [(sender, _), (recipient, recipient_origin)] =
establish_para_connection::<T>(1, 2, ParachainSetupStep::Requested);
}: _(recipient_origin, sender)
verify {

#[extrinsic_call]
_(recipient_origin, sender);

assert_last_event::<T>(Event::<T>::OpenChannelAccepted(sender, recipient).into());
}

hrmp_close_channel {
#[benchmark]
fn hrmp_close_channel () {
let [(sender, sender_origin), (recipient, _)] =
establish_para_connection::<T>(1, 2, ParachainSetupStep::Established);
let channel_id = HrmpChannelId { sender, recipient };
}: _(sender_origin, channel_id.clone())
verify {

#[extrinsic_call]
_(sender_origin, channel_id.clone());

assert_last_event::<T>(Event::<T>::ChannelClosed(sender, channel_id).into());
}

// NOTE: a single parachain should have the maximum number of allowed ingress and egress
// channels.
force_clean_hrmp {
#[benchmark]
fn force_clean_hrmp (
// ingress channels to a single leaving parachain that need to be closed.
let i in 0 .. (HRMP_MAX_INBOUND_CHANNELS_BOUND - 1);
i: Linear<0, { HRMP_MAX_INBOUND_CHANNELS_BOUND - 1 }>,
// egress channels to a single leaving parachain that need to be closed.
let e in 0 .. (HRMP_MAX_OUTBOUND_CHANNELS_BOUND - 1);

e: Linear<0, { HRMP_MAX_OUTBOUND_CHANNELS_BOUND - 1 }>
) {
// first, update the configs to support this many open channels...
assert_ok!(
Configuration::<T>::set_hrmp_max_parachain_outbound_channels(frame_system::RawOrigin::Root.into(), e + 1)
);
assert_ok!(
Configuration::<T>::set_hrmp_max_parachain_inbound_channels(frame_system::RawOrigin::Root.into(), i + 1)
);
assert_ok!(
Configuration::<T>::set_max_downward_message_size(frame_system::RawOrigin::Root.into(), 1024)
);
// .. and enact it.
Configuration::<T>::initializer_on_new_session(&Shared::<T>::scheduled_session());

Expand Down Expand Up @@ -225,48 +242,58 @@ frame_benchmarking::benchmarks! {

// all in all, we have created this many channels.
assert_eq!(HrmpChannels::<T>::iter().count() as u32, i + e);
}: _(frame_system::Origin::<T>::Root, para, i, e) verify {

#[extrinsic_call]
_(frame_system::Origin::<T>::Root, para, i, e);

// all in all, all of them must be gone by now.
assert_eq!(HrmpChannels::<T>::iter().count() as u32, 0);
// borrow this function from the tests to make sure state is clear, given that we do a lot
// of out-of-ordinary ops here.
Hrmp::<T>::assert_storage_consistency_exhaustive();
}

force_process_hrmp_open {
#[benchmark]
fn force_process_hrmp_open (
// number of channels that need to be processed. Worse case is an N-M relation: unique
// sender and recipients for all channels.
let c in 0 .. MAX_UNIQUE_CHANNELS;

c: Linear<0, MAX_UNIQUE_CHANNELS>
) {
for id in 0 .. c {
let _ = establish_para_connection::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Accepted);
}
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
}: _(frame_system::Origin::<T>::Root, c)
verify {

#[extrinsic_call]
_(frame_system::Origin::<T>::Root, c);

assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, 0);
}

force_process_hrmp_close {
#[benchmark]
fn force_process_hrmp_close (
// number of channels that need to be processed. Worse case is an N-M relation: unique
// sender and recipients for all channels.
let c in 0 .. MAX_UNIQUE_CHANNELS;

c: Linear<0, MAX_UNIQUE_CHANNELS>
) {
for id in 0 .. c {
let _ = establish_para_connection::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::CloseRequested);
}

assert_eq!(HrmpCloseChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
}: _(frame_system::Origin::<T>::Root, c)
verify {

#[extrinsic_call]
_(frame_system::Origin::<T>::Root, c);

assert_eq!(HrmpCloseChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, 0);
}

hrmp_cancel_open_request {
#[benchmark]
fn hrmp_cancel_open_request (
// number of items already existing in the `HrmpOpenChannelRequestsList`, other than the
// one that we remove.
let c in 0 .. MAX_UNIQUE_CHANNELS;

c: Linear<0, MAX_UNIQUE_CHANNELS>
) {
for id in 0 .. c {
let _ = establish_para_connection::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested);
}
Expand All @@ -275,16 +302,18 @@ frame_benchmarking::benchmarks! {
establish_para_connection::<T>(1, 2, ParachainSetupStep::Requested);
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c + 1);
let channel_id = HrmpChannelId { sender, recipient };
}: _(sender_origin, channel_id, c + 1)
verify {

#[extrinsic_call]
_(sender_origin, channel_id, c + 1);

assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
}

// worse case will be `n` parachain channel requests, where in all of them either the sender or
// the recipient need to be cleaned. This enforces the deposit of at least one to be processed.
// No code path for triggering two deposit process exists.
clean_open_channel_requests {
let c in 0 .. MAX_UNIQUE_CHANNELS;
#[benchmark]
fn clean_open_channel_requests (c: Linear<0, MAX_UNIQUE_CHANNELS>) {

for id in 0 .. c {
let _ = establish_para_connection::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested);
Expand All @@ -293,13 +322,17 @@ frame_benchmarking::benchmarks! {
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
let outgoing = (0..c).map(|id| (id + PREFIX_1).into()).collect::<Vec<ParaId>>();
let config = Configuration::<T>::config();
}: {
Hrmp::<T>::clean_open_channel_requests(&config, &outgoing);
} verify {

#[block]
{
Hrmp::<T>::clean_open_channel_requests(&config, &outgoing);
}

assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, 0);
}

force_open_hrmp_channel {
#[benchmark]
fn force_open_hrmp_channel () {
seadanda marked this conversation as resolved.
Show resolved Hide resolved
let sender_id: ParaId = 1u32.into();
let sender_origin: crate::Origin = 1u32.into();
let recipient_id: ParaId = 2u32.into();
Expand Down Expand Up @@ -344,14 +377,17 @@ frame_benchmarking::benchmarks! {

// but the _channel_ should not exist
assert!(HrmpChannels::<T>::get(&channel_id).is_none());
}: _(frame_system::Origin::<T>::Root, sender_id, recipient_id, capacity, message_size)
verify {

#[extrinsic_call]
_(frame_system::Origin::<T>::Root, sender_id, recipient_id, capacity, message_size);

assert_last_event::<T>(
Event::<T>::HrmpChannelForceOpened(sender_id, recipient_id, capacity, message_size).into()
);
}

establish_system_channel {
#[benchmark]
fn establish_system_channel () {
let sender_id: ParaId = 1u32.into();
let recipient_id: ParaId = 2u32.into();

Expand All @@ -364,14 +400,17 @@ frame_benchmarking::benchmarks! {

let capacity = config.hrmp_channel_max_capacity;
let message_size = config.hrmp_channel_max_message_size;
}: _(frame_system::RawOrigin::Signed(caller), sender_id, recipient_id)
verify {

#[extrinsic_call]
_(frame_system::RawOrigin::Signed(caller), sender_id, recipient_id);

assert_last_event::<T>(
Event::<T>::HrmpSystemChannelOpened(sender_id, recipient_id, capacity, message_size).into()
);
}

poke_channel_deposits {
#[benchmark]
fn poke_channel_deposits () {
let sender_id: ParaId = 1u32.into();
let recipient_id: ParaId = 2u32.into();
let channel_id = HrmpChannelId {sender: sender_id, recipient: recipient_id };
Expand Down Expand Up @@ -403,8 +442,10 @@ frame_benchmarking::benchmarks! {
// Actually reserve the deposits.
let _ = T::Currency::reserve(&sender_id.into_account_truncating(), sender_deposit);
let _ = T::Currency::reserve(&recipient_id.into_account_truncating(), recipient_deposit);
}: _(frame_system::RawOrigin::Signed(caller), sender_id, recipient_id)
verify {

#[extrinsic_call]
_(frame_system::RawOrigin::Signed(caller), sender_id, recipient_id);

assert_last_event::<T>(
Event::<T>::OpenChannelDepositsUpdated(sender_id, recipient_id).into()
);
Expand Down
Loading