Allow renaming storage item prefixes (#9016)

* Implement parsing for #[pallet::storage_name] on storage items

* Rename storage prefix when a #[pallet::storage_name] is supplied

* Fix test_storage_info

* Rename storage_name to storage_prefix

* Check for duplicates when renaming storage prefixes

* Allow only string literals for storage_prefix renames

* Use proper spans for attribute errors

* Check for valid identifiers when parsing storage prefix renames
This commit is contained in:
Keith Yeung
2021-06-14 03:07:09 -07:00
committed by GitHub
parent 0975a92818
commit c2f13a03a8
13 changed files with 288 additions and 20 deletions
@@ -198,6 +198,10 @@ pub mod pallet {
#[pallet::storage]
pub type Value<T> = StorageValue<Value = u32>;
#[pallet::storage]
#[pallet::storage_prefix = "Value2"]
pub type RenamedValue<T> = StorageValue<Value = u64>;
#[pallet::type_value]
pub fn MyDefault<T: Config>() -> u16
where T::AccountId: From<SomeType7> + From<SomeType1> + SomeAssociation1
@@ -577,6 +581,10 @@ fn storage_expand() {
let k = [twox_128(b"Example"), twox_128(b"Value")].concat();
assert_eq!(unhashed::get::<u32>(&k), Some(1u32));
pallet::RenamedValue::<Runtime>::put(2);
let k = [twox_128(b"Example"), twox_128(b"Value2")].concat();
assert_eq!(unhashed::get::<u64>(&k), Some(2));
pallet::Map::<Runtime>::insert(1, 2);
let mut k = [twox_128(b"Example"), twox_128(b"Map")].concat();
k.extend(1u8.using_encoded(blake2_128_concat));
@@ -697,6 +705,13 @@ fn metadata() {
default: DecodeDifferent::Decoded(vec![0]),
documentation: DecodeDifferent::Decoded(vec![]),
},
StorageEntryMetadata {
name: DecodeDifferent::Decoded("Value2".to_string()),
modifier: StorageEntryModifier::Optional,
ty: StorageEntryType::Plain(DecodeDifferent::Decoded("u64".to_string())),
default: DecodeDifferent::Decoded(vec![0]),
documentation: DecodeDifferent::Decoded(vec![]),
},
StorageEntryMetadata {
name: DecodeDifferent::Decoded("Map".to_string()),
modifier: StorageEntryModifier::Default,
@@ -993,6 +1008,11 @@ fn test_storage_info() {
max_values: Some(1),
max_size: Some(4),
},
StorageInfo {
prefix: prefix(b"Example", b"Value2"),
max_values: Some(1),
max_size: Some(8),
},
StorageInfo {
prefix: prefix(b"Example", b"Map"),
max_values: None,
@@ -0,0 +1,21 @@
#[frame_support::pallet]
mod pallet {
use frame_support::pallet_prelude::StorageValue;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::pallet]
#[pallet::generate_store(trait Store)]
pub struct Pallet<T>(core::marker::PhantomData<T>);
#[pallet::storage]
type Foo<T> = StorageValue<_, u8>;
#[pallet::storage]
#[pallet::storage_prefix = "Foo"]
type NotFoo<T> = StorageValue<_, u16>;
}
fn main() {
}
@@ -0,0 +1,17 @@
error: Duplicate storage prefixes found for `Foo`
--> $DIR/duplicate_storage_prefix.rs:16:32
|
16 | #[pallet::storage_prefix = "Foo"]
| ^^^^^
error[E0412]: cannot find type `_GeneratedPrefixForStorageFoo` in this scope
--> $DIR/duplicate_storage_prefix.rs:13:7
|
13 | type Foo<T> = StorageValue<_, u8>;
| ^^^ not found in this scope
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/duplicate_storage_prefix.rs:17:35
|
17 | type NotFoo<T> = StorageValue<_, u16>;
| ^ not allowed in type signatures
@@ -0,0 +1,21 @@
#[frame_support::pallet]
mod pallet {
use frame_support::pallet_prelude::Hooks;
use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {}
#[pallet::storage]
#[pallet::generate_store(pub trait Store)]
type Foo<T> = StorageValue<u8, u8>;
}
fn main() {
}
@@ -0,0 +1,5 @@
error: expected `getter` or `storage_prefix`
--> $DIR/storage_invalid_attribute.rs:16:12
|
16 | #[pallet::generate_store(pub trait Store)]
| ^^^^^^^^^^^^^^
@@ -0,0 +1,18 @@
#[frame_support::pallet]
mod pallet {
use frame_support::pallet_prelude::Hooks;
use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::pallet]
pub struct Pallet<T>(core::marker::PhantomData<T>);
#[pallet::storage]
#[pallet::storage_prefix = "pub"]
type Foo<T> = StorageValue<_, u8>;
}
fn main() {
}
@@ -0,0 +1,5 @@
error: `pub` is not a valid identifier
--> $DIR/storage_invalid_rename_value.rs:13:29
|
13 | #[pallet::storage_prefix = "pub"]
| ^^^^^
@@ -0,0 +1,25 @@
#[frame_support::pallet]
mod pallet {
use frame_support::pallet_prelude::Hooks;
use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::pallet]
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> {}
#[pallet::storage]
#[pallet::getter(fn get_foo)]
#[pallet::getter(fn foo_error)]
type Foo<T> = StorageValue<_, u8>;
}
fn main() {
}
@@ -0,0 +1,5 @@
error: Invalid pallet::storage, multiple argument pallet::getter found
--> $DIR/storage_multiple_getters.rs:20:3
|
20 | #[pallet::getter(fn foo_error)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -0,0 +1,25 @@
#[frame_support::pallet]
mod pallet {
use frame_support::pallet_prelude::Hooks;
use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
pub trait Config: frame_system::Config {}
#[pallet::pallet]
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> {}
#[pallet::storage]
#[pallet::storage_prefix = "Bar"]
#[pallet::storage_prefix = "Baz"]
type Foo<T> = StorageValue<_, u8>;
}
fn main() {
}
@@ -0,0 +1,5 @@
error: Invalid pallet::storage, multiple argument pallet::storage_prefix found
--> $DIR/storage_multiple_renames.rs:20:3
|
20 | #[pallet::storage_prefix = "Baz"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^