diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index c3c3e66c12e95e08a4d7012e19e05462e3baa8c4..f169f7b24e2710840f597a7c7c23587db7b53370 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -539,6 +539,30 @@ dependencies = [
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "criterion"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "criterion-plot"
 version = "0.3.1"
@@ -549,6 +573,15 @@ dependencies = [
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "criterion-plot"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "crossbeam-channel"
 version = "0.3.9"
@@ -3318,6 +3351,15 @@ dependencies = [
  "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rand_os"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rand_pcg"
 version = "0.1.2"
@@ -3344,6 +3386,14 @@ dependencies = [
  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rand_xoshiro"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rayon"
 version = "1.2.0"
@@ -3491,7 +3541,7 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "0.1.4"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3825,12 +3875,12 @@ name = "sr-api-macros"
 version = "2.0.0"
 dependencies = [
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 2.0.0",
  "sr-version 2.0.0",
  "substrate-client 2.0.0",
@@ -6829,7 +6879,9 @@ dependencies = [
 "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
 "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
 "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
+"checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6"
 "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e"
+"checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2"
 "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
 "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
 "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
@@ -7084,9 +7136,11 @@ dependencies = [
 "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
 "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
 "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a"
 "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
 "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
 "checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929"
+"checksum rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff"
 "checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123"
 "checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b"
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
@@ -7104,7 +7158,7 @@ dependencies = [
 "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e"
-"checksum rustversion 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b48139cfc215c6cc70d43c6c555a59e723c3b5adb26a4cfa09f815a5ae5871e8"
+"checksum rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48f91977f4ef3be5358c15d131d3f663f6b4d7a112555bf3bf52ad23b6659e5"
 "checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78"
 "checksum ryu 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19d2271fa48eaf61e53cc88b4ad9adcbafa2d512c531e7fadb6dc11a4d3656c5"
 "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347"
diff --git a/substrate/core/client/src/runtime_api.rs b/substrate/core/client/src/runtime_api.rs
index a5700951e9c4c64d1266f6f4f3054d22a93b1af5..68b49e5910b4511a0390bee22231027bb4def391 100644
--- a/substrate/core/client/src/runtime_api.rs
+++ b/substrate/core/client/src/runtime_api.rs
@@ -23,6 +23,9 @@ pub use state_machine::OverlayedChanges;
 #[cfg(feature = "std")]
 pub use primitives::NativeOrEncoded;
 #[doc(hidden)]
+#[cfg(not(feature = "std"))]
+pub use primitives::to_substrate_wasm_fn_return_value;
+#[doc(hidden)]
 pub use sr_primitives::{
 	traits::{
 		Block as BlockT, GetNodeBlockType, GetRuntimeBlockType,
diff --git a/substrate/core/primitives/src/lib.rs b/substrate/core/primitives/src/lib.rs
index d1b42766a08f0c970e045f75984dae1d9b4fa1ce..02f28c797c0027b4a42d30c160e2ff95b36d56e7 100644
--- a/substrate/core/primitives/src/lib.rs
+++ b/substrate/core/primitives/src/lib.rs
@@ -287,3 +287,25 @@ impl From<LogLevel> for log::Level {
 		}
 	}
 }
+
+/// Encodes the given value into a buffer and returns the pointer and the length as a single `u64`.
+///
+/// When Substrate calls into Wasm it expects a fixed signature for functions exported
+/// from the Wasm blob. The return value of this signature is always a `u64`.
+/// This `u64` stores the pointer to the encoded return value and the length of this encoded value.
+/// The low `32bits` are reserved for the pointer, followed by `32bit` for the length.
+#[cfg(not(feature = "std"))]
+pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 {
+	let encoded = value.encode();
+
+	let ptr = encoded.as_ptr() as u64;
+	let length = encoded.len() as u64;
+	let res = ptr | (length << 32);
+
+	// Leak the output vector to avoid it being freed.
+	// This is fine in a WASM context since the heap
+	// will be discarded after the call.
+	rstd::mem::forget(encoded);
+
+	res
+}
diff --git a/substrate/core/primitives/src/testing.rs b/substrate/core/primitives/src/testing.rs
index 92a09ff044f773c2f43675040ebdd065e4082a20..e5d301008e3d4fb3344ad7306b797f9b70727964 100644
--- a/substrate/core/primitives/src/testing.rs
+++ b/substrate/core/primitives/src/testing.rs
@@ -196,15 +196,7 @@ macro_rules! wasm_export_functions {
 				$( $fn_impl )*
 			}
 
-			// We need to return *something*
-			let output = Vec::<u8>::new();
-			let res = output.as_ptr() as u64 + ((output.len() as u64) << 32);
-
-			// Leak the output vector to avoid it being freed.
-			// This is fine in a WASM context since the heap
-			// will be discarded after the call.
-			$crate::rstd::mem::forget(output);
-			res
+			$crate::to_substrate_wasm_fn_return_value(&())
 		}
 	};
 	(@IMPL
@@ -232,14 +224,7 @@ macro_rules! wasm_export_functions {
 				$( $fn_impl )*
 			};
 
-			let output = $crate::Encode::encode(&output);
-			let res = output.as_ptr() as u64 + ((output.len() as u64) << 32);
-
-			// Leak the output vector to avoid it being freed.
-			// This is fine in a WASM context since the heap
-			// will be discarded after the call.
-			$crate::rstd::mem::forget(output);
-			res
+			$crate::to_substrate_wasm_fn_return_value(&output)
 		}
 	};
 }
diff --git a/substrate/core/sr-api-macros/Cargo.toml b/substrate/core/sr-api-macros/Cargo.toml
index 6f02e3040986f2842401db5cb7aa6d1d0093928d..022536136b80e31529bfdff4de71ac7ae40ae64a 100644
--- a/substrate/core/sr-api-macros/Cargo.toml
+++ b/substrate/core/sr-api-macros/Cargo.toml
@@ -21,12 +21,17 @@ state_machine = { package = "substrate-state-machine", path = "../state-machine"
 sr-primitives = {  path = "../sr-primitives" }
 sr-version = { path = "../sr-version" }
 primitives = { package = "substrate-primitives",  path = "../primitives" }
-criterion = "0.2.11"
+criterion = "0.3.0"
 consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" }
 codec = { package = "parity-scale-codec", version = "1.0.0" }
-trybuild = "1.0.14"
-rustversion = "0.1.4"
+trybuild = "1.0.17"
+rustversion = "1.0.0"
 
 [[bench]]
 name = "bench"
 harness = false
+
+# We actually don't need the `std` feature in this crate, but the tests require it.
+[features]
+default = [ "std" ]
+std = []
diff --git a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
index fb154aa1123580a1e35597b1b40f1961b6ebb522..28eb5c60729edda5f4b4b41cad03b6dbc89eb3e9 100644
--- a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
+++ b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
@@ -83,8 +83,7 @@ fn generate_impl_call(
 			)*
 
 			#[allow(deprecated)]
-			let output = <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*);
-			#c::runtime_api::Encode::encode(&output)
+			<#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*)
 		)
 	)
 }
@@ -175,11 +174,12 @@ fn generate_impl_calls(
 /// Generate the dispatch function that is used in native to call into the runtime.
 fn generate_dispatch_function(impls: &[ItemImpl]) -> Result<TokenStream> {
 	let data = Ident::new("data", Span::call_site());
+	let c = generate_crate_access(HIDDEN_INCLUDES_ID);
 	let impl_calls = generate_impl_calls(impls, &data)?
 		.into_iter()
 		.map(|(trait_, fn_name, impl_)| {
 			let name = prefix_function_with_trait(&trait_, &fn_name);
-			quote!( #name => Some({ #impl_ }), )
+			quote!( #name => Some(#c::runtime_api::Encode::encode(&{ #impl_ })), )
 		});
 
 	Ok(quote!(
@@ -218,13 +218,7 @@ fn generate_wasm_interface(impls: &[ItemImpl]) -> Result<TokenStream> {
 					};
 
 					let output = { #impl_ };
-					let res = output.as_ptr() as u64 + ((output.len() as u64) << 32);
-
-					// Leak the output vector to avoid it being freed.
-					// This is fine in a WASM context since the heap
-					// will be discarded after the call.
-					#c::runtime_api::mem::forget(output);
-					res
+					#c::runtime_api::to_substrate_wasm_fn_return_value(&output)
 				}
 			)
 		});
diff --git a/substrate/core/sr-api-macros/tests/decl_and_impl.rs b/substrate/core/sr-api-macros/tests/decl_and_impl.rs
index 36091d1f85062e6c693e0780383d0d9680b1d258..a539d838221be1409b5bd8ae8ebb451382ef82b0 100644
--- a/substrate/core/sr-api-macros/tests/decl_and_impl.rs
+++ b/substrate/core/sr-api-macros/tests/decl_and_impl.rs
@@ -93,13 +93,6 @@ fn test_client_side_function_signature() {
 			RuntimeApiImpl::<TestClient>::same_name_before_version_2;
 }
 
-#[test]
-fn test_runtime_side_function_signature() {
-	let _api_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = api::Api_same_name;
-	let _api_with_version_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 =
-		api::ApiWithCustomVersion_same_name;
-}
-
 #[test]
 fn check_runtime_api_info() {
 	assert_eq!(&Api::<Block>::ID, &runtime_decl_for_Api::ID);
diff --git a/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.rs b/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.rs
index 774d017c190e926e1a4e4d55e6ab9aa6ab46214e..b85431f3ba049b0a55e7e9ddd6a6c0d80e89cb27 100644
--- a/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.rs
+++ b/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.rs
@@ -1,6 +1,6 @@
-use sr_primitives::traits::GetNodeBlockType;
+use sr_primitives::traits::{GetNodeBlockType, Block as BlockT};
 use test_client::runtime::Block;
-use client::{decl_runtime_apis, impl_runtime_apis};
+use client::{decl_runtime_apis, impl_runtime_apis, runtime_api};
 
 /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
 /// trait are done by the `construct_runtime!` macro in a real runtime.
@@ -19,6 +19,18 @@ impl_runtime_apis! {
 	impl self::Api<Block> for Runtime {
 		fn test(data: String) {}
 	}
+
+	impl runtime_api::Core<Block> for Runtime {
+		fn version() -> runtime_api::RuntimeVersion {
+			unimplemented!()
+		}
+		fn execute_block(_: Block) {
+			unimplemented!()
+		}
+		fn initialize_block(_: &<Block as BlockT>::Header) {
+			unimplemented!()
+		}
+	}
 }
 
 fn main() {}
diff --git a/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.stderr b/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.stderr
index 15434a52ba8b78ae6876b17e34f72ff9c7e85779..025ca60c48095365e706871c1ec4a2fe3a50d10e 100644
--- a/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.stderr
+++ b/substrate/core/sr-api-macros/tests/ui/impl_incorrect_method_signature.stderr
@@ -10,6 +10,37 @@ error[E0053]: method `test` has an incompatible type for trait
    = note: expected type `fn(u64)`
               found type `fn(std::string::String)`
 
+error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait
+  --> $DIR/impl_incorrect_method_signature.rs:18:1
+   |
+12 | / decl_runtime_apis! {
+13 | |     pub trait Api {
+14 | |         fn test(data: u64);
+15 | |     }
+16 | | }
+   | |_- type in trait
+17 | 
+18 |   impl_runtime_apis! {
+   |   ^^^^^^^^^^^^^^^^^^ expected u64, found struct `std::string::String`
+   |
+   = note: expected type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
+              found type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<std::string::String>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
+
+error[E0308]: mismatched types
+  --> $DIR/impl_incorrect_method_signature.rs:18:1
+   |
+18 | / impl_runtime_apis! {
+19 | |     impl self::Api<Block> for Runtime {
+20 | |         fn test(data: String) {}
+21 | |     }
+...  |
+33 | |     }
+34 | | }
+   | |_^ expected u64, found struct `std::string::String`
+   |
+   = note: expected type `u64`
+              found type `std::string::String`
+
 error[E0308]: mismatched types
   --> $DIR/impl_incorrect_method_signature.rs:20:11
    |
@@ -18,6 +49,3 @@ error[E0308]: mismatched types
    |
    = note: expected type `u64`
               found type `std::string::String`
-
-Some errors have detailed explanations: E0053, E0308.
-For more information about an error, try `rustc --explain E0053`.
diff --git a/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.rs b/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.rs
index acca97a73df5bd2464fb736c733d84116b07c994..1664bec577b57a53715fc65b0f3234e12bd78503 100644
--- a/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.rs
+++ b/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.rs
@@ -16,6 +16,8 @@ decl_runtime_apis! {
 }
 
 mod second {
+	use super::*;
+
 	decl_runtime_apis! {
 		pub trait Api {
 			fn test2(data: u64);
diff --git a/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.stderr b/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.stderr
index 355db2864bb784a7011b5c0b8376a713371f88b2..4c37b6b716a0a97cd19bca6a5f469adc56e58ed4 100644
--- a/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.stderr
+++ b/substrate/core/sr-api-macros/tests/ui/impl_two_traits_with_same_name.stderr
@@ -1,25 +1,17 @@
 error: Two traits with the same name detected! The trait name is used to generate its ID. Please rename one trait at the declaration!
-  --> $DIR/impl_two_traits_with_same_name.rs:31:15
+  --> $DIR/impl_two_traits_with_same_name.rs:33:15
    |
-31 |     impl second::Api<Block> for Runtime {
+33 |     impl second::Api<Block> for Runtime {
    |                  ^^^
 
-error: cannot find macro `decl_runtime_apis!` in this scope
-  --> $DIR/impl_two_traits_with_same_name.rs:19:2
+error[E0277]: the trait bound `RuntimeApiImpl<RuntimeApiImplCall>: sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not satisfied
+  --> $DIR/impl_two_traits_with_same_name.rs:29:7
    |
-19 |     decl_runtime_apis! {
-   |     ^^^^^^^^^^^^^^^^^
+29 |     impl self::Api<Block> for Runtime {
+   |          ^^^^^^^^^^^^^^^^ the trait `sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not implemented for `RuntimeApiImpl<RuntimeApiImplCall>`
 
-error[E0433]: failed to resolve: could not find `runtime_decl_for_Api` in `second`
-  --> $DIR/impl_two_traits_with_same_name.rs:26:1
+error[E0277]: the trait bound `RuntimeApiImpl<RuntimeApiImplCall>: sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not satisfied
+  --> $DIR/impl_two_traits_with_same_name.rs:33:7
    |
-26 | / impl_runtime_apis! {
-27 | |     impl self::Api<Block> for Runtime {
-28 | |         fn test(data: u64) {}
-29 | |     }
-...  |
-33 | |     }
-34 | | }
-   | |_^ could not find `runtime_decl_for_Api` in `second`
-
-For more information about this error, try `rustc --explain E0433`.
+33 |     impl second::Api<Block> for Runtime {
+   |          ^^^^^^^^^^^^^^^^^^ the trait `sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::Core<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>` is not implemented for `RuntimeApiImpl<RuntimeApiImplCall>`
diff --git a/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.rs b/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.rs
index 0e7dc56951647264d532ee41c4a917883e9f5b22..20f114c6bb29e597f7c093c72be7c9ebd9501b7b 100644
--- a/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.rs
+++ b/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.rs
@@ -1,6 +1,6 @@
-use sr_primitives::traits::GetNodeBlockType;
+use sr_primitives::traits::{GetNodeBlockType, Block as BlockT};
 use test_client::runtime::Block;
-use client::{decl_runtime_apis, impl_runtime_apis};
+use client::{decl_runtime_apis, impl_runtime_apis, runtime_api};
 
 /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType`
 /// trait are done by the `construct_runtime!` macro in a real runtime.
@@ -21,6 +21,18 @@ impl_runtime_apis! {
 			unimplemented!()
 		}
 	}
+
+	impl runtime_api::Core<Block> for Runtime {
+		fn version() -> runtime_api::RuntimeVersion {
+			unimplemented!()
+		}
+		fn execute_block(_: Block) {
+			unimplemented!()
+		}
+		fn initialize_block(_: &<Block as BlockT>::Header) {
+			unimplemented!()
+		}
+	}
 }
 
 fn main() {}
diff --git a/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.stderr b/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.stderr
index 9bfc04c8db046ecba4f42d2140143a7ade6b3886..f3abaddd6ea9d757ae1b132a9274c068bc6814c6 100644
--- a/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.stderr
+++ b/substrate/core/sr-api-macros/tests/ui/type_reference_in_impl_runtime_apis_call.stderr
@@ -10,6 +10,22 @@ error[E0053]: method `test` has an incompatible type for trait
    = note: expected type `fn(u64)`
               found type `fn(&u64)`
 
+error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait
+  --> $DIR/type_reference_in_impl_runtime_apis_call.rs:18:1
+   |
+12 | / decl_runtime_apis! {
+13 | |     pub trait Api {
+14 | |         fn test(data: u64);
+15 | |     }
+16 | | }
+   | |_- type in trait
+17 | 
+18 |   impl_runtime_apis! {
+   |   ^^^^^^^^^^^^^^^^^^ expected u64, found &u64
+   |
+   = note: expected type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
+              found type `fn(&RuntimeApiImpl<RuntimeApiImplCall>, &sr_primitives::generic::block::BlockId<sr_primitives::generic::block::Block<sr_primitives::generic::header::Header<u64, sr_primitives::traits::BlakeTwo256>, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec<u8>) -> std::result::Result<sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::runtime_api::NativeOrEncoded<()>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api_client::error::Error>`
+
 error[E0308]: mismatched types
   --> $DIR/type_reference_in_impl_runtime_apis_call.rs:18:1
    |
@@ -17,13 +33,10 @@ error[E0308]: mismatched types
 19 | |     impl self::Api<Block> for Runtime {
 20 | |         fn test(data: &u64) {
 21 | |             unimplemented!()
-22 | |         }
-23 | |     }
-24 | | }
+...  |
+35 | |     }
+36 | | }
    | |_^ expected u64, found &u64
    |
    = note: expected type `u64`
               found type `&u64`
-
-Some errors have detailed explanations: E0053, E0308.
-For more information about an error, try `rustc --explain E0053`.
diff --git a/substrate/core/telemetry/src/worker/node.rs b/substrate/core/telemetry/src/worker/node.rs
index 11b1f2a81e6996da38c9636f563bbf809922b7a2..0f606e40638024c82c9c2cc96784d4faf3217580 100644
--- a/substrate/core/telemetry/src/worker/node.rs
+++ b/substrate/core/telemetry/src/worker/node.rs
@@ -58,6 +58,8 @@ struct NodeSocketConnected<TTrans: Transport> {
 	pending: VecDeque<BytesMut>,
 	/// If true, we need to flush the sink.
 	need_flush: bool,
+	/// A timeout for the socket to write data.
+	timeout: Option<Delay>,
 }
 
 /// Event that can happen with this node.
@@ -66,7 +68,16 @@ pub enum NodeEvent<TSinkErr> {
 	/// We are now connected to this node.
 	Connected,
 	/// We are now disconnected from this node.
-	Disconnected(TSinkErr),
+	Disconnected(ConnectionError<TSinkErr>),
+}
+
+/// Reason for disconnecting from a node.
+#[derive(Debug)]
+pub enum ConnectionError<TSinkErr> {
+	/// The connection timed-out.
+	Timeout,
+	/// The sink errored.
+	Sink(TSinkErr),
 }
 
 impl<TTrans: Transport> Node<TTrans> {
@@ -116,10 +127,12 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin,
 		let mut socket = mem::replace(&mut self.socket, NodeSocket::Poisoned);
 		self.socket = loop {
 			match socket {
-				NodeSocket::Connected(mut conn) =>
+				NodeSocket::Connected(mut conn) => {
 					match NodeSocketConnected::poll(Pin::new(&mut conn), cx, &self.addr) {
-						Poll::Ready(Ok(v)) => match v {}
-						Poll::Pending => break NodeSocket::Connected(conn),
+						Poll::Ready(Ok(v)) => match v {},
+						Poll::Pending => {
+							break NodeSocket::Connected(conn)
+						},
 						Poll::Ready(Err(err)) => {
 							warn!(target: "telemetry", "Disconnected from {}: {:?}", self.addr, err);
 							let timeout = gen_rand_reconnect_delay();
@@ -127,10 +140,16 @@ where TTrans: Clone + Unpin, TTrans::Dial: Unpin,
 							return Poll::Ready(NodeEvent::Disconnected(err))
 						}
 					}
+				}
 				NodeSocket::Dialing(mut s) => match Future::poll(Pin::new(&mut s), cx) {
 					Poll::Ready(Ok(sink)) => {
 						debug!(target: "telemetry", "Connected to {}", self.addr);
-						let conn = NodeSocketConnected { sink, pending: VecDeque::new(), need_flush: false };
+						let conn = NodeSocketConnected {
+							sink,
+							pending: VecDeque::new(),
+							need_flush: false,
+							timeout: None,
+						};
 						self.socket = NodeSocket::Connected(conn);
 						return Poll::Ready(NodeEvent::Connected)
 					},
@@ -189,18 +208,15 @@ where TTrans::Output: Sink<BytesMut, Error = TSinkErr>
 	fn poll(
 		mut self: Pin<&mut Self>,
 		cx: &mut Context,
-		my_addr: &Multiaddr
-	) -> Poll<Result<futures::never::Never, TSinkErr>> {
-		loop {
-			if let Some(item) = self.pending.pop_front() {
-				if let Poll::Pending = Sink::poll_ready(Pin::new(&mut self.sink), cx) {
-					self.pending.push_front(item);
-					return Poll::Pending
-				}
+		my_addr: &Multiaddr,
+	) -> Poll<Result<futures::never::Never, ConnectionError<TSinkErr>>> {
 
+		while let Some(item) = self.pending.pop_front() {
+			if let Poll::Ready(_) = Sink::poll_ready(Pin::new(&mut self.sink), cx) {
 				let item_len = item.len();
 				if let Err(err) = Sink::start_send(Pin::new(&mut self.sink), item) {
-					return Poll::Ready(Err(err))
+					self.timeout = None;
+					return Poll::Ready(Err(ConnectionError::Sink(err)))
 				}
 				trace!(
 					target: "telemetry", "Successfully sent {:?} bytes message to {}",
@@ -208,28 +224,59 @@ where TTrans::Output: Sink<BytesMut, Error = TSinkErr>
 				);
 				self.need_flush = true;
 
-			} else if self.need_flush {
-				match Sink::poll_flush(Pin::new(&mut self.sink), cx) {
-					Poll::Pending => return Poll::Pending,
-					Poll::Ready(Err(err)) => return Poll::Ready(Err(err)),
-					Poll::Ready(Ok(())) => self.need_flush = false,
+			} else {
+				self.pending.push_front(item);
+				if self.timeout.is_none() {
+					self.timeout = Some(Delay::new(Duration::from_secs(10)));
 				}
+				break;
+			}
+		}
 
-			} else {
-				match Stream::poll_next(Pin::new(&mut self.sink), cx) {
-					Poll::Ready(Some(Ok(_))) => {
-						// We poll the telemetry `Stream` because the underlying implementation relies on
-						// this in order to answer PINGs.
-						// We don't do anything with incoming messages, however.
-					},
-					Poll::Ready(Some(Err(err))) => {
-						return Poll::Ready(Err(err))
-					},
-					Poll::Pending | Poll::Ready(None) => break,
+		if self.need_flush {
+			match Sink::poll_flush(Pin::new(&mut self.sink), cx) {
+				Poll::Pending => {
+					if self.timeout.is_none() {
+						self.timeout = Some(Delay::new(Duration::from_secs(10)));
+					}
+				},
+				Poll::Ready(Err(err)) => {
+					self.timeout = None;
+					return Poll::Ready(Err(ConnectionError::Sink(err)))
+				},
+				Poll::Ready(Ok(())) => {
+					self.timeout = None;
+					self.need_flush = false;
+				},
+			}
+		}
+
+		if let Some(timeout) = self.timeout.as_mut() {
+			match Future::poll(Pin::new(timeout), cx) {
+				Poll::Pending => {},
+				Poll::Ready(Err(err)) => {
+					self.timeout = None;
+					warn!(target: "telemetry", "Connection timeout error for {} {:?}", my_addr, err);
+				}
+				Poll::Ready(Ok(_)) => {
+					self.timeout = None;
+					return Poll::Ready(Err(ConnectionError::Timeout))
 				}
 			}
 		}
 
+		match Stream::poll_next(Pin::new(&mut self.sink), cx) {
+			Poll::Ready(Some(Ok(_))) => {
+				// We poll the telemetry `Stream` because the underlying implementation relies on
+				// this in order to answer PINGs.
+				// We don't do anything with incoming messages, however.
+			},
+			Poll::Ready(Some(Err(err))) => {
+				return Poll::Ready(Err(ConnectionError::Sink(err)))
+			},
+			Poll::Pending | Poll::Ready(None) => {},
+		}
+
 		Poll::Pending
 	}
 }