mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 04:37:57 +00:00
Use EncodeLike for storages traits (#3676)
* 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>
This commit is contained in:
committed by
Bastian Köcher
parent
83d4764d46
commit
53e0ddee4e
@@ -6,7 +6,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] }
|
||||
srml-metadata = { path = "../metadata", default-features = false }
|
||||
rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false }
|
||||
runtime-io ={ package = "sr-io", path = "../../core/sr-io", default-features = false }
|
||||
|
||||
@@ -338,7 +338,7 @@ fn decl_store_extra_genesis(
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
#scrate::storage::StorageValue<#typ>
|
||||
>::put(&v);
|
||||
>::put::<#typ>(v);
|
||||
}}
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, is_linked, .. } => {
|
||||
@@ -363,7 +363,7 @@ fn decl_store_extra_genesis(
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
#scrate::storage::#map<#key_type, #typ>
|
||||
>::insert(&k, &v);
|
||||
>::insert::<#key_type, #typ>(k, v);
|
||||
});
|
||||
}}
|
||||
},
|
||||
@@ -384,7 +384,7 @@ fn decl_store_extra_genesis(
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
#scrate::storage::StorageDoubleMap<#key1_type, #key2_type, #typ>
|
||||
>::insert(&k1, &k2, &v);
|
||||
>::insert::<#key1_type, #key2_type, #typ>(k1, k2, v);
|
||||
});
|
||||
}}
|
||||
},
|
||||
@@ -927,11 +927,11 @@ fn impl_store_fns(
|
||||
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
pub fn #get_fn<K: #scrate::rstd::borrow::Borrow<#key_type>>(key: K) -> #value_type {
|
||||
pub fn #get_fn<K: #scrate::codec::EncodeLike<#key_type>>(key: K) -> #value_type {
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
#scrate::storage::#map<#key_type, #typ>
|
||||
>::get(key.borrow())
|
||||
>::get(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -946,12 +946,10 @@ fn impl_store_fns(
|
||||
};
|
||||
|
||||
quote!{
|
||||
pub fn #get_fn<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> #value_type
|
||||
pub fn #get_fn<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> #value_type
|
||||
where
|
||||
#key1_type: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#key2_type: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
KArg1: #scrate::codec::EncodeLike<#key1_type>,
|
||||
KArg2: #scrate::codec::EncodeLike<#key2_type>,
|
||||
{
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
pub use crate::rstd::{result, prelude::{Vec, Clone, Eq, PartialEq}, marker};
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::fmt;
|
||||
pub use crate::codec::{Codec, Decode, Encode, Input, Output, HasCompact, EncodeAsRef};
|
||||
pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef};
|
||||
pub use srml_metadata::{
|
||||
FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata,
|
||||
ModuleConstantMetadata, DefaultByte, DefaultByteGetter,
|
||||
@@ -49,16 +49,16 @@ pub trait Callable<T> {
|
||||
pub type CallableCallFor<A, T> = <A as Callable<T>>::Call;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub trait Parameter: Codec + Clone + Eq + fmt::Debug {}
|
||||
pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T> Parameter for T where T: Codec + Clone + Eq + fmt::Debug {}
|
||||
impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub trait Parameter: Codec + Clone + Eq {}
|
||||
pub trait Parameter: Codec + EncodeLike + Clone + Eq {}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<T> Parameter for T where T: Codec + Clone + Eq {}
|
||||
impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq {}
|
||||
|
||||
/// Declares a `Module` struct and a `Call` enum, which implements the dispatch logic.
|
||||
///
|
||||
|
||||
@@ -235,7 +235,7 @@ pub use serde::{Serialize, Deserialize};
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codec::Codec;
|
||||
use codec::{Codec, EncodeLike};
|
||||
use runtime_io::with_externalities;
|
||||
use primitives::Blake2Hasher;
|
||||
pub use srml_metadata::{
|
||||
@@ -245,7 +245,7 @@ mod tests {
|
||||
pub use rstd::marker::PhantomData;
|
||||
|
||||
pub trait Trait {
|
||||
type BlockNumber: Codec + Default;
|
||||
type BlockNumber: Codec + EncodeLike + Default;
|
||||
type Origin;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
//! avoid collision from a resistant hash function (which unique implies)).
|
||||
// NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>).
|
||||
|
||||
use super::{Codec, Encode, Decode, Vec};
|
||||
use crate::rstd::prelude::*;
|
||||
use codec::{Codec, Encode, Decode};
|
||||
|
||||
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
|
||||
pub fn get<T: Decode + Sized>(storage_key: &[u8], key: &[u8]) -> Option<T> {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
use rstd::prelude::*;
|
||||
use rstd::borrow::Borrow;
|
||||
use codec::{Codec, Encode, EncodeAppend};
|
||||
use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend};
|
||||
use crate::{storage::{self, unhashed}, hash::StorageHasher};
|
||||
|
||||
/// Generator for `StorageDoubleMap` used by `decl_storage`.
|
||||
@@ -39,7 +39,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher};
|
||||
/// If the key2s are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
|
||||
/// `blake2_256` must be used for Hasher2. Otherwise, other items in storage with the same first
|
||||
/// key can be compromised.
|
||||
pub trait StorageDoubleMap<K1: Encode, K2: Encode, V: Codec> {
|
||||
pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
@@ -59,10 +59,9 @@ pub trait StorageDoubleMap<K1: Encode, K2: Encode, V: Codec> {
|
||||
fn from_query_to_optional_value(v: Self::Query) -> Option<V>;
|
||||
|
||||
/// Generate the first part of the key used in top storage.
|
||||
fn storage_double_map_final_key1<KArg1>(k1: &KArg1) -> <Self::Hasher1 as StorageHasher>::Output
|
||||
fn storage_double_map_final_key1<KArg1>(k1: KArg1) -> <Self::Hasher1 as StorageHasher>::Output
|
||||
where
|
||||
KArg1: ?Sized + Encode,
|
||||
K1: Borrow<KArg1>,
|
||||
KArg1: EncodeLike<K1>,
|
||||
{
|
||||
let mut final_key1 = Self::key1_prefix().to_vec();
|
||||
k1.encode_to(&mut final_key1);
|
||||
@@ -70,12 +69,10 @@ pub trait StorageDoubleMap<K1: Encode, K2: Encode, V: Codec> {
|
||||
}
|
||||
|
||||
/// Generate the full key used in top storage.
|
||||
fn storage_double_map_final_key<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Vec<u8>
|
||||
fn storage_double_map_final_key<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Vec<u8>
|
||||
where
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec();
|
||||
final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref());
|
||||
@@ -85,39 +82,33 @@ pub trait StorageDoubleMap<K1: Encode, K2: Encode, V: Codec> {
|
||||
|
||||
impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G
|
||||
where
|
||||
K1: Encode,
|
||||
K2: Encode,
|
||||
V: Codec,
|
||||
K1: FullEncode,
|
||||
K2: FullEncode,
|
||||
V: FullCodec,
|
||||
G: StorageDoubleMap<K1, K2, V>,
|
||||
{
|
||||
type Query = G::Query;
|
||||
|
||||
fn exists<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> bool
|
||||
fn exists<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> bool
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
unhashed::exists(&Self::storage_double_map_final_key(k1, k2))
|
||||
}
|
||||
|
||||
fn get<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
fn get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
G::from_optional_value_to_query(unhashed::get(&Self::storage_double_map_final_key(k1, k2)))
|
||||
}
|
||||
|
||||
fn take<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
fn take<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
let final_key = Self::storage_double_map_final_key(k1, k2);
|
||||
|
||||
@@ -125,62 +116,57 @@ where
|
||||
G::from_optional_value_to_query(value)
|
||||
}
|
||||
|
||||
fn insert<KArg1, KArg2, VArg>(k1: &KArg1, k2: &KArg2, val: &VArg)
|
||||
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
V: Borrow<VArg>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
VArg: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
VArg: EncodeLike<V>,
|
||||
{
|
||||
unhashed::put(&Self::storage_double_map_final_key(k1, k2), &val.borrow())
|
||||
}
|
||||
|
||||
fn remove<KArg1, KArg2>(k1: &KArg1, k2: &KArg2)
|
||||
fn remove<KArg1, KArg2>(k1: KArg1, k2: KArg2)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
{
|
||||
unhashed::kill(&Self::storage_double_map_final_key(k1, k2))
|
||||
}
|
||||
|
||||
fn remove_prefix<KArg1>(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow<KArg1> {
|
||||
fn remove_prefix<KArg1>(k1: KArg1) where KArg1: EncodeLike<K1> {
|
||||
unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref())
|
||||
}
|
||||
|
||||
fn mutate<KArg1, KArg2, R, F>(k1: &KArg1, k2: &KArg2, f: F) -> R
|
||||
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
F: FnOnce(&mut Self::Query) -> R,
|
||||
{
|
||||
let mut val = G::get(k1, k2);
|
||||
let final_key = Self::storage_double_map_final_key(k1, k2);
|
||||
let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref()));
|
||||
|
||||
let ret = f(&mut val);
|
||||
match G::from_query_to_optional_value(val) {
|
||||
Some(ref val) => G::insert(k1, k2, val),
|
||||
None => G::remove(k1, k2),
|
||||
Some(ref val) => unhashed::put(final_key.as_ref(), val),
|
||||
None => unhashed::kill(final_key.as_ref()),
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn append<KArg1, KArg2, I>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
items: &[I],
|
||||
fn append<Items, Item, EncodeLikeItem, KArg1, KArg2>(
|
||||
k1: KArg1,
|
||||
k2: KArg2,
|
||||
items: Items,
|
||||
) -> Result<(), &'static str>
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
I: codec::Encode,
|
||||
V: EncodeAppend<Item=I>,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
Item: Encode,
|
||||
EncodeLikeItem: EncodeLike<Item>,
|
||||
V: EncodeAppend<Item=Item>,
|
||||
Items: IntoIterator<Item=EncodeLikeItem>,
|
||||
Items::IntoIter: ExactSizeIterator
|
||||
{
|
||||
let final_key = Self::storage_double_map_final_key(k1, k2);
|
||||
|
||||
@@ -192,7 +178,7 @@ where
|
||||
}
|
||||
});
|
||||
|
||||
let new_val = V::append(
|
||||
let new_val = V::append_or_new(
|
||||
encoded_value,
|
||||
items,
|
||||
).map_err(|_| "Could not append given item")?;
|
||||
@@ -200,4 +186,22 @@ where
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
Self::append(Ref::from(&k1), Ref::from(&k2), items.clone())
|
||||
.unwrap_or_else(|_| Self::insert(k1, k2, items));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use codec::{Codec, Encode, Decode};
|
||||
use codec::{FullCodec, Encode, Decode, EncodeLike, Ref};
|
||||
use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len};
|
||||
use rstd::{
|
||||
borrow::Borrow,
|
||||
marker::PhantomData,
|
||||
};
|
||||
use rstd::marker::PhantomData;
|
||||
|
||||
/// Generator for `StorageLinkedMap` used by `decl_storage`.
|
||||
///
|
||||
@@ -43,7 +40,7 @@ use rstd::{
|
||||
///
|
||||
/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
|
||||
/// `blake2_256` must be used. Otherwise, other values in storage can be compromised.
|
||||
pub trait StorageLinkedMap<K: Codec, V: Codec> {
|
||||
pub trait StorageLinkedMap<K: FullCodec, V: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
@@ -65,10 +62,10 @@ pub trait StorageLinkedMap<K: Codec, V: Codec> {
|
||||
/// Generate the full key used in top storage.
|
||||
fn storage_linked_map_final_key<KeyArg>(key: KeyArg) -> <Self::Hasher as StorageHasher>::Output
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
KeyArg: EncodeLike<K>,
|
||||
{
|
||||
let mut final_key = Self::prefix().to_vec();
|
||||
key.borrow().encode_to(&mut final_key);
|
||||
key.encode_to(&mut final_key);
|
||||
Self::Hasher::hash(&final_key)
|
||||
}
|
||||
|
||||
@@ -96,13 +93,29 @@ impl<Key> Default for Linkage<Key> {
|
||||
}
|
||||
}
|
||||
|
||||
// Encode like a linkage.
|
||||
#[derive(Encode)]
|
||||
struct EncodeLikeLinkage<PKey: EncodeLike<Key>, NKey: EncodeLike<Key>, Key: Encode> {
|
||||
// Previous element key in storage (None for the first element)
|
||||
previous: Option<PKey>,
|
||||
// Next element key in storage (None for the last element)
|
||||
next: Option<NKey>,
|
||||
// The key of the linkage this type encode to
|
||||
phantom: core::marker::PhantomData<Key>,
|
||||
}
|
||||
|
||||
/// A key-value pair iterator for enumerable map.
|
||||
pub struct Enumerator<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> {
|
||||
pub struct Enumerator<K: FullCodec, V: FullCodec, G: StorageLinkedMap<K, V>> {
|
||||
next: Option<K>,
|
||||
_phantom: PhantomData<(G, V)>,
|
||||
}
|
||||
|
||||
impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> Iterator for Enumerator<K, V, G> {
|
||||
impl<K, V, G> Iterator for Enumerator<K, V, G>
|
||||
where
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
type Item = (K, V);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@@ -123,7 +136,12 @@ impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> Iterator for Enumerator<K, V
|
||||
///
|
||||
/// Takes care of updating previous and next elements points
|
||||
/// as well as updates head if the element is first or last.
|
||||
fn remove_linkage<K: Codec, V: Codec, G: StorageLinkedMap<K, V>>(linkage: Linkage<K>) {
|
||||
fn remove_linkage<K, V, G>(linkage: Linkage<K>)
|
||||
where
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
let next_key = linkage.next.as_ref()
|
||||
.map(G::storage_linked_map_final_key)
|
||||
.map(|x| x.as_ref().to_vec());
|
||||
@@ -140,7 +158,7 @@ fn remove_linkage<K: Codec, V: Codec, G: StorageLinkedMap<K, V>>(linkage: Linkag
|
||||
unhashed::put(prev_key.as_ref(), &res);
|
||||
} else {
|
||||
// we were first so let's update the head
|
||||
write_head::<_, _, G>(linkage.next.as_ref());
|
||||
write_head::<_, _, _, G>(linkage.next.as_ref());
|
||||
}
|
||||
if let Some(next_key) = next_key {
|
||||
// Update previous of next element
|
||||
@@ -155,9 +173,9 @@ fn remove_linkage<K: Codec, V: Codec, G: StorageLinkedMap<K, V>>(linkage: Linkag
|
||||
/// Read the contained data and it's linkage.
|
||||
fn read_with_linkage<K, V, G>(key: &[u8]) -> Option<(V, Linkage<K>)>
|
||||
where
|
||||
K: Codec,
|
||||
V: Codec,
|
||||
G: StorageLinkedMap<K, V>
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
unhashed::get(key)
|
||||
}
|
||||
@@ -165,11 +183,12 @@ where
|
||||
/// Generate linkage for newly inserted element.
|
||||
///
|
||||
/// Takes care of updating head and previous head's pointer.
|
||||
fn new_head_linkage<K, V, G>(key: &K) -> Linkage<K>
|
||||
fn new_head_linkage<KeyArg, K, V, G>(key: KeyArg) -> Linkage<K>
|
||||
where
|
||||
K: Codec,
|
||||
V: Codec,
|
||||
G: StorageLinkedMap<K, V>
|
||||
KeyArg: EncodeLike<K>,
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
if let Some(head) = read_head::<_, _, G>() {
|
||||
// update previous head predecessor
|
||||
@@ -179,20 +198,22 @@ where
|
||||
.expect("head is set when first element is inserted
|
||||
and unset when last element is removed;
|
||||
if head is Some then it points to existing key; qed");
|
||||
unhashed::put(head_key.as_ref(), &(data, Linkage {
|
||||
let new_linkage = EncodeLikeLinkage::<_, _, K> {
|
||||
previous: Some(Ref::from(&key)),
|
||||
next: linkage.next.as_ref(),
|
||||
previous: Some(key),
|
||||
}));
|
||||
phantom: Default::default(),
|
||||
};
|
||||
unhashed::put(head_key.as_ref(), &(data, new_linkage));
|
||||
}
|
||||
// update to current head
|
||||
write_head::<_, _, G>(Some(key));
|
||||
write_head::<_, _, _, G>(Some(key));
|
||||
// return linkage with pointer to previous head
|
||||
let mut linkage = Linkage::default();
|
||||
linkage.next = Some(head);
|
||||
linkage
|
||||
} else {
|
||||
// we are first - update the head and produce empty linkage
|
||||
write_head::<_, _, G>(Some(key));
|
||||
write_head::<_, _, _, G>(Some(key));
|
||||
Linkage::default()
|
||||
}
|
||||
}
|
||||
@@ -200,9 +221,9 @@ where
|
||||
/// Read current head pointer.
|
||||
fn read_head<K, V, G>() -> Option<K>
|
||||
where
|
||||
K: Codec,
|
||||
V: Codec,
|
||||
G: StorageLinkedMap<K, V>
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
unhashed::get(G::storage_linked_map_final_head_key().as_ref())
|
||||
}
|
||||
@@ -210,35 +231,41 @@ where
|
||||
/// Overwrite current head pointer.
|
||||
///
|
||||
/// If `None` is given head is removed from storage.
|
||||
fn write_head<K, V, G>(head: Option<&K>)
|
||||
fn write_head<KeyArg, K, V, G>(head: Option<KeyArg>)
|
||||
where
|
||||
K: Codec,
|
||||
V: Codec,
|
||||
G: StorageLinkedMap<K, V>
|
||||
KeyArg: EncodeLike<K>,
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
match head {
|
||||
match head.as_ref() {
|
||||
Some(head) => unhashed::put(G::storage_linked_map_final_head_key().as_ref(), head),
|
||||
None => unhashed::kill(G::storage_linked_map_final_head_key().as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> storage::StorageLinkedMap<K, V> for G {
|
||||
impl<K, V, G> storage::StorageLinkedMap<K, V> for G
|
||||
where
|
||||
K: FullCodec,
|
||||
V: FullCodec,
|
||||
G: StorageLinkedMap<K, V>,
|
||||
{
|
||||
type Query = G::Query;
|
||||
|
||||
type Enumerator = Enumerator<K, V, Self>;
|
||||
|
||||
fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool {
|
||||
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool {
|
||||
unhashed::exists(Self::storage_linked_map_final_key(key).as_ref())
|
||||
}
|
||||
|
||||
fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
|
||||
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
|
||||
let val = unhashed::get(Self::storage_linked_map_final_key(key).as_ref());
|
||||
G::from_optional_value_to_query(val)
|
||||
}
|
||||
|
||||
fn swap<KeyArg1: Borrow<K>, KeyArg2: Borrow<K>>(key1: KeyArg1, key2: KeyArg2) {
|
||||
let final_key1 = Self::storage_linked_map_final_key(key1.borrow());
|
||||
let final_key2 = Self::storage_linked_map_final_key(key2.borrow());
|
||||
fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2) {
|
||||
let final_key1 = Self::storage_linked_map_final_key(Ref::from(&key1));
|
||||
let final_key2 = Self::storage_linked_map_final_key(Ref::from(&key2));
|
||||
let full_value_1 = read_with_linkage::<_, _, G>(final_key1.as_ref());
|
||||
let full_value_2 = read_with_linkage::<_, _, G>(final_key2.as_ref());
|
||||
|
||||
@@ -251,13 +278,13 @@ impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> storage::StorageLinkedMap<K,
|
||||
// Remove key and insert the new one.
|
||||
(Some((value, _linkage)), None) => {
|
||||
Self::remove(key1);
|
||||
let linkage = new_head_linkage::<_, _, G>(key2.borrow());
|
||||
let linkage = new_head_linkage::<_, _, _, G>(key2);
|
||||
unhashed::put(final_key2.as_ref(), &(value, linkage));
|
||||
}
|
||||
// Remove key and insert the new one.
|
||||
(None, Some((value, _linkage))) => {
|
||||
Self::remove(key2);
|
||||
let linkage = new_head_linkage::<_, _, G>(key1.borrow());
|
||||
let linkage = new_head_linkage::<_, _, _, G>(key1);
|
||||
unhashed::put(final_key1.as_ref(), &(value, linkage));
|
||||
}
|
||||
// No-op.
|
||||
@@ -265,37 +292,23 @@ impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> storage::StorageLinkedMap<K,
|
||||
}
|
||||
}
|
||||
|
||||
fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg) {
|
||||
let final_key = Self::storage_linked_map_final_key(key.borrow());
|
||||
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg) {
|
||||
let final_key = Self::storage_linked_map_final_key(Ref::from(&key));
|
||||
let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) {
|
||||
// overwrite but reuse existing linkage
|
||||
Some((_data, linkage)) => linkage,
|
||||
// create new linkage
|
||||
None => new_head_linkage::<_, _, G>(key.borrow()),
|
||||
None => new_head_linkage::<_, _, _, G>(key),
|
||||
};
|
||||
unhashed::put(final_key.as_ref(), &(val.borrow(), linkage))
|
||||
unhashed::put(final_key.as_ref(), &(val, linkage))
|
||||
}
|
||||
|
||||
fn insert_ref<KeyArg: Borrow<K>, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg)
|
||||
where
|
||||
V: AsRef<ValArg>
|
||||
{
|
||||
let final_key = Self::storage_linked_map_final_key(key.borrow());
|
||||
let linkage = match read_with_linkage::<_, _, G>(final_key.as_ref()) {
|
||||
// overwrite but reuse existing linkage
|
||||
Some((_data, linkage)) => linkage,
|
||||
// create new linkage
|
||||
None => new_head_linkage::<_, _, G>(key.borrow()),
|
||||
};
|
||||
unhashed::put(final_key.as_ref(), &(&val, &linkage))
|
||||
}
|
||||
|
||||
fn remove<KeyArg: Borrow<K>>(key: KeyArg) {
|
||||
fn remove<KeyArg: EncodeLike<K>>(key: KeyArg) {
|
||||
G::take(key);
|
||||
}
|
||||
|
||||
fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
|
||||
let final_key = Self::storage_linked_map_final_key(key.borrow());
|
||||
fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
|
||||
let final_key = Self::storage_linked_map_final_key(Ref::from(&key));
|
||||
|
||||
let (mut val, _linkage) = read_with_linkage::<_, _, G>(final_key.as_ref())
|
||||
.map(|(data, linkage)| (G::from_optional_value_to_query(Some(data)), Some(linkage)))
|
||||
@@ -303,13 +316,13 @@ impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> storage::StorageLinkedMap<K,
|
||||
|
||||
let ret = f(&mut val);
|
||||
match G::from_query_to_optional_value(val) {
|
||||
Some(ref val) => G::insert(key.borrow(), val),
|
||||
None => G::remove(key.borrow()),
|
||||
Some(ref val) => G::insert(key, val),
|
||||
None => G::remove(key),
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
|
||||
fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
|
||||
let final_key = Self::storage_linked_map_final_key(key);
|
||||
|
||||
let full_value: Option<(V, Linkage<K>)> = unhashed::take(final_key.as_ref());
|
||||
@@ -333,7 +346,7 @@ impl<K: Codec, V: Codec, G: StorageLinkedMap<K, V>> storage::StorageLinkedMap<K,
|
||||
read_head::<_, _, G>()
|
||||
}
|
||||
|
||||
fn decode_len<KeyArg: Borrow<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
fn decode_len<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
where V: codec::DecodeLength + Len
|
||||
{
|
||||
let key = Self::storage_linked_map_final_key(key);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#[cfg(not(feature = "std"))]
|
||||
use rstd::prelude::*;
|
||||
use rstd::borrow::Borrow;
|
||||
use codec::{Codec, Encode};
|
||||
use codec::{FullCodec, FullEncode, Encode, EncodeLike, Ref, EncodeAppend};
|
||||
use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len};
|
||||
|
||||
/// Generator for `StorageMap` used by `decl_storage`.
|
||||
@@ -31,7 +31,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len};
|
||||
///
|
||||
/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
|
||||
/// `blake2_256` must be used. Otherwise, other values in storage can be compromised.
|
||||
pub trait StorageMap<K: Codec, V: Codec> {
|
||||
pub trait StorageMap<K: FullEncode, V: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
@@ -50,7 +50,7 @@ pub trait StorageMap<K: Codec, V: Codec> {
|
||||
/// Generate the full key used in top storage.
|
||||
fn storage_map_final_key<KeyArg>(key: KeyArg) -> <Self::Hasher as StorageHasher>::Output
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
KeyArg: EncodeLike<K>,
|
||||
{
|
||||
let mut final_key = Self::prefix().to_vec();
|
||||
key.borrow().encode_to(&mut final_key);
|
||||
@@ -58,14 +58,14 @@ pub trait StorageMap<K: Codec, V: Codec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Codec, V: Codec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
|
||||
impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
|
||||
type Query = G::Query;
|
||||
|
||||
fn hashed_key_for<KeyArg: Borrow<K>>(key: KeyArg) -> Vec<u8> {
|
||||
fn hashed_key_for<KeyArg: EncodeLike<K>>(key: KeyArg) -> Vec<u8> {
|
||||
Self::storage_map_final_key(key).as_ref().to_vec()
|
||||
}
|
||||
|
||||
fn swap<KeyArg1: Borrow<K>, KeyArg2: Borrow<K>>(key1: KeyArg1, key2: KeyArg2) {
|
||||
fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2) {
|
||||
let k1 = Self::storage_map_final_key(key1);
|
||||
let k2 = Self::storage_map_final_key(key2);
|
||||
|
||||
@@ -82,52 +82,48 @@ impl<K: Codec, V: Codec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
|
||||
}
|
||||
}
|
||||
|
||||
fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool {
|
||||
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool {
|
||||
unhashed::exists(Self::storage_map_final_key(key).as_ref())
|
||||
}
|
||||
|
||||
fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
|
||||
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
|
||||
G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref()))
|
||||
}
|
||||
|
||||
fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg) {
|
||||
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg) {
|
||||
unhashed::put(Self::storage_map_final_key(key).as_ref(), &val.borrow())
|
||||
}
|
||||
|
||||
fn insert_ref<KeyArg: Borrow<K>, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg)
|
||||
where V: AsRef<ValArg>
|
||||
{
|
||||
val.using_encoded(|b| unhashed::put_raw(Self::storage_map_final_key(key).as_ref(), b))
|
||||
}
|
||||
|
||||
fn remove<KeyArg: Borrow<K>>(key: KeyArg) {
|
||||
fn remove<KeyArg: EncodeLike<K>>(key: KeyArg) {
|
||||
unhashed::kill(Self::storage_map_final_key(key).as_ref())
|
||||
}
|
||||
|
||||
fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
|
||||
let mut val = G::get(key.borrow());
|
||||
fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
|
||||
let final_key = Self::storage_map_final_key(key);
|
||||
let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref()));
|
||||
|
||||
let ret = f(&mut val);
|
||||
match G::from_query_to_optional_value(val) {
|
||||
Some(ref val) => G::insert(key, val),
|
||||
None => G::remove(key),
|
||||
Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()),
|
||||
None => unhashed::kill(final_key.as_ref()),
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
|
||||
fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
|
||||
let key = Self::storage_map_final_key(key);
|
||||
let value = unhashed::take(key.as_ref());
|
||||
G::from_optional_value_to_query(value)
|
||||
}
|
||||
|
||||
fn append<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str>
|
||||
fn append<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items) -> Result<(), &'static str>
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
I: 'a + codec::Encode,
|
||||
V: codec::EncodeAppend<Item=I>,
|
||||
R: IntoIterator<Item=&'a I>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
KeyArg: EncodeLike<K>,
|
||||
Item: Encode,
|
||||
EncodeLikeItem: EncodeLike<Item>,
|
||||
V: EncodeAppend<Item=Item>,
|
||||
Items: IntoIterator<Item=EncodeLikeItem>,
|
||||
Items::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let key = Self::storage_map_final_key(key);
|
||||
let encoded_value = unhashed::get_raw(key.as_ref())
|
||||
@@ -138,7 +134,7 @@ impl<K: Codec, V: Codec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
|
||||
}
|
||||
});
|
||||
|
||||
let new_val = V::append(
|
||||
let new_val = V::append_or_new(
|
||||
encoded_value,
|
||||
items,
|
||||
).map_err(|_| "Could not append given item")?;
|
||||
@@ -146,19 +142,20 @@ impl<K: Codec, V: Codec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R)
|
||||
fn append_or_insert<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items)
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
I: 'a + codec::Encode + Clone,
|
||||
V: codec::EncodeAppend<Item=I> + crate::rstd::iter::FromIterator<I>,
|
||||
R: IntoIterator<Item=&'a I> + Clone,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
KeyArg: EncodeLike<K>,
|
||||
Item: Encode,
|
||||
EncodeLikeItem: EncodeLike<Item>,
|
||||
V: EncodeAppend<Item=Item>,
|
||||
Items: IntoIterator<Item=EncodeLikeItem> + Clone + EncodeLike<V>,
|
||||
Items::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
Self::append(key.borrow(), items.clone())
|
||||
.unwrap_or_else(|_| Self::insert(key, &items.into_iter().cloned().collect()));
|
||||
Self::append(Ref::from(&key), items.clone())
|
||||
.unwrap_or_else(|_| Self::insert(key, items));
|
||||
}
|
||||
|
||||
fn decode_len<KeyArg: Borrow<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
fn decode_len<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
where V: codec::DecodeLength + Len
|
||||
{
|
||||
let key = Self::storage_map_final_key(key);
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use rstd::prelude::*;
|
||||
use rstd::{borrow::Borrow, iter::FromIterator};
|
||||
use codec::{Codec, Encode};
|
||||
use codec::{FullCodec, Encode, EncodeAppend, EncodeLike};
|
||||
use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len};
|
||||
|
||||
/// Generator for `StorageValue` used by `decl_storage`.
|
||||
@@ -26,7 +25,7 @@ use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::L
|
||||
/// ```nocompile
|
||||
/// Twox128(unhashed_key)
|
||||
/// ```
|
||||
pub trait StorageValue<T: Codec> {
|
||||
pub trait StorageValue<T: FullCodec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
@@ -45,7 +44,7 @@ pub trait StorageValue<T: Codec> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Codec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
type Query = G::Query;
|
||||
|
||||
fn hashed_key() -> [u8; 16] {
|
||||
@@ -61,12 +60,8 @@ impl<T: Codec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
G::from_optional_value_to_query(value)
|
||||
}
|
||||
|
||||
fn put<Arg: Borrow<T>>(val: Arg) {
|
||||
unhashed::put(&Self::storage_value_final_key(), val.borrow())
|
||||
}
|
||||
|
||||
fn put_ref<Arg: ?Sized + Encode>(val: &Arg) where T: AsRef<Arg> {
|
||||
val.using_encoded(|b| unhashed::put_raw(&Self::storage_value_final_key(), b))
|
||||
fn put<Arg: EncodeLike<T>>(val: Arg) {
|
||||
unhashed::put(&Self::storage_value_final_key(), &val)
|
||||
}
|
||||
|
||||
fn kill() {
|
||||
@@ -96,12 +91,13 @@ impl<T: Codec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
/// Append the given items to the value in the storage.
|
||||
///
|
||||
/// `T` is required to implement `codec::EncodeAppend`.
|
||||
fn append<'a, I, R>(items: R) -> Result<(), &'static str>
|
||||
fn append<Items, Item, EncodeLikeItem>(items: Items) -> Result<(), &'static str>
|
||||
where
|
||||
I: 'a + codec::Encode,
|
||||
T: codec::EncodeAppend<Item=I>,
|
||||
R: IntoIterator<Item=&'a I>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
Item: Encode,
|
||||
EncodeLikeItem: EncodeLike<Item>,
|
||||
T: EncodeAppend<Item=Item>,
|
||||
Items: IntoIterator<Item=EncodeLikeItem>,
|
||||
Items::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let key = Self::storage_value_final_key();
|
||||
let encoded_value = unhashed::get_raw(&key)
|
||||
@@ -112,7 +108,7 @@ impl<T: Codec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
}
|
||||
});
|
||||
|
||||
let new_val = T::append(
|
||||
let new_val = T::append_or_new(
|
||||
encoded_value,
|
||||
items,
|
||||
).map_err(|_| "Could not append given item")?;
|
||||
@@ -124,15 +120,14 @@ impl<T: Codec, G: StorageValue<T>> storage::StorageValue<T> for G {
|
||||
/// old (presumably corrupt) value is replaced with the given `items`.
|
||||
///
|
||||
/// `T` is required to implement `codec::EncodeAppend`.
|
||||
fn append_or_put<'a, I, R>(items: R)
|
||||
where
|
||||
I: 'a + codec::Encode + Clone,
|
||||
T: codec::EncodeAppend<Item=I> + FromIterator<I>,
|
||||
R: IntoIterator<Item=&'a I> + Clone,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
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
|
||||
{
|
||||
Self::append(items.clone())
|
||||
.unwrap_or_else(|_| Self::put(&items.into_iter().cloned().collect()));
|
||||
Self::append(items.clone()).unwrap_or_else(|_| Self::put(items));
|
||||
}
|
||||
|
||||
/// Read the length of the value in a fast way, without decoding the entire value.
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
//! Stuff to do with the runtime's storage.
|
||||
|
||||
use crate::rstd::prelude::*;
|
||||
use crate::rstd::{borrow::Borrow, iter::FromIterator};
|
||||
use codec::{Codec, Encode, Decode, EncodeAppend};
|
||||
use rstd::prelude::*;
|
||||
use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike};
|
||||
use crate::traits::Len;
|
||||
|
||||
#[macro_use]
|
||||
@@ -29,7 +28,7 @@ pub mod child;
|
||||
pub mod generator;
|
||||
|
||||
/// A trait for working with macro-generated storage values under the substrate storage API.
|
||||
pub trait StorageValue<T: Codec> {
|
||||
pub trait StorageValue<T: FullCodec> {
|
||||
/// The type that get/take return.
|
||||
type Query;
|
||||
|
||||
@@ -43,11 +42,7 @@ pub trait StorageValue<T: Codec> {
|
||||
fn get() -> Self::Query;
|
||||
|
||||
/// Store a value under this key into the provided storage instance.
|
||||
fn put<Arg: Borrow<T>>(val: Arg);
|
||||
|
||||
/// Store a value under this key into the provided storage instance; this can take any reference
|
||||
/// type that derefs to `T` (and has `Encode` implemented).
|
||||
fn put_ref<Arg: ?Sized + Encode>(val: &Arg) where T: AsRef<Arg>;
|
||||
fn put<Arg: EncodeLike<T>>(val: Arg);
|
||||
|
||||
/// Mutate the value
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R>(f: F) -> R;
|
||||
@@ -61,11 +56,13 @@ pub trait StorageValue<T: Codec> {
|
||||
/// Append the given item to the value in the storage.
|
||||
///
|
||||
/// `T` is required to implement `codec::EncodeAppend`.
|
||||
fn append<'a, I, R>(items: R) -> Result<(), &'static str> where
|
||||
I: 'a + Encode,
|
||||
T: EncodeAppend<Item=I>,
|
||||
R: IntoIterator<Item=&'a I>,
|
||||
R::IntoIter: ExactSizeIterator;
|
||||
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.
|
||||
///
|
||||
@@ -78,11 +75,13 @@ pub trait StorageValue<T: Codec> {
|
||||
///
|
||||
/// 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<'a, I, R>(items: R) where
|
||||
I: 'a + Encode + Clone,
|
||||
T: EncodeAppend<Item=I> + FromIterator<I>,
|
||||
R: IntoIterator<Item=&'a I> + Clone,
|
||||
R::IntoIter: ExactSizeIterator;
|
||||
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.
|
||||
///
|
||||
@@ -92,60 +91,58 @@ pub trait StorageValue<T: Codec> {
|
||||
}
|
||||
|
||||
/// A strongly-typed map in storage.
|
||||
pub trait StorageMap<K: Codec, V: Codec> {
|
||||
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: Borrow<K>>(key: KeyArg) -> Vec<u8>;
|
||||
fn hashed_key_for<KeyArg: EncodeLike<K>>(key: KeyArg) -> Vec<u8>;
|
||||
|
||||
/// Does the value (explicitly) exist in storage?
|
||||
fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool;
|
||||
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool;
|
||||
|
||||
/// Load the value associated with the given key from the map.
|
||||
fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
|
||||
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
||||
|
||||
/// Swap the values of two keys.
|
||||
fn swap<KeyArg1: Borrow<K>, KeyArg2: Borrow<K>>(key1: KeyArg1, key2: KeyArg2);
|
||||
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: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg);
|
||||
|
||||
/// Store a value under this key into the provided storage instance; this can take any reference
|
||||
/// type that derefs to `T` (and has `Encode` implemented).
|
||||
fn insert_ref<KeyArg: Borrow<K>, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef<ValArg>;
|
||||
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg);
|
||||
|
||||
/// Remove the value under a key.
|
||||
fn remove<KeyArg: Borrow<K>>(key: KeyArg);
|
||||
fn remove<KeyArg: EncodeLike<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;
|
||||
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: Borrow<K>>(key: KeyArg) -> Self::Query;
|
||||
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<'a, I, R, KeyArg>(key: KeyArg, items: R) -> Result<(), &'static str>
|
||||
fn append<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items) -> Result<(), &'static str>
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
I: 'a + codec::Encode,
|
||||
V: codec::EncodeAppend<Item=I>,
|
||||
R: IntoIterator<Item=&'a I> + Clone,
|
||||
R::IntoIter: ExactSizeIterator;
|
||||
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`.
|
||||
///
|
||||
/// `T` is required to implement `codec::EncodeAppend`.
|
||||
fn append_or_insert<'a, I, R, KeyArg>(key: KeyArg, items: R)
|
||||
/// `V` is required to implement `codec::EncodeAppend`.
|
||||
fn append_or_insert<Items, Item, EncodeLikeItem, KeyArg>(key: KeyArg, items: Items)
|
||||
where
|
||||
KeyArg: Borrow<K>,
|
||||
I: 'a + codec::Encode + Clone,
|
||||
V: codec::EncodeAppend<Item=I> + crate::rstd::iter::FromIterator<I>,
|
||||
R: IntoIterator<Item=&'a I> + Clone,
|
||||
R::IntoIter: ExactSizeIterator;
|
||||
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.
|
||||
///
|
||||
@@ -154,14 +151,14 @@ pub trait StorageMap<K: Codec, V: Codec> {
|
||||
/// 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: Borrow<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
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: Codec, V: Codec> {
|
||||
pub trait StorageLinkedMap<K: FullCodec, V: FullCodec> {
|
||||
/// The type that get/take return.
|
||||
type Query;
|
||||
|
||||
@@ -169,29 +166,25 @@ pub trait StorageLinkedMap<K: Codec, V: Codec> {
|
||||
type Enumerator: Iterator<Item = (K, V)>;
|
||||
|
||||
/// Does the value (explicitly) exist in storage?
|
||||
fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool;
|
||||
fn exists<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool;
|
||||
|
||||
/// Load the value associated with the given key from the map.
|
||||
fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
|
||||
fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
||||
|
||||
/// Swap the values of two keys.
|
||||
fn swap<KeyArg1: Borrow<K>, KeyArg2: Borrow<K>>(key1: KeyArg1, key2: KeyArg2);
|
||||
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: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg);
|
||||
|
||||
/// Store a value under this key into the provided storage instance; this can take any reference
|
||||
/// type that derefs to `T` (and has `Encode` implemented).
|
||||
fn insert_ref<KeyArg: Borrow<K>, ValArg: ?Sized + Encode>(key: KeyArg, val: &ValArg) where V: AsRef<ValArg>;
|
||||
fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg);
|
||||
|
||||
/// Remove the value under a key.
|
||||
fn remove<KeyArg: Borrow<K>>(key: KeyArg);
|
||||
fn remove<KeyArg: EncodeLike<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;
|
||||
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: Borrow<K>>(key: KeyArg) -> Self::Query;
|
||||
fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query;
|
||||
|
||||
/// Return current head element.
|
||||
fn head() -> Option<K>;
|
||||
@@ -206,7 +199,7 @@ pub trait StorageLinkedMap<K: Codec, V: Codec> {
|
||||
/// 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: Borrow<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
fn decode_len<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<usize, &'static str>
|
||||
where V: codec::DecodeLength + Len;
|
||||
}
|
||||
|
||||
@@ -214,67 +207,69 @@ pub trait StorageLinkedMap<K: Codec, V: Codec> {
|
||||
///
|
||||
/// It provides an important ability to efficiently remove all entries
|
||||
/// that have a common first key.
|
||||
pub trait StorageDoubleMap<K1: Encode, K2: Encode, V: Codec> {
|
||||
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
|
||||
fn exists<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> bool
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>;
|
||||
|
||||
fn get<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
fn get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>;
|
||||
|
||||
fn take<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
fn take<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>;
|
||||
|
||||
fn insert<KArg1, KArg2, VArg>(k1: &KArg1, k2: &KArg2, val: &VArg)
|
||||
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
V: Borrow<VArg>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
VArg: ?Sized + Encode;
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
VArg: EncodeLike<V>;
|
||||
|
||||
fn remove<KArg1, KArg2>(k1: &KArg1, k2: &KArg2)
|
||||
fn remove<KArg1, KArg2>(k1: KArg1, k2: KArg2)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>;
|
||||
|
||||
fn remove_prefix<KArg1>(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow<KArg1>;
|
||||
fn remove_prefix<KArg1>(k1: KArg1) where KArg1: ?Sized + EncodeLike<K1>;
|
||||
|
||||
fn mutate<KArg1, KArg2, R, F>(k1: &KArg1, k2: &KArg2, f: F) -> R
|
||||
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
KArg1: EncodeLike<K1>,
|
||||
KArg2: EncodeLike<K2>,
|
||||
F: FnOnce(&mut Self::Query) -> R;
|
||||
|
||||
fn append<KArg1, KArg2, I>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
items: &[I],
|
||||
fn append<Items, Item, EncodeLikeItem, KArg1, KArg2>(
|
||||
k1: KArg1,
|
||||
k2: KArg2,
|
||||
items: Items,
|
||||
) -> Result<(), &'static str>
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
I: codec::Encode,
|
||||
V: EncodeAppend<Item=I>;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -256,6 +256,7 @@ mod tests {
|
||||
use crate::metadata::*;
|
||||
use crate::metadata::StorageHasher;
|
||||
use crate::rstd::marker::PhantomData;
|
||||
use crate::codec::{Encode, Decode, EncodeLike};
|
||||
|
||||
storage_items! {
|
||||
Value: b"a" => u32;
|
||||
@@ -286,7 +287,7 @@ mod tests {
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
type Origin: crate::codec::Encode + crate::codec::Decode + ::std::default::Default;
|
||||
type Origin: Encode + Decode + EncodeLike + std::default::Default;
|
||||
type BlockNumber;
|
||||
}
|
||||
|
||||
@@ -839,13 +840,17 @@ mod test_append_and_len {
|
||||
#[test]
|
||||
fn append_or_put_works() {
|
||||
with_externalities(&mut TestExternalities::default(), || {
|
||||
let _ = MapVec::append_or_insert(1, [1, 2, 3].iter());
|
||||
let _ = MapVec::append_or_insert(1, [4, 5].iter());
|
||||
let _ = MapVec::append_or_insert(1, &[1, 2, 3][..]);
|
||||
let _ = MapVec::append_or_insert(1, &[4, 5][..]);
|
||||
assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]);
|
||||
|
||||
let _ = JustVec::append_or_put([1, 2, 3].iter());
|
||||
let _ = JustVec::append_or_put([4, 5].iter());
|
||||
let _ = JustVec::append_or_put(&[1, 2, 3][..]);
|
||||
let _ = JustVec::append_or_put(&[4, 5][..]);
|
||||
assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]);
|
||||
|
||||
let _ = OptionVec::append_or_put(&[1, 2, 3][..]);
|
||||
let _ = OptionVec::append_or_put(&[4, 5][..]);
|
||||
assert_eq!(OptionVec::get(), Some(vec![1, 2, 3, 4, 5]));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
//! Operation on unhashed runtime storage.
|
||||
|
||||
use super::{Encode, Decode, Vec};
|
||||
use rstd::prelude::*;
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
/// 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> {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module.
|
||||
|
||||
use rstd::{prelude::*, result, marker::PhantomData, ops::Div};
|
||||
use codec::{Codec, Encode, Decode};
|
||||
use codec::{FullCodec, Codec, Encode, Decode};
|
||||
use primitives::u32_trait::Value as U32;
|
||||
use sr_primitives::{
|
||||
ConsensusEngineId,
|
||||
@@ -254,7 +254,7 @@ pub enum SignedImbalance<B, P: Imbalance<B>>{
|
||||
impl<
|
||||
P: Imbalance<B, Opposite=N>,
|
||||
N: Imbalance<B, Opposite=P>,
|
||||
B: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default,
|
||||
B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDebug + Default,
|
||||
> SignedImbalance<B, P> {
|
||||
pub fn zero() -> Self {
|
||||
SignedImbalance::Positive(P::zero())
|
||||
@@ -317,7 +317,7 @@ impl<
|
||||
/// Abstraction over a fungible assets system.
|
||||
pub trait Currency<AccountId> {
|
||||
/// The balance of an account.
|
||||
type Balance: SimpleArithmetic + Codec + Copy + MaybeSerializeDebug + Default;
|
||||
type Balance: SimpleArithmetic + FullCodec + 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.
|
||||
@@ -615,7 +615,7 @@ bitmask! {
|
||||
}
|
||||
|
||||
pub trait Time {
|
||||
type Moment: SimpleArithmetic + Codec + Clone + Default + Copy;
|
||||
type Moment: SimpleArithmetic + FullCodec + Clone + Default + Copy;
|
||||
|
||||
fn now() -> Self::Moment;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ use codec::Encode;
|
||||
use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue};
|
||||
|
||||
mod no_instance {
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Encode, Decode, EncodeLike};
|
||||
|
||||
pub trait Trait {
|
||||
type Origin;
|
||||
type BlockNumber: Encode + Decode + Default + Clone;
|
||||
type BlockNumber: Encode + Decode + EncodeLike + Default + Clone;
|
||||
}
|
||||
|
||||
support::decl_module! {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub trait Trait {
|
||||
type BlockNumber: codec::Codec + Default;
|
||||
type BlockNumber: codec::Codec + codec::EncodeLike + Default;
|
||||
type Origin;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ mod module1 {
|
||||
type Event: From<Event<Self, I>> + Into<<Self as system::Trait>::Event>;
|
||||
type Origin: From<Origin<Self, I>>;
|
||||
type SomeParameter: Get<u32>;
|
||||
type GenericType: Default + Clone + codec::Codec;
|
||||
type GenericType: Default + Clone + codec::Codec + codec::EncodeLike;
|
||||
}
|
||||
|
||||
support::decl_module! {
|
||||
@@ -314,10 +314,10 @@ fn storage_instance_independance() {
|
||||
module2::Map::<module2::Instance1>::insert(0, 0);
|
||||
module2::Map::<module2::Instance2>::insert(0, 0);
|
||||
module2::Map::<module2::Instance3>::insert(0, 0);
|
||||
module2::LinkedMap::<module2::DefaultInstance>::insert(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance1>::insert(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance2>::insert(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance3>::insert(0, vec![]);
|
||||
module2::LinkedMap::<module2::DefaultInstance>::insert::<_, Vec<u8>>(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance1>::insert::<_, Vec<u8>>(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance2>::insert::<_, Vec<u8>>(0, vec![]);
|
||||
module2::LinkedMap::<module2::Instance3>::insert::<_, Vec<u8>>(0, vec![]);
|
||||
module2::DoubleMap::<module2::DefaultInstance>::insert(&0, &0, &0);
|
||||
module2::DoubleMap::<module2::Instance1>::insert(&0, &0, &0);
|
||||
module2::DoubleMap::<module2::Instance2>::insert(&0, &0, &0);
|
||||
@@ -377,7 +377,7 @@ fn storage_with_instance_basic_operation() {
|
||||
assert_eq!(LinkedMap::get(key), vec![]);
|
||||
assert_eq!(LinkedMap::exists(key), false);
|
||||
assert_eq!(LinkedMap::enumerate().count(), 1);
|
||||
LinkedMap::insert_ref(key, &vec![1]);
|
||||
LinkedMap::insert(key, &vec![1]);
|
||||
assert_eq!(LinkedMap::enumerate().count(), 2);
|
||||
|
||||
let key1 = 1;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use support::codec::{Encode, Decode};
|
||||
use support::codec::{Encode, Decode, EncodeLike};
|
||||
|
||||
pub trait Trait: 'static + Eq + Clone {
|
||||
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
|
||||
+ From<RawOrigin<Self::AccountId>>;
|
||||
|
||||
type BlockNumber: Decode + Encode + Clone + Default;
|
||||
type BlockNumber: Decode + Encode + EncodeLike + Clone + Default;
|
||||
type Hash;
|
||||
type AccountId: Encode + Decode;
|
||||
type AccountId: Encode + EncodeLike + Decode;
|
||||
type Event: From<Event>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user