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:
Bastian Köcher
2019-07-24 10:40:04 +02:00
committed by Gavin Wood
parent c8dab27f35
commit 5d58d583e3
14 changed files with 365 additions and 201 deletions
+2 -2
View File
@@ -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];
+21 -21
View File
@@ -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]);
});
}
+134 -69
View File
@@ -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));
}