mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 12:48:00 +00:00
Refactor srml-support/storage (#3702)
* refactor * fix * remove unused vec storages * address comment
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user