From f4035cd5ac862d63113f6fb2806b691895254321 Mon Sep 17 00:00:00 2001
From: thiolliere <gui.thiolliere@gmail.com>
Date: Wed, 27 Nov 2019 19:23:20 +0100
Subject: [PATCH] Implement all storage after prefix (#4227)

* Implement all storage after prefix

* fix test, bump version and fix doc

* bump metadata version

* Update frame/support/procedural/src/storage/storage_struct.rs
---
 substrate/bin/node/runtime/src/lib.rs         |   2 +-
 substrate/frame/executive/src/lib.rs          |   2 +-
 substrate/frame/metadata/src/lib.rs           |  12 +-
 substrate/frame/support/procedural/src/lib.rs |  46 +++++-
 .../procedural/src/storage/instance_trait.rs  |  73 +--------
 .../procedural/src/storage/storage_struct.rs  |  73 +++++----
 .../src/storage/generator/double_map.rs       |  31 +++-
 .../src/storage/generator/linked_map.rs       | 154 +++++++++---------
 .../support/src/storage/generator/map.rs      |  35 ++--
 .../support/src/storage/generator/mod.rs      |  10 +-
 .../support/src/storage/generator/value.rs    |  20 ++-
 substrate/frame/support/src/storage/mod.rs    |   2 +-
 .../frame/support/test/tests/final_keys.rs    | 146 ++++++++---------
 .../frame/support/test/tests/instance.rs      |  11 --
 substrate/utils/frame/rpc/support/src/lib.rs  |   4 +-
 15 files changed, 303 insertions(+), 318 deletions(-)

diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 8e405739167..fbb690a622e 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -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,
 };
diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs
index f6b50143a70..d160bd7bdd4 100644
--- a/substrate/frame/executive/src/lib.rs
+++ b/substrate/frame/executive/src/lib.rs
@@ -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![], },
 				},
diff --git a/substrate/frame/metadata/src/lib.rs b/substrate/frame/metadata/src/lib.rs
index d85a6837fc6..113273be028 100644
--- a/substrate/frame/metadata/src/lib.rs
+++ b/substrate/frame/metadata/src/lib.rs
@@ -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.
@@ -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)]
@@ -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))
 	}
 }
diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs
index 8f23142beab..506e55fa175 100644
--- a/substrate/frame/support/procedural/src/lib.rs
+++ b/substrate/frame/support/procedural/src/lib.rs
@@ -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
@@ -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).
@@ -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).
@@ -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.
diff --git a/substrate/frame/support/procedural/src/storage/instance_trait.rs b/substrate/frame/support/procedural/src/storage/instance_trait.rs
index 1a7add89a4b..abc56092e31 100644
--- a/substrate/frame/support/procedural/src/storage/instance_trait.rs
+++ b/substrate/frame/support/procedural/src/storage/instance_trait.rs
@@ -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,
@@ -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 {
@@ -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));
 		}
 	}
 
@@ -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 {
@@ -151,7 +104,6 @@ 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
 		}
 	}
 }
@@ -159,22 +111,8 @@ fn create_instance_trait(
 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()));
 
@@ -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
 		}
 	}
 }
diff --git a/substrate/frame/support/procedural/src/storage/storage_struct.rs b/substrate/frame/support/procedural/src/storage/storage_struct.rs
index 5267876a441..017e6cf2ff1 100644
--- a/substrate/frame/support/procedural/src/storage/storage_struct.rs
+++ b/substrate/frame/support/procedural/src/storage/storage_struct.rs
@@ -16,11 +16,11 @@
 
 //! Implementation of storage structures and implementation of storage traits on them.
 
