Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(prelude_import)]
- #![no_std]
- //! Support code for the runtime.
- #[prelude_import]
- use std::prelude::v1::*;
- #[macro_use]
- extern crate std as std;
- #[macro_use]
- extern crate bitmask;
- pub use self::storage::hashed::generator::{
- Blake2_128, Blake2_256, HashedStorage, Twox128, Twox256, Twox64Concat,
- };
- pub use self::storage::unhashed::generator::UnhashedStorage;
- #[doc(hidden)]
- pub use codec;
- #[cfg(feature = "std")]
- #[doc(hidden)]
- pub use once_cell;
- #[doc(hidden)]
- pub use paste;
- #[cfg(feature = "std")]
- pub use serde;
- pub use sr_primitives as runtime_primitives;
- #[doc(hidden)]
- pub use sr_std as rstd;
- #[macro_use]
- pub mod dispatch {
- //! Dispatch system. Contains a macro for defining runtime modules and
- //! generating values representing lazy module function calls.
- pub use crate::codec::{Codec, Decode, Encode, EncodeAsRef, HasCompact, Input, Output};
- pub use crate::rstd::prelude::{Clone, Eq, PartialEq, Vec};
- pub use crate::rstd::result;
- pub use srml_metadata::{
- DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, FunctionMetadata,
- };
- #[cfg(feature = "std")]
- pub use std::fmt;
- /// A type that cannot be instantiated.
- pub enum Never {}
- /// Result of a module function call; either nothing (functions are only called for "side effects")
- /// or an error message.
- pub type Result = result::Result<(), &'static str>;
- /// A lazy call (module function and argument values) that can be executed via its `dispatch`
- /// method.
- pub trait Dispatchable {
- /// Every function call from your runtime has an origin, which specifies where the extrinsic was
- /// generated from. In the case of a signed extrinsic (transaction), the origin contains an
- /// identifier for the caller. The origin can be empty in the case of an inherent extrinsic.
- type Origin;
- type Trait;
- fn dispatch(self, origin: Self::Origin) -> Result;
- }
- /// Serializable version of Dispatchable.
- /// This value can be used as a "function" in an extrinsic.
- pub trait Callable {
- type Call: Dispatchable + Codec + Clone + PartialEq + Eq;
- }
- pub type CallableCallFor<A> = <A as Callable>::Call;
- #[cfg(feature = "std")]
- pub trait Parameter: Codec + Clone + Eq + fmt::Debug {}
- #[cfg(feature = "std")]
- impl<T> Parameter for T where T: Codec + Clone + Eq + fmt::Debug {}
- pub trait IsSubType<T: Callable> {
- fn is_aux_sub_type(&self) -> Option<&<T as Callable>::Call>;
- }
- }
- #[macro_use]
- pub mod storage {
- //! Stuff to do with the runtime's storage.
- use crate::rstd::borrow::Borrow;
- use crate::rstd::prelude::*;
- use codec::{Codec, Decode, Encode, EncodeAppend, Input, KeyedVec};
- use hashed::generator::{HashedStorage, StorageHasher};
- use unhashed::generator::UnhashedStorage;
- #[macro_use]
- pub mod storage_items {
- //! Strongly typed wrappers around values in storage.
- //!
- //! This crate exports a macro `storage_items!` and traits describing behavior of generated
- //! structs.
- //!
- //! Three kinds of data types are currently supported:
- //! - values
- //! - maps
- //!
- //! # Examples:
- //!
- //! ```rust
- //! #[macro_use]
- //! extern crate srml_support;
- //!
- //! type AuthorityId = [u8; 32];
- //! type Balance = u64;
- //! pub type SessionKey = [u8; 32];
- //!
- //! storage_items! {
- //! // public value
- //! pub Value: b"putd_key" => SessionKey;
- //! // private map.
- //! Balances: b"private_map:" => map [AuthorityId => Balance];
- //! }
- //!
- //!# fn main() { }
- //! ```
- #[doc(hidden)]
- pub use crate::rstd::borrow::Borrow;
- #[doc(hidden)]
- pub use crate::rstd::boxed::Box;
- #[doc(hidden)]
- pub use crate::rstd::marker::PhantomData;
- }
- pub mod unhashed {
- //! Operation on unhashed runtime storage
- use super::{Codec, Decode, Encode, IncrementalInput, KeyedVec, Vec};
- use crate::rstd::borrow::Borrow;
- pub mod generator {
- use crate::codec;
- use crate::rstd::vec::Vec;
- /// Abstraction around storage with unhashed access.
- pub trait UnhashedStorage {
- /// true if the key exists in storage.
- fn exists(&self, key: &[u8]) -> bool;
- /// Load the bytes of a key from storage. Can panic if the type is incorrect.
- fn get<T: codec::Decode>(&self, key: &[u8]) -> Option<T>;
- /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if
- /// it's not there.
- fn require<T: codec::Decode>(&self, key: &[u8]) -> T {
- self.get(key).expect("Required values must be in storage")
- }
- /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's
- /// default is returned if it's not there.
- fn get_or_default<T: codec::Decode + Default>(&self, key: &[u8]) -> T {
- self.get(key).unwrap_or_default()
- }
- /// Put a value in under a key.
- fn put<T: codec::Encode>(&mut self, key: &[u8], val: &T);
- /// Remove the bytes of a key from storage.
- fn kill(&mut self, key: &[u8]);
- /// Remove the bytes of a key from storage.
- fn kill_prefix(&mut self, prefix: &[u8]);
- /// Take a value from storage, deleting it after reading.
- fn take<T: codec::Decode>(&mut self, key: &[u8]) -> Option<T> {
- let value = self.get(key);
- self.kill(key);
- value
- }
- /// Take a value from storage, deleting it after reading.
- fn take_or_panic<T: codec::Decode>(&mut self, key: &[u8]) -> T {
- self.take(key).expect("Required values must be in storage")
- }
- /// Take a value from storage, deleting it after reading.
- fn take_or_default<T: codec::Decode + Default>(&mut self, key: &[u8]) -> T {
- self.take(key).unwrap_or_default()
- }
- /// Get a Vec of bytes from storage.
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>>;
- /// Put a raw byte slice into storage.
- fn put_raw(&mut self, key: &[u8], value: &[u8]);
- }
- #[cfg(feature = "std")]
- impl UnhashedStorage for sr_primitives::StorageOverlay {
- fn exists(&self, key: &[u8]) -> bool {
- self.contains_key(key)
- }
- fn get<T: codec::Decode>(&self, key: &[u8]) -> Option<T> {
- self.get(key).map(|x| {
- codec::Decode::decode(&mut x.as_slice())
- .expect("Unable to decode expected type.")
- })
- }
- fn put<T: codec::Encode>(&mut self, key: &[u8], val: &T) {
- self.insert(key.to_vec(), codec::Encode::encode(val));
- }
- fn kill(&mut self, key: &[u8]) {
- self.remove(key);
- }
- fn kill_prefix(&mut self, prefix: &[u8]) {
- self.retain(|key, _| !key.starts_with(prefix))
- }
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>> {
- self.get(key).cloned()
- }
- fn put_raw(&mut self, key: &[u8], value: &[u8]) {
- self.insert(key.to_vec(), value.to_vec());
- }
- }
- /// 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.
- ///
- /// # Mapping of keys to a storage path
- ///
- /// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts.
- /// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part
- /// is a hash of a `Key2`.
- ///
- /// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie.
- pub trait StorageDoubleMap<K1: codec::Codec, K2: codec::Codec, V: codec::Codec> {
- /// The type that get/take returns.
- type Query;
- /// Get the prefix key in storage.
- fn prefix() -> &'static [u8];
- /// Get the storage key used to fetch a value corresponding to a specific key.
- fn key_for(k1: &K1, k2: &K2) -> Vec<u8>;
- /// Get the storage prefix used to fetch keys corresponding to a specific key1.
- fn prefix_for(k1: &K1) -> Vec<u8>;
- /// true if the value is defined in storage.
- fn exists<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &S) -> bool {
- storage.exists(&Self::key_for(k1, k2))
- }
- /// Load the value associated with the given key from the map.
- fn get<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &S) -> Self::Query;
- /// Take the value under a key.
- fn take<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &mut S) -> Self::Query;
- /// Store a value to be associated with the given key from the map.
- fn insert<S: UnhashedStorage>(k1: &K1, k2: &K2, val: &V, storage: &mut S) {
- storage.put(&Self::key_for(k1, k2), val);
- }
- /// Remove the value under a key.
- fn remove<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &mut S) {
- storage.kill(&Self::key_for(k1, k2));
- }
- /// Removes all entries that shares the `k1` as the first key.
- fn remove_prefix<S: UnhashedStorage>(k1: &K1, storage: &mut S) {
- storage.kill_prefix(&Self::prefix_for(k1));
- }
- /// Mutate the value under a key.
- fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: UnhashedStorage>(
- k1: &K1,
- k2: &K2,
- f: F,
- storage: &mut S,
- ) -> R;
- /// Append the given items to the value under the key specified.
- fn append<I, S: UnhashedStorage>(
- k1: &K1,
- k2: &K2,
- items: &[I],
- storage: &mut S,
- ) -> Result<(), &'static str>
- where
- I: codec::Encode,
- V: codec::EncodeAppend<Item = I>,
- {
- let key = Self::key_for(k1, k2);
- let new_val = <V as codec::EncodeAppend>::append(
- storage.get_raw(&key).unwrap_or_default(),
- items,
- )
- .ok_or_else(|| "Could not append given item")?;
- storage.put_raw(&key, &new_val);
- Ok(())
- }
- }
- }
- /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
- pub fn get<T: Decode + Sized>(key: &[u8]) -> Option<T> {
- runtime_io::read_storage(key, &mut [0; 0][..], 0).map(|_| {
- let mut input = IncrementalInput { key, pos: 0 };
- Decode::decode(&mut input)
- .expect("storage is not null, therefore must be a valid type")
- })
- }
- /// Return the value of the item in storage under `key`, or the type's default if there is no
- /// explicit entry.
- pub fn get_or_default<T: Decode + Sized + Default>(key: &[u8]) -> T {
- get(key).unwrap_or_else(Default::default)
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry.
- pub fn get_or<T: Decode + Sized>(key: &[u8], default_value: T) -> T {
- get(key).unwrap_or(default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry.
- pub fn get_or_else<T: Decode + Sized, F: FnOnce() -> T>(key: &[u8], default_value: F) -> T {
- get(key).unwrap_or_else(default_value)
- }
- /// Put `value` in storage under `key`.
- pub fn put<T: Encode>(key: &[u8], value: &T) {
- value.using_encoded(|slice| runtime_io::set_storage(key, slice));
- }
- /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
- pub fn take<T: Decode + Sized>(key: &[u8]) -> Option<T> {
- let r = get(key);
- if r.is_some() {
- kill(key);
- }
- r
- }
- /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
- /// the default for its type.
- pub fn take_or_default<T: Decode + Sized + Default>(key: &[u8]) -> T {
- take(key).unwrap_or_else(Default::default)
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or<T: Decode + Sized>(key: &[u8], default_value: T) -> T {
- take(key).unwrap_or(default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or_else<T: Decode + Sized, F: FnOnce() -> T>(
- key: &[u8],
- default_value: F,
- ) -> T {
- take(key).unwrap_or_else(default_value)
- }
- /// Check to see if `key` has an explicit entry in storage.
- pub fn exists(key: &[u8]) -> bool {
- runtime_io::read_storage(key, &mut [0; 0][..], 0).is_some()
- }
- /// Ensure `key` has no explicit entry in storage.
- pub fn kill(key: &[u8]) {
- runtime_io::clear_storage(key);
- }
- /// Ensure keys with the given `prefix` have no entries in storage.
- pub fn kill_prefix(prefix: &[u8]) {
- runtime_io::clear_prefix(prefix);
- }
- /// Get a Vec of bytes from storage.
- pub fn get_raw(key: &[u8]) -> Option<Vec<u8>> {
- runtime_io::storage(key)
- }
- /// Put a raw byte slice into storage.
- pub fn put_raw(key: &[u8], value: &[u8]) {
- runtime_io::set_storage(key, value)
- }
- /// A trait to conveniently store a vector of storable data.
- pub trait StorageVec {
- type Item: Default + Sized + Codec;
- const PREFIX: &'static [u8];
- /// Get the current set of items.
- fn items() -> Vec<Self::Item> {
- (0..Self::count()).into_iter().map(Self::item).collect()
- }
- /// Set the current set of items.
- fn set_items<I, T>(items: I)
- where
- I: IntoIterator<Item = T>,
- T: Borrow<Self::Item>,
- {
- let mut count: u32 = 0;
- for i in items.into_iter() {
- put(&count.to_keyed_vec(Self::PREFIX), i.borrow());
- count = count
- .checked_add(1)
- .expect("exceeded runtime storage capacity");
- }
- Self::set_count(count);
- }
- fn set_item(index: u32, item: &Self::Item) {
- if index < Self::count() {
- put(&index.to_keyed_vec(Self::PREFIX), item);
- }
- }
- fn clear_item(index: u32) {
- if index < Self::count() {
- kill(&index.to_keyed_vec(Self::PREFIX));
- }
- }
- fn item(index: u32) -> Self::Item {
- get_or_default(&index.to_keyed_vec(Self::PREFIX))
- }
- fn set_count(count: u32) {
- (count..Self::count()).for_each(Self::clear_item);
- put(&b"len".to_keyed_vec(Self::PREFIX), &count);
- }
- fn count() -> u32 {
- get_or_default(&b"len".to_keyed_vec(Self::PREFIX))
- }
- }
- }
- pub mod hashed {
- //! Operation on runtime storage using hashed keys.
- pub mod generator {
- //! Abstract storage to use on HashedStorage trait
- use crate::codec;
- use crate::rstd::prelude::{Box, Vec};
- #[cfg(feature = "std")]
- use crate::storage::unhashed::generator::UnhashedStorage;
- use runtime_io::{blake2_128, blake2_256, twox_128, twox_256, twox_64};
- pub trait StorageHasher: 'static {
- type Output: AsRef<[u8]>;
- fn hash(x: &[u8]) -> Self::Output;
- }
- /// Hash storage keys with `concat(twox128(key), key)`
- pub struct Twox64Concat;
- impl StorageHasher for Twox64Concat {
- type Output = Vec<u8>;
- fn hash(x: &[u8]) -> Vec<u8> {
- twox_64(x)
- .into_iter()
- .chain(x.into_iter())
- .cloned()
- .collect::<Vec<_>>()
- }
- }
- /// Hash storage keys with blake2 128
- pub struct Blake2_128;
- impl StorageHasher for Blake2_128 {
- type Output = [u8; 16];
- fn hash(x: &[u8]) -> [u8; 16] {
- blake2_128(x)
- }
- }
- /// Hash storage keys with blake2 256
- pub struct Blake2_256;
- impl StorageHasher for Blake2_256 {
- type Output = [u8; 32];
- fn hash(x: &[u8]) -> [u8; 32] {
- blake2_256(x)
- }
- }
- /// Hash storage keys with twox 128
- pub struct Twox128;
- impl StorageHasher for Twox128 {
- type Output = [u8; 16];
- fn hash(x: &[u8]) -> [u8; 16] {
- twox_128(x)
- }
- }
- /// Hash storage keys with twox 256
- pub struct Twox256;
- impl StorageHasher for Twox256 {
- type Output = [u8; 32];
- fn hash(x: &[u8]) -> [u8; 32] {
- twox_256(x)
- }
- }
- /// Abstraction around storage.
- pub trait HashedStorage<H: StorageHasher> {
- /// true if the key exists in storage.
- fn exists(&self, key: &[u8]) -> bool;
- /// Load the bytes of a key from storage. Can panic if the type is incorrect.
- fn get<T: codec::Decode>(&self, key: &[u8]) -> Option<T>;
- /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if
- /// it's not there.
- fn require<T: codec::Decode>(&self, key: &[u8]) -> T {
- self.get(key).expect("Required values must be in storage")
- }
- /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's
- /// default is returned if it's not there.
- fn get_or_default<T: codec::Decode + Default>(&self, key: &[u8]) -> T {
- self.get(key).unwrap_or_default()
- }
- /// Put a value in under a key.
- fn put<T: codec::Encode>(&mut self, key: &[u8], val: &T);
- /// Remove the bytes of a key from storage.
- fn kill(&mut self, key: &[u8]);
- /// Take a value from storage, deleting it after reading.
- fn take<T: codec::Decode>(&mut self, key: &[u8]) -> Option<T> {
- let value = self.get(key);
- self.kill(key);
- value
- }
- /// Take a value from storage, deleting it after reading.
- fn take_or_panic<T: codec::Decode>(&mut self, key: &[u8]) -> T {
- self.take(key).expect("Required values must be in storage")
- }
- /// Take a value from storage, deleting it after reading.
- fn take_or_default<T: codec::Decode + Default>(&mut self, key: &[u8]) -> T {
- self.take(key).unwrap_or_default()
- }
- /// Get a Vec of bytes from storage.
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>>;
- /// Put a raw byte slice into storage.
- fn put_raw(&mut self, key: &[u8], value: &[u8]);
- }
- #[cfg(feature = "std")]
- impl<H: StorageHasher> HashedStorage<H> for sr_primitives::StorageOverlay {
- fn exists(&self, key: &[u8]) -> bool {
- UnhashedStorage::exists(self, &H::hash(key).as_ref())
- }
- fn get<T: codec::Decode>(&self, key: &[u8]) -> Option<T> {
- UnhashedStorage::get(self, &H::hash(key).as_ref())
- }
- fn put<T: codec::Encode>(&mut self, key: &[u8], val: &T) {
- UnhashedStorage::put(self, &H::hash(key).as_ref(), val)
- }
- fn kill(&mut self, key: &[u8]) {
- UnhashedStorage::kill(self, &H::hash(key).as_ref())
- }
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>> {
- UnhashedStorage::get_raw(self, &H::hash(key).as_ref())
- }
- fn put_raw(&mut self, key: &[u8], value: &[u8]) {
- UnhashedStorage::put_raw(self, &H::hash(key).as_ref(), value)
- }
- }
- /// A strongly-typed value kept in storage.
- pub trait StorageValue<T: codec::Codec> {
- /// The type that get/take returns.
- type Query;
- /// Get the storage key.
- fn key() -> &'static [u8];
- /// true if the value is defined in storage.
- fn exists<S: HashedStorage<Twox128>>(storage: &S) -> bool {
- storage.exists(Self::key())
- }
- /// Load the value from the provided storage instance.
- fn get<S: HashedStorage<Twox128>>(storage: &S) -> Self::Query;
- /// Take a value from storage, removing it afterwards.
- fn take<S: HashedStorage<Twox128>>(storage: &mut S) -> Self::Query;
- /// Store a value under this key into the provided storage instance.
- fn put<S: HashedStorage<Twox128>>(val: &T, storage: &mut S) {
- storage.put(Self::key(), val)
- }
- /// Mutate this value
- fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: HashedStorage<Twox128>>(
- f: F,
- storage: &mut S,
- ) -> R;
- /// Clear the storage value.
- fn kill<S: HashedStorage<Twox128>>(storage: &mut S) {
- storage.kill(Self::key())
- }
- /// Append the given items to the value in the storage.
- ///
- /// `T` is required to implement `codec::EncodeAppend`.
- fn append<S: HashedStorage<Twox128>, I: codec::Encode>(
- items: &[I],
- storage: &mut S,
- ) -> Result<(), &'static str>
- where
- T: codec::EncodeAppend<Item = I>,
- {
- let new_val = <T as codec::EncodeAppend>::append(
- storage.get_raw(Self::key()).unwrap_or_default(),
- items,
- )
- .ok_or_else(|| "Could not append given item")?;
- storage.put_raw(Self::key(), &new_val);
- Ok(())
- }
- }
- /// A strongly-typed map in storage.
- pub trait StorageMap<K: codec::Codec, V: codec::Codec> {
- /// The type that get/take returns.
- type Query;
- type Hasher: StorageHasher;
- /// Get the prefix key in storage.
- fn prefix() -> &'static [u8];
- /// Get the storage key used to fetch a value corresponding to a specific key.
- fn key_for(x: &K) -> Vec<u8>;
- /// true if the value is defined in storage.
- fn exists<S: HashedStorage<Self::Hasher>>(key: &K, storage: &S) -> bool {
- storage.exists(&Self::key_for(key)[..])
- }
- /// Load the value associated with the given key from the map.
- fn get<S: HashedStorage<Self::Hasher>>(key: &K, storage: &S) -> Self::Query;
- /// Take the value under a key.
- fn take<S: HashedStorage<Self::Hasher>>(key: &K, storage: &mut S) -> Self::Query;
- /// Store a value to be associated with the given key from the map.
- fn insert<S: HashedStorage<Self::Hasher>>(key: &K, val: &V, storage: &mut S) {
- storage.put(&Self::key_for(key)[..], val);
- }
- /// Remove the value under a key.
- fn remove<S: HashedStorage<Self::Hasher>>(key: &K, storage: &mut S) {
- storage.kill(&Self::key_for(key)[..]);
- }
- /// Mutate the value under a key.
- fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: HashedStorage<Self::Hasher>>(
- key: &K,
- f: F,
- storage: &mut S,
- ) -> R;
- }
- /// A `StorageMap` with enumerable entries.
- pub trait EnumerableStorageMap<K: codec::Codec, V: codec::Codec>:
- StorageMap<K, V>
- {
- /// Return current head element.
- fn head<S: HashedStorage<Self::Hasher>>(storage: &S) -> Option<K>;
- /// Enumerate all elements in the map.
- fn enumerate<'a, S: HashedStorage<Self::Hasher>>(
- storage: &'a S,
- ) -> Box<dyn Iterator<Item = (K, V)> + 'a>
- where
- K: 'a,
- V: 'a;
- }
- /// A `StorageMap` with appendable entries.
- pub trait AppendableStorageMap<K: codec::Codec, V: codec::Codec>:
- StorageMap<K, V>
- {
- /// Append the given items to the value in the storage.
- ///
- /// `T` is required to implement `codec::EncodeAppend`.
- fn append<S: HashedStorage<Self::Hasher>, I: codec::Encode>(
- key: &K,
- items: &[I],
- storage: &mut S,
- ) -> Result<(), &'static str>
- where
- V: codec::EncodeAppend<Item = I>,
- {
- let k = Self::key_for(key);
- let new_val = <V as codec::EncodeAppend>::append(
- storage.get_raw(&k[..]).unwrap_or_default(),
- items,
- )
- .ok_or_else(|| "Could not append given item")?;
- storage.put_raw(&k[..], &new_val);
- Ok(())
- }
- }
- }
- use super::unhashed;
- use crate::codec::{Codec, Decode, Encode, KeyedVec};
- use crate::rstd::borrow::Borrow;
- use crate::rstd::prelude::*;
- use runtime_io::{self, twox_128};
- /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
- pub fn get<T: Decode + Sized, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- ) -> Option<T> {
- unhashed::get(&hash(key).as_ref())
- }
- /// Return the value of the item in storage under `key`, or the type's default if there is no
- /// explicit entry.
- pub fn get_or_default<
- T: Decode + Sized + Default,
- HashFn: Fn(&[u8]) -> R,
- R: AsRef<[u8]>,
- >(
- hash: &HashFn,
- key: &[u8],
- ) -> T {
- unhashed::get_or_default(&hash(key).as_ref())
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry.
- pub fn get_or<T: Decode + Sized, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- default_value: T,
- ) -> T {
- unhashed::get_or(&hash(key).as_ref(), default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry.
- pub fn get_or_else<
- T: Decode + Sized,
- F: FnOnce() -> T,
- HashFn: Fn(&[u8]) -> R,
- R: AsRef<[u8]>,
- >(
- hash: &HashFn,
- key: &[u8],
- default_value: F,
- ) -> T {
- unhashed::get_or_else(&hash(key).as_ref(), default_value)
- }
- /// Put `value` in storage under `key`.
- pub fn put<T: Encode, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- value: &T,
- ) {
- unhashed::put(&hash(key).as_ref(), value)
- }
- /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
- pub fn take<T: Decode + Sized, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- ) -> Option<T> {
- unhashed::take(&hash(key).as_ref())
- }
- /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
- /// the default for its type.
- pub fn take_or_default<
- T: Decode + Sized + Default,
- HashFn: Fn(&[u8]) -> R,
- R: AsRef<[u8]>,
- >(
- hash: &HashFn,
- key: &[u8],
- ) -> T {
- unhashed::take_or_default(&hash(key).as_ref())
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or<T: Decode + Sized, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- default_value: T,
- ) -> T {
- unhashed::take_or(&hash(key).as_ref(), default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or_else<
- T: Decode + Sized,
- F: FnOnce() -> T,
- HashFn: Fn(&[u8]) -> R,
- R: AsRef<[u8]>,
- >(
- hash: &HashFn,
- key: &[u8],
- default_value: F,
- ) -> T {
- unhashed::take_or_else(&hash(key).as_ref(), default_value)
- }
- /// Check to see if `key` has an explicit entry in storage.
- pub fn exists<HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> bool {
- unhashed::exists(&hash(key).as_ref())
- }
- /// Ensure `key` has no explicit entry in storage.
- pub fn kill<HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) {
- unhashed::kill(&hash(key).as_ref())
- }
- /// Get a Vec of bytes from storage.
- pub fn get_raw<HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- ) -> Option<Vec<u8>> {
- unhashed::get_raw(&hash(key).as_ref())
- }
- /// Put a raw byte slice into storage.
- pub fn put_raw<HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(
- hash: &HashFn,
- key: &[u8],
- value: &[u8],
- ) {
- unhashed::put_raw(&hash(key).as_ref(), value)
- }
- /// A trait to conveniently store a vector of storable data.
- ///
- /// It uses twox_128 hasher. Final keys in trie are `twox_128(concatenation(PREFIX,count))`
- pub trait StorageVec {
- type Item: Default + Sized + Codec;
- const PREFIX: &'static [u8];
- /// Get the current set of items.
- fn items() -> Vec<Self::Item> {
- (0..Self::count()).into_iter().map(Self::item).collect()
- }
- /// Set the current set of items.
- fn set_items<I, T>(items: I)
- where
- I: IntoIterator<Item = T>,
- T: Borrow<Self::Item>,
- {
- let mut count: u32 = 0;
- for i in items.into_iter() {
- put(&twox_128, &count.to_keyed_vec(Self::PREFIX), i.borrow());
- count = count
- .checked_add(1)
- .expect("exceeded runtime storage capacity");
- }
- Self::set_count(count);
- }
- /// Push an item.
- fn push(item: &Self::Item) {
- let len = Self::count();
- put(&twox_128, &len.to_keyed_vec(Self::PREFIX), item);
- Self::set_count(len + 1);
- }
- fn set_item(index: u32, item: &Self::Item) {
- if index < Self::count() {
- put(&twox_128, &index.to_keyed_vec(Self::PREFIX), item);
- }
- }
- fn clear_item(index: u32) {
- if index < Self::count() {
- kill(&twox_128, &index.to_keyed_vec(Self::PREFIX));
- }
- }
- fn item(index: u32) -> Self::Item {
- get_or_default(&twox_128, &index.to_keyed_vec(Self::PREFIX))
- }
- fn set_count(count: u32) {
- (count..Self::count()).for_each(Self::clear_item);
- put(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count);
- }
- fn count() -> u32 {
- get_or_default(&twox_128, &b"len".to_keyed_vec(Self::PREFIX))
- }
- }
- }
- struct IncrementalInput<'a> {
- key: &'a [u8],
- pos: usize,
- }
- impl<'a> Input for IncrementalInput<'a> {
- fn read(&mut self, into: &mut [u8]) -> usize {
- let len = runtime_io::read_storage(self.key, into, self.pos).unwrap_or(0);
- let read = crate::rstd::cmp::min(len, into.len());
- self.pos += read;
- read
- }
- }
- struct IncrementalChildInput<'a> {
- storage_key: &'a [u8],
- key: &'a [u8],
- pos: usize,
- }
- impl<'a> Input for IncrementalChildInput<'a> {
- fn read(&mut self, into: &mut [u8]) -> usize {
- let len = runtime_io::read_child_storage(self.storage_key, self.key, into, self.pos)
- .unwrap_or(0);
- let read = crate::rstd::cmp::min(len, into.len());
- self.pos += read;
- read
- }
- }
- /// The underlying runtime storage.
- pub struct RuntimeStorage;
- impl<H: StorageHasher> HashedStorage<H> for RuntimeStorage {
- fn exists(&self, key: &[u8]) -> bool {
- hashed::exists(&H::hash, key)
- }
- /// Load the bytes of a key from storage. Can panic if the type is incorrect.
- fn get<T: Decode>(&self, key: &[u8]) -> Option<T> {
- hashed::get(&H::hash, key)
- }
- /// Put a value in under a key.
- fn put<T: Encode>(&mut self, key: &[u8], val: &T) {
- hashed::put(&H::hash, key, val)
- }
- /// Remove the bytes of a key from storage.
- fn kill(&mut self, key: &[u8]) {
- hashed::kill(&H::hash, key)
- }
- /// Take a value from storage, deleting it after reading.
- fn take<T: Decode>(&mut self, key: &[u8]) -> Option<T> {
- hashed::take(&H::hash, key)
- }
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>> {
- hashed::get_raw(&H::hash, key)
- }
- fn put_raw(&mut self, key: &[u8], value: &[u8]) {
- hashed::put_raw(&H::hash, key, value)
- }
- }
- impl UnhashedStorage for RuntimeStorage {
- fn exists(&self, key: &[u8]) -> bool {
- unhashed::exists(key)
- }
- /// Load the bytes of a key from storage. Can panic if the type is incorrect.
- fn get<T: Decode>(&self, key: &[u8]) -> Option<T> {
- unhashed::get(key)
- }
- /// Put a value in under a key.
- fn put<T: Encode>(&mut self, key: &[u8], val: &T) {
- unhashed::put(key, val)
- }
- /// Remove the bytes of a key from storage.
- fn kill(&mut self, key: &[u8]) {
- unhashed::kill(key)
- }
- /// Remove the bytes of a key from storage.
- fn kill_prefix(&mut self, prefix: &[u8]) {
- unhashed::kill_prefix(prefix)
- }
- /// Take a value from storage, deleting it after reading.
- fn take<T: Decode>(&mut self, key: &[u8]) -> Option<T> {
- unhashed::take(key)
- }
- fn get_raw(&self, key: &[u8]) -> Option<Vec<u8>> {
- unhashed::get_raw(key)
- }
- fn put_raw(&mut self, key: &[u8], value: &[u8]) {
- unhashed::put_raw(key, value)
- }
- }
- /// A trait for working with macro-generated storage values under the substrate storage API.
- pub trait StorageValue<T: Codec> {
- /// The type that get/take return.
- type Query;
- /// Get the storage key.
- fn key() -> &'static [u8];
- /// 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: Borrow<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<I: Encode>(items: &[I]) -> Result<(), &'static str>
- where
- T: EncodeAppend<Item = I>;
- }
- impl<T: Codec, U> StorageValue<T> for U
- where
- U: hashed::generator::StorageValue<T>,
- {
- type Query = U::Query;
- fn key() -> &'static [u8] {
- <U as hashed::generator::StorageValue<T>>::key()
- }
- fn exists() -> bool {
- U::exists(&RuntimeStorage)
- }
- fn get() -> Self::Query {
- U::get(&RuntimeStorage)
- }
- fn put<Arg: Borrow<T>>(val: Arg) {
- U::put(val.borrow(), &mut RuntimeStorage)
- }
- fn mutate<R, F: FnOnce(&mut Self::Query) -> R>(f: F) -> R {
- U::mutate(f, &mut RuntimeStorage)
- }
- fn kill() {
- U::kill(&mut RuntimeStorage)
- }
- fn take() -> Self::Query {
- U::take(&mut RuntimeStorage)
- }
- fn append<I: Encode>(items: &[I]) -> Result<(), &'static str>
- where
- T: EncodeAppend<Item = I>,
- {
- U::append(items, &mut RuntimeStorage)
- }
- }
- /// A strongly-typed map in storage.
- pub trait StorageMap<K: Codec, V: Codec> {
- /// The type that get/take return.
- type Query;
- /// Get the prefix key in storage.
- fn prefix() -> &'static [u8];
- /// Get the storage key used to fetch a value corresponding to a specific key.
- fn key_for<KeyArg: Borrow<K>>(key: KeyArg) -> Vec<u8>;
- /// Does the value (explicitly) exist in storage?
- fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool;
- /// Load the value associated with the given key from the map.
- fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
- /// Store a value to be associated with the given key from the map.
- fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg);
- /// Remove the value under a key.
- fn remove<KeyArg: Borrow<K>>(key: KeyArg);
- /// Mutate the value under a key.
- fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R;
- /// Take the value under a key.
- fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
- }
- impl<K: Codec, V: Codec, U> StorageMap<K, V> for U
- where
- U: hashed::generator::StorageMap<K, V>,
- {
- type Query = U::Query;
- fn prefix() -> &'static [u8] {
- <U as hashed::generator::StorageMap<K, V>>::prefix()
- }
- fn key_for<KeyArg: Borrow<K>>(key: KeyArg) -> Vec<u8> {
- <U as hashed::generator::StorageMap<K, V>>::key_for(key.borrow())
- }
- fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool {
- U::exists(key.borrow(), &RuntimeStorage)
- }
- fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
- U::get(key.borrow(), &RuntimeStorage)
- }
- fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg) {
- U::insert(key.borrow(), val.borrow(), &mut RuntimeStorage)
- }
- fn remove<KeyArg: Borrow<K>>(key: KeyArg) {
- U::remove(key.borrow(), &mut RuntimeStorage)
- }
- fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
- U::mutate(key.borrow(), f, &mut RuntimeStorage)
- }
- fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
- U::take(key.borrow(), &mut RuntimeStorage)
- }
- }
- /// A storage map with values that can be appended to.
- pub trait AppendableStorageMap<K: Codec, V: Codec>: StorageMap<K, V> {
- /// Append the given item to the value in the storage.
- ///
- /// `T` is required to implement `codec::EncodeAppend`.
- fn append<KeyArg: Borrow<K>, I: Encode>(
- key: KeyArg,
- items: &[I],
- ) -> Result<(), &'static str>
- where
- V: EncodeAppend<Item = I>;
- }
- impl<K: Codec, V: Codec, U> AppendableStorageMap<K, V> for U
- where
- U: hashed::generator::AppendableStorageMap<K, V>,
- {
- fn append<KeyArg: Borrow<K>, I: Encode>(
- key: KeyArg,
- items: &[I],
- ) -> Result<(), &'static str>
- where
- V: EncodeAppend<Item = I>,
- {
- U::append(key.borrow(), items, &mut RuntimeStorage)
- }
- }
- /// A storage map that can be enumerated.
- ///
- /// Primarily useful for off-chain computations.
- /// Runtime implementors should avoid enumerating storage entries on-chain.
- pub trait EnumerableStorageMap<K: Codec, V: Codec>: StorageMap<K, V> {
- /// Return current head element.
- fn head() -> Option<K>;
- /// Enumerate all elements in the map.
- fn enumerate() -> Box<dyn Iterator<Item = (K, V)>>
- where
- K: 'static,
- V: 'static;
- }
- impl<K: Codec, V: Codec, U> EnumerableStorageMap<K, V> for U
- where
- U: hashed::generator::EnumerableStorageMap<K, V>,
- {
- fn head() -> Option<K> {
- <U as hashed::generator::EnumerableStorageMap<K, V>>::head(&RuntimeStorage)
- }
- fn enumerate() -> Box<dyn Iterator<Item = (K, V)>>
- where
- K: 'static,
- V: 'static,
- {
- <U as hashed::generator::EnumerableStorageMap<K, V>>::enumerate(&RuntimeStorage)
- }
- }
- /// 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.
- ///
- /// # Mapping of keys to a storage path
- ///
- /// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts.
- /// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part
- /// is a hash of a `Key2`.
- ///
- /// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie.
- pub trait StorageDoubleMap<K1: Codec, K2: Codec, V: Codec> {
- /// The type that get/take returns.
- type Query;
- /// Get the prefix key in storage.
- fn prefix() -> &'static [u8];
- /// Get the storage key used to fetch a value corresponding to a specific key.
- fn key_for<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Vec<u8>;
- /// Get the storage prefix used to fetch keys corresponding to a specific key1.
- fn prefix_for<KArg1: Borrow<K1>>(k1: KArg1) -> Vec<u8>;
- /// true if the value is defined in storage.
- fn exists<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> bool;
- /// Load the value associated with the given key from the map.
- fn get<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Self::Query;
- /// Take the value under a key.
- fn take<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Self::Query;
- /// Store a value to be associated with the given key from the map.
- fn insert<KArg1: Borrow<K1>, KArg2: Borrow<K2>, VArg: Borrow<V>>(
- k1: KArg1,
- k2: KArg2,
- val: VArg,
- );
- /// Remove the value under a key.
- fn remove<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2);
- /// Removes all entries that shares the `k1` as the first key.
- fn remove_prefix<KArg1: Borrow<K1>>(k1: KArg1);
- /// Mutate the value under a key.
- fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
- where
- KArg1: Borrow<K1>,
- KArg2: Borrow<K2>,
- F: FnOnce(&mut Self::Query) -> R;
- /// Append the given items to the value under the key specified.
- ///
- /// `V` is required to implement `codec::EncodeAppend<Item=I>`.
- fn append<KArg1, KArg2, I>(k1: KArg1, k2: KArg2, items: &[I]) -> Result<(), &'static str>
- where
- KArg1: Borrow<K1>,
- KArg2: Borrow<K2>,
- I: codec::Encode,
- V: EncodeAppend<Item = I>;
- }
- impl<K1: Codec, K2: Codec, V: Codec, U> StorageDoubleMap<K1, K2, V> for U
- where
- U: unhashed::generator::StorageDoubleMap<K1, K2, V>,
- {
- type Query = U::Query;
- fn prefix() -> &'static [u8] {
- <U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::prefix()
- }
- fn key_for<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Vec<u8> {
- <U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::key_for(
- k1.borrow(),
- k2.borrow(),
- )
- }
- fn prefix_for<KArg1: Borrow<K1>>(k1: KArg1) -> Vec<u8> {
- <U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::prefix_for(k1.borrow())
- }
- fn exists<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> bool {
- U::exists(k1.borrow(), k2.borrow(), &RuntimeStorage)
- }
- fn get<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Self::Query {
- U::get(k1.borrow(), k2.borrow(), &RuntimeStorage)
- }
- fn take<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Self::Query {
- U::take(k1.borrow(), k2.borrow(), &mut RuntimeStorage)
- }
- fn insert<KArg1: Borrow<K1>, KArg2: Borrow<K2>, VArg: Borrow<V>>(
- k1: KArg1,
- k2: KArg2,
- val: VArg,
- ) {
- U::insert(k1.borrow(), k2.borrow(), val.borrow(), &mut RuntimeStorage)
- }
- fn remove<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) {
- U::remove(k1.borrow(), k2.borrow(), &mut RuntimeStorage)
- }
- fn remove_prefix<KArg1: Borrow<K1>>(k1: KArg1) {
- U::remove_prefix(k1.borrow(), &mut RuntimeStorage)
- }
- fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
- where
- KArg1: Borrow<K1>,
- KArg2: Borrow<K2>,
- F: FnOnce(&mut Self::Query) -> R,
- {
- U::mutate(k1.borrow(), k2.borrow(), f, &mut RuntimeStorage)
- }
- fn append<KArg1, KArg2, I>(k1: KArg1, k2: KArg2, items: &[I]) -> Result<(), &'static str>
- where
- KArg1: Borrow<K1>,
- KArg2: Borrow<K2>,
- I: codec::Encode,
- V: EncodeAppend<Item = I>,
- {
- U::append(k1.borrow(), k2.borrow(), items, &mut RuntimeStorage)
- }
- }
- /// child storage NOTE could replace unhashed by having only one kind of storage (root being null storage
- /// key (storage_key can become Option<&[u8]>).
- /// This module is a currently only a variant of unhashed with additional `storage_key`.
- /// Note that `storage_key` must be unique and strong (strong in the sense of being long enough to
- /// avoid collision from a resistant hash function (which unique implies)).
- pub mod child {
- use super::{Codec, Decode, IncrementalChildInput, Vec};
- /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
- pub fn get<T: Codec + Sized>(storage_key: &[u8], key: &[u8]) -> Option<T> {
- runtime_io::read_child_storage(storage_key, key, &mut [0; 0][..], 0).map(|_| {
- let mut input = IncrementalChildInput {
- storage_key,
- key,
- pos: 0,
- };
- Decode::decode(&mut input)
- .expect("storage is not null, therefore must be a valid type")
- })
- }
- /// Return the value of the item in storage under `key`, or the type's default if there is no
- /// explicit entry.
- pub fn get_or_default<T: Codec + Sized + Default>(storage_key: &[u8], key: &[u8]) -> T {
- get(storage_key, key).unwrap_or_else(Default::default)
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry.
- pub fn get_or<T: Codec + Sized>(storage_key: &[u8], key: &[u8], default_value: T) -> T {
- get(storage_key, key).unwrap_or(default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry.
- pub fn get_or_else<T: Codec + Sized, F: FnOnce() -> T>(
- storage_key: &[u8],
- key: &[u8],
- default_value: F,
- ) -> T {
- get(storage_key, key).unwrap_or_else(default_value)
- }
- /// Put `value` in storage under `key`.
- pub fn put<T: Codec>(storage_key: &[u8], key: &[u8], value: &T) {
- value.using_encoded(|slice| runtime_io::set_child_storage(storage_key, key, slice));
- }
- /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
- pub fn take<T: Codec + Sized>(storage_key: &[u8], key: &[u8]) -> Option<T> {
- let r = get(storage_key, key);
- if r.is_some() {
- kill(storage_key, key);
- }
- r
- }
- /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
- /// the default for its type.
- pub fn take_or_default<T: Codec + Sized + Default>(storage_key: &[u8], key: &[u8]) -> T {
- take(storage_key, key).unwrap_or_else(Default::default)
- }
- /// Return the value of the item in storage under `key`, or `default_value` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or<T: Codec + Sized>(storage_key: &[u8], key: &[u8], default_value: T) -> T {
- take(storage_key, key).unwrap_or(default_value)
- }
- /// Return the value of the item in storage under `key`, or `default_value()` if there is no
- /// explicit entry. Ensure there is no explicit entry on return.
- pub fn take_or_else<T: Codec + Sized, F: FnOnce() -> T>(
- storage_key: &[u8],
- key: &[u8],
- default_value: F,
- ) -> T {
- take(storage_key, key).unwrap_or_else(default_value)
- }
- /// Check to see if `key` has an explicit entry in storage.
- pub fn exists(storage_key: &[u8], key: &[u8]) -> bool {
- runtime_io::read_child_storage(storage_key, key, &mut [0; 0][..], 0).is_some()
- }
- /// Remove all `storage_key` key/values
- pub fn kill_storage(storage_key: &[u8]) {
- runtime_io::kill_child_storage(storage_key)
- }
- /// Ensure `key` has no explicit entry in storage.
- pub fn kill(storage_key: &[u8], key: &[u8]) {
- runtime_io::clear_child_storage(storage_key, key);
- }
- /// Get a Vec of bytes from storage.
- pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option<Vec<u8>> {
- runtime_io::child_storage(storage_key, key)
- }
- /// Put a raw byte slice into storage.
- pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) {
- runtime_io::set_child_storage(storage_key, key, value)
- }
- pub use super::unhashed::StorageVec;
- }
- }
- mod hashable {
- //! Hashable trait.
- use crate::codec::Codec;
- use crate::rstd::prelude::Vec;
- use crate::storage::hashed::generator::StorageHasher;
- use crate::Twox64Concat;
- use runtime_io::{blake2_128, blake2_256, twox_128, twox_256};
- pub trait Hashable: Sized {
- fn blake2_128(&self) -> [u8; 16];
- fn blake2_256(&self) -> [u8; 32];
- fn twox_128(&self) -> [u8; 16];
- fn twox_256(&self) -> [u8; 32];
- fn twox_64_concat(&self) -> Vec<u8>;
- }
- impl<T: Codec> Hashable for T {
- fn blake2_128(&self) -> [u8; 16] {
- self.using_encoded(blake2_128)
- }
- fn blake2_256(&self) -> [u8; 32] {
- self.using_encoded(blake2_256)
- }
- fn twox_128(&self) -> [u8; 16] {
- self.using_encoded(twox_128)
- }
- fn twox_256(&self) -> [u8; 32] {
- self.using_encoded(twox_256)
- }
- fn twox_64_concat(&self) -> Vec<u8> {
- self.using_encoded(Twox64Concat::hash)
- }
- }
- }
- #[macro_use]
- pub mod event {
- //! Macros that define an Event types. Events can be used to easily report changes or conditions
- //! in your runtime to external entities like users, chain explorers, or dApps.
- pub use srml_metadata::{DecodeDifferent, EventMetadata, FnEncode, OuterEventMetadata};
- }
- #[macro_use]
- mod origin {
- //! Macros that define an Origin type. Every function call to your runtime has an origin which
- //! specifies where the extrinsic was generated from.
- }
- #[macro_use]
- pub mod metadata {
- pub use srml_metadata::{
- DecodeDifferent, DefaultByte, DefaultByteGetter, FnEncode, ModuleMetadata, RuntimeMetadata,
- RuntimeMetadataPrefixed, RuntimeMetadataV4, StorageFunctionMetadata,
- StorageFunctionModifier, StorageFunctionType, StorageHasher, StorageMetadata,
- };
- }
- #[macro_use]
- mod runtime {
- //! Macros to define a runtime. A runtime is basically all your logic running in Substrate,
- //! consisting of selected SRML modules and maybe some of your own modules.
- //! A lot of supporting logic is automatically generated for a runtime,
- //! mostly to combine data types and metadata of the included modules.
- }
- #[macro_use]
- pub mod inherent {
- #[doc(hidden)]
- pub use crate::rstd::vec::Vec;
- #[doc(hidden)]
- pub use crate::runtime_primitives::traits::{Block as BlockT, Extrinsic};
- #[doc(hidden)]
- pub use inherents::{CheckInherentsResult, InherentData, IsFatalError, ProvideInherent};
- }
- #[macro_use]
- pub mod unsigned {
- #[doc(hidden)]
- pub use crate::runtime_primitives::traits::ValidateUnsigned;
- #[doc(hidden)]
- pub use crate::runtime_primitives::transaction_validity::TransactionValidity;
- #[doc(hidden)]
- pub use crate::runtime_primitives::ApplyError;
- }
- mod double_map {
- //! An implementation of double map backed by storage.
- use crate::codec::{Codec, Encode};
- use crate::rstd::prelude::*;
- use crate::storage::unhashed;
- use sr_std::borrow::Borrow;
- /// 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.
- ///
- /// # Mapping of keys to a storage path
- ///
- /// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts.
- /// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part
- /// is a hash of a `Key2`.
- ///
- /// Hasher are implemented in derive_key* methods.
- pub trait StorageDoubleMapWithHasher {
- type Key1: Codec;
- type Key2: Codec;
- type Value: Codec + Default;
- const PREFIX: &'static [u8];
- /// Insert an entry into this map.
- fn insert<Q, R>(k1: &Q, k2: &R, val: Self::Value)
- where
- Self::Key1: Borrow<Q>,
- Self::Key2: Borrow<R>,
- Q: Codec,
- R: Codec,
- {
- unhashed::put(&Self::full_key(k1, k2)[..], &val);
- }
- /// Remove an entry from this map.
- fn remove<Q, R>(k1: &Q, k2: &R)
- where
- Self::Key1: Borrow<Q>,
- Self::Key2: Borrow<R>,
- Q: Codec,
- R: Codec,
- {
- unhashed::kill(&Self::full_key(k1, k2)[..]);
- }
- /// Get an entry from this map.
- ///
- /// If there is entry stored under the given keys, returns `None`.
- fn get<Q, R>(k1: &Q, k2: &R) -> Option<Self::Value>
- where
- Self::Key1: Borrow<Q>,
- Self::Key2: Borrow<R>,
- Q: Codec,
- R: Codec,
- {
- unhashed::get(&Self::full_key(k1, k2)[..])
- }
- /// Returns `true` if value under the specified keys exists.
- fn exists<Q, R>(k1: &Q, k2: &R) -> bool
- where
- Self::Key1: Borrow<Q>,
- Self::Key2: Borrow<R>,
- Q: Codec,
- R: Codec,
- {
- unhashed::exists(&Self::full_key(k1, k2)[..])
- }
- /// Removes all entries that shares the `k1` as the first key.
- fn remove_prefix<Q>(k1: &Q)
- where
- Self::Key1: Borrow<Q>,
- Q: Codec,
- {
- unhashed::kill_prefix(&Self::derive_key1(Self::encode_key1(k1)))
- }
- /// Encode key1 into Vec<u8> and prepend a prefix
- fn encode_key1<Q>(key: &Q) -> Vec<u8>
- where
- Self::Key1: Borrow<Q>,
- Q: Codec,
- {
- let mut raw_prefix = Vec::new();
- raw_prefix.extend(Self::PREFIX);
- key.encode_to(&mut raw_prefix);
- raw_prefix
- }
- /// Encode key2 into Vec<u8>
- fn encode_key2<R>(key: &R) -> Vec<u8>
- where
- Self::Key2: Borrow<R>,
- R: Codec,
- {
- Encode::encode(&key)
- }
- /// Derive the first part of the key
- fn derive_key1(key1_data: Vec<u8>) -> Vec<u8>;
- /// Derive the remaining part of the key
- fn derive_key2(key2_data: Vec<u8>) -> Vec<u8>;
- /// Returns a compound key that consist of the two parts: (prefix, `k1`) and `k2`.
- /// The first part is hashed and then concatenated with a hash of `k2`.
- fn full_key<Q, R>(k1: &Q, k2: &R) -> Vec<u8>
- where
- Self::Key1: Borrow<Q>,
- Self::Key2: Borrow<R>,
- Q: Codec,
- R: Codec,
- {
- let key1_data = Self::encode_key1(k1);
- let key2_data = Self::encode_key2(k2);
- let mut key = Self::derive_key1(key1_data);
- key.extend(Self::derive_key2(key2_data));
- key
- }
- }
- }
- pub mod traits {
- //! Traits for SRML
- use crate::codec::{Codec, Decode, Encode};
- use crate::rstd::result;
- use crate::runtime_primitives::traits::{MaybeSerializeDebug, SimpleArithmetic};
- /// New trait for querying a single fixed value from a type.
- pub trait Get<T> {
- /// Return a constant value.
- fn get() -> T;
- }
- /// The account with the given id was killed.
- pub trait OnFreeBalanceZero<AccountId> {
- /// The account was the given id was killed.
- fn on_free_balance_zero(who: &AccountId);
- }
- impl<AccountId> OnFreeBalanceZero<AccountId> for () {
- fn on_free_balance_zero(_who: &AccountId) {}
- }
- impl<AccountId, X: OnFreeBalanceZero<AccountId>, Y: OnFreeBalanceZero<AccountId>>
- OnFreeBalanceZero<AccountId> for (X, Y)
- {
- fn on_free_balance_zero(who: &AccountId) {
- X::on_free_balance_zero(who);
- Y::on_free_balance_zero(who);
- }
- }
- /// Trait for a hook to get called when some balance has been minted, causing dilution.
- pub trait OnDilution<Balance> {
- /// Some `portion` of the total balance just "grew" by `minted`. `portion` is the pre-growth
- /// amount (it doesn't take account of the recent growth).
- fn on_dilution(minted: Balance, portion: Balance);
- }
- impl<Balance> OnDilution<Balance> for () {
- fn on_dilution(_minted: Balance, _portion: Balance) {}
- }
- /// Outcome of a balance update.
- pub enum UpdateBalanceOutcome {
- /// Account balance was simply updated.
- Updated,
- /// The update led to killing the account.
- AccountKilled,
- }
- /// Simple trait designed for hooking into a transaction payment.
- ///
- /// It operates over a single generic `AccountId` type.
- pub trait MakePayment<AccountId> {
- /// Make transaction payment from `who` for an extrinsic of encoded length
- /// `encoded_len` bytes. Return `Ok` iff the payment was successful.
- fn make_payment(who: &AccountId, encoded_len: usize) -> Result<(), &'static str>;
- }
- impl<T> MakePayment<T> for () {
- fn make_payment(_: &T, _: usize) -> Result<(), &'static str> {
- Ok(())
- }
- }
- /// Handler for when some currency "account" decreased in balance for
- /// some reason.
- ///
- /// The only reason at present for an increase would be for validator rewards, but
- /// there may be other reasons in the future or for other chains.
- ///
- /// Reasons for decreases include:
- ///
- /// - Someone got slashed.
- /// - Someone paid for a transaction to be included.
- pub trait OnUnbalanced<Imbalance> {
- /// Handler for some imbalance. Infallible.
- fn on_unbalanced(amount: Imbalance);
- }
- impl<Imbalance: Drop> OnUnbalanced<Imbalance> for () {
- fn on_unbalanced(amount: Imbalance) {
- drop(amount);
- }
- }
- /// Simple boolean for whether an account needs to be kept in existence.
- #[structural_match]
- #[rustc_copy_clone_marker]
- pub enum ExistenceRequirement {
- /// Operation must not result in the account going out of existence.
- KeepAlive,
- /// Operation may result in account going out of existence.
- AllowDeath,
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::marker::Copy for ExistenceRequirement {}
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::clone::Clone for ExistenceRequirement {
- #[inline]
- fn clone(&self) -> ExistenceRequirement {
- {
- *self
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::cmp::Eq for ExistenceRequirement {
- #[inline]
- #[doc(hidden)]
- fn assert_receiver_is_total_eq(&self) -> () {
- {}
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::cmp::PartialEq for ExistenceRequirement {
- #[inline]
- fn eq(&self, other: &ExistenceRequirement) -> bool {
- {
- let __self_vi = unsafe { ::std::intrinsics::discriminant_value(&*self) } as isize;
- let __arg_1_vi = unsafe { ::std::intrinsics::discriminant_value(&*other) } as isize;
- if true && __self_vi == __arg_1_vi {
- match (&*self, &*other) {
- _ => true,
- }
- } else {
- false
- }
- }
- }
- }
- /// A trait for a not-quite Linear Type that tracks an imbalance.
- ///
- /// Functions that alter account balances return an object of this trait to
- /// express how much account balances have been altered in aggregate. If
- /// dropped, the currency system will take some default steps to deal with
- /// the imbalance (`balances` module simply reduces or increases its
- /// total issuance). Your module should generally handle it in some way,
- /// good practice is to do so in a configurable manner using an
- /// `OnUnbalanced` type for each situation in which your module needs to
- /// handle an imbalance.
- ///
- /// Imbalances can either be Positive (funds were added somewhere without
- /// being subtracted elsewhere - e.g. a reward) or Negative (funds deducted
- /// somewhere without an equal and opposite addition - e.g. a slash or
- /// system fee payment).
- ///
- /// Since they are unsigned, the actual type is always Positive or Negative.
- /// The trait makes no distinction except to define the `Opposite` type.
- ///
- /// New instances of zero value can be created (`zero`) and destroyed
- /// (`drop_zero`).
- ///
- /// Existing instances can be `split` and merged either consuming `self` with
- /// `merge` or mutating `self` with `subsume`. If the target is an `Option`,
- /// then `maybe_merge` and `maybe_subsume` might work better. Instances can
- /// also be `offset` with an `Opposite` that is less than or equal to in value.
- ///
- /// You can always retrieve the raw balance value using `peek`.
- #[must_use]
- pub trait Imbalance<Balance>: Sized {
- /// The oppositely imbalanced type. They come in pairs.
- type Opposite: Imbalance<Balance>;
- /// The zero imbalance. Can be destroyed with `drop_zero`.
- fn zero() -> Self;
- /// Drop an instance cleanly. Only works if its `value()` is zero.
- fn drop_zero(self) -> Result<(), Self>;
- /// Consume `self` and return two independent instances; the first
- /// is guaranteed to be at most `amount` and the second will be the remainder.
- fn split(self, amount: Balance) -> (Self, Self);
- /// Consume `self` and an `other` to return a new instance that combines
- /// both.
- fn merge(self, other: Self) -> Self;
- /// Consume `self` and maybe an `other` to return a new instance that combines
- /// both.
- fn maybe_merge(self, other: Option<Self>) -> Self {
- if let Some(o) = other {
- self.merge(o)
- } else {
- self
- }
- }
- /// Consume an `other` to mutate `self` into a new instance that combines
- /// both.
- fn subsume(&mut self, other: Self);
- /// Maybe consume an `other` to mutate `self` into a new instance that combines
- /// both.
- fn maybe_subsume(&mut self, other: Option<Self>) {
- if let Some(o) = other {
- self.subsume(o)
- }
- }
- /// Consume self and along with an opposite counterpart to return
- /// a combined result.
- ///
- /// Returns `Ok` along with a new instance of `Self` if this instance has a
- /// greater value than the `other`. Otherwise returns `Err` with an instance of
- /// the `Opposite`. In both cases the value represents the combination of `self`
- /// and `other`.
- fn offset(self, other: Self::Opposite) -> Result<Self, Self::Opposite>;
- /// The raw value of self.
- fn peek(&self) -> Balance;
- }
- /// Either a positive or a negative imbalance.
- pub enum SignedImbalance<B, P: Imbalance<B>> {
- /// A positive imbalance (funds have been created but none destroyed).
- Positive(P),
- /// A negative imbalance (funds have been destroyed but none created).
- Negative(P::Opposite),
- }
- impl<
- P: Imbalance<B, Opposite = N>,
- N: Imbalance<B, Opposite = P>,
- B: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default,
- > SignedImbalance<B, P>
- {
- pub fn zero() -> Self {
- SignedImbalance::Positive(P::zero())
- }
- pub fn drop_zero(self) -> Result<(), Self> {
- match self {
- SignedImbalance::Positive(x) => x.drop_zero().map_err(SignedImbalance::Positive),
- SignedImbalance::Negative(x) => x.drop_zero().map_err(SignedImbalance::Negative),
- }
- }
- /// Consume `self` and an `other` to return a new instance that combines
- /// both.
- pub fn merge(self, other: Self) -> Self {
- match (self, other) {
- (SignedImbalance::Positive(one), SignedImbalance::Positive(other)) => {
- SignedImbalance::Positive(one.merge(other))
- }
- (SignedImbalance::Negative(one), SignedImbalance::Negative(other)) => {
- SignedImbalance::Negative(one.merge(other))
- }
- (SignedImbalance::Positive(one), SignedImbalance::Negative(other)) => {
- if one.peek() > other.peek() {
- SignedImbalance::Positive(one.offset(other).ok().unwrap_or_else(P::zero))
- } else {
- SignedImbalance::Negative(other.offset(one).ok().unwrap_or_else(N::zero))
- }
- }
- (one, other) => other.merge(one),
- }
- }
- }
- /// Abstraction over a fungible assets system.
- pub trait Currency<AccountId> {
- /// The balance of an account.
- type Balance: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default;
- /// The opaque token type for an imbalance. This is returned by unbalanced operations
- /// and must be dealt with. It may be dropped but cannot be cloned.
- type PositiveImbalance: Imbalance<Self::Balance, Opposite = Self::NegativeImbalance>;
- /// The opaque token type for an imbalance. This is returned by unbalanced operations
- /// and must be dealt with. It may be dropped but cannot be cloned.
- type NegativeImbalance: Imbalance<Self::Balance, Opposite = Self::PositiveImbalance>;
- /// The combined balance of `who`.
- fn total_balance(who: &AccountId) -> Self::Balance;
- /// Same result as `slash(who, value)` (but without the side-effects) assuming there are no
- /// balance changes in the meantime and only the reserved balance is not taken into account.
- fn can_slash(who: &AccountId, value: Self::Balance) -> bool;
- /// The total amount of issuance in the system.
- fn total_issuance() -> Self::Balance;
- /// The minimum balance any single account may have. This is equivalent to the `Balances` module's
- /// `ExistentialDeposit`.
- fn minimum_balance() -> Self::Balance;
- /// The 'free' balance of a given account.
- ///
- /// This is the only balance that matters in terms of most operations on tokens. It alone
- /// is used to determine the balance when in the contract execution environment. When this
- /// balance falls below the value of `ExistentialDeposit`, then the 'current account' is
- /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback
- /// is invoked, giving a chance to external modules to clean up data associated with
- /// the deleted account.
- ///
- /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
- /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
- fn free_balance(who: &AccountId) -> Self::Balance;
- /// Returns `Ok` iff the account is able to make a withdrawal of the given amount
- /// for the given reason. Basically, it's just a dry-run of `withdraw`.
- ///
- /// `Err(...)` with the reason why not otherwise.
- fn ensure_can_withdraw(
- who: &AccountId,
- _amount: Self::Balance,
- reason: WithdrawReason,
- new_balance: Self::Balance,
- ) -> result::Result<(), &'static str>;
- /// Transfer some liquid free balance to another staker.
- ///
- /// This is a very high-level function. It will ensure all appropriate fees are paid
- /// and no imbalance in the system remains.
- fn transfer(
- source: &AccountId,
- dest: &AccountId,
- value: Self::Balance,
- ) -> result::Result<(), &'static str>;
- /// Deducts up to `value` from the combined balance of `who`, preferring to deduct from the
- /// free balance. This function cannot fail.
- ///
- /// The resulting imbalance is the first item of the tuple returned.
- ///
- /// As much funds up to `value` will be deducted as possible. If this is less than `value`,
- /// then a non-zero second item will be returned.
- fn slash(who: &AccountId, value: Self::Balance)
- -> (Self::NegativeImbalance, Self::Balance);
- /// Mints `value` to the free balance of `who`.
- ///
- /// If `who` doesn't exist, nothing is done and an Err returned.
- fn deposit_into_existing(
- who: &AccountId,
- value: Self::Balance,
- ) -> result::Result<Self::PositiveImbalance, &'static str>;
- /// Removes some free balance from `who` account for `reason` if possible. If `liveness` is `KeepAlive`,
- /// then no less than `ExistentialDeposit` must be left remaining.
- ///
- /// This checks any locks, vesting, and liquidity requirements. If the removal is not possible, then it
- /// returns `Err`.
- fn withdraw(
- who: &AccountId,
- value: Self::Balance,
- reason: WithdrawReason,
- liveness: ExistenceRequirement,
- ) -> result::Result<Self::NegativeImbalance, &'static str>;
- /// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created.
- ///
- /// Infallible.
- fn deposit_creating(who: &AccountId, value: Self::Balance) -> Self::PositiveImbalance;
- /// Ensure an account's free balance equals some value; this will create the account
- /// if needed.
- ///
- /// Returns a signed imbalance and status to indicate if the account was successfully updated or update
- /// has led to killing of the account.
- fn make_free_balance_be(
- who: &AccountId,
- balance: Self::Balance,
- ) -> (
- SignedImbalance<Self::Balance, Self::PositiveImbalance>,
- UpdateBalanceOutcome,
- );
- }
- /// A currency where funds can be reserved from the user.
- pub trait ReservableCurrency<AccountId>: Currency<AccountId> {
- /// Same result as `reserve(who, value)` (but without the side-effects) assuming there
- /// are no balance changes in the meantime.
- fn can_reserve(who: &AccountId, value: Self::Balance) -> bool;
- /// Deducts up to `value` from reserved balance of `who`. This function cannot fail.
- ///
- /// As much funds up to `value` will be deducted as possible. If the reserve balance of `who`
- /// is less than `value`, then a non-zero second item will be returned.
- fn slash_reserved(
- who: &AccountId,
- value: Self::Balance,
- ) -> (Self::NegativeImbalance, Self::Balance);
- /// The amount of the balance of a given account that is externally reserved; this can still get
- /// slashed, but gets slashed last of all.
- ///
- /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens
- /// that are still 'owned' by the account holder, but which are suspendable.
- ///
- /// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account'
- /// is deleted: specifically, `ReservedBalance`.
- ///
- /// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets
- /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
- fn reserved_balance(who: &AccountId) -> Self::Balance;
- /// Moves `value` from balance to reserved balance.
- ///
- /// If the free balance is lower than `value`, then no funds will be moved and an `Err` will
- /// be returned to notify of this. This is different behavior than `unreserve`.
- fn reserve(who: &AccountId, value: Self::Balance) -> result::Result<(), &'static str>;
- /// Moves up to `value` from reserved balance to free balance. This function cannot fail.
- ///
- /// As much funds up to `value` will be moved as possible. If the reserve balance of `who`
- /// is less than `value`, then the remaining amount will be returned.
- ///
- /// # NOTES
- ///
- /// - This is different from `reserve`.
- /// - If the remaining reserved balance is less than `ExistentialDeposit`, it will
- /// invoke `on_reserved_too_low` and could reap the account.
- fn unreserve(who: &AccountId, value: Self::Balance) -> Self::Balance;
- /// Moves up to `value` from reserved balance of account `slashed` to free balance of account
- /// `beneficiary`. `beneficiary` must exist for this to succeed. If it does not, `Err` will be
- /// returned.
- ///
- /// As much funds up to `value` will be deducted as possible. If this is less than `value`,
- /// then `Ok(non_zero)` will be returned.
- fn repatriate_reserved(
- slashed: &AccountId,
- beneficiary: &AccountId,
- value: Self::Balance,
- ) -> result::Result<Self::Balance, &'static str>;
- }
- /// An identifier for a lock. Used for disambiguating different locks so that
- /// they can be individually replaced or removed.
- pub type LockIdentifier = [u8; 8];
- /// A currency whose accounts can have liquidity restrictions.
- pub trait LockableCurrency<AccountId>: Currency<AccountId> {
- /// The quantity used to denote time; usually just a `BlockNumber`.
- type Moment;
- /// Create a new balance lock on account `who`.
- ///
- /// If the new lock is valid (i.e. not already expired), it will push the struct to
- /// the `Locks` vec in storage. Note that you can lock more funds than a user has.
- ///
- /// If the lock `id` already exists, this will update it.
- fn set_lock(
- id: LockIdentifier,
- who: &AccountId,
- amount: Self::Balance,
- until: Self::Moment,
- reasons: WithdrawReasons,
- );
- /// Changes a balance lock (selected by `id`) so that it becomes less liquid in all
- /// parameters or creates a new one if it does not exist.
- ///
- /// Calling `extend_lock` on an existing lock `id` differs from `set_lock` in that it
- /// applies the most severe constraints of the two, while `set_lock` replaces the lock
- /// with the new parameters. As in, `extend_lock` will set:
- /// - maximum `amount`
- /// - farthest duration (`until`)
- /// - bitwise mask of all `reasons`
- fn extend_lock(
- id: LockIdentifier,
- who: &AccountId,
- amount: Self::Balance,
- until: Self::Moment,
- reasons: WithdrawReasons,
- );
- /// Remove an existing lock.
- fn remove_lock(id: LockIdentifier, who: &AccountId);
- }
- #[repr(i8)]
- #[allow(dead_code)]
- /// Reason for moving funds out of an account.
- #[structural_match]
- #[rustc_copy_clone_marker]
- pub enum WithdrawReason {
- /// In order to pay for (system) transaction costs.
- TransactionPayment = 1,
- /// In order to transfer ownership.
- Transfer = 2,
- /// In order to reserve some funds for a later return or repatriation
- Reserve = 4,
- /// In order to pay some other (higher-level) fees.
- Fee = 8,
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::marker::Copy for WithdrawReason {}
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::clone::Clone for WithdrawReason {
- #[inline]
- fn clone(&self) -> WithdrawReason {
- {
- *self
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::Eq for WithdrawReason {
- #[inline]
- #[doc(hidden)]
- fn assert_receiver_is_total_eq(&self) -> () {
- {}
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::PartialEq for WithdrawReason {
- #[inline]
- fn eq(&self, other: &WithdrawReason) -> bool {
- {
- let __self_vi = unsafe { ::std::intrinsics::discriminant_value(&*self) } as i8;
- let __arg_1_vi = unsafe { ::std::intrinsics::discriminant_value(&*other) } as i8;
- if true && __self_vi == __arg_1_vi {
- match (&*self, &*other) {
- _ => true,
- }
- } else {
- false
- }
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::Ord for WithdrawReason {
- #[inline]
- fn cmp(&self, other: &WithdrawReason) -> ::std::cmp::Ordering {
- {
- let __self_vi = unsafe { ::std::intrinsics::discriminant_value(&*self) } as i8;
- let __arg_1_vi = unsafe { ::std::intrinsics::discriminant_value(&*other) } as i8;
- if true && __self_vi == __arg_1_vi {
- match (&*self, &*other) {
- _ => ::std::cmp::Ordering::Equal,
- }
- } else {
- __self_vi.cmp(&__arg_1_vi)
- }
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::PartialOrd for WithdrawReason {
- #[inline]
- fn partial_cmp(
- &self,
- other: &WithdrawReason,
- ) -> ::std::option::Option<::std::cmp::Ordering> {
- {
- let __self_vi = unsafe { ::std::intrinsics::discriminant_value(&*self) } as i8;
- let __arg_1_vi = unsafe { ::std::intrinsics::discriminant_value(&*other) } as i8;
- if true && __self_vi == __arg_1_vi {
- match (&*self, &*other) {
- _ => ::std::option::Option::Some(::std::cmp::Ordering::Equal),
- }
- } else {
- __self_vi.partial_cmp(&__arg_1_vi)
- }
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::fmt::Debug for WithdrawReason {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- match (&*self,) {
- (&WithdrawReason::TransactionPayment,) => {
- let mut debug_trait_builder = f.debug_tuple("TransactionPayment");
- debug_trait_builder.finish()
- }
- (&WithdrawReason::Transfer,) => {
- let mut debug_trait_builder = f.debug_tuple("Transfer");
- debug_trait_builder.finish()
- }
- (&WithdrawReason::Reserve,) => {
- let mut debug_trait_builder = f.debug_tuple("Reserve");
- debug_trait_builder.finish()
- }
- (&WithdrawReason::Fee,) => {
- let mut debug_trait_builder = f.debug_tuple("Fee");
- debug_trait_builder.finish()
- }
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::hash::Hash for WithdrawReason {
- fn hash<__H: ::std::hash::Hasher>(&self, state: &mut __H) -> () {
- match (&*self,) {
- _ => ::std::hash::Hash::hash(
- &unsafe { ::std::intrinsics::discriminant_value(self) },
- state,
- ),
- }
- }
- }
- #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
- const _IMPL_ENCODE_FOR_WithdrawReason: () = {
- #[allow(unknown_lints)]
- #[allow(rust_2018_idioms)]
- extern crate codec as _parity_codec;
- impl _parity_codec::Encode for WithdrawReason {
- fn encode_to<EncOut: _parity_codec::Output>(&self, dest: &mut EncOut) {
- match *self {
- WithdrawReason::TransactionPayment => {
- dest.push_byte(1 as u8);
- }
- WithdrawReason::Transfer => {
- dest.push_byte(2 as u8);
- }
- WithdrawReason::Reserve => {
- dest.push_byte(4 as u8);
- }
- WithdrawReason::Fee => {
- dest.push_byte(8 as u8);
- }
- _ => (),
- }
- }
- }
- };
- #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
- const _IMPL_DECODE_FOR_WithdrawReason: () = {
- #[allow(unknown_lints)]
- #[allow(rust_2018_idioms)]
- extern crate codec as _parity_codec;
- impl _parity_codec::Decode for WithdrawReason {
- fn decode<DecIn: _parity_codec::Input>(input: &mut DecIn) -> Option<Self> {
- match input.read_byte()? {
- x if x == 1 as u8 => Some(WithdrawReason::TransactionPayment),
- x if x == 2 as u8 => Some(WithdrawReason::Transfer),
- x if x == 4 as u8 => Some(WithdrawReason::Reserve),
- x if x == 8 as u8 => Some(WithdrawReason::Fee),
- _ => None,
- }
- }
- }
- };
- #[allow(dead_code)]
- /// Reasons for moving funds out of an account.
- #[structural_match]
- #[rustc_copy_clone_marker]
- pub struct WithdrawReasons {
- mask: i8,
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::marker::Copy for WithdrawReasons {}
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::clone::Clone for WithdrawReasons {
- #[inline]
- fn clone(&self) -> WithdrawReasons {
- {
- let _: ::std::clone::AssertParamIsClone<i8>;
- *self
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::Eq for WithdrawReasons {
- #[inline]
- #[doc(hidden)]
- fn assert_receiver_is_total_eq(&self) -> () {
- {
- let _: ::std::cmp::AssertParamIsEq<i8>;
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::PartialEq for WithdrawReasons {
- #[inline]
- fn eq(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => (*__self_0_0) == (*__self_1_0),
- },
- }
- }
- #[inline]
- fn ne(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => (*__self_0_0) != (*__self_1_0),
- },
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::Ord for WithdrawReasons {
- #[inline]
- fn cmp(&self, other: &WithdrawReasons) -> ::std::cmp::Ordering {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => match ::std::cmp::Ord::cmp(&(*__self_0_0), &(*__self_1_0)) {
- ::std::cmp::Ordering::Equal => ::std::cmp::Ordering::Equal,
- cmp => cmp,
- },
- },
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::cmp::PartialOrd for WithdrawReasons {
- #[inline]
- fn partial_cmp(
- &self,
- other: &WithdrawReasons,
- ) -> ::std::option::Option<::std::cmp::Ordering> {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- match ::std::cmp::PartialOrd::partial_cmp(&(*__self_0_0), &(*__self_1_0)) {
- ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {
- ::std::option::Option::Some(::std::cmp::Ordering::Equal)
- }
- cmp => cmp,
- }
- }
- },
- }
- }
- #[inline]
- fn lt(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- ::std::option::Option::unwrap_or(
- ::std::cmp::PartialOrd::partial_cmp(&(*__self_0_0), &(*__self_1_0)),
- ::std::cmp::Ordering::Greater,
- ) == ::std::cmp::Ordering::Less
- }
- },
- }
- }
- #[inline]
- fn le(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- ::std::option::Option::unwrap_or(
- ::std::cmp::PartialOrd::partial_cmp(&(*__self_0_0), &(*__self_1_0)),
- ::std::cmp::Ordering::Greater,
- ) != ::std::cmp::Ordering::Greater
- }
- },
- }
- }
- #[inline]
- fn gt(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- ::std::option::Option::unwrap_or(
- ::std::cmp::PartialOrd::partial_cmp(&(*__self_0_0), &(*__self_1_0)),
- ::std::cmp::Ordering::Less,
- ) == ::std::cmp::Ordering::Greater
- }
- },
- }
- }
- #[inline]
- fn ge(&self, other: &WithdrawReasons) -> bool {
- match *other {
- WithdrawReasons {
- mask: ref __self_1_0,
- } => match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- ::std::option::Option::unwrap_or(
- ::std::cmp::PartialOrd::partial_cmp(&(*__self_0_0), &(*__self_1_0)),
- ::std::cmp::Ordering::Less,
- ) != ::std::cmp::Ordering::Less
- }
- },
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::fmt::Debug for WithdrawReasons {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => {
- let mut debug_trait_builder = f.debug_struct("WithdrawReasons");
- let _ = debug_trait_builder.field("mask", &&(*__self_0_0));
- debug_trait_builder.finish()
- }
- }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- #[allow(dead_code)]
- impl ::std::hash::Hash for WithdrawReasons {
- fn hash<__H: ::std::hash::Hasher>(&self, state: &mut __H) -> () {
- match *self {
- WithdrawReasons {
- mask: ref __self_0_0,
- } => ::std::hash::Hash::hash(&(*__self_0_0), state),
- }
- }
- }
- #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
- const _IMPL_ENCODE_FOR_WithdrawReasons: () = {
- #[allow(unknown_lints)]
- #[allow(rust_2018_idioms)]
- extern crate codec as _parity_codec;
- impl _parity_codec::Encode for WithdrawReasons {
- fn encode_to<EncOut: _parity_codec::Output>(&self, dest: &mut EncOut) {
- dest.push(&self.mask);
- }
- }
- };
- #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
- const _IMPL_DECODE_FOR_WithdrawReasons: () = {
- #[allow(unknown_lints)]
- #[allow(rust_2018_idioms)]
- extern crate codec as _parity_codec;
- impl _parity_codec::Decode for WithdrawReasons {
- fn decode<DecIn: _parity_codec::Input>(input: &mut DecIn) -> Option<Self> {
- Some(WithdrawReasons {
- mask: _parity_codec::Decode::decode(input)?,
- })
- }
- }
- };
- #[allow(dead_code)]
- impl WithdrawReasons {
- /// Create a new mask with all flags unset.
- #[inline]
- pub fn none() -> Self {
- WithdrawReasons { mask: 0 }
- }
- /// Create a new mask with all flags set.
- #[inline]
- pub fn all() -> Self {
- WithdrawReasons {
- mask: 1 | 2 | 4 | 8,
- }
- }
- /// Set all `other` flags.
- ///
- /// `other` can be either a single flag or another mask.
- #[inline]
- pub fn set<T>(&mut self, other: T)
- where
- T: Into<WithdrawReasons> + ::bitmask::__core::ops::Deref<Target = i8>,
- {
- self.mask |= *other;
- }
- /// Unset all `other` flags.
- ///
- /// `other` can be either a single flag or another mask.
- #[inline]
- pub fn unset<T>(&mut self, other: T)
- where
- T: Into<WithdrawReasons> + ::bitmask::__core::ops::Deref<Target = i8>,
- {
- self.mask &= Self::all().mask ^ *other;
- }
- /// Toggle all `other` flags.
- ///
- /// `other` can be either a single flag or another mask.
- #[inline]
- pub fn toggle<T>(&mut self, other: T)
- where
- T: Into<WithdrawReasons> + ::bitmask::__core::ops::Deref<Target = i8>,
- {
- self.mask ^= *other;
- }
- /// Check if the mask contains all of `other`'s flags.
- ///
- /// `other` can be either a single flag or another mask.
- #[inline]
- pub fn contains<T>(&self, other: T) -> bool
- where
- T: Into<WithdrawReasons> + ::bitmask::__core::ops::Deref<Target = i8>,
- {
- self.mask & *other == *other
- }
- /// Check if the mask has common flags with `other`.
- ///
- /// `other` can be either a single flag or another mask.
- #[inline]
- pub fn intersects<T>(&self, other: T) -> bool
- where
- T: Into<WithdrawReasons> + ::bitmask::__core::ops::Deref<Target = i8>,
- {
- self.mask & *other != 0
- }
- /// Check if all flags are set.
- pub fn is_all(&self) -> bool {
- self.mask == Self::all().mask
- }
- /// Check if all flags are unset.
- pub fn is_none(&self) -> bool {
- self.mask == 0
- }
- }
- impl ::bitmask::__core::convert::From<WithdrawReason> for WithdrawReasons {
- /// Create a mask from a single flag.
- ///
- /// When creating a mask from multiple flags or another mask just use the `clone` method
- /// or the `copy` semantics.
- #[inline]
- fn from(flag: WithdrawReason) -> Self {
- WithdrawReasons { mask: flag as i8 }
- }
- }
- impl ::bitmask::__core::ops::Deref for WithdrawReasons {
- type Target = i8;
- /// Deref to the internal type.
- ///
- /// Useful for FFI.
- #[inline]
- fn deref(&self) -> &i8 {
- &self.mask as &i8
- }
- }
- impl ::bitmask::__core::ops::Deref for WithdrawReason {
- type Target = i8;
- /// Deref to the internal type.
- ///
- /// Useful for FFI.
- #[inline]
- fn deref(&self) -> &i8 {
- unsafe { ::bitmask::__core::mem::transmute(self) }
- }
- }
- impl ::bitmask::__core::ops::BitOr<WithdrawReasons> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitor(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self | *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitOr<WithdrawReason> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitor(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self | *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitOr<WithdrawReasons> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitor(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self | *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitOr<WithdrawReason> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitor(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self | *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitAnd<WithdrawReasons> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitand(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self & *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitAnd<WithdrawReason> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitand(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self & *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitAnd<WithdrawReasons> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitand(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self & *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitAnd<WithdrawReason> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitand(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self & *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitXor<WithdrawReasons> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitxor(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self ^ *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitXor<WithdrawReason> for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn bitxor(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self ^ *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitXor<WithdrawReasons> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitxor(self, other: WithdrawReasons) -> Self::Output {
- WithdrawReasons {
- mask: *self ^ *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitXor<WithdrawReason> for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn bitxor(self, other: WithdrawReason) -> Self::Output {
- WithdrawReasons {
- mask: *self ^ *other,
- }
- }
- }
- impl ::bitmask::__core::ops::BitOrAssign<WithdrawReasons> for WithdrawReasons {
- #[inline]
- fn bitor_assign(&mut self, other: WithdrawReasons) {
- self.mask |= *other
- }
- }
- impl ::bitmask::__core::ops::BitOrAssign<WithdrawReason> for WithdrawReasons {
- #[inline]
- fn bitor_assign(&mut self, other: WithdrawReason) {
- self.mask |= *other
- }
- }
- impl ::bitmask::__core::ops::BitAndAssign<WithdrawReasons> for WithdrawReasons {
- #[inline]
- fn bitand_assign(&mut self, other: WithdrawReasons) {
- self.mask &= *other
- }
- }
- impl ::bitmask::__core::ops::BitAndAssign<WithdrawReason> for WithdrawReasons {
- #[inline]
- fn bitand_assign(&mut self, other: WithdrawReason) {
- self.mask &= *other
- }
- }
- impl ::bitmask::__core::ops::BitXorAssign<WithdrawReasons> for WithdrawReasons {
- #[inline]
- fn bitxor_assign(&mut self, other: WithdrawReasons) {
- self.mask ^= *other
- }
- }
- impl ::bitmask::__core::ops::BitXorAssign<WithdrawReason> for WithdrawReasons {
- #[inline]
- fn bitxor_assign(&mut self, other: WithdrawReason) {
- self.mask ^= *other
- }
- }
- impl ::bitmask::__core::ops::Not for WithdrawReasons {
- type Output = WithdrawReasons;
- #[inline]
- fn not(self) -> Self::Output {
- let all_flags = WithdrawReasons::all();
- WithdrawReasons {
- mask: *all_flags ^ *self,
- }
- }
- }
- impl ::bitmask::__core::ops::Not for WithdrawReason {
- type Output = WithdrawReasons;
- #[inline]
- fn not(self) -> Self::Output {
- let all_flags = WithdrawReasons::all();
- WithdrawReasons {
- mask: *all_flags ^ *self,
- }
- }
- }
- }
- pub use self::dispatch::{Callable, Dispatchable, IsSubType, Parameter};
- pub use self::double_map::StorageDoubleMapWithHasher;
- pub use self::hashable::Hashable;
- pub use self::storage::{
- AppendableStorageMap, EnumerableStorageMap, StorageDoubleMap, StorageMap, StorageValue,
- };
- pub use runtime_io::{print, storage_root};
- #[doc(inline)]
- pub use srml_support_procedural::decl_storage;
- /// The void type - it cannot exist.
- #[structural_match]
- pub enum Void {}
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::clone::Clone for Void {
- #[inline]
- fn clone(&self) -> Void {
- unsafe { ::std::intrinsics::unreachable() }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::cmp::Eq for Void {
- #[inline]
- #[doc(hidden)]
- fn assert_receiver_is_total_eq(&self) -> () {
- {}
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::cmp::PartialEq for Void {
- #[inline]
- fn eq(&self, other: &Void) -> bool {
- unsafe { ::std::intrinsics::unreachable() }
- }
- }
- #[automatically_derived]
- #[allow(unused_qualifications)]
- impl ::std::fmt::Debug for Void {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- unsafe { ::std::intrinsics::unreachable() }
- }
- }
- #[cfg(feature = "std")]
- #[doc(hidden)]
- pub use serde::{Deserialize, Serialize};
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement