5

my lovely Substrate-Heros,

at the moment I try to benchmark the FRAME pallets of our custom runtime. Unfortunately, I ran into an error while benchmarking the session pallet. I copied the implementation from the Polkadot runtime and integrated the benchmark crate in the same way. When I try to compile I get the following error:

impl pallet_session_benchmarking::Config for Runtime {}
      |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<pallet_staking::pallet::pallet::Call<Runtime>>` is not implemented for `Call`

I checked the benchmark of the session pallet and I saw that they have a reference to pallet_staking even though this is not a reference to the session pallet itself. As it seems the problem is that we don't use the staking pallet at all in our runtime - we have our own implementation of staking. Let's come to my actual question: Is it possible to benchmark the session pallet for a custom runtime if I do not use the staking pallet and if yes how?

Thanks in advance!

1 Answer 1

5

You are correct that the benchmarking for the Session pallet depends on the Substrate Staking pallet also be used. If you do not use the Substrate staking pallet, you cannot (and should not) use the benchmarking included in the Session pallet.

Instead, you should write your own custom benchmark which handles benchmarking here.

You can already see that the benchmarks for session are in their own crate: pallet-session-benchmarking. In this case, you should write your own crate which does something similar to this crate, but uses the appropriate dependencies.

Specifically, the Session pallet expects someone to implement a SessionManager and SessionHandler. The behavior and overhead of these hooks is hard to setup for benchmarks in general, so instead, we programmed the benchmarks to be for a specific scenario.

If you have created your own staking pallet, then you should consider how your pallet interacts with the Session pallet, and create custom benchmarks which test these two behaving together in a worst case scenario.

Once you have created your benchmarking crate, all you need to do is include that benchmarking crate into your runtime:

#[cfg(feature = "runtime-benchmarks")]
mod benches {
    define_benchmarks!(
        [pallet_session, SessionBench::<Runtime>]
        // -- snip --
    );
}

// -- snip --

    #[cfg(feature = "runtime-benchmarks")]
    impl frame_benchmarking::Benchmark<Block> for Runtime {
        fn benchmark_metadata(extra: bool) -> (
            Vec<frame_benchmarking::BenchmarkList>,
            Vec<frame_support::traits::StorageInfo>,
        ) {
            use frame_benchmarking::{baseline, Benchmarking, BenchmarkList};
            use frame_support::traits::StorageInfoTrait;

            // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency
            // issues. To get around that, we separated the Session benchmarks into its own crate,
            // which is why we need these two lines below.
            use pallet_session_benchmarking::Pallet as SessionBench;

            // -- snip --

            let mut list = Vec::<BenchmarkList>::new();
            list_benchmarks!(list, extra);

            let storage_info = AllPalletsWithSystem::storage_info();

            (list, storage_info)
        }
1
  • 1
    Hey Shawn, this definitely answers my question, thanks!
    – Janislav
    Commented Jun 16, 2022 at 7:56

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.