-use proc_macro2::TokenStream;
+use proc_macro2::{TokenStream, Ident, Span};
 use quote::quote;
 use super::{
 	DeclStorageDefExt, StorageLineTypeDef,
-	instance_trait::{PREFIX_FOR, HEAD_KEY_FOR},
+	instance_trait::INHERENT_INSTANCE_NAME,
 };
 
 fn from_optional_value_to_query(is_option: bool, default: &Option<syn::Expr>) -> TokenStream {
@@ -78,17 +78,14 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 		let from_optional_value_to_query =
 			from_optional_value_to_query(line.is_option, &line.default_value);
 
-		let final_prefix = if let Some(instance) = def.module_instance.as_ref() {
-			let instance = &instance.instance_generic;
-			let const_name = syn::Ident::new(
-				&format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site()
-			);
-			quote!( #instance::#const_name.as_bytes() )
+		// Contains accessor to instance, used to get prefixes
+		let instance_or_inherent = if let Some(instance) = def.module_instance.as_ref() {
+			instance.instance_generic.clone()
 		} else {
-			let prefix = format!("{} {}", def.crate_name, line.name);
-			quote!( #prefix.as_bytes() )
+			Ident::new(INHERENT_INSTANCE_NAME, Span::call_site())
 		};
 
+		let storage_name_str = syn::LitStr::new(&line.name.to_string(), line.name.span());
 
 		let storage_generator_trait = &line.storage_generator_trait;
 		let storage_struct = &line.storage_struct;
@@ -104,8 +101,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 					{
 						type Query = #query_type;
 
-						fn unhashed_key() -> &'static [u8] {
-							#final_prefix
+						fn module_prefix() -> &'static [u8] {
+							#instance_or_inherent::PREFIX.as_bytes()
+						}
+
+						fn storage_prefix() -> &'static [u8] {
+							#storage_name_str.as_bytes()
 						}
 
 						fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
@@ -127,8 +128,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 						type Query = #query_type;
 						type Hasher = #scrate::#hasher;
 
-						fn prefix() -> &'static [u8] {
-							#final_prefix
+						fn module_prefix() -> &'static [u8] {
+							#instance_or_inherent::PREFIX.as_bytes()
+						}
+
+						fn storage_prefix() -> &'static [u8] {
+							#storage_name_str.as_bytes()
 						}
 
 						fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
@@ -144,30 +149,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 			StorageLineTypeDef::LinkedMap(map) => {
 				let hasher = map.hasher.to_storage_hasher_struct();
 
-				// make sure to use different prefix for head and elements.
-				let head_key = if let Some(instance) = def.module_instance.as_ref() {
-					let instance = &instance.instance_generic;
-					let const_name = syn::Ident::new(
-						&format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site()
-					);
-					quote!( #instance::#const_name.as_bytes() )
-				} else {
-					let prefix = format!("head of {} {}", def.crate_name, line.name);
-					quote!( #prefix.as_bytes() )
-				};
+				let head_prefix_str = syn::LitStr::new(
+					&format!("HeadOf{}", line.name.to_string()),
+					line.name.span(),
+				);
 
 				quote!(
 					impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct
 					#optional_storage_where_clause
 					{
 						type Query = #query_type;
-						type Hasher = #scrate::#hasher;
 						type KeyFormat = Self;
 
-						fn prefix() -> &'static [u8] {
-							#final_prefix
-						}
-
 						fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
 							#from_optional_value_to_query
 						}
@@ -180,8 +173,16 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 					impl<#impl_trait> #scrate::storage::generator::LinkedMapKeyFormat for #storage_struct {
 						type Hasher = #scrate::#hasher;
 
-						fn head_key() -> &'static [u8] {
-							#head_key
+						fn module_prefix() -> &'static [u8] {
+							#instance_or_inherent::PREFIX.as_bytes()
+						}
+
+						fn storage_prefix() -> &'static [u8] {
+							#storage_name_str.as_bytes()
+						}
+
+						fn head_prefix() -> &'static [u8] {
+							#head_prefix_str.as_bytes()
 						}
 					}
 				)
@@ -199,8 +200,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
 
 						type Hasher2 = #scrate::#hasher2;
 
-						fn key1_prefix() -> &'static [u8] {
-							#final_prefix
+						fn module_prefix() -> &'static [u8] {
+							#instance_or_inherent::PREFIX.as_bytes()
+						}
+
+						fn storage_prefix() -> &'static [u8] {
+							#storage_name_str.as_bytes()
 						}
 
 						fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query {
diff --git a/substrate/frame/support/src/storage/generator/double_map.rs b/substrate/frame/support/src/storage/generator/double_map.rs
index 072b530e4cd..28378034b22 100644
--- a/substrate/frame/support/src/storage/generator/double_map.rs
+++ b/substrate/frame/support/src/storage/generator/double_map.rs
@@ -17,7 +17,7 @@
 use rstd::prelude::*;
 use rstd::borrow::Borrow;
 use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend};
-use crate::{storage::{self, unhashed}, hash::StorageHasher};
+use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}};
 
 /// Generator for `StorageDoubleMap` used by `decl_storage`.
 ///
@@ -29,7 +29,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher};
 ///
 /// Thus value for (key1, key2) is stored at:
 /// ```nocompile
-/// Hasher1(key1_prefix ++ key1) ++ Hasher2(key2)
+/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2))
 /// ```
 ///
 /// # Warning
@@ -49,8 +49,11 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
 	/// Hasher for the second key.
 	type Hasher2: StorageHasher;
 
-	/// Get the prefix for first key.
-	fn key1_prefix() -> &'static [u8];
+	/// Module prefix. Used for generating final key.
+	fn module_prefix() -> &'static [u8];
+
+	/// Storage prefix. Used for generating final key.
+	fn storage_prefix() -> &'static [u8];
 
 	/// Convert an optional value retrieved from storage to the type queried.
 	fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
@@ -59,13 +62,23 @@ 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) -> <Self::Hasher1 as StorageHasher>::Output
+	fn storage_double_map_final_key1<KArg1>(k1: KArg1) -> Vec<u8>
 	where
 		KArg1: EncodeLike<K1>,
 	{
-		let mut final_key1 = Self::key1_prefix().to_vec();
-		k1.encode_to(&mut final_key1);
-		Self::Hasher1::hash(&final_key1)
+		let module_prefix_hashed = Twox128::hash(Self::module_prefix());
+		let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
+		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()
+		);
+
+		final_key.extend_from_slice(&module_prefix_hashed[..]);
+		final_key.extend_from_slice(&storage_prefix_hashed[..]);
+		final_key.extend_from_slice(key_hashed.as_ref());
+
+		final_key
 	}
 
 	/// Generate the full key used in top storage.
