2

Is it possible to get the set of keys from a Storage Map on Substrate. It doesn’t seem like Substrate exposes a method to do so: https://docs.substrate.io/rustdocs/latest/frame_support/storage/trait.StorageMap.html#required-methods.

1 Answer 1

6

The FRAME StorageMap also implements IterableStorageMap which allows you to iterate over the keys and/or values of the map:

pub trait IterableStorageMap<K: FullEncode, V: FullCodec>: StorageMap<K, V> {
    type Iterator: Iterator<Item = (K, V)>;
    type KeyIterator: Iterator<Item = K>;
    fn iter() -> Self::Iterator;
    fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator;
    fn iter_keys() -> Self::KeyIterator;
    fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator;
    fn drain() -> Self::Iterator;
    fn translate<O: Decode, F: FnMut(K, O) -> Option<V>>(f: F);
}

However, you should probably never use this in your runtime in an unbounded way. Iterating over the N keys of your storage map would require N database reads, which can be extremely expensive for your runtime weight.

Instead you should use something like fn iter_keys_from where you can pick a specific key to start iterating from, and control how many keys you iterate in a single call.

1
  • If I use fn iter_keys_from for a non-dynamic StorageMap this seems great. But if I add additional keys, then I can't be sure that I miss some keys which were inserted before iter_keys_from(starting_raw_key), right? Example, where assert fails: github.com/zeitgeistpm/zeitgeist/blob/…
    – Chralt
    Mar 17, 2023 at 8:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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