2

My code for this crowdloan rewards pallet

  #[pallet::config]
  pub trait Config: frame_system::Config {
    type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
    type RelayChainAccountId: Parameter
      + Into<AccountId32>
      + From<AccountId32>
      + TypeInfo
      + Ord;
    type VestingBlockNumber: AtLeast32BitUnsigned + Parameter + Default + Into<BalanceOf<Self>>;
    type VestingBlockProvider: BlockNumberProvider<BlockNumber = Self::VestingBlockNumber>;
      ...
  }


  #[pallet::storage]
  #[pallet::getter(fn accounts_payable)]
  pub type AccountsPayable<T: Config> =
    StorageMap<_, Blake2_128Concat, T::AccountId, RewardInfo<T>>;

  #[pallet::storage]
  #[pallet::getter(fn claimed_relay_chain_ids)]
  pub type ClaimedRelayChainIds<T: Config> =
    StorageMap<_, Blake2_128Concat, T::RelayChainAccountId, ()>;

  #[pallet::storage]
  #[pallet::getter(fn unassociated_contributions)]
  pub type UnassociatedContributions<T: Config> =
    StorageMap<_, Blake2_128Concat, T::RelayChainAccountId, RewardInfo<T>>;

  #[pallet::storage]
  #[pallet::storage_prefix = "InitRelayBlock"]
  #[pallet::getter(fn init_vesting_block)]
  type InitVestingBlock<T: Config> = StorageValue<_, T::VestingBlockNumber, ValueQuery>;

  #[pallet::storage]
  #[pallet::storage_prefix = "EndRelayBlock"]
  #[pallet::getter(fn end_vesting_block)]
  type EndVestingBlock<T: Config> = StorageValue<_, T::VestingBlockNumber, ValueQuery>;


pub type BalanceOf<T> =
  <<T as Config>::RewardCurrency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

#[derive(Clone, PartialEq, Eq, Encode, Decode, Default, TypeInfo)]
#[scale_info(skip_type_params(T))]
#[cfg_attr(feature = "std", derive(Debug))]
//#[codec(mel_bound())] //not working
//#[pallet::without_storage_info] // not working
pub struct RewardInfo<T: Config> {
  pub total_reward: BalanceOf<T>,
  pub claimed_reward: BalanceOf<T>,
  pub contributed_relay_addresses: Vec<T::RelayChainAccountId>,
}

Then I got error messages:

error[E0277]: the trait bound `RewardInfo<T>: parity_scale_codec::MaxEncodedLen` is not satisfied
  --> pallets/crowdloan-rewards/src/lib.rs:36:12
   |
36 |     #[pallet::pallet]
   |               ^^^^^^ the trait `parity_scale_codec::MaxEncodedLen` is not implemented for `RewardInfo<T>`
   |
   = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageMap<_GeneratedPrefixForStorageAccountsPayable<T>, frame_support::Blake2_128Concat, <T as frame_system::Config>::AccountId, RewardInfo<T>>`

error[E0277]: the trait bound `<T as pallet::Config>::RelayChainAccountId: parity_scale_codec::MaxEncodedLen` is not satisfied
  --> pallets/crowdloan-rewards/src/lib.rs:36:12
   |
36 |     #[pallet::pallet]
   |               ^^^^^^ the trait `parity_scale_codec::MaxEncodedLen` is not implemented for `<T as pallet::Config>::RelayChainAccountId`
   |

   = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageMap<_GeneratedPrefixForStorageClaimedRelayChainIds<T>, frame_support::Blake2_128Concat, <T as pallet::Config>::RelayChainAccountId, ()>`

error[E0277]: the trait bound `<T as pallet::Config>::VestingBlockNumber: parity_scale_codec::MaxEncodedLen` is not satisfied
  --> pallets/crowdloan-rewards/src/lib.rs:36:12
   |
36 |     #[pallet::pallet]
   |               ^^^^^^ the trait `parity_scale_codec::MaxEncodedLen` is not implemented for `<T as pallet::Config>::VestingBlockNumber`
   |
   = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageInitVestingBlock<T>, <T as pallet::Config>::VestingBlockNumber, frame_support::pallet_prelude::ValueQuery>`

It seems those three errors are related to the MaxEncodedLen...

I am using polkadot-v0.9.17 substrate. Please advise. Thanks

2
  • 1
    There are multiple such questions, please search first. TLDR; as quick fix put #[pallet::without_storage_info] under the #[pallet::pallet]. Mar 28, 2022 at 9:58
  • That solves it. Thank you
    – Russo
    Mar 28, 2022 at 14:09

1 Answer 1

2

pub contributed_relay_addresses: Vec<T::RelayChainAccountId>,

  • If you replace the Vec with a BoundedVec it won't complain.

You would want something like this instead:

pub contributed_relay_addresses: BoundedVec<T::RelayChainAccountId, ConstU32<100>>,

See How to use bounded vector for storage

You can read more about bounded vec here: When to use `BoundedVec` vs. `WeakBoundedVec` vs. `Vec`?

2
  • May i know the difference between your answer and adding #[pallet::without_storage_info] under the #[pallet::pallet] ?
    – Russo
    Mar 28, 2022 at 14:16
  • 1
    without_storage_info changes the pallet-wide default to allow unbounded state. Generally you want your state to be bounded. You can opt out just one storage item using #[pallet::unbounded]. FYI: I am just updating the docs on this: github.com/substrate-developer-hub/substrate-docs/pull/925/…
    – Squirrel
    Mar 28, 2022 at 15:52

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.