diff --git a/auction/Cargo.toml b/auction/Cargo.toml index 4db36b2c4..5bb3be932 100644 --- a/auction/Cargo.toml +++ b/auction/Cargo.toml @@ -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-runtime = { workspace = true } @@ -26,6 +27,7 @@ sp-io = { workspace = true, features = ["std"] } [features] default = [ "std" ] std = [ + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "orml-traits/std", @@ -35,6 +37,12 @@ std = [ "sp-runtime/std", "sp-std/std", ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/auction/src/benchmarking.rs b/auction/src/benchmarking.rs new file mode 100644 index 000000000..7d58c6e18 --- /dev/null +++ b/auction/src/benchmarking.rs @@ -0,0 +1,108 @@ +pub use crate::*; + +use frame_benchmarking::v2::*; +use frame_support::assert_ok; +use frame_system::{EventRecord, RawOrigin}; + +/// Helper trait for benchmarking. +pub trait BenchmarkHelper { + fn setup_bid() -> Option<(AccountId, Balance)>; + fn setup_on_finalize(rand: u32) -> Option; +} + +impl BenchmarkHelper for () { + fn setup_bid() -> Option<(AccountId, Balance)> { + None + } + fn setup_on_finalize(_rand: u32) -> Option { + None + } +} + +pub struct BaseBenchmarkHelper(sp_std::marker::PhantomData); + +impl BenchmarkHelper, T::AccountId, T::Balance> for BaseBenchmarkHelper { + fn setup_bid() -> Option<(T::AccountId, T::Balance)> { + let end_block: BlockNumberFor = frame_system::Pallet::::block_number() + 10u32.into(); + assert_ok!(Pallet::::new_auction( + frame_system::Pallet::::block_number(), + Some(end_block), + )); + + let auction_id: T::AuctionId = 0u32.into(); + let pre_bidder: T::AccountId = account("pre_bidder", 0, 0); + let pre_bid_price: T::Balance = 10_000u32.into(); + + assert_ok!(Pallet::::bid( + RawOrigin::Signed(pre_bidder).into(), + auction_id, + pre_bid_price + )); + + let bidder: T::AccountId = account("bidder", 0, 0); + let bid_price: T::Balance = 20_000u32.into(); + + Some((bidder, bid_price)) + } + + fn setup_on_finalize(rand: u32) -> Option> { + let end_block: BlockNumberFor = frame_system::Pallet::::block_number() + 10u32.into(); + + for _auction_id in 0..rand { + assert_ok!(Pallet::::new_auction( + frame_system::Pallet::::block_number(), + Some(end_block), + )); + } + Some(end_block) + } +} + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::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::*; + + // `bid` a collateral auction, worst cases: + // there's bidder before and bid price will exceed target amount + #[benchmark] + fn bid() { + let auction_id: T::AuctionId = 0u32.into(); + let (bidder, bid_price) = T::BenchmarkHelper::setup_bid().unwrap(); + + #[extrinsic_call] + _(RawOrigin::Signed(bidder.clone()), auction_id, bid_price); + + assert_last_event::( + Event::Bid { + auction_id, + bidder: bidder, + amount: bid_price, + } + .into(), + ); + } + + #[benchmark] + fn on_finalize(c: Liner<1, 100>) { + let end_block = T::BenchmarkHelper::setup_on_finalize(c).unwrap(); + + #[block] + { + Pallet::::on_finalize(end_block); + } + } + + impl_benchmark_test_suite! { + Pallet, + crate::mock::ExtBuilder::default().build(), + crate::mock::Runtime, + } +} diff --git a/auction/src/lib.rs b/auction/src/lib.rs index c0b6a2f34..06c8837ce 100644 --- a/auction/src/lib.rs +++ b/auction/src/lib.rs @@ -22,10 +22,14 @@ use sp_runtime::{ DispatchError, DispatchResult, }; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; mod mock; mod tests; mod weights; +#[cfg(feature = "runtime-benchmarks")] +pub use benchmarking::{BaseBenchmarkHelper, BenchmarkHelper}; pub use module::*; pub use weights::WeightInfo; @@ -61,6 +65,9 @@ pub mod module { /// Weight information for extrinsics in this module. type WeightInfo: WeightInfo; + + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper: BenchmarkHelper, Self::AccountId, Self::Balance>; } #[pallet::error] @@ -130,7 +137,7 @@ pub mod module { /// The dispatch origin for this call must be `Signed` by the /// transactor. #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::bid_collateral_auction())] + #[pallet::weight(T::WeightInfo::bid())] pub fn bid(origin: OriginFor, id: T::AuctionId, #[pallet::compact] value: T::Balance) -> DispatchResult { let from = ensure_signed(origin)?; diff --git a/auction/src/mock.rs b/auction/src/mock.rs index 9f5dff7c6..21b40001f 100644 --- a/auction/src/mock.rs +++ b/auction/src/mock.rs @@ -29,9 +29,9 @@ impl AuctionHandler for Handler { now: BlockNumber, _id: AuctionId, new_bid: (AccountId, Balance), - _last_bid: Option<(AccountId, Balance)>, + last_bid: Option<(AccountId, Balance)>, ) -> OnNewBidResult { - if new_bid.0 == ALICE { + if last_bid.is_none() || last_bid.unwrap().0 != new_bid.0 { OnNewBidResult { accept_bid: true, auction_end_change: Change::NewValue(Some(now + BID_EXTEND_BLOCK)), @@ -52,6 +52,8 @@ impl Config for Runtime { type AuctionId = AuctionId; type Handler = Handler; type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = BaseBenchmarkHelper; } type Block = frame_system::mocking::MockBlock; @@ -64,7 +66,6 @@ construct_runtime!( ); pub const ALICE: AccountId = 1; -pub const BOB: AccountId = 2; pub const BID_EXTEND_BLOCK: BlockNumber = 10; pub struct ExtBuilder; diff --git a/auction/src/tests.rs b/auction/src/tests.rs index ed79b6362..698fc3464 100644 --- a/auction/src/tests.rs +++ b/auction/src/tests.rs @@ -93,8 +93,9 @@ fn bid_should_fail() { AuctionModule::bid(RuntimeOrigin::signed(ALICE), 0, 20), Error::::AuctionNotStarted ); + assert_ok!(AuctionModule::bid(RuntimeOrigin::signed(ALICE), 1, 20)); assert_noop!( - AuctionModule::bid(RuntimeOrigin::signed(BOB), 1, 20), + AuctionModule::bid(RuntimeOrigin::signed(ALICE), 1, 30), Error::::BidNotAccepted, ); assert_noop!( diff --git a/auction/src/weights.rs b/auction/src/weights.rs index 92af4c258..68151ed56 100644 --- a/auction/src/weights.rs +++ b/auction/src/weights.rs @@ -30,13 +30,13 @@ use sp_std::marker::PhantomData; /// Weight functions needed for orml_auction. pub trait WeightInfo { - fn bid_collateral_auction() -> Weight; + fn bid() -> Weight; fn on_finalize(c: u32, ) -> Weight; } /// Default weights. impl WeightInfo for () { - fn bid_collateral_auction() -> Weight { + fn bid() -> Weight { Weight::from_parts(108_000_000, 0) .saturating_add(RocksDbWeight::get().reads(8 as u64)) .saturating_add(RocksDbWeight::get().writes(9 as u64)) diff --git a/currencies/src/default_weight.rs b/currencies/src/default_weight.rs deleted file mode 100644 index c0fb92770..000000000 --- a/currencies/src/default_weight.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 - -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] - -use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight}; - -impl crate::WeightInfo for () { - fn transfer_non_native_currency() -> Weight { - Weight::from_parts(172_011_000, 0) - .saturating_add(DbWeight::get().reads(5 as u64)) - .saturating_add(DbWeight::get().writes(2 as u64)) - } - fn transfer_native_currency() -> Weight { - Weight::from_parts(43_023_000, 0) - } - fn update_balance_non_native_currency() -> Weight { - Weight::from_parts(137_440_000, 0) - .saturating_add(DbWeight::get().reads(5 as u64)) - .saturating_add(DbWeight::get().writes(2 as u64)) - } - fn update_balance_native_currency_creating() -> Weight { - Weight::from_parts(64_432_000, 0) - } - fn update_balance_native_currency_killing() -> Weight { - Weight::from_parts(62_595_000, 0) - } -} diff --git a/vesting/src/default_weight.rs b/vesting/src/default_weight.rs deleted file mode 100644 index 42da01846..000000000 --- a/vesting/src/default_weight.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 - -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] - -use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight}; - -impl crate::WeightInfo for () { - fn vested_transfer() -> Weight { - Weight::from_parts(310_862_000, 0) - .saturating_add(DbWeight::get().reads(4 as u64)) - .saturating_add(DbWeight::get().writes(4 as u64)) - } - fn claim(i: u32) -> Weight { - Weight::from_parts(158_614_000, 0) - .saturating_add(Weight::from_parts(958_000, 0).saturating_mul(i as u64)) - .saturating_add(DbWeight::get().reads(3 as u64)) - .saturating_add(DbWeight::get().writes(3 as u64)) - } - fn update_vesting_schedules(i: u32) -> Weight { - Weight::from_parts(119_811_000, 0) - .saturating_add(Weight::from_parts(2_320_000, 0).saturating_mul(i as u64)) - .saturating_add(DbWeight::get().reads(2 as u64)) - .saturating_add(DbWeight::get().writes(3 as u64)) - } -}