Skip to content

Commit

Permalink
Implement all storage after prefix (paritytech#4227)
Browse files Browse the repository at this point in the history
* Implement all storage after prefix

* fix test, bump version and fix doc

* bump metadata version

* Update frame/support/procedural/src/storage/storage_struct.rs
  • Loading branch information
gui1117 authored and gavofyork committed Nov 27, 2019
1 parent cc14055 commit a512dcd
Show file tree
Hide file tree
Showing 15 changed files with 303 additions and 318 deletions.
2 changes: 1 addition & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 195,
spec_version: 196,
impl_version: 196,
apis: RUNTIME_API_VERSIONS,
};
Expand Down
2 changes: 1 addition & 1 deletion frame/executive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ mod tests {
header: Header {
parent_hash: [69u8; 32].into(),
number: 1,
state_root: hex!("f0d1d66255c2e5b40580eb8b93ddbe732491478487f85e358e1d167d369e398e").into(),
state_root: hex!("c6b01b27df520ba23adb96e7fc032acb7c586ba1b477c6282de43184111f2091").into(),
extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
digest: Digest { logs: vec![], },
},
Expand Down
12 changes: 7 additions & 5 deletions frame/metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,10 @@ pub enum RuntimeMetadata {
V6(RuntimeMetadataDeprecated),
/// Version 7 for runtime metadata. No longer used.
V7(RuntimeMetadataDeprecated),
/// Version 8 for runtime metadata.
V8(RuntimeMetadataV8),
/// Version 8 for runtime metadata. No longer used.
V8(RuntimeMetadataDeprecated),
/// Version 9 for runtime metadata.
V9(RuntimeMetadataV9),
}

/// Enum that should fail.
Expand All @@ -367,12 +369,12 @@ impl Decode for RuntimeMetadataDeprecated {
/// The metadata of a runtime.
#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Decode, Serialize))]
pub struct RuntimeMetadataV8 {
pub struct RuntimeMetadataV9 {
pub modules: DecodeDifferentArray<ModuleMetadata>,
}

/// The latest version of the metadata.
pub type RuntimeMetadataLastVersion = RuntimeMetadataV8;
pub type RuntimeMetadataLastVersion = RuntimeMetadataV9;

/// All metadata about an runtime module.
#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
Expand All @@ -397,6 +399,6 @@ impl Into<primitives::OpaqueMetadata> for RuntimeMetadataPrefixed {

impl Into<RuntimeMetadataPrefixed> for RuntimeMetadataLastVersion {
fn into(self) -> RuntimeMetadataPrefixed {
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self))
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V9(self))
}
}
46 changes: 38 additions & 8 deletions frame/support/procedural/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ use proc_macro::TokenStream;
/// * Value: `Foo: type`: Implements the
/// [`StorageValue`](../frame_support/storage/trait.StorageValue.html) trait using the
/// [`StorageValue generator`](../frame_support/storage/generator/trait.StorageValue.html).
/// The generator `unhashed_key` is `$module_prefix ++ " " ++ $storage_name`
///
/// The generator is implemented with:
/// * `module_prefix`: module_prefix
/// * `storage_prefix`: storage_name
///
/// Thus the storage value is finally stored at:
/// ```nocompile
/// Twox128(module_prefix) ++ Twox128(storage_prefix)
/// ```
///
/// * Map: `Foo: map hasher($hash) type => type`: Implements the
/// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the
Expand All @@ -69,9 +77,15 @@ use proc_macro::TokenStream;
/// with care, see generator documentation.
///
/// The generator is implemented with:
/// * `prefix`: `$module_prefix ++ " " ++ $storage_name`
/// * `module_prefix`: $module_prefix
/// * `storage_prefix`: storage_name
/// * `Hasher`: $hash
///
/// Thus the keys are stored at:
/// ```nocompile
/// twox128(module_prefix) ++ twox128(storage_prefix) ++ hasher(encode(key))
/// ```
///
/// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the
/// [`StorageLinkedMap`](../frame_support/storage/trait.StorageLinkedMap.html) trait using the
/// [`StorageLinkedMap generator`](../frame_support/storage/generator/trait.StorageLinkedMap.html).
Expand All @@ -82,15 +96,25 @@ use proc_macro::TokenStream;
/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher
/// with care, see generator documentation.
///
/// The generator is implemented with:
/// * `prefix`: `$module_prefix ++ " " ++ $storage_name`
/// * `head_key`: `"head of " ++ $module_prefix ++ " " ++ $storage_name`
/// * `Hasher`: $hash
///
/// All key formatting logic can be accessed in a type-agnostic format via the
/// [`KeyFormat`](../srml_support/storage/generator/trait.KeyFormat.html) trait, which
/// is implemented for the storage linked map type as well.
///
/// The generator key format is implemented with:
/// * `module_prefix`: $module_prefix
/// * `storage_prefix`: storage_name
/// * `head_prefix`: `"HeadOf" ++ storage_name`
/// * `Hasher`: $hash
///
/// Thus the keys are stored at:
/// ```nocompile
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key))
/// ```
/// and head is stored at:
/// ```nocompile
/// Twox128(module_prefix) ++ Twox128(head_prefix)
/// ```
///
/// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the
/// [`StorageDoubleMap`](../frame_support/storage/trait.StorageDoubleMap.html) trait using the
/// [`StorageDoubleMap generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html).
Expand All @@ -111,10 +135,16 @@ use proc_macro::TokenStream;
/// Otherwise, other items in storage with the same first key can be compromised.
///
/// The generator is implemented with:
/// * `key1_prefix`: `$module_prefix ++ " " ++ $storage_name`
/// * `module_prefix`: $module_prefix
/// * `storage_prefix`: storage_name
/// * `Hasher1`: $hash1
/// * `Hasher2`: $hash2
///
/// Thus keys are stored at:
/// ```nocompile
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2))
/// ```
///
/// Supported hashers (ordered from least to best security):
///
/// * `twox_64_concat` - TwoX with 64bit + key concatenated.
Expand Down
73 changes: 5 additions & 68 deletions frame/support/procedural/src/storage/instance_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,12 @@
use proc_macro2::{TokenStream, Span};
use quote::quote;
use super::{DeclStorageDefExt, StorageLineTypeDef};
use super::DeclStorageDefExt;

