// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Stuff to do with the runtime's storage. use crate::{ hash::{ReversibleStorageHasher, StorageHasher}, storage::types::{ EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, KeyGenerator, ReversibleKeyGenerator, TupleToEncodedIter, }, }; use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode}; use sp_core::storage::ChildInfo; use sp_runtime::generic::{Digest, DigestItem}; use sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}; pub use self::{ stream_iter::StorageStreamIter, transactional::{ in_storage_layer, with_storage_layer, with_transaction, with_transaction_unchecked, }, types::StorageEntryMetadataBuilder, }; pub use sp_runtime::TransactionOutcome; pub use types::Key; pub mod bounded_btree_map; pub mod bounded_btree_set; pub mod bounded_vec; pub mod child; #[doc(hidden)] pub mod generator; pub mod hashed; pub mod migration; pub mod storage_noop_guard; mod stream_iter; pub mod transactional; pub mod types; pub mod unhashed; pub mod weak_bounded_vec; /// Utility type for converting a storage map into a `Get` impl which returns the maximum /// key size. pub struct KeyLenOf(PhantomData); /// A trait for working with macro-generated storage values under the substrate storage API. /// /// Details on implementation can be found at [`generator::StorageValue`]. pub trait StorageValue { /// The type that get/take return. type Query; /// Get the storage key. fn hashed_key() -> [u8; 32]; /// Does the value (explicitly) exist in storage? fn exists() -> bool; /// Load the value from the provided storage instance. fn get() -> Self::Query; /// Try to get the underlying value from the provided storage instance. /// /// Returns `Ok` if it exists, `Err` if not. fn try_get() -> Result; /// Translate a value from some previous type (`O`) to the current type. /// /// `f: F` is the translation function. /// /// Returns `Err` if the storage item could not be interpreted as the old type, and Ok, along /// with the new value if it could. /// /// NOTE: This operates from and to `Option<_>` types; no effort is made to respect the default /// value of the original type. /// /// # Warning /// /// This function must be used with care, before being updated the storage still contains the /// old type, thus other calls (such as `get`) will fail at decoding it. /// /// # Usage /// /// This would typically be called inside the module implementation of on_runtime_upgrade, while /// ensuring **no usage of this storage are made before the call to `on_runtime_upgrade`**. /// (More precisely prior initialized modules doesn't make use of this storage). fn translate) -> Option>(f: F) -> Result, ()>; /// Store a value under this key into the provided storage instance. fn put>(val: Arg); /// Store a value under this key into the provided storage instance; this uses the query /// type rather than the underlying value. fn set(val: Self::Query); /// Mutate the value fn mutate R>(f: F) -> R; /// Mutate the value under a key if the value already exists. Do nothing and return the default /// value if not. fn mutate_extant R>(f: F) -> R { Self::mutate_exists(|maybe_v| match maybe_v { Some(ref mut value) => f(value), None => R::default(), }) } /// Mutate the value if closure returns `Ok` fn try_mutate Result>(f: F) -> Result; /// Mutate the value. Deletes the item if mutated to a `None`. fn mutate_exists) -> R>(f: F) -> R; /// Mutate the value if closure returns `Ok`. Deletes the item if mutated to a `None`. fn try_mutate_exists) -> Result>(f: F) -> Result; /// Clear the storage value. fn kill(); /// Take a value from storage, removing it afterwards. fn take() -> Self::Query; /// Append the given item to the value in the storage. /// /// `T` is required to implement [`StorageAppend`]. /// /// # Warning /// /// If the storage item is not encoded properly, the storage item will be overwritten /// and set to `[item]`. Any default value set for the storage item will be ignored /// on overwrite. fn append(item: EncodeLikeItem) where Item: Encode, EncodeLikeItem: EncodeLike, T: StorageAppend; /// Read the length of the storage value without decoding the entire value. /// /// `T` is required to implement [`StorageDecodeLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. fn decode_len() -> Option where T: StorageDecodeLength, { T::decode_len(&Self::hashed_key()) } /// Read the length of the storage value without decoding the entire value. /// /// `T` is required to implement [`StorageDecodeNonDedupLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// - The value returned is the non-deduplicated length of the underlying Vector in storage.This /// means that any duplicate items are included. /// /// - `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. /// /// # Example #[doc = docify::embed!("src/storage/mod.rs", btree_set_decode_non_dedup_len)] /// This demonstrates how `decode_non_dedup_len` will count even the duplicate values in the /// storage (in this case, the number `4` is counted twice). fn decode_non_dedup_len() -> Option where T: StorageDecodeNonDedupLength, { T::decode_non_dedup_len(&Self::hashed_key()) } } /// A non-continuous container type. pub trait StorageList { /// Iterator for normal and draining iteration. type Iterator: Iterator; /// Append iterator for fast append operations. type Appender: StorageAppender; /// List the elements in append order. fn iter() -> Self::Iterator; /// Drain the elements in append order. /// /// Note that this drains a value as soon as it is being inspected. For example `take_while(|_| /// false)` still drains the first element. This also applies to `peek()`. fn drain() -> Self::Iterator; /// A fast append iterator. fn appender() -> Self::Appender; /// Append a single element. /// /// Should not be called repeatedly; use `append_many` instead. /// Worst case linear `O(len)` with `len` being the number if elements in the list. fn append_one(item: EncodeLikeValue) where EncodeLikeValue: EncodeLike, { Self::append_many(core::iter::once(item)); } /// Append many elements. /// /// Should not be called repeatedly; use `appender` instead. /// Worst case linear `O(len + items.count())` with `len` beings the number if elements in the /// list. fn append_many(items: I) where EncodeLikeValue: EncodeLike, I: IntoIterator, { let mut ap = Self::appender(); ap.append_many(items); } } /// Append iterator to append values to a storage struct. /// /// Can be used in situations where appending does not have constant time complexity. pub trait StorageAppender { /// Append a single item in constant time `O(1)`. fn append(&mut self, item: EncodeLikeValue) where EncodeLikeValue: EncodeLike; /// Append many items in linear time `O(items.count())`. // Note: a default impl is provided since `Self` is already assumed to be optimal for single // append operations. fn append_many(&mut self, items: I) where EncodeLikeValue: EncodeLike, I: IntoIterator, { for item in items.into_iter() { self.append(item); } } } /// A strongly-typed map in storage. /// /// Details on implementation can be found at [`generator::StorageMap`]. pub trait StorageMap { /// The type that get/take return. type Query; /// Get the storage key used to fetch a value corresponding to a specific key. fn hashed_key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? fn contains_key>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; /// Store or remove the value to be associated with `key` so that `get` returns the `query`. fn set>(key: KeyArg, query: Self::Query); /// Try to get the value for the given key from the map. /// /// Returns `Ok` if it exists, `Err` if not. fn try_get>(key: KeyArg) -> Result; /// Swap the values of two keys. fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); /// Store a value to be associated with the given key from the map. fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg); /// Remove the value under a key. fn remove>(key: KeyArg); /// Mutate the value under a key. fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; /// Mutate the item, only if an `Ok` value is returned. fn try_mutate, R, E, F: FnOnce(&mut Self::Query) -> Result>( key: KeyArg, f: F, ) -> Result; /// Mutate the value under a key if the value already exists. Do nothing and return the default /// value if not. fn mutate_extant, R: Default, F: FnOnce(&mut V) -> R>( key: KeyArg, f: F, ) -> R { Self::mutate_exists(key, |maybe_v| match maybe_v { Some(ref mut value) => f(value), None => R::default(), }) } /// Mutate the value under a key. /// /// Deletes the item if mutated to a `None`. fn mutate_exists, R, F: FnOnce(&mut Option) -> R>( key: KeyArg, f: F, ) -> R; /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. /// `f` will always be called with an option representing if the storage item exists (`Some`) /// or if the storage item does not exist (`None`), independent of the `QueryType`. fn try_mutate_exists, R, E, F: FnOnce(&mut Option) -> Result>( key: KeyArg, f: F, ) -> Result; /// Take the value under a key. fn take>(key: KeyArg) -> Self::Query; /// Append the given items to the value in the storage. /// /// `V` is required to implement `codec::EncodeAppend`. /// /// # Warning /// /// If the storage item is not encoded properly, the storage will be overwritten /// and set to `[item]`. Any default value set for the storage item will be ignored /// on overwrite. fn append(key: EncodeLikeKey, item: EncodeLikeItem) where EncodeLikeKey: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: StorageAppend; /// Read the length of the storage value without decoding the entire value under the /// given `key`. /// /// `V` is required to implement [`StorageDecodeLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. fn decode_len>(key: KeyArg) -> Option where V: StorageDecodeLength, { V::decode_len(&Self::hashed_key_for(key)) } /// Read the length of the storage value without decoding the entire value. /// /// `V` is required to implement [`StorageDecodeNonDedupLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// - `None` does not mean that `get()` does not return a value. The default value is /// completely /// ignored by this function. /// /// - The value returned is the non-deduplicated length of the underlying Vector in storage.This /// means that any duplicate items are included. fn decode_non_dedup_len>(key: KeyArg) -> Option where V: StorageDecodeNonDedupLength, { V::decode_non_dedup_len(&Self::hashed_key_for(key)) } /// Migrate an item with the given `key` from a defunct `OldHasher` to the current hasher. /// /// If the key doesn't exist, then it's a no-op. If it does, then it returns its value. fn migrate_key>(key: KeyArg) -> Option; /// Migrate an item with the given `key` from a `blake2_256` hasher to the current hasher. /// /// If the key doesn't exist, then it's a no-op. If it does, then it returns its value. fn migrate_key_from_blake>(key: KeyArg) -> Option { Self::migrate_key::(key) } } /// A strongly-typed map in storage whose keys and values can be iterated over. pub trait IterableStorageMap: StorageMap { /// The type that iterates over all `(key, value)`. type Iterator: Iterator; /// The type that iterates over all `key`s. type KeyIterator: Iterator; /// Enumerate all elements in the map in lexicographical order of the encoded key. If you /// alter the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical /// order of the encoded key. If you alter the map while doing this, you'll get undefined /// results. fn iter_from(starting_raw_key: Vec) -> Self::Iterator; /// Enumerate all keys in the map in lexicographical order of the encoded key, skipping over /// the elements. If you alter the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; /// Enumerate all keys in the map after a specified `starting_raw_key` in lexicographical order /// of the encoded key. If you alter the map while doing this, you'll get undefined results. fn iter_keys_from(starting_raw_key: Vec) -> Self::KeyIterator; /// Remove all elements from the map and iterate through them in lexicographical order of the /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; /// Translate the values of all elements by a function `f`, in the map in lexicographical order /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. fn translate Option>(f: F); /// Translate the next entry following `previous_key` by a function `f`. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// Returns the next key to iterate from in lexicographical order of the encoded key. fn translate_next Option>( previous_key: Option>, f: F, ) -> Option>; } /// A strongly-typed double map in storage whose secondary keys and values can be iterated over. pub trait IterableStorageDoubleMap: StorageDoubleMap { /// The type that iterates over all `key2`. type PartialKeyIterator: Iterator; /// The type that iterates over all `(key2, value)`. type PrefixIterator: Iterator; /// The type that iterates over all `(key1, key2)`. type FullKeyIterator: Iterator; /// The type that iterates over all `(key1, key2, value)`. type Iterator: Iterator; /// Enumerate all elements in the map with first key `k1` in lexicographical order of the /// encoded key. If you add or remove values whose first key is `k1` to the map while doing /// this, you'll get undefined results. fn iter_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; /// Enumerate all elements in the map with first key `k1` after a specified `starting_raw_key` /// in lexicographical order of the encoded key. If you add or remove values whose first key is /// `k1` to the map while doing this, you'll get undefined results. fn iter_prefix_from(k1: impl EncodeLike, starting_raw_key: Vec) -> Self::PrefixIterator; /// Enumerate all second keys `k2` in the map with the same first key `k1` in lexicographical /// order of the encoded key. If you add or remove values whose first key is `k1` to the map /// while doing this, you'll get undefined results. fn iter_key_prefix(k1: impl EncodeLike) -> Self::PartialKeyIterator; /// Enumerate all second keys `k2` in the map with the same first key `k1` after a specified /// `starting_raw_key` in lexicographical order of the encoded key. If you add or remove values /// whose first key is `k1` to the map while doing this, you'll get undefined results. fn iter_key_prefix_from( k1: impl EncodeLike, starting_raw_key: Vec, ) -> Self::PartialKeyIterator; /// Remove all elements from the map with first key `k1` and iterate through them in /// lexicographical order of the encoded key. If you add elements with first key `k1` to the /// map while doing this, you'll get undefined results. fn drain_prefix(k1: impl EncodeLike) -> Self::PrefixIterator; /// Enumerate all elements in the map in lexicographical order of the encoded key. If you add /// or remove values to the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical /// order of the encoded key. If you add or remove values to the map while doing this, you'll /// get undefined results. fn iter_from(starting_raw_key: Vec) -> Self::Iterator; /// Enumerate all keys `k1` and `k2` in the map in lexicographical order of the encoded key. If /// you add or remove values to the map while doing this, you'll get undefined results. fn iter_keys() -> Self::FullKeyIterator; /// Enumerate all keys `k1` and `k2` in the map after a specified `starting_raw_key` in /// lexicographical order of the encoded key. If you add or remove values to the map while /// doing this, you'll get undefined results. fn iter_keys_from(starting_raw_key: Vec) -> Self::FullKeyIterator; /// Remove all elements from the map and iterate through them in lexicographical order of the /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; /// Translate the values of all elements by a function `f`, in the map in lexicographical order /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. fn translate Option>(f: F); } /// A strongly-typed map with arbitrary number of keys in storage whose keys and values can be /// iterated over. pub trait IterableStorageNMap: StorageNMap { /// The type that iterates over all `(key1, key2, key3, ... keyN)` tuples. type KeyIterator: Iterator; /// The type that iterates over all `(key1, key2, key3, ... keyN), value)` tuples. type Iterator: Iterator; /// Enumerate all elements in the map with prefix key `kp` in lexicographical order of the /// encoded key. If you add or remove values whose prefix is `kp` to the map while doing this, /// you'll get undefined results. fn iter_prefix(kp: KP) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; /// Enumerate all elements in the map with prefix key `kp` after a specified `starting_raw_key` /// in lexicographical order of the encoded key. If you add or remove values whose prefix is /// `kp` to the map while doing this, you'll get undefined results. fn iter_prefix_from( kp: KP, starting_raw_key: Vec, ) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; /// Enumerate all suffix keys in the map with prefix key `kp` in lexicographical order of the /// encoded key. If you add or remove values whose prefix is `kp` to the map while doing this, /// you'll get undefined results. fn iter_key_prefix(kp: KP) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; /// Enumerate all suffix keys in the map with prefix key `kp` after a specified /// `starting_raw_key` in lexicographical order of the encoded key. If you add or remove values /// whose prefix is `kp` to the map while doing this, you'll get undefined results. fn iter_key_prefix_from( kp: KP, starting_raw_key: Vec, ) -> KeyPrefixIterator<>::Suffix> where K: HasReversibleKeyPrefix; /// Remove all elements from the map with prefix key `kp` and iterate through them in /// lexicographical order of the encoded key. If you add elements with prefix key `kp` to the /// map while doing this, you'll get undefined results. fn drain_prefix(kp: KP) -> PrefixIterator<(>::Suffix, V)> where K: HasReversibleKeyPrefix; /// Enumerate all elements in the map in lexicographical order of the encoded key. If you add /// or remove values to the map while doing this, you'll get undefined results. fn iter() -> Self::Iterator; /// Enumerate all elements in the map after a specified `starting_raw_key` in lexicographical /// order of the encoded key. If you add or remove values to the map while doing this, you'll /// get undefined results. fn iter_from(starting_raw_key: Vec) -> Self::Iterator; /// Enumerate all keys in the map in lexicographical order of the encoded key. If you add or /// remove values to the map while doing this, you'll get undefined results. fn iter_keys() -> Self::KeyIterator; /// Enumerate all keys in the map after `starting_raw_key` in lexicographical order of the /// encoded key. If you add or remove values to the map while doing this, you'll get undefined /// results. fn iter_keys_from(starting_raw_key: Vec) -> Self::KeyIterator; /// Remove all elements from the map and iterate through them in lexicographical order of the /// encoded key. If you add elements to the map while doing this, you'll get undefined results. fn drain() -> Self::Iterator; /// Translate the values of all elements by a function `f`, in the map in lexicographical order /// of the encoded key. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. fn translate Option>(f: F); } /// An implementation of a map with a two keys. /// /// Details on implementation can be found at [`generator::StorageDoubleMap`]. pub trait StorageDoubleMap { /// The type that get/take returns. type Query; /// Get the storage key used to fetch a value corresponding to a specific key. fn hashed_key_for(k1: KArg1, k2: KArg2) -> Vec where KArg1: EncodeLike, KArg2: EncodeLike; /// Does the value (explicitly) exist in storage? fn contains_key(k1: KArg1, k2: KArg2) -> bool where KArg1: EncodeLike, KArg2: EncodeLike; /// Load the value associated with the given key from the double map. fn get(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, KArg2: EncodeLike; /// Try to get the value for the given key from the double map. /// /// Returns `Ok` if it exists, `Err` if not. fn try_get(k1: KArg1, k2: KArg2) -> Result where KArg1: EncodeLike, KArg2: EncodeLike; /// Store or remove the value to be associated with `key` so that `get` returns the `query`. fn set, KArg2: EncodeLike>(k1: KArg1, k2: KArg2, query: Self::Query); /// Take a value from storage, removing it afterwards. fn take(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, KArg2: EncodeLike; /// Swap the values of two key-pairs. fn swap(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2) where XKArg1: EncodeLike, XKArg2: EncodeLike, YKArg1: EncodeLike, YKArg2: EncodeLike; /// Store a value to be associated with the given keys from the double map. fn insert(k1: KArg1, k2: KArg2, val: VArg) where KArg1: EncodeLike, KArg2: EncodeLike, VArg: EncodeLike; /// Remove the value under the given keys. fn remove(k1: KArg1, k2: KArg2) where KArg1: EncodeLike, KArg2: EncodeLike; /// Remove all values under the first key `k1` in the overlay and up to `limit` in the /// backend. /// /// All values in the client overlay will be deleted, if there is some `limit` then up to /// `limit` values are deleted from the client backend, if `limit` is none then all values in /// the client backend are deleted. /// /// # Note /// /// Calling this multiple times per block with a `limit` set leads always to the same keys being /// removed and the same result being returned. This happens because the keys to delete in the /// overlay are not taken into account when deleting keys in the backend. #[deprecated = "Use `clear_prefix` instead"] fn remove_prefix(k1: KArg1, limit: Option) -> sp_io::KillStorageResult where KArg1: ?Sized + EncodeLike; /// Remove all values under the first key `k1` in the overlay and up to `maybe_limit` in the /// backend. /// /// All values in the client overlay will be deleted, if `maybe_limit` is `Some` then up to /// that number of values are deleted from the client backend, otherwise all values in the /// client backend are deleted. /// /// ## Cursors /// /// The `maybe_cursor` parameter should be `None` for the first call to initial removal. /// If the resultant `maybe_cursor` is `Some`, then another call is required to complete the /// removal operation. This value must be passed in as the subsequent call's `maybe_cursor` /// parameter. If the resultant `maybe_cursor` is `None`, then the operation is complete and no /// items remain in storage provided that no items were added between the first calls and the /// final call. fn clear_prefix( k1: KArg1, limit: u32, maybe_cursor: Option<&[u8]>, ) -> sp_io::MultiRemovalResults where KArg1: ?Sized + EncodeLike; /// Does any value under the first key `k1` (explicitly) exist in storage? /// Might have unexpected behaviour with empty keys, e.g. `[]`. fn contains_prefix(k1: KArg1) -> bool where KArg1: EncodeLike; /// Iterate over values that share the first key. fn iter_prefix_values(k1: KArg1) -> PrefixIterator where KArg1: ?Sized + EncodeLike; /// Mutate the value under the given keys. fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R; /// Mutate the value under the given keys when the closure returns `Ok`. fn try_mutate(k1: KArg1, k2: KArg2, f: F) -> Result where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> Result; /// Mutate the value under the given keys. Deletes the item if mutated to a `None`. fn mutate_exists(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Option) -> R; /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. /// `f` will always be called with an option representing if the storage item exists (`Some`) /// or if the storage item does not exist (`None`), independent of the `QueryType`. fn try_mutate_exists(k1: KArg1, k2: KArg2, f: F) -> Result where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Option) -> Result; /// Append the given item to the value in the storage. /// /// `V` is required to implement [`StorageAppend`]. /// /// # Warning /// /// If the storage item is not encoded properly, the storage will be overwritten /// and set to `[item]`. Any default value set for the storage item will be ignored /// on overwrite. fn append(k1: KArg1, k2: KArg2, item: EncodeLikeItem) where KArg1: EncodeLike, KArg2: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: StorageAppend; /// Read the length of the storage value without decoding the entire value under the /// given `key1` and `key2`. /// /// `V` is required to implement [`StorageDecodeLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. fn decode_len(key1: KArg1, key2: KArg2) -> Option where KArg1: EncodeLike, KArg2: EncodeLike, V: StorageDecodeLength, { V::decode_len(&Self::hashed_key_for(key1, key2)) } /// Read the length of the storage value without decoding the entire value under the /// given `key1` and `key2`. /// /// `V` is required to implement [`StorageDecodeNonDedupLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. fn decode_non_dedup_len(key1: KArg1, key2: KArg2) -> Option where KArg1: EncodeLike, KArg2: EncodeLike, V: StorageDecodeNonDedupLength, { V::decode_non_dedup_len(&Self::hashed_key_for(key1, key2)) } /// Migrate an item with the given `key1` and `key2` from defunct `OldHasher1` and /// `OldHasher2` to the current hashers. /// /// If the key doesn't exist, then it's a no-op. If it does, then it returns its value. fn migrate_keys< OldHasher1: StorageHasher, OldHasher2: StorageHasher, KeyArg1: EncodeLike, KeyArg2: EncodeLike, >( key1: KeyArg1, key2: KeyArg2, ) -> Option; } /// An implementation of a map with an arbitrary number of keys. /// /// Details of implementation can be found at [`generator::StorageNMap`]. pub trait StorageNMap { /// The type that get/take returns. type Query; /// Get the storage key used to fetch a value corresponding to a specific key. fn hashed_key_for + TupleToEncodedIter>(key: KArg) -> Vec; /// Does the value (explicitly) exist in storage? fn contains_key + TupleToEncodedIter>(key: KArg) -> bool; /// Load the value associated with the given key from the map. fn get + TupleToEncodedIter>(key: KArg) -> Self::Query; /// Try to get the value for the given key from the map. /// /// Returns `Ok` if it exists, `Err` if not. fn try_get + TupleToEncodedIter>(key: KArg) -> Result; /// Store or remove the value to be associated with `key` so that `get` returns the `query`. fn set + TupleToEncodedIter>(key: KArg, query: Self::Query); /// Swap the values of two keys. fn swap(key1: KArg1, key2: KArg2) where KOther: KeyGenerator, KArg1: EncodeLikeTuple + TupleToEncodedIter, KArg2: EncodeLikeTuple + TupleToEncodedIter; /// Store a value to be associated with the given key from the map. fn insert(key: KArg, val: VArg) where KArg: EncodeLikeTuple + TupleToEncodedIter, VArg: EncodeLike; /// Remove the value under a key. fn remove + TupleToEncodedIter>(key: KArg); /// Remove all values starting with `partial_key` in the overlay and up to `limit` in the /// backend. /// /// All values in the client overlay will be deleted, if there is some `limit` then up to /// `limit` values are deleted from the client backend, if `limit` is none then all values in /// the client backend are deleted. /// /// # Note /// /// Calling this multiple times per block with a `limit` set leads always to the same keys being /// removed and the same result being returned. This happens because the keys to delete in the /// overlay are not taken into account when deleting keys in the backend. #[deprecated = "Use `clear_prefix` instead"] fn remove_prefix(partial_key: KP, limit: Option) -> sp_io::KillStorageResult where K: HasKeyPrefix; /// Attempt to remove items from the map matching a `partial_key` prefix. /// /// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once /// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted. /// /// NOTE: After the initial call for any given map, it is important that no further items /// are inserted into the map which match the `partial key`. If so, then the map may not be /// empty when the resultant `maybe_cursor` is `None`. /// /// # Limit /// /// A `limit` must be provided in order to cap the maximum /// amount of deletions done in a single call. This is one fewer than the /// maximum number of backend iterations which may be done by this operation and as such /// represents the maximum number of backend deletions which may happen. A `limit` of zero /// implies that no keys will be deleted, though there may be a single iteration done. /// /// # Cursor /// /// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be /// passed once (in the initial call) for any given storage map and `partial_key`. Subsequent /// calls operating on the same map/`partial_key` should always pass `Some`, and this should be /// equal to the previous call result's `maybe_cursor` field. fn clear_prefix( partial_key: KP, limit: u32, maybe_cursor: Option<&[u8]>, ) -> sp_io::MultiRemovalResults where K: HasKeyPrefix; /// Does any value under a `partial_key` prefix (explicitly) exist in storage? /// Might have unexpected behaviour with empty keys, e.g. `[]`. fn contains_prefix(partial_key: KP) -> bool where K: HasKeyPrefix; /// Iterate over values that share the partial prefix key. fn iter_prefix_values(partial_key: KP) -> PrefixIterator where K: HasKeyPrefix; /// Mutate the value under a key. fn mutate(key: KArg, f: F) -> R where KArg: EncodeLikeTuple + TupleToEncodedIter, F: FnOnce(&mut Self::Query) -> R; /// Mutate the item, only if an `Ok` value is returned. fn try_mutate(key: KArg, f: F) -> Result where KArg: EncodeLikeTuple + TupleToEncodedIter, F: FnOnce(&mut Self::Query) -> Result; /// Mutate the value under a key. /// /// Deletes the item if mutated to a `None`. fn mutate_exists(key: KArg, f: F) -> R where KArg: EncodeLikeTuple + TupleToEncodedIter, F: FnOnce(&mut Option) -> R; /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. /// `f` will always be called with an option representing if the storage item exists (`Some`) /// or if the storage item does not exist (`None`), independent of the `QueryType`. fn try_mutate_exists(key: KArg, f: F) -> Result where KArg: EncodeLikeTuple + TupleToEncodedIter, F: FnOnce(&mut Option) -> Result; /// Take the value under a key. fn take + TupleToEncodedIter>(key: KArg) -> Self::Query; /// Append the given items to the value in the storage. /// /// `V` is required to implement `codec::EncodeAppend`. /// /// # Warning /// /// If the storage item is not encoded properly, the storage will be overwritten /// and set to `[item]`. Any default value set for the storage item will be ignored /// on overwrite. fn append(key: KArg, item: EncodeLikeItem) where KArg: EncodeLikeTuple + TupleToEncodedIter, Item: Encode, EncodeLikeItem: EncodeLike, V: StorageAppend; /// Read the length of the storage value without decoding the entire value under the /// given `key`. /// /// `V` is required to implement [`StorageDecodeLength`]. /// /// If the value does not exists or it fails to decode the length, `None` is returned. /// Otherwise `Some(len)` is returned. /// /// # Warning /// /// `None` does not mean that `get()` does not return a value. The default value is completely /// ignored by this function. fn decode_len + TupleToEncodedIter>(key: KArg) -> Option where V: StorageDecodeLength, { V::decode_len(&Self::hashed_key_for(key)) } /// Migrate an item with the given `key` from defunct `hash_fns` to the current hashers. /// /// If the key doesn't exist, then it's a no-op. If it does, then it returns its value. fn migrate_keys(key: KArg, hash_fns: K::HArg) -> Option where KArg: EncodeLikeTuple + TupleToEncodedIter; } /// Iterate or drain over a prefix and decode raw_key and raw_value into `T`. /// /// If any decoding fails it skips it and continues to the next key. /// /// If draining, then the hook `OnRemoval::on_removal` is called after each removal. pub struct PrefixIterator { prefix: Vec, previous_key: Vec, /// If true then value are removed while iterating drain: bool, /// Function that take `(raw_key_without_prefix, raw_value)` and decode `T`. /// `raw_key_without_prefix` is the raw storage key without the prefix iterated on. closure: fn(&[u8], &[u8]) -> Result, phantom: core::marker::PhantomData, } impl PrefixIterator { /// Converts to the same iterator but with the different 'OnRemoval' type pub fn convert_on_removal(self) -> PrefixIterator { PrefixIterator:: { prefix: self.prefix, previous_key: self.previous_key, drain: self.drain, closure: self.closure, phantom: Default::default(), } } } /// Trait for specialising on removal logic of [`PrefixIterator`]. pub trait PrefixIteratorOnRemoval { /// This function is called whenever a key/value is removed. fn on_removal(key: &[u8], value: &[u8]); } /// No-op implementation. impl PrefixIteratorOnRemoval for () { fn on_removal(_key: &[u8], _value: &[u8]) {} } impl PrefixIterator { /// Creates a new `PrefixIterator`, iterating after `previous_key` and filtering out keys that /// are not prefixed with `prefix`. /// /// A `decode_fn` function must also be supplied, and it takes in two `&[u8]` parameters, /// returning a `Result` containing the decoded type `T` if successful, and a `codec::Error` on /// failure. The first `&[u8]` argument represents the raw, undecoded key without the prefix of /// the current item, while the second `&[u8]` argument denotes the corresponding raw, /// undecoded value. pub fn new( prefix: Vec, previous_key: Vec, decode_fn: fn(&[u8], &[u8]) -> Result, ) -> Self { PrefixIterator { prefix, previous_key, drain: false, closure: decode_fn, phantom: Default::default(), } } /// Get the last key that has been iterated upon and return it. pub fn last_raw_key(&self) -> &[u8] { &self.previous_key } /// Get the prefix that is being iterated upon for this iterator and return it. pub fn prefix(&self) -> &[u8] { &self.prefix } /// Set the key that the iterator should start iterating after. pub fn set_last_raw_key(&mut self, previous_key: Vec) { self.previous_key = previous_key; } /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; self } } impl Iterator for PrefixIterator { type Item = T; fn next(&mut self) -> Option { loop { let maybe_next = sp_io::storage::next_key(&self.previous_key) .filter(|n| n.starts_with(&self.prefix)); break match maybe_next { Some(next) => { self.previous_key = next; let raw_value = match unhashed::get_raw(&self.previous_key) { Some(raw_value) => raw_value, None => { log::error!( "next_key returned a key with no value at {:?}", self.previous_key, ); continue }, }; if self.drain { unhashed::kill(&self.previous_key); OnRemoval::on_removal(&self.previous_key, &raw_value); } let raw_key_without_prefix = &self.previous_key[self.prefix.len()..]; let item = match (self.closure)(raw_key_without_prefix, &raw_value[..]) { Ok(item) => item, Err(e) => { log::error!( "(key, value) failed to decode at {:?}: {:?}", self.previous_key, e, ); continue }, }; Some(item) }, None => None, } } } } /// Iterate over a prefix and decode raw_key into `T`. /// /// If any decoding fails it skips it and continues to the next key. pub struct KeyPrefixIterator { prefix: Vec, previous_key: Vec, /// If true then value are removed while iterating drain: bool, /// Function that take `raw_key_without_prefix` and decode `T`. /// `raw_key_without_prefix` is the raw storage key without the prefix iterated on. closure: fn(&[u8]) -> Result, } impl KeyPrefixIterator { /// Creates a new `KeyPrefixIterator`, iterating after `previous_key` and filtering out keys /// that are not prefixed with `prefix`. /// /// A `decode_fn` function must also be supplied, and it takes in a `&[u8]` parameter, returning /// a `Result` containing the decoded key type `T` if successful, and a `codec::Error` on /// failure. The `&[u8]` argument represents the raw, undecoded key without the prefix of the /// current item. pub fn new( prefix: Vec, previous_key: Vec, decode_fn: fn(&[u8]) -> Result, ) -> Self { KeyPrefixIterator { prefix, previous_key, drain: false, closure: decode_fn } } /// Get the last key that has been iterated upon and return it. pub fn last_raw_key(&self) -> &[u8] { &self.previous_key } /// Get the prefix that is being iterated upon for this iterator and return it. pub fn prefix(&self) -> &[u8] { &self.prefix } /// Set the key that the iterator should start iterating after. pub fn set_last_raw_key(&mut self, previous_key: Vec) { self.previous_key = previous_key; } /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; self } } impl Iterator for KeyPrefixIterator { type Item = T; fn next(&mut self) -> Option { loop { let maybe_next = sp_io::storage::next_key(&self.previous_key) .filter(|n| n.starts_with(&self.prefix)); if let Some(next) = maybe_next { self.previous_key = next; if self.drain { unhashed::kill(&self.previous_key); } let raw_key_without_prefix = &self.previous_key[self.prefix.len()..]; match (self.closure)(raw_key_without_prefix) { Ok(item) => return Some(item), Err(e) => { log::error!("key failed to decode at {:?}: {:?}", self.previous_key, e); continue }, } } return None } } } /// Iterate over a prefix of a child trie and decode raw_key and raw_value into `T`. /// /// If any decoding fails it skips the key and continues to the next one. pub struct ChildTriePrefixIterator { /// The prefix iterated on prefix: Vec, /// child info for child trie child_info: ChildInfo, /// The last key iterated on previous_key: Vec, /// If true then values are removed while iterating drain: bool, /// Whether or not we should fetch the previous key fetch_previous_key: bool, /// Function that takes `(raw_key_without_prefix, raw_value)` and decode `T`. /// `raw_key_without_prefix` is the raw storage key without the prefix iterated on. closure: fn(&[u8], &[u8]) -> Result, } impl ChildTriePrefixIterator { /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; self } } impl ChildTriePrefixIterator<(Vec, T)> { /// Construct iterator to iterate over child trie items in `child_info` with the prefix /// `prefix`. /// /// NOTE: Iterator with [`Self::drain`] will remove any value who failed to decode pub fn with_prefix(child_info: &ChildInfo, prefix: &[u8]) -> Self { let prefix = prefix.to_vec(); let previous_key = prefix.clone(); let closure = |raw_key_without_prefix: &[u8], mut raw_value: &[u8]| { let value = T::decode(&mut raw_value)?; Ok((raw_key_without_prefix.to_vec(), value)) }; Self { prefix, child_info: child_info.clone(), previous_key, drain: false, fetch_previous_key: true, closure, } } } impl ChildTriePrefixIterator<(K, T)> { /// Construct iterator to iterate over child trie items in `child_info` with the prefix /// `prefix`. /// /// NOTE: Iterator with [`Self::drain`] will remove any key or value who failed to decode pub fn with_prefix_over_key( child_info: &ChildInfo, prefix: &[u8], ) -> Self { let prefix = prefix.to_vec(); let previous_key = prefix.clone(); let closure = |raw_key_without_prefix: &[u8], mut raw_value: &[u8]| { let mut key_material = H::reverse(raw_key_without_prefix); let key = K::decode(&mut key_material)?; let value = T::decode(&mut raw_value)?; Ok((key, value)) }; Self { prefix, child_info: child_info.clone(), previous_key, drain: false, fetch_previous_key: true, closure, } } } impl Iterator for ChildTriePrefixIterator { type Item = T; fn next(&mut self) -> Option { loop { let maybe_next = if self.fetch_previous_key { self.fetch_previous_key = false; Some(self.previous_key.clone()) } else { sp_io::default_child_storage::next_key( self.child_info.storage_key(), &self.previous_key, ) .filter(|n| n.starts_with(&self.prefix)) }; break match maybe_next { Some(next) => { self.previous_key = next; let raw_value = match child::get_raw(&self.child_info, &self.previous_key) { Some(raw_value) => raw_value, None => { log::error!( "next_key returned a key with no value at {:?}", self.previous_key, ); continue }, }; if self.drain { child::kill(&self.child_info, &self.previous_key) } let raw_key_without_prefix = &self.previous_key[self.prefix.len()..]; let item = match (self.closure)(raw_key_without_prefix, &raw_value[..]) { Ok(item) => item, Err(e) => { log::error!( "(key, value) failed to decode at {:?}: {:?}", self.previous_key, e, ); continue }, }; Some(item) }, None => None, } } } } /// Trait for storage types that store all its value after a unique prefix. pub trait StoragePrefixedContainer { /// Pallet prefix. Used for generating final key. fn pallet_prefix() -> &'static [u8]; /// Storage prefix. Used for generating final key. fn storage_prefix() -> &'static [u8]; /// Final full prefix that prefixes all keys. fn final_prefix() -> [u8; 32] { crate::storage::storage_prefix(Self::pallet_prefix(), Self::storage_prefix()) } } /// Trait for maps that store all its value after a unique prefix. /// /// By default the final prefix is: /// ```nocompile /// Twox128(pallet_prefix) ++ Twox128(storage_prefix) /// ``` pub trait StoragePrefixedMap { /// Pallet prefix. Used for generating final key. fn pallet_prefix() -> &'static [u8]; // TODO move to StoragePrefixedContainer /// Storage prefix. Used for generating final key. fn storage_prefix() -> &'static [u8]; /// Final full prefix that prefixes all keys. fn final_prefix() -> [u8; 32] { crate::storage::storage_prefix(Self::pallet_prefix(), Self::storage_prefix()) } /// Remove all values in the overlay and up to `limit` in the backend. /// /// All values in the client overlay will be deleted, if there is some `limit` then up to /// `limit` values are deleted from the client backend, if `limit` is none then all values in /// the client backend are deleted. /// /// # Note /// /// Calling this multiple times per block with a `limit` set leads always to the same keys being /// removed and the same result being returned. This happens because the keys to delete in the /// overlay are not taken into account when deleting keys in the backend. #[deprecated = "Use `clear` instead"] fn remove_all(limit: Option) -> sp_io::KillStorageResult { unhashed::clear_prefix(&Self::final_prefix(), limit, None).into() } /// Attempt to remove all items from the map. /// /// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once /// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted. /// /// NOTE: After the initial call for any given map, it is important that no further items /// are inserted into the map. If so, then the map may not be empty when the resultant /// `maybe_cursor` is `None`. /// /// # Limit /// /// A `limit` must always be provided through in order to cap the maximum /// amount of deletions done in a single call. This is one fewer than the /// maximum number of backend iterations which may be done by this operation and as such /// represents the maximum number of backend deletions which may happen. A `limit` of zero /// implies that no keys will be deleted, though there may be a single iteration done. /// /// # Cursor /// /// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be /// passed once (in the initial call) for any given storage map. Subsequent calls /// operating on the same map should always pass `Some`, and this should be equal to the /// previous call result's `maybe_cursor` field. fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults { unhashed::clear_prefix(&Self::final_prefix(), Some(limit), maybe_cursor) } /// Iter over all value of the storage. /// /// NOTE: If a value failed to decode because storage is corrupted then it is skipped. fn iter_values() -> PrefixIterator { let prefix = Self::final_prefix(); PrefixIterator { prefix: prefix.to_vec(), previous_key: prefix.to_vec(), drain: false, closure: |_raw_key, mut raw_value| Value::decode(&mut raw_value), phantom: Default::default(), } } /// Translate the values of all elements by a function `f`, in the map in no particular order. /// By returning `None` from `f` for an element, you'll remove it from the map. /// /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. /// /// # Warning /// /// This function must be used with care, before being updated the storage still contains the /// old type, thus other calls (such as `get`) will fail at decoding it. /// /// # Usage /// /// This would typically be called inside the module implementation of on_runtime_upgrade. fn translate_values Option>(mut f: F) { let prefix = Self::final_prefix(); let mut previous_key = prefix.clone().to_vec(); while let Some(next) = sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix)) { previous_key = next; let maybe_value = unhashed::get::(&previous_key); match maybe_value { Some(value) => match f(value) { Some(new) => unhashed::put::(&previous_key, &new), None => unhashed::kill(&previous_key), }, None => { log::error!("old key failed to decode at {:?}", previous_key); continue }, } } } } /// Marker trait that will be implemented for types that support the `storage::append` api. /// /// This trait is sealed. pub trait StorageAppend: private::Sealed {} /// It is expected that the length is at the beginning of the encoded object /// and that the length is a `Compact`. /// /// This trait is sealed. pub trait StorageDecodeLength: private::Sealed + codec::DecodeLength { /// Decode the length of the storage value at `key`. /// /// This function assumes that the length is at the beginning of the encoded object /// and is a `Compact`. /// /// Returns `None` if the storage value does not exist or the decoding failed. fn decode_len(key: &[u8]) -> Option { // `Compact` is 5 bytes in maximum. let mut data = [0u8; 5]; let len = sp_io::storage::read(key, &mut data, 0)?; let len = data.len().min(len as usize); ::len(&data[..len]).ok() } } /// It is expected that the length is at the beginning of the encoded object and that the length is /// a `Compact`. /// /// # Note /// The length returned by this trait is not deduplicated, i.e. it is the length of the underlying /// stored Vec. /// /// This trait is sealed. pub trait StorageDecodeNonDedupLength: private::Sealed + codec::DecodeLength { /// Decode the length of the storage value at `key`. /// /// This function assumes that the length is at the beginning of the encoded object and is a /// `Compact`. /// /// Returns `None` if the storage value does not exist or the decoding failed. fn decode_non_dedup_len(key: &[u8]) -> Option { let mut data = [0u8; 5]; let len = sp_io::storage::read(key, &mut data, 0)?; let len = data.len().min(len as usize); ::len(&data[..len]).ok() } } /// Provides `Sealed` trait to prevent implementing trait `StorageAppend` & `StorageDecodeLength` /// & `EncodeLikeTuple` outside of this crate. mod private { use super::*; use bounded_vec::BoundedVec; use weak_bounded_vec::WeakBoundedVec; pub trait Sealed {} impl Sealed for Vec {} impl Sealed for Digest {} impl Sealed for BoundedVec {} impl Sealed for WeakBoundedVec {} impl Sealed for bounded_btree_map::BoundedBTreeMap {} impl Sealed for bounded_btree_set::BoundedBTreeSet {} impl Sealed for BTreeSet {} impl<'a, T: EncodeLike, U: Encode> Sealed for codec::Ref<'a, T, U> {} macro_rules! impl_sealed_for_tuple { ($($elem:ident),+) => { paste::paste! { impl<$($elem: Encode,)+> Sealed for ($($elem,)+) {} impl<$($elem: Encode,)+> Sealed for &($($elem,)+) {} } }; } impl_sealed_for_tuple!(A); impl_sealed_for_tuple!(A, B); impl_sealed_for_tuple!(A, B, C); impl_sealed_for_tuple!(A, B, C, D); impl_sealed_for_tuple!(A, B, C, D, E); impl_sealed_for_tuple!(A, B, C, D, E, F); impl_sealed_for_tuple!(A, B, C, D, E, F, G); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, O); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q); impl_sealed_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, O, P, Q, R); } impl StorageAppend for Vec {} impl StorageDecodeLength for Vec {} impl StorageAppend for BTreeSet {} impl StorageDecodeNonDedupLength for BTreeSet {} // Blanket implementation StorageDecodeNonDedupLength for all types that are StorageDecodeLength. impl StorageDecodeNonDedupLength for T { fn decode_non_dedup_len(key: &[u8]) -> Option { T::decode_len(key) } } /// We abuse the fact that SCALE does not put any marker into the encoding, i.e. we only encode the /// internal vec and we can append to this vec. We have a test that ensures that if the `Digest` /// format ever changes, we need to remove this here. impl StorageAppend for Digest {} /// Marker trait that is implemented for types that support the `storage::append` api with a limit /// on the number of element. /// /// This trait is sealed. pub trait StorageTryAppend: StorageDecodeLength + private::Sealed { fn bound() -> usize; } /// Storage value that is capable of [`StorageTryAppend`]. pub trait TryAppendValue, I: Encode> { /// Try and append the `item` into the storage item. /// /// This might fail if bounds are not respected. fn try_append>(item: LikeI) -> Result<(), ()>; } impl TryAppendValue for StorageValueT where I: Encode, T: FullCodec + StorageTryAppend, StorageValueT: generator::StorageValue, { fn try_append>(item: LikeI) -> Result<(), ()> { let bound = T::bound(); let current = Self::decode_len().unwrap_or_default(); if current < bound { // NOTE: we cannot reuse the implementation for `Vec` here because we never want to // mark `BoundedVec` as `StorageAppend`. let key = Self::storage_value_final_key(); sp_io::storage::append(&key, item.encode()); Ok(()) } else { Err(()) } } } /// Storage map that is capable of [`StorageTryAppend`]. pub trait TryAppendMap, I: Encode> { /// Try and append the `item` into the storage map at the given `key`. /// /// This might fail if bounds are not respected. fn try_append + Clone, LikeI: EncodeLike>( key: LikeK, item: LikeI, ) -> Result<(), ()>; } impl TryAppendMap for StorageMapT where K: FullCodec, T: FullCodec + StorageTryAppend, I: Encode, StorageMapT: generator::StorageMap, { fn try_append + Clone, LikeI: EncodeLike>( key: LikeK, item: LikeI, ) -> Result<(), ()> { let bound = T::bound(); let current = Self::decode_len(key.clone()).unwrap_or_default(); if current < bound { let key = Self::storage_map_final_key(key); sp_io::storage::append(&key, item.encode()); Ok(()) } else { Err(()) } } } /// Storage double map that is capable of [`StorageTryAppend`]. pub trait TryAppendDoubleMap, I: Encode> { /// Try and append the `item` into the storage double map at the given `key`. /// /// This might fail if bounds are not respected. fn try_append< LikeK1: EncodeLike + Clone, LikeK2: EncodeLike + Clone, LikeI: EncodeLike, >( key1: LikeK1, key2: LikeK2, item: LikeI, ) -> Result<(), ()>; } impl TryAppendDoubleMap for StorageDoubleMapT where K1: FullCodec, K2: FullCodec, T: FullCodec + StorageTryAppend, I: Encode, StorageDoubleMapT: generator::StorageDoubleMap, { fn try_append< LikeK1: EncodeLike + Clone, LikeK2: EncodeLike + Clone, LikeI: EncodeLike, >( key1: LikeK1, key2: LikeK2, item: LikeI, ) -> Result<(), ()> { let bound = T::bound(); let current = Self::decode_len(key1.clone(), key2.clone()).unwrap_or_default(); if current < bound { let double_map_key = Self::storage_double_map_final_key(key1, key2); sp_io::storage::append(&double_map_key, item.encode()); Ok(()) } else { Err(()) } } } /// Returns the storage prefix for a specific pallet name and storage name. /// /// The storage prefix is `concat(twox_128(pallet_name), twox_128(storage_name))`. pub fn storage_prefix(pallet_name: &[u8], storage_name: &[u8]) -> [u8; 32] { let pallet_hash = sp_io::hashing::twox_128(pallet_name); let storage_hash = sp_io::hashing::twox_128(storage_name); let mut final_key = [0u8; 32]; final_key[..16].copy_from_slice(&pallet_hash); final_key[16..].copy_from_slice(&storage_hash); final_key } #[cfg(test)] mod test { use super::*; use crate::{assert_ok, hash::Identity, pallet_prelude::NMapKey, Twox128}; use bounded_vec::BoundedVec; use frame_support::traits::ConstU32; use generator::StorageValue as _; use sp_crypto_hashing::twox_128; use sp_io::TestExternalities; use weak_bounded_vec::WeakBoundedVec; #[test] fn prefixed_map_works() { TestExternalities::default().execute_with(|| { struct MyStorage; impl StoragePrefixedMap for MyStorage { fn pallet_prefix() -> &'static [u8] { b"MyModule" } fn storage_prefix() -> &'static [u8] { b"MyStorage" } } let key_before = { let mut k = MyStorage::final_prefix(); let last = k.iter_mut().last().unwrap(); *last = last.checked_sub(1).unwrap(); k }; let key_after = { let mut k = MyStorage::final_prefix(); let last = k.iter_mut().last().unwrap(); *last = last.checked_add(1).unwrap(); k }; unhashed::put(&key_before[..], &32u64); unhashed::put(&key_after[..], &33u64); let k = [twox_128(b"MyModule"), twox_128(b"MyStorage")].concat(); assert_eq!(MyStorage::final_prefix().to_vec(), k); // test iteration assert!(MyStorage::iter_values().collect::>().is_empty()); unhashed::put(&[&k[..], &vec![1][..]].concat(), &1u64); unhashed::put(&[&k[..], &vec![1, 1][..]].concat(), &2u64); unhashed::put(&[&k[..], &vec![8][..]].concat(), &3u64); unhashed::put(&[&k[..], &vec![10][..]].concat(), &4u64); assert_eq!(MyStorage::iter_values().collect::>(), vec![1, 2, 3, 4]); // test removal let _ = MyStorage::clear(u32::max_value(), None); assert!(MyStorage::iter_values().collect::>().is_empty()); // test migration unhashed::put(&[&k[..], &vec![1][..]].concat(), &1u32); unhashed::put(&[&k[..], &vec![8][..]].concat(), &2u32); assert!(MyStorage::iter_values().collect::>().is_empty()); MyStorage::translate_values(|v: u32| Some(v as u64)); assert_eq!(MyStorage::iter_values().collect::>(), vec![1, 2]); let _ = MyStorage::clear(u32::max_value(), None); // test migration 2 unhashed::put(&[&k[..], &vec![1][..]].concat(), &1u128); unhashed::put(&[&k[..], &vec![1, 1][..]].concat(), &2u64); unhashed::put(&[&k[..], &vec![8][..]].concat(), &3u128); unhashed::put(&[&k[..], &vec![10][..]].concat(), &4u32); // (contains some value that successfully decoded to u64) assert_eq!(MyStorage::iter_values().collect::>(), vec![1, 2, 3]); MyStorage::translate_values(|v: u128| Some(v as u64)); assert_eq!(MyStorage::iter_values().collect::>(), vec![1, 2, 3]); let _ = MyStorage::clear(u32::max_value(), None); // test that other values are not modified. assert_eq!(unhashed::get(&key_before[..]), Some(32u64)); assert_eq!(unhashed::get(&key_after[..]), Some(33u64)); }); } // This test ensures that the Digest encoding does not change without being noticed. #[test] fn digest_storage_append_works_as_expected() { TestExternalities::default().execute_with(|| { struct Storage; impl generator::StorageValue for Storage { type Query = Digest; fn pallet_prefix() -> &'static [u8] { b"MyModule" } fn storage_prefix() -> &'static [u8] { b"Storage" } fn from_optional_value_to_query(v: Option) -> Self::Query { v.unwrap() } fn from_query_to_optional_value(v: Self::Query) -> Option { Some(v) } fn storage_value_final_key() -> [u8; 32] { storage_prefix(Self::pallet_prefix(), Self::storage_prefix()) } } Storage::append(DigestItem::Other(Vec::new())); let value = unhashed::get_raw(&Storage::storage_value_final_key()).unwrap(); let expected = Digest { logs: vec![DigestItem::Other(Vec::new())] }; assert_eq!(Digest::decode(&mut &value[..]).unwrap(), expected); }); } #[test] fn key_prefix_iterator_works() { TestExternalities::default().execute_with(|| { use crate::{hash::Twox64Concat, storage::generator::StorageMap}; struct MyStorageMap; impl StorageMap for MyStorageMap { type Query = u64; type Hasher = Twox64Concat; fn pallet_prefix() -> &'static [u8] { b"MyModule" } fn storage_prefix() -> &'static [u8] { b"MyStorageMap" } fn prefix_hash() -> [u8; 32] { storage_prefix(Self::pallet_prefix(), Self::storage_prefix()) } fn from_optional_value_to_query(v: Option) -> Self::Query { v.unwrap_or_default() } fn from_query_to_optional_value(v: Self::Query) -> Option { Some(v) } } let k = [twox_128(b"MyModule"), twox_128(b"MyStorageMap")].concat(); assert_eq!(MyStorageMap::prefix_hash().to_vec(), k); // empty to start assert!(MyStorageMap::iter_keys().collect::>().is_empty()); MyStorageMap::insert(1, 10); MyStorageMap::insert(2, 20); MyStorageMap::insert(3, 30); MyStorageMap::insert(4, 40); // just looking let mut keys = MyStorageMap::iter_keys().collect::>(); keys.sort(); assert_eq!(keys, vec![1, 2, 3, 4]); // draining the keys and values let mut drained_keys = MyStorageMap::iter_keys().drain().collect::>(); drained_keys.sort(); assert_eq!(drained_keys, vec![1, 2, 3, 4]); // empty again assert!(MyStorageMap::iter_keys().collect::>().is_empty()); }); } #[test] fn prefix_iterator_pagination_works() { TestExternalities::default().execute_with(|| { use crate::{hash::Identity, storage::generator::map::StorageMap}; #[crate::storage_alias] type MyStorageMap = StorageMap; MyStorageMap::insert(1, 10); MyStorageMap::insert(2, 20); MyStorageMap::insert(3, 30); MyStorageMap::insert(4, 40); MyStorageMap::insert(5, 50); MyStorageMap::insert(6, 60); MyStorageMap::insert(7, 70); MyStorageMap::insert(8, 80); MyStorageMap::insert(9, 90); MyStorageMap::insert(10, 100); let op = |(_, v)| v / 10; let mut final_vec = vec![]; let mut iter = MyStorageMap::iter(); let elem = iter.next().unwrap(); assert_eq!(elem, (1, 10)); final_vec.push(op(elem)); let elem = iter.next().unwrap(); assert_eq!(elem, (2, 20)); final_vec.push(op(elem)); let stored_key = iter.last_raw_key().to_owned(); assert_eq!(stored_key, MyStorageMap::storage_map_final_key(2)); let mut iter = MyStorageMap::iter_from(stored_key.clone()); final_vec.push(op(iter.next().unwrap())); final_vec.push(op(iter.next().unwrap())); final_vec.push(op(iter.next().unwrap())); assert_eq!(final_vec, vec![1, 2, 3, 4, 5]); let mut iter = PrefixIterator::<_>::new( iter.prefix().to_vec(), stored_key, |mut raw_key_without_prefix, mut raw_value| { let key = u64::decode(&mut raw_key_without_prefix)?; Ok((key, u64::decode(&mut raw_value)?)) }, ); let previous_key = MyStorageMap::storage_map_final_key(5); iter.set_last_raw_key(previous_key); let remaining = iter.map(op).collect::>(); assert_eq!(remaining.len(), 5); assert_eq!(remaining, vec![6, 7, 8, 9, 10]); final_vec.extend_from_slice(&remaining); assert_eq!(final_vec, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }); } #[test] fn child_trie_prefixed_map_works() { TestExternalities::default().execute_with(|| { let child_info_a = child::ChildInfo::new_default(b"a"); child::put(&child_info_a, &[1, 2, 3], &8u16); child::put(&child_info_a, &[2], &8u16); child::put(&child_info_a, &[2, 1, 3], &8u8); child::put(&child_info_a, &[2, 2, 3], &8u16); child::put(&child_info_a, &[3], &8u16); assert_eq!( ChildTriePrefixIterator::with_prefix(&child_info_a, &[2]) .collect::, u16)>>(), vec![(vec![], 8), (vec![2, 3], 8),], ); assert_eq!( ChildTriePrefixIterator::with_prefix(&child_info_a, &[2]) .drain() .collect::, u16)>>(), vec![(vec![], 8), (vec![2, 3], 8),], ); // The only remaining is the ones outside prefix assert_eq!( ChildTriePrefixIterator::with_prefix(&child_info_a, &[]) .collect::, u8)>>(), vec![(vec![1, 2, 3], 8), (vec![3], 8),], ); child::put(&child_info_a, &[1, 2, 3], &8u16); child::put(&child_info_a, &[2], &8u16); child::put(&child_info_a, &[2, 1, 3], &8u8); child::put(&child_info_a, &[2, 2, 3], &8u16); child::put(&child_info_a, &[3], &8u16); assert_eq!( ChildTriePrefixIterator::with_prefix_over_key::(&child_info_a, &[2]) .collect::>(), vec![(u16::decode(&mut &[2, 3][..]).unwrap(), 8),], ); assert_eq!( ChildTriePrefixIterator::with_prefix_over_key::(&child_info_a, &[2]) .drain() .collect::>(), vec![(u16::decode(&mut &[2, 3][..]).unwrap(), 8),], ); // The only remaining is the ones outside prefix assert_eq!( ChildTriePrefixIterator::with_prefix(&child_info_a, &[]) .collect::, u8)>>(), vec![(vec![1, 2, 3], 8), (vec![3], 8),], ); }); } #[crate::storage_alias] type Foo = StorageValue>>; #[crate::storage_alias] type FooMap = StorageMap>>; #[crate::storage_alias] type FooDoubleMap = StorageDoubleMap>>; #[crate::storage_alias] type FooTripleMap = StorageNMap< Prefix, (NMapKey, NMapKey, NMapKey), u64, >; #[test] fn contains_prefix_works() { TestExternalities::default().execute_with(|| { // Test double maps assert!(FooDoubleMap::iter_prefix_values(1).next().is_none()); assert_eq!(FooDoubleMap::contains_prefix(1), false); assert_ok!(FooDoubleMap::try_append(1, 1, 4)); assert_ok!(FooDoubleMap::try_append(2, 1, 4)); assert!(FooDoubleMap::iter_prefix_values(1).next().is_some()); assert!(FooDoubleMap::contains_prefix(1)); FooDoubleMap::remove(1, 1); assert_eq!(FooDoubleMap::contains_prefix(1), false); // Test N Maps assert!(FooTripleMap::iter_prefix_values((1,)).next().is_none()); assert_eq!(FooTripleMap::contains_prefix((1,)), false); FooTripleMap::insert((1, 1, 1), 4); FooTripleMap::insert((2, 1, 1), 4); assert!(FooTripleMap::iter_prefix_values((1,)).next().is_some()); assert!(FooTripleMap::contains_prefix((1,))); FooTripleMap::remove((1, 1, 1)); assert_eq!(FooTripleMap::contains_prefix((1,)), false); }); } #[test] fn try_append_works() { TestExternalities::default().execute_with(|| { let bounded: WeakBoundedVec> = vec![1, 2, 3].try_into().unwrap(); Foo::put(bounded); assert_ok!(Foo::try_append(4)); assert_ok!(Foo::try_append(5)); assert_ok!(Foo::try_append(6)); assert_ok!(Foo::try_append(7)); assert_eq!(Foo::decode_len().unwrap(), 7); assert!(Foo::try_append(8).is_err()); }); TestExternalities::default().execute_with(|| { let bounded: BoundedVec> = vec![1, 2, 3].try_into().unwrap(); FooMap::insert(1, bounded); assert_ok!(FooMap::try_append(1, 4)); assert_ok!(FooMap::try_append(1, 5)); assert_ok!(FooMap::try_append(1, 6)); assert_ok!(FooMap::try_append(1, 7)); assert_eq!(FooMap::decode_len(1).unwrap(), 7); assert!(FooMap::try_append(1, 8).is_err()); // append to a non-existing assert!(FooMap::get(2).is_none()); assert_ok!(FooMap::try_append(2, 4)); assert_eq!( FooMap::get(2).unwrap(), BoundedVec::>::try_from(vec![4]).unwrap(), ); assert_ok!(FooMap::try_append(2, 5)); assert_eq!( FooMap::get(2).unwrap(), BoundedVec::>::try_from(vec![4, 5]).unwrap(), ); }); TestExternalities::default().execute_with(|| { let bounded: BoundedVec> = vec![1, 2, 3].try_into().unwrap(); FooDoubleMap::insert(1, 1, bounded); assert_ok!(FooDoubleMap::try_append(1, 1, 4)); assert_ok!(FooDoubleMap::try_append(1, 1, 5)); assert_ok!(FooDoubleMap::try_append(1, 1, 6)); assert_ok!(FooDoubleMap::try_append(1, 1, 7)); assert_eq!(FooDoubleMap::decode_len(1, 1).unwrap(), 7); assert!(FooDoubleMap::try_append(1, 1, 8).is_err()); // append to a non-existing assert!(FooDoubleMap::get(2, 1).is_none()); assert_ok!(FooDoubleMap::try_append(2, 1, 4)); assert_eq!( FooDoubleMap::get(2, 1).unwrap(), BoundedVec::>::try_from(vec![4]).unwrap(), ); assert_ok!(FooDoubleMap::try_append(2, 1, 5)); assert_eq!( FooDoubleMap::get(2, 1).unwrap(), BoundedVec::>::try_from(vec![4, 5]).unwrap(), ); }); } #[crate::storage_alias] type FooSet = StorageValue>; #[test] fn btree_set_append_and_decode_len_works() { TestExternalities::default().execute_with(|| { let btree = BTreeSet::from([1, 2, 3]); FooSet::put(btree); FooSet::append(4); FooSet::append(5); FooSet::append(6); FooSet::append(7); assert_eq!(FooSet::decode_non_dedup_len().unwrap(), 7); }); } #[docify::export] #[test] fn btree_set_decode_non_dedup_len() { #[crate::storage_alias] type Store = StorageValue>; TestExternalities::default().execute_with(|| { Store::append(4); Store::append(4); // duplicate value Store::append(5); let length_with_dup_items = 3; assert_eq!(Store::decode_non_dedup_len().unwrap(), length_with_dup_items); }); } }