mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 09:57:56 +00:00
Allow to specify some max number of values for storages in pallet macro. (#8735)
* implement max_values + storages info * some formatting + doc * rename StoragesInfo -> PalletStorageInfo * merge both StorageInfoTrait and PalletStorageInfo I think it is more future proof. In the future some storage could make use of multiple prefix. Like one to store how much value has been inserted, etc... * Update frame/support/procedural/src/storage/parse.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * Update frame/support/procedural/src/storage/storage_struct.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * Fix max_size using hasher information hasher now expose `max_len` which allows to computes their maximum len. For hasher without concatenation, it is the size of the hash part, for hasher with concatenation, it is the size of the hash part + max encoded len of the key. * fix tests * fix ui tests Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
59f34ab8bc
commit
9bf62ef65d
@@ -27,9 +27,13 @@ mod tests {
|
||||
pub struct Module<T: Config> for enum Call where origin: T::Origin, system=frame_support_test {}
|
||||
}
|
||||
|
||||
pub trait Config: frame_support_test::Config {}
|
||||
pub trait Config: frame_support_test::Config {
|
||||
type Origin2: codec::Codec + codec::EncodeLike + Default
|
||||
+ frame_support::traits::MaxEncodedLen;
|
||||
}
|
||||
|
||||
frame_support::decl_storage! {
|
||||
generate_storage_info
|
||||
trait Store for Module<T: Config> as TestStorage {
|
||||
// non-getters: pub / $default
|
||||
|
||||
@@ -41,7 +45,7 @@ mod tests {
|
||||
|
||||
// getters: pub / $default
|
||||
// we need at least one type which uses T, otherwise GenesisConfig will complain.
|
||||
GETU32 get(fn u32_getter): T::Origin;
|
||||
GETU32 get(fn u32_getter): T::Origin2;
|
||||
pub PUBGETU32 get(fn pub_u32_getter): u32;
|
||||
GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32;
|
||||
pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32;
|
||||
@@ -56,23 +60,29 @@ mod tests {
|
||||
GetOptU32WithBuilderNone get(fn opt_u32_with_builder_none) build(|_| None): Option<u32>;
|
||||
|
||||
// map non-getters: pub / $default
|
||||
MAPU32: map hasher(blake2_128_concat) u32 => Option<String>;
|
||||
pub PUBMAPU32: map hasher(blake2_128_concat) u32 => Option<String>;
|
||||
MAPU32MYDEF: map hasher(blake2_128_concat) u32 => Option<String>;
|
||||
pub PUBMAPU32MYDEF: map hasher(blake2_128_concat) u32 => Option<String>;
|
||||
MAPU32 max_values(3): map hasher(blake2_128_concat) u32 => Option<[u8; 4]>;
|
||||
pub PUBMAPU32: map hasher(blake2_128_concat) u32 => Option<[u8; 4]>;
|
||||
|
||||
// map getters: pub / $default
|
||||
GETMAPU32 get(fn map_u32_getter): map hasher(blake2_128_concat) u32 => String;
|
||||
pub PUBGETMAPU32 get(fn pub_map_u32_getter): map hasher(blake2_128_concat) u32 => String;
|
||||
|
||||
GETMAPU32 get(fn map_u32_getter): map hasher(blake2_128_concat) u32 => [u8; 4];
|
||||
pub PUBGETMAPU32 get(fn pub_map_u32_getter): map hasher(blake2_128_concat) u32 => [u8; 4];
|
||||
GETMAPU32MYDEF get(fn map_u32_getter_mydef):
|
||||
map hasher(blake2_128_concat) u32 => String = "map".into();
|
||||
map hasher(blake2_128_concat) u32 => [u8; 4] = *b"mapd";
|
||||
pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef):
|
||||
map hasher(blake2_128_concat) u32 => String = "pubmap".into();
|
||||
map hasher(blake2_128_concat) u32 => [u8; 4] = *b"pubm";
|
||||
|
||||
COMPLEXTYPE1: ::std::vec::Vec<T::Origin>;
|
||||
COMPLEXTYPE2: (Vec<Vec<(u16, Box<()>)>>, u32);
|
||||
DOUBLEMAP max_values(3): double_map
|
||||
hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Option<[u8; 4]>;
|
||||
|
||||
DOUBLEMAP2: double_map
|
||||
hasher(blake2_128_concat) u32, hasher(blake2_128_concat) u32 => Option<[u8; 4]>;
|
||||
|
||||
COMPLEXTYPE1: (::std::option::Option<T::Origin2>,);
|
||||
COMPLEXTYPE2: ([[(u16, Option<()>); 32]; 12], u32);
|
||||
COMPLEXTYPE3: [u32; 25];
|
||||
|
||||
NMAP: nmap hasher(blake2_128_concat) u32, hasher(twox_64_concat) u16 => u8;
|
||||
NMAP2: nmap hasher(blake2_128_concat) u32 => u8;
|
||||
}
|
||||
add_extra_genesis {
|
||||
build(|_| {});
|
||||
@@ -88,7 +98,9 @@ mod tests {
|
||||
type DbWeight = ();
|
||||
}
|
||||
|
||||
impl Config for TraitImpl {}
|
||||
impl Config for TraitImpl {
|
||||
type Origin2 = u32;
|
||||
}
|
||||
|
||||
const EXPECTED_METADATA: StorageMetadata = StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("TestStorage"),
|
||||
@@ -133,7 +145,7 @@ mod tests {
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("GETU32"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("T::Origin")),
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("T::Origin2")),
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructGETU32(PhantomData::<TraitImpl>))
|
||||
),
|
||||
@@ -244,7 +256,7 @@ mod tests {
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -258,7 +270,7 @@ mod tests {
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -266,41 +278,13 @@ mod tests {
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("MAPU32MYDEF"),
|
||||
modifier: StorageEntryModifier::Optional,
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructMAPU32MYDEF(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("PUBMAPU32MYDEF"),
|
||||
modifier: StorageEntryModifier::Optional,
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructPUBMAPU32MYDEF(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("GETMAPU32"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -314,7 +298,7 @@ mod tests {
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -328,7 +312,7 @@ mod tests {
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -342,7 +326,7 @@ mod tests {
|
||||
ty: StorageEntryType::Map {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("String"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
unused: false,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
@@ -350,10 +334,40 @@ mod tests {
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("DOUBLEMAP"),
|
||||
modifier: StorageEntryModifier::Optional,
|
||||
ty: StorageEntryType::DoubleMap {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key1: DecodeDifferent::Encode("u32"),
|
||||
key2: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
key2_hasher: StorageHasher::Blake2_128Concat,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructDOUBLEMAP(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("DOUBLEMAP2"),
|
||||
modifier: StorageEntryModifier::Optional,
|
||||
ty: StorageEntryType::DoubleMap {
|
||||
hasher: StorageHasher::Blake2_128Concat,
|
||||
key1: DecodeDifferent::Encode("u32"),
|
||||
key2: DecodeDifferent::Encode("u32"),
|
||||
value: DecodeDifferent::Encode("[u8; 4]"),
|
||||
key2_hasher: StorageHasher::Blake2_128Concat,
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructDOUBLEMAP2(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("COMPLEXTYPE1"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("::std::vec::Vec<T::Origin>")),
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("(::std::option::Option<T::Origin2>,)")),
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructCOMPLEXTYPE1(PhantomData::<TraitImpl>))
|
||||
),
|
||||
@@ -362,7 +376,7 @@ mod tests {
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("COMPLEXTYPE2"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("(Vec<Vec<(u16, Box<()>)>>, u32)")),
|
||||
ty: StorageEntryType::Plain(DecodeDifferent::Encode("([[(u16, Option<()>); 32]; 12], u32)")),
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructCOMPLEXTYPE2(PhantomData::<TraitImpl>))
|
||||
),
|
||||
@@ -377,10 +391,201 @@ mod tests {
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("NMAP"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::NMap {
|
||||
keys: DecodeDifferent::Encode(&["u32", "u16"]),
|
||||
hashers: DecodeDifferent::Encode(&[StorageHasher::Blake2_128Concat, StorageHasher::Twox64Concat]),
|
||||
value: DecodeDifferent::Encode("u8"),
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructNMAP(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageEntryMetadata {
|
||||
name: DecodeDifferent::Encode("NMAP2"),
|
||||
modifier: StorageEntryModifier::Default,
|
||||
ty: StorageEntryType::NMap {
|
||||
keys: DecodeDifferent::Encode(&["u32"]),
|
||||
hashers: DecodeDifferent::Encode(&[StorageHasher::Blake2_128Concat]),
|
||||
value: DecodeDifferent::Encode("u8"),
|
||||
},
|
||||
default: DecodeDifferent::Encode(
|
||||
DefaultByteGetter(&__GetByteStructNMAP(PhantomData::<TraitImpl>))
|
||||
),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
]
|
||||
),
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn storage_info() {
|
||||
use frame_support::{
|
||||
StorageHasher,
|
||||
traits::{StorageInfoTrait, StorageInfo},
|
||||
pallet_prelude::*,
|
||||
};
|
||||
let prefix = |pallet_name, storage_name| {
|
||||
let mut res = [0u8; 32];
|
||||
res[0..16].copy_from_slice(&Twox128::hash(pallet_name));
|
||||
res[16..32].copy_from_slice(&Twox128::hash(storage_name));
|
||||
res
|
||||
};
|
||||
pretty_assertions::assert_eq!(
|
||||
<Module<TraitImpl>>::storage_info(),
|
||||
vec![
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"U32"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBU32"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"U32MYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBU32MYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETU32"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETU32"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETU32WITHCONFIG"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIG"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETU32MYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETU32MYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETU32WITHCONFIGMYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIGMYDEF"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETU32WITHCONFIGMYDEFOPT"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GetU32WithBuilder"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GetOptU32WithBuilderSome"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GetOptU32WithBuilderNone"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"MAPU32"),
|
||||
max_values: Some(3),
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBMAPU32"),
|
||||
max_values: None,
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETMAPU32"),
|
||||
max_values: None,
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETMAPU32"),
|
||||
max_values: None,
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"GETMAPU32MYDEF"),
|
||||
max_values: None,
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"PUBGETMAPU32MYDEF"),
|
||||
max_values: None,
|
||||
max_size: Some(8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"DOUBLEMAP"),
|
||||
max_values: Some(3),
|
||||
max_size: Some(12 + 16 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"DOUBLEMAP2"),
|
||||
max_values: None,
|
||||
max_size: Some(12 + 16 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"COMPLEXTYPE1"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(5),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"COMPLEXTYPE2"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(1156),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"COMPLEXTYPE3"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(100),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"NMAP"),
|
||||
max_values: None,
|
||||
max_size: Some(16 + 4 + 8 + 2 + 1),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"TestStorage", b"NMAP2"),
|
||||
max_values: None,
|
||||
max_size: Some(16 + 4 + 1),
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_metadata() {
|
||||
let metadata = Module::<TraitImpl>::storage_metadata();
|
||||
|
||||
@@ -19,6 +19,7 @@ use frame_support::{
|
||||
weights::{DispatchInfo, DispatchClass, Pays, GetDispatchInfo},
|
||||
traits::{
|
||||
GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade, GetPalletVersion, OnGenesis,
|
||||
MaxEncodedLen,
|
||||
},
|
||||
dispatch::{UnfilteredDispatchable, Parameter},
|
||||
storage::unhashed,
|
||||
@@ -47,10 +48,10 @@ impl From<SomeType6> for u64 { fn from(_t: SomeType6) -> Self { 0u64 } }
|
||||
pub struct SomeType7;
|
||||
impl From<SomeType7> for u64 { fn from(_t: SomeType7) -> Self { 0u64 } }
|
||||
|
||||
pub trait SomeAssociation1 { type _1: Parameter; }
|
||||
pub trait SomeAssociation1 { type _1: Parameter + MaxEncodedLen; }
|
||||
impl SomeAssociation1 for u64 { type _1 = u64; }
|
||||
|
||||
pub trait SomeAssociation2 { type _2: Parameter; }
|
||||
pub trait SomeAssociation2 { type _2: Parameter + MaxEncodedLen; }
|
||||
impl SomeAssociation2 for u64 { type _2 = u64; }
|
||||
|
||||
#[frame_support::pallet]
|
||||
@@ -100,6 +101,7 @@ pub mod pallet {
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(crate) trait Store)]
|
||||
#[pallet::generate_storage_info]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::hooks]
|
||||
@@ -209,13 +211,15 @@ pub mod pallet {
|
||||
StorageMap<_, Blake2_128Concat, u8, u16, ValueQuery, MyDefault<T>>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type Map2<T> = StorageMap<_, Twox64Concat, u16, u32>;
|
||||
pub type Map2<T> = StorageMap<_, Twox64Concat, u16, u32, OptionQuery, GetDefault, ConstU32<3>>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type DoubleMap<T> = StorageDoubleMap<_, Blake2_128Concat, u8, Twox64Concat, u16, u32>;
|
||||
|
||||
#[pallet::storage]
|
||||
pub type DoubleMap2<T> = StorageDoubleMap<_, Twox64Concat, u16, Blake2_128Concat, u32, u64>;
|
||||
pub type DoubleMap2<T> = StorageDoubleMap<
|
||||
_, Twox64Concat, u16, Blake2_128Concat, u32, u64, OptionQuery, GetDefault, ConstU32<5>,
|
||||
>;
|
||||
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn nmap)]
|
||||
@@ -230,6 +234,9 @@ pub mod pallet {
|
||||
NMapKey<Blake2_128Concat, u32>,
|
||||
),
|
||||
u64,
|
||||
OptionQuery,
|
||||
GetDefault,
|
||||
ConstU32<11>,
|
||||
>;
|
||||
|
||||
#[pallet::storage]
|
||||
@@ -240,7 +247,8 @@ pub mod pallet {
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn conditional_map)]
|
||||
pub type ConditionalMap<T> = StorageMap<_, Twox64Concat, u16, u32>;
|
||||
pub type ConditionalMap<T> =
|
||||
StorageMap<_, Twox64Concat, u16, u32, OptionQuery, GetDefault, ConstU32<12>>;
|
||||
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
#[pallet::storage]
|
||||
@@ -560,7 +568,7 @@ fn pallet_expand_deposit_event() {
|
||||
#[test]
|
||||
fn storage_expand() {
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_support::StoragePrefixedMap;
|
||||
use frame_support::storage::StoragePrefixedMap;
|
||||
|
||||
fn twox_64_concat(d: &[u8]) -> Vec<u8> {
|
||||
let mut v = twox_64(d).to_vec();
|
||||
@@ -966,3 +974,97 @@ fn test_pallet_info_access() {
|
||||
assert_eq!(<Example as frame_support::traits::PalletInfoAccess>::index(), 1);
|
||||
assert_eq!(<Example2 as frame_support::traits::PalletInfoAccess>::index(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_storage_info() {
|
||||
use frame_support::{
|
||||
StorageHasher,
|
||||
traits::{StorageInfoTrait, StorageInfo},
|
||||
pallet_prelude::*,
|
||||
};
|
||||
|
||||
let prefix = |pallet_name, storage_name| {
|
||||
let mut res = [0u8; 32];
|
||||
res[0..16].copy_from_slice(&Twox128::hash(pallet_name));
|
||||
res[16..32].copy_from_slice(&Twox128::hash(storage_name));
|
||||
res
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
Example::storage_info(),
|
||||
vec![
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"ValueWhereClause"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(8),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"Value"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"Map"),
|
||||
max_values: None,
|
||||
max_size: Some(3 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"Map2"),
|
||||
max_values: Some(3),
|
||||
max_size: Some(6 + 8),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"DoubleMap"),
|
||||
max_values: None,
|
||||
max_size: Some(7 + 16 + 8),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"DoubleMap2"),
|
||||
max_values: Some(5),
|
||||
max_size: Some(14 + 8 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"NMap"),
|
||||
max_values: None,
|
||||
max_size: Some(5 + 16),
|
||||
},
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"NMap2"),
|
||||
max_values: Some(11),
|
||||
max_size: Some(14 + 8 + 16),
|
||||
},
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
{
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"ConditionalValue"),
|
||||
max_values: Some(1),
|
||||
max_size: Some(4),
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
{
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"ConditionalMap"),
|
||||
max_values: Some(12),
|
||||
max_size: Some(6 + 8),
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
{
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"ConditionalDoubleMap"),
|
||||
max_values: None,
|
||||
max_size: Some(7 + 16 + 8),
|
||||
}
|
||||
},
|
||||
#[cfg(feature = "conditional-storage")]
|
||||
{
|
||||
StorageInfo {
|
||||
prefix: prefix(b"Example", b"ConditionalNMap"),
|
||||
max_values: None,
|
||||
max_size: Some(7 + 16 + 8),
|
||||
}
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ fn pallet_expand_deposit_event() {
|
||||
#[test]
|
||||
fn storage_expand() {
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_support::StoragePrefixedMap;
|
||||
use frame_support::storage::StoragePrefixedMap;
|
||||
|
||||
fn twox_64_concat(d: &[u8]) -> Vec<u8> {
|
||||
let mut v = twox_64(d).to_vec();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error: Invalid pallet::pallet, multiple argument pallet::generate_store found
|
||||
--> $DIR/duplicate_store_attr.rs:12:33
|
||||
error: Unexpected duplicated attribute
|
||||
--> $DIR/duplicate_store_attr.rs:12:12
|
||||
|
|
||||
12 | #[pallet::generate_store(trait Store)]
|
||||
| ^^^^^
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#[frame_support::pallet]
|
||||
mod pallet {
|
||||
use frame_support::pallet_prelude::{Hooks, StorageValue};
|
||||
use frame_system::pallet_prelude::BlockNumberFor;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_storage_info]
|
||||
pub struct Pallet<T>(core::marker::PhantomData<T>);
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {}
|
||||
|
||||
#[derive(codec::Encode, codec::Decode)]
|
||||
struct Bar;
|
||||
|
||||
#[pallet::storage]
|
||||
type Foo<T> = StorageValue<_, Bar>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
|
||||
--> $DIR/storage_info_unsatisfied.rs:10:12
|
||||
|
|
||||
10 | #[pallet::generate_storage_info]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `MaxEncodedLen` is not implemented for `Bar`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageValue<_GeneratedPrefixForStorageFoo<T>, Bar>`
|
||||
= note: required by `storage_info`
|
||||
@@ -0,0 +1,27 @@
|
||||
#[frame_support::pallet]
|
||||
mod pallet {
|
||||
use frame_support::pallet_prelude::{Hooks, StorageNMap, Twox64Concat, NMapKey};
|
||||
use frame_system::pallet_prelude::BlockNumberFor;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {}
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_storage_info]
|
||||
pub struct Pallet<T>(core::marker::PhantomData<T>);
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {}
|
||||
|
||||
#[derive(codec::Encode, codec::Decode)]
|
||||
struct Bar;
|
||||
|
||||
#[pallet::storage]
|
||||
type Foo<T> = StorageNMap<_, NMapKey<Twox64Concat, Bar>, u32>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
|
||||
--> $DIR/storage_info_unsatisfied_nmap.rs:10:12
|
||||
|
|
||||
10 | #[pallet::generate_storage_info]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `MaxEncodedLen` is not implemented for `Bar`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `KeyGeneratorMaxEncodedLen` for `NMapKey<frame_support::Twox64Concat, Bar>`
|
||||
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, NMapKey<frame_support::Twox64Concat, Bar>, u32>`
|
||||
= note: required by `storage_info`
|
||||
Reference in New Issue
Block a user