mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 20:27:58 +00:00
Enrich metadata with type information (#8615)
* Cargo.lock after merge * Restore scale-info feature * Fully qualify TypeInfo derive * Skip PendingSwap T * Add missing skip_type_params attr * metadata docs features * Reduce pallet event attribute to struct * Cargo.lock * Update frame/balances/src/tests_composite.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Line widths check * Cargo.lock * Add scale-info/std * Update frame/system/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Use `skip_type_params` to remove `TypeInfo` requirements on checks * Revert "Remove unused Call metadata stuff" This reverts commit 41311f85 * Skip BalanceSwapAction type parameter * Remove unused event metadata macro * Update frame-metadata * Update primitives/npos-elections/compact/src/codec.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Manual TypeInfo for Header * Remove TypeInfo requirement for consts in BoundedVec etc. * Another TypeInfo bound removed * review: fix indentation * TypeInfo impls for Identity types * Add some todos to add custom TypeInfo impls * Update frame/support/procedural/src/pallet/expand/pallet_struct.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Add some todos to add custom TypeInfo impls * Add a test for manual Data TypeInfo impl * Add custom TypeInfo impl for Vote * Era custom TypeInfo crimes * Revert finality-grandpa version to 0.14.z * review: renamed module to pallet_constants_metadata * New line at end of file * Add missing scale-info/std * Update frame/support/src/storage/types/mod.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Remove StorageEntryType::Map unused flag * Add missing scale-info dependency after merge * SignedExtension::AdditionalSigned metadata * Update frame-metadata, use abbreviated docs and args fields * Update frame/example/Cargo.toml Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Add scale_info/std and remove unused scale-info dependency * Remove scale-info dependency * Remove treasury pallet::metadata * Remove redundant Event test * Add back scale-info as dev dependency * fix error metadata when no error defined in decl_module * Add Module3 to tests * Fix metadata test * Add docs feature to frame-support test * WIP fixing pallet metadata test * Remove redundant FunctionMetadata, FunctionArgumentMetadata as per https://github.com/paritytech/frame-metadata/pull/20 * Use main branch of frame-metadata * Use patch of scale-info for latest changes * Use latest patched scale-info * Manual TypeInfo for DigestItem * Manual TypeInfo for DigestItem * Update scale-info * Skip __Ignore variants for Error, depends on https://github.com/paritytech/scale-info/pull/117 * Named fields for FRAME v2 pallet Call variants * Named fields for FRAME v1 pallet Call variants * Add missing scale-info dependency * WIP expand benchmark call variant * fix benchmark with new function create a new function for each variant of a pallet call. This function is called by benchmarking macro in order not to break call creation with unnamed argument * fix tests * more fix * Fix staking tests * Fix offchain workers calls * Cherry pick rustfmt.toml from master * cargo +nightly-2021-06-22 fmt --all * Update to new call variant structs * More call variant struct updates * Remove unused import * More call variant structs * More call variant structs * Even more call variant structs * Mooar variant structs * Evermore variant structs * Call variant structs ad infinitum * Fmt * More call variants * Last call variant * Call variants all done? * Fix SS58Prefix type * Potential workaround for BitFlags<IdentityFields> TypeInfo * Enable docs capturing for Call, Event, and Error types * Fix IdentityFields TypeInfo * Remove metadata-docs feature * Add capture_docs = true for legacy Call, Event and Error types * Fmt * Fix metadata test type * Update benchmarks with call struct variants * Fmt * More test fixes * Fmt * Fix benches * Use latest capture_docs attr * Latest scale_info * Fmt * review: change &Vec to &[] * Remove pallet metadata attr * review: remove commented out test code * review: skip_type_params trailing comma suggestion * Update to scale-info 0.10.0 * Update construct_runtime ui tests, different because of metadata TypeInfo impls * Add some TypeInfo derives for UI tests * Update storage ensure span ui stderrs * Update call argument bound ui tests Possibly changed because change from tuple to struct variants? * Add scale-info dev dependency * Update to latest finality-grandpa release * review: missing newline * review: missing scale-info/std * review: remove duplicate scale-info/std * review: remove fully qualified TypeInfo * review: add missing scale-info/std * review: remove unnecessary imports. * Fmt * Use crates.io RC version of frame-metadata * Remove scale-info/std because it is a dev dependency * Add missing scale_info dev-dependency for test * Delete empty metadata folder * Fix sp_std import * review: improve manual UncheckedExtrinsic TypeInfo impl * review: use full scale-info for dev-dependency * Remove DefaultByteGetter impl * review: derive TypeInfo for generic header * Fmt * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update bin/node/executor/Cargo.toml Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/identity/src/types.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/support/src/dispatch.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Remove redundant derive * Simplify scale-info dependency * Strip underscore prefix from call variant struct names * Another underscore field * More underscore fields * Another underscore field * Update to frame-metadata 14.0.0-rc.2 with combined StorageEntryType::Map * Fmt * Revert weights formatting * Fix up some tests * Fix up some tests for StorageEntryTypeMetadata * scale-info dev dependency * Fix test error * Add missing TypeInfo derives * Add back missing scale-info dependency * Add back missing scale-info dependency * Fix npos compact impls * Cargo.lock * Fmt * Fix errors * Fmt * Fix renamed raw_solution field * Fix error * Fmt * Fix some benchmarks * Fmt * Stray R * Fix * Add missing TypeInfos * ui test fix * Fix line widths * Revert "ui test fix" This reverts commit 2d15ec058a216e3f92d713f1174603a2bb1eac65. * Upgrade to scale-info 0.11.0 * Revert "Upgrade to scale-info 0.11.0" This reverts commit 047bb179085a0059c36cd20ab405f55cf0867e28. * Add Runtime type * Update to scale-info 0.12 * Update to scale-info 1.0 * Update frame-metadata to version 14.0.0 * Patch finality-grandpa until release available * Fix metadata tests * Fix metadata tests * Fmt * Remove patched finality-grandpa * Fix tests, use scale_info imports * Fix pallet tests * Add BlockNumber TypeInfo bound * ui test fix * Cargo.lock * Remove pallet metadata * Cargo.lock * Add missing scale-info dependency * Remove pallet event metadata * Fix error * Fix collective errors * Semicolol * Fmt * Remove another metadata attribute * Add new variant to custom digest TypeInfo * Fmt * Cargo.lock from master * Remove comma lol * Fix example call error * Fix example call error properly Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -31,7 +31,8 @@ use sp_std::{
|
||||
///
|
||||
/// Unlike a standard `BTreeMap`, there is an enforced upper limit to the number of items in the
|
||||
/// map. All internal operations ensure this bound is respected.
|
||||
#[derive(Encode)]
|
||||
#[derive(Encode, scale_info::TypeInfo)]
|
||||
#[scale_info(skip_type_params(S))]
|
||||
pub struct BoundedBTreeMap<K, V, S>(BTreeMap<K, V>, PhantomData<S>);
|
||||
|
||||
impl<K, V, S> Decode for BoundedBTreeMap<K, V, S>
|
||||
|
||||
@@ -37,7 +37,8 @@ use sp_std::{convert::TryFrom, fmt, marker::PhantomData, prelude::*};
|
||||
///
|
||||
/// As the name suggests, the length of the queue is always bounded. All internal operations ensure
|
||||
/// this bound is respected.
|
||||
#[derive(Encode)]
|
||||
#[derive(Encode, scale_info::TypeInfo)]
|
||||
#[scale_info(skip_type_params(S))]
|
||||
pub struct BoundedVec<T, S>(Vec<T>, PhantomData<S>);
|
||||
|
||||
/// A bounded slice.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
//! Stuff to do with the runtime's storage.
|
||||
|
||||
pub use self::types::StorageEntryMetadata;
|
||||
use crate::{
|
||||
hash::{ReversibleStorageHasher, StorageHasher},
|
||||
storage::types::{
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
//! StoragePrefixedDoubleMap traits and their methods directly.
|
||||
|
||||
use crate::{
|
||||
metadata::{StorageEntryModifier, StorageEntryType},
|
||||
storage::{
|
||||
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
|
||||
types::{OptionQuery, QueryKindTrait, StorageEntryMetadata},
|
||||
StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
|
||||
},
|
||||
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::*;
|
||||
|
||||
@@ -511,37 +511,34 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Part of storage metadata for a storage double map.
|
||||
///
|
||||
/// NOTE: Generic hashers is supported.
|
||||
pub trait StorageDoubleMapMetadata {
|
||||
const MODIFIER: StorageEntryModifier;
|
||||
const NAME: &'static str;
|
||||
const DEFAULT: DefaultByteGetter;
|
||||
const HASHER1: frame_metadata::StorageHasher;
|
||||
const HASHER2: frame_metadata::StorageHasher;
|
||||
}
|
||||
|
||||
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
|
||||
StorageDoubleMapMetadata
|
||||
StorageEntryMetadata
|
||||
for StorageDoubleMap<Prefix, Hasher1, Key1, Hasher2, Key2, Value, QueryKind, OnEmpty, MaxValues>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
Hasher1: crate::hash::StorageHasher,
|
||||
Hasher2: crate::hash::StorageHasher,
|
||||
Key1: FullCodec,
|
||||
Key2: FullCodec,
|
||||
Value: FullCodec,
|
||||
Key1: FullCodec + scale_info::StaticTypeInfo,
|
||||
Key2: FullCodec + scale_info::StaticTypeInfo,
|
||||
Value: FullCodec + scale_info::StaticTypeInfo,
|
||||
QueryKind: QueryKindTrait<Value, OnEmpty>,
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
const MODIFIER: StorageEntryModifier = QueryKind::METADATA;
|
||||
const HASHER1: frame_metadata::StorageHasher = Hasher1::METADATA;
|
||||
const HASHER2: frame_metadata::StorageHasher = Hasher2::METADATA;
|
||||
const NAME: &'static str = Prefix::STORAGE_PREFIX;
|
||||
const DEFAULT: DefaultByteGetter =
|
||||
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
|
||||
|
||||
fn ty() -> StorageEntryType {
|
||||
StorageEntryType::Map {
|
||||
hashers: vec![Hasher1::METADATA, Hasher2::METADATA],
|
||||
key: scale_info::meta_type::<(Key1, Key2)>(),
|
||||
value: scale_info::meta_type::<Value>(),
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Vec<u8> {
|
||||
OnEmpty::get().encode()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Hasher1, Hasher2, Key1, Key2, Value, QueryKind, OnEmpty, MaxValues>
|
||||
@@ -603,8 +600,12 @@ where
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{hash::*, storage::types::ValueQuery};
|
||||
use frame_metadata::StorageEntryModifier;
|
||||
use crate::{
|
||||
hash::*,
|
||||
metadata::{StorageEntryModifier, StorageEntryType, StorageHasher},
|
||||
storage::types::ValueQuery,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use sp_io::{hashing::twox_128, TestExternalities};
|
||||
|
||||
struct Prefix;
|
||||
@@ -768,19 +769,27 @@ mod test {
|
||||
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::HASHER1, frame_metadata::StorageHasher::Blake2_128Concat);
|
||||
assert_eq!(A::HASHER2, frame_metadata::StorageHasher::Twox64Concat);
|
||||
assert_eq!(
|
||||
AValueQueryWithAnOnEmpty::HASHER1,
|
||||
frame_metadata::StorageHasher::Blake2_128Concat
|
||||
|
||||
let assert_map_hashers = |ty, expected_hashers| {
|
||||
if let StorageEntryType::Map { hashers, .. } = ty {
|
||||
assert_eq!(hashers, expected_hashers)
|
||||
} else {
|
||||
assert_matches!(ty, StorageEntryType::Map { .. })
|
||||
}
|
||||
};
|
||||
|
||||
assert_map_hashers(
|
||||
A::ty(),
|
||||
vec![StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat],
|
||||
);
|
||||
assert_eq!(
|
||||
AValueQueryWithAnOnEmpty::HASHER2,
|
||||
frame_metadata::StorageHasher::Twox64Concat
|
||||
assert_map_hashers(
|
||||
AValueQueryWithAnOnEmpty::ty(),
|
||||
vec![StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat],
|
||||
);
|
||||
|
||||
assert_eq!(A::NAME, "foo");
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 97u32.encode());
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 97u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
|
||||
WithLen::remove_all(None);
|
||||
assert_eq!(WithLen::decode_len(3, 30), None);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
use crate::hash::{ReversibleStorageHasher, StorageHasher};
|
||||
use codec::{Encode, EncodeLike, FullCodec, MaxEncodedLen};
|
||||
use paste::paste;
|
||||
use scale_info::StaticTypeInfo;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
/// A type used exclusively by storage maps as their key type.
|
||||
@@ -35,14 +36,14 @@ pub struct Key<Hasher, KeyType>(core::marker::PhantomData<(Hasher, KeyType)>);
|
||||
|
||||
/// A trait that contains the current key as an associated type.
|
||||
pub trait KeyGenerator {
|
||||
type Key: EncodeLike<Self::Key>;
|
||||
type Key: EncodeLike<Self::Key> + StaticTypeInfo;
|
||||
type KArg: Encode;
|
||||
type HashFn: FnOnce(&[u8]) -> Vec<u8>;
|
||||
type HArg;
|
||||
|
||||
const HASHER_METADATA: &'static [frame_metadata::StorageHasher];
|
||||
const HASHER_METADATA: &'static [crate::metadata::StorageHasher];
|
||||
|
||||
/// Given a `key` tuple, calculate the final key by encoding each element individuallly and
|
||||
/// Given a `key` tuple, calculate the final key by encoding each element individually and
|
||||
/// hashing them using the corresponding hasher in the `KeyGenerator`.
|
||||
fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8>;
|
||||
/// Given a `key` tuple, migrate the keys from using the old hashers as given by `hash_fns`
|
||||
@@ -67,13 +68,13 @@ pub trait KeyGeneratorInner: KeyGenerator {
|
||||
fn final_hash(encoded: &[u8]) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl<H: StorageHasher, K: FullCodec> KeyGenerator for Key<H, K> {
|
||||
impl<H: StorageHasher, K: FullCodec + StaticTypeInfo> KeyGenerator for Key<H, K> {
|
||||
type Key = K;
|
||||
type KArg = (K,);
|
||||
type HashFn = Box<dyn FnOnce(&[u8]) -> Vec<u8>>;
|
||||
type HArg = (Self::HashFn,);
|
||||
|
||||
const HASHER_METADATA: &'static [frame_metadata::StorageHasher] = &[H::METADATA];
|
||||
const HASHER_METADATA: &'static [crate::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!"))
|
||||
@@ -89,13 +90,15 @@ impl<H: StorageHasher, K: FullCodec> KeyGenerator for Key<H, K> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: StorageHasher, K: FullCodec + MaxEncodedLen> KeyGeneratorMaxEncodedLen for Key<H, K> {
|
||||
impl<H: StorageHasher, K: FullCodec + MaxEncodedLen + StaticTypeInfo> KeyGeneratorMaxEncodedLen
|
||||
for Key<H, K>
|
||||
{
|
||||
fn key_max_encoded_len() -> usize {
|
||||
H::max_len::<K>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: StorageHasher, K: FullCodec> KeyGeneratorInner for Key<H, K> {
|
||||
impl<H: StorageHasher, K: FullCodec + StaticTypeInfo> KeyGeneratorInner for Key<H, K> {
|
||||
type Hasher = H;
|
||||
|
||||
fn final_hash(encoded: &[u8]) -> Vec<u8> {
|
||||
@@ -111,7 +114,7 @@ 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] =
|
||||
const HASHER_METADATA: &'static [crate::metadata::StorageHasher] =
|
||||
&[for_tuples!( #(Tuple::Hasher::METADATA),* )];
|
||||
|
||||
fn final_key<KArg: EncodeLikeTuple<Self::KArg> + TupleToEncodedIter>(key: KArg) -> Vec<u8> {
|
||||
@@ -218,7 +221,9 @@ pub trait ReversibleKeyGenerator: KeyGenerator {
|
||||
fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error>;
|
||||
}
|
||||
|
||||
impl<H: ReversibleStorageHasher, K: FullCodec> ReversibleKeyGenerator for Key<H, K> {
|
||||
impl<H: ReversibleStorageHasher, K: FullCodec + StaticTypeInfo> ReversibleKeyGenerator
|
||||
for Key<H, K>
|
||||
{
|
||||
type ReversibleHasher = H;
|
||||
|
||||
fn decode_final_key(key_material: &[u8]) -> Result<(Self::Key, &[u8]), codec::Error> {
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
//! methods directly.
|
||||
|
||||
use crate::{
|
||||
metadata::{StorageEntryModifier, StorageEntryType},
|
||||
storage::{
|
||||
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
|
||||
types::{OptionQuery, QueryKindTrait, StorageEntryMetadata},
|
||||
StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
|
||||
},
|
||||
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::*;
|
||||
|
||||
@@ -336,32 +336,31 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Part of storage metadata for a storage map.
|
||||
///
|
||||
/// NOTE: Generic hasher is supported.
|
||||
pub trait StorageMapMetadata {
|
||||
const MODIFIER: StorageEntryModifier;
|
||||
const NAME: &'static str;
|
||||
const DEFAULT: DefaultByteGetter;
|
||||
const HASHER: frame_metadata::StorageHasher;
|
||||
}
|
||||
|
||||
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageMapMetadata
|
||||
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadata
|
||||
for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
Hasher: crate::hash::StorageHasher,
|
||||
Key: FullCodec,
|
||||
Value: FullCodec,
|
||||
Key: FullCodec + scale_info::StaticTypeInfo,
|
||||
Value: FullCodec + scale_info::StaticTypeInfo,
|
||||
QueryKind: QueryKindTrait<Value, OnEmpty>,
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
const MODIFIER: StorageEntryModifier = QueryKind::METADATA;
|
||||
const HASHER: frame_metadata::StorageHasher = Hasher::METADATA;
|
||||
const NAME: &'static str = Prefix::STORAGE_PREFIX;
|
||||
const DEFAULT: DefaultByteGetter =
|
||||
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
|
||||
|
||||
fn ty() -> StorageEntryType {
|
||||
StorageEntryType::Map {
|
||||
hashers: vec![Hasher::METADATA],
|
||||
key: scale_info::meta_type::<Key>(),
|
||||
value: scale_info::meta_type::<Value>(),
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Vec<u8> {
|
||||
OnEmpty::get().encode()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
|
||||
@@ -417,8 +416,12 @@ where
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{hash::*, storage::types::ValueQuery};
|
||||
use frame_metadata::StorageEntryModifier;
|
||||
use crate::{
|
||||
hash::*,
|
||||
metadata::{StorageEntryModifier, StorageEntryType, StorageHasher},
|
||||
storage::types::ValueQuery,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use sp_io::{hashing::twox_128, TestExternalities};
|
||||
|
||||
struct Prefix;
|
||||
@@ -572,14 +575,23 @@ mod test {
|
||||
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::HASHER, frame_metadata::StorageHasher::Blake2_128Concat);
|
||||
assert_eq!(
|
||||
AValueQueryWithAnOnEmpty::HASHER,
|
||||
frame_metadata::StorageHasher::Blake2_128Concat
|
||||
|
||||
let assert_map_hashers = |ty, expected_hashers| {
|
||||
if let StorageEntryType::Map { hashers, .. } = ty {
|
||||
assert_eq!(hashers, expected_hashers)
|
||||
} else {
|
||||
assert_matches!(ty, StorageEntryType::Map { .. })
|
||||
}
|
||||
};
|
||||
|
||||
assert_map_hashers(A::ty(), vec![StorageHasher::Blake2_128Concat]);
|
||||
assert_map_hashers(
|
||||
AValueQueryWithAnOnEmpty::ty(),
|
||||
vec![StorageHasher::Blake2_128Concat],
|
||||
);
|
||||
assert_eq!(A::NAME, "foo");
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 97u32.encode());
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 97u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
|
||||
WithLen::remove_all(None);
|
||||
assert_eq!(WithLen::decode_len(3), None);
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
//! Storage types to build abstraction on storage, they implements storage traits such as
|
||||
//! StorageMap and others.
|
||||
|
||||
use crate::metadata::{StorageEntryModifier, StorageEntryType};
|
||||
use codec::FullCodec;
|
||||
use frame_metadata::{DefaultByte, StorageEntryModifier};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
mod double_map;
|
||||
mod key;
|
||||
@@ -27,14 +28,14 @@ mod map;
|
||||
mod nmap;
|
||||
mod value;
|
||||
|
||||
pub use double_map::{StorageDoubleMap, StorageDoubleMapMetadata};
|
||||
pub use double_map::StorageDoubleMap;
|
||||
pub use key::{
|
||||
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, Key, KeyGenerator,
|
||||
KeyGeneratorMaxEncodedLen, ReversibleKeyGenerator, TupleToEncodedIter,
|
||||
};
|
||||
pub use map::{StorageMap, StorageMapMetadata};
|
||||
pub use nmap::{StorageNMap, StorageNMapMetadata};
|
||||
pub use value::{StorageValue, StorageValueMetadata};
|
||||
pub use map::StorageMap;
|
||||
pub use nmap::StorageNMap;
|
||||
pub use value::StorageValue;
|
||||
|
||||
/// Trait implementing how the storage optional value is converted into the queried type.
|
||||
///
|
||||
@@ -102,14 +103,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper struct which implements DefaultByte using `Get<Value>` and encode it.
|
||||
struct OnEmptyGetter<Value, OnEmpty>(core::marker::PhantomData<(Value, OnEmpty)>);
|
||||
impl<Value: FullCodec, OnEmpty: crate::traits::Get<Value>> DefaultByte
|
||||
for OnEmptyGetter<Value, OnEmpty>
|
||||
{
|
||||
fn default_byte(&self) -> sp_std::vec::Vec<u8> {
|
||||
OnEmpty::get().encode()
|
||||
}
|
||||
/// Provide metadata for a storage entry.
|
||||
///
|
||||
/// Implemented by each of the storage entry kinds: value, map, doublemap and nmap.
|
||||
pub trait StorageEntryMetadata {
|
||||
const MODIFIER: StorageEntryModifier;
|
||||
const NAME: &'static str;
|
||||
|
||||
fn ty() -> StorageEntryType;
|
||||
fn default() -> Vec<u8>;
|
||||
}
|
||||
unsafe impl<Value, OnEmpty: crate::traits::Get<Value>> Send for OnEmptyGetter<Value, OnEmpty> {}
|
||||
unsafe impl<Value, OnEmpty: crate::traits::Get<Value>> Sync for OnEmptyGetter<Value, OnEmpty> {}
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
//! StoragePrefixedDoubleMap traits and their methods directly.
|
||||
|
||||
use crate::{
|
||||
metadata::{StorageEntryModifier, StorageEntryType},
|
||||
storage::{
|
||||
types::{
|
||||
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OnEmptyGetter, OptionQuery,
|
||||
QueryKindTrait, TupleToEncodedIter,
|
||||
EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OptionQuery, QueryKindTrait,
|
||||
StorageEntryMetadata, TupleToEncodedIter,
|
||||
},
|
||||
KeyGenerator, PrefixIterator, StorageAppend, StorageDecodeLength, StoragePrefixedMap,
|
||||
},
|
||||
traits::{Get, GetDefault, StorageInfo, StorageInstance},
|
||||
};
|
||||
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
|
||||
use frame_metadata::{DefaultByteGetter, StorageEntryModifier};
|
||||
use sp_runtime::SaturatedConversion;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
@@ -440,31 +440,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Part of storage metadata for a storage n map.
|
||||
///
|
||||
/// NOTE: Generic hashers is supported.
|
||||
pub trait StorageNMapMetadata {
|
||||
const MODIFIER: StorageEntryModifier;
|
||||
const NAME: &'static str;
|
||||
const DEFAULT: DefaultByteGetter;
|
||||
const HASHERS: &'static [frame_metadata::StorageHasher];
|
||||
}
|
||||
|
||||
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> StorageNMapMetadata
|
||||
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadata
|
||||
for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
Key: super::key::KeyGenerator,
|
||||
Value: FullCodec,
|
||||
Value: FullCodec + scale_info::StaticTypeInfo,
|
||||
QueryKind: QueryKindTrait<Value, OnEmpty>,
|
||||
OnEmpty: Get<QueryKind::Query> + 'static,
|
||||
MaxValues: Get<Option<u32>>,
|
||||
{
|
||||
const MODIFIER: StorageEntryModifier = QueryKind::METADATA;
|
||||
const NAME: &'static str = Prefix::STORAGE_PREFIX;
|
||||
const DEFAULT: DefaultByteGetter =
|
||||
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
|
||||
const HASHERS: &'static [frame_metadata::StorageHasher] = Key::HASHER_METADATA;
|
||||
|
||||
fn ty() -> StorageEntryType {
|
||||
StorageEntryType::Map {
|
||||
key: scale_info::meta_type::<Key::Key>(),
|
||||
hashers: Key::HASHER_METADATA.iter().cloned().collect(),
|
||||
value: scale_info::meta_type::<Value>(),
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Vec<u8> {
|
||||
OnEmpty::get().encode()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
|
||||
@@ -518,9 +517,9 @@ mod test {
|
||||
use super::*;
|
||||
use crate::{
|
||||
hash::*,
|
||||
metadata::StorageEntryModifier,
|
||||
storage::types::{Key, ValueQuery},
|
||||
};
|
||||
use frame_metadata::StorageEntryModifier;
|
||||
use sp_io::{hashing::twox_128, TestExternalities};
|
||||
|
||||
struct Prefix;
|
||||
@@ -688,8 +687,8 @@ mod test {
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::NAME, "Foo");
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 98u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
|
||||
WithLen::remove_all(None);
|
||||
assert_eq!(WithLen::decode_len((3,)), None);
|
||||
@@ -856,8 +855,8 @@ mod test {
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::NAME, "Foo");
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 98u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
|
||||
WithLen::remove_all(None);
|
||||
assert_eq!(WithLen::decode_len((3, 30)), None);
|
||||
@@ -1046,8 +1045,8 @@ mod test {
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::NAME, "Foo");
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 98u32.encode());
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 98u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
|
||||
WithLen::remove_all(None);
|
||||
assert_eq!(WithLen::decode_len((3, 30, 300)), None);
|
||||
|
||||
@@ -18,15 +18,15 @@
|
||||
//! Storage value type. Implements StorageValue trait and its method directly.
|
||||
|
||||
use crate::{
|
||||
metadata::{StorageEntryModifier, StorageEntryType},
|
||||
storage::{
|
||||
generator::StorageValue as StorageValueT,
|
||||
types::{OnEmptyGetter, OptionQuery, QueryKindTrait},
|
||||
types::{OptionQuery, QueryKindTrait, StorageEntryMetadata},
|
||||
StorageAppend, StorageDecodeLength, StorageTryAppend,
|
||||
},
|
||||
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::*;
|
||||
|
||||
@@ -201,25 +201,24 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Part of storage metadata for storage value.
|
||||
pub trait StorageValueMetadata {
|
||||
const MODIFIER: StorageEntryModifier;
|
||||
const NAME: &'static str;
|
||||
const DEFAULT: DefaultByteGetter;
|
||||
}
|
||||
|
||||
impl<Prefix, Value, QueryKind, OnEmpty> StorageValueMetadata
|
||||
impl<Prefix, Value, QueryKind, OnEmpty> StorageEntryMetadata
|
||||
for StorageValue<Prefix, Value, QueryKind, OnEmpty>
|
||||
where
|
||||
Prefix: StorageInstance,
|
||||
Value: FullCodec,
|
||||
Value: FullCodec + scale_info::StaticTypeInfo,
|
||||
QueryKind: QueryKindTrait<Value, OnEmpty>,
|
||||
OnEmpty: crate::traits::Get<QueryKind::Query> + 'static,
|
||||
{
|
||||
const MODIFIER: StorageEntryModifier = QueryKind::METADATA;
|
||||
const NAME: &'static str = Prefix::STORAGE_PREFIX;
|
||||
const DEFAULT: DefaultByteGetter =
|
||||
DefaultByteGetter(&OnEmptyGetter::<QueryKind::Query, OnEmpty>(core::marker::PhantomData));
|
||||
|
||||
fn ty() -> StorageEntryType {
|
||||
StorageEntryType::Plain(scale_info::meta_type::<Value>())
|
||||
}
|
||||
|
||||
fn default() -> Vec<u8> {
|
||||
OnEmpty::get().encode()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Prefix, Value, QueryKind, OnEmpty> crate::traits::StorageInfoTrait
|
||||
@@ -264,8 +263,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::storage::types::ValueQuery;
|
||||
use frame_metadata::StorageEntryModifier;
|
||||
use crate::{metadata::StorageEntryModifier, storage::types::ValueQuery};
|
||||
use sp_io::{hashing::twox_128, TestExternalities};
|
||||
|
||||
struct Prefix;
|
||||
@@ -347,8 +345,8 @@ mod test {
|
||||
assert_eq!(A::MODIFIER, StorageEntryModifier::Optional);
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::MODIFIER, StorageEntryModifier::Default);
|
||||
assert_eq!(A::NAME, "foo");
|
||||
assert_eq!(A::DEFAULT.0.default_byte(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::DEFAULT.0.default_byte(), 97u32.encode());
|
||||
assert_eq!(A::default(), Option::<u32>::None.encode());
|
||||
assert_eq!(AValueQueryWithAnOnEmpty::default(), 97u32.encode());
|
||||
|
||||
WithLen::kill();
|
||||
assert_eq!(WithLen::decode_len(), None);
|
||||
|
||||
@@ -36,7 +36,8 @@ use sp_std::{convert::TryFrom, fmt, marker::PhantomData, prelude::*};
|
||||
///
|
||||
/// The length of the vec is not strictly bounded. Decoding a vec with more element that the bound
|
||||
/// is accepted, and some method allow to bypass the restriction with warnings.
|
||||
#[derive(Encode)]
|
||||
#[derive(Encode, scale_info::TypeInfo)]
|
||||
#[scale_info(skip_type_params(S))]
|
||||
pub struct WeakBoundedVec<T, S>(Vec<T>, PhantomData<S>);
|
||||
|
||||
impl<T: Decode, S: Get<u32>> Decode for WeakBoundedVec<T, S> {
|
||||
|
||||
Reference in New Issue
Block a user