2

Im trying to have my pallet compile a pallet call based on the feature that is set, for example if i have two function calls feature_one() and feature_two(), it works fine with feature_one but when i add the second method with the #[cfg(feature= "feature2")] macro it gives me the following error:

      error[E0599]: no function or associated item named `feature_two` found for struct `pallet::Pallet` in the current scope

    function or associated item not found in `pallet::Pallet<T>`
    help: there is an associated function with a similar name: `feature_one`

this is the pallet code:

        #![cfg_attr(not(feature = "std"), no_std)]
        #[cfg(test)]
        mod tests;
        pub use pallet::*;
        #[frame_support::pallet]
        pub mod pallet {
            use frame_system::pallet_prelude::*;
            pub use sp_runtime::traits::Extrinsic;
            #[pallet::pallet]
            #[pallet::generate_store(pub(super) trait Store)]
            pub struct Pallet<T>(_);
        
            #[pallet::config]
            pub trait Config: frame_system::Config {
                type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
            }
            #[pallet::event]
            #[pallet::generate_deposit(pub(super) fn deposit_event)]
            pub enum Event<T: Config> {
                /// An Event has been validated
                CustomEvent { event_id: T::Hash },
            }
            #[pallet::error]
            pub enum Error<T> {
                AlreadySymbitted,
            }
       #[pallet::storage]
        pub(super) type MyStorage<T: Config> = StorageMap<_, Blake2_128Concat, T::Hash, T::BlockNumber>;
    
    
            #[pallet::call]
            impl<T: Config> Pallet<T> {
                #[cfg(feature= "feature1")]
                #[pallet::weight(0)]
                pub fn feature_one(_origin: OriginFor<T>, event_id: T::Hash) -> DispatchResult {
                } 
    
               #[cfg(feature= "feature2")]
               #[pallet::weight(0)]
                pub fn feature_two(_origin: OriginFor<T>, event_id: T::Hash) -> DispatchResult {
            
            }
    
        }
3
  • FYI #[cfg(feature= "feature1")] is supported in the construct_runtime! macro these days.
    – Squirrel
    Mar 27 at 12:49
  • @Squirrel how can i use it? are there any examples? does it solve my problem? any links?
    – dadzerlaze
    Mar 27 at 12:57
  • This was the PR that added the functionality: github.com/paritytech/substrate/pull/11818
    – Squirrel
    Apr 18 at 17:54

1 Answer 1

2

You can do this:

#[pallet::call]
impl<T: Config> Pallet<T> {
  #[pallet::call_index(0)]
  #[pallet::weight(0)]
  fn f() {
    Self::ff();
  }
}

impl<T: Config> Pallet<T> {
  #[cfg(not(feature = "g"))]
  fn ff() {}

  #[cfg(feature = "g")]
  fn ff() {}
}

or:

#[pallet::call]
impl<T: Config> Pallet<T> {
  #[pallet::call_index(0)]
  #[pallet::weight(0)]
  fn f() {
     Self::ff();
  }

  #[pallet::call_index(1)]
  #[pallet::weight(0)]
  fn g() {
     Self::gg();
  }
}

impl<T: Config> Pallet<T> {
  #[cfg(feature = "f")]
  fn ff() {}
  #[cfg(not(feature = "f"))]
  fn ff() { return not enable }

  #[cfg(feature = "g")]
  fn gg() {}
  #[cfg(not(feature = "g"))]
  fn gg() { return not enable }
}

or:

#[pallet::call_index(0)]
#[pallet::weight(0)]
fn f(.., params: Params) {
   Self::ff(params);
}

#[cfg(feature = "f")]
struct Params {
  f: u8
}

#[cfg(feature = "g")]
struct Params {
  g: u16
}
13
  • what if feature_two() have diffrent paramters than feature one, in this case it wouldn't work in the first solution? and does it work that way? whats wrong with my implementation?
    – dadzerlaze
    Mar 27 at 13:09
  • 1_, 2_ From the code in your question, I saw they are the same. It depends on the code, maybe you can leave the optional field empty. e.g. always passing an empty vec to it. 3_ #[pallet] not support cfg yet. Mar 27 at 13:10
  • yeah true, but what if they are not the same, i forgot to add that sorry
    – dadzerlaze
    Mar 27 at 13:11
  • Updated my answer. Mar 27 at 13:15
  • 1
    Imagine, schedule(0x1000000) means feature_f(xxx). After the runtime upgrade, it was changed to feature_g(xxx). It will try to decode the 0x1000000 into a different call. We don't know what would happen. Mar 27 at 14:09

Your Answer

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

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