Refactor srml-support/storage (#3702)

* refactor

* fix

* remove unused vec storages

* address comment
This commit is contained in:
thiolliere
2019-09-27 14:39:14 +02:00
committed by GitHub
parent ff75e498d4
commit 75ed6cc04e
12 changed files with 133 additions and 453 deletions
+2 -193
View File
@@ -17,71 +17,8 @@
//! Operation on runtime storage using hashed keys.
use super::unhashed;
use crate::rstd::prelude::*;
use crate::rstd::borrow::Borrow;
use crate::codec::{Codec, Encode, Decode, KeyedVec};
use runtime_io::{self, twox_64, twox_128, blake2_128, twox_256, blake2_256};
/// Hasher to use to hash keys to insert to storage.
pub trait StorageHasher: 'static {
type Output: AsRef<[u8]>;
fn hash(x: &[u8]) -> Self::Output;
}
/// Hash storage keys with `concat(twox64(key), key)`
pub struct Twox64Concat;
impl StorageHasher for Twox64Concat {
type Output = Vec<u8>;
fn hash(x: &[u8]) -> Vec<u8> {
twox_64(x)
.into_iter()
.chain(x.into_iter())
.cloned()
.collect::<Vec<_>>()
}
}
#[test]
fn test_twox_64_concat() {
let r = Twox64Concat::hash(b"foo");
assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..]))
}
/// Hash storage keys with blake2 128
pub struct Blake2_128;
impl StorageHasher for Blake2_128 {
type Output = [u8; 16];
fn hash(x: &[u8]) -> [u8; 16] {
blake2_128(x)
}
}
/// Hash storage keys with blake2 256
pub struct Blake2_256;
impl StorageHasher for Blake2_256 {
type Output = [u8; 32];
fn hash(x: &[u8]) -> [u8; 32] {
blake2_256(x)
}
}
/// Hash storage keys with twox 128
pub struct Twox128;
impl StorageHasher for Twox128 {
type Output = [u8; 16];
fn hash(x: &[u8]) -> [u8; 16] {
twox_128(x)
}
}
/// Hash storage keys with twox 256
pub struct Twox256;
impl StorageHasher for Twox256 {
type Output = [u8; 32];
fn hash(x: &[u8]) -> [u8; 32] {
twox_256(x)
}
}
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, HashFn, R>(hash: &HashFn, key: &[u8]) -> Option<T>
@@ -216,131 +153,3 @@ where
{
unhashed::put_raw(&hash(key).as_ref(), value)
}
/// A trait to conveniently store a vector of storable data.
///
/// It uses twox_128 hasher. Final keys in trie are `twox_128(concatenation(PREFIX,count))`
pub trait StorageVec {
type Item: Default + Sized + Codec;
const PREFIX: &'static [u8];
/// Get the current set of items.
fn items() -> Vec<Self::Item> {
(0..Self::count()).into_iter().map(Self::item).collect()
}
/// Set the current set of items.
fn set_items<I, T>(items: I)
where
I: IntoIterator<Item=T>,
T: Borrow<Self::Item>,
{
let mut count: u32 = 0;
for i in items.into_iter() {
put(&twox_128, &count.to_keyed_vec(Self::PREFIX), i.borrow());
count = count.checked_add(1).expect("exceeded runtime storage capacity");
}
Self::set_count(count);
}
/// Push an item.
fn push(item: &Self::Item) {
let len = Self::count();
put(&twox_128, &len.to_keyed_vec(Self::PREFIX), item);
Self::set_count(len + 1);
}
fn set_item(index: u32, item: &Self::Item) {
if index < Self::count() {
put(&twox_128, &index.to_keyed_vec(Self::PREFIX), item);
}
}
fn clear_item(index: u32) {
if index < Self::count() {
kill(&twox_128, &index.to_keyed_vec(Self::PREFIX));
}
}
fn item(index: u32) -> Self::Item {
get_or_default(&twox_128, &index.to_keyed_vec(Self::PREFIX))
}
fn set_count(count: u32) {
(count..Self::count()).for_each(Self::clear_item);
put(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count);
}
fn count() -> u32 {
get_or_default(&twox_128, &b"len".to_keyed_vec(Self::PREFIX))
}
}
#[cfg(test)]
mod tests {
use super::*;
use runtime_io::{twox_128, TestExternalities, with_externalities};
#[test]
fn integers_can_be_stored() {
let mut t = TestExternalities::default();
with_externalities(&mut t, || {
let x = 69u32;
put(&twox_128, b":test", &x);
let y: u32 = get(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
with_externalities(&mut t, || {
let x = 69426942i64;
put(&twox_128, b":test", &x);
let y: i64 = get(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
}
#[test]
fn bools_can_be_stored() {
let mut t = TestExternalities::default();
with_externalities(&mut t, || {
let x = true;
put(&twox_128, b":test", &x);
let y: bool = get(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
with_externalities(&mut t, || {
let x = false;
put(&twox_128, b":test", &x);
let y: bool = get(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
}
#[test]
fn vecs_can_be_retrieved() {
let mut t = TestExternalities::default();
with_externalities(&mut t, || {
runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world");
let x = b"Hello world".to_vec();
let y = get::<Vec<u8>, _, _>(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
}
#[test]
fn vecs_can_be_stored() {
let mut t = TestExternalities::default();
let x = b"Hello world".to_vec();
with_externalities(&mut t, || {
put(&twox_128, b":test", &x);
});
with_externalities(&mut t, || {
let y: Vec<u8> = get(&twox_128, b":test").unwrap();
assert_eq!(x, y);
});
}
}