const NUMBER_OF_INSTANCE: usize = 16;
const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable";

// prefix for consts in trait Instance
pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_";
pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_";

// Used to generate the const:
// `const $name: &'static str = $value_prefix ++ instance_prefix ++ $value_suffix`
struct InstanceConstDef {
name: syn::Ident,
value_prefix: String,
value_suffix: String,
}

// Used to generate an instance implementation.
struct InstanceDef {
prefix: String,
Expand All @@ -47,33 +35,7 @@ struct InstanceDef {
pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream {
let mut impls = TokenStream::new();

let mut const_defs = vec![];

for line in def.storage_lines.iter() {
let storage_prefix = format!("{} {}", def.crate_name, line.name);

let const_name = syn::Ident::new(
&format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
const_defs.push(InstanceConstDef {
name: const_name,
value_prefix: String::new(),
value_suffix: storage_prefix.clone(),
});

if let StorageLineTypeDef::LinkedMap(_) = line.storage_type {
let const_name = syn::Ident::new(
&format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site()
);
const_defs.push(InstanceConstDef {
name: const_name,
value_prefix: "head of ".into(),
value_suffix: storage_prefix,
});
}
}

impls.extend(create_instance_trait(&const_defs, def));
impls.extend(create_instance_trait(def));

// Implementation of instances.
if let Some(module_instance) = &def.module_instance {
Expand All @@ -95,7 +57,7 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
);

for instance_def in instance_defs {
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def));
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def));
}
}

Expand All @@ -116,27 +78,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
instance_struct: inherent_instance,
doc: quote!(#[doc(hidden)]),
};
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def));
impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def));
}

impls
}

fn create_instance_trait(
const_defs: &[InstanceConstDef],
def: &DeclStorageDefExt,
) -> TokenStream {
let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone())
.unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()));

let mut const_impls = TokenStream::new();
for const_def in const_defs {
let const_name = &const_def.name;
const_impls.extend(quote! {
const #const_name: &'static str;
});
}

let optional_hide = if def.module_instance.is_some() {
quote!()
} else {
Expand All @@ -151,30 +104,15 @@ fn create_instance_trait(
pub trait #instance_trait: 'static {
/// The prefix used by any storage entry of an instance.
const PREFIX: &'static str;
#const_impls
}
}
}

fn create_and_impl_instance_struct(
scrate: &TokenStream,
instance_def: &InstanceDef,
const_defs: &[InstanceConstDef],
def: &DeclStorageDefExt,
) -> TokenStream {
let mut const_impls = TokenStream::new();

for const_def in const_defs {
let const_value = format!(
"{}{}{}", const_def.value_prefix, instance_def.prefix, const_def.value_suffix
);
let const_name = &const_def.name;

const_impls.extend(quote! {
const #const_name: &'static str = #const_value;
});
}

let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone())
.unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()));

Expand All @@ -194,7 +132,6 @@ fn create_and_impl_instance_struct(
pub struct #instance_struct;
impl #instance_trait for #instance_struct {
const PREFIX: &'static str = #prefix;
#const_impls
}
}
}
Loading

0 comments on commit a512dcd

Please sign in to comment.