Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -17,15 +17,12 @@
//! Traits, types and structs to support a bounded BTreeMap.
use crate::{storage::StorageDecodeLength, traits::Get};
use codec::{Decode, Encode, MaxEncodedLen};
use sp_std::{
borrow::Borrow, collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData,
ops::Deref,
};
use crate::{
storage::StorageDecodeLength,
traits::Get,
};
use codec::{Encode, Decode, MaxEncodedLen};
/// A bounded map based on a B-Tree.
///
@@ -46,7 +43,7 @@ where
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
let inner = BTreeMap::<K, V>::decode(input)?;
if inner.len() > S::get() as usize {
return Err("BoundedBTreeMap exceeds its limit".into());
return Err("BoundedBTreeMap exceeds its limit".into())
}
Ok(Self(inner, PhantomData))
}
@@ -280,7 +277,9 @@ where
type Error = ();
fn try_from(value: BTreeMap<K, V>) -> Result<Self, Self::Error> {
(value.len() <= Self::bound()).then(move || BoundedBTreeMap(value, PhantomData)).ok_or(())
(value.len() <= Self::bound())
.then(move || BoundedBTreeMap(value, PhantomData))
.ok_or(())
}
}
@@ -303,9 +302,9 @@ impl<K, V, S> codec::EncodeLike<BTreeMap<K, V>> for BoundedBTreeMap<K, V, S> whe
#[cfg(test)]
pub mod test {
use super::*;
use crate::Twox128;
use sp_io::TestExternalities;
use sp_std::convert::TryInto;
use crate::Twox128;
crate::parameter_types! {
pub const Seven: u32 = 7;
@@ -17,15 +17,12 @@
//! Traits, types and structs to support a bounded `BTreeSet`.
use crate::{storage::StorageDecodeLength, traits::Get};
use codec::{Decode, Encode, MaxEncodedLen};
use sp_std::{
borrow::Borrow, collections::btree_set::BTreeSet, convert::TryFrom, fmt, marker::PhantomData,
ops::Deref,
};
use crate::{
storage::StorageDecodeLength,
traits::Get,
};
use codec::{Encode, Decode, MaxEncodedLen};
/// A bounded set based on a B-Tree.
///
@@ -45,7 +42,7 @@ where
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
let inner = BTreeSet::<T>::decode(input)?;
if inner.len() > S::get() as usize {
return Err("BoundedBTreeSet exceeds its limit".into());
return Err("BoundedBTreeSet exceeds its limit".into())
}
Ok(Self(inner, PhantomData))
}
@@ -266,7 +263,9 @@ where
type Error = ();
fn try_from(value: BTreeSet<T>) -> Result<Self, Self::Error> {
(value.len() <= Self::bound()).then(move || BoundedBTreeSet(value, PhantomData)).ok_or(())
(value.len() <= Self::bound())
.then(move || BoundedBTreeSet(value, PhantomData))
.ok_or(())
}
}
@@ -281,16 +280,14 @@ impl<T, S> codec::DecodeLength for BoundedBTreeSet<T, S> {
impl<T, S> StorageDecodeLength for BoundedBTreeSet<T, S> {}
impl<T, S> codec::EncodeLike<BTreeSet<T>> for BoundedBTreeSet<T, S> where
BTreeSet<T>: Encode
{}
impl<T, S> codec::EncodeLike<BTreeSet<T>> for BoundedBTreeSet<T, S> where BTreeSet<T>: Encode {}
#[cfg(test)]
pub mod test {
use super::*;
use crate::Twox128;
use sp_io::TestExternalities;
use sp_std::convert::TryInto;
use crate::Twox128;
crate::parameter_types! {
pub const Seven: u32 = 7;
@@ -18,17 +18,16 @@
//! Traits, types and structs to support putting a bounded vector into storage, as a raw value, map
//! or a double map.
use sp_std::prelude::*;
use sp_std::{convert::TryFrom, fmt, marker::PhantomData};
use codec::{Encode, Decode, EncodeLike, MaxEncodedLen};
use crate::{
storage::{StorageDecodeLength, StorageTryAppend},
traits::Get,
};
use codec::{Decode, Encode, EncodeLike, MaxEncodedLen};
use core::{
ops::{Deref, Index, IndexMut},
slice::SliceIndex,
};
use crate::{
traits::Get,
storage::{StorageDecodeLength, StorageTryAppend},
};
use sp_std::{convert::TryFrom, fmt, marker::PhantomData, prelude::*};
/// A bounded vector.
///
@@ -71,7 +70,7 @@ impl<T: Decode, S: Get<u32>> Decode for BoundedVec<T, S> {
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
let inner = Vec::<T>::decode(input)?;
if inner.len() > S::get() as usize {
return Err("BoundedVec exceeds its limit".into());
return Err("BoundedVec exceeds its limit".into())
}
Ok(Self(inner, PhantomData))
}
@@ -341,9 +340,9 @@ where
#[cfg(test)]
pub mod test {
use super::*;
use crate::Twox128;
use sp_io::TestExternalities;
use sp_std::convert::TryInto;
use crate::Twox128;
crate::parameter_types! {
pub const Seven: u32 = 7;
+33 -104
View File
@@ -21,23 +21,17 @@
// NOTE: could replace unhashed by having only one kind of storage (top trie being the child info
// of null length parent storage key).
use crate::sp_std::prelude::*;
use codec::{Codec, Encode, Decode};
pub use sp_core::storage::{ChildInfo, ChildType};
pub use crate::sp_io::KillStorageResult;
use crate::sp_std::prelude::*;
use codec::{Codec, Decode, Encode};
pub use sp_core::storage::{ChildInfo, ChildType};
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
pub fn get<T: Decode + Sized>(
child_info: &ChildInfo,
key: &[u8],
) -> Option<T> {
pub fn get<T: Decode + Sized>(child_info: &ChildInfo, key: &[u8]) -> Option<T> {
match child_info.child_type() {
ChildType::ParentKeyId => {
let storage_key = child_info.storage_key();
sp_io::default_child_storage::get(
storage_key,
key,
).and_then(|v| {
sp_io::default_child_storage::get(storage_key, key).and_then(|v| {
Decode::decode(&mut &v[..]).map(Some).unwrap_or_else(|_| {
// TODO #3700: error should be handleable.
crate::runtime_print!(
@@ -54,20 +48,13 @@ pub fn get<T: Decode + Sized>(
/// Return the value of the item in storage under `key`, or the type's default if there is no
/// explicit entry.
pub fn get_or_default<T: Decode + Sized + Default>(
child_info: &ChildInfo,
key: &[u8],
) -> T {
pub fn get_or_default<T: Decode + Sized + Default>(child_info: &ChildInfo, key: &[u8]) -> T {
get(child_info, key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry.
pub fn get_or<T: Decode + Sized>(
child_info: &ChildInfo,
key: &[u8],
default_value: T,
) -> T {
pub fn get_or<T: Decode + Sized>(child_info: &ChildInfo, key: &[u8], default_value: T) -> T {
get(child_info, key).unwrap_or(default_value)
}
@@ -82,27 +69,16 @@ pub fn get_or_else<T: Decode + Sized, F: FnOnce() -> T>(
}
/// Put `value` in storage under `key`.
pub fn put<T: Encode>(
child_info: &ChildInfo,
key: &[u8],
value: &T,
) {
pub fn put<T: Encode>(child_info: &ChildInfo, key: &[u8], value: &T) {
match child_info.child_type() {
ChildType::ParentKeyId => value.using_encoded(|slice|
sp_io::default_child_storage::set(
child_info.storage_key(),
key,
slice,
)
),
ChildType::ParentKeyId => value.using_encoded(|slice| {
sp_io::default_child_storage::set(child_info.storage_key(), key, slice)
}),
}
}
/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise.
pub fn take<T: Decode + Sized>(
child_info: &ChildInfo,
key: &[u8],
) -> Option<T> {
pub fn take<T: Decode + Sized>(child_info: &ChildInfo, key: &[u8]) -> Option<T> {
let r = get(child_info, key);
if r.is_some() {
kill(child_info, key);
@@ -112,20 +88,13 @@ pub fn take<T: Decode + Sized>(
/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage,
/// the default for its type.
pub fn take_or_default<T: Codec + Sized + Default>(
child_info: &ChildInfo,
key: &[u8],
) -> T {
pub fn take_or_default<T: Codec + Sized + Default>(child_info: &ChildInfo, key: &[u8]) -> T {
take(child_info, key).unwrap_or_else(Default::default)
}
/// Return the value of the item in storage under `key`, or `default_value` if there is no
/// explicit entry. Ensure there is no explicit entry on return.
pub fn take_or<T: Codec + Sized>(
child_info: &ChildInfo,
key: &[u8],
default_value: T,
) -> T {
pub fn take_or<T: Codec + Sized>(child_info: &ChildInfo, key: &[u8], default_value: T) -> T {
take(child_info, key).unwrap_or(default_value)
}
@@ -140,15 +109,11 @@ pub fn take_or_else<T: Codec + Sized, F: FnOnce() -> T>(
}
/// Check to see if `key` has an explicit entry in storage.
pub fn exists(
child_info: &ChildInfo,
key: &[u8],
) -> bool {
pub fn exists(child_info: &ChildInfo, key: &[u8]) -> bool {
match child_info.child_type() {
ChildType::ParentKeyId => sp_io::default_child_storage::read(
child_info.storage_key(),
key, &mut [0;0][..], 0,
).is_some(),
ChildType::ParentKeyId =>
sp_io::default_child_storage::read(child_info.storage_key(), key, &mut [0; 0][..], 0)
.is_some(),
}
}
@@ -171,86 +136,50 @@ pub fn exists(
/// not make much sense because it is not cumulative when called inside the same block.
/// Use this function to distribute the deletion of a single child trie across multiple
/// blocks.
pub fn kill_storage(
child_info: &ChildInfo,
limit: Option<u32>,
) -> KillStorageResult {
pub fn kill_storage(child_info: &ChildInfo, limit: Option<u32>) -> KillStorageResult {
match child_info.child_type() {
ChildType::ParentKeyId => sp_io::default_child_storage::storage_kill(
child_info.storage_key(),
limit
),
ChildType::ParentKeyId =>
sp_io::default_child_storage::storage_kill(child_info.storage_key(), limit),
}
}
/// Ensure `key` has no explicit entry in storage.
pub fn kill(
child_info: &ChildInfo,
key: &[u8],
) {
pub fn kill(child_info: &ChildInfo, key: &[u8]) {
match child_info.child_type() {
ChildType::ParentKeyId => {
sp_io::default_child_storage::clear(
child_info.storage_key(),
key,
);
sp_io::default_child_storage::clear(child_info.storage_key(), key);
},
}
}
/// Get a Vec of bytes from storage.
pub fn get_raw(
child_info: &ChildInfo,
key: &[u8],
) -> Option<Vec<u8>> {
pub fn get_raw(child_info: &ChildInfo, key: &[u8]) -> Option<Vec<u8>> {
match child_info.child_type() {
ChildType::ParentKeyId => sp_io::default_child_storage::get(
child_info.storage_key(),
key,
),
ChildType::ParentKeyId => sp_io::default_child_storage::get(child_info.storage_key(), key),
}
}
/// Put a raw byte slice into storage.
pub fn put_raw(
child_info: &ChildInfo,
key: &[u8],
value: &[u8],
) {
pub fn put_raw(child_info: &ChildInfo, key: &[u8], value: &[u8]) {
match child_info.child_type() {
ChildType::ParentKeyId => sp_io::default_child_storage::set(
child_info.storage_key(),
key,
value,
),
ChildType::ParentKeyId =>
sp_io::default_child_storage::set(child_info.storage_key(), key, value),
}
}
/// Calculate current child root value.
pub fn root(
child_info: &ChildInfo,
) -> Vec<u8> {
pub fn root(child_info: &ChildInfo) -> Vec<u8> {
match child_info.child_type() {
ChildType::ParentKeyId => sp_io::default_child_storage::root(
child_info.storage_key(),
),
ChildType::ParentKeyId => sp_io::default_child_storage::root(child_info.storage_key()),
}
}
/// Return the length in bytes of the value without reading it. `None` if it does not exist.
pub fn len(
child_info: &ChildInfo,
key: &[u8],
) -> Option<u32> {
pub fn len(child_info: &ChildInfo, key: &[u8]) -> Option<u32> {
match child_info.child_type() {
ChildType::ParentKeyId => {
let mut buffer = [0; 0];
sp_io::default_child_storage::read(
child_info.storage_key(),
key,
&mut buffer,
0,
)
}
sp_io::default_child_storage::read(child_info.storage_key(), key, &mut buffer, 0)
},
}
}
@@ -15,11 +15,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use sp_std::prelude::*;
use sp_std::borrow::Borrow;
use codec::{FullCodec, FullEncode, Decode, Encode, EncodeLike};
use crate::{storage::{self, unhashed, KeyPrefixIterator, StorageAppend, PrefixIterator}, Never};
use crate::hash::{StorageHasher, Twox128, ReversibleStorageHasher};
use crate::{
hash::{ReversibleStorageHasher, StorageHasher, Twox128},
storage::{self, unhashed, KeyPrefixIterator, PrefixIterator, StorageAppend},
Never,
};
use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode};
use sp_std::{borrow::Borrow, prelude::*};
/// Generator for `StorageDoubleMap` used by `decl_storage`.
///
@@ -63,9 +65,8 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
let module_prefix_hashed = Twox128::hash(Self::module_prefix());
let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
let mut result = Vec::with_capacity(
module_prefix_hashed.len() + storage_prefix_hashed.len()
);
let mut result =
Vec::with_capacity(module_prefix_hashed.len() + storage_prefix_hashed.len());
result.extend_from_slice(&module_prefix_hashed[..]);
result.extend_from_slice(&storage_prefix_hashed[..]);
@@ -80,7 +81,8 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
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) -> Vec<u8> where
fn storage_double_map_final_key1<KArg1>(k1: KArg1) -> Vec<u8>
where
KArg1: EncodeLike<K1>,
{
let module_prefix_hashed = Twox128::hash(Self::module_prefix());
@@ -88,7 +90,7 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
let key_hashed = k1.borrow().using_encoded(Self::Hasher1::hash);
let mut final_key = Vec::with_capacity(
module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len()
module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len(),
);
final_key.extend_from_slice(&module_prefix_hashed[..]);
@@ -99,7 +101,8 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
}
/// Generate the full key used in top storage.
fn storage_double_map_final_key<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Vec<u8> where
fn storage_double_map_final_key<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Vec<u8>
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
{
@@ -109,10 +112,10 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
let key2_hashed = k2.borrow().using_encoded(Self::Hasher2::hash);
let mut final_key = Vec::with_capacity(
module_prefix_hashed.len()
+ storage_prefix_hashed.len()
+ key1_hashed.as_ref().len()
+ key2_hashed.as_ref().len()
module_prefix_hashed.len() +
storage_prefix_hashed.len() +
key1_hashed.as_ref().len() +
key2_hashed.as_ref().len(),
);
final_key.extend_from_slice(&module_prefix_hashed[..]);
@@ -124,7 +127,8 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
}
}
impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G
where
K1: FullEncode,
K2: FullEncode,
V: FullCodec,
@@ -132,21 +136,24 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
{
type Query = G::Query;
fn hashed_key_for<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Vec<u8> where
fn hashed_key_for<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Vec<u8>
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
{
Self::storage_double_map_final_key(k1, k2)
}
fn contains_key<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> bool where
fn contains_key<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> bool
where
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 where
fn get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
{
@@ -156,11 +163,13 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
fn try_get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Result<V, ()>
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2> {
KArg2: EncodeLike<K2>,
{
unhashed::get(&Self::storage_double_map_final_key(k1, k2)).ok_or(())
}
fn take<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query where
fn take<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Self::Query
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
{
@@ -170,16 +179,12 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
G::from_optional_value_to_query(value)
}
fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(
x_k1: XKArg1,
x_k2: XKArg2,
y_k1: YKArg1,
y_k2: YKArg2
) where
fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2)
where
XKArg1: EncodeLike<K1>,
XKArg2: EncodeLike<K2>,
YKArg1: EncodeLike<K1>,
YKArg2: EncodeLike<K2>
YKArg2: EncodeLike<K2>,
{
let final_x_key = Self::storage_double_map_final_key(x_k1, x_k2);
let final_y_key = Self::storage_double_map_final_key(y_k1, y_k2);
@@ -197,7 +202,8 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
}
}
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg) where
fn insert<KArg1, KArg2, VArg>(k1: KArg1, k2: KArg2, val: VArg)
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
VArg: EncodeLike<V>,
@@ -205,7 +211,8 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
unhashed::put(&Self::storage_double_map_final_key(k1, k2), &val.borrow())
}
fn remove<KArg1, KArg2>(k1: KArg1, k2: KArg2) where
fn remove<KArg1, KArg2>(k1: KArg1, k2: KArg2)
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
{
@@ -213,12 +220,15 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
}
fn remove_prefix<KArg1>(k1: KArg1, limit: Option<u32>) -> sp_io::KillStorageResult
where KArg1: EncodeLike<K1> {
where
KArg1: EncodeLike<K1>,
{
unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref(), limit)
}
fn iter_prefix_values<KArg1>(k1: KArg1) -> storage::PrefixIterator<V> where
KArg1: ?Sized + EncodeLike<K1>
fn iter_prefix_values<KArg1>(k1: KArg1) -> storage::PrefixIterator<V>
where
KArg1: ?Sized + EncodeLike<K1>,
{
let prefix = Self::storage_double_map_final_key1(k1);
storage::PrefixIterator {
@@ -229,12 +239,14 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
}
}
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R where
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
F: FnOnce(&mut Self::Query) -> R,
{
Self::try_mutate(k1, k2, |v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
Self::try_mutate(k1, k2, |v| Ok::<R, Never>(f(v)))
.expect("`Never` can not be constructed; qed")
}
fn mutate_exists<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
@@ -243,10 +255,12 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
KArg2: EncodeLike<K2>,
F: FnOnce(&mut Option<V>) -> R,
{
Self::try_mutate_exists(k1, k2, |v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
Self::try_mutate_exists(k1, k2, |v| Ok::<R, Never>(f(v)))
.expect("`Never` can not be constructed; qed")
}
fn try_mutate<KArg1, KArg2, R, E, F>(k1: KArg1, k2: KArg2, f: F) -> Result<R, E> where
fn try_mutate<KArg1, KArg2, R, E, F>(k1: KArg1, k2: KArg2, f: F) -> Result<R, E>
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
F: FnOnce(&mut Self::Query) -> Result<R, E>,
@@ -283,11 +297,8 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
ret
}
fn append<Item, EncodeLikeItem, KArg1, KArg2>(
k1: KArg1,
k2: KArg2,
item: EncodeLikeItem,
) where
fn append<Item, EncodeLikeItem, KArg1, KArg2>(k1: KArg1, k2: KArg2, item: EncodeLikeItem)
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
Item: Encode,
@@ -303,7 +314,10 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
OldHasher2: StorageHasher,
KeyArg1: EncodeLike<K1>,
KeyArg2: EncodeLike<K2>,
>(key1: KeyArg1, key2: KeyArg2) -> Option<V> {
>(
key1: KeyArg1,
key2: KeyArg2,
) -> Option<V> {
let old_key = {
let module_prefix_hashed = Twox128::hash(Self::module_prefix());
let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
@@ -311,10 +325,10 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
let key2_hashed = key2.borrow().using_encoded(OldHasher2::hash);
let mut final_key = Vec::with_capacity(
module_prefix_hashed.len()
+ storage_prefix_hashed.len()
+ key1_hashed.as_ref().len()
+ key2_hashed.as_ref().len()
module_prefix_hashed.len() +
storage_prefix_hashed.len() +
key1_hashed.as_ref().len() +
key2_hashed.as_ref().len(),
);
final_key.extend_from_slice(&module_prefix_hashed[..]);
@@ -331,14 +345,11 @@ impl<K1, K2, V, G> storage::StorageDoubleMap<K1, K2, V> for G where
}
}
impl<
K1: FullCodec,
K2: FullCodec,
V: FullCodec,
G: StorageDoubleMap<K1, K2, V>,
> storage::IterableStorageDoubleMap<K1, K2, V> for G where
impl<K1: FullCodec, K2: FullCodec, V: FullCodec, G: StorageDoubleMap<K1, K2, V>>
storage::IterableStorageDoubleMap<K1, K2, V> for G
where
G::Hasher1: ReversibleStorageHasher,
G::Hasher2: ReversibleStorageHasher
G::Hasher2: ReversibleStorageHasher,
{
type PartialKeyIterator = KeyPrefixIterator<K2>;
type PrefixIterator = PrefixIterator<(K2, V)>;
@@ -367,7 +378,7 @@ impl<
closure: |raw_key_without_prefix| {
let mut key_material = G::Hasher2::reverse(raw_key_without_prefix);
K2::decode(&mut key_material)
}
},
}
}
@@ -405,7 +416,7 @@ impl<
let mut k2_material = G::Hasher2::reverse(k1_k2_material);
let k2 = K2::decode(&mut k2_material)?;
Ok((k1, k2))
}
},
}
}
@@ -418,8 +429,8 @@ impl<
fn translate<O: Decode, F: FnMut(K1, K2, O) -> Option<V>>(mut f: F) {
let prefix = G::prefix_hash();
let mut previous_key = prefix.clone();
while let Some(next) = sp_io::storage::next_key(&previous_key)
.filter(|n| n.starts_with(&prefix))
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
previous_key = next;
let value = match unhashed::get::<O>(&previous_key) {
@@ -458,11 +469,11 @@ impl<
/// Test iterators for StorageDoubleMap
#[cfg(test)]
mod test_iterators {
use codec::{Encode, Decode};
use crate::{
hash::StorageHasher,
storage::{generator::StorageDoubleMap, IterableStorageDoubleMap, unhashed},
storage::{generator::StorageDoubleMap, unhashed, IterableStorageDoubleMap},
};
use codec::{Decode, Encode};
pub trait Config: 'static {
type Origin;
@@ -521,10 +532,7 @@ mod test_iterators {
vec![(3, 3), (0, 0), (2, 2), (1, 1)],
);
assert_eq!(
DoubleMap::iter_values().collect::<Vec<_>>(),
vec![3, 0, 2, 1],
);
assert_eq!(DoubleMap::iter_values().collect::<Vec<_>>(), vec![3, 0, 2, 1],);
assert_eq!(
DoubleMap::drain().collect::<Vec<_>>(),
@@ -551,15 +559,9 @@ mod test_iterators {
vec![(1, 1), (2, 2), (0, 0), (3, 3)],
);
assert_eq!(
DoubleMap::iter_key_prefix(k1).collect::<Vec<_>>(),
vec![1, 2, 0, 3],
);
assert_eq!(DoubleMap::iter_key_prefix(k1).collect::<Vec<_>>(), vec![1, 2, 0, 3],);
assert_eq!(
DoubleMap::iter_prefix_values(k1).collect::<Vec<_>>(),
vec![1, 2, 0, 3],
);
assert_eq!(DoubleMap::iter_prefix_values(k1).collect::<Vec<_>>(), vec![1, 2, 0, 3],);
assert_eq!(
DoubleMap::drain_prefix(k1).collect::<Vec<_>>(),
@@ -580,15 +582,12 @@ mod test_iterators {
}
// Wrong key1
unhashed::put(
&[prefix.clone(), vec![1, 2, 3]].concat(),
&3u64.encode()
);
unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode());
// Wrong key2
unhashed::put(
&[prefix.clone(), crate::Blake2_128Concat::hash(&1u16.encode())].concat(),
&3u64.encode()
&3u64.encode(),
);
// Wrong value
@@ -597,11 +596,12 @@ mod test_iterators {
prefix.clone(),
crate::Blake2_128Concat::hash(&1u16.encode()),
crate::Twox64Concat::hash(&2u32.encode()),
].concat(),
]
.concat(),
&vec![1],
);
DoubleMap::translate(|_k1, _k2, v: u64| Some(v*2));
DoubleMap::translate(|_k1, _k2, v: u64| Some(v * 2));
assert_eq!(
DoubleMap::iter().collect::<Vec<_>>(),
vec![(3, 3, 6), (0, 0, 0), (2, 2, 4), (1, 1, 2)],
@@ -15,14 +15,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::{
hash::{ReversibleStorageHasher, StorageHasher, Twox128},
storage::{self, unhashed, KeyPrefixIterator, PrefixIterator, StorageAppend},
Never,
};
use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode};
use sp_std::borrow::Borrow;
#[cfg(not(feature = "std"))]
use sp_std::prelude::*;
use sp_std::borrow::Borrow;
use codec::{FullCodec, FullEncode, Decode, Encode, EncodeLike};
use crate::{
storage::{self, unhashed, KeyPrefixIterator, StorageAppend, PrefixIterator},
Never, hash::{StorageHasher, Twox128, ReversibleStorageHasher},
};
/// Generator for `StorageMap` used by `decl_storage`.
///
@@ -54,9 +55,8 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
let module_prefix_hashed = Twox128::hash(Self::module_prefix());
let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
let mut result = Vec::with_capacity(
module_prefix_hashed.len() + storage_prefix_hashed.len()
);
let mut result =
Vec::with_capacity(module_prefix_hashed.len() + storage_prefix_hashed.len());
result.extend_from_slice(&module_prefix_hashed[..]);
result.extend_from_slice(&storage_prefix_hashed[..]);
@@ -71,7 +71,8 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
fn from_query_to_optional_value(v: Self::Query) -> Option<V>;
/// Generate the full key used in top storage.
fn storage_map_final_key<KeyArg>(key: KeyArg) -> Vec<u8> where
fn storage_map_final_key<KeyArg>(key: KeyArg) -> Vec<u8>
where
KeyArg: EncodeLike<K>,
{
let module_prefix_hashed = Twox128::hash(Self::module_prefix());
@@ -79,7 +80,7 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
let key_hashed = key.borrow().using_encoded(Self::Hasher::hash);
let mut final_key = Vec::with_capacity(
module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len()
module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len(),
);
final_key.extend_from_slice(&module_prefix_hashed[..]);
@@ -98,11 +99,9 @@ pub struct StorageMapIterator<K, V, Hasher> {
_phantom: ::sp_std::marker::PhantomData<(K, V, Hasher)>,
}
impl<
K: Decode + Sized,
V: Decode + Sized,
Hasher: ReversibleStorageHasher
> Iterator for StorageMapIterator<K, V, Hasher> {
impl<K: Decode + Sized, V: Decode + Sized, Hasher: ReversibleStorageHasher> Iterator
for StorageMapIterator<K, V, Hasher>
{
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
@@ -117,27 +116,25 @@ impl<
if self.drain {
unhashed::kill(&self.previous_key)
}
let mut key_material = Hasher::reverse(&self.previous_key[self.prefix.len()..]);
let mut key_material =
Hasher::reverse(&self.previous_key[self.prefix.len()..]);
match K::decode(&mut key_material) {
Ok(key) => Some((key, value)),
Err(_) => continue,
}
}
},
None => continue,
}
}
},
None => None,
}
}
}
}
impl<
K: FullCodec,
V: FullCodec,
G: StorageMap<K, V>,
> storage::IterableStorageMap<K, V> for G where
G::Hasher: ReversibleStorageHasher
impl<K: FullCodec, V: FullCodec, G: StorageMap<K, V>> storage::IterableStorageMap<K, V> for G
where
G::Hasher: ReversibleStorageHasher,
{
type Iterator = PrefixIterator<(K, V)>;
type KeyIterator = KeyPrefixIterator<K>;
@@ -166,7 +163,7 @@ impl<
closure: |raw_key_without_prefix| {
let mut key_material = G::Hasher::reverse(raw_key_without_prefix);
K::decode(&mut key_material)
}
},
}
}
@@ -180,8 +177,8 @@ impl<
fn translate<O: Decode, F: FnMut(K, O) -> Option<V>>(mut f: F) {
let prefix = G::prefix_hash();
let mut previous_key = prefix.clone();
while let Some(next) = sp_io::storage::next_key(&previous_key)
.filter(|n| n.starts_with(&prefix))
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
previous_key = next;
let value = match unhashed::get::<O>(&previous_key) {
@@ -254,16 +251,21 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
}
fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
Self::try_mutate(key, |v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
Self::try_mutate(key, |v| Ok::<R, Never>(f(v)))
.expect("`Never` can not be constructed; qed")
}
fn mutate_exists<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Option<V>) -> R>(key: KeyArg, f: F) -> R {
Self::try_mutate_exists(key, |v| Ok::<R, Never>(f(v))).expect("`Never` can not be constructed; qed")
fn mutate_exists<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Option<V>) -> R>(
key: KeyArg,
f: F,
) -> R {
Self::try_mutate_exists(key, |v| Ok::<R, Never>(f(v)))
.expect("`Never` can not be constructed; qed")
}
fn try_mutate<KeyArg: EncodeLike<K>, R, E, F: FnOnce(&mut Self::Query) -> Result<R, E>>(
key: KeyArg,
f: F
f: F,
) -> Result<R, E> {
let final_key = Self::storage_map_final_key(key);
let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref()));
@@ -280,7 +282,7 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
fn try_mutate_exists<KeyArg: EncodeLike<K>, R, E, F: FnOnce(&mut Option<V>) -> Result<R, E>>(
key: KeyArg,
f: F
f: F,
) -> Result<R, E> {
let final_key = Self::storage_map_final_key(key);
let mut val = unhashed::get(final_key.as_ref());
@@ -319,7 +321,9 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
let key_hashed = key.borrow().using_encoded(OldHasher::hash);
let mut final_key = Vec::with_capacity(
module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len()
module_prefix_hashed.len() +
storage_prefix_hashed.len() +
key_hashed.as_ref().len(),
);
final_key.extend_from_slice(&module_prefix_hashed[..]);
@@ -338,11 +342,11 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
/// Test iterators for StorageMap
#[cfg(test)]
mod test_iterators {
use codec::{Encode, Decode};
use crate::{
hash::StorageHasher,
storage::{generator::StorageMap, IterableStorageMap, unhashed},
storage::{generator::StorageMap, unhashed, IterableStorageMap},
};
use codec::{Decode, Encode};
pub trait Config: 'static {
type Origin;
@@ -421,7 +425,7 @@ mod test_iterators {
&vec![1],
);
Map::translate(|_k1, v: u64| Some(v*2));
Map::translate(|_k1, v: u64| Some(v * 2));
assert_eq!(Map::iter().collect::<Vec<_>>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]);
})
}
@@ -24,23 +24,25 @@
//!
//! This is internal api and is subject to change.
mod double_map;
mod map;
mod nmap;
mod double_map;
mod value;
pub use double_map::StorageDoubleMap;
pub use map::StorageMap;
pub use nmap::StorageNMap;
pub use double_map::StorageDoubleMap;
pub use value::StorageValue;
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use sp_io::TestExternalities;
use crate::{
assert_noop, assert_ok,
storage::{generator::StorageValue, unhashed, IterableStorageMap},
};
use codec::Encode;
use crate::storage::{unhashed, generator::StorageValue, IterableStorageMap};
use crate::{assert_noop, assert_ok};
use sp_io::TestExternalities;
struct Runtime;
@@ -80,7 +82,7 @@ mod tests {
// translate
let translate_fn = |old: Option<u32>| -> Option<(u64, u64)> {
old.map(|o| (o.into(), (o*2).into()))
old.map(|o| (o.into(), (o * 2).into()))
};
let res = Value::translate(translate_fn);
debug_assert!(res.is_ok());
@@ -105,11 +107,16 @@ mod tests {
);
// do translation.
NumberMap::translate(|k: u32, v: u64| if k % 2 == 0 { Some((k as u64) << 32 | v) } else { None });
NumberMap::translate(
|k: u32, v: u64| if k % 2 == 0 { Some((k as u64) << 32 | v) } else { None },
);
assert_eq!(
NumberMap::iter().collect::<Vec<_>>(),
(0..50u32).map(|x| x * 2).map(|x| (x, (x as u64) << 32 | x as u64)).collect::<Vec<_>>(),
(0..50u32)
.map(|x| x * 2)
.map(|x| (x, (x as u64) << 32 | x as u64))
.collect::<Vec<_>>(),
);
})
}
@@ -123,20 +130,29 @@ mod tests {
assert_eq!(DoubleMap::get(0, 0), 0);
// `assert_noop` ensures that the state does not change
assert_noop!(Value::try_mutate(|value| -> Result<(), &'static str> {
*value = (2, 2);
Err("don't change value")
}), "don't change value");
assert_noop!(
Value::try_mutate(|value| -> Result<(), &'static str> {
*value = (2, 2);
Err("don't change value")
}),
"don't change value"
);
assert_noop!(NumberMap::try_mutate(0, |value| -> Result<(), &'static str> {
*value = 4;
Err("don't change value")
}), "don't change value");
assert_noop!(
NumberMap::try_mutate(0, |value| -> Result<(), &'static str> {
*value = 4;
Err("don't change value")
}),
"don't change value"
);
assert_noop!(DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> {
*value = 6;
Err("don't change value")
}), "don't change value");
assert_noop!(
DoubleMap::try_mutate(0, 0, |value| -> Result<(), &'static str> {
*value = 6;
Err("don't change value")
}),
"don't change value"
);
// Showing this explicitly for clarity
assert_eq!(Value::get(), (0, 0));
@@ -228,7 +228,7 @@ where
fn try_mutate<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
where
KArg: EncodeLikeTuple<K::KArg> + TupleToEncodedIter,
F: FnOnce(&mut Self::Query) -> Result<R, E>
F: FnOnce(&mut Self::Query) -> Result<R, E>,
{
let final_key = Self::storage_n_map_final_key::<K, _>(key);
let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref()));
@@ -373,7 +373,7 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
closure: |raw_key_without_prefix| {
let (final_key, _) = K::decode_final_key(raw_key_without_prefix)?;
Ok(final_key)
}
},
}
}
@@ -394,16 +394,16 @@ impl<K: ReversibleKeyGenerator, V: FullCodec, G: StorageNMap<K, V>>
Some(value) => value,
None => {
log::error!("Invalid translate: fail to decode old value");
continue;
}
continue
},
};
let final_key = match K::decode_final_key(&previous_key[prefix.len()..]) {
Ok((final_key, _)) => final_key,
Err(_) => {
log::error!("Invalid translate: fail to decode key");
continue;
}
continue
},
};
match f(final_key, value) {
@@ -452,10 +452,7 @@ mod test_iterators {
fn key_after_prefix(mut prefix: Vec<u8>) -> Vec<u8> {
let last = prefix.iter_mut().last().unwrap();
assert!(
*last != 255,
"mock function not implemented for this prefix"
);
assert!(*last != 255, "mock function not implemented for this prefix");
*last += 1;
prefix
}
@@ -498,10 +495,7 @@ mod test_iterators {
vec![((3, 3), 3), ((0, 0), 0), ((2, 2), 2), ((1, 1), 1)],
);
assert_eq!(
NMap::iter_keys().collect::<Vec<_>>(),
vec![(3, 3), (0, 0), (2, 2), (1, 1)],
);
assert_eq!(NMap::iter_keys().collect::<Vec<_>>(), vec![(3, 3), (0, 0), (2, 2), (1, 1)],);
assert_eq!(NMap::iter_values().collect::<Vec<_>>(), vec![3, 0, 2, 1],);
@@ -511,10 +505,7 @@ mod test_iterators {
);
assert_eq!(NMap::iter().collect::<Vec<_>>(), vec![]);
assert_eq!(
unhashed::get(&key_before_prefix(prefix.clone())),
Some(1u64)
);
assert_eq!(unhashed::get(&key_before_prefix(prefix.clone())), Some(1u64));
assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
// Prefix iterator
@@ -533,15 +524,9 @@ mod test_iterators {
vec![(1, 1), (2, 2), (0, 0), (3, 3)],
);
assert_eq!(
NMap::iter_key_prefix((k1,)).collect::<Vec<_>>(),
vec![1, 2, 0, 3],
);
assert_eq!(NMap::iter_key_prefix((k1,)).collect::<Vec<_>>(), vec![1, 2, 0, 3],);
assert_eq!(
NMap::iter_prefix_values((k1,)).collect::<Vec<_>>(),
vec![1, 2, 0, 3],
);
assert_eq!(NMap::iter_prefix_values((k1,)).collect::<Vec<_>>(), vec![1, 2, 0, 3],);
assert_eq!(
NMap::drain_prefix((k1,)).collect::<Vec<_>>(),
@@ -549,10 +534,7 @@ mod test_iterators {
);
assert_eq!(NMap::iter_prefix((k1,)).collect::<Vec<_>>(), vec![]);
assert_eq!(
unhashed::get(&key_before_prefix(prefix.clone())),
Some(1u64)
);
assert_eq!(unhashed::get(&key_before_prefix(prefix.clone())), Some(1u64));
assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
// Translate
@@ -569,11 +551,7 @@ mod test_iterators {
// Wrong key2
unhashed::put(
&[
prefix.clone(),
crate::Blake2_128Concat::hash(&1u16.encode()),
]
.concat(),
&[prefix.clone(), crate::Blake2_128Concat::hash(&1u16.encode())].concat(),
&3u64.encode(),
);
@@ -15,12 +15,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{FullCodec, Encode, EncodeLike, Decode};
use crate::{
Never,
hash::{StorageHasher, Twox128},
storage::{self, unhashed, StorageAppend},
hash::{Twox128, StorageHasher},
Never,
};
use codec::{Decode, Encode, EncodeLike, FullCodec};
/// Generator for `StorageValue` used by `decl_storage`.
///
@@ -78,7 +78,8 @@ impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
// attempt to get the length directly.
let maybe_old = unhashed::get_raw(&key)
.map(|old_data| O::decode(&mut &old_data[..]).map_err(|_| ())).transpose()?;
.map(|old_data| O::decode(&mut &old_data[..]).map_err(|_| ()))
.transpose()?;
let maybe_new = f(maybe_old);
if let Some(new) = maybe_new.as_ref() {
new.using_encoded(|d| unhashed::put_raw(&key, d));
@@ -18,8 +18,8 @@
//! Operation on runtime storage using hashed keys.
use super::unhashed;
use codec::{Decode, Encode};
use sp_std::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>
@@ -17,10 +17,9 @@
//! Some utilities for helping access storage with arbitrary key types.
use crate::{hash::ReversibleStorageHasher, storage::unhashed, StorageHasher, Twox128};
use codec::{Decode, Encode};
use sp_std::prelude::*;
use codec::{Encode, Decode};
use crate::{StorageHasher, Twox128, storage::unhashed};
use crate::hash::ReversibleStorageHasher;
use super::PrefixIterator;
@@ -34,14 +33,18 @@ pub struct StorageIterator<T> {
impl<T> StorageIterator<T> {
/// Construct iterator to iterate over map items in `module` for the map called `item`.
#[deprecated(note="Please use the storage_iter or storage_iter_with_suffix functions instead")]
#[deprecated(
note = "Please use the storage_iter or storage_iter_with_suffix functions instead"
)]
pub fn new(module: &[u8], item: &[u8]) -> Self {
#[allow(deprecated)]
Self::with_suffix(module, item, &[][..])
}
/// Construct iterator to iterate over map items in `module` for the map called `item`.
#[deprecated(note="Please use the storage_iter or storage_iter_with_suffix functions instead")]
#[deprecated(
note = "Please use the storage_iter or storage_iter_with_suffix functions instead"
)]
pub fn with_suffix(module: &[u8], item: &[u8], suffix: &[u8]) -> Self {
let mut prefix = Vec::new();
prefix.extend_from_slice(&Twox128::hash(module));
@@ -75,10 +78,10 @@ impl<T: Decode + Sized> Iterator for StorageIterator<T> {
frame_support::storage::unhashed::kill(&next);
}
Some((self.previous_key[self.prefix.len()..].to_vec(), value))
}
},
None => continue,
}
}
},
None => None,
}
}
@@ -95,14 +98,18 @@ pub struct StorageKeyIterator<K, T, H: ReversibleStorageHasher> {
impl<K, T, H: ReversibleStorageHasher> StorageKeyIterator<K, T, H> {
/// Construct iterator to iterate over map items in `module` for the map called `item`.
#[deprecated(note="Please use the storage_key_iter or storage_key_iter_with_suffix functions instead")]
#[deprecated(
note = "Please use the storage_key_iter or storage_key_iter_with_suffix functions instead"
)]
pub fn new(module: &[u8], item: &[u8]) -> Self {
#[allow(deprecated)]
Self::with_suffix(module, item, &[][..])
}
/// Construct iterator to iterate over map items in `module` for the map called `item`.
#[deprecated(note="Please use the storage_key_iter or storage_key_iter_with_suffix functions instead")]
#[deprecated(
note = "Please use the storage_key_iter or storage_key_iter_with_suffix functions instead"
)]
pub fn with_suffix(module: &[u8], item: &[u8], suffix: &[u8]) -> Self {
let mut prefix = Vec::new();
prefix.extend_from_slice(&Twox128::hash(module));
@@ -141,13 +148,13 @@ impl<K: Decode + Sized, T: Decode + Sized, H: ReversibleStorageHasher> Iterator
frame_support::storage::unhashed::kill(&next);
}
Some((key, value))
}
},
None => continue,
}
}
},
Err(_) => continue,
}
}
},
None => None,
}
}
@@ -187,7 +194,11 @@ pub fn storage_key_iter<K: Decode + Sized, T: Decode + Sized, H: ReversibleStora
}
/// Construct iterator to iterate over map items in `module` for the map called `item`.
pub fn storage_key_iter_with_suffix<K: Decode + Sized, T: Decode + Sized, H: ReversibleStorageHasher>(
pub fn storage_key_iter_with_suffix<
K: Decode + Sized,
T: Decode + Sized,
H: ReversibleStorageHasher,
>(
module: &[u8],
item: &[u8],
suffix: &[u8],
@@ -279,7 +290,7 @@ pub fn take_storage_item<K: Encode + Sized, T: Decode + Sized, H: StorageHasher>
pub fn move_storage_from_pallet(
storage_name: &[u8],
old_pallet_name: &[u8],
new_pallet_name: &[u8]
new_pallet_name: &[u8],
) {
let mut new_prefix = Vec::new();
new_prefix.extend_from_slice(&Twox128::hash(new_pallet_name));
@@ -347,18 +358,14 @@ pub fn move_prefix(from_prefix: &[u8], to_prefix: &[u8]) {
#[cfg(test)]
mod tests {
use super::{
move_pallet, move_prefix, move_storage_from_pallet, storage_iter, storage_key_iter,
};
use crate::{
pallet_prelude::{StorageValue, StorageMap, Twox64Concat, Twox128},
hash::StorageHasher,
pallet_prelude::{StorageMap, StorageValue, Twox128, Twox64Concat},
};
use sp_io::TestExternalities;
use super::{
move_prefix,
move_pallet,
move_storage_from_pallet,
storage_iter,
storage_key_iter,
};
struct OldPalletStorageValuePrefix;
impl frame_support::traits::StorageInstance for OldPalletStorageValuePrefix {
@@ -459,21 +466,22 @@ mod tests {
OldStorageMap::insert(3, 4);
assert_eq!(
storage_key_iter::<i32, i32, Twox64Concat>(b"my_old_pallet", b"foo_map").collect::<Vec<_>>(),
storage_key_iter::<i32, i32, Twox64Concat>(b"my_old_pallet", b"foo_map")
.collect::<Vec<_>>(),
vec![(1, 2), (3, 4)],
);
assert_eq!(
storage_iter(b"my_old_pallet", b"foo_map").drain().map(|t| t.1).collect::<Vec<i32>>(),
storage_iter(b"my_old_pallet", b"foo_map")
.drain()
.map(|t| t.1)
.collect::<Vec<i32>>(),
vec![2, 4],
);
assert_eq!(OldStorageMap::iter().collect::<Vec<_>>(), vec![]);
// Empty because storage iterator skips over the entry under the first key
assert_eq!(
storage_iter::<i32>(b"my_old_pallet", b"foo_value").drain().next(),
None
);
assert_eq!(storage_iter::<i32>(b"my_old_pallet", b"foo_value").drain().next(), None);
assert_eq!(OldStorageValue::get(), Some(3));
});
}
+84 -84
View File
@@ -17,31 +17,31 @@
//! Stuff to do with the runtime's storage.
use sp_core::storage::ChildInfo;
use sp_std::prelude::*;
use codec::{FullCodec, FullEncode, Encode, EncodeLike, Decode};
use crate::{
hash::{Twox128, StorageHasher, ReversibleStorageHasher},
hash::{ReversibleStorageHasher, StorageHasher, Twox128},
storage::types::{
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, KeyGenerator,
ReversibleKeyGenerator, TupleToEncodedIter,
},
};
use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode};
use sp_core::storage::ChildInfo;
use sp_runtime::generic::{Digest, DigestItem};
pub use sp_runtime::TransactionOutcome;
use sp_std::prelude::*;
pub use types::Key;
pub mod unhashed;
pub mod hashed;
pub mod bounded_btree_map;
pub mod bounded_btree_set;
pub mod bounded_vec;
pub mod weak_bounded_vec;
pub mod child;
#[doc(hidden)]
pub mod generator;
pub mod hashed;
pub mod migration;
pub mod types;
pub mod unhashed;
pub mod weak_bounded_vec;
#[cfg(all(feature = "std", any(test, debug_assertions)))]
mod debug_helper {
@@ -101,9 +101,7 @@ pub fn require_transaction() {
///
/// Transactions can be nested to any depth. Commits happen to the parent transaction.
pub fn with_transaction<R>(f: impl FnOnce() -> TransactionOutcome<R>) -> R {
use sp_io::storage::{
start_transaction, commit_transaction, rollback_transaction,
};
use sp_io::storage::{commit_transaction, rollback_transaction, start_transaction};
use TransactionOutcome::*;
start_transaction();
@@ -112,8 +110,14 @@ pub fn with_transaction<R>(f: impl FnOnce() -> TransactionOutcome<R>) -> R {
let _guard = debug_helper::inc_transaction_level();
match f() {
Commit(res) => { commit_transaction(); res },
Rollback(res) => { rollback_transaction(); res },
Commit(res) => {
commit_transaction();
res
},
Rollback(res) => {
rollback_transaction();
res
},
}
}
@@ -205,7 +209,10 @@ pub trait StorageValue<T: FullCodec> {
///
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
fn decode_len() -> Option<usize> where T: StorageDecodeLength {
fn decode_len() -> Option<usize>
where
T: StorageDecodeLength,
{
T::decode_len(&Self::hashed_key())
}
}
@@ -252,7 +259,10 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
/// Mutate the value under a key.
///
/// Deletes the item if mutated to a `None`.
fn mutate_exists<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Option<V>) -> R>(key: KeyArg, f: F) -> R;
fn mutate_exists<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Option<V>) -> R>(
key: KeyArg,
f: F,
) -> R;
/// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`.
fn try_mutate_exists<KeyArg: EncodeLike<K>, R, E, F: FnOnce(&mut Option<V>) -> Result<R, E>>(
@@ -292,7 +302,8 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
fn decode_len<KeyArg: EncodeLike<K>>(key: KeyArg) -> Option<usize>
where V: StorageDecodeLength,
where
V: StorageDecodeLength,
{
V::decode_len(&Self::hashed_key_for(key))
}
@@ -337,11 +348,9 @@ pub trait IterableStorageMap<K: FullEncode, V: FullCodec>: StorageMap<K, V> {
}
/// A strongly-typed double map in storage whose secondary keys and values can be iterated over.
pub trait IterableStorageDoubleMap<
K1: FullCodec,
K2: FullCodec,
V: FullCodec
>: StorageDoubleMap<K1, K2, V> {
pub trait IterableStorageDoubleMap<K1: FullCodec, K2: FullCodec, V: FullCodec>:
StorageDoubleMap<K1, K2, V>
{
/// The type that iterates over all `key2`.
type PartialKeyIterator: Iterator<Item = K2>;
@@ -401,19 +410,22 @@ pub trait IterableStorageNMap<K: ReversibleKeyGenerator, V: FullCodec>: StorageN
/// remove values whose prefix is `kp` to the map while doing this, you'll get undefined
/// results.
fn iter_prefix<KP>(kp: KP) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)>
where K: HasReversibleKeyPrefix<KP>;
where
K: HasReversibleKeyPrefix<KP>;
/// Enumerate all suffix keys in the map with prefix key `kp` in no particular order. If you
/// add or remove values whose prefix is `kp` to the map while doing this, you'll get undefined
/// results.
fn iter_key_prefix<KP>(kp: KP) -> KeyPrefixIterator<<K as HasKeyPrefix<KP>>::Suffix>
where K: HasReversibleKeyPrefix<KP>;
where
K: HasReversibleKeyPrefix<KP>;
/// Remove all elements from the map with prefix key `kp` and iterate through them in no
/// particular order. If you add elements with prefix key `kp` to the map while doing this,
/// you'll get undefined results.
fn drain_prefix<KP>(kp: KP) -> PrefixIterator<(<K as HasKeyPrefix<KP>>::Suffix, V)>
where K: HasReversibleKeyPrefix<KP>;
where
K: HasReversibleKeyPrefix<KP>;
/// Enumerate all elements in the map in no particular order. If you add or remove values to
/// the map while doing this, you'll get undefined results.
@@ -499,11 +511,13 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
/// Remove all values under the first key.
fn remove_prefix<KArg1>(k1: KArg1, limit: Option<u32>) -> sp_io::KillStorageResult
where KArg1: ?Sized + EncodeLike<K1>;
where
KArg1: ?Sized + EncodeLike<K1>;
/// Iterate over values that share the first key.
fn iter_prefix_values<KArg1>(k1: KArg1) -> PrefixIterator<V>
where KArg1: ?Sized + EncodeLike<K1>;
where
KArg1: ?Sized + EncodeLike<K1>;
/// Mutate the value under the given keys.
fn mutate<KArg1, KArg2, R, F>(k1: KArg1, k2: KArg2, f: F) -> R
@@ -542,11 +556,8 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
/// If the storage item is not encoded properly, the storage will be overwritten
/// and set to `[item]`. Any default value set for the storage item will be ignored
/// on overwrite.
fn append<Item, EncodeLikeItem, KArg1, KArg2>(
k1: KArg1,
k2: KArg2,
item: EncodeLikeItem,
) where
fn append<Item, EncodeLikeItem, KArg1, KArg2>(k1: KArg1, k2: KArg2, item: EncodeLikeItem)
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
Item: Encode,
@@ -566,10 +577,10 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
fn decode_len<KArg1, KArg2>(key1: KArg1, key2: KArg2) -> Option<usize>
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
V: StorageDecodeLength,
where
KArg1: EncodeLike<K1>,
KArg2: EncodeLike<K2>,
V: StorageDecodeLength,
{
V::decode_len(&Self::hashed_key_for(key1, key2))
}
@@ -583,7 +594,10 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
OldHasher2: StorageHasher,
KeyArg1: EncodeLike<K1>,
KeyArg2: EncodeLike<K2>,
>(key1: KeyArg1, key2: KeyArg2) -> Option<V>;
>(
key1: KeyArg1,
key2: KeyArg2,
) -> Option<V>;
}
/// An implementation of a map with an arbitrary number of keys.
@@ -625,10 +639,13 @@ pub trait StorageNMap<K: KeyGenerator, V: FullCodec> {
/// Remove all values under the partial prefix key.
fn remove_prefix<KP>(partial_key: KP, limit: Option<u32>) -> sp_io::KillStorageResult
where K: HasKeyPrefix<KP>;
where
K: HasKeyPrefix<KP>;
/// Iterate over values that share the partial prefix key.
fn iter_prefix_values<KP>(partial_key: KP) -> PrefixIterator<V> where K: HasKeyPrefix<KP>;
fn iter_prefix_values<KP>(partial_key: KP) -> PrefixIterator<V>
where
K: HasKeyPrefix<KP>;
/// Mutate the value under a key.
fn mutate<KArg, R, F>(key: KArg, f: F) -> R
@@ -741,7 +758,7 @@ impl<T> Iterator for PrefixIterator<T> {
self.previous_key,
);
continue
}
},
};
if self.drain {
unhashed::kill(&self.previous_key)
@@ -756,11 +773,11 @@ impl<T> Iterator for PrefixIterator<T> {
e,
);
continue
}
},
};
Some(item)
}
},
None => None,
}
}
@@ -807,12 +824,12 @@ impl<T> Iterator for KeyPrefixIterator<T> {
Ok(item) => return Some(item),
Err(e) => {
log::error!("key failed to decode at {:?}: {:?}", self.previous_key, e);
continue;
}
continue
},
}
}
return None;
return None
}
}
}
@@ -871,7 +888,10 @@ impl<K: Decode + Sized, T: Decode + Sized> ChildTriePrefixIterator<(K, T)> {
/// Construct iterator to iterate over child trie items in `child_info` with the prefix `prefix`.
///
/// NOTE: Iterator with [`Self::drain`] will remove any key or value who failed to decode
pub fn with_prefix_over_key<H: ReversibleStorageHasher>(child_info: &ChildInfo, prefix: &[u8]) -> Self {
pub fn with_prefix_over_key<H: ReversibleStorageHasher>(
child_info: &ChildInfo,
prefix: &[u8],
) -> Self {
let prefix = prefix.to_vec();
let previous_key = prefix.clone();
let closure = |raw_key_without_prefix: &[u8], raw_value: &[u8]| {
@@ -888,7 +908,7 @@ impl<K: Decode + Sized, T: Decode + Sized> ChildTriePrefixIterator<(K, T)> {
drain: false,
fetch_previous_key: true,
closure,
}
}
}
}
@@ -905,7 +925,7 @@ impl<T> Iterator for ChildTriePrefixIterator<T> {
&self.child_info.storage_key(),
&self.previous_key,
)
.filter(|n| n.starts_with(&self.prefix))
.filter(|n| n.starts_with(&self.prefix))
};
break match maybe_next {
Some(next) => {
@@ -918,7 +938,7 @@ impl<T> Iterator for ChildTriePrefixIterator<T> {
self.previous_key,
);
continue
}
},
};
if self.drain {
child::kill(&self.child_info, &self.previous_key)
@@ -933,11 +953,11 @@ impl<T> Iterator for ChildTriePrefixIterator<T> {
e,
);
continue
}
},
};
Some(item)
}
},
None => None,
}
}
@@ -999,8 +1019,8 @@ pub trait StoragePrefixedMap<Value: FullCodec> {
fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(mut f: F) {
let prefix = Self::final_prefix();
let mut previous_key = prefix.clone().to_vec();
while let Some(next) = sp_io::storage::next_key(&previous_key)
.filter(|n| n.starts_with(&prefix))
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
previous_key = next;
let maybe_value = unhashed::get::<OldValue>(&previous_key);
@@ -1010,10 +1030,7 @@ pub trait StoragePrefixedMap<Value: FullCodec> {
None => unhashed::kill(&previous_key),
},
None => {
log::error!(
"old key failed to decode at {:?}",
previous_key,
);
log::error!("old key failed to decode at {:?}", previous_key,);
continue
},
}
@@ -1218,13 +1235,13 @@ where
#[cfg(test)]
mod test {
use super::*;
use sp_core::hashing::twox_128;
use crate::{hash::Identity, assert_ok};
use sp_io::TestExternalities;
use generator::StorageValue as _;
use crate::{assert_ok, hash::Identity};
use bounded_vec::BoundedVec;
use weak_bounded_vec::WeakBoundedVec;
use core::convert::{TryFrom, TryInto};
use generator::StorageValue as _;
use sp_core::hashing::twox_128;
use sp_io::TestExternalities;
use weak_bounded_vec::WeakBoundedVec;
#[test]
fn prefixed_map_works() {
@@ -1363,8 +1380,7 @@ mod test {
#[test]
fn key_prefix_iterator_works() {
TestExternalities::default().execute_with(|| {
use crate::storage::generator::StorageMap;
use crate::hash::Twox64Concat;
use crate::{hash::Twox64Concat, storage::generator::StorageMap};
struct MyStorageMap;
impl StorageMap<u64, u64> for MyStorageMap {
type Query = u64;
@@ -1426,30 +1442,21 @@ mod test {
assert_eq!(
ChildTriePrefixIterator::with_prefix(&child_info_a, &[2])
.collect::<Vec<(Vec<u8>, u16)>>(),
vec![
(vec![], 8),
(vec![2, 3], 8),
],
vec![(vec![], 8), (vec![2, 3], 8),],
);
assert_eq!(
ChildTriePrefixIterator::with_prefix(&child_info_a, &[2])
.drain()
.collect::<Vec<(Vec<u8>, u16)>>(),
vec![
(vec![], 8),
(vec![2, 3], 8),
],
vec![(vec![], 8), (vec![2, 3], 8),],
);
// The only remaining is the ones outside prefix
assert_eq!(
ChildTriePrefixIterator::with_prefix(&child_info_a, &[])
.collect::<Vec<(Vec<u8>, u8)>>(),
vec![
(vec![1, 2, 3], 8),
(vec![3], 8),
],
vec![(vec![1, 2, 3], 8), (vec![3], 8),],
);
child::put(&child_info_a, &[1, 2, 3], &8u16);
@@ -1461,28 +1468,21 @@ mod test {
assert_eq!(
ChildTriePrefixIterator::with_prefix_over_key::<Identity>(&child_info_a, &[2])
.collect::<Vec<(u16, u16)>>(),
vec![
(u16::decode(&mut &[2, 3][..]).unwrap(), 8),
],
vec![(u16::decode(&mut &[2, 3][..]).unwrap(), 8),],
);
assert_eq!(
ChildTriePrefixIterator::with_prefix_over_key::<Identity>(&child_info_a, &[2])
.drain()
.collect::<Vec<(u16, u16)>>(),
vec![
(u16::decode(&mut &[2, 3][..]).unwrap(), 8),
],
vec![(u16::decode(&mut &[2, 3][..]).unwrap(), 8),],
);
// The only remaining is the ones outside prefix
assert_eq!(
ChildTriePrefixIterator::with_prefix(&child_info_a, &[])
.collect::<Vec<(Vec<u8>, u8)>>(),
vec![
(vec![1, 2, 3], 8),
(vec![3], 8),
],
vec![(vec![1, 2, 3], 8), (vec![3], 8),],
);
});
}
@@ -18,14 +18,14 @@
//! Storage map type. Implements StorageDoubleMap, StorageIterableDoubleMap,
//! StoragePrefixedDoubleMap traits and their methods directly.
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use crate::{
storage::{
StorageAppend, StorageTryAppend, StorageDecodeLength, StoragePrefixedMap,
types::{OptionQuery, QueryKindTrait, OnEmptyGetter},
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
},
traits::{GetDefault, StorageInstance, Get, StorageInfo},
traits::{Get, GetDefault, StorageInfo, StorageInstance},
};
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use frame_metadata::{DefaultByteGetter, StorageEntryModifier};
use sp_arithmetic::traits::SaturatedConversion;
use sp_std::prelude::*;
@@ -36,9 +36,9 @@ use sp_std::prelude::*;
/// Each value is stored at:
/// ```nocompile
/// Twox128(Prefix::pallet_prefix())
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key1))
/// ++ Hasher2(encode(key2))
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key1))
/// ++ Hasher2(encode(key2))
/// ```
///
/// # Warning
@@ -53,18 +53,26 @@ pub struct StorageDoubleMap<
Hasher2,
Key2,
Value,
QueryKind=OptionQuery,
OnEmpty=GetDefault,
MaxValues=GetDefault,
QueryKind = OptionQuery,
OnEmpty = GetDefault,
MaxValues = GetDefault,
>(
core::marker::PhantomData<
(Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues)
>
core::marker::PhantomData<(
Prefix,
Hasher1,
Key1,
Hasher2,
Key2,
Value,
QueryKind,
OnEmpty,
MaxValues,
)>,
);
impl<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::storage::generator::StorageDoubleMap<Key1, Key2, Value> for
StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::storage::generator::StorageDoubleMap<Key1, Key2, Value>
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
@@ -94,8 +102,8 @@ where
}
impl<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
StoragePrefixedMap<Value> for
StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
StoragePrefixedMap<Value>
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
@@ -161,7 +169,8 @@ where
pub fn try_get<KArg1, KArg2>(k1: KArg1, k2: KArg2) -> Result<Value, ()>
where
KArg1: EncodeLike<Key1>,
KArg2: EncodeLike<Key2> {
KArg2: EncodeLike<Key2>,
{
<Self as crate::storage::StorageDoubleMap<Key1, Key2, Value>>::try_get(k1, k2)
}
@@ -175,8 +184,12 @@ where
}
/// Swap the values of two key-pairs.
pub fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2)
where
pub fn swap<XKArg1, XKArg2, YKArg1, YKArg2>(
x_k1: XKArg1,
x_k2: XKArg2,
y_k1: YKArg1,
y_k2: YKArg2,
) where
XKArg1: EncodeLike<Key1>,
XKArg2: EncodeLike<Key2>,
YKArg1: EncodeLike<Key1>,
@@ -206,13 +219,16 @@ where
/// Remove all values under the first key.
pub fn remove_prefix<KArg1>(k1: KArg1, limit: Option<u32>) -> sp_io::KillStorageResult
where KArg1: ?Sized + EncodeLike<Key1> {
where
KArg1: ?Sized + EncodeLike<Key1>,
{
<Self as crate::storage::StorageDoubleMap<Key1, Key2, Value>>::remove_prefix(k1, limit)
}
/// Iterate over values that share the first key.
pub fn iter_prefix_values<KArg1>(k1: KArg1) -> crate::storage::PrefixIterator<Value>
where KArg1: ?Sized + EncodeLike<Key1>
where
KArg1: ?Sized + EncodeLike<Key1>,
{
<Self as crate::storage::StorageDoubleMap<Key1, Key2, Value>>::iter_prefix_values(k1)
}
@@ -266,11 +282,8 @@ where
/// If the storage item is not encoded properly, the storage will be overwritten
/// and set to `[item]`. Any default value set for the storage item will be ignored
/// on overwrite.
pub fn append<Item, EncodeLikeItem, KArg1, KArg2>(
k1: KArg1,
k2: KArg2,
item: EncodeLikeItem,
) where
pub fn append<Item, EncodeLikeItem, KArg1, KArg2>(k1: KArg1, k2: KArg2, item: EncodeLikeItem)
where
KArg1: EncodeLike<Key1>,
KArg2: EncodeLike<Key2>,
Item: Encode,
@@ -310,10 +323,16 @@ where
OldHasher2: crate::StorageHasher,
KeyArg1: EncodeLike<Key1>,
KeyArg2: EncodeLike<Key2>,
>(key1: KeyArg1, key2: KeyArg2) -> Option<Value> {
<
Self as crate::storage::StorageDoubleMap<Key1, Key2, Value>
>::migrate_keys::<OldHasher1, OldHasher2, _, _>(key1, key2)
>(
key1: KeyArg1,
key2: KeyArg2,
) -> Option<Value> {
<Self as crate::storage::StorageDoubleMap<Key1, Key2, Value>>::migrate_keys::<
OldHasher1,
OldHasher2,
_,
_,
>(key1, key2)
}
/// Remove all value of the storage.
@@ -360,9 +379,9 @@ where
EncodeLikeItem: EncodeLike<Item>,
Value: StorageTryAppend<Item>,
{
<
Self as crate::storage::TryAppendDoubleMap<Key1, Key2, Value, Item>
>::try_append(key1, key2, item)
<Self as crate::storage::TryAppendDoubleMap<Key1, Key2, Value, Item>>::try_append(
key1, key2, item,
)
}
}
@@ -401,7 +420,9 @@ where
///
/// If you add elements with first key `k1` to the map while doing this, you'll get undefined
/// results.
pub fn drain_prefix(k1: impl EncodeLike<Key1>) -> crate::storage::PrefixIterator<(Key2, Value)> {
pub fn drain_prefix(
k1: impl EncodeLike<Key1>,
) -> crate::storage::PrefixIterator<(Key2, Value)> {
<Self as crate::storage::IterableStorageDoubleMap<Key1, Key2, Value>>::drain_prefix(k1)
}
@@ -448,8 +469,8 @@ pub trait StorageDoubleMapMetadata {
}
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
StorageDoubleMapMetadata for
StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
StorageDoubleMapMetadata
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
@@ -470,8 +491,8 @@ where
}
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::StorageInfoTrait for
StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::StorageInfoTrait
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
@@ -484,27 +505,25 @@ where
MaxValues: Get<Option<u32>>,
{
fn storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher1::max_len::<Key1>()
.saturating_add(Hasher2::max_len::<Key2>())
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher1::max_len::<Key1>()
.saturating_add(Hasher2::max_len::<Key2>())
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait for
StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher1: crate::hash::StorageHasher,
@@ -517,29 +536,28 @@ where
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
}
#[cfg(test)]
mod test {
use super::*;
use sp_io::{TestExternalities, hashing::twox_128};
use crate::hash::*;
use crate::storage::types::ValueQuery;
use crate::{hash::*, storage::types::ValueQuery};
use frame_metadata::StorageEntryModifier;
use sp_io::{hashing::twox_128, TestExternalities};
struct Prefix;
impl StorageInstance for Prefix {
fn pallet_prefix() -> &'static str { "test" }
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "foo";
}
@@ -552,11 +570,17 @@ mod test {
#[test]
fn test() {
type A = StorageDoubleMap<
Prefix, Blake2_128Concat, u16, Twox64Concat, u8, u32, OptionQuery
>;
type A =
StorageDoubleMap<Prefix, Blake2_128Concat, u16, Twox64Concat, u8, u32, OptionQuery>;
type AValueQueryWithAnOnEmpty = StorageDoubleMap<
Prefix, Blake2_128Concat, u16, Twox64Concat, u8, u32, ValueQuery, ADefault
Prefix,
Blake2_128Concat,
u16,
Twox64Concat,
u8,
u32,
ValueQuery,
ADefault,
>;
type B = StorageDoubleMap<Prefix, Blake2_256, u16, Twox128, u8, u32, ValueQuery>;
type C = StorageDoubleMap<Prefix, Blake2_128Concat, u16, Twox64Concat, u8, u8, ValueQuery>;
@@ -598,17 +622,20 @@ mod test {
A::remove(2, 20);
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, 20, |v| {
*v = *v * 2; Ok(())
*v = *v * 2;
Ok(())
});
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, 20, |v| {
*v = *v * 2; Ok(())
*v = *v * 2;
Ok(())
});
assert_eq!(A::contains_key(2, 20), true);
assert_eq!(A::get(2, 20), Some(97 * 4));
A::remove(2, 20);
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, 20, |v| {
*v = *v * 2; Err(())
*v = *v * 2;
Err(())
});
assert_eq!(A::contains_key(2, 20), false);
@@ -647,7 +674,6 @@ mod test {
assert_eq!(A::contains_key(2, 20), true);
assert_eq!(A::get(2, 20), Some(100));
A::insert(2, 20, 10);
assert_eq!(A::take(2, 20), Some(10));
assert_eq!(A::contains_key(2, 20), false);
@@ -672,7 +698,7 @@ mod test {
C::insert(3, 30, 10);
C::insert(4, 40, 10);
A::translate_values::<u8,_>(|v| Some((v * 2).into()));
A::translate_values::<u8, _>(|v| Some((v * 2).into()));
assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40, 20), (3, 30, 20)]);
A::insert(3, 30, 10);
@@ -683,7 +709,7 @@ mod test {
C::insert(3, 30, 10);
C::insert(4, 40, 10);
A::translate::<u8,_>(|k1, k2, v| Some((k1 * k2 as u16 * v as u16).into()));
A::translate::<u8, _>(|k1, k2, v| Some((k1 * k2 as u16 * v as u16).into()));
assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40, 1600), (3, 30, 900)]);
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
@@ -75,24 +75,16 @@ impl<H: StorageHasher, K: FullCodec> KeyGenerator for Key<H, K> {
const HASHER_METADATA: &'static [frame_metadata::StorageHasher] = &[H::METADATA];
fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
H::hash(
&key.to_encoded_iter()
.next()
.expect("should have at least one element!"),
)
.as_ref()
.to_vec()
H::hash(&key.to_encoded_iter().next().expect("should have at least one element!"))
.as_ref()
.to_vec()
}
fn migrate_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(
key: &KArg,
hash_fns: Self::HArg,
) -> Vec<u8> {
(hash_fns.0)(
&key.to_encoded_iter()
.next()
.expect("should have at least one element!"),
)
(hash_fns.0)(&key.to_encoded_iter().next().expect("should have at least one element!"))
}
}
@@ -118,9 +110,8 @@ impl KeyGenerator for Tuple {
for_tuples!( type HArg = ( #(Tuple::HashFn),* ); );
type HashFn = Box<dyn FnOnce(&[u8]) -> Vec<u8>>;
const HASHER_METADATA: &'static [frame_metadata::StorageHasher] = &[
for_tuples!( #(Tuple::Hasher::METADATA),* )
];
const HASHER_METADATA: &'static [frame_metadata::StorageHasher] =
&[for_tuples!( #(Tuple::Hasher::METADATA),* )];
fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
let mut final_key = Vec::new();
@@ -210,9 +201,7 @@ pub trait TupleToEncodedIter {
#[tuple_types_custom_trait_bound(Encode)]
impl TupleToEncodedIter for Tuple {
fn to_encoded_iter(&self) -> sp_std::vec::IntoIter<Vec<u8>> {
[for_tuples!( #(self.Tuple.encode()),* )]
.to_vec()
.into_iter()
[for_tuples!( #(self.Tuple.encode()),* )].to_vec().into_iter()
}
}
@@ -246,7 +235,7 @@ impl ReversibleKeyGenerator for Tuple {
fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error> {
let mut current_key_material = key_material;
Ok((
(for_tuples!{
(for_tuples! {
#({
let (key, material) = Tuple::decode_final_key(current_key_material)?;
current_key_material = material;
@@ -18,14 +18,14 @@
//! Storage map type. Implements StorageMap, StorageIterableMap, StoragePrefixedMap traits and their
//! methods directly.
use codec::{FullCodec, Decode, EncodeLike, Encode, MaxEncodedLen};
use crate::{
storage::{
StorageAppend, StorageTryAppend, StorageDecodeLength, StoragePrefixedMap,
types::{OptionQuery, QueryKindTrait, OnEmptyGetter},
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
},
traits::{GetDefault, StorageInstance, Get, StorageInfo},
traits::{Get, GetDefault, StorageInfo, StorageInstance},
};
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use frame_metadata::{DefaultByteGetter, StorageEntryModifier};
use sp_arithmetic::traits::SaturatedConversion;
use sp_std::prelude::*;
@@ -35,8 +35,8 @@ use sp_std::prelude::*;
/// Each value is stored at:
/// ```nocompile
/// Twox128(Prefix::pallet_prefix())
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key))
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key))
/// ```
///
/// # Warning
@@ -44,10 +44,14 @@ use sp_std::prelude::*;
/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
/// `blake2_128_concat` must be used. Otherwise, other values in storage can be compromised.
pub struct StorageMap<
Prefix, Hasher, Key, Value, QueryKind=OptionQuery, OnEmpty=GetDefault, MaxValues=GetDefault,
>(
core::marker::PhantomData<(Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues)>
);
Prefix,
Hasher,
Key,
Value,
QueryKind = OptionQuery,
OnEmpty = GetDefault,
MaxValues = GetDefault,
>(core::marker::PhantomData<(Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues)>);
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::storage::generator::StorageMap<Key, Value>
@@ -77,9 +81,8 @@ where
}
}
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
StoragePrefixedMap<Value> for
StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StoragePrefixedMap<Value>
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher: crate::hash::StorageHasher,
@@ -148,7 +151,7 @@ where
/// Mutate the value under a key.
pub fn mutate<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut QueryKind::Query) -> R>(
key: KeyArg,
f: F
f: F,
) -> R {
<Self as crate::storage::StorageMap<Key, Value>>::mutate(key, f)
}
@@ -165,7 +168,7 @@ where
/// Mutate the value under a key. Deletes the item if mutated to a `None`.
pub fn mutate_exists<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut Option<Value>) -> R>(
key: KeyArg,
f: F
f: F,
) -> R {
<Self as crate::storage::StorageMap<Key, Value>>::mutate_exists(key, f)
}
@@ -198,7 +201,7 @@ where
EncodeLikeKey: EncodeLike<Key>,
Item: Encode,
EncodeLikeItem: EncodeLike<Item>,
Value: StorageAppend<Item>
Value: StorageAppend<Item>,
{
<Self as crate::storage::StorageMap<Key, Value>>::append(key, item)
}
@@ -216,7 +219,8 @@ where
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
pub fn decode_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
where Value: StorageDecodeLength,
where
Value: StorageDecodeLength,
{
<Self as crate::storage::StorageMap<Key, Value>>::decode_len(key)
}
@@ -225,7 +229,7 @@ where
///
/// If the key doesn't exist, then it's a no-op. If it does, then it returns its value.
pub fn migrate_key<OldHasher: crate::hash::StorageHasher, KeyArg: EncodeLike<Key>>(
key: KeyArg
key: KeyArg,
) -> Option<Value> {
<Self as crate::storage::StorageMap<Key, Value>>::migrate_key::<OldHasher, _>(key)
}
@@ -263,19 +267,14 @@ where
/// Try and append the given item to the value in the storage.
///
/// Is only available if `Value` of the storage implements [`StorageTryAppend`].
pub fn try_append<KArg, Item, EncodeLikeItem>(
key: KArg,
item: EncodeLikeItem,
) -> Result<(), ()>
pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
where
KArg: EncodeLike<Key> + Clone,
Item: Encode,
EncodeLikeItem: EncodeLike<Item>,
Value: StorageTryAppend<Item>,
{
<
Self as crate::storage::TryAppendMap<Key, Value, Item>
>::try_append(key, item)
<Self as crate::storage::TryAppendMap<Key, Value, Item>>::try_append(key, item)
}
}
@@ -332,7 +331,8 @@ pub trait StorageMapMetadata {
}
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageMapMetadata
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> where
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher: crate::hash::StorageHasher,
Key: FullCodec,
@@ -348,9 +348,8 @@ impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageMapMetada
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
}
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::StorageInfoTrait for
StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher: crate::hash::StorageHasher,
@@ -361,26 +360,24 @@ where
MaxValues: Get<Option<u32>>,
{
fn storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher::max_len::<Key>()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Hasher::max_len::<Key>()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait for
StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Hasher: crate::hash::StorageHasher,
@@ -391,29 +388,28 @@ where
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
}
#[cfg(test)]
mod test {
use super::*;
use sp_io::{TestExternalities, hashing::twox_128};
use crate::hash::*;
use crate::storage::types::ValueQuery;
use crate::{hash::*, storage::types::ValueQuery};
use frame_metadata::StorageEntryModifier;
use sp_io::{hashing::twox_128, TestExternalities};
struct Prefix;
impl StorageInstance for Prefix {
fn pallet_prefix() -> &'static str { "test" }
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "foo";
}
@@ -427,9 +423,8 @@ mod test {
#[test]
fn test() {
type A = StorageMap<Prefix, Blake2_128Concat, u16, u32, OptionQuery>;
type AValueQueryWithAnOnEmpty = StorageMap<
Prefix, Blake2_128Concat, u16, u32, ValueQuery, ADefault
>;
type AValueQueryWithAnOnEmpty =
StorageMap<Prefix, Blake2_128Concat, u16, u32, ValueQuery, ADefault>;
type B = StorageMap<Prefix, Blake2_256, u16, u32, ValueQuery>;
type C = StorageMap<Prefix, Blake2_128Concat, u16, u8, ValueQuery>;
type WithLen = StorageMap<Prefix, Blake2_128Concat, u16, Vec<u32>>;
@@ -471,17 +466,20 @@ mod test {
A::remove(2);
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
*v = *v * 2; Ok(())
*v = *v * 2;
Ok(())
});
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
*v = *v * 2; Ok(())
*v = *v * 2;
Ok(())
});
assert_eq!(A::contains_key(2), true);
assert_eq!(A::get(2), Some(97 * 4));
A::remove(2);
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
*v = *v * 2; Err(())
*v = *v * 2;
Err(())
});
assert_eq!(A::contains_key(2), false);
@@ -519,7 +517,6 @@ mod test {
assert_eq!(A::contains_key(2), true);
assert_eq!(A::get(2), Some(100));
A::insert(2, 10);
assert_eq!(A::take(2), Some(10));
assert_eq!(A::contains_key(2), false);
@@ -543,7 +540,7 @@ mod test {
C::insert(3, 10);
C::insert(4, 10);
A::translate_values::<u8,_>(|v| Some((v * 2).into()));
A::translate_values::<u8, _>(|v| Some((v * 2).into()));
assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
A::insert(3, 10);
@@ -554,7 +551,7 @@ mod test {
C::insert(3, 10);
C::insert(4, 10);
A::translate::<u8,_>(|k, v| Some((k * v as u16).into()));
A::translate::<u8, _>(|k, v| Some((k * v as u16).into()));
assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
@@ -30,7 +30,7 @@ mod value;
pub use double_map::{StorageDoubleMap, StorageDoubleMapMetadata};
pub use key::{
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, Key, KeyGenerator,
ReversibleKeyGenerator, TupleToEncodedIter, KeyGeneratorMaxEncodedLen,
KeyGeneratorMaxEncodedLen, ReversibleKeyGenerator, TupleToEncodedIter,
};
pub use map::{StorageMap, StorageMapMetadata};
pub use nmap::{StorageNMap, StorageNMapMetadata};
+80 -156
View File
@@ -21,12 +21,12 @@
use crate::{
storage::{
types::{
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OnEmptyGetter,
OptionQuery, QueryKindTrait, TupleToEncodedIter,
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OnEmptyGetter, OptionQuery,
QueryKindTrait, TupleToEncodedIter,
},
KeyGenerator, PrefixIterator, StorageAppend, StorageDecodeLength, StoragePrefixedMap,
},
traits::{Get, GetDefault, StorageInstance, StorageInfo},
traits::{Get, GetDefault, StorageInfo, StorageInstance},
};
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use frame_metadata::{DefaultByteGetter, StorageEntryModifier};
@@ -39,9 +39,9 @@ use sp_std::prelude::*;
/// Each value is stored at:
/// ```nocompile
/// Twox128(Prefix::pallet_prefix())
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key1))
/// ++ Hasher2(encode(key2))
/// ++ Twox128(Prefix::STORAGE_PREFIX)
/// ++ Hasher1(encode(key1))
/// ++ Hasher2(encode(key2))
/// ++ ...
/// ++ HasherN(encode(keyN))
/// ```
@@ -52,10 +52,13 @@ use sp_std::prelude::*;
/// such as `blake2_128_concat` must be used for the key hashers. Otherwise, other values
/// in storage can be compromised.
pub struct StorageNMap<
Prefix, Key, Value, QueryKind = OptionQuery, OnEmpty = GetDefault, MaxValues=GetDefault,
>(
core::marker::PhantomData<(Prefix, Key, Value, QueryKind, OnEmpty, MaxValues)>,
);
Prefix,
Key,
Value,
QueryKind = OptionQuery,
OnEmpty = GetDefault,
MaxValues = GetDefault,
>(core::marker::PhantomData<(Prefix, Key, Value, QueryKind, OnEmpty, MaxValues)>);
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::storage::generator::StorageNMap<Key, Value>
@@ -83,8 +86,7 @@ where
}
}
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::storage::StoragePrefixedMap<Value>
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::storage::StoragePrefixedMap<Value>
for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
@@ -113,7 +115,9 @@ where
MaxValues: Get<Option<u32>>,
{
/// Get the storage key used to fetch a value corresponding to a specific key.
pub fn hashed_key_for<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
pub fn hashed_key_for<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
key: KArg,
) -> Vec<u8> {
<Self as crate::storage::StorageNMap<Key, Value>>::hashed_key_for(key)
}
@@ -123,7 +127,9 @@ where
}
/// Load the value associated with the given key from the map.
pub fn get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> QueryKind::Query {
pub fn get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
key: KArg,
) -> QueryKind::Query {
<Self as crate::storage::StorageNMap<Key, Value>>::get(key)
}
@@ -137,7 +143,9 @@ where
}
/// Take a value from storage, removing it afterwards.
pub fn take<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> QueryKind::Query {
pub fn take<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
key: KArg,
) -> QueryKind::Query {
<Self as crate::storage::StorageNMap<Key, Value>>::take(key)
}
@@ -248,7 +256,9 @@ where
///
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
pub fn decode_len<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> Option<usize>
pub fn decode_len<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
key: KArg,
) -> Option<usize>
where
Value: StorageDecodeLength,
{
@@ -260,7 +270,7 @@ where
/// If the key doesn't exist, then it's a no-op. If it does, then it returns its value.
pub fn migrate_keys<KArg>(key: KArg, hash_fns: Key::HArg) -> Option<Value>
where
KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter
KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
{
<Self as crate::storage::StorageNMap<Key, Value>>::migrate_keys::<_>(key, hash_fns)
}
@@ -398,15 +408,13 @@ where
{
const MODIFIER: StorageEntryModifier = QueryKind::METADATA;
const NAME: &'static str = Prefix::STORAGE_PREFIX;
const DEFAULT: DefaultByteGetter = DefaultByteGetter(
&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData),
);
const DEFAULT: DefaultByteGetter =
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
const HASHERS: &'static [frame_metadata::StorageHasher] = Key::HASHER_METADATA;
}
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::StorageInfoTrait for
StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Key: super::key::KeyGenerator + super::key::KeyGeneratorMaxEncodedLen,
@@ -416,26 +424,23 @@ where
MaxValues: Get<Option<u32>>,
{
fn storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Key::key_max_encoded_len()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: Some(
Key::key_max_encoded_len()
.saturating_add(Value::max_encoded_len())
.saturated_into(),
),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
crate::traits::PartialStorageInfoTrait for
StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::PartialStorageInfoTrait
for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
where
Prefix: StorageInstance,
Key: super::key::KeyGenerator,
@@ -445,22 +450,22 @@ where
MaxValues: Get<Option<u32>>,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::final_prefix().to_vec(),
max_values: MaxValues::get(),
max_size: None,
}]
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::hash::*;
use crate::storage::types::{Key, ValueQuery};
use crate::{
hash::*,
storage::types::{Key, ValueQuery},
};
use frame_metadata::StorageEntryModifier;
use sp_io::{hashing::twox_128, TestExternalities};
@@ -627,15 +632,9 @@ mod test {
assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
assert_eq!(
AValueQueryWithAnOnEmpty::MODIFIER,
StorageEntryModifier::Default
);
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
assert_eq!(A::NAME, "Foo");
assert_eq!(
AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(),
98u32.encode()
);
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
WithLen::remove_all(None);
@@ -787,41 +786,23 @@ mod test {
C::insert((3, 30), 10);
C::insert((4, 40), 10);
A::translate_values::<u8, _>(|v| Some((v * 2).into()));
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40), 20), ((3, 30), 20)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 20), ((3, 30), 20)]);
A::insert((3, 30), 10);
A::insert((4, 40), 10);
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40), 10), ((3, 30), 10)]
);
assert_eq!(
A::drain().collect::<Vec<_>>(),
vec![((4, 40), 10), ((3, 30), 10)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
assert_eq!(A::drain().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
C::insert((3, 30), 10);
C::insert((4, 40), 10);
A::translate::<u8, _>(|(k1, k2), v| Some((k1 * k2 as u16 * v as u16).into()));
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40), 1600), ((3, 30), 900)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 1600), ((3, 30), 900)]);
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
assert_eq!(
AValueQueryWithAnOnEmpty::MODIFIER,
StorageEntryModifier::Default
);
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
assert_eq!(A::NAME, "Foo");
assert_eq!(
AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(),
98u32.encode()
);
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
WithLen::remove_all(None);
@@ -833,14 +814,8 @@ mod test {
A::insert((3, 31), 12);
A::insert((4, 40), 13);
A::insert((4, 41), 14);
assert_eq!(
A::iter_prefix_values((3,)).collect::<Vec<_>>(),
vec![12, 11]
);
assert_eq!(
A::iter_prefix_values((4,)).collect::<Vec<_>>(),
vec![13, 14]
);
assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![12, 11]);
assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![13, 14]);
});
}
@@ -848,52 +823,32 @@ mod test {
fn test_3_keys() {
type A = StorageNMap<
Prefix,
(
Key<Blake2_128Concat, u16>,
Key<Blake2_128Concat, u16>,
Key<Twox64Concat, u16>,
),
(Key<Blake2_128Concat, u16>, Key<Blake2_128Concat, u16>, Key<Twox64Concat, u16>),
u32,
OptionQuery,
>;
type AValueQueryWithAnOnEmpty = StorageNMap<
Prefix,
(
Key<Blake2_128Concat, u16>,
Key<Blake2_128Concat, u16>,
Key<Twox64Concat, u16>,
),
(Key<Blake2_128Concat, u16>, Key<Blake2_128Concat, u16>, Key<Twox64Concat, u16>),
u32,
ValueQuery,
ADefault,
>;
type B = StorageNMap<
Prefix,
(
Key<Blake2_256, u16>,
Key<Blake2_256, u16>,
Key<Twox128, u16>,
),
(Key<Blake2_256, u16>, Key<Blake2_256, u16>, Key<Twox128, u16>),
u32,
ValueQuery,
>;
type C = StorageNMap<
Prefix,
(
Key<Blake2_128Concat, u16>,
Key<Blake2_128Concat, u16>,
Key<Twox64Concat, u16>,
),
(Key<Blake2_128Concat, u16>, Key<Blake2_128Concat, u16>, Key<Twox64Concat, u16>),
u8,
ValueQuery,
>;
type WithLen = StorageNMap<
Prefix,
(
Key<Blake2_128Concat, u16>,
Key<Blake2_128Concat, u16>,
Key<Twox64Concat, u16>,
),
(Key<Blake2_128Concat, u16>, Key<Blake2_128Concat, u16>, Key<Twox64Concat, u16>),
Vec<u32>,
>;
@@ -916,11 +871,7 @@ mod test {
assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 30);
A::swap::<
(
Key<Blake2_128Concat, u16>,
Key<Blake2_128Concat, u16>,
Key<Twox64Concat, u16>,
),
(Key<Blake2_128Concat, u16>, Key<Blake2_128Concat, u16>, Key<Twox64Concat, u16>),
_,
_,
>((1, 10, 100), (2, 20, 200));
@@ -1020,17 +971,11 @@ mod test {
C::insert((3, 30, 300), 10);
C::insert((4, 40, 400), 10);
A::translate_values::<u8, _>(|v| Some((v * 2).into()));
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40, 400), 20), ((3, 30, 300), 20)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 20), ((3, 30, 300), 20)]);
A::insert((3, 30, 300), 10);
A::insert((4, 40, 400), 10);
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40, 400), 10), ((3, 30, 300), 10)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 10), ((3, 30, 300), 10)]);
assert_eq!(
A::drain().collect::<Vec<_>>(),
vec![((4, 40, 400), 10), ((3, 30, 300), 10)]
@@ -1042,21 +987,12 @@ mod test {
A::translate::<u8, _>(|(k1, k2, k3), v| {
Some((k1 * k2 as u16 * v as u16 / k3 as u16).into())
});
assert_eq!(
A::iter().collect::<Vec<_>>(),
vec![((4, 40, 400), 4), ((3, 30, 300), 3)]
);
assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 4), ((3, 30, 300), 3)]);
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
assert_eq!(
AValueQueryWithAnOnEmpty::MODIFIER,
StorageEntryModifier::Default
);
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
assert_eq!(A::NAME, "Foo");
assert_eq!(
AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(),
98u32.encode()
);
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
WithLen::remove_all(None);
@@ -1068,22 +1004,10 @@ mod test {
A::insert((3, 30, 301), 12);
A::insert((4, 40, 400), 13);
A::insert((4, 40, 401), 14);
assert_eq!(
A::iter_prefix_values((3,)).collect::<Vec<_>>(),
vec![11, 12]
);
assert_eq!(
A::iter_prefix_values((4,)).collect::<Vec<_>>(),
vec![14, 13]
);
assert_eq!(
A::iter_prefix_values((3, 30)).collect::<Vec<_>>(),
vec![11, 12]
);
assert_eq!(
A::iter_prefix_values((4, 40)).collect::<Vec<_>>(),
vec![14, 13]
);
assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![11, 12]);
assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![14, 13]);
assert_eq!(A::iter_prefix_values((3, 30)).collect::<Vec<_>>(), vec![11, 12]);
assert_eq!(A::iter_prefix_values((4, 40)).collect::<Vec<_>>(), vec![14, 13]);
});
}
}
@@ -17,15 +17,15 @@
//! Storage value type. Implements StorageValue trait and its method directly.
use codec::{FullCodec, Decode, EncodeLike, Encode, MaxEncodedLen};
use crate::{
storage::{
StorageAppend, StorageTryAppend, StorageDecodeLength,
types::{OptionQuery, QueryKindTrait, OnEmptyGetter},
generator::{StorageValue as StorageValueT},
generator::StorageValue as StorageValueT,
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
StorageAppend, StorageDecodeLength, StorageTryAppend,
},
traits::{GetDefault, StorageInstance, StorageInfo},
traits::{GetDefault, StorageInfo, StorageInstance},
};
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use frame_metadata::{DefaultByteGetter, StorageEntryModifier};
use sp_arithmetic::traits::SaturatedConversion;
use sp_std::prelude::*;
@@ -36,12 +36,12 @@ use sp_std::prelude::*;
/// ```nocompile
/// Twox128(Prefix::pallet_prefix()) ++ Twox128(Prefix::STORAGE_PREFIX)
/// ```
pub struct StorageValue<Prefix, Value, QueryKind=OptionQuery, OnEmpty=GetDefault>(
core::marker::PhantomData<(Prefix, Value, QueryKind, OnEmpty)>
pub struct StorageValue<Prefix, Value, QueryKind = OptionQuery, OnEmpty = GetDefault>(
core::marker::PhantomData<(Prefix, Value, QueryKind, OnEmpty)>,
);
impl<Prefix, Value, QueryKind, OnEmpty> crate::storage::generator::StorageValue<Value> for
StorageValue<Prefix, Value, QueryKind, OnEmpty>
impl<Prefix, Value, QueryKind, OnEmpty> crate::storage::generator::StorageValue<Value>
for StorageValue<Prefix, Value, QueryKind, OnEmpty>
where
Prefix: StorageInstance,
Value: FullCodec,
@@ -71,13 +71,19 @@ where
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static,
{
/// Get the storage key.
pub fn hashed_key() -> [u8; 32] { <Self as crate::storage::StorageValue<Value>>::hashed_key() }
pub fn hashed_key() -> [u8; 32] {
<Self as crate::storage::StorageValue<Value>>::hashed_key()
}
/// Does the value (explicitly) exist in storage?
pub fn exists() -> bool { <Self as crate::storage::StorageValue<Value>>::exists() }
pub fn exists() -> bool {
<Self as crate::storage::StorageValue<Value>>::exists()
}
/// Load the value from the provided storage instance.
pub fn get() -> QueryKind::Query { <Self as crate::storage::StorageValue<Value>>::get() }
pub fn get() -> QueryKind::Query {
<Self as crate::storage::StorageValue<Value>>::get()
}
/// Try to get the underlying value from the provided storage instance; `Ok` if it exists,
/// `Err` if not.
@@ -120,7 +126,9 @@ where
/// Store a value under this key into the provided storage instance.
///
/// this uses the query type rather than the underlying value.
pub fn set(val: QueryKind::Query) { <Self as crate::storage::StorageValue<Value>>::set(val) }
pub fn set(val: QueryKind::Query) {
<Self as crate::storage::StorageValue<Value>>::set(val)
}
/// Mutate the value
pub fn mutate<R, F: FnOnce(&mut QueryKind::Query) -> R>(f: F) -> R {
@@ -135,10 +143,14 @@ where
}
/// Clear the storage value.
pub fn kill() { <Self as crate::storage::StorageValue<Value>>::kill() }
pub fn kill() {
<Self as crate::storage::StorageValue<Value>>::kill()
}
/// Take a value from storage, removing it afterwards.
pub fn take() -> QueryKind::Query { <Self as crate::storage::StorageValue<Value>>::take() }
pub fn take() -> QueryKind::Query {
<Self as crate::storage::StorageValue<Value>>::take()
}
/// Append the given item to the value in the storage.
///
@@ -153,7 +165,7 @@ where
where
Item: Encode,
EncodeLikeItem: EncodeLike<Item>,
Value: StorageAppend<Item>
Value: StorageAppend<Item>,
{
<Self as crate::storage::StorageValue<Value>>::append(item)
}
@@ -169,7 +181,10 @@ where
///
/// `None` does not mean that `get()` does not return a value. The default value is completly
/// ignored by this function.
pub fn decode_len() -> Option<usize> where Value: StorageDecodeLength {
pub fn decode_len() -> Option<usize>
where
Value: StorageDecodeLength,
{
<Self as crate::storage::StorageValue<Value>>::decode_len()
}
@@ -194,7 +209,8 @@ pub trait StorageValueMetadata {
}
impl<Prefix, Value, QueryKind, OnEmpty> StorageValueMetadata
for StorageValue<Prefix, Value, QueryKind, OnEmpty> where
for StorageValue<Prefix, Value, QueryKind, OnEmpty>
where
Prefix: StorageInstance,
Value: FullCodec,
QueryKind: QueryKindTrait<Value, OnEmpty>,
@@ -206,64 +222,57 @@ impl<Prefix, Value, QueryKind, OnEmpty> StorageValueMetadata
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
}
impl<Prefix, Value, QueryKind, OnEmpty>
crate::traits::StorageInfoTrait for
StorageValue<Prefix, Value, QueryKind, OnEmpty>
impl<Prefix, Value, QueryKind, OnEmpty> crate::traits::StorageInfoTrait
for StorageValue<Prefix, Value, QueryKind, OnEmpty>
where
Prefix: StorageInstance,
Value: FullCodec + MaxEncodedLen,
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static,
{
fn storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::hashed_key().to_vec(),
max_values: Some(1),
max_size: Some(
Value::max_encoded_len()
.saturated_into(),
),
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::hashed_key().to_vec(),
max_values: Some(1),
max_size: Some(Value::max_encoded_len().saturated_into()),
}]
}
}
/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
impl<Prefix, Value, QueryKind, OnEmpty>
crate::traits::PartialStorageInfoTrait for
StorageValue<Prefix, Value, QueryKind, OnEmpty>
impl<Prefix, Value, QueryKind, OnEmpty> crate::traits::PartialStorageInfoTrait
for StorageValue<Prefix, Value, QueryKind, OnEmpty>
where
Prefix: StorageInstance,
Value: FullCodec,
QueryKind: QueryKindTrait<Value, OnEmpty>,
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static,
{
fn partial_storage_info() -> Vec<StorageInfo> {
vec![
StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::hashed_key().to_vec(),
max_values: Some(1),
max_size: None,
}
]
vec![StorageInfo {
pallet_name: Self::module_prefix().to_vec(),
storage_name: Self::storage_prefix().to_vec(),
prefix: Self::hashed_key().to_vec(),
max_values: Some(1),
max_size: None,
}]
}
}
#[cfg(test)]
mod test {
use super::*;
use sp_io::{TestExternalities, hashing::twox_128};
use crate::storage::types::ValueQuery;
use frame_metadata::StorageEntryModifier;
use sp_io::{hashing::twox_128, TestExternalities};
struct Prefix;
impl StorageInstance for Prefix {
fn pallet_prefix() -> &'static str { "test" }
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "foo";
}
@@ -309,10 +318,16 @@ mod test {
assert_eq!(A::try_get(), Ok(4));
A::set(Some(4));
let _: Result<(), ()> = A::try_mutate(|v| { *v = Some(v.unwrap() * 2); Ok(()) });
let _: Result<(), ()> = A::try_mutate(|v| {
*v = Some(v.unwrap() * 2);
Ok(())
});
assert_eq!(A::try_get(), Ok(8));
let _: Result<(), ()> = A::try_mutate(|v| { *v = Some(v.unwrap() * 2); Err(()) });
let _: Result<(), ()> = A::try_mutate(|v| {
*v = Some(v.unwrap() * 2);
Err(())
});
assert_eq!(A::try_get(), Ok(8));
A::kill();
@@ -321,7 +336,8 @@ mod test {
AValueQueryWithAnOnEmpty::kill();
let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(|v| {
*v = *v * 2; Ok(())
*v = *v * 2;
Ok(())
});
assert_eq!(AValueQueryWithAnOnEmpty::try_get(), Ok(97 * 2));
@@ -17,8 +17,8 @@
//! Operation on unhashed runtime storage.
use codec::{Decode, Encode};
use sp_std::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> {
@@ -18,17 +18,16 @@
//! Traits, types and structs to support putting a bounded vector into storage, as a raw value, map
//! or a double map.
use sp_std::prelude::*;
use sp_std::{convert::TryFrom, fmt, marker::PhantomData};
use codec::{Encode, Decode, MaxEncodedLen};
use crate::{
storage::{StorageDecodeLength, StorageTryAppend},
traits::Get,
};
use codec::{Decode, Encode, MaxEncodedLen};
use core::{
ops::{Deref, Index, IndexMut},
slice::SliceIndex,
};
use crate::{
traits::Get,
storage::{StorageDecodeLength, StorageTryAppend},
};
use sp_std::{convert::TryFrom, fmt, marker::PhantomData, prelude::*};
/// A weakly bounded vector.
///
@@ -317,9 +316,9 @@ where
#[cfg(test)]
pub mod test {
use super::*;
use crate::Twox128;
use sp_io::TestExternalities;
use sp_std::convert::TryInto;
use crate::Twox128;
crate::parameter_types! {
pub const Seven: u32 = 7;