1

How to declare the type for following data structure?

A product can have many candidates and each candidate has a stake. But same candidate can remain in more than one product with different stakes. I also need to query stake from a candidate id, and candidate ids from product id.

    #[pallet::storage]
    #[pallet::getter(fn governor_group)]
    pub type ProductId<T> = StorageMap<_, Blake2_128Concat, ProductId, Vec<CandidateId>>; 

    #[pallet::storage]
    #[pallet::getter(fn candidate_nominee)]
    pub type Stakes<T> = StorageMap<_, Blake2_128Concat, CandidateId, Stake>;

In the above code each candidate can have only one stake.

Nested storage map are not allowed in substrate like:

    #[pallet::storage]
    #[pallet::getter(fn governor_group)]
    pub type ProductId<T> = StorageMap<_, Blake2_128Concat, ProductId, Stakes>; 
Amiya Behera
  • 2,210
  • 19
  • 32

1 Answers1

1

I think you are looking for a StorageDoubleMap.

This allows you to have:

Key -> Key -> Value

So that would look like:

#[pallet::storage]
#[pallet::getter(fn governor_group)]
pub type ProductId<T> = StorageMap<
    _,
    Blake2_128Concat,
    ProductId,
    Blake2_128Concat,
    CandidateId,
    Stakes,
>;

You may need to introduce other maps which clarify sub-context of this double map, or create some data structures which hold the information you are looking for.

Note that we support an arbitrary nesting of maps with StorageNMap, which just extends this concept further and further.

Shawn Tabrizi
  • 12,206
  • 1
  • 38
  • 69
  • But I want the number (length) of candidateids (key2) for the productid (key1), how can I get that? Any function? – Amiya Behera Nov 08 '21 at 13:46
  • Also I will be needing two keys to fetch the value, how to fetch all the candidateIds and stakes for a productId? – Amiya Behera Nov 08 '21 at 13:59
  • Got it, there is a function called iter_key_prefix. Thanks. https://crates.parity.io/frame_support/pallet_prelude/struct.StorageDoubleMap.html#method.iter_key_prefix – Amiya Behera Nov 08 '21 at 14:12
  • Your first question, you will need to keep track of the length of the map in a separate storage value. It is not a good idea to fetch everything at once in the runtime, it will be a very expensive storage read operation, and can be very bad for your chain. If you need all the data you should be using a vec with limited size. If this answered your question, please mark it as answered. – Shawn Tabrizi Nov 09 '21 at 13:30