2

I'm working with a StorageMap and want to return a dynamic default value based on the queried key when the key isn't found. Here's my attempt:

#[pallet::storage]
#[pallet::getter(fn asset)]
pub(super) type Asset<T: Config> =
    StorageMap<_, Blake2_128Concat, U256, T::AccountId, ValueQuery, GetDefault<T::AccountId>>;

pub struct GetDefault<T>(sp_std::marker::PhantomData<T>);

impl<AccountId> Get<AccountId> for GetDefault<AccountId> {
    fn get() -> AccountId {
        // logic to derive dynamic default value based on asset_id
    }
}

Is there a way to achieve this?

1 Answer 1

2

The FRAME syntax does not allow for this directly since the key is not passed to the Get default impl.

One way to achieve this would be to use an OptionQuery and create a custom getter function like this:

#[pallet::storage]
pub(super) type Asset<T: Config> =
    StorageMap<_, Blake2_128Concat, U256, T::AccountId, OptionQuery>;

fn asset<T: Config>(key: U256) -> <T as frame_system::Config>::AccountId {
    Asset::<T>::get(key).unwrap_or_else(|| {
        todo!("Custom default logic goes here")
    })
}

This replaces the auto-generated asset getter that you formerly created with
#[pallet::getter(fn asset)] and offers a custom default per key.

2
  • Thank you for the suggestion @Oliver Tale-Yazdi. Despite integrating the code you provided, I'm still unable to invoke it from the pallet function using the line: let result = Asset::<T>::get(asset_id).ok_or(Error::<T>::UnexistentAsset)?;. Instead of the expected default value, I receive the error.
    – magecnion
    Commented Aug 21, 2023 at 15:21
  • 1
    Well, you use the getter function now instead of the map: asset::<T>(asset_id). Commented Aug 21, 2023 at 15:50

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