@@ -74,7 +87,7 @@ pub trait StorageDoubleMap<K1: FullEncode, K2: FullEncode, V: FullCodec> {
 		KArg1: EncodeLike<K1>,
 		KArg2: EncodeLike<K2>,
 	{
-		let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec();
+		let mut final_key = Self::storage_double_map_final_key1(k1);
 		final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref());
 		final_key
 	}
diff --git a/substrate/frame/support/src/storage/generator/linked_map.rs b/substrate/frame/support/src/storage/generator/linked_map.rs
index cf403496990..fb0603fce76 100644
--- a/substrate/frame/support/src/storage/generator/linked_map.rs
+++ b/substrate/frame/support/src/storage/generator/linked_map.rs
@@ -15,48 +15,18 @@
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
 use codec::{FullCodec, Encode, Decode, EncodeLike, Ref};
-use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len};
-use rstd::marker::PhantomData;
+use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len};
+use rstd::{prelude::*, marker::PhantomData};
 
 /// Generator for `StorageLinkedMap` used by `decl_storage`.
 ///
-/// # Mapping of keys to a storage path
-///
-/// The key for the head of the map is stored at one fixed path:
-/// ```nocompile
-/// Hasher(head_key)
-/// ```
-///
-/// For each key, the value stored under that key is appended with a
-/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path:
-/// ```nocompile
-/// Hasher(prefix ++ key)
-/// ```
-///
-/// Enumeration is done by getting the head of the linked map and then iterating getting the
-/// value and linkage stored at the key until the found linkage has no next key.
-///
-/// # Warning
-///
-/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
-/// `blake2_256` must be used. Otherwise, other values in storage can be compromised.
+/// By default final key generation rely on `KeyFormat`.
 pub trait StorageLinkedMap<K: FullCodec, V: FullCodec> {
 	/// The type that get/take returns.
 	type Query;
 
-	/// Hasher used to insert into storage.
-	type Hasher: StorageHasher;
-
 	/// The family of key formats used for this map.
-	type KeyFormat: KeyFormat<Hasher=Self::Hasher>;
-
-	/// Prefix used to prepend each key.
-	fn prefix() -> &'static [u8];
-
-	/// The head key of the linked-map.
-	fn head_key() -> &'static [u8] {
-		<Self::KeyFormat as KeyFormat>::head_key()
-	}
+	type KeyFormat: KeyFormat;
 
 	/// Convert an optional value retrieved from storage to the type queried.
 	fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
@@ -65,41 +35,80 @@ pub trait StorageLinkedMap<K: FullCodec, V: FullCodec> {
 	fn from_query_to_optional_value(v: Self::Query) -> Option<V>;
 
 	/// Generate the full key used in top storage.
-	fn storage_linked_map_final_key<KeyArg>(key: KeyArg) -> <Self::Hasher as StorageHasher>::Output
+	fn storage_linked_map_final_key<KeyArg>(key: KeyArg) -> Vec<u8>
 	where
 		KeyArg: EncodeLike<K>,
 	{
-		<Self::KeyFormat as KeyFormat>::storage_linked_map_final_key::<KeyArg>(Self::prefix(), &key)
+		<Self::KeyFormat as KeyFormat>::storage_linked_map_final_key::<KeyArg>(&key)
 	}
 
 	/// Generate the hashed key for head
-	fn storage_linked_map_final_head_key() -> <Self::Hasher as StorageHasher>::Output {
+	fn storage_linked_map_final_head_key() -> Vec<u8> {
 		<Self::KeyFormat as KeyFormat>::storage_linked_map_final_head_key()
 	}
 }
 
 /// A type-abstracted key format used for a family of linked-map types.
+///
+/// # Default mapping of keys to a storage path
+///
+/// The key for the head of the map is stored at one fixed path:
+/// ```nocompile
+/// Twox128(module_prefix) ++ Twox128(head_prefix)
+/// ```
+///
+/// For each key, the value stored under that key is appended with a
+/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path:
+/// ```nocompile
+/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key))
+/// ```
+///
+/// Enumeration is done by getting the head of the linked map and then iterating getting the
+/// value and linkage stored at the key until the found linkage has no next key.
+///
+/// # Warning
+///
+/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as
+/// `blake2_256` must be used. Otherwise, other values in storage can be compromised.
 pub trait KeyFormat {
+	/// Hasher. Used for generating final key and final head key.
 	type Hasher: StorageHasher;
 
-	/// Key used to store linked map head.
-	fn head_key() -> &'static [u8];
+	/// Module prefix. Used for generating final key.
+	fn module_prefix() -> &'static [u8];
+
+	/// Storage prefix. Used for generating final key.
+	fn storage_prefix() -> &'static [u8];
+
+	/// Storage prefix. Used for generating final head key.
+	fn head_prefix() -> &'static [u8];
 
 	/// Generate the full key used in top storage.
-	fn storage_linked_map_final_key<K>(prefix: &[u8], key: &K)
-		-> <Self::Hasher as StorageHasher>::Output
+	fn storage_linked_map_final_key<K>(key: &K) -> Vec<u8>
 	where
 		K: Encode,
 	{
-		let mut final_key = prefix.to_vec();
-		key.encode_to(&mut final_key);
-		<Self::Hasher as StorageHasher>::hash(&final_key)
+		let module_prefix_hashed = Twox128::hash(Self::module_prefix());
+		let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
+		let key_hashed = key.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()
+		);
+
+		final_key.extend_from_slice(&module_prefix_hashed[..]);
+		final_key.extend_from_slice(&storage_prefix_hashed[..]);
+		final_key.extend_from_slice(key_hashed.as_ref());
+
+		final_key
 	}
 
