1

I have a pallet that can be used to dispatch other calls to the runtime and it's defined as

internal_call : Box<<T as Config>::Call>

Given that Call is just an enum, I want to check if the dispatchable is for a certain pallet, let's say pallet_kitties::create_kitty . How can I go about doing that? If I debug print internal_call I get Call::Kitties(Call::create_kitty) but this doesn't work in my pallet due to multiple errors :

match internal_call {
  <T as Config>::Call::Kitties(Call::create_kitty) => {do_something();}
   ^^^^^^^^^^^^^^^^^^ error    ^^^^ error
  _ => {}
}

one of which is Kitties is not found for associated type <T as pallet::Config>::Call. I know this is happening probably because the runtime is being built after the fact that all pallets have been built and that the Runtime itself cannot be a dependency for the pallets in order to be able to use Call::Kitties as that would cause a dependency cycle.

Is there any easier way to get access to the internal call ?

2 Answers 2

2

It is possible to match the pallet's own calls.

Check the example: https://github.com/paritytech/substrate/blob/eae25c901ccd4ef5c3ceb082e3f2c66753879062/frame/election-provider-multi-phase/src/lib.rs#L1197-L1200.

If you want to match other pallets' calls. You could use a trait.

// in your pallet/lib.rs
trait Config {
  type MatchOtherCalls: CallMatch;
}
trait CallMatch {
  // you could make a more complicative logic here
  fn match(c) -> bool;
}

// in your runtime/lib.rs
struct CallMatcher;
impl CallMatch for CallMatcher {
  fn match(c) -> bool {
    matches!(c, System::remark(..))
  }
}

impl pallet::Config for Runtime {
  type MachOtherCalls = CallMatcher;
}
2
  • Could you explain where is Call<T> in type Call = Call<T>; coming from? Nov 11, 2022 at 16:11
  • I should've mentioned it in my question but I need to make calls to other pallets after matching on them to ensure special action when certain dispatchables are called. How would that change fn match(c)? Nov 11, 2022 at 16:21
1

I am not sure if this helps but can fetch pallet id and call id from a call.

let (pallet_idx, call_idx): (u8, u8) = call
        .using_encoded(|mut bytes| Decode::decode(&mut bytes))
        .expect(
            "decode input is output of Call encode; Call guaranteed to have two enums; qed",
        );

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.