Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions auction/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub use crate::*;

use frame_benchmarking::v2::*;
use frame_support::assert_ok;
use frame_system::{EventRecord, RawOrigin};
use frame_system::RawOrigin;

/// Helper trait for benchmarking.
pub trait BenchmarkHelper<BlockNumber, AccountId, Balance> {
Expand Down Expand Up @@ -58,14 +58,6 @@ impl<T: Config> BenchmarkHelper<BlockNumberFor<T>, T::AccountId, T::Balance> for
}
}

fn assert_last_event<T: Config>(generic_event: <T as frame_system::Config>::RuntimeEvent) {
let events = frame_system::Pallet::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
let EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}

#[benchmarks]
mod benchmarks {
use super::*;
Expand All @@ -80,7 +72,7 @@ mod benchmarks {
#[extrinsic_call]
_(RawOrigin::Signed(bidder.clone()), auction_id, bid_price);

assert_last_event::<T>(
frame_system::Pallet::<T>::assert_last_event(
Event::Bid {
auction_id,
bidder: bidder,
Expand Down
3 changes: 3 additions & 0 deletions authority/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
serde = { workspace = true, optional = true }

frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-core = { workspace = true }
Expand All @@ -28,6 +29,7 @@ sp-io = { workspace = true, features = ["std"] }
[features]
default = [ "std" ]
std = [
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"parity-scale-codec/std",
Expand All @@ -39,6 +41,7 @@ std = [
"sp-std/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
Expand Down
263 changes: 263 additions & 0 deletions authority/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
pub use crate::*;

use frame_benchmarking::v2::*;
use frame_support::assert_ok;
use frame_system::RawOrigin;
use sp_std::vec;

/// Helper trait for benchmarking.
pub trait BenchmarkHelper<AsOriginId> {
fn get_as_origin_id() -> Option<AsOriginId>;
}

impl<AsOriginId> BenchmarkHelper<AsOriginId> for () {
fn get_as_origin_id() -> Option<AsOriginId> {
None
}
}

#[benchmarks(where
<T as Config>::RuntimeCall: From<frame_system::Call<T>>
)]
mod benchmarks {
use super::*;

// dispatch a dispatchable as other origin
#[benchmark]
fn dispatch_as() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let call = frame_system::Call::remark { remark: vec![] }.into();

#[extrinsic_call]
_(RawOrigin::Root, as_origin, Box::new(call));
}

// schedule a dispatchable to be dispatched at later block.
#[benchmark]
fn schedule_dispatch_without_delay() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let sub_call = frame_system::Call::remark { remark: vec![] }.into();

let call: Call<T> = Call::dispatch_as {
as_origin: as_origin,
call: Box::new(sub_call),
};

let encoded_call = call.encode();
let bounded_call = Box::new(Bounded::Inline(encoded_call.try_into().unwrap()));

#[extrinsic_call]
schedule_dispatch(RawOrigin::Root, DispatchTime::At(2u32.into()), 0, false, bounded_call);
}

// schedule a dispatchable to be dispatched at later block.
// ensure that the delay is reached when scheduling
#[benchmark]
fn schedule_dispatch_with_delay() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let sub_call = frame_system::Call::remark { remark: vec![] }.into();

let call: Call<T> = Call::dispatch_as {
as_origin: as_origin,
call: Box::new(sub_call),
};

let encoded_call = call.encode();
let bounded_call = Box::new(Bounded::Inline(encoded_call.try_into().unwrap()));

#[extrinsic_call]
schedule_dispatch(RawOrigin::Root, DispatchTime::At(2u32.into()), 0, true, bounded_call);
}

// fast track a scheduled dispatchable.
#[benchmark]
fn fast_track_scheduled_dispatch() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let sub_call = frame_system::Call::remark { remark: vec![] }.into();

let call: Call<T> = Call::dispatch_as {
as_origin: as_origin,
call: Box::new(sub_call),
};

let encoded_call = call.encode();
let bounded_call = Box::new(Bounded::Inline(encoded_call.try_into().unwrap()));

frame_system::Pallet::<T>::set_block_number(1u32.into());
assert_ok!(Pallet::<T>::schedule_dispatch(
<T as frame_system::Config>::RuntimeOrigin::root(),
DispatchTime::At(2u32.into()),
0,
true,
bounded_call
));

let schedule_origin = {
let origin: <T as Config>::RuntimeOrigin = From::from(<T as Config>::RuntimeOrigin::root());
let origin: <T as Config>::RuntimeOrigin =
From::from(DelayedOrigin::<BlockNumberFor<T>, <T as Config>::PalletsOrigin>::new(
1u32.into(),
Box::new(origin.caller().clone()),
));
origin
};

let pallets_origin = schedule_origin.caller().clone();

#[extrinsic_call]
fast_track_scheduled_dispatch(
RawOrigin::Root,
Box::new(pallets_origin),
0,
DispatchTime::At(4u32.into()),
);
}

// delay a scheduled dispatchable.
#[benchmark]
fn delay_scheduled_dispatch() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let sub_call = frame_system::Call::remark { remark: vec![] }.into();

let call: Call<T> = Call::dispatch_as {
as_origin: as_origin,
call: Box::new(sub_call),
};

let encoded_call = call.encode();
let bounded_call = Box::new(Bounded::Inline(encoded_call.try_into().unwrap()));

frame_system::Pallet::<T>::set_block_number(1u32.into());
assert_ok!(Pallet::<T>::schedule_dispatch(
<T as frame_system::Config>::RuntimeOrigin::root(),
DispatchTime::At(2u32.into()),
0,
true,
bounded_call
));

let schedule_origin = {
let origin: <T as Config>::RuntimeOrigin = From::from(<T as Config>::RuntimeOrigin::root());
let origin: <T as Config>::RuntimeOrigin =
From::from(DelayedOrigin::<BlockNumberFor<T>, <T as Config>::PalletsOrigin>::new(
1u32.into(),
Box::new(origin.caller().clone()),
));
origin
};

let pallets_origin = schedule_origin.caller().clone();

#[extrinsic_call]
_(RawOrigin::Root, Box::new(pallets_origin), 0, 5u32.into());
}

// cancel a scheduled dispatchable
#[benchmark]
fn cancel_scheduled_dispatch() {
let as_origin = T::BenchmarkHelper::get_as_origin_id().unwrap();

let sub_call = frame_system::Call::remark { remark: vec![] }.into();

let call: Call<T> = Call::dispatch_as {
as_origin: as_origin,
call: Box::new(sub_call),
};

let encoded_call = call.encode();
let bounded_call = Box::new(Bounded::Inline(encoded_call.try_into().unwrap()));

frame_system::Pallet::<T>::set_block_number(1u32.into());
assert_ok!(Pallet::<T>::schedule_dispatch(
<T as frame_system::Config>::RuntimeOrigin::root(),
DispatchTime::At(2u32.into()),
0,
true,
bounded_call
));

let schedule_origin = {
let origin: <T as Config>::RuntimeOrigin = From::from(<T as Config>::RuntimeOrigin::root());
let origin: <T as Config>::RuntimeOrigin =
From::from(DelayedOrigin::<BlockNumberFor<T>, <T as Config>::PalletsOrigin>::new(
1u32.into(),
Box::new(origin.caller().clone()),
));
origin
};

let pallets_origin = schedule_origin.caller().clone();

#[extrinsic_call]
_(RawOrigin::Root, Box::new(pallets_origin), 0u32.into());
}

// authorize a call that can be triggered later
#[benchmark]
fn authorize_call() {
let caller: T::AccountId = whitelisted_caller();

let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
let hash = <T as frame_system::Config>::Hashing::hash_of(&call);

frame_system::Pallet::<T>::set_block_number(1u32.into());

#[extrinsic_call]
_(RawOrigin::Root, Box::new(call.clone()), Some(caller.clone()));

assert_eq!(Pallet::<T>::saved_calls(&hash), Some((call, Some(caller))));
}

#[benchmark]
fn remove_authorized_call() {
let caller: T::AccountId = whitelisted_caller();

let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
let hash = <T as frame_system::Config>::Hashing::hash_of(&call);

frame_system::Pallet::<T>::set_block_number(1u32.into());
assert_ok!(Pallet::<T>::authorize_call(
RawOrigin::Root.into(),
Box::new(call.clone()),
Some(caller.clone())
));

#[extrinsic_call]
_(RawOrigin::Signed(caller), hash);

assert_eq!(Pallet::<T>::saved_calls(&hash), None);
}

#[benchmark]
fn trigger_call() {
let caller: T::AccountId = whitelisted_caller();

let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
let hash = <T as frame_system::Config>::Hashing::hash_of(&call);

let call_weight_bound = call.get_dispatch_info().call_weight;

frame_system::Pallet::<T>::set_block_number(1u32.into());
assert_ok!(Pallet::<T>::authorize_call(
RawOrigin::Root.into(),
Box::new(call.clone()),
Some(caller.clone())
));

#[extrinsic_call]
_(RawOrigin::Signed(caller), hash, call_weight_bound);

assert_eq!(Pallet::<T>::saved_calls(&hash), None);
}

impl_benchmark_test_suite! {
Pallet,
crate::mock::ExtBuilder::default().build(),
crate::mock::Runtime,
}
}
7 changes: 7 additions & 0 deletions authority/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ use sp_std::prelude::*;