-	fn storage_linked_map_final_head_key()
-		-> <Self::Hasher as StorageHasher>::Output
-	{
-		<Self::Hasher as StorageHasher>::hash(Self::head_key())
+	/// Generate the full key used in top storage to store the head of the linked map.
+	fn storage_linked_map_final_head_key() -> Vec<u8> {
+		[
+			Twox128::hash(Self::module_prefix()),
+			Twox128::hash(Self::head_prefix()),
+		].concat()
 	}
 }
 
@@ -135,17 +144,15 @@ struct EncodeLikeLinkage<PKey: EncodeLike<Key>, NKey: EncodeLike<Key>, Key: Enco
 /// A key-value pair iterator for enumerable map.
 pub struct Enumerator<K, V, F> {
 	next: Option<K>,
-	prefix: &'static [u8],
 	_phantom: PhantomData<(V, F)>,
 }
 
 impl<K, V, F> Enumerator<K, V, F> {
 	/// Create an explicit enumerator for testing.
 	#[cfg(test)]
-	pub fn from_head(head: K, prefix: &'static [u8]) -> Self {
+	pub fn from_head(head: K) -> Self {
 		Enumerator {
 			next: Some(head),
-			prefix,
 			_phantom: Default::default(),
 		}
 	}
@@ -163,15 +170,15 @@ where
 		let next = self.next.take()?;
 
 		let (val, linkage): (V, Linkage<K>) = {
-			let next_full_key = F::storage_linked_map_final_key(self.prefix, &next);
+			let next_full_key = F::storage_linked_map_final_key(&next);
 			match read_with_linkage::<K, V>(next_full_key.as_ref()) {
 				Some(value) => value,
 				None => {
 					// TODO #3700: error should be handleable.
 					runtime_print!(
-						"ERROR: Corrupted state: linked map head_key={:?}: \
+						"ERROR: Corrupted state: linked map {:?}{:?}: \
 						next value doesn't exist at {:?}",
-						F::head_key(), next_full_key.as_ref(),
+						F::module_prefix(), F::storage_prefix(), next_full_key,
 					);
 					return None
 				}
@@ -187,18 +194,14 @@ where
 ///
 /// Takes care of updating previous and next elements points
 /// as well as updates head if the element is first or last.
-fn remove_linkage<K, V, F>(linkage: Linkage<K>, prefix: &[u8])
+fn remove_linkage<K, V, F>(linkage: Linkage<K>)
 where
 	K: FullCodec,
 	V: FullCodec,
 	F: KeyFormat,
 {
-	let next_key = linkage.next.as_ref()
-		.map(|k| F::storage_linked_map_final_key(prefix, k))
-		.map(|x| x.as_ref().to_vec());
-	let prev_key = linkage.previous.as_ref()
-		.map(|k| F::storage_linked_map_final_key(prefix, k))
-		.map(|x| x.as_ref().to_vec());
+	let next_key = linkage.next.as_ref().map(|k| F::storage_linked_map_final_key(k));
+	let prev_key = linkage.previous.as_ref().map(|k| F::storage_linked_map_final_key(k));
 
 	if let Some(prev_key) = prev_key {
 		// Retrieve previous element and update `next`
@@ -208,9 +211,9 @@ where
 		} else {
 			// TODO #3700: error should be handleable.
 			runtime_print!(
-				"ERROR: Corrupted state: linked map head_key={:?}: \
+				"ERROR: Corrupted state: linked map {:?}{:?}: \
 				previous value doesn't exist at {:?}",
-				F::head_key(), prev_key,
+				F::module_prefix(), F::storage_prefix(), prev_key,
 			);
 		}
 	} else {
@@ -225,9 +228,9 @@ where
 		} else {
 			// TODO #3700: error should be handleable.
 			runtime_print!(
-				"ERROR: Corrupted state: linked map head_key={:?}: \
+				"ERROR: Corrupted state: linked map {:?}{:?}: \
 				next value doesn't exist at {:?}",
-				F::head_key(), next_key,
+				F::module_prefix(), F::storage_prefix(), next_key,
 			);
 		}
 	}
@@ -245,7 +248,7 @@ where
 /// Generate linkage for newly inserted element.
 ///
 /// Takes care of updating head and previous head's pointer.
-pub(super) fn new_head_linkage<KeyArg, K, V, F>(key: KeyArg, prefix: &[u8]) -> Linkage<K>
+pub(super) fn new_head_linkage<KeyArg, K, V, F>(key: KeyArg) -> Linkage<K>
 where
 	KeyArg: EncodeLike<K>,
 	K: FullCodec,
@@ -255,7 +258,7 @@ where
 	if let Some(head) = read_head::<K, F>() {
 		// update previous head predecessor
 		{
-			let head_key = F::storage_linked_map_final_key(prefix, &head);
+			let head_key = F::storage_linked_map_final_key(&head);
 			if let Some((data, linkage)) = read_with_linkage::<K, V>(head_key.as_ref()) {
 				let new_linkage = EncodeLikeLinkage::<_, _, K> {
 					previous: Some(Ref::from(&key)),
@@ -266,9 +269,9 @@ where
 			} else {
 				// TODO #3700: error should be handleable.
 				runtime_print!(
-					"ERROR: Corrupted state: linked map head_key={:?}: \
+					"ERROR: Corrupted state: linked map {:?}{:?}: \
 					head value doesn't exist at {:?}",
-					F::head_key(), head_key.as_ref(),
+					F::module_prefix(), F::storage_prefix(), head_key,
 				);
 				// Thus we consider we are first - update the head and produce empty linkage
 
@@ -333,7 +336,6 @@ where
 	}
 
 	fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2) {
-		let prefix = Self::prefix();
 		let final_key1 = Self::storage_linked_map_final_key(Ref::from(&key1));
 		let final_key2 = Self::storage_linked_map_final_key(Ref::from(&key2));
 		let full_value_1 = read_with_linkage::<K, V>(final_key1.as_ref());
@@ -348,13 +350,13 @@ where
 			// Remove key and insert the new one.
 			(Some((value, _linkage)), None) => {
 				Self::remove(key1);
-				let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key2, prefix);
+				let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key2);
 				unhashed::put(final_key2.as_ref(), &(value, linkage));
 			}
 			// Remove key and insert the new one.
 			(None, Some((value, _linkage))) => {
 				Self::remove(key2);
-				let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key1, prefix);
+				let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key1);
 				unhashed::put(final_key1.as_ref(), &(value, linkage));
 			}
 			// No-op.
@@ -368,7 +370,7 @@ where
 			// overwrite but reuse existing linkage
 			Some((_data, linkage)) => linkage,
 			// create new linkage
-			None => new_head_linkage::<_, _, V, G::KeyFormat>(key, Self::prefix()),
+			None => new_head_linkage::<_, _, V, G::KeyFormat>(key),
 		};
 		unhashed::put(final_key.as_ref(), &(val, linkage))
 	}
