mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-30 20:07:24 +00:00
53e0ddee4e
* impl * patch * lock * some refactor * some avoided copy * new api without ref for doublemap * fix * version bump * fix * point to incoming release * use codec latest * bumpd impl version * fix unused * fix * Update srml/support/src/storage/mod.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>
276 lines
9.0 KiB
Rust
276 lines
9.0 KiB
Rust
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
//! Stuff to do with the runtime's storage.
|
|
|
|
use rstd::prelude::*;
|
|
use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike};
|
|
use crate::traits::Len;
|
|
|
|
#[macro_use]
|
|
pub mod storage_items;
|
|
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.
|
|
pub trait StorageValue<T: FullCodec> {
|
|
/// The type that get/take return.
|
|
type Query;
|
|
|
|
/// Get the storage key.
|
|
fn hashed_key() -> [u8; 16];
|
|
|
|
/// Does the value (explicitly) exist in storage?
|
|
fn exists() -> bool;
|
|
|
|
/// Load the value from the provided storage instance.
|
|
fn get() -> Self::Query;
|
|
|
|
/// Store a value under this key into the provided storage instance.
|
|
fn put<Arg: EncodeLike<T>>(val: Arg);
|
|
|
|
/// Mutate the value
|
|
fn mutate<R, F: FnOnce(&mut Self::Query) -> 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, Item, EncodeLikeItem>(items: Items) -> Result<(), &'static str>
|
|
where
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
T: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem>,
|
|
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, Item, EncodeLikeItem>(items: Items) where
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
T: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem> + Clone + EncodeLike<T>,
|
|
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<usize, &'static str>
|
|
where T: codec::DecodeLength + Len;
|
|
}
|
|
|
|
/// A strongly-typed map in storage.
|
|
pub trait StorageMap<K: FullEncode, V: FullCodec> {
|
|
/// 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<KeyArg: EncodeLike<K>>(key: KeyArg) -> Vec<u8>;
|
|
|
|
/// Does the value (explicitly) exist in storage?
|
|
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool;
|
|
|
|
/// Load the value associated with the given key from the map.
|
|
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
|
|
|
/// Swap the values of two keys.
|
|
fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2);
|
|
|
|
/// Store a value to be associated with the given key from the map.
|
|
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg);
|
|
|
|
/// Remove the value under a key.
|
|
fn remove<KeyArg: EncodeLike<K>>(key: KeyArg);
|
|
|
|
/// Mutate the value under a key.
|
|
fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R;
|
|
|
|
/// Take the value under a key.
|
|
fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
|
|
|
/// Append the given items to the value in the storage.
|
|
///
|
|
/// `V` is required to implement `codec::EncodeAppend`.
|
|
fn append<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items) -> Result<(), &'static str>
|
|
where
|
|
KeyArg: EncodeLike<K>,
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
V: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem>,
|
|
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<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items)
|
|
where
|
|
KeyArg: EncodeLike<K>,
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
V: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem> + Clone + EncodeLike<V>,
|
|
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<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<usize, &'static str>
|
|
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.
|
|
pub trait StorageLinkedMap<K: FullCodec, V: FullCodec> {
|
|
/// The type that get/take return.
|
|
type Query;
|
|
|
|
/// The type that iterates over all `(key, value)`.
|
|
type Enumerator: Iterator<Item = (K, V)>;
|
|
|
|
/// Does the value (explicitly) exist in storage?
|
|
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool;
|
|
|
|
/// Load the value associated with the given key from the map.
|
|
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
|
|
|
/// Swap the values of two keys.
|
|
fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2);
|
|
|
|
/// Store a value to be associated with the given key from the map.
|
|
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg);
|
|
|
|
/// Remove the value under a key.
|
|
fn remove<KeyArg: EncodeLike<K>>(key: KeyArg);
|
|
|
|
/// Mutate the value under a key.
|
|
fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R;
|
|
|
|
/// Take the value under a key.
|
|
fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
|
|
|
/// Return current head element.
|
|
fn head() -> Option<K>;
|
|
|
|
/// 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<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<usize, &'static str>
|
|
where V: codec::DecodeLength + Len;
|
|
}
|
|
|
|
/// 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.
|
|
pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
|
/// The type that get/take returns.
|
|
type Query;
|
|
|
|
fn exists<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> bool
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>;
|
|
|
|
fn get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>;
|
|
|
|
fn take<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>;
|
|
|
|
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>,
|
|
VArg: EncodeLike<V>;
|
|
|
|
fn remove<KArg1, KArg2>(k1: KArg1, k2: KArg2)
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>;
|
|
|
|
fn remove_prefix<KArg1>(k1: KArg1) where KArg1: ?Sized + EncodeLike<K1>;
|
|
|
|
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>,
|
|
F: FnOnce(&mut Self::Query) -> R;
|
|
|
|
fn append<Items, Item, EncodeLikeItem, KArg1, KArg2>(
|
|
k1: KArg1,
|
|
k2: KArg2,
|
|
items: Items,
|
|
) -> Result<(), &'static str>
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>,
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
V: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem>,
|
|
Items::IntoIter: ExactSizeIterator;
|
|
|
|
fn append_or_insert<Items, Item, EncodeLikeItem, KArg1, KArg2>(
|
|
k1: KArg1,
|
|
k2: KArg2,
|
|
items: Items,
|
|
)
|
|
where
|
|
KArg1: EncodeLike<K1>,
|
|
KArg2: EncodeLike<K2>,
|
|
Item: Encode,
|
|
EncodeLikeItem: EncodeLike<Item>,
|
|
V: EncodeAppend<Item=Item>,
|
|
Items: IntoIterator<Item=EncodeLikeItem> + Clone + EncodeLike<V>,
|
|
Items::IntoIter: ExactSizeIterator;
|
|
}
|