1

I have substrate pallet structure as follows

                    #[derive(
                        Encode, Decode, CloneNoBound, PartialEqNoBound, Eq, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen,
                    )]
                    #[scale_info(skip_type_params(MetadataSize))]
                    #[codec(mel_bound(AccountId: MaxEncodedLen, BlockNumber: MaxEncodedLen))]
                    pub struct DataLog<AccountId, BlockNumber, MetadataSize>
                    where
                        AccountId: Clone + PartialEq + Debug,
                        BlockNumber: Clone + PartialEq + Debug + PartialOrd,
                        MetadataSize: Get<u32>,
                    {
                        pub account_id: Option<AccountId>,

                        pub status: u32,

                        pub block_number: Option<BlockNumber>,

                        pub remarks: Option<BoundedVec<u8, MetadataSize>>,
                    }


                    #[pallet::storage]
                    #[pallet::getter(fn get_tracer)]
                    pub(super) type Tracer<T: Config> = StorageMap<
                        _,
                        Blake2_128Concat,
                        BoundedVec<u8, T::MAX_T_SIZE>,
                        BoundedVec<
                            DataLog<T::AccountId, T::BlockNumber, T::MetadataSize>,
                            T::MetadataSize,
                        >,
                    >;

                    Im trying to push a value for a  vec if exists

                    let block_number = <frame_system::Module<T>>::block_number();
                    let mut dd_log = DataLog {
                        account_id,
                        block_number: Some(block_number),
                        status,
                        remarks,
                    };

                    if Tracer::<T>::contains_key(&key) {
                        Tracer::<T>::mutate(key.clone(), |vc| match vc {
                            | None => return Err(Error::<T>::DIDDoesNotExist),
                            | Some(vc) => {
                                vc.push(dd_log.clone());
                                Ok(())
                            },
                        })?;
                    }

Im getting the following error:

466 |                     vc.push(dd_log);
    |                     ^^^^^^^^^^^^^^^ cannot borrow as mutable
    |
    = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `frame_support::BoundedVec<types::DataLog<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::BlockNumber, <T as pallet::Config>::MetadataSize>, <T as pallet::Config>::MetadataSize>`

How to fix this issue?

1 Answer 1

1

The idea behind BoundedVec is to have a vector that is ensuring that the maximum size is not exceeded. Basically it is just a wrapper around Vec, but most of the methods are prefixed with try_. The reason for the naming is that these methods are checking that the maximum size isn't exceeded and if that would happen, an error is returned.

To solve your issue, you need to call:

vc.try_push(dd_log.clone());

But as try_push is returning a Result, you still need to handle the result as this would mean that pushing to the vector was rejected because there are too many items in it.

You can find here all methods supported by BoundedVec.

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.