@@ -398,7 +400,7 @@ where
 		let full_value: Option<(V, Linkage<K>)> = unhashed::take(final_key.as_ref());
 
 		let value = full_value.map(|(data, linkage)| {
-			remove_linkage::<K, V, G::KeyFormat>(linkage, Self::prefix());
+			remove_linkage::<K, V, G::KeyFormat>(linkage);
 			data
 		});
 
@@ -408,7 +410,6 @@ where
 	fn enumerate() -> Self::Enumerator {
 		Enumerator::<_, _, G::KeyFormat> {
 			next: read_head::<_, G::KeyFormat>(),
-			prefix: Self::prefix(),
 			_phantom: Default::default(),
 		}
 	}
@@ -436,7 +437,6 @@ where
 		where K2: FullCodec + Clone, V2: Decode, TK: Fn(K2) -> K, TV: Fn(V2) -> V
 	{
 		let head_key = read_head::<K2, G::KeyFormat>().ok_or(None)?;
-		let prefix = G::prefix();
 
 		let mut last_key = None;
 		let mut current_key = head_key.clone();
@@ -451,7 +451,7 @@ where
 		};
 
 		loop {
-			let old_raw_key = G::KeyFormat::storage_linked_map_final_key(prefix, &current_key);
+			let old_raw_key = G::KeyFormat::storage_linked_map_final_key(&current_key);
 			let x = unhashed::take(old_raw_key.as_ref());
 			let (val, linkage): (V2, Linkage<K2>) = match x {
 				Some(v) => v,
diff --git a/substrate/frame/support/src/storage/generator/map.rs b/substrate/frame/support/src/storage/generator/map.rs
index 3c3edac28a4..926fe8748db 100644
--- a/substrate/frame/support/src/storage/generator/map.rs
+++ b/substrate/frame/support/src/storage/generator/map.rs
@@ -18,13 +18,13 @@
 use rstd::prelude::*;
 use rstd::borrow::Borrow;
 use codec::{FullCodec, FullEncode, Encode, EncodeLike, Ref, EncodeAppend};
-use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len};
+use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len};
 
 /// Generator for `StorageMap` used by `decl_storage`.
 ///
-/// For each key value is stored at:
+/// By default each key value is stored at:
 /// ```nocompile
-/// Hasher(prefix ++ key)
+/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key))
 /// ```
 ///
 /// # Warning
