From 6244b6a3b922a774328c0bc20b152c1db6a7f8da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bastian=20K=C3=B6cher?= <bkchr@users.noreply.github.com>
Date: Thu, 25 Oct 2018 09:36:57 +0200
Subject: [PATCH] Encode `Metadata` once instead of two times (#946)

---
 substrate/core/client/src/client.rs    |  9 ++-------
 substrate/core/rpc/src/state/mod.rs    |  2 +-
 substrate/core/sr-api/src/lib.rs       |  4 ++--
 substrate/node/runtime/src/lib.rs      |  6 +++---
 substrate/srml/support/src/lib.rs      |  1 +
 substrate/srml/support/src/metadata.rs | 18 ++++++++----------
 6 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs
index 9182ab0a780..fcf917584e3 100644
--- a/substrate/core/client/src/client.rs
+++ b/substrate/core/client/src/client.rs
@@ -346,11 +346,6 @@ impl<B, E, Block> Client<B, E, Block> where
 		&self.executor
 	}
 
-	/// Returns the runtime metadata.
-	pub fn metadata(&self, id: &BlockId<Block>) -> error::Result<Vec<u8>> {
-		self.executor.call(id, "metadata",&[]).map(|v| v.return_data)
-	}
-
 	/// Reads storage value at a given block + key, returning read proof.
 	pub fn read_proof(&self, id: &BlockId<Block>, key: &[u8]) -> error::Result<Vec<Vec<u8>>> {
 		self.state_at(id)
@@ -1074,7 +1069,7 @@ impl<B, E, Block> api::Core<Block, AuthorityId> for Client<B, E, Block> where
 	}
 }
 
-impl<B, E, Block> api::Metadata<Block> for Client<B, E, Block> where
+impl<B, E, Block> api::Metadata<Block, Vec<u8>> for Client<B, E, Block> where
 	B: backend::Backend<Block, Blake2Hasher>,
 	E: CallExecutor<Block, Blake2Hasher>,
 	Block: BlockT,
@@ -1082,7 +1077,7 @@ impl<B, E, Block> api::Metadata<Block> for Client<B, E, Block> where
 	type Error = Error;
 
 	fn metadata(&self, at: &BlockId<Block>) -> Result<Vec<u8>, Self::Error> {
-		self.call_api_at(at, "metadata", &())
+		self.executor.call(at, "metadata",&[]).map(|v| v.return_data)
 	}
 }
 
diff --git a/substrate/core/rpc/src/state/mod.rs b/substrate/core/rpc/src/state/mod.rs
index 4c3110f8e14..3fda746dcb0 100644
--- a/substrate/core/rpc/src/state/mod.rs
+++ b/substrate/core/rpc/src/state/mod.rs
@@ -21,7 +21,7 @@ use std::{
 	sync::Arc,
 };
 
-use client::{self, Client, CallExecutor, BlockchainEvents};
+use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata};
 use jsonrpc_macros::Trailing;
 use jsonrpc_macros::pubsub;
 use jsonrpc_pubsub::SubscriptionId;
diff --git a/substrate/core/sr-api/src/lib.rs b/substrate/core/sr-api/src/lib.rs
index 2021e2f2a0b..b610606d02e 100644
--- a/substrate/core/sr-api/src/lib.rs
+++ b/substrate/core/sr-api/src/lib.rs
@@ -436,8 +436,8 @@ decl_apis! {
 	}
 
 	/// The `Metadata` api trait that returns metadata for the runtime.
-	pub trait Metadata {
-		fn metadata() -> Vec<u8>;
+	pub trait Metadata<Data> {
+		fn metadata() -> Data;
 	}
 
 	/// The `OldTxQueue` api trait for interfering with the old transaction queue.
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 36dcd347b96..1f4a44bb294 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -81,7 +81,7 @@ pub use timestamp::Call as TimestampCall;
 pub use balances::Call as BalancesCall;
 pub use runtime_primitives::{Permill, Perbill};
 pub use timestamp::BlockPeriod;
-pub use srml_support::StorageValue;
+pub use srml_support::{StorageValue, RuntimeMetadata};
 
 const TIMESTAMP_SET_POSITION: u32 = 0;
 const NOTE_OFFLINE_POSITION: u32 = 1;
@@ -246,8 +246,8 @@ impl_apis! {
 		}
 	}
 
-	impl Metadata for Runtime {
-		fn metadata() -> Vec<u8> {
+	impl Metadata<RuntimeMetadata> for Runtime {
+		fn metadata() -> RuntimeMetadata {
 			Runtime::metadata()
 		}
 	}
diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs
index 02747b199ae..a8b1fa88a48 100644
--- a/substrate/srml/support/src/lib.rs
+++ b/substrate/srml/support/src/lib.rs
@@ -65,6 +65,7 @@ pub mod inherent;
 pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap};
 pub use self::hashable::Hashable;
 pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType};
+pub use self::metadata::RuntimeMetadata;
 pub use runtime_io::print;
 
 #[macro_export]
diff --git a/substrate/srml/support/src/metadata.rs b/substrate/srml/support/src/metadata.rs
index 79df4815bb2..2a6b05bde2e 100644
--- a/substrate/srml/support/src/metadata.rs
+++ b/substrate/srml/support/src/metadata.rs
@@ -33,14 +33,12 @@ macro_rules! impl_runtime_metadata {
 		$( $rest:tt )*
 	) => {
 		impl $runtime {
-			pub fn metadata() -> Vec<u8> {
-				$crate::codec::Encode::encode(
-					&$crate::metadata::RuntimeMetadata {
-						outer_event: Self::outer_event_metadata(),
-						modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*),
-						outer_dispatch: Self::outer_dispatch_metadata(),
-					}
-				)
+			pub fn metadata() -> $crate::metadata::RuntimeMetadata {
+				$crate::metadata::RuntimeMetadata {
+					outer_event: Self::outer_event_metadata(),
+					modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*),
+					outer_dispatch: Self::outer_dispatch_metadata(),
+				}
 			}
 		}
 	}
@@ -105,7 +103,7 @@ mod tests {
 		StorageFunctionModifier, StorageFunctionType, FunctionMetadata,
 		StorageMetadata, StorageFunctionMetadata, OuterDispatchMetadata, OuterDispatchCall
 	};
-	use codec::Decode;
+	use codec::{Decode, Encode};
 
 	mod system {
 		pub trait Trait {
@@ -352,7 +350,7 @@ mod tests {
 
 	#[test]
 	fn runtime_metadata() {
-		let metadata_encoded = TestRuntime::metadata();
+		let metadata_encoded = TestRuntime::metadata().encode();
 		let metadata_decoded = RuntimeMetadata::decode(&mut &metadata_encoded[..]);
 
 		assert_eq!(EXPECTED_METADATA, metadata_decoded.unwrap());
-- 
GitLab