3

I am trying to use T::Call (This type is defined in frame_system) in storage and pallet dispatchable functions but getting below error.

error[E0277]: the trait bound `<T as frame_system::Config>::Call: WrapperTypeEncode` is not satisfied
  --> pallets/test/src/lib.rs:33:1
   |
33 | #[frame_support::pallet]
   | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `WrapperTypeEncode` is not implemented for `<T as frame_system::Config>::Call`
   |
   = note: required because of the requirements on the impl of `Encode` for `<T as frame_system::Config>::Call`
note: required by a bound in `EncodeLike`
  --> /Users/sm/.cargo/registry/src/github.com-1ecc6299db9ec823/parity-scale-codec-2.3.1/src/encode_like.rs:73:25
   |
73 | pub trait EncodeLike<T: Encode = Self>: Sized + Encode {}
   |                         ^^^^^^ required by this bound in `EncodeLike`
   = note: this error originates in the attribute macro `frame_support::pallet` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting the associated type
   |
68 |     #[pallet::storage, <T as frame_system::Config>::Call: WrapperTypeEncode]
   |                      ++++++++++++++++++++++++++++++++++++++++++++++++++++++

However, I am able to use other frame_system types like AccountId and BlockNumber. Can someone please help me to fix this?

4
  • Please also post the code. Are you trying to pass a Call as argument to an extrinsic? Commented Mar 20, 2022 at 17:35
  • 2
    @Ayush Mishra, please don't post errors without posting code. Do you expect us to be mind readers on how an error is caused?
    – Shawn Tabrizi
    Commented Mar 20, 2022 at 22:24
  • @ShawnTabrizi sorry I should have posted the code. I will take care of it next time. Thanks for your answer. It really helps. Commented Mar 21, 2022 at 2:13
  • @AyushMishra you can stil edit the question to include the problematic code in order to help new readers. Commented Mar 21, 2022 at 8:48

1 Answer 1

7

The Call type from frame_system is not the call that you want to use in this scenario. You should look at how the Multisig pallet handles working with the Call type.

  1. You must define a new Call type in your Pallet config which represents the outer call of the whole runtime:

    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// The overarching call type.
        type Call: Parameter
            + Dispatchable<Origin = Self::Origin, PostInfo = PostDispatchInfo>
            + GetDispatchInfo
            + From<frame_system::Call<Self>>;
    
        // ...
    }
    
  2. When referencing this type, you should disambiguate which Call you want to use, by referring to it by: <T as Config>::Call>. Where Config represents your pallet's config.

  3. When using the Call as a parameter input into an extrinsic, you should wrap it in a Box so that it can be placed on the heap and referenced by pointer, which can help since a Call can be very large in size: Box<<T as Config>::Call>

1
  • 1
    Boxing the call is not an optional thing. You are required to box it, otherwise you would have a self recursive enum that the compiler can not get the size of. You would get a compiler error.
    – bkchr
    Commented Mar 21, 2022 at 7:11

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.