@@ -35,11 +35,14 @@ pub trait StorageMap<K: FullEncode, V: FullCodec> {
 	/// The type that get/take returns.
 	type Query;
 
-	/// Hasher used to insert into storage.
+	/// Hasher. Used for generating final key.
 	type Hasher: StorageHasher;
 
-	/// Prefix used to prepend each key.
-	fn prefix() -> &'static [u8];
+	/// Module prefix. Used for generating final key.
+	fn module_prefix() -> &'static [u8];
+
+	/// Storage prefix. Used for generating final key.
+	fn storage_prefix() -> &'static [u8];
 
 	/// Convert an optional value retrieved from storage to the type queried.
 	fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
@@ -48,13 +51,23 @@ 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) -> <Self::Hasher as StorageHasher>::Output
+	fn storage_map_final_key<KeyArg>(key: KeyArg) -> Vec<u8>
 	where
 		KeyArg: EncodeLike<K>,
 	{
-		let mut final_key = Self::prefix().to_vec();
-		key.borrow().encode_to(&mut final_key);
-		Self::Hasher::hash(&final_key)
+		let module_prefix_hashed = Twox128::hash(Self::module_prefix());
+		let storage_prefix_hashed = Twox128::hash(Self::storage_prefix());
+		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()
+		);
+
+		final_key.extend_from_slice(&module_prefix_hashed[..]);
+		final_key.extend_from_slice(&storage_prefix_hashed[..]);
+		final_key.extend_from_slice(key_hashed.as_ref());
+
+		final_key
 	}
 }
 
