// Copyright 2017-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . //! Stuff to do with the runtime's storage. use rstd::prelude::*; use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike, Decode}; use crate::traits::Len; pub mod unhashed; pub mod hashed; pub mod child; pub mod generator; /// 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; /// 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_initialize, while /// ensuring **no usage of this storage are made before the call to `on_initialize`**. (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); /// Mutate the value fn mutate R>(f: F) -> R; /// 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 `codec::EncodeAppend`. fn append(items: Items) -> Result<(), &'static str> where Item: Encode, EncodeLikeItem: EncodeLike, T: EncodeAppend, Items: IntoIterator, Items::IntoIter: ExactSizeIterator; /// Append the given items to the value in the storage. /// /// `T` is required to implement `Codec::EncodeAppend`. /// /// Upon any failure, it replaces `items` as the new value (assuming that the previous stored /// data is simply corrupt and no longer usable). /// /// ### WARNING /// /// use with care; if your use-case is not _exactly_ as what this function is doing, /// you should use append and sensibly handle failure within the runtime code if it happens. fn append_or_put(items: Items) where Item: Encode, EncodeLikeItem: EncodeLike, T: EncodeAppend, Items: IntoIterator + Clone + EncodeLike, Items::IntoIter: ExactSizeIterator; /// Read the length of the value in a fast way, without decoding the entire value. /// /// `T` is required to implement `Codec::DecodeLength`. fn decode_len() -> Result where T: codec::DecodeLength + Len; } /// 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 exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; /// 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; /// 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`. fn append(key: KeyArg, items: Items) -> Result<(), &'static str> where KeyArg: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: EncodeAppend, Items: IntoIterator, Items::IntoIter: ExactSizeIterator; /// Safely append the given items to the value in the storage. If a codec error occurs, then the /// old (presumably corrupt) value is replaced with the given `items`. /// /// `V` is required to implement `codec::EncodeAppend`. fn append_or_insert(key: KeyArg, items: Items) where KeyArg: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: EncodeAppend, Items: IntoIterator + Clone + EncodeLike, Items::IntoIter: ExactSizeIterator; /// Read the length of the value in a fast way, without decoding the entire value. /// /// `T` is required to implement `Codec::DecodeLength`. /// /// Note that `0` is returned as the default value if no encoded value exists at the given key. /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` /// function for this purpose. fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; } /// A strongly-typed linked map in storage. /// /// Similar to `StorageMap` but allows to enumerate other elements and doesn't implement append. /// /// Details on implementation can be found at /// [`generator::StorageLinkedMap`] pub trait StorageLinkedMap { /// The type that get/take return. type Query; /// The type that iterates over all `(key, value)`. type Enumerator: Iterator; /// Does the value (explicitly) exist in storage? fn exists>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; /// 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; /// Take the value under a key. fn take>(key: KeyArg) -> Self::Query; /// Return current head element. fn head() -> Option; /// Enumerate all elements in the map. fn enumerate() -> Self::Enumerator; /// Read the length of the value in a fast way, without decoding the entire value. /// /// `T` is required to implement `Codec::DecodeLength`. /// /// Note that `0` is returned as the default value if no encoded value exists at the given key. /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` /// function for this purpose. fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; /// Translate the keys and values from some previous `(K2, V2)` to the current type. /// /// `TK` translates keys from the old type, and `TV` translates values. /// /// Returns `Err` if the map could not be interpreted as the old type, and Ok if it could. /// The `Err` contains the first key which could not be migrated, or `None` if the /// head of the list could not be read. /// /// # 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_initialize, while /// ensuring **no usage of this storage are made before the call to `on_initialize`**. (More /// precisely prior initialized modules doesn't make use of this storage). fn translate(translate_key: TK, translate_val: TV) -> Result<(), Option> where K2: FullCodec + Clone, V2: Decode, TK: Fn(K2) -> K, TV: Fn(V2) -> V; } /// An implementation of a map with a two keys. /// /// It provides an important ability to efficiently remove all entries /// that have a common first key. /// /// Details on implementation can be found at /// [`generator::StorageDoubleMap`] pub trait StorageDoubleMap { /// The type that get/take returns. type Query; fn hashed_key_for(k1: KArg1, k2: KArg2) -> Vec where KArg1: EncodeLike, KArg2: EncodeLike; fn exists(k1: KArg1, k2: KArg2) -> bool where KArg1: EncodeLike, KArg2: EncodeLike; fn get(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, KArg2: EncodeLike; 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; fn insert(k1: KArg1, k2: KArg2, val: VArg) where KArg1: EncodeLike, KArg2: EncodeLike, VArg: EncodeLike; fn remove(k1: KArg1, k2: KArg2) where KArg1: EncodeLike, KArg2: EncodeLike; fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> R; fn append( k1: KArg1, k2: KArg2, items: Items, ) -> Result<(), &'static str> where KArg1: EncodeLike, KArg2: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: EncodeAppend, Items: IntoIterator, Items::IntoIter: ExactSizeIterator; fn append_or_insert( k1: KArg1, k2: KArg2, items: Items, ) where KArg1: EncodeLike, KArg2: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, V: EncodeAppend, Items: IntoIterator + Clone + EncodeLike, Items::IntoIter: ExactSizeIterator; /// Read the length of the value in a fast way, without decoding the entire value. /// /// `V` is required to implement `Codec::DecodeLength`. /// /// Note that `0` is returned as the default value if no encoded value exists at the given key. /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` /// function for this purpose. fn decode_len(key1: KArg1, key2: KArg2) -> Result where KArg1: EncodeLike, KArg2: EncodeLike, V: codec::DecodeLength + Len; }