substratepolkadot

What is the use of ValueQuery in FRAME2 storage?


FRAME2 storage get defined using following syntax:

#[pallet::storage]
type SomePrivateValue<T> = StorageValue<_, u32, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn some_primitive_value)]
pub(super) type SomePrimitiveValue<T> = StorageValue<_, u32, ValueQuery>;

But storage works without ValueQuery keyword.

e.g.

#[pallet::storage]
type SomePrivateValue<T> = StorageValue<_, u32>;

What is the use of ValueQuery?

Similarly setting default value requires ValueStorage, and getter function is not allowed with ValueStorage. How can I have getter function with setting default value?

https://substrate.dev/docs/en/knowledgebase/runtime/storage#default-values


Solution

  • EDIT: docs are now hosted at https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/index.html

    The formal documenation of StorageValue can be found here https://paritytech.github.io/substrate/monthly-2021-09+1/frame_support/storage/types/struct.StorageValue.html

    There you can see that the third generic QueryKind is by default the type OptionQuery, when you don't provide a specific type, then OptionQuery is used.

    In the method implementation of the type StorageValue you can see it requires some bounds on the generics https://paritytech.github.io/substrate/monthly-2021-09+1/frame_support/storage/types/struct.StorageValue.html#impl

    Especially it requires QueryKind: QueryKindTrait<Value, OnEmpty>, This means QueryKind must implement how the value is queried from storage.

    There is currently 2 implementors: OptionQuery and ValueQuery: https://paritytech.github.io/substrate/monthly-2021-09+1/frame_support/storage/types/trait.QueryKindTrait.html#implementors

    OptionQuery implement the trait in a way that returns None when no value is found in the storage. ValueQuery implement the trait in a way that returns some on empty value (configured by the generic OnEmpty) when no value is found in the storage.

    So you would use either ValueQuery when you want to get some "default" value when you try to get some value from storage and there is no value, and OptionQuery when you want to get None, when you try to get some value from storage and there is no value.

    The consequences are visible in the signature of the method: the method get will return either a value or an option: https://paritytech.github.io/substrate/monthly-2021-09+1/frame_support/storage/types/struct.StorageValue.html#method.get