@@ -62,7 +75,7 @@ impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V>
 	type Query = G::Query;
 
 	fn hashed_key_for<KeyArg: EncodeLike<K>>(key: KeyArg) -> Vec<u8> {
-		Self::storage_map_final_key(key).as_ref().to_vec()
+		Self::storage_map_final_key(key)
 	}
 
 	fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2) {
diff --git a/substrate/frame/support/src/storage/generator/mod.rs b/substrate/frame/support/src/storage/generator/mod.rs
index f546546dc72..2db3e08ccf2 100644
--- a/substrate/frame/support/src/storage/generator/mod.rs
+++ b/substrate/frame/support/src/storage/generator/mod.rs
@@ -94,22 +94,18 @@ mod tests {
 
 		let t = GenesisConfig::default().build_storage().unwrap();
 		TestExternalities::new(t).execute_with(|| {
-			let prefix = NumberMap::prefix();
-
 			// start with a map of u32 -> u32.
 			for i in 0u32..100u32 {
-				let final_key = <Format as KeyFormat>::storage_linked_map_final_key(
-					prefix, &i,
-				);
+				let final_key = <Format as KeyFormat>::storage_linked_map_final_key(&i);
 
-				let linkage = linked_map::new_head_linkage::<_, u32, u32, Format>(&i, prefix);
+				let linkage = linked_map::new_head_linkage::<_, u32, u32, Format>(&i);
 				unhashed::put(final_key.as_ref(), &(&i, linkage));
 			}
 
 			let head = linked_map::read_head::<u32, Format>().unwrap();
 
 			assert_eq!(
-				Enumerator::<u32, u32, Format>::from_head(head, prefix).collect::<Vec<_>>(),
+				Enumerator::<u32, u32, Format>::from_head(head).collect::<Vec<_>>(),
 				(0..100).rev().map(|x| (x, x)).collect::<Vec<_>>(),
 			);
 
diff --git a/substrate/frame/support/src/storage/generator/value.rs b/substrate/frame/support/src/storage/generator/value.rs
index 5ebc25a70af..0cf143bac1f 100644
--- a/substrate/frame/support/src/storage/generator/value.rs
+++ b/substrate/frame/support/src/storage/generator/value.rs
@@ -21,16 +21,19 @@ use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::L
 
 /// Generator for `StorageValue` used by `decl_storage`.
 ///
-/// Value is stored at:
+/// By default value is stored at:
 /// ```nocompile
-/// Twox128(unhashed_key)
+/// Twox128(module_prefix) ++ Twox128(storage_prefix)
 /// ```
 pub trait StorageValue<T: FullCodec> {
 	/// The type that get/take returns.
 	type Query;
 
-	/// Unhashed key used in storage
-	fn unhashed_key() -> &'static [u8];
+	/// Module prefix. Used for generating final key.
+	fn module_prefix() -> &'static [u8];
+
+	/// Storage prefix. Used for generating final key.
+	fn storage_prefix() -> &'static [u8];
 
 	/// Convert an optional value retrieved from storage to the type queried.
 	fn from_optional_value_to_query(v: Option<T>) -> Self::Query;
@@ -39,15 +42,18 @@ pub trait StorageValue<T: FullCodec> {
 	fn from_query_to_optional_value(v: Self::Query) -> Option<T>;
 
 	/// Generate the full key used in top storage.
-	fn storage_value_final_key() -> [u8; 16] {
-		Twox128::hash(Self::unhashed_key())
+	fn storage_value_final_key() -> [u8; 32] {
+		let mut final_key = [0u8; 32];
+		final_key[0..16].copy_from_slice(&Twox128::hash(Self::module_prefix()));
+		final_key[16..32].copy_from_slice(&Twox128::hash(Self::storage_prefix()));
+		final_key
 	}
 }
 
 impl<T: FullCodec, G: StorageValue<T>> storage::StorageValue<T> for G {
 	type Query = G::Query;
 
-	fn hashed_key() -> [u8; 16] {
+	fn hashed_key() -> [u8; 32] {
 		Self::storage_value_final_key()
 	}
 
diff --git a/substrate/frame/support/src/storage/mod.rs b/substrate/frame/support/src/storage/mod.rs
index 91e17767885..88818b84e2e 100644
--- a/substrate/frame/support/src/storage/mod.rs
+++ b/substrate/frame/support/src/storage/mod.rs
@@ -34,7 +34,7 @@ pub trait StorageValue<T: FullCodec> {
 	type Query;
 
 	/// Get the storage key.
-	fn hashed_key() -> [u8; 16];
+	fn hashed_key() -> [u8; 32];
 
 	/// Does the value (explicitly) exist in storage?
 	fn exists() -> bool;
diff --git a/substrate/frame/support/test/tests/final_keys.rs b/substrate/frame/support/test/tests/final_keys.rs
index c1cf5c651a5..365aa5779d1 100644
--- a/substrate/frame/support/test/tests/final_keys.rs
+++ b/substrate/frame/support/test/tests/final_keys.rs
@@ -17,7 +17,7 @@
 use support::storage::unhashed;
 use codec::Encode;
 use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue};
-use runtime_io::{TestExternalities, hashing};
+use runtime_io::{TestExternalities, hashing::{twox_128, blake2_128, blake2_256}};
 
 mod no_instance {
 	use codec::{Encode, Decode, EncodeLike};
@@ -89,44 +89,43 @@ mod instance {
 fn final_keys_no_instance() {
 	TestExternalities::default().execute_with(|| {
 		no_instance::Value::put(1);
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(b"FinalKeysNone Value")), Some(1u32));
+		let k = [twox_128(b"FinalKeysNone"), twox_128(b"Value")].concat();
+		assert_eq!(unhashed::get::<u32>(&k), Some(1u32));
 
 		no_instance::Map::insert(1, 2);
-		let mut k = b"FinalKeysNone Map".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"Map")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		no_instance::Map2::insert(1, 2);
-		let mut k = b"FinalKeysNone Map2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"Map2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
-		let head = b"head of FinalKeysNone LinkedMap".to_vec();
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
+		let head = [twox_128(b"FinalKeysNone"), twox_128(b"HeadOfLinkedMap")].concat();
+		assert_eq!(unhashed::get::<u32>(&head), None);
 
 		no_instance::LinkedMap::insert(1, 2);
-		let mut k = b"FinalKeysNone LinkedMap".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"LinkedMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
+		assert_eq!(unhashed::get::<u32>(&head), Some(1u32));
 
 		no_instance::LinkedMap2::insert(1, 2);
-		let mut k = b"FinalKeysNone LinkedMap2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"LinkedMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		no_instance::DoubleMap::insert(&1, &2, &3);
-		let mut k = b"FinalKeysNone DoubleMap".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::blake2_256(&k).to_vec();
-		k.extend(&hashing::blake2_256(&2u32.encode()));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"DoubleMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		k.extend(2u32.using_encoded(blake2_256).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 
 		no_instance::DoubleMap2::insert(&1, &2, &3);
-		let mut k = b"FinalKeysNone DoubleMap2".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::twox_128(&k).to_vec();
-		k.extend(&hashing::blake2_128(&2u32.encode()));
+		let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"DoubleMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		k.extend(2u32.using_encoded(blake2_128).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 	});
 }
@@ -135,44 +134,43 @@ fn final_keys_no_instance() {
 fn final_keys_default_instance() {
 	TestExternalities::default().execute_with(|| {
 		<instance::Value<instance::DefaultInstance>>::put(1);
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(b"FinalKeysSome Value")), Some(1u32));
+		let k = [twox_128(b"FinalKeysSome"), twox_128(b"Value")].concat();
+		assert_eq!(unhashed::get::<u32>(&k), Some(1u32));
 
 		<instance::Map<instance::DefaultInstance>>::insert(1, 2);
-		let mut k = b"FinalKeysSome Map".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"Map")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		<instance::Map2<instance::DefaultInstance>>::insert(1, 2);
-		let mut k = b"FinalKeysSome Map2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"Map2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
-		let head = b"head of FinalKeysSome LinkedMap".to_vec();
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
+		let head = [twox_128(b"FinalKeysSome"), twox_128(b"HeadOfLinkedMap")].concat();
+		assert_eq!(unhashed::get::<u32>(&head), None);
 
 		<instance::LinkedMap<instance::DefaultInstance>>::insert(1, 2);
-		let mut k = b"FinalKeysSome LinkedMap".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"LinkedMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
+		assert_eq!(unhashed::get::<u32>(&head), Some(1u32));
 
 		<instance::LinkedMap2<instance::DefaultInstance>>::insert(1, 2);
-		let mut k = b"FinalKeysSome LinkedMap2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"LinkedMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		<instance::DoubleMap<instance::DefaultInstance>>::insert(&1, &2, &3);
-		let mut k = b"FinalKeysSome DoubleMap".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::blake2_256(&k).to_vec();
-		k.extend(&hashing::blake2_256(&2u32.encode()));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"DoubleMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		k.extend(2u32.using_encoded(blake2_256).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 
 		<instance::DoubleMap2<instance::DefaultInstance>>::insert(&1, &2, &3);
-		let mut k = b"FinalKeysSome DoubleMap2".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::twox_128(&k).to_vec();
-		k.extend(&hashing::blake2_128(&2u32.encode()));
+		let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"DoubleMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		k.extend(2u32.using_encoded(blake2_128).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 	});
 }
@@ -181,47 +179,43 @@ fn final_keys_default_instance() {
 fn final_keys_instance_2() {
 	TestExternalities::default().execute_with(|| {
 		<instance::Value<instance::Instance2>>::put(1);
-		assert_eq!(
-			unhashed::get::<u32>(&hashing::twox_128(b"Instance2FinalKeysSome Value")),
-			Some(1u32)
-		);
+		let k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Value")].concat();
+		assert_eq!(unhashed::get::<u32>(&k), Some(1u32));
 
 		<instance::Map<instance::Instance2>>::insert(1, 2);
-		let mut k = b"Instance2FinalKeysSome Map".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Map")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		<instance::Map2<instance::Instance2>>::insert(1, 2);
-		let mut k = b"Instance2FinalKeysSome Map2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Map2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
-		let head = b"head of Instance2FinalKeysSome LinkedMap".to_vec();
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), None);
+		let head = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"HeadOfLinkedMap")].concat();
+		assert_eq!(unhashed::get::<u32>(&head), None);
 
 		<instance::LinkedMap<instance::Instance2>>::insert(1, 2);
-		let mut k = b"Instance2FinalKeysSome LinkedMap".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&k)), Some(2u32));
-		assert_eq!(unhashed::get::<u32>(&hashing::blake2_256(&head)), Some(1u32));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"LinkedMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
+		assert_eq!(unhashed::get::<u32>(&head), Some(1u32));
 
 		<instance::LinkedMap2<instance::Instance2>>::insert(1, 2);
-		let mut k = b"Instance2FinalKeysSome LinkedMap2".to_vec();
-		k.extend(1u32.encode());
-		assert_eq!(unhashed::get::<u32>(&hashing::twox_128(&k)), Some(2u32));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"LinkedMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		assert_eq!(unhashed::get::<u32>(&k), Some(2u32));
 
 		<instance::DoubleMap<instance::Instance2>>::insert(&1, &2, &3);
-		let mut k = b"Instance2FinalKeysSome DoubleMap".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::blake2_256(&k).to_vec();
-		k.extend(&hashing::blake2_256(&2u32.encode()));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"DoubleMap")].concat();
+		k.extend(1u32.using_encoded(blake2_256).to_vec());
+		k.extend(2u32.using_encoded(blake2_256).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 
 		<instance::DoubleMap2<instance::Instance2>>::insert(&1, &2, &3);
-		let mut k = b"Instance2FinalKeysSome DoubleMap2".to_vec();
-		k.extend(1u32.encode());
-		let mut k = hashing::twox_128(&k).to_vec();
-		k.extend(&hashing::blake2_128(&2u32.encode()));
+		let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"DoubleMap2")].concat();
+		k.extend(1u32.using_encoded(twox_128).to_vec());
+		k.extend(2u32.using_encoded(blake2_128).to_vec());
 		assert_eq!(unhashed::get::<u32>(&k), Some(3u32));
 	});
 }
