2

I read in this answer that you can access everything from mock runtime in the benchmarking file by just adding #[cfg(test)] above the import use crate::mock::*; and that it is not a good idea since it only applies when running benchmark tests and not during the actual benchmarking against the real runtime.

In my case, I need to deploy a smart contract, get its address from the events emitted and then use that to benchmark a Pallet::<T>::transfer(to, erc20_address, amount) function. How can I access the Systems::events() inside the benchmark file? Thanks.

Edit: This solution worked for getting all the events emitted by the frame_system pallet. However, I need to match the contract instantiation event with all the events returned from the frame_system::Pallet::<T>::events() to extract the deployed contract code. I defined an Event = <T as frame_system::Config>::Event but it gave the error --

let Event = <T as frame_system::Config>::Event;
   |         ----- help: `Event` is defined here, but is not a type
...
60 |             if let Event::Contracts(pallet_contracts::Event::Instantiated {
   |                    ^^^^^ use of undeclared type `Event`

error[E0575]: expected method or associated constant, found associated type `frame_system::Config::Event`

I've added the code snippet for more context below:

    let evts = frame_system::Pallet::<T>::events();
    let Event = <T as frame_system::Config>::Event; // This line doesn't work
    let deployed = evts
        .iter()
        .rev()
        .find_map(|rec| {
            if let Event::Contracts(pallet_contracts::Event::Instantiated {
                deployer: _,
                contract,
            }) = &rec.event
            {
                Some(contract)
            } else {
                None
            }
        })
        .expect("unable to find deployed contract");

1 Answer 1

2

You can directly access the events. For example like this:

benchmarks! {
    something {
        assert!(frame_system::Pallet::<T>::events().is_empty());
    }: _(…)
    verify {
        assert!(!frame_system::Pallet::<T>::events().is_empty());
    }

One gotcha here is to initialize the block number in your new_test_ext functions. Otherwise the event emission does not work:

pub fn new_test_ext() -> sp_io::TestExternalities {
    let mut ext = sp_io::TestExternalities::new(t);
    ext.execute_with(|| System::set_block_number(1));
    ext
}
3
  • Thanks it worked! Can you please check my recent edit to the question? I need help on just one more thing.
    – AKASH S M
    Sep 30, 2022 at 15:59
  • what about if let pallet_contracts::Event::Instantiated { .. } Feb 23, 2023 at 15:57
  • Please paste it into a new question - in case Daan's comment did not answer it. Otherwise it is not as helpful to others who may come across the same hardship. Feb 23, 2023 at 16: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.