2

I am currently writing code for the hooks on_initialize and on_idle. They share functionality in the form of 2 methods, each using these methods multiple times. I would like to accurately benchmark these 2 methods to use when calculating and returning the weight in the mentioned hooks.

Is this the correct method? or should i be benchmarking the hooks themselves with some worst case scenario. In essence i am trying to dynamically set the weight which feels especially like gas metering. To the best of my knowledge this is not supported in standard extrinsic calls, except it seems possible in the hooks.

If it is the correct method how can i benchmark code that is not an extrinsic (not annotated with #[pallet::call]).

Preferably i would like to avoid db::reads_writes(x, y) to manually tally weights, is this best practice?

Here is some sample code to describe what i am trying to do:

 fn on_initialize(_b: T::BlockNumber) -> Weight { 
      let mut weight = Weight::default();
      let mut details = Details::<T>::get();

      Self::do_something_with_details(details);                    
      weight.saturating_add(T::WeightInfo::do_something_with_details());
                   
      Self::mutate_details(details, c);
      weight.saturating_add(T::WeightInfo::mutate_details());

      weight
 }

1 Answer 1

1

The benchmarking framework supports any arbitrary logic which is written in rust and compiles to Wasm.

You can see an example of benchmarking directly the on_initialize function in the Treasury pallet:

https://github.com/paritytech/substrate/blob/master/frame/treasury/src/benchmarking.rs#L130

on_initialize_proposals {
    let p in 0 .. T::MaxApprovals::get();
    setup_pot_account::<T, _>();
    create_approved_proposals::<T, _>(p)?;
}: {
    // You can see here we call the `on_initialize` function.
    Treasury::<T, _>::on_initialize(T::BlockNumber::zero());
}

You can write whatever logic you want in those brackets after the setup. For example you can also benchmark hashing functions something like this:

hashing {
    let i in 0 .. 100;
    let mut hash = T::Hash::default();
}: {
    (0..=100_000u32).for_each(|j| hash = T::Hashing::hash(&j.to_be_bytes()));
} verify {
    assert!(hash != T::Hash::default());
}

As seen here: https://github.com/paritytech/substrate/blob/master/frame/benchmarking/src/baseline.rs

Take a look at the documentation here:

https://github.com/paritytech/substrate/blob/master/frame/benchmarking/src/lib.rs

1
  • Thanks Shawn, seems to be a misunderstanding of syntax more than anything.
    – gatsey
    Nov 13, 2022 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.