use frame_support::traits::schedule::v3::Named as ScheduleNamed;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
mod mock;
mod tests;
mod weights;

#[cfg(feature = "runtime-benchmarks")]
pub use benchmarking::BenchmarkHelper;
pub use weights::WeightInfo;

/// A delayed origin. Can only be dispatched via `dispatch_as` with a delay.
Expand Down Expand Up @@ -238,6 +242,9 @@ pub mod module {

/// Weight information for extrinsics in this module.
type WeightInfo: WeightInfo;

#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper: BenchmarkHelper<Self::AsOriginId>;
}

#[pallet::error]
Expand Down
11 changes: 11 additions & 0 deletions authority/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ impl AsOriginId<RuntimeOrigin, OriginCaller> for MockAsOriginId {
}
}

#[cfg(feature = "runtime-benchmarks")]
pub struct MockBenchmarkHelper;
#[cfg(feature = "runtime-benchmarks")]
impl BenchmarkHelper<MockAsOriginId> for MockBenchmarkHelper {
fn get_as_origin_id() -> Option<MockAsOriginId> {
Some(MockAsOriginId::Root)
}
}

impl Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
type PalletsOrigin = OriginCaller;
Expand All @@ -145,6 +154,8 @@ impl Config for Runtime {
type AsOriginId = MockAsOriginId;
type AuthorityConfig = AuthorityConfigImpl;
type WeightInfo = ();
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = MockBenchmarkHelper;
}

type Block = frame_system::mocking::MockBlock<Runtime>;
Expand Down
Loading