diff --git a/substrate/frame/support/test/tests/instance.rs b/substrate/frame/support/test/tests/instance.rs
index dc4fded17ed..eff73ad6eaf 100644
--- a/substrate/frame/support/test/tests/instance.rs
+++ b/substrate/frame/support/test/tests/instance.rs
@@ -472,14 +472,3 @@ fn test_instance_storage_metadata() {
 	let metadata = Module2_2::storage_metadata();
 	pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata);
 }
-
-#[test]
-fn instance_prefix_is_prefix_of_entries() {
-	use module2::Instance;
-
-	let prefix = module2::Instance2::PREFIX;
-	assert!(module2::Instance2::PREFIX_FOR_Value.starts_with(prefix));
-	assert!(module2::Instance2::PREFIX_FOR_Map.starts_with(prefix));
-	assert!(module2::Instance2::PREFIX_FOR_LinkedMap.starts_with(prefix));
-	assert!(module2::Instance2::PREFIX_FOR_DoubleMap.starts_with(prefix));
-}
diff --git a/substrate/utils/frame/rpc/support/src/lib.rs b/substrate/utils/frame/rpc/support/src/lib.rs
index ef594b687e2..c9163bdc306 100644
--- a/substrate/utils/frame/rpc/support/src/lib.rs
+++ b/substrate/utils/frame/rpc/support/src/lib.rs
@@ -108,7 +108,7 @@ impl<V: FullCodec> StorageQuery<V> {
 	/// Create a storage query for a value in a StorageMap.
 	pub fn map<St: StorageMap<K, V>, K: FullEncode>(key: K) -> Self {
 		Self {
-			key: StorageKey(St::storage_map_final_key(key).as_ref().to_vec()),
+			key: StorageKey(St::storage_map_final_key(key)),
 			_spook: PhantomData,
 		}
 	}
@@ -116,7 +116,7 @@ impl<V: FullCodec> StorageQuery<V> {
 	/// Create a storage query for a value in a StorageLinkedMap.
 	pub fn linked_map<St: StorageLinkedMap<K, V>, K: FullCodec>(key: K) -> Self {
 		Self {
-			key: StorageKey(St::storage_linked_map_final_key(key).as_ref().to_vec()),
+			key: StorageKey(St::storage_linked_map_final_key(key)),
 			_spook: PhantomData,
 		}
 	}
-- 
GitLab