mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 21:41:12 +00:00
Switch srml-session keys to decl_storage! (#3184)
* Switch `srml-session` keys to `decl_storage!` * Expose `DEDUP_KEY_PREFIX` in constants * Fix test * Bump spec version
This commit is contained in:
committed by
Gavin Wood
parent
c8dab27f35
commit
5d58d583e3
@@ -18,7 +18,7 @@
|
||||
//! Proc macro of Support code for the runtime.
|
||||
// end::description[]
|
||||
|
||||
#![recursion_limit="256"]
|
||||
#![recursion_limit="512"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
||||
@@ -694,13 +694,18 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
|
||||
let mutate_impl = if !is_option {
|
||||
quote!{
|
||||
#as_double_map::insert(key1, key2, &val, storage)
|
||||
#as_double_map::insert(k1, k2, &val, storage)
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
match val {
|
||||
Some(ref val) => #as_double_map::insert(key1, key2, &val, storage),
|
||||
None => #as_double_map::remove(key1, key2, storage),
|
||||
Some(ref val) => #as_double_map::insert::<KArg1, KArg2, #typ, S>(
|
||||
k1,
|
||||
k2,
|
||||
val,
|
||||
storage,
|
||||
),
|
||||
None => #as_double_map::remove(k1, k2, storage),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -751,7 +756,10 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
fn prefix_for(k1: &#k1ty) -> Vec<u8> {
|
||||
fn prefix_for<KArg1>(k1: &KArg1) -> #scrate::rstd::vec::Vec<u8> where
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
#k1ty: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
{
|
||||
use #scrate::storage::hashed::generator::StorageHasher;
|
||||
|
||||
let mut key = #as_double_map::prefix().to_vec();
|
||||
@@ -763,7 +771,15 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
#final_prefix
|
||||
}
|
||||
|
||||
fn key_for(k1: &#k1ty, k2: &#k2ty) -> Vec<u8> {
|
||||
fn key_for<KArg1, KArg2>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
) -> #scrate::rstd::vec::Vec<u8> where
|
||||
#k1ty: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#k2ty: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
{
|
||||
use #scrate::storage::hashed::generator::StorageHasher;
|
||||
|
||||
let mut key = #as_double_map::prefix_for(k1);
|
||||
@@ -771,25 +787,50 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
key
|
||||
}
|
||||
|
||||
fn get<S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query {
|
||||
let key = #as_double_map::key_for(key1, key2);
|
||||
fn get<KArg1, KArg2, S: #scrate::UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &S,
|
||||
) -> Self::Query where
|
||||
#k1ty: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#k2ty: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
{
|
||||
let key = #as_double_map::key_for(k1, k2);
|
||||
storage.get(&key).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
fn take<S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, storage: &mut S) -> Self::Query {
|
||||
let key = #as_double_map::key_for(key1, key2);
|
||||
fn take<KArg1, KArg2, S: #scrate::UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &mut S,
|
||||
) -> Self::Query where
|
||||
#k1ty: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#k2ty: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
{
|
||||
let key = #as_double_map::key_for(k1, k2);
|
||||
storage.take(&key).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
fn mutate<R, F, S>(key1: &#k1ty, key2: &#k2ty, f: F, storage: &mut S) -> R
|
||||
where
|
||||
fn mutate<KArg1, KArg2, R, F, S: #scrate::UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
f: F,
|
||||
storage: &mut S,
|
||||
) -> R where
|
||||
#k1ty: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#k2ty: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
F: FnOnce(&mut Self::Query) -> R,
|
||||
S: #scrate::UnhashedStorage,
|
||||
{
|
||||
let mut val = #as_double_map::get(key1, key2, storage);
|
||||
let mut val = #as_double_map::get(k1, k2, storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
#mutate_impl ;
|
||||
#mutate_impl;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,15 +905,17 @@ 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
|
||||
KArg1: #scrate::rstd::borrow::Borrow<#key1_type>,
|
||||
KArg2: #scrate::rstd::borrow::Borrow<#key2_type>,
|
||||
#key1_type: #scrate::rstd::borrow::Borrow<KArg1>,
|
||||
#key2_type: #scrate::rstd::borrow::Borrow<KArg2>,
|
||||
KArg1: ?Sized + #scrate::codec::Encode,
|
||||
KArg2: ?Sized + #scrate::codec::Encode,
|
||||
{
|
||||
<
|
||||
#name<#struct_trait #instance> as
|
||||
#scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>
|
||||
>::get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage)
|
||||
>::get(k1, k2, &#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ use sr_std::borrow::Borrow;
|
||||
///
|
||||
/// Hasher are implemented in derive_key* methods.
|
||||
pub trait StorageDoubleMapWithHasher {
|
||||
type Key1: Codec;
|
||||
type Key2: Codec;
|
||||
type Key1: Encode;
|
||||
type Key2: Encode;
|
||||
type Value: Codec + Default;
|
||||
|
||||
const PREFIX: &'static [u8];
|
||||
|
||||
@@ -387,32 +387,32 @@ mod tests {
|
||||
// get / insert / take
|
||||
let key1 = 17u32;
|
||||
let key2 = 18u32;
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0u64);
|
||||
DoubleMap::insert(key1, key2, 4u64);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 4u64);
|
||||
assert_eq!(DoubleMap::take(key1, key2), 4u64);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0u64);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0u64);
|
||||
DoubleMap::insert(&key1, &key2, &4u64);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 4u64);
|
||||
assert_eq!(DoubleMap::take(&key1, &key2), 4u64);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0u64);
|
||||
|
||||
// mutate
|
||||
DoubleMap::mutate(key1, key2, |val| {
|
||||
DoubleMap::mutate(&key1, &key2, |val| {
|
||||
*val = 15;
|
||||
});
|
||||
assert_eq!(DoubleMap::get(key1, key2), 15u64);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 15u64);
|
||||
|
||||
// remove
|
||||
DoubleMap::remove(key1, key2);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0u64);
|
||||
DoubleMap::remove(&key1, &key2);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0u64);
|
||||
|
||||
// remove prefix
|
||||
DoubleMap::insert(key1, key2, 4u64);
|
||||
DoubleMap::insert(key1, key2+1, 4u64);
|
||||
DoubleMap::insert(key1+1, key2, 4u64);
|
||||
DoubleMap::insert(key1+1, key2+1, 4u64);
|
||||
DoubleMap::remove_prefix(key1);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0u64);
|
||||
assert_eq!(DoubleMap::get(key1, key2+1), 0u64);
|
||||
assert_eq!(DoubleMap::get(key1+1, key2), 4u64);
|
||||
assert_eq!(DoubleMap::get(key1+1, key2+1), 4u64);
|
||||
DoubleMap::insert(&key1, &key2, &4u64);
|
||||
DoubleMap::insert(&key1, &(key2 + 1), &4u64);
|
||||
DoubleMap::insert(&(key1 + 1), &key2, &4u64);
|
||||
DoubleMap::insert(&(key1 + 1), &(key2 + 1), &4u64);
|
||||
DoubleMap::remove_prefix(&key1);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0u64);
|
||||
assert_eq!(DoubleMap::get(&key1, &(key2 + 1)), 0u64);
|
||||
assert_eq!(DoubleMap::get(&(key1 + 1), &key2), 4u64);
|
||||
assert_eq!(DoubleMap::get(&(key1 + 1), &(key2 + 1)), 4u64);
|
||||
|
||||
});
|
||||
}
|
||||
@@ -425,9 +425,9 @@ mod tests {
|
||||
let key1 = 17u32;
|
||||
let key2 = 18u32;
|
||||
|
||||
DoubleMap::insert(key1, key2, vec![1]);
|
||||
DoubleMap::append(key1, key2, &[2, 3]).unwrap();
|
||||
assert_eq!(DoubleMap::get(key1, key2), vec![1, 2, 3]);
|
||||
DoubleMap::insert(&key1, &key2, &vec![1]);
|
||||
DoubleMap::append(&key1, &key2, &[2, 3]).unwrap();
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), &[1, 2, 3]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ impl UnhashedStorage for RuntimeStorage {
|
||||
}
|
||||
|
||||
/// Put a value in under a key.
|
||||
fn put<T: Encode>(&mut self, key: &[u8], val: &T) {
|
||||
fn put<T: Encode + ?Sized>(&mut self, key: &[u8], val: &T) {
|
||||
unhashed::put(key, val)
|
||||
}
|
||||
|
||||
@@ -332,60 +332,83 @@ impl<K: Codec, V: Codec, U> EnumerableStorageMap<K, V> for U
|
||||
/// 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> {
|
||||
pub trait StorageDoubleMap<K1: Encode, K2: Encode, 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
|
||||
fn key_for<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Vec<u8>
|
||||
where
|
||||
KArg1: Borrow<K1>,
|
||||
KArg2: Borrow<K2>,
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
fn prefix_for<KArg1>(k1: &KArg1) -> Vec<u8> where KArg1: ?Sized + Encode, K1: Borrow<KArg1>;
|
||||
|
||||
fn exists<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> bool
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
fn get<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
fn take<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
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;
|
||||
|
||||
fn remove<KArg1, KArg2>(k1: &KArg1, k2: &KArg2)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
fn remove_prefix<KArg1>(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow<KArg1>;
|
||||
|
||||
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,
|
||||
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,
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
items: &[I],
|
||||
) -> Result<(), &'static str>
|
||||
where
|
||||
KArg1: Borrow<K1>,
|
||||
KArg2: Borrow<K2>,
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
I: codec::Encode,
|
||||
V: EncodeAppend<Item=I>;
|
||||
}
|
||||
|
||||
impl<K1: Codec, K2: Codec, V: Codec, U> StorageDoubleMap<K1, K2, V> for U
|
||||
impl<K1: Encode, K2: Encode, V: Codec, U> StorageDoubleMap<K1, K2, V> for U
|
||||
where
|
||||
U: unhashed::generator::StorageDoubleMap<K1, K2, V>
|
||||
{
|
||||
@@ -395,59 +418,101 @@ where
|
||||
<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 key_for<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Vec<u8>
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
{
|
||||
<U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::key_for(k1, k2)
|
||||
}
|
||||
|
||||
fn prefix_for<KArg1: Borrow<K1>>(k1: KArg1) -> Vec<u8> {
|
||||
<U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::prefix_for(k1.borrow())
|
||||
fn prefix_for<KArg1>(k1: &KArg1) -> Vec<u8> where KArg1: ?Sized + Encode, K1: Borrow<KArg1> {
|
||||
<U as unhashed::generator::StorageDoubleMap<K1, K2, V>>::prefix_for(k1)
|
||||
}
|
||||
|
||||
fn exists<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> bool {
|
||||
U::exists(k1.borrow(), k2.borrow(), &RuntimeStorage)
|
||||
fn exists<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> bool
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
{
|
||||
U::exists(k1, k2, &RuntimeStorage)
|
||||
}
|
||||
|
||||
fn get<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(k1: KArg1, k2: KArg2) -> Self::Query {
|
||||
U::get(k1.borrow(), k2.borrow(), &RuntimeStorage)
|
||||
fn get<KArg1, KArg2>(k1: &KArg1, k2: &KArg2) -> Self::Query
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
{
|
||||
U::get(k1, k2, &RuntimeStorage)
|
||||
}
|
||||
|
||||
fn take<KArg1: Borrow<K1>, KArg2: Borrow<K2>>(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,
|
||||
{
|
||||
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
|
||||
fn insert<KArg1, KArg2, VArg>(k1: &KArg1, k2: &KArg2, val: &VArg)
|
||||
where
|
||||
KArg1: Borrow<K1>,
|
||||
KArg2: Borrow<K2>,
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
V: Borrow<VArg>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
VArg: ?Sized + Encode,
|
||||
{
|
||||
U::insert(k1, k2, val, &mut RuntimeStorage)
|
||||
}
|
||||
|
||||
fn remove<KArg1, KArg2>(k1: &KArg1, k2: &KArg2)
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
{
|
||||
U::remove(k1, k2, &mut RuntimeStorage)
|
||||
}
|
||||
|
||||
fn remove_prefix<KArg1>(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow<KArg1> {
|
||||
U::remove_prefix(k1, &mut RuntimeStorage)
|
||||
}
|
||||
|
||||
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,
|
||||
F: FnOnce(&mut Self::Query) -> R
|
||||
{
|
||||
U::mutate(k1.borrow(), k2.borrow(), f, &mut RuntimeStorage)
|
||||
U::mutate(k1, k2, f, &mut RuntimeStorage)
|
||||
}
|
||||
|
||||
fn append<KArg1, KArg2, I>(
|
||||
k1: KArg1,
|
||||
k2: KArg2,
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
items: &[I],
|
||||
) -> Result<(), &'static str>
|
||||
where
|
||||
KArg1: Borrow<K1>,
|
||||
KArg2: Borrow<K2>,
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
I: codec::Encode,
|
||||
V: EncodeAppend<Item=I>,
|
||||
{
|
||||
U::append(k1.borrow(), k2.borrow(), items, &mut RuntimeStorage)
|
||||
U::append(k1, k2, items, &mut RuntimeStorage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::codec;
|
||||
use crate::rstd::vec::Vec;
|
||||
use crate::codec::{self, Encode, EncodeAppend};
|
||||
use crate::rstd::{borrow::Borrow, vec::Vec};
|
||||
|
||||
/// Abstraction around storage with unhashed access.
|
||||
pub trait UnhashedStorage {
|
||||
@@ -38,7 +38,7 @@ pub trait UnhashedStorage {
|
||||
}
|
||||
|
||||
/// Put a value in under a key.
|
||||
fn put<T: codec::Encode>(&mut self, key: &[u8], val: &T);
|
||||
fn put<T: codec::Encode + ?Sized>(&mut self, key: &[u8], val: &T);
|
||||
|
||||
/// Remove the bytes of a key from storage.
|
||||
fn kill(&mut self, key: &[u8]);
|
||||
@@ -82,7 +82,7 @@ impl UnhashedStorage for sr_primitives::StorageOverlay {
|
||||
.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) {
|
||||
fn put<T: codec::Encode + ?Sized>(&mut self, key: &[u8], val: &T) {
|
||||
self.insert(key.to_vec(), codec::Encode::encode(val));
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ impl UnhashedStorage for sr_primitives::StorageOverlay {
|
||||
/// 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> {
|
||||
pub trait StorageDoubleMap<K1: codec::Encode, K2: codec::Encode, V: codec::Codec> {
|
||||
/// The type that get/take returns.
|
||||
type Query;
|
||||
|
||||
@@ -125,50 +125,110 @@ pub trait StorageDoubleMap<K1: codec::Codec, K2: codec::Codec, V: codec::Codec>
|
||||
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>;
|
||||
fn key_for<KArg1, KArg2>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
) -> Vec<u8> where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
/// Get the storage prefix used to fetch keys corresponding to a specific key1.
|
||||
fn prefix_for(k1: &K1) -> Vec<u8>;
|
||||
fn prefix_for<KArg1>(k1: &KArg1) -> Vec<u8> where KArg1: ?Sized + Encode, K1: Borrow<KArg1>;
|
||||
|
||||
/// true if the value is defined in storage.
|
||||
fn exists<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &S) -> bool {
|
||||
fn exists<KArg1, KArg2, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &S,
|
||||
) -> bool where K1: Borrow<KArg1>, K2: Borrow<KArg2>, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode {
|
||||
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;
|
||||
fn get<KArg1, KArg2, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &S,
|
||||
) -> Self::Query where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
/// Take the value under a key.
|
||||
fn take<S: UnhashedStorage>(k1: &K1, k2: &K2, storage: &mut S) -> Self::Query;
|
||||
fn take<KArg1, KArg2, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &mut S,
|
||||
) -> Self::Query where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode;
|
||||
|
||||
/// 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) {
|
||||
fn insert<KArg1, KArg2, VArg, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
val: &VArg,
|
||||
storage: &mut S,
|
||||
) where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
V: Borrow<VArg>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
VArg: ?Sized + Encode,
|
||||
{
|
||||
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) {
|
||||
fn remove<KArg1, KArg2, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
storage: &mut S,
|
||||
) where K1: Borrow<KArg1>, K2: Borrow<KArg2>, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode {
|
||||
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) {
|
||||
fn remove_prefix<KArg1, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
storage: &mut S,
|
||||
) where KArg1: ?Sized + Encode, K1: Borrow<KArg1> {
|
||||
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;
|
||||
fn mutate<KArg1, KArg2, R, F, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
f: F,
|
||||
storage: &mut S,
|
||||
) -> R where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
F: FnOnce(&mut Self::Query) -> R;
|
||||
|
||||
/// Append the given items to the value under the key specified.
|
||||
fn append<I, S: UnhashedStorage>(
|
||||
k1: &K1,
|
||||
k2: &K2,
|
||||
fn append<KArg1, KArg2, I, S: UnhashedStorage>(
|
||||
k1: &KArg1,
|
||||
k2: &KArg2,
|
||||
items: &[I],
|
||||
storage: &mut S,
|
||||
) -> Result<(), &'static str>
|
||||
where
|
||||
K1: Borrow<KArg1>,
|
||||
K2: Borrow<KArg2>,
|
||||
KArg1: ?Sized + Encode,
|
||||
KArg2: ?Sized + Encode,
|
||||
I: codec::Encode,
|
||||
V: codec::EncodeAppend<Item=I>,
|
||||
V: EncodeAppend<Item=I>,
|
||||
{
|
||||
let key = Self::key_for(k1, k2);
|
||||
let new_val = <V as codec::EncodeAppend>::append(
|
||||
|
||||
@@ -51,7 +51,7 @@ pub fn get_or_else<T: Decode + Sized, F: FnOnce() -> T>(key: &[u8], default_valu
|
||||
}
|
||||
|
||||
/// Put `value` in storage under `key`.
|
||||
pub fn put<T: Encode>(key: &[u8], value: &T) {
|
||||
pub fn put<T: Encode + ?Sized>(key: &[u8], value: &T) {
|
||||
value.using_encoded(|slice| runtime_io::set_storage(key, slice));
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ srml_support::decl_module! {
|
||||
}
|
||||
|
||||
srml_support::decl_storage!{
|
||||
trait Store for Module<T: Trait> as Module {
|
||||
trait Store for Module<T: Trait> as FinalKeys {
|
||||
pub Value config(value): u32;
|
||||
|
||||
pub Map: map u32 => u32;
|
||||
@@ -60,37 +60,37 @@ fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
fn final_keys() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
Value::put(1);
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(b"Module Value")), Some(1u32));
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(b"FinalKeys Value")), Some(1u32));
|
||||
|
||||
Map::insert(1, 2);
|
||||
let mut k = b"Module Map".to_vec();
|
||||
let mut k = b"FinalKeys Map".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::blake2_256(&k)), Some(2u32));
|
||||
|
||||
Map2::insert(1, 2);
|
||||
let mut k = b"Module Map2".to_vec();
|
||||
let mut k = b"FinalKeys Map2".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(&k)), Some(2u32));
|
||||
|
||||
LinkedMap::insert(1, 2);
|
||||
let mut k = b"Module LinkedMap".to_vec();
|
||||
let mut k = b"FinalKeys LinkedMap".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::blake2_256(&k)), Some(2u32));
|
||||
|
||||
LinkedMap2::insert(1, 2);
|
||||
let mut k = b"Module LinkedMap2".to_vec();
|
||||
let mut k = b"FinalKeys LinkedMap2".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(&k)), Some(2u32));
|
||||
|
||||
DoubleMap::insert(1, 2, 3);
|
||||
let mut k = b"Module DoubleMap".to_vec();
|
||||
DoubleMap::insert(&1, &2, &3);
|
||||
let mut k = b"FinalKeys DoubleMap".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
let mut k = runtime_io::blake2_256(&k).to_vec();
|
||||
k.extend(&runtime_io::blake2_256(&2u32.encode()));
|
||||
assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
|
||||
|
||||
DoubleMap2::insert(1, 2, 3);
|
||||
let mut k = b"Module DoubleMap2".to_vec();
|
||||
DoubleMap2::insert(&1, &2, &3);
|
||||
let mut k = b"FinalKeys DoubleMap2".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
let mut k = runtime_io::twox_128(&k).to_vec();
|
||||
k.extend(&runtime_io::blake2_128(&2u32.encode()));
|
||||
|
||||
@@ -335,14 +335,14 @@ fn storage_instance_independance() {
|
||||
module2::LinkedMap::<module2::Instance1>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance2>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance3>::key_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::prefix_for(1),
|
||||
module2::DoubleMap::<module2::Instance1>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::key_for(1, 1),
|
||||
module2::DoubleMap::<module2::Instance1>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::prefix_for(&1),
|
||||
module2::DoubleMap::<module2::Instance1>::prefix_for(&1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::prefix_for(&1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::prefix_for(&1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::key_for(&1, &1),
|
||||
module2::DoubleMap::<module2::Instance1>::key_for(&1, &1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::key_for(&1, &1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::key_for(&1, &1).to_vec(),
|
||||
].iter() {
|
||||
assert!(map.insert(key, ()).is_none())
|
||||
}
|
||||
@@ -396,15 +396,15 @@ fn storage_with_instance_basic_operation() {
|
||||
|
||||
let key1 = 1;
|
||||
let key2 = 1;
|
||||
assert_eq!(DoubleMap::exists(0, 0), true);
|
||||
assert_eq!(DoubleMap::exists(key1, key2), false);
|
||||
DoubleMap::insert(key1, key2, 1);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 1);
|
||||
assert_eq!(DoubleMap::take(key1, key2), 1);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0);
|
||||
DoubleMap::mutate(key1, key2, |a| *a=2);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 2);
|
||||
DoubleMap::remove(key1, key2);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0);
|
||||
assert_eq!(DoubleMap::exists(&0, &0), true);
|
||||
assert_eq!(DoubleMap::exists(&key1, &key2), false);
|
||||
DoubleMap::insert(&key1, &key2, &1);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 1);
|
||||
assert_eq!(DoubleMap::take(&key1, &key2), 1);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0);
|
||||
DoubleMap::mutate(&key1, &key2, |a| *a=2);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 2);
|
||||
DoubleMap::remove(&key1, &key2);
|
||||
assert_eq!(DoubleMap::get(&key1, &key2), 0);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user