5

Here is a simple edit of the pallet/template/lib.rs that uses Vec<u8> in storage:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    #[pallet::config]
    pub trait Config: frame_system::Config {
        type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
    }

    #[pallet::pallet]
    #[pallet::generate_store(pub(super) trait Store)]
    pub struct Pallet<T>(_);

    #[pallet::storage]
    #[pallet::getter(fn something)]
    pub(super) type Something<T: Config> = StorageMap<
        _,
        Twox64Concat,
        T::AccountId,
        Vec<u8>,
        ValueQuery,
    >;

    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        SomethingStored(Vec<u8>, T::AccountId),
    }

    #[pallet::error]
    pub enum Error<T> {
        NoneValue,
        StorageOverflow,
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
        pub fn do_something(origin: OriginFor<T>, something: Vec<u8>) -> DispatchResult {
            let who = ensure_signed(origin)?;
            <Something<T>>::insert(&who, &something);
            Self::deposit_event(Event::SomethingStored(something, who));
            Ok(())
        }
    }
}

Using it with the current substrate-node-template is not compiling due to the following error:

error[E0277]: the trait bound `Vec<u8>: MaxEncodedLen` is not satisfied
  --> pallets/template/src/lib.rs:15:12
   |
15 |     #[pallet::pallet]
   |               ^^^^^^ the trait `MaxEncodedLen` is not implemented for `Vec<u8>`
   |
   = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageMap<_GeneratedPrefixForStorageSomething<T>, frame_support::Twox64Concat, <T as frame_system::Config>::AccountId, Vec<u8>, frame_support::pallet_prelude::ValueQuery>`

I can compile it using a previous version of the substrate-node-template or using the BoundedVec<u8, T::MaxLength>, but is there a way to keep using the Vec<u8>?

1 Answer 1

10

MaxEncodedLen is all about setting an upper limit to the size of a storage item.

In the case of Vec<u8>, there is no limit to the size of this storage, since Vectors in Rust do not have such limits (besides fitting in usize).

Thus, if you want to satisfy MaxEncodedLen, you must use a BoundedVec, and appropriate length limits.

If you want to keep your storage unbounded, you can include #[pallet::without_storage_info].

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);

This is okay for a solo-chain, but will be incompatible for Parachains since you need to know limits here in order to limit the PoV size.

6
  • 1
    Thanks Shawn, it makes sense. So I think we need to update: docs.substrate.io/tutorials/v3/proof-of-existence/…, right? Will try to do it and open a PR there. Feb 28 at 21:27
  • Yes, will do. Thanks.
    – Shawn Tabrizi
    Feb 28 at 21:28
  • The same issue arises in the kitties tutorial, and it's not with a vec, but with a struct. I'm not sure how to solve it there, except using #[pallet::without_storage_info] — which is definitely only a temporary solution. Mar 6 at 18:21
  • @IlyaS fixed things up here: github.com/substrate-developer-hub/substrate-docs/commit/…
    – Shawn Tabrizi
    Mar 6 at 19:51
  • I am rewriting my code with BoundedVec in structs that are used for storage. While I got an error complaining the trait Clone is not implemented for the constant that represents the max length of my BoundedVec. It's a runtime config constant of Get<u32>, and we may consider expanding the S in BoundedVec<T, S> to make it more flexible in this situation.
    – Han
    Aug 2 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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