Skip to content

Commit

Permalink
Add benchmarks to oracle (open-web3-stack#985)
Browse files Browse the repository at this point in the history
* Add benchmarks to oracle

* Add cfg for runtime-benchmarks

* toml format
  • Loading branch information
Dinonard authored Mar 26, 2024
1 parent 58f847f commit 2dbcd1d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 4 deletions.
8 changes: 8 additions & 0 deletions oracle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ sp-application-crypto = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
frame-benchmarking = { workspace = true, optional = true }

orml-traits = { path = "../traits", version = "0.8.0", default-features = false }
orml-utilities = { path = "../utilities", version = "0.8.0", default-features = false }
Expand All @@ -28,6 +29,7 @@ sp-core = { workspace = true }
[features]
default = [ "std" ]
std = [
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"orml-traits/std",
Expand All @@ -45,3 +47,9 @@ try-runtime = [
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
55 changes: 55 additions & 0 deletions oracle/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use super::*;
use crate::Pallet as Oracle;

use frame_benchmarking::v2::*;

use frame_support::assert_ok;
use frame_system::{Pallet as System, RawOrigin};
use sp_std::vec;

#[instance_benchmarks]
mod benchmarks {
use super::*;

#[benchmark]
fn feed_values(x: Linear<1, { T::BenchmarkHelper::get_currency_id_value_pairs().len() as u32 }>) {
// Register the caller
let caller: T::AccountId = whitelisted_caller();
T::Members::add(&caller);

let values = T::BenchmarkHelper::get_currency_id_value_pairs()[..x as usize]
.to_vec()
.try_into()
.expect("Must succeed since at worst the length remained the same.");

#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), values);

assert!(HasDispatched::<T, I>::get().contains(&caller));
}

#[benchmark]
fn on_finalize() {
// Register the caller
let caller: T::AccountId = whitelisted_caller();
T::Members::add(&caller);

// Feed some values before running `on_finalize` hook
System::<T>::set_block_number(1u32.into());
let values = T::BenchmarkHelper::get_currency_id_value_pairs();
assert_ok!(Oracle::<T, I>::feed_values(RawOrigin::Signed(caller).into(), values));

#[block]
{
Oracle::<T, I>::on_finalize(System::<T>::block_number());
}

assert!(!HasDispatched::<T, I>::exists());
}

impl_benchmark_test_suite! {
Oracle,
crate::mock::new_test_ext(),
crate::mock::Test,
}
}
15 changes: 15 additions & 0 deletions oracle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ use sp_std::{prelude::*, vec};

pub use crate::default_combine_data::DefaultCombineData;

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

mod default_combine_data;
mod mock;
mod tests;
Expand All @@ -49,6 +52,15 @@ mod weights;
pub use module::*;
pub use weights::WeightInfo;

#[cfg(feature = "runtime-benchmarks")]
/// Helper trait for benchmarking.
pub trait BenchmarkHelper<OracleKey, OracleValue, L: Get<u32>> {
/// Returns a list of `(oracle_key, oracle_value)` pairs to be used for benchmarking.
///
/// NOTE: User should ensure to at least submit two values, otherwise the benchmark linear analysis might fail.
fn get_currency_id_value_pairs() -> BoundedVec<(OracleKey, OracleValue), L>;
}

#[frame_support::pallet]
pub mod module {
use super::*;
Expand Down Expand Up @@ -100,6 +112,9 @@ pub mod module {
/// Maximum size the vector used for feed values
#[pallet::constant]
type MaxFeedValues: Get<u32>;

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

#[pallet::error]
Expand Down
27 changes: 24 additions & 3 deletions oracle/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl frame_system::Config for Test {

thread_local! {
static TIME: RefCell<u32> = RefCell::new(0);
static MEMBERS: RefCell<Vec<AccountId>> = RefCell::new(vec![1, 2, 3]);
}

pub struct Timestamp;
Expand All @@ -46,14 +47,28 @@ impl Timestamp {

parameter_types! {
pub const RootOperatorAccountId: AccountId = 4;
pub static OracleMembers: Vec<AccountId> = vec![1, 2, 3];
pub const MaxFeedValues: u32 = 5;
}

pub struct Members;

impl SortedMembers<AccountId> for Members {
fn sorted_members() -> Vec<AccountId> {
OracleMembers::get()
MEMBERS.with(|v| v.borrow().clone())
}

#[cfg(feature = "runtime-benchmarks")]
fn add(who: &AccountId) {
MEMBERS.with(|v| v.borrow_mut().push(*who));
}
}

#[cfg(feature = "runtime-benchmarks")]
pub struct BenchmarkHelper;
#[cfg(feature = "runtime-benchmarks")]
impl crate::BenchmarkHelper<Key, Value, MaxFeedValues> for BenchmarkHelper {
fn get_currency_id_value_pairs() -> BoundedVec<(Key, Value), MaxFeedValues> {
vec![(1, 1), (2, 2), (3, 3)].try_into().unwrap()
}
}

Expand All @@ -68,7 +83,9 @@ impl Config for Test {
type Members = Members;
type WeightInfo = ();
type MaxHasDispatchedSize = ConstU32<100>;
type MaxFeedValues = ConstU32<5>;
type MaxFeedValues = MaxFeedValues;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = BenchmarkHelper;
}

type Block = frame_system::mocking::MockBlock<Test>;
Expand All @@ -80,6 +97,10 @@ construct_runtime!(
}
);

pub fn set_members(members: Vec<AccountId>) {
MEMBERS.with(|v| *v.borrow_mut() = members);
}

// This function basically just builds a genesis storage key/value store
// according to our desired mockup.
pub fn new_test_ext() -> sp_io::TestExternalities {
Expand Down
2 changes: 1 addition & 1 deletion oracle/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ fn get_all_values_should_work() {
#[test]
fn change_member_should_work() {
new_test_ext().execute_with(|| {
OracleMembers::set(vec![2, 3, 4]);
set_members(vec![2, 3, 4]);
<ModuleOracle as ChangeMembers<AccountId>>::change_members_sorted(&[4], &[1], &[2, 3, 4]);
assert_noop!(
ModuleOracle::feed_values(RuntimeOrigin::signed(1), vec![(50, 1000)].try_into().unwrap()),
Expand Down

0 comments on commit 2dbcd1d

Please sign in to comment.