diff --git a/substrate/.github/dependabot.yml b/substrate/.github/dependabot.yml
index c93461c8806ded009a54984b62a154fe386facc1..a321729dcbc81806a1ec24fdc86da68ba3085100 100644
--- a/substrate/.github/dependabot.yml
+++ b/substrate/.github/dependabot.yml
@@ -5,6 +5,3 @@ updates:
     labels: ["A2-insubstantial", "B0-silent", "C1-low 📌"]
     schedule:
       interval: "daily"
-    ignore:
-        - dependency-name: "jsonrpc-*"
-          versions: [">= 16"]
diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index bc33d4a5fed9c81b523aa888bad0c61fb723b470..5aaa7e2b1b2e2e5fbcde5d019ac9c398eb1de44e 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -104,7 +104,7 @@ checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
 dependencies = [
  "getrandom 0.2.3",
  "once_cell",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -269,7 +269,7 @@ dependencies = [
  "fastrand",
  "futures-lite",
  "libc",
- "log",
+ "log 0.4.14",
  "nb-connect",
  "once_cell",
  "parking",
@@ -332,7 +332,7 @@ dependencies = [
  "futures-lite",
  "gloo-timers",
  "kv-log-macro",
- "log",
+ "log 0.4.14",
  "memchr",
  "num_cpus",
  "once_cell",
@@ -405,7 +405,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -425,6 +425,12 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+
 [[package]]
 name = "autocfg"
 version = "1.0.1"
@@ -470,6 +476,25 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
 
+[[package]]
+name = "base64"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
+dependencies = [
+ "byteorder",
+ "safemem",
+]
+
+[[package]]
+name = "base64"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
+dependencies = [
+ "byteorder",
+]
+
 [[package]]
 name = "base64"
 version = "0.12.3"
@@ -726,7 +751,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
 dependencies = [
  "byteorder",
- "either",
  "iovec",
 ]
 
@@ -1034,7 +1058,7 @@ dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
  "gimli 0.24.0",
- "log",
+ "log 0.4.14",
  "regalloc",
  "serde",
  "smallvec 1.6.1",
@@ -1076,7 +1100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c31b783b351f966fce33e3c03498cb116d16d97a8f9978164a60920bd0d3a99c"
 dependencies = [
  "cranelift-codegen",
- "log",
+ "log 0.4.14",
  "smallvec 1.6.1",
  "target-lexicon",
 ]
@@ -1101,7 +1125,7 @@ dependencies = [
  "cranelift-entity",
  "cranelift-frontend",
  "itertools 0.10.0",
- "log",
+ "log 0.4.14",
  "serde",
  "smallvec 1.6.1",
  "thiserror",
@@ -1191,7 +1215,7 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "cfg-if 0.1.10",
  "crossbeam-utils 0.7.2",
  "lazy_static",
@@ -1230,7 +1254,7 @@ version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "cfg-if 0.1.10",
  "lazy_static",
 ]
@@ -1241,7 +1265,7 @@ version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "cfg-if 1.0.0",
  "lazy_static",
 ]
@@ -1582,7 +1606,7 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
 dependencies = [
  "atty",
  "humantime 1.3.0",
- "log",
+ "log 0.4.14",
  "regex",
  "termcolor",
 ]
@@ -1595,7 +1619,7 @@ checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
 dependencies = [
  "atty",
  "humantime 2.1.0",
- "log",
+ "log 0.4.14",
  "regex",
  "termcolor",
 ]
@@ -1651,28 +1675,6 @@ dependencies = [
  "futures 0.3.16",
 ]
 
-[[package]]
-name = "failure"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
-dependencies = [
- "backtrace",
- "failure_derive",
-]
-
-[[package]]
-name = "failure_derive"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "synstructure",
-]
-
 [[package]]
 name = "fake-simd"
 version = "0.1.2"
@@ -1710,7 +1712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4fdbe0d94371f9ce939b555dd342d0686cc4c0cadbcd4b61d70af5ff97eb4126"
 dependencies = [
  "env_logger 0.7.1",
- "log",
+ "log 0.4.14",
 ]
 
 [[package]]
@@ -1722,7 +1724,7 @@ dependencies = [
  "either",
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "num-traits",
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -1766,6 +1768,21 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
 [[package]]
 name = "fork-tree"
 version = "3.0.0"
@@ -1791,7 +1808,7 @@ dependencies = [
  "frame-system",
  "hex-literal",
  "linregress",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "paste 1.0.4",
  "serde",
@@ -1813,7 +1830,7 @@ dependencies = [
  "frame-support",
  "handlebars",
  "linked-hash-map",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-cli",
  "sc-client-db",
@@ -1880,7 +1897,7 @@ dependencies = [
  "frame-support-procedural",
  "frame-system",
  "impl-trait-for-tuples",
- "log",
+ "log 0.4.14",
  "once_cell",
  "parity-scale-codec",
  "parity-util-mem",
@@ -1966,7 +1983,7 @@ dependencies = [
  "criterion",
  "frame-support",
  "impl-trait-for-tuples",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "serde",
  "sp-core",
@@ -2105,16 +2122,6 @@ version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
 
-[[package]]
-name = "futures-cpupool"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
-dependencies = [
- "futures 0.1.31",
- "num_cpus",
-]
-
 [[package]]
 name = "futures-executor"
 version = "0.3.16"
@@ -2154,7 +2161,7 @@ version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "proc-macro-hack",
  "proc-macro2",
  "quote",
@@ -2206,7 +2213,7 @@ version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "futures 0.1.31",
  "futures-channel",
  "futures-core",
@@ -2244,7 +2251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
 dependencies = [
  "typenum",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -2315,7 +2322,7 @@ dependencies = [
  "aho-corasick",
  "bstr",
  "fnv",
- "log",
+ "log 0.4.14",
  "regex",
 ]
 
@@ -2332,24 +2339,6 @@ dependencies = [
  "web-sys",
 ]
 
-[[package]]
-name = "h2"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
-dependencies = [
- "byteorder",
- "bytes 0.4.12",
- "fnv",
- "futures 0.1.31",
- "http 0.1.21",
- "indexmap",
- "log",
- "slab",
- "string",
- "tokio-io",
-]
-
 [[package]]
 name = "h2"
 version = "0.2.7"
@@ -2361,11 +2350,11 @@ dependencies = [
  "futures-core",
  "futures-sink",
  "futures-util",
- "http 0.2.3",
+ "http",
  "indexmap",
  "slab",
  "tokio 0.2.25",
- "tokio-util",
+ "tokio-util 0.3.1",
  "tracing",
  "tracing-futures",
 ]
@@ -2382,7 +2371,7 @@ version = "3.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdb0867bbc5a3da37a753e78021d5fcf8a4db00e18dd2dd90fd36e24190e162d"
 dependencies = [
- "log",
+ "log 0.4.14",
  "pest",
  "pest_derive",
  "quick-error 2.0.0",
@@ -2512,17 +2501,6 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
-[[package]]
-name = "http"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
-dependencies = [
- "bytes 0.4.12",
- "fnv",
- "itoa",
-]
-
 [[package]]
 name = "http"
 version = "0.2.3"
@@ -2534,18 +2512,6 @@ dependencies = [
  "itoa",
 ]
 
-[[package]]
-name = "http-body"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "http 0.1.21",
- "tokio-buf",
-]
-
 [[package]]
 name = "http-body"
 version = "0.3.1"
@@ -2553,7 +2519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
 dependencies = [
  "bytes 0.5.6",
- "http 0.2.3",
+ "http",
 ]
 
 [[package]]
@@ -2563,15 +2529,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9"
 dependencies = [
  "bytes 1.0.1",
- "http 0.2.3",
+ "http",
  "pin-project-lite 0.2.6",
 ]
 
 [[package]]
 name = "httparse"
-version = "1.3.5"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
+checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
 
 [[package]]
 name = "httpdate"
@@ -2579,6 +2545,12 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
 
+[[package]]
+name = "httpdate"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
+
 [[package]]
 name = "humantime"
 version = "1.3.0"
@@ -2596,32 +2568,21 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.12.36"
+version = "0.10.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52"
+checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
 dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "futures-cpupool",
- "h2 0.1.26",
- "http 0.1.21",
- "http-body 0.1.0",
+ "base64 0.9.3",
  "httparse",
- "iovec",
- "itoa",
- "log",
- "net2",
- "rustc_version",
+ "language-tags",
+ "log 0.3.9",
+ "mime",
+ "num_cpus",
  "time",
- "tokio 0.1.22",
- "tokio-buf",
- "tokio-executor",
- "tokio-io",
- "tokio-reactor",
- "tokio-tcp",
- "tokio-threadpool",
- "tokio-timer",
- "want 0.2.0",
+ "traitobject",
+ "typeable",
+ "unicase 1.4.2",
+ "url 1.7.2",
 ]
 
 [[package]]
@@ -2634,40 +2595,41 @@ dependencies = [
  "futures-channel",
  "futures-core",
  "futures-util",
- "h2 0.2.7",
- "http 0.2.3",
+ "h2",
+ "http",
  "http-body 0.3.1",
  "httparse",
- "httpdate",
+ "httpdate 0.3.2",
  "itoa",
  "pin-project 1.0.5",
  "socket2 0.3.19",
  "tokio 0.2.25",
  "tower-service",
  "tracing",
- "want 0.3.0",
+ "want",
 ]
 
 [[package]]
 name = "hyper"
-version = "0.14.5"
+version = "0.14.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1"
+checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11"
 dependencies = [
  "bytes 1.0.1",
  "futures-channel",
  "futures-core",
  "futures-util",
- "http 0.2.3",
+ "http",
  "http-body 0.4.2",
  "httparse",
- "httpdate",
+ "httpdate 1.0.1",
  "itoa",
- "pin-project 1.0.5",
- "tokio 1.6.0",
+ "pin-project-lite 0.2.6",
+ "socket2 0.4.0",
+ "tokio 1.9.0",
  "tower-service",
  "tracing",
- "want 0.3.0",
+ "want",
 ]
 
 [[package]]
@@ -2680,7 +2642,7 @@ dependencies = [
  "ct-logs",
  "futures-util",
  "hyper 0.13.10",
- "log",
+ "log 0.4.14",
  "rustls 0.18.1",
  "rustls-native-certs 0.4.0",
  "tokio 0.2.25",
@@ -2688,6 +2650,19 @@ dependencies = [
  "webpki",
 ]
 
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes 1.0.1",
+ "hyper 0.14.11",
+ "native-tls",
+ "tokio 1.9.0",
+ "tokio-native-tls",
+]
+
 [[package]]
 name = "idna"
 version = "0.1.5"
@@ -2743,7 +2718,7 @@ dependencies = [
  "if-addrs",
  "ipnet",
  "libc",
- "log",
+ "log 0.4.14",
  "winapi 0.3.9",
 ]
 
@@ -2782,7 +2757,7 @@ version = "1.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "hashbrown 0.9.1",
  "serde",
 ]
@@ -2895,29 +2870,34 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-client-transports"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489b9c612e60c766f751ab40fcb43cbb55a1e10bb44a9b4307ed510ca598cbd7"
+checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a"
 dependencies = [
- "failure",
- "futures 0.1.31",
- "hyper 0.12.36",
+ "derive_more",
+ "futures 0.3.16",
+ "hyper 0.14.11",
+ "hyper-tls",
  "jsonrpc-core",
  "jsonrpc-pubsub",
- "log",
+ "log 0.4.14",
  "serde",
  "serde_json",
+ "tokio 1.9.0",
  "url 1.7.2",
+ "websocket",
 ]
 
 [[package]]
 name = "jsonrpc-core"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0745a6379e3edc893c84ec203589790774e4247420033e71a76d3ab4687991fa"
+checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
 dependencies = [
- "futures 0.1.31",
- "log",
+ "futures 0.3.16",
+ "futures-executor",
+ "futures-util",
+ "log 0.4.14",
  "serde",
  "serde_derive",
  "serde_json",
@@ -2925,18 +2905,19 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-core-client"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f764902d7b891344a0acb65625f32f6f7c6db006952143bd650209fbe7d94db"
+checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0"
 dependencies = [
+ "futures 0.3.16",
  "jsonrpc-client-transports",
 ]
 
 [[package]]
 name = "jsonrpc-derive"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99a847f9ec7bb52149b2786a17c9cb260d6effc6b8eeb8c16b343a487a7563a3"
+checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2"
 dependencies = [
  "proc-macro-crate 0.1.5",
  "proc-macro2",
@@ -2946,73 +2927,80 @@ dependencies = [
 
 [[package]]
 name = "jsonrpc-http-server"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb5c4513b7b542f42da107942b7b759f27120b5cc894729f88254b28dff44b7"
+checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff"
 dependencies = [
- "hyper 0.12.36",
+ "futures 0.3.16",
+ "hyper 0.14.11",
  "jsonrpc-core",
  "jsonrpc-server-utils",
- "log",
+ "log 0.4.14",
  "net2",
- "parking_lot 0.10.2",
- "unicase",
+ "parking_lot 0.11.1",
+ "unicase 2.6.0",
 ]
 
 [[package]]
 name = "jsonrpc-ipc-server"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf50e53e4eea8f421a7316c5f63e395f7bc7c4e786a6dc54d76fab6ff7aa7ce7"
+checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845"
 dependencies = [
+ "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-server-utils",
- "log",
+ "log 0.4.14",
  "parity-tokio-ipc",
- "parking_lot 0.10.2",
- "tokio-service",
+ "parking_lot 0.11.1",
+ "tower-service",
 ]
 
 [[package]]
 name = "jsonrpc-pubsub"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "639558e0604013be9787ae52f798506ae42bf4220fe587bdc5625871cc8b9c77"
+checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011"
 dependencies = [
+ "futures 0.3.16",
  "jsonrpc-core",
- "log",
- "parking_lot 0.10.2",
+ "lazy_static",
+ "log 0.4.14",
+ "parking_lot 0.11.1",
  "rand 0.7.3",
  "serde",
 ]
 
 [[package]]
 name = "jsonrpc-server-utils"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f1f3990650c033bd8f6bd46deac76d990f9bbfb5f8dc8c4767bf0a00392176"
+checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4"
 dependencies = [
- "bytes 0.4.12",
+ "bytes 1.0.1",
+ "futures 0.3.16",
  "globset",
  "jsonrpc-core",
  "lazy_static",
- "log",
- "tokio 0.1.22",
- "tokio-codec",
- "unicase",
+ "log 0.4.14",
+ "tokio 1.9.0",
+ "tokio-stream",
+ "tokio-util 0.6.7",
+ "unicase 2.6.0",
 ]
 
 [[package]]
 name = "jsonrpc-ws-server"
-version = "15.1.0"
+version = "18.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6596fe75209b73a2a75ebe1dce4e60e03b88a2b25e8807b667597f6315150d22"
+checksum = "f892c7d766369475ab7b0669f417906302d7c0fb521285c0a0c92e52e7c8e946"
 dependencies = [
+ "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-server-utils",
- "log",
+ "log 0.4.14",
  "parity-ws",
- "parking_lot 0.10.2",
+ "parking_lot 0.11.1",
  "slab",
 ]
 
@@ -3040,8 +3028,8 @@ dependencies = [
  "beef",
  "futures-channel",
  "futures-util",
- "hyper 0.14.5",
- "log",
+ "hyper 0.14.11",
+ "log 0.4.14",
  "serde",
  "serde_json",
  "soketto 0.6.0",
@@ -3058,7 +3046,7 @@ dependencies = [
  "fnv",
  "futures 0.3.16",
  "jsonrpsee-types",
- "log",
+ "log 0.4.14",
  "pin-project 1.0.5",
  "rustls 0.19.1",
  "rustls-native-certs 0.5.0",
@@ -3068,7 +3056,7 @@ dependencies = [
  "thiserror",
  "tokio 0.2.25",
  "tokio-rustls 0.15.0",
- "tokio-util",
+ "tokio-util 0.3.1",
  "url 2.2.1",
 ]
 
@@ -3105,7 +3093,7 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
 dependencies = [
- "log",
+ "log 0.4.14",
 ]
 
 [[package]]
@@ -3137,7 +3125,7 @@ checksum = "9b1b6ea8f2536f504b645ad78419c8246550e19d2c3419a167080ce08edee35a"
 dependencies = [
  "fs-swap",
  "kvdb",
- "log",
+ "log 0.4.14",
  "num_cpus",
  "owning_ref",
  "parity-util-mem",
@@ -3147,6 +3135,12 @@ dependencies = [
  "smallvec 1.6.1",
 ]
 
+[[package]]
+name = "language-tags"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
+
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -3251,7 +3245,7 @@ dependencies = [
  "futures-timer 3.0.2",
  "lazy_static",
  "libsecp256k1",
- "log",
+ "log 0.4.14",
  "multihash",
  "multistream-select",
  "parity-multiaddr",
@@ -3290,7 +3284,7 @@ dependencies = [
  "async-std-resolver",
  "futures 0.3.16",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "smallvec 1.6.1",
  "trust-dns-resolver",
 ]
@@ -3306,7 +3300,7 @@ dependencies = [
  "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -3328,7 +3322,7 @@ dependencies = [
  "hex_fmt",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -3348,7 +3342,7 @@ dependencies = [
  "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "smallvec 1.6.1",
@@ -3369,7 +3363,7 @@ dependencies = [
  "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -3395,7 +3389,7 @@ dependencies = [
  "lazy_static",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "rand 0.8.4",
  "smallvec 1.6.1",
  "socket2 0.4.0",
@@ -3412,7 +3406,7 @@ dependencies = [
  "bytes 1.0.1",
  "futures 0.3.16",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "nohash-hasher",
  "parking_lot 0.11.1",
  "rand 0.7.3",
@@ -3431,7 +3425,7 @@ dependencies = [
  "futures 0.3.16",
  "lazy_static",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "rand 0.7.3",
@@ -3451,7 +3445,7 @@ dependencies = [
  "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "rand 0.7.3",
  "void",
  "wasm-timer",
@@ -3467,7 +3461,7 @@ dependencies = [
  "bytes 1.0.1",
  "futures 0.3.16",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "prost",
  "prost-build",
  "unsigned-varint 0.7.0",
@@ -3481,7 +3475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ce3374f3b28162db9d3442c9347c4f14cb01e8290052615c7d341d40eae0599"
 dependencies = [
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "pin-project 1.0.5",
  "rand 0.7.3",
  "salsa20",
@@ -3500,7 +3494,7 @@ dependencies = [
  "futures-timer 3.0.2",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "pin-project 1.0.5",
  "prost",
  "prost-build",
@@ -3522,7 +3516,7 @@ dependencies = [
  "futures 0.3.16",
  "libp2p-core",
  "libp2p-swarm",
- "log",
+ "log 0.4.14",
  "lru",
  "minicbor",
  "rand 0.7.3",
@@ -3540,7 +3534,7 @@ dependencies = [
  "either",
  "futures 0.3.16",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "rand 0.7.3",
  "smallvec 1.6.1",
  "void",
@@ -3570,7 +3564,7 @@ dependencies = [
  "ipnet",
  "libc",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "socket2 0.4.0",
 ]
 
@@ -3583,7 +3577,7 @@ dependencies = [
  "async-std",
  "futures 0.3.16",
  "libp2p-core",
- "log",
+ "log 0.4.14",
 ]
 
 [[package]]
@@ -3610,7 +3604,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-rustls",
  "libp2p-core",
- "log",
+ "log 0.4.14",
  "quicksink",
  "rw-stream-sink",
  "soketto 0.4.2",
@@ -3731,6 +3725,15 @@ dependencies = [
  "scopeguard",
 ]
 
+[[package]]
+name = "log"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
+dependencies = [
+ "log 0.4.14",
+]
+
 [[package]]
 name = "log"
 version = "0.4.14"
@@ -3861,7 +3864,7 @@ version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -3870,7 +3873,7 @@ version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -3902,6 +3905,15 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "mime"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
+dependencies = [
+ "log 0.3.9",
+]
+
 [[package]]
 name = "minicbor"
 version = "0.8.0"
@@ -3929,7 +3941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
 dependencies = [
  "adler",
- "autocfg",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -3944,7 +3956,7 @@ dependencies = [
  "iovec",
  "kernel32-sys",
  "libc",
- "log",
+ "log 0.4.14",
  "miow 0.2.2",
  "net2",
  "slab",
@@ -3952,27 +3964,28 @@ dependencies = [
 ]
 
 [[package]]
-name = "mio-extras"
-version = "2.0.6"
+name = "mio"
+version = "0.7.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
+checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
 dependencies = [
- "lazycell",
- "log",
- "mio",
- "slab",
+ "libc",
+ "log 0.4.14",
+ "miow 0.3.6",
+ "ntapi",
+ "winapi 0.3.9",
 ]
 
 [[package]]
-name = "mio-named-pipes"
-version = "0.1.7"
+name = "mio-extras"
+version = "2.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
+checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
 dependencies = [
- "log",
- "mio",
- "miow 0.3.6",
- "winapi 0.3.9",
+ "lazycell",
+ "log 0.4.14",
+ "mio 0.6.23",
+ "slab",
 ]
 
 [[package]]
@@ -3983,7 +3996,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
 dependencies = [
  "iovec",
  "libc",
- "mio",
+ "mio 0.6.23",
 ]
 
 [[package]]
@@ -4070,7 +4083,7 @@ checksum = "7d91ec0a2440aaff5f78ec35631a7027d50386c6163aa975f7caa0d5da4b6ff8"
 dependencies = [
  "bytes 1.0.1",
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "pin-project 1.0.5",
  "smallvec 1.6.1",
  "unsigned-varint 0.7.0",
@@ -4114,6 +4127,24 @@ dependencies = [
  "rand 0.3.23",
 ]
 
+[[package]]
+name = "native-tls"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log 0.4.14",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework 2.3.0",
+ "security-framework-sys 2.3.0",
+ "tempfile",
+]
+
 [[package]]
 name = "nb-connect"
 version = "1.0.3"
@@ -4159,7 +4190,7 @@ dependencies = [
  "kvdb",
  "kvdb-rocksdb",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "node-primitives",
  "node-runtime",
  "node-testing",
@@ -4215,7 +4246,7 @@ dependencies = [
  "futures 0.3.16",
  "hex-literal",
  "libp2p-wasm-ext",
- "log",
+ "log 0.4.14",
  "nix",
  "node-executor",
  "node-inspect",
@@ -4329,7 +4360,7 @@ name = "node-inspect"
 version = "0.9.0-dev"
 dependencies = [
  "derive_more",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-cli",
  "sc-client-api",
@@ -4388,10 +4419,9 @@ dependencies = [
 name = "node-rpc-client"
 version = "2.0.0"
 dependencies = [
- "futures 0.1.31",
- "hyper 0.12.36",
+ "futures 0.3.16",
  "jsonrpc-core-client",
- "log",
+ "log 0.4.14",
  "node-primitives",
  "sc-rpc",
  "sp-tracing",
@@ -4410,7 +4440,7 @@ dependencies = [
  "frame-system-rpc-runtime-api",
  "frame-try-runtime",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "node-primitives",
  "pallet-assets",
  "pallet-authority-discovery",
@@ -4558,7 +4588,7 @@ dependencies = [
  "frame-system",
  "fs_extra",
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "node-executor",
  "node-primitives",
  "node-runtime",
@@ -4615,7 +4645,16 @@ dependencies = [
  "bitvec 0.19.5",
  "funty",
  "memchr",
- "version_check",
+ "version_check 0.9.2",
+]
+
+[[package]]
+name = "ntapi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
+dependencies = [
+ "winapi 0.3.9",
 ]
 
 [[package]]
@@ -4624,7 +4663,7 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "num-integer",
  "num-traits",
 ]
@@ -4644,7 +4683,7 @@ version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "num-traits",
 ]
 
@@ -4654,7 +4693,7 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "num-bigint",
  "num-integer",
  "num-traits",
@@ -4666,7 +4705,7 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "num-integer",
  "num-traits",
 ]
@@ -4677,7 +4716,7 @@ version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "libm",
 ]
 
@@ -4734,12 +4773,39 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
+[[package]]
+name = "openssl"
+version = "0.10.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885"
+dependencies = [
+ "bitflags",
+ "cfg-if 1.0.0",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-sys",
+]
+
 [[package]]
 name = "openssl-probe"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
+[[package]]
+name = "openssl-sys"
+version = "0.9.65"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d"
+dependencies = [
+ "autocfg 1.0.1",
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
 [[package]]
 name = "output_vt100"
 version = "0.1.2"
@@ -4847,7 +4913,7 @@ dependencies = [
  "frame-election-provider-support",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-authorship",
  "pallet-balances",
  "pallet-offences",
@@ -4874,7 +4940,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-transaction-payment",
  "parity-scale-codec",
  "sp-core",
@@ -4908,7 +4974,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "parity-scale-codec",
  "sp-core",
@@ -4927,7 +4993,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "pallet-contracts-primitives",
  "pallet-contracts-proc-macro",
@@ -5031,7 +5097,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -5071,7 +5137,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "parity-scale-codec",
  "sp-core",
@@ -5089,7 +5155,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "parity-scale-codec",
  "sp-core",
@@ -5105,7 +5171,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "lite-json",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-io",
@@ -5154,7 +5220,7 @@ dependencies = [
  "frame-election-provider-support",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-authorship",
  "pallet-balances",
  "pallet-offences",
@@ -5197,7 +5263,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-authorship",
  "pallet-session",
  "parity-scale-codec",
@@ -5249,7 +5315,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-io",
@@ -5282,7 +5348,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "serde",
  "sp-api",
@@ -5344,7 +5410,7 @@ version = "4.0.0-dev"
 dependencies = [
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-io",
@@ -5358,7 +5424,7 @@ version = "4.0.0-dev"
 dependencies = [
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "pallet-balances",
  "parity-scale-codec",
  "serde",
@@ -5447,7 +5513,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-io",
@@ -5478,7 +5544,7 @@ dependencies = [
  "frame-system",
  "impl-trait-for-tuples",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "pallet-timestamp",
  "parity-scale-codec",
  "sp-application-crypto",
@@ -5539,7 +5605,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "hex",
- "log",
+ "log 0.4.14",
  "pallet-authorship",
  "pallet-balances",
  "pallet-session",
@@ -5577,7 +5643,7 @@ dependencies = [
 name = "pallet-staking-reward-fn"
 version = "4.0.0-dev"
 dependencies = [
- "log",
+ "log 0.4.14",
  "sp-arithmetic",
 ]
 
@@ -5616,7 +5682,7 @@ dependencies = [
  "frame-support",
  "frame-system",
  "impl-trait-for-tuples",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-inherents",
@@ -5785,7 +5851,7 @@ dependencies = [
  "fs2",
  "hex",
  "libc",
- "log",
+ "log 0.4.14",
  "lz4",
  "memmap2",
  "parking_lot 0.11.1",
@@ -5845,20 +5911,15 @@ checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f"
 
 [[package]]
 name = "parity-tokio-ipc"
-version = "0.4.0"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf"
+checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
 dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
+ "futures 0.3.16",
  "libc",
- "log",
- "mio-named-pipes",
- "miow 0.3.6",
+ "log 0.4.14",
  "rand 0.7.3",
- "tokio 0.1.22",
- "tokio-named-pipes",
- "tokio-uds",
+ "tokio 1.9.0",
  "winapi 0.3.9",
 ]
 
@@ -5906,15 +5967,15 @@ checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92"
 
 [[package]]
 name = "parity-ws"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61"
+checksum = "d0ab8a461779bd022964cae2b4989fa9c99deb270bec162da2125ec03c09fcaa"
 dependencies = [
  "byteorder",
  "bytes 0.4.12",
  "httparse",
- "log",
- "mio",
+ "log 0.4.14",
+ "mio 0.6.23",
  "mio-extras",
  "rand 0.7.3",
  "sha-1 0.8.2",
@@ -6224,7 +6285,7 @@ checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
 dependencies = [
  "cfg-if 0.1.10",
  "libc",
- "log",
+ "log 0.4.14",
  "wepoll-sys",
  "winapi 0.3.9",
 ]
@@ -6347,7 +6408,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "syn",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -6360,7 +6421,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "syn",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -6373,7 +6434,7 @@ dependencies = [
  "quote",
  "syn",
  "syn-mid",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -6384,7 +6445,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
 dependencies = [
  "proc-macro2",
  "quote",
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -6441,7 +6502,7 @@ dependencies = [
  "bytes 1.0.1",
  "heck",
  "itertools 0.9.0",
- "log",
+ "log 0.4.14",
  "multimap",
  "petgraph",
  "prost",
@@ -6489,7 +6550,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f0c1a2f10b47d446372a4f397c58b329aaea72b2daf9395a623a411cb8ccb54f"
 dependencies = [
  "byteorder",
- "log",
+ "log 0.4.14",
  "parity-wasm 0.42.2",
 ]
 
@@ -6512,7 +6573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
 dependencies = [
  "env_logger 0.8.3",
- "log",
+ "log 0.4.14",
  "rand 0.8.4",
 ]
 
@@ -6571,6 +6632,25 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "rand"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
+dependencies = [
+ "autocfg 0.1.7",
+ "libc",
+ "rand_chacha 0.1.1",
+ "rand_core 0.4.2",
+ "rand_hc 0.1.0",
+ "rand_isaac",
+ "rand_jitter",
+ "rand_os",
+ "rand_pcg 0.1.2",
+ "rand_xorshift",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "rand"
 version = "0.7.3"
@@ -6597,6 +6677,16 @@ dependencies = [
  "rand_hc 0.3.0",
 ]
 
+[[package]]
+name = "rand_chacha"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
+dependencies = [
+ "autocfg 0.1.7",
+ "rand_core 0.3.1",
+]
+
 [[package]]
 name = "rand_chacha"
 version = "0.2.2"
@@ -6660,6 +6750,15 @@ dependencies = [
  "rand 0.8.4",
 ]
 
+[[package]]
+name = "rand_hc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
 [[package]]
 name = "rand_hc"
 version = "0.2.0"
@@ -6678,6 +6777,50 @@ dependencies = [
  "rand_core 0.6.2",
 ]
 
+[[package]]
+name = "rand_isaac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
+[[package]]
+name = "rand_jitter"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
+dependencies = [
+ "libc",
+ "rand_core 0.4.2",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "rand_os"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
+dependencies = [
+ "cloudabi",
+ "fuchsia-cprng",
+ "libc",
+ "rand_core 0.4.2",
+ "rdrand",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
+dependencies = [
+ "autocfg 0.1.7",
+ "rand_core 0.4.2",
+]
+
 [[package]]
 name = "rand_pcg"
 version = "0.2.1"
@@ -6696,6 +6839,15 @@ dependencies = [
  "rand_core 0.6.2",
 ]
 
+[[package]]
+name = "rand_xorshift"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
+dependencies = [
+ "rand_core 0.3.1",
+]
+
 [[package]]
 name = "rawpointer"
 version = "0.2.1"
@@ -6708,7 +6860,7 @@ version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
  "crossbeam-deque 0.8.0",
  "either",
  "rayon-core",
@@ -6798,7 +6950,7 @@ version = "0.0.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
 dependencies = [
- "log",
+ "log 0.4.14",
  "rustc-hash",
  "serde",
  "smallvec 1.6.1",
@@ -6853,7 +7005,7 @@ dependencies = [
  "hex",
  "jsonrpsee-proc-macros",
  "jsonrpsee-ws-client",
- "log",
+ "log 0.4.14",
  "pallet-elections-phragmen",
  "parity-scale-codec",
  "serde",
@@ -6970,7 +7122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
 dependencies = [
  "base64 0.12.3",
- "log",
+ "log 0.4.14",
  "ring",
  "sct",
  "webpki",
@@ -6983,7 +7135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
 dependencies = [
  "base64 0.13.0",
- "log",
+ "log 0.4.14",
  "ring",
  "sct",
  "webpki",
@@ -7055,6 +7207,12 @@ dependencies = [
  "rustc_version",
 ]
 
+[[package]]
+name = "safemem"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+
 [[package]]
 name = "salsa20"
 version = "0.7.2"
@@ -7077,7 +7235,7 @@ dependencies = [
 name = "sc-allocator"
 version = "4.0.0-dev"
 dependencies = [
- "log",
+ "log 0.4.14",
  "sp-core",
  "sp-wasm-interface",
  "thiserror",
@@ -7094,7 +7252,7 @@ dependencies = [
  "futures-timer 3.0.2",
  "ip_network",
  "libp2p",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "prost",
  "prost-build",
@@ -7121,7 +7279,7 @@ version = "0.10.0-dev"
 dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-block-builder",
@@ -7191,7 +7349,7 @@ dependencies = [
  "futures 0.3.16",
  "hex",
  "libp2p",
- "log",
+ "log 0.4.14",
  "names",
  "parity-scale-codec",
  "rand 0.7.3",
@@ -7231,7 +7389,7 @@ dependencies = [
  "kvdb",
  "kvdb-memorydb",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-executor",
@@ -7267,7 +7425,7 @@ dependencies = [
  "kvdb-memorydb",
  "kvdb-rocksdb",
  "linked-hash-map",
- "log",
+ "log 0.4.14",
  "parity-db",
  "parity-scale-codec",
  "parity-util-mem",
@@ -7298,7 +7456,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p",
- "log",
+ "log 0.4.14",
  "parking_lot 0.11.1",
  "sc-client-api",
  "serde",
@@ -7324,7 +7482,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "getrandom 0.2.3",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-block-builder",
@@ -7367,7 +7525,7 @@ dependencies = [
  "fork-tree",
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "merlin",
  "num-bigint",
  "num-rational 0.2.4",
@@ -7466,7 +7624,7 @@ dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
  "jsonrpc-derive",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-basic-authorship",
@@ -7503,7 +7661,7 @@ dependencies = [
  "derive_more",
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-client-api",
@@ -7527,7 +7685,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "impl-trait-for-tuples",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-client-api",
  "sc-consensus",
@@ -7567,7 +7725,7 @@ dependencies = [
  "hex-literal",
  "lazy_static",
  "libsecp256k1",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-wasm 0.42.2",
  "parking_lot 0.11.1",
@@ -7620,7 +7778,7 @@ dependencies = [
 name = "sc-executor-wasmi"
 version = "0.10.0-dev"
 dependencies = [
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-allocator",
  "sc-executor-common",
@@ -7637,7 +7795,7 @@ dependencies = [
  "assert_matches",
  "cfg-if 1.0.0",
  "libc",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-wasm 0.42.2",
  "pwasm-utils",
@@ -7666,7 +7824,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "linked-hash-map",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "pin-project 1.0.5",
@@ -7714,7 +7872,7 @@ dependencies = [
  "jsonrpc-derive",
  "jsonrpc-pubsub",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-block-builder",
  "sc-client-api",
@@ -7739,7 +7897,7 @@ dependencies = [
  "ansi_term 0.12.1",
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "parity-util-mem",
  "sc-client-api",
  "sc-network",
@@ -7811,7 +7969,7 @@ dependencies = [
  "libp2p",
  "linked-hash-map",
  "linked_hash_set",
- "log",
+ "log 0.4.14",
  "lru",
  "nohash-hasher",
  "parity-scale-codec",
@@ -7857,7 +8015,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p",
- "log",
+ "log 0.4.14",
  "lru",
  "quickcheck",
  "rand 0.7.3",
@@ -7878,7 +8036,7 @@ dependencies = [
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "libp2p",
- "log",
+ "log 0.4.14",
  "parking_lot 0.11.1",
  "rand 0.7.3",
  "sc-block-builder",
@@ -7909,7 +8067,7 @@ dependencies = [
  "hyper 0.13.10",
  "hyper-rustls",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "num_cpus",
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -7939,7 +8097,7 @@ version = "4.0.0-dev"
 dependencies = [
  "futures 0.3.16",
  "libp2p",
- "log",
+ "log 0.4.14",
  "rand 0.7.3",
  "serde_json",
  "sp-utils",
@@ -7950,7 +8108,7 @@ dependencies = [
 name = "sc-proposer-metrics"
 version = "0.9.0"
 dependencies = [
- "log",
+ "log 0.4.14",
  "substrate-prometheus-endpoint",
 ]
 
@@ -7959,13 +8117,12 @@ name = "sc-rpc"
 version = "4.0.0-dev"
 dependencies = [
  "assert_matches",
- "futures 0.1.31",
  "futures 0.3.16",
  "hash-db",
  "jsonrpc-core",
  "jsonrpc-pubsub",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-block-builder",
@@ -7995,7 +8152,6 @@ dependencies = [
  "sp-utils",
  "sp-version",
  "substrate-test-runtime-client",
- "tokio 0.1.22",
 ]
 
 [[package]]
@@ -8008,7 +8164,7 @@ dependencies = [
  "jsonrpc-core-client",
  "jsonrpc-derive",
  "jsonrpc-pubsub",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-chain-spec",
@@ -8026,13 +8182,13 @@ dependencies = [
 name = "sc-rpc-server"
 version = "4.0.0-dev"
 dependencies = [
- "futures 0.1.31",
+ "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-http-server",
  "jsonrpc-ipc-server",
  "jsonrpc-pubsub",
  "jsonrpc-ws-server",
- "log",
+ "log 0.4.14",
  "serde",
  "serde_json",
  "sp-runtime",
@@ -8060,14 +8216,13 @@ dependencies = [
  "async-trait",
  "directories",
  "exit-future",
- "futures 0.1.31",
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "hash-db",
  "jsonrpc-core",
  "jsonrpc-pubsub",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
@@ -8134,7 +8289,7 @@ dependencies = [
  "futures 0.1.31",
  "futures 0.3.16",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sc-block-builder",
@@ -8167,7 +8322,7 @@ dependencies = [
 name = "sc-state-db"
 version = "0.10.0-dev"
 dependencies = [
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-util-mem",
  "parity-util-mem-derive",
@@ -8205,7 +8360,7 @@ dependencies = [
  "chrono",
  "futures 0.3.16",
  "libp2p",
- "log",
+ "log 0.4.14",
  "parking_lot 0.11.1",
  "pin-project 1.0.5",
  "rand 0.7.3",
@@ -8225,7 +8380,7 @@ dependencies = [
  "atty",
  "erased-serde",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "once_cell",
  "parking_lot 0.11.1",
  "regex",
@@ -8274,7 +8429,7 @@ dependencies = [
  "hex",
  "intervalier",
  "linked-hash-map",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-util-mem",
  "parking_lot 0.11.1",
@@ -8305,7 +8460,7 @@ version = "4.0.0-dev"
 dependencies = [
  "derive_more",
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "serde",
  "sp-blockchain",
@@ -8533,6 +8688,12 @@ dependencies = [
  "opaque-debug 0.3.0",
 ]
 
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+
 [[package]]
 name = "sha2"
 version = "0.8.2"
@@ -8708,7 +8869,7 @@ dependencies = [
  "flate2",
  "futures 0.3.16",
  "httparse",
- "log",
+ "log 0.4.14",
  "rand 0.7.3",
  "sha-1 0.9.4",
 ]
@@ -8723,7 +8884,7 @@ dependencies = [
  "bytes 1.0.1",
  "futures 0.3.16",
  "httparse",
- "log",
+ "log 0.4.14",
  "rand 0.8.4",
  "sha-1 0.9.4",
 ]
@@ -8733,7 +8894,7 @@ name = "sp-api"
 version = "4.0.0-dev"
 dependencies = [
  "hash-db",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-api-proc-macro",
  "sp-core",
@@ -8762,7 +8923,7 @@ version = "2.0.1"
 dependencies = [
  "criterion",
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "rustversion",
  "sc-block-builder",
@@ -8867,7 +9028,7 @@ name = "sp-blockchain"
 version = "4.0.0-dev"
 dependencies = [
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "lru",
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -8886,7 +9047,7 @@ dependencies = [
  "async-trait",
  "futures 0.3.16",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-inherents",
@@ -8984,7 +9145,7 @@ dependencies = [
  "impl-serde",
  "lazy_static",
  "libsecp256k1",
- "log",
+ "log 0.4.14",
  "merlin",
  "num-traits",
  "parity-scale-codec",
@@ -9047,7 +9208,7 @@ name = "sp-finality-grandpa"
 version = "4.0.0-dev"
 dependencies = [
  "finality-grandpa",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "serde",
  "sp-api",
@@ -9079,7 +9240,7 @@ dependencies = [
  "futures 0.3.16",
  "hash-db",
  "libsecp256k1",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.11.1",
  "sp-core",
@@ -9210,7 +9371,7 @@ dependencies = [
  "either",
  "hash256-std-hasher",
  "impl-trait-for-tuples",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parity-util-mem",
  "paste 1.0.4",
@@ -9349,7 +9510,7 @@ version = "0.10.0-dev"
 dependencies = [
  "hash-db",
  "hex-literal",
- "log",
+ "log 0.4.14",
  "num-traits",
  "parity-scale-codec",
  "parking_lot 0.11.1",
@@ -9388,7 +9549,7 @@ dependencies = [
 name = "sp-tasks"
 version = "4.0.0-dev"
 dependencies = [
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-externalities",
@@ -9415,7 +9576,7 @@ version = "4.0.0-dev"
 dependencies = [
  "async-trait",
  "futures-timer 3.0.2",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-api",
  "sp-inherents",
@@ -9430,7 +9591,7 @@ name = "sp-tracing"
 version = "4.0.0-dev"
 dependencies = [
  "erased-serde",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "parking_lot 0.10.2",
  "serde",
@@ -9455,7 +9616,7 @@ name = "sp-transaction-storage-proof"
 version = "4.0.0-dev"
 dependencies = [
  "async-trait",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sp-core",
  "sp-inherents",
@@ -9570,15 +9731,6 @@ dependencies = [
  "generic-array 0.14.4",
 ]
 
-[[package]]
-name = "string"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
-dependencies = [
- "bytes 0.4.12",
-]
-
 [[package]]
 name = "strsim"
 version = "0.8.0"
@@ -9657,14 +9809,13 @@ version = "0.10.0-dev"
 dependencies = [
  "chrono",
  "console_error_panic_hook",
- "futures 0.1.31",
  "futures 0.3.16",
  "futures-timer 3.0.2",
  "getrandom 0.2.3",
  "js-sys",
  "kvdb-memorydb",
  "libp2p-wasm-ext",
- "log",
+ "log 0.4.14",
  "rand 0.7.3",
  "sc-chain-spec",
  "sc-informant",
@@ -9720,7 +9871,7 @@ dependencies = [
  "jsonrpc-core",
  "jsonrpc-core-client",
  "jsonrpc-derive",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "sc-client-api",
  "sc-rpc-api",
@@ -9744,7 +9895,7 @@ dependencies = [
  "derive_more",
  "futures-util",
  "hyper 0.13.10",
- "log",
+ "log 0.4.14",
  "prometheus",
  "tokio 0.2.25",
 ]
@@ -9754,7 +9905,6 @@ name = "substrate-test-client"
 version = "2.0.1"
 dependencies = [
  "async-trait",
- "futures 0.1.31",
  "futures 0.3.16",
  "hash-db",
  "hex",
@@ -9786,7 +9936,7 @@ dependencies = [
  "frame-system",
  "frame-system-rpc-runtime-api",
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "memory-db",
  "pallet-babe",
  "pallet-timestamp",
@@ -9995,7 +10145,7 @@ dependencies = [
  "frame-system",
  "futures 0.3.16",
  "jsonrpc-core",
- "log",
+ "log 0.4.14",
  "num-traits",
  "sc-basic-authorship",
  "sc-cli",
@@ -10040,7 +10190,7 @@ dependencies = [
  "frame-benchmarking",
  "frame-support",
  "frame-system",
- "log",
+ "log 0.4.14",
  "node-cli",
  "node-primitives",
  "node-runtime",
@@ -10184,7 +10334,7 @@ checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
 dependencies = [
  "bytes 0.4.12",
  "futures 0.1.31",
- "mio",
+ "mio 0.6.23",
  "num_cpus",
  "tokio-codec",
  "tokio-current-thread",
@@ -10213,35 +10363,34 @@ dependencies = [
  "lazy_static",
  "libc",
  "memchr",
- "mio",
+ "mio 0.6.23",
  "mio-uds",
  "num_cpus",
  "pin-project-lite 0.1.12",
  "signal-hook-registry",
  "slab",
- "tokio-macros",
+ "tokio-macros 0.2.6",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "tokio"
-version = "1.6.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd3076b5c8cc18138b8f8814895c11eb4de37114a5d127bafdc5e55798ceef37"
+checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
 dependencies = [
- "autocfg",
+ "autocfg 1.0.1",
+ "bytes 1.0.1",
+ "libc",
+ "memchr",
+ "mio 0.7.13",
+ "num_cpus",
+ "once_cell",
+ "parking_lot 0.11.1",
  "pin-project-lite 0.2.6",
-]
-
-[[package]]
-name = "tokio-buf"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
-dependencies = [
- "bytes 0.4.12",
- "either",
- "futures 0.1.31",
+ "signal-hook-registry",
+ "tokio-macros 1.3.0",
+ "winapi 0.3.9",
 ]
 
 [[package]]
@@ -10294,7 +10443,7 @@ checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
 dependencies = [
  "bytes 0.4.12",
  "futures 0.1.31",
- "log",
+ "log 0.4.14",
 ]
 
 [[package]]
@@ -10309,16 +10458,24 @@ dependencies = [
 ]
 
 [[package]]
-name = "tokio-named-pipes"
-version = "0.1.0"
+name = "tokio-macros"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae"
+checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
 dependencies = [
- "bytes 0.4.12",
- "futures 0.1.31",
- "mio",
- "mio-named-pipes",
- "tokio 0.1.22",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
+dependencies = [
+ "native-tls",
+ "tokio 1.9.0",
 ]
 
 [[package]]
@@ -10330,8 +10487,8 @@ dependencies = [
  "crossbeam-utils 0.7.2",
  "futures 0.1.31",
  "lazy_static",
- "log",
- "mio",
+ "log 0.4.14",
+ "mio 0.6.23",
  "num_cpus",
  "parking_lot 0.9.0",
  "slab",
@@ -10365,12 +10522,14 @@ dependencies = [
 ]
 
 [[package]]
-name = "tokio-service"
-version = "0.1.0"
+name = "tokio-stream"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
+checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f"
 dependencies = [
- "futures 0.1.31",
+ "futures-core",
+ "pin-project-lite 0.2.6",
+ "tokio 1.9.0",
 ]
 
 [[package]]
@@ -10392,7 +10551,7 @@ dependencies = [
  "bytes 0.4.12",
  "futures 0.1.31",
  "iovec",
- "mio",
+ "mio 0.6.23",
  "tokio-io",
  "tokio-reactor",
 ]
@@ -10408,7 +10567,7 @@ dependencies = [
  "crossbeam-utils 0.7.2",
  "futures 0.1.31",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "num_cpus",
  "slab",
  "tokio-executor",
@@ -10426,6 +10585,17 @@ dependencies = [
  "tokio-executor",
 ]
 
+[[package]]
+name = "tokio-tls"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c"
+dependencies = [
+ "futures 0.1.31",
+ "native-tls",
+ "tokio-io",
+]
+
 [[package]]
 name = "tokio-udp"
 version = "0.1.6"
@@ -10434,8 +10604,8 @@ checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82"
 dependencies = [
  "bytes 0.4.12",
  "futures 0.1.31",
- "log",
- "mio",
+ "log 0.4.14",
+ "mio 0.6.23",
  "tokio-codec",
  "tokio-io",
  "tokio-reactor",
@@ -10451,8 +10621,8 @@ dependencies = [
  "futures 0.1.31",
  "iovec",
  "libc",
- "log",
- "mio",
+ "log 0.4.14",
+ "mio 0.6.23",
  "mio-uds",
  "tokio-codec",
  "tokio-io",
@@ -10469,11 +10639,25 @@ dependencies = [
  "futures-core",
  "futures-io",
  "futures-sink",
- "log",
+ "log 0.4.14",
  "pin-project-lite 0.1.12",
  "tokio 0.2.25",
 ]
 
+[[package]]
+name = "tokio-util"
+version = "0.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
+dependencies = [
+ "bytes 1.0.1",
+ "futures-core",
+ "futures-sink",
+ "log 0.4.14",
+ "pin-project-lite 0.2.6",
+ "tokio 1.9.0",
+]
+
 [[package]]
 name = "toml"
 version = "0.5.8"
@@ -10496,7 +10680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
 dependencies = [
  "cfg-if 1.0.0",
- "log",
+ "log 0.4.14",
  "pin-project-lite 0.2.6",
  "tracing-attributes",
  "tracing-core",
@@ -10539,7 +10723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
 dependencies = [
  "lazy_static",
- "log",
+ "log 0.4.14",
  "tracing-core",
 ]
 
@@ -10575,6 +10759,12 @@ dependencies = [
  "tracing-serde",
 ]
 
+[[package]]
+name = "traitobject"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
+
 [[package]]
 name = "treeline"
 version = "0.1.0"
@@ -10605,7 +10795,7 @@ checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa"
 dependencies = [
  "hash-db",
  "hashbrown 0.11.2",
- "log",
+ "log 0.4.14",
  "rustc-hex",
  "smallvec 1.6.1",
 ]
@@ -10645,7 +10835,7 @@ dependencies = [
  "idna 0.2.2",
  "ipnet",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "rand 0.8.4",
  "smallvec 1.6.1",
  "thiserror",
@@ -10663,7 +10853,7 @@ dependencies = [
  "futures-util",
  "ipconfig",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "lru-cache",
  "parking_lot 0.11.1",
  "resolv-conf",
@@ -10683,7 +10873,7 @@ name = "try-runtime-cli"
 version = "0.10.0-dev"
 dependencies = [
  "frame-try-runtime",
- "log",
+ "log 0.4.14",
  "parity-scale-codec",
  "remote-externalities",
  "sc-chain-spec",
@@ -10728,6 +10918,12 @@ dependencies = [
  "static_assertions",
 ]
 
+[[package]]
+name = "typeable"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
+
 [[package]]
 name = "typenum"
 version = "1.12.0"
@@ -10752,13 +10948,22 @@ dependencies = [
  "static_assertions",
 ]
 
+[[package]]
+name = "unicase"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
+dependencies = [
+ "version_check 0.1.5",
+]
+
 [[package]]
 name = "unicase"
 version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
 dependencies = [
- "version_check",
+ "version_check 0.9.2",
 ]
 
 [[package]]
@@ -10893,6 +11098,12 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
 
+[[package]]
+name = "version_check"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
+
 [[package]]
 name = "version_check"
 version = "0.9.2"
@@ -10931,24 +11142,13 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "want"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
-dependencies = [
- "futures 0.1.31",
- "log",
- "try-lock",
-]
-
 [[package]]
 name = "want"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
 dependencies = [
- "log",
+ "log 0.4.14",
  "try-lock",
 ]
 
@@ -10984,7 +11184,7 @@ checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
 dependencies = [
  "bumpalo",
  "lazy_static",
- "log",
+ "log 0.4.14",
  "proc-macro2",
  "quote",
  "syn",
@@ -11062,7 +11262,7 @@ version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9"
 dependencies = [
- "log",
+ "log 0.4.14",
  "parity-wasm 0.32.0",
  "rustc-demangle",
 ]
@@ -11127,7 +11327,7 @@ dependencies = [
  "indexmap",
  "lazy_static",
  "libc",
- "log",
+ "log 0.4.14",
  "paste 1.0.4",
  "psm",
  "region",
@@ -11157,7 +11357,7 @@ dependencies = [
  "errno",
  "file-per-thread-logger",
  "libc",
- "log",
+ "log 0.4.14",
  "serde",
  "sha2 0.9.3",
  "toml",
@@ -11208,7 +11408,7 @@ dependencies = [
  "cranelift-wasm",
  "gimli 0.24.0",
  "indexmap",
- "log",
+ "log 0.4.14",
  "more-asserts",
  "serde",
  "thiserror",
@@ -11230,7 +11430,7 @@ dependencies = [
  "cranelift-native",
  "cranelift-wasm",
  "gimli 0.24.0",
- "log",
+ "log 0.4.14",
  "more-asserts",
  "object 0.24.0",
  "rayon",
@@ -11291,7 +11491,7 @@ dependencies = [
  "indexmap",
  "lazy_static",
  "libc",
- "log",
+ "log 0.4.14",
  "mach",
  "memoffset 0.6.1",
  "more-asserts",
@@ -11349,6 +11549,47 @@ dependencies = [
  "webpki",
 ]
 
+[[package]]
+name = "websocket"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0"
+dependencies = [
+ "bytes 0.4.12",
+ "futures 0.1.31",
+ "hyper 0.10.16",
+ "native-tls",
+ "rand 0.6.5",
+ "tokio-codec",
+ "tokio-io",
+ "tokio-reactor",
+ "tokio-tcp",
+ "tokio-tls",
+ "unicase 1.4.2",
+ "url 1.7.2",
+ "websocket-base",
+]
+
+[[package]]
+name = "websocket-base"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374"
+dependencies = [
+ "base64 0.10.1",
+ "bitflags",
+ "byteorder",
+ "bytes 0.4.12",
+ "futures 0.1.31",
+ "native-tls",
+ "rand 0.6.5",
+ "sha1",
+ "tokio-codec",
+ "tokio-io",
+ "tokio-tcp",
+ "tokio-tls",
+]
+
 [[package]]
 name = "wepoll-sys"
 version = "3.0.1"
@@ -11460,7 +11701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107"
 dependencies = [
  "futures 0.3.16",
- "log",
+ "log 0.4.14",
  "nohash-hasher",
  "parking_lot 0.11.1",
  "rand 0.8.4",
diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml
index 21f28764eab4f216f7b9b5efb2bd88f77202987c..98d880b95d70d2602975a35a15a400ffad20bf9a 100644
--- a/substrate/bin/node-template/node/Cargo.toml
+++ b/substrate/bin/node-template/node/Cargo.toml
@@ -39,7 +39,7 @@ sp-runtime = { version = "4.0.0-dev", path = "../../../primitives/runtime" }
 sp-timestamp = { version = "4.0.0-dev", path = "../../../primitives/timestamp" }
 
 # These dependencies are used for the node template's RPCs
-jsonrpc-core = "15.1.0"
+jsonrpc-core = "18.0.0"
 sc-rpc = { version = "4.0.0-dev", path = "../../../client/rpc" }
 sp-api = { version = "4.0.0-dev", path = "../../../primitives/api" }
 sc-rpc-api = { version = "0.10.0-dev", path = "../../../client/rpc-api" }
diff --git a/substrate/bin/node/bench/src/construct.rs b/substrate/bin/node/bench/src/construct.rs
index eeeb833c1ff123e0b8f5842fc1298631665ff238..1532e02bd3ef67cb7913e88b33d52693ffa647c1 100644
--- a/substrate/bin/node/bench/src/construct.rs
+++ b/substrate/bin/node/bench/src/construct.rs
@@ -248,7 +248,7 @@ impl sc_transaction_pool_api::TransactionPool for Transactions {
 		_at: &BlockId<Self::Block>,
 		_source: TransactionSource,
 		_xt: TransactionFor<Self>,
-	) -> PoolFuture<Box<TransactionStatusStreamFor<Self>>, Self::Error> {
+	) -> PoolFuture<Pin<Box<TransactionStatusStreamFor<Self>>>, Self::Error> {
 		unimplemented!()
 	}
 
diff --git a/substrate/bin/node/browser-testing/Cargo.toml b/substrate/bin/node/browser-testing/Cargo.toml
index 17b3966766b9b243541b07692a296b3260f59f0c..b4f2cfa5ecec16981056c9894bc23d51f9eccca1 100644
--- a/substrate/bin/node/browser-testing/Cargo.toml
+++ b/substrate/bin/node/browser-testing/Cargo.toml
@@ -9,7 +9,7 @@ license = "Apache-2.0"
 [dependencies]
 futures-timer = "3.0.2"
 libp2p = { version = "0.37.1", default-features = false }
-jsonrpc-core = "15.0.0"
+jsonrpc-core = "18.0.0"
 serde = "1.0.126"
 serde_json = "1.0.48"
 wasm-bindgen = { version = "=0.2.73", features = ["serde-serialize"] }
diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml
index 1b5173246c38718a85578947eb0c4a519d26d3cc..df432ab26647241cd937f3e0bbf3414291de656c 100644
--- a/substrate/bin/node/cli/Cargo.toml
+++ b/substrate/bin/node/cli/Cargo.toml
@@ -36,7 +36,7 @@ crate-type = ["cdylib", "rlib"]
 # third-party dependencies
 codec = { package = "parity-scale-codec", version = "2.0.0" }
 serde = { version = "1.0.126", features = ["derive"] }
-futures = { version = "0.3.9", features = ["compat"] }
+futures = "0.3.16"
 hex-literal = "0.3.1"
 log = "0.4.8"
 rand = "0.7.2"
diff --git a/substrate/bin/node/rpc-client/Cargo.toml b/substrate/bin/node/rpc-client/Cargo.toml
index 9ccb6c0817fd040a4c582b345bec4fac37fc927c..4cf3e57994db561b90f84b3450a290894b031c6b 100644
--- a/substrate/bin/node/rpc-client/Cargo.toml
+++ b/substrate/bin/node/rpc-client/Cargo.toml
@@ -11,9 +11,8 @@ repository = "https://github.com/paritytech/substrate/"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-futures = "0.1.29"
-hyper = "~0.12.35"
-jsonrpc-core-client = { version = "15.1.0", default-features = false, features = ["http"] }
+futures = "0.3.16"
+jsonrpc-core-client = { version = "18.0.0", default-features = false, features = ["http"] }
 log = "0.4.8"
 node-primitives = { version = "2.0.0", path = "../primitives" }
 sp-tracing = { version = "4.0.0-dev", path = "../../../primitives/tracing" }
diff --git a/substrate/bin/node/rpc-client/src/main.rs b/substrate/bin/node/rpc-client/src/main.rs
index 46e700a73911b8df1a1633cfa4d5eee9c91dd5fd..6d0b88799f54cf7b6ad065f2b793d39b1573b686 100644
--- a/substrate/bin/node/rpc-client/src/main.rs
+++ b/substrate/bin/node/rpc-client/src/main.rs
@@ -22,24 +22,21 @@
 //! This module shows how you can write a Rust RPC client that connects to a running
 //! substrate node and use statically typed RPC wrappers.
 
-use futures::Future;
-use hyper::rt;
+use futures::{Future, TryFutureExt};
 use jsonrpc_core_client::{transports::http, RpcError};
 use node_primitives::Hash;
 use sc_rpc::author::{hash::ExtrinsicOrHash, AuthorClient};
 
-fn main() {
+fn main() -> Result<(), RpcError> {
 	sp_tracing::try_init_simple();
 
-	rt::run(rt::lazy(|| {
+	futures::executor::block_on(async {
 		let uri = "http://localhost:9933";
 
 		http::connect(uri)
 			.and_then(|client: AuthorClient<Hash, Hash>| remove_all_extrinsics(client))
-			.map_err(|e| {
-				println!("Error: {:?}", e);
-			})
-	}))
+			.await
+	})
 }
 
 /// Remove all pending extrinsics from the node.
@@ -52,7 +49,7 @@ fn main() {
 /// to be removed and the extrinsics are going to be temporarily banned.
 fn remove_all_extrinsics(
 	client: AuthorClient<Hash, Hash>,
-) -> impl Future<Item = (), Error = RpcError> {
+) -> impl Future<Output = Result<(), RpcError>> {
 	client
 		.pending_extrinsics()
 		.and_then(move |pending| {
@@ -60,7 +57,7 @@ fn remove_all_extrinsics(
 				pending.into_iter().map(|tx| ExtrinsicOrHash::Extrinsic(tx.into())).collect(),
 			)
 		})
-		.map(|removed| {
+		.map_ok(|removed| {
 			println!("Removed extrinsics: {:?}", removed);
 		})
 }
diff --git a/substrate/bin/node/rpc/Cargo.toml b/substrate/bin/node/rpc/Cargo.toml
index 464971379c4929709e39c4c871e9c371e376b6a0..971a02e733867bdab5b5d9af08dbbc535882a424 100644
--- a/substrate/bin/node/rpc/Cargo.toml
+++ b/substrate/bin/node/rpc/Cargo.toml
@@ -11,7 +11,7 @@ repository = "https://github.com/paritytech/substrate/"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-jsonrpc-core = "15.1.0"
+jsonrpc-core = "18.0.0"
 node-primitives = { version = "2.0.0", path = "../primitives" }
 pallet-contracts-rpc = { version = "4.0.0-dev", path = "../../../frame/contracts/rpc/" }
 pallet-mmr-rpc = { version = "3.0.0", path = "../../../frame/merkle-mountain-range/rpc/" }
diff --git a/substrate/client/consensus/babe/rpc/Cargo.toml b/substrate/client/consensus/babe/rpc/Cargo.toml
index 5081edf25594f5aff5b1c9aa45b88e47e0c1ad6c..0f6c411a730e4514c31358860bf6059bbcce9a32 100644
--- a/substrate/client/consensus/babe/rpc/Cargo.toml
+++ b/substrate/client/consensus/babe/rpc/Cargo.toml
@@ -15,15 +15,15 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 sc-consensus-babe = { version = "0.10.0-dev", path = "../" }
 sc-rpc-api = { version = "0.10.0-dev", path = "../../../rpc-api" }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 sp-consensus-babe = { version = "0.10.0-dev", path = "../../../../primitives/consensus/babe" }
 serde = { version = "1.0.126", features=["derive"] }
 sp-blockchain = { version = "4.0.0-dev", path = "../../../../primitives/blockchain" }
 sp-runtime = { version = "4.0.0-dev", path = "../../../../primitives/runtime" }
 sc-consensus-epochs = { version = "0.10.0-dev", path = "../../epochs" }
-futures = { version = "0.3.4", features = ["compat"] }
+futures = "0.3.16"
 derive_more = "0.99.2"
 sp-api = { version = "4.0.0-dev", path = "../../../../primitives/api" }
 sp-consensus = { version = "0.10.0-dev", path = "../../../../primitives/consensus/common" }
diff --git a/substrate/client/consensus/babe/rpc/src/lib.rs b/substrate/client/consensus/babe/rpc/src/lib.rs
index e85a4306553711a91753f6dd5eec101be9a05b64..285cfe543cee8aa955122b713a3a6b7d3f0c5f00 100644
--- a/substrate/client/consensus/babe/rpc/src/lib.rs
+++ b/substrate/client/consensus/babe/rpc/src/lib.rs
@@ -18,8 +18,8 @@
 
 //! RPC api for babe.
 
-use futures::{FutureExt as _, TryFutureExt as _};
-use jsonrpc_core::{futures::future as rpc_future, Error as RpcError};
+use futures::{FutureExt, TryFutureExt};
+use jsonrpc_core::Error as RpcError;
 use jsonrpc_derive::rpc;
 use sc_consensus_babe::{authorship, Config, Epoch};
 use sc_consensus_epochs::{descendent_query, Epoch as EpochT, SharedEpochChanges};
@@ -35,7 +35,7 @@ use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
 use sp_runtime::traits::{Block as BlockT, Header as _};
 use std::{collections::HashMap, sync::Arc};
 
-type FutureResult<T> = Box<dyn rpc_future::Future<Item = T, Error = RpcError> + Send>;
+type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T, RpcError>>;
 
 /// Provides rpc methods for interacting with Babe.
 #[rpc]
@@ -88,7 +88,7 @@ where
 {
 	fn epoch_authorship(&self) -> FutureResult<HashMap<AuthorityId, EpochAuthorship>> {
 		if let Err(err) = self.deny_unsafe.check_if_safe() {
-			return Box::new(rpc_future::err(err.into()))
+			return async move { Err(err.into()) }.boxed()
 		}
 
 		let (babe_config, keystore, shared_epoch, client, select_chain) = (
@@ -98,7 +98,8 @@ where
 			self.client.clone(),
 			self.select_chain.clone(),
 		);
-		let future = async move {
+
+		async move {
 			let header = select_chain.best_chain().map_err(Error::Consensus).await?;
 			let epoch_start = client
 				.runtime_api()
@@ -149,9 +150,7 @@ where
 
 			Ok(claims)
 		}
-		.boxed();
-
-		Box::new(future.compat())
+		.boxed()
 	}
 }
 
diff --git a/substrate/client/consensus/manual-seal/Cargo.toml b/substrate/client/consensus/manual-seal/Cargo.toml
index a0de596b005b7708cc518521cdd21c6cce04e15a..82969c91652ddfb257406c2d14b38a028f1c2dbc 100644
--- a/substrate/client/consensus/manual-seal/Cargo.toml
+++ b/substrate/client/consensus/manual-seal/Cargo.toml
@@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 derive_more = "0.99.2"
 futures = "0.3.9"
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 log = "0.4.8"
 parking_lot = "0.11.1"
 codec = { package = "parity-scale-codec", version = "2.0.0" }
diff --git a/substrate/client/consensus/manual-seal/src/rpc.rs b/substrate/client/consensus/manual-seal/src/rpc.rs
index 699505b00c3c295b5d243e607e5606919bff09e1..6755879ceedd659784278bd5e00f4611f3c18824 100644
--- a/substrate/client/consensus/manual-seal/src/rpc.rs
+++ b/substrate/client/consensus/manual-seal/src/rpc.rs
@@ -30,7 +30,7 @@ use serde::{Deserialize, Serialize};
 use sp_runtime::EncodedJustification;
 
 /// Future's type for jsonrpc
-type FutureResult<T> = Box<dyn jsonrpc_core::futures::Future<Item = T, Error = Error> + Send>;
+type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T, Error>>;
 /// sender passed to the authorship task to report errors or successes.
 pub type Sender<T> = Option<oneshot::Sender<std::result::Result<T, crate::Error>>>;
 
@@ -114,7 +114,7 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
 		parent_hash: Option<Hash>,
 	) -> FutureResult<CreatedBlock<Hash>> {
 		let mut sink = self.import_block_channel.clone();
-		let future = async move {
+		async move {
 			let (sender, receiver) = oneshot::channel();
 			let command = EngineCommand::SealNewBlock {
 				create_empty,
@@ -125,9 +125,8 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
 			sink.send(command).await?;
 			receiver.await?
 		}
-		.boxed();
-
-		Box::new(future.map_err(Error::from).compat())
+		.map_err(Error::from)
+		.boxed()
 	}
 
 	fn finalize_block(
@@ -136,15 +135,15 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
 		justification: Option<EncodedJustification>,
 	) -> FutureResult<bool> {
 		let mut sink = self.import_block_channel.clone();
-		let future = async move {
+		async move {
 			let (sender, receiver) = oneshot::channel();
 			sink.send(EngineCommand::FinalizeBlock { hash, sender: Some(sender), justification })
 				.await?;
 
 			receiver.await?.map(|_| true)
-		};
-
-		Box::new(future.boxed().map_err(Error::from).compat())
+		}
+		.map_err(Error::from)
+		.boxed()
 	}
 }
 
diff --git a/substrate/client/consensus/pow/Cargo.toml b/substrate/client/consensus/pow/Cargo.toml
index 368005fafb13666f7c314880599d1dd18ca995f5..c71e11aef275ed5a5271f2c1515bead22d218439 100644
--- a/substrate/client/consensus/pow/Cargo.toml
+++ b/substrate/client/consensus/pow/Cargo.toml
@@ -25,7 +25,7 @@ sp-consensus-pow = { version = "0.10.0-dev", path = "../../../primitives/consens
 sp-consensus = { version = "0.10.0-dev", path = "../../../primitives/consensus/common" }
 sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/common" }
 log = "0.4.8"
-futures = { version = "0.3.1", features = ["compat"] }
+futures = "0.3.16"
 futures-timer = "3.0.1"
 parking_lot = "0.11.1"
 derive_more = "0.99.2"
diff --git a/substrate/client/finality-grandpa/rpc/Cargo.toml b/substrate/client/finality-grandpa/rpc/Cargo.toml
index e965f9279bd37f6132d95b53ff59b9bf13d82e8e..13fcd3f7392daeba9688b40ed5ff013feafbd22b 100644
--- a/substrate/client/finality-grandpa/rpc/Cargo.toml
+++ b/substrate/client/finality-grandpa/rpc/Cargo.toml
@@ -15,11 +15,11 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain"
 sp-core = { version = "4.0.0-dev", path = "../../../primitives/core" }
 sp-runtime = { version = "4.0.0-dev", path = "../../../primitives/runtime" }
 finality-grandpa = { version = "0.14.1", features = ["derive-codec"] }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
-jsonrpc-pubsub = "15.1.0"
-futures = { version = "0.3.4", features = ["compat"] }
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
+jsonrpc-pubsub = "18.0.0"
+futures = "0.3.16"
 serde = { version = "1.0.105", features = ["derive"] }
 serde_json = "1.0.50"
 log = "0.4.8"
diff --git a/substrate/client/finality-grandpa/rpc/src/lib.rs b/substrate/client/finality-grandpa/rpc/src/lib.rs
index 42d8630d10f832c34c6558640f0b63a1b3576d01..b8b8b2d9564632a0e7c1bafa58794e98386ae1e0 100644
--- a/substrate/client/finality-grandpa/rpc/src/lib.rs
+++ b/substrate/client/finality-grandpa/rpc/src/lib.rs
@@ -19,12 +19,7 @@
 //! RPC API for GRANDPA.
 #![warn(missing_docs)]
 
-use futures::{FutureExt, StreamExt, TryFutureExt, TryStreamExt};
-use jsonrpc_core::futures::{
-	future::{Executor as Executor01, Future as Future01},
-	sink::Sink as Sink01,
-	stream::Stream as Stream01,
-};
+use futures::{task::Spawn, FutureExt, SinkExt, StreamExt, TryFutureExt};
 use jsonrpc_derive::rpc;
 use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
 use log::warn;
@@ -42,8 +37,7 @@ use finality::{EncodedFinalityProof, RpcFinalityProofProvider};
 use notification::JustificationNotification;
 use report::{ReportAuthoritySet, ReportVoterState, ReportedRoundStates};
 
-type FutureResult<T> =
-	Box<dyn jsonrpc_core::futures::Future<Item = T, Error = jsonrpc_core::Error> + Send>;
+type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T, jsonrpc_core::Error>>;
 
 /// Provides RPC methods for interacting with GRANDPA.
 #[rpc]
@@ -108,7 +102,7 @@ impl<AuthoritySet, VoterState, Block: BlockT, ProofProvider>
 		finality_proof_provider: Arc<ProofProvider>,
 	) -> Self
 	where
-		E: Executor01<Box<dyn Future01<Item = (), Error = ()> + Send>> + Send + Sync + 'static,
+		E: Spawn + Sync + Send + 'static,
 	{
 		let manager = SubscriptionManager::new(Arc::new(executor));
 		Self { authority_set, voter_state, justification_stream, manager, finality_proof_provider }
@@ -129,7 +123,7 @@ where
 	fn round_state(&self) -> FutureResult<ReportedRoundStates> {
 		let round_states = ReportedRoundStates::from(&self.authority_set, &self.voter_state);
 		let future = async move { round_states }.boxed();
-		Box::new(future.map_err(jsonrpc_core::Error::from).compat())
+		future.map_err(jsonrpc_core::Error::from).boxed()
 	}
 
 	fn subscribe_justifications(
@@ -140,14 +134,11 @@ where
 		let stream = self
 			.justification_stream
 			.subscribe()
-			.map(|x| Ok::<_, ()>(JustificationNotification::from(x)))
-			.map_err(|e| warn!("Notification stream error: {:?}", e))
-			.compat();
+			.map(|x| Ok(Ok::<_, jsonrpc_core::Error>(JustificationNotification::from(x))));
 
 		self.manager.add(subscriber, |sink| {
-			let stream = stream.map(|res| Ok(res));
-			sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-				.send_all(stream)
+			stream
+				.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 				.map(|_| ())
 		});
 	}
@@ -166,15 +157,13 @@ where
 	) -> FutureResult<Option<EncodedFinalityProof>> {
 		let result = self.finality_proof_provider.rpc_prove_finality(block);
 		let future = async move { result }.boxed();
-		Box::new(
-			future
-				.map_err(|e| {
-					warn!("Error proving finality: {}", e);
-					error::Error::ProveFinalityFailed(e)
-				})
-				.map_err(jsonrpc_core::Error::from)
-				.compat(),
-		)
+		future
+			.map_err(|e| {
+				warn!("Error proving finality: {}", e);
+				error::Error::ProveFinalityFailed(e)
+			})
+			.map_err(jsonrpc_core::Error::from)
+			.boxed()
 	}
 }
 
@@ -350,8 +339,8 @@ mod tests {
 		assert_eq!(io.handle_request_sync(request, meta), Some(response.into()));
 	}
 
-	fn setup_session() -> (sc_rpc::Metadata, jsonrpc_core::futures::sync::mpsc::Receiver<String>) {
-		let (tx, rx) = jsonrpc_core::futures::sync::mpsc::channel(1);
+	fn setup_session() -> (sc_rpc::Metadata, futures::channel::mpsc::UnboundedReceiver<String>) {
+		let (tx, rx) = futures::channel::mpsc::unbounded();
 		let meta = sc_rpc::Metadata::new(tx);
 		(meta, rx)
 	}
@@ -385,7 +374,7 @@ mod tests {
 		// Unsubscribe again and fail
 		assert_eq!(
 			io.handle_request_sync(&unsub_req, meta),
-			Some(r#"{"jsonrpc":"2.0","result":false,"id":1}"#.into()),
+			Some("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32602,\"message\":\"Invalid subscription id.\"},\"id\":1}".into()),
 		);
 	}
 
@@ -407,7 +396,7 @@ mod tests {
 				r#"{"jsonrpc":"2.0","method":"grandpa_unsubscribeJustifications","params":["FOO"],"id":1}"#,
 				meta.clone()
 			),
-			Some(r#"{"jsonrpc":"2.0","result":false,"id":1}"#.into())
+			Some("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32602,\"message\":\"Invalid subscription id.\"},\"id\":1}".into())
 		);
 	}
 
@@ -483,7 +472,7 @@ mod tests {
 		justification_sender.notify(|| Ok(justification.clone())).unwrap();
 
 		// Inspect what we received
-		let recv = receiver.take(1).wait().flatten().collect::<Vec<_>>();
+		let recv = futures::executor::block_on(receiver.take(1).collect::<Vec<_>>());
 		let recv: Notification = serde_json::from_str(&recv[0]).unwrap();
 		let mut json_map = match recv.params {
 			Params::Map(json_map) => json_map,
diff --git a/substrate/client/rpc-api/Cargo.toml b/substrate/client/rpc-api/Cargo.toml
index 0ed17813ee755c787434ef7b17e59379a8e5c0e6..b0d7c28b788eaaf2c30f89179b85264fa58290b8 100644
--- a/substrate/client/rpc-api/Cargo.toml
+++ b/substrate/client/rpc-api/Cargo.toml
@@ -15,11 +15,11 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.0.0" }
 derive_more = "0.99.2"
-futures = { version = "0.3.1", features = ["compat"] }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
-jsonrpc-pubsub = "15.1.0"
+futures = "0.3.16"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
+jsonrpc-pubsub = "18.0.0"
 log = "0.4.8"
 parking_lot = "0.11.1"
 sp-core = { version = "4.0.0-dev", path = "../../primitives/core" }
diff --git a/substrate/client/rpc-api/src/author/error.rs b/substrate/client/rpc-api/src/author/error.rs
index 0c963d4e4c2596e3dad4978a2e4be75cb895782c..249c8df39518d4f8084d21cd59d23c6dc4e9afc6 100644
--- a/substrate/client/rpc-api/src/author/error.rs
+++ b/substrate/client/rpc-api/src/author/error.rs
@@ -26,7 +26,7 @@ use sp_runtime::transaction_validity::InvalidTransaction;
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// Author RPC future Result type.
-pub type FutureResult<T> = Box<dyn rpc::futures::Future<Item = T, Error = Error> + Send>;
+pub type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T>>;
 
 /// Author RPC errors.
 #[derive(Debug, derive_more::Display, derive_more::From)]
diff --git a/substrate/client/rpc-api/src/chain/error.rs b/substrate/client/rpc-api/src/chain/error.rs
index 9bedd328d0015b7df6263793095501e09efc2733..b1ce800d27312a71699945f256058a4386e12fce 100644
--- a/substrate/client/rpc-api/src/chain/error.rs
+++ b/substrate/client/rpc-api/src/chain/error.rs
@@ -25,7 +25,7 @@ use jsonrpc_core as rpc;
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// Chain RPC future Result type.
-pub type FutureResult<T> = Box<dyn rpc::futures::Future<Item = T, Error = Error> + Send>;
+pub type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T>>;
 
 /// Chain RPC errors.
 #[derive(Debug, derive_more::Display, derive_more::From)]
diff --git a/substrate/client/rpc-api/src/helpers.rs b/substrate/client/rpc-api/src/helpers.rs
index bb37cfbbb780e822fa0a0dbc99b587a617a10add..a26adbf2e9032e1d94967ed79073bf543d79fe12 100644
--- a/substrate/client/rpc-api/src/helpers.rs
+++ b/substrate/client/rpc-api/src/helpers.rs
@@ -16,18 +16,26 @@
 // You should have received a copy of the GNU General Public License
 // along with this program. If not, see <https://www.gnu.org/licenses/>.
 
-use futures::{channel::oneshot, compat::Compat};
-use jsonrpc_core::futures::prelude::*;
+use futures::{channel::oneshot, Future};
+use std::pin::Pin;
 
 /// Wraps around `oneshot::Receiver` and adjusts the error type to produce an internal error if the
 /// sender gets dropped.
-pub struct Receiver<T>(pub Compat<oneshot::Receiver<T>>);
+pub struct Receiver<T>(pub oneshot::Receiver<T>);
 
 impl<T> Future for Receiver<T> {
-	type Item = T;
-	type Error = jsonrpc_core::Error;
+	type Output = Result<T, jsonrpc_core::Error>;
 
-	fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
-		self.0.poll().map_err(|_| jsonrpc_core::Error::internal_error())
+	fn poll(
+		mut self: Pin<&mut Self>,
+		cx: &mut std::task::Context<'_>,
+	) -> std::task::Poll<Self::Output> {
+		Future::poll(Pin::new(&mut self.0), cx).map_err(|_| jsonrpc_core::Error::internal_error())
+	}
+}
+
+impl<T: Send + 'static> jsonrpc_core::WrapFuture<T, jsonrpc_core::Error> for Receiver<T> {
+	fn into_future(self) -> jsonrpc_core::BoxFuture<Result<T, jsonrpc_core::Error>> {
+		Box::pin(async { self.await })
 	}
 }
diff --git a/substrate/client/rpc-api/src/metadata.rs b/substrate/client/rpc-api/src/metadata.rs
index bda7b8f7ba36ba339c231f9c1b16f7f7cca1e5c2..d493b92c11ac5145fa851d69dffa0ae6b209ad98 100644
--- a/substrate/client/rpc-api/src/metadata.rs
+++ b/substrate/client/rpc-api/src/metadata.rs
@@ -19,7 +19,7 @@
 //! RPC Metadata
 use std::sync::Arc;
 
-use jsonrpc_core::futures::sync::mpsc;
+use futures::channel::mpsc;
 use jsonrpc_pubsub::{PubSubMetadata, Session};
 
 /// RPC Metadata.
@@ -41,20 +41,20 @@ impl PubSubMetadata for Metadata {
 
 impl Metadata {
 	/// Create new `Metadata` with session (Pub/Sub) support.
-	pub fn new(transport: mpsc::Sender<String>) -> Self {
+	pub fn new(transport: mpsc::UnboundedSender<String>) -> Self {
 		Metadata { session: Some(Arc::new(Session::new(transport))) }
 	}
 
 	/// Create new `Metadata` for tests.
 	#[cfg(test)]
-	pub fn new_test() -> (mpsc::Receiver<String>, Self) {
-		let (tx, rx) = mpsc::channel(1);
+	pub fn new_test() -> (mpsc::UnboundedReceiver<String>, Self) {
+		let (tx, rx) = mpsc::unbounded();
 		(rx, Self::new(tx))
 	}
 }
 
-impl From<mpsc::Sender<String>> for Metadata {
-	fn from(sender: mpsc::Sender<String>) -> Self {
+impl From<mpsc::UnboundedSender<String>> for Metadata {
+	fn from(sender: mpsc::UnboundedSender<String>) -> Self {
 		Self::new(sender)
 	}
 }
diff --git a/substrate/client/rpc-api/src/state/error.rs b/substrate/client/rpc-api/src/state/error.rs
index 30437246e6ea7bcb85008c9c07b52671f0144db1..e30757f0dd39a4fd5391348a01fbd5b9a0294629 100644
--- a/substrate/client/rpc-api/src/state/error.rs
+++ b/substrate/client/rpc-api/src/state/error.rs
@@ -25,7 +25,7 @@ use jsonrpc_core as rpc;
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// State RPC future Result type.
-pub type FutureResult<T> = Box<dyn rpc::futures::Future<Item = T, Error = Error> + Send>;
+pub type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T>>;
 
 /// State RPC errors.
 #[derive(Debug, derive_more::Display, derive_more::From)]
diff --git a/substrate/client/rpc-api/src/system/mod.rs b/substrate/client/rpc-api/src/system/mod.rs
index 2f9ed45cd2e25970e4a732b7c075ac754957d190..3ffc5f434650864f4c4727017e47d64dd89e88a4 100644
--- a/substrate/client/rpc-api/src/system/mod.rs
+++ b/substrate/client/rpc-api/src/system/mod.rs
@@ -22,7 +22,7 @@ pub mod error;
 pub mod helpers;
 
 use crate::helpers::Receiver;
-use futures::{compat::Compat, future::BoxFuture};
+use jsonrpc_core::BoxFuture;
 use jsonrpc_derive::rpc;
 
 use self::error::Result as SystemResult;
@@ -76,9 +76,7 @@ pub trait SystemApi<Hash, Number> {
 
 	/// Returns currently connected peers
 	#[rpc(name = "system_peers", returns = "Vec<PeerInfo<Hash, Number>>")]
-	fn system_peers(
-		&self,
-	) -> Compat<BoxFuture<'static, jsonrpc_core::Result<Vec<PeerInfo<Hash, Number>>>>>;
+	fn system_peers(&self) -> BoxFuture<jsonrpc_core::Result<Vec<PeerInfo<Hash, Number>>>>;
 
 	/// Returns current state of the network.
 	///
@@ -87,9 +85,7 @@ pub trait SystemApi<Hash, Number> {
 	// TODO: the future of this call is uncertain: https://github.com/paritytech/substrate/issues/1890
 	// https://github.com/paritytech/substrate/issues/5541
 	#[rpc(name = "system_unstable_networkState", returns = "jsonrpc_core::Value")]
-	fn system_network_state(
-		&self,
-	) -> Compat<BoxFuture<'static, jsonrpc_core::Result<jsonrpc_core::Value>>>;
+	fn system_network_state(&self) -> BoxFuture<jsonrpc_core::Result<jsonrpc_core::Value>>;
 
 	/// Adds a reserved peer. Returns the empty string or an error. The string
 	/// parameter should encode a `p2p` multiaddr.
@@ -97,10 +93,7 @@ pub trait SystemApi<Hash, Number> {
 	/// `/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV`
 	/// is an example of a valid, passing multiaddr with PeerId attached.
 	#[rpc(name = "system_addReservedPeer", returns = "()")]
-	fn system_add_reserved_peer(
-		&self,
-		peer: String,
-	) -> Compat<BoxFuture<'static, Result<(), jsonrpc_core::Error>>>;
+	fn system_add_reserved_peer(&self, peer: String) -> BoxFuture<Result<(), jsonrpc_core::Error>>;
 
 	/// Remove a reserved peer. Returns the empty string or an error. The string
 	/// should encode only the PeerId e.g. `QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV`.
@@ -108,7 +101,7 @@ pub trait SystemApi<Hash, Number> {
 	fn system_remove_reserved_peer(
 		&self,
 		peer_id: String,
-	) -> Compat<BoxFuture<'static, Result<(), jsonrpc_core::Error>>>;
+	) -> BoxFuture<Result<(), jsonrpc_core::Error>>;
 
 	/// Returns the list of reserved peers
 	#[rpc(name = "system_reservedPeers", returns = "Vec<String>")]
diff --git a/substrate/client/rpc-servers/Cargo.toml b/substrate/client/rpc-servers/Cargo.toml
index 025d586c4e537165b1a0065860862807857a77ac..d2bce6a08638b41553ef9edddf25689812f46fa2 100644
--- a/substrate/client/rpc-servers/Cargo.toml
+++ b/substrate/client/rpc-servers/Cargo.toml
@@ -13,9 +13,9 @@ readme = "README.md"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-futures = "0.1.6"
-jsonrpc-core = "15.1.0"
-pubsub = { package = "jsonrpc-pubsub", version = "15.1.0" }
+futures = "0.3.16"
+jsonrpc-core = "18.0.0"
+pubsub = { package = "jsonrpc-pubsub", version = "18.0.0" }
 log = "0.4.8"
 prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.9.0"}
 serde = "1.0.126"
@@ -23,6 +23,6 @@ serde_json = "1.0.41"
 sp-runtime = { version = "4.0.0-dev", path = "../../primitives/runtime" }
 
 [target.'cfg(not(target_os = "unknown"))'.dependencies]
-http = { package = "jsonrpc-http-server", version = "15.1.0" }
-ipc = { package = "jsonrpc-ipc-server", version = "15.1.0" }
-ws = { package = "jsonrpc-ws-server", version = "15.1.0" }
+http = { package = "jsonrpc-http-server", version = "18.0.0" }
+ipc = { package = "jsonrpc-ipc-server", version = "18.0.0" }
+ws = { package = "jsonrpc-ws-server", version = "18.0.0" }
diff --git a/substrate/client/rpc-servers/src/lib.rs b/substrate/client/rpc-servers/src/lib.rs
index 7f14cee39f20f2483f36358ca33589f207e0a9cb..a833002fcdbfff457933ba87859e00a065ec9f7c 100644
--- a/substrate/client/rpc-servers/src/lib.rs
+++ b/substrate/client/rpc-servers/src/lib.rs
@@ -61,10 +61,13 @@ pub fn rpc_handler<M: PubSubMetadata>(
 			.expect("Serialization of Vec<String> is infallible; qed");
 
 		move |_| {
-			Ok(serde_json::json!({
-				"version": 1,
-				"methods": methods.clone(),
-			}))
+			let methods = methods.clone();
+			async move {
+				Ok(serde_json::json!({
+					"version": 1,
+					"methods": methods,
+				}))
+			}
 		}
 	});
 	io
@@ -84,7 +87,7 @@ mod inner {
 	/// Start HTTP server listening on given address.
 	///
 	/// **Note**: Only available if `not(target_os = "unknown")`.
-	pub fn start_http<M: pubsub::PubSubMetadata + Default>(
+	pub fn start_http<M: pubsub::PubSubMetadata + Default + Unpin>(
 		addr: &std::net::SocketAddr,
 		thread_pool_size: Option<usize>,
 		cors: Option<&Vec<String>>,
@@ -94,6 +97,7 @@ mod inner {
 		let max_request_body_size = maybe_max_payload_mb
 			.map(|mb| mb.saturating_mul(MEGABYTE))
 			.unwrap_or(RPC_MAX_PAYLOAD_DEFAULT);
+
 		http::ServerBuilder::new(io)
 			.threads(thread_pool_size.unwrap_or(HTTP_THREADS))
 			.health_api(("/health", "system_health"))
@@ -125,7 +129,7 @@ mod inner {
 	///
 	/// **Note**: Only available if `not(target_os = "unknown")`.
 	pub fn start_ws<
-		M: pubsub::PubSubMetadata + From<jsonrpc_core::futures::sync::mpsc::Sender<String>>,
+		M: pubsub::PubSubMetadata + From<futures::channel::mpsc::UnboundedSender<String>>,
 	>(
 		addr: &std::net::SocketAddr,
 		max_connections: Option<usize>,
diff --git a/substrate/client/rpc-servers/src/middleware.rs b/substrate/client/rpc-servers/src/middleware.rs
index d87c653e2b250aea11293fba44b2be7b355c5e57..5ba5c18a8e9534f1c37bc2195a2f296c342559d4 100644
--- a/substrate/client/rpc-servers/src/middleware.rs
+++ b/substrate/client/rpc-servers/src/middleware.rs
@@ -73,12 +73,12 @@ impl<M: Metadata> RequestMiddleware<M> for RpcMiddleware {
 	fn on_request<F, X>(&self, request: Request, meta: M, next: F) -> Either<FutureResponse, X>
 	where
 		F: Fn(Request, M) -> X + Send + Sync,
-		X: Future<Item = Option<Response>, Error = ()> + Send + 'static,
+		X: Future<Output = Option<Response>> + Send + 'static,
 	{
 		if let Some(ref rpc_calls) = self.metrics.rpc_calls {
 			rpc_calls.with_label_values(&[self.transport_label.as_str()]).inc();
 		}
 
-		Either::B(next(request, meta))
+		Either::Right(next(request, meta))
 	}
 }
diff --git a/substrate/client/rpc/Cargo.toml b/substrate/client/rpc/Cargo.toml
index 04eb8b8b3f78e86598b1e25ffdc89c592e75f0d9..89064d879a986f1fbb376924a0568bfb4bf0e273 100644
--- a/substrate/client/rpc/Cargo.toml
+++ b/substrate/client/rpc/Cargo.toml
@@ -17,11 +17,11 @@ sc-rpc-api = { version = "0.10.0-dev", path = "../rpc-api" }
 sc-client-api = { version = "4.0.0-dev", path = "../api" }
 sp-api = { version = "4.0.0-dev", path = "../../primitives/api" }
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-futures = { version = "0.3.1", features = ["compat"] }
-jsonrpc-pubsub = "15.1.0"
+futures = "0.3.16"
+jsonrpc-pubsub = "18.0.0"
 log = "0.4.8"
 sp-core = { version = "4.0.0-dev", path = "../../primitives/core" }
-rpc = { package = "jsonrpc-core", version = "15.1.0" }
+rpc = { package = "jsonrpc-core", version = "18.0.0" }
 sp-version = { version = "4.0.0-dev", path = "../../primitives/version" }
 serde_json = "1.0.41"
 sp-session = { version = "4.0.0-dev", path = "../../primitives/session" }
@@ -45,12 +45,10 @@ sc-transaction-pool-api = { version = "4.0.0-dev", path = "../transaction-pool/a
 
 [dev-dependencies]
 assert_matches = "1.3.0"
-futures01 = { package = "futures", version = "0.1.29" }
 lazy_static = "1.4.0"
 sc-network = { version = "0.10.0-dev", path = "../network" }
 sp-io = { version = "4.0.0-dev", path = "../../primitives/io" }
 substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" }
-tokio = "0.1.22"
 sc-transaction-pool = { version = "4.0.0-dev", path = "../transaction-pool" }
 sc-cli = { version = "0.10.0-dev", path = "../cli" }
 sp-consensus = { version = "0.10.0-dev", path = "../../primitives/consensus/common" }
diff --git a/substrate/client/rpc/src/author/mod.rs b/substrate/client/rpc/src/author/mod.rs
index 0cb24d25b20643e31f34a0357f591275755436ff..40b477a662a601b0afe9656caf96074ed24c4ab0 100644
--- a/substrate/client/rpc/src/author/mod.rs
+++ b/substrate/client/rpc/src/author/mod.rs
@@ -28,12 +28,10 @@ use sp_blockchain::HeaderBackend;
 
 use codec::{Decode, Encode};
 use futures::{
-	compat::Compat,
-	future::{ready, FutureExt, TryFutureExt},
-	StreamExt as _,
+	future::{FutureExt, TryFutureExt},
+	SinkExt, StreamExt as _,
 };
 use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
-use rpc::futures::{future::result, Future, Sink};
 use sc_rpc_api::DenyUnsafe;
 use sc_transaction_pool_api::{
 	error::IntoPoolError, BlockHash, InPoolTransaction, TransactionFor, TransactionPool,
@@ -42,7 +40,7 @@ use sc_transaction_pool_api::{
 use sp_api::ProvideRuntimeApi;
 use sp_core::Bytes;
 use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
-use sp_runtime::generic;
+use sp_runtime::{generic, traits::Block as BlockT};
 use sp_session::SessionKeys;
 
 use self::error::{Error, FutureResult, Result};
@@ -88,6 +86,8 @@ where
 	P: TransactionPool + Sync + Send + 'static,
 	Client: HeaderBackend<P::Block> + ProvideRuntimeApi<P::Block> + Send + Sync + 'static,
 	Client::Api: SessionKeys<P::Block>,
+	P::Hash: Unpin,
+	<P::Block as BlockT>::Hash: Unpin,
 {
 	type Metadata = crate::Metadata;
 
@@ -135,19 +135,18 @@ where
 	fn submit_extrinsic(&self, ext: Bytes) -> FutureResult<TxHash<P>> {
 		let xt = match Decode::decode(&mut &ext[..]) {
 			Ok(xt) => xt,
-			Err(err) => return Box::new(result(Err(err.into()))),
+			Err(err) => return async move { Err(err.into()) }.boxed(),
 		};
 		let best_block_hash = self.client.info().best_hash;
-		Box::new(
-			self.pool
-				.submit_one(&generic::BlockId::hash(best_block_hash), TX_SOURCE, xt)
-				.compat()
-				.map_err(|e| {
-					e.into_pool_error()
-						.map(Into::into)
-						.unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())
-				}),
-		)
+
+		self.pool
+			.submit_one(&generic::BlockId::hash(best_block_hash), TX_SOURCE, xt)
+			.map_err(|e| {
+				e.into_pool_error()
+					.map(Into::into)
+					.unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())
+			})
+			.boxed()
 	}
 
 	fn pending_extrinsics(&self) -> Result<Vec<Bytes>> {
@@ -185,46 +184,50 @@ where
 		subscriber: Subscriber<TransactionStatus<TxHash<P>, BlockHash<P>>>,
 		xt: Bytes,
 	) {
-		let submit = || -> Result<_> {
-			let best_block_hash = self.client.info().best_hash;
-			let dxt = TransactionFor::<P>::decode(&mut &xt[..]).map_err(error::Error::from)?;
-			Ok(self
-				.pool
-				.submit_and_watch(&generic::BlockId::hash(best_block_hash), TX_SOURCE, dxt)
-				.map_err(|e| {
-					e.into_pool_error()
-						.map(error::Error::from)
-						.unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())
-				}))
+		let best_block_hash = self.client.info().best_hash;
+		let dxt = match TransactionFor::<P>::decode(&mut &xt[..]).map_err(error::Error::from) {
+			Ok(tx) => tx,
+			Err(err) => {
+				warn!("Failed to submit extrinsic: {}", err);
+				// reject the subscriber (ignore errors - we don't care if subscriber is no longer
+				// there).
+				let _ = subscriber.reject(err.into());
+				return
+			},
 		};
 
+		let submit = self
+			.pool
+			.submit_and_watch(&generic::BlockId::hash(best_block_hash), TX_SOURCE, dxt)
+			.map_err(|e| {
+				e.into_pool_error()
+					.map(error::Error::from)
+					.unwrap_or_else(|e| error::Error::Verification(Box::new(e)).into())
+			});
+
 		let subscriptions = self.subscriptions.clone();
-		let future = ready(submit())
-			.and_then(|res| res)
-			// convert the watcher into a `Stream`
-			.map(|res| res.map(|stream| stream.map(|v| Ok::<_, ()>(Ok(v)))))
-			// now handle the import result,
-			// start a new subscrition
-			.map(move |result| match result {
-				Ok(watcher) => {
-					subscriptions.add(subscriber, move |sink| {
-						sink.sink_map_err(|e| log::debug!("Subscription sink failed: {:?}", e))
-							.send_all(Compat::new(watcher))
-							.map(|_| ())
-					});
-				},
+
+		let future = async move {
+			let tx_stream = match submit.await {
+				Ok(s) => s,
 				Err(err) => {
 					warn!("Failed to submit extrinsic: {}", err);
 					// reject the subscriber (ignore errors - we don't care if subscriber is no
 					// longer there).
 					let _ = subscriber.reject(err.into());
+					return
 				},
+			};
+
+			subscriptions.add(subscriber, move |sink| {
+				tx_stream
+					.map(|v| Ok(Ok(v)))
+					.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
+					.map(drop)
 			});
+		};
 
-		let res = self
-			.subscriptions
-			.executor()
-			.execute(Box::new(Compat::new(future.map(|_| Ok(())))));
+		let res = self.subscriptions.executor().spawn_obj(future.boxed().into());
 		if res.is_err() {
 			warn!("Error spawning subscription RPC task.");
 		}
diff --git a/substrate/client/rpc/src/author/tests.rs b/substrate/client/rpc/src/author/tests.rs
index 9da6ff8d13f6eeb2be37e671471494850338f32b..2349e08fee50637b435bacc764b366235e4b17e0 100644
--- a/substrate/client/rpc/src/author/tests.rs
+++ b/substrate/client/rpc/src/author/tests.rs
@@ -20,8 +20,7 @@ use super::*;
 
 use assert_matches::assert_matches;
 use codec::Encode;
-use futures::{compat::Future01CompatExt, executor};
-use rpc::futures::Stream as _;
+use futures::executor;
 use sc_transaction_pool::{BasicPool, FullChainApi};
 use sp_core::{
 	blake2_256,
@@ -86,10 +85,10 @@ fn submit_transaction_should_not_cause_error() {
 	let h: H256 = blake2_256(&xt).into();
 
 	assert_matches!(
-		AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(),
+		executor::block_on(AuthorApi::submit_extrinsic(&p, xt.clone().into())),
 		Ok(h2) if h == h2
 	);
-	assert!(AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err());
+	assert!(executor::block_on(AuthorApi::submit_extrinsic(&p, xt.into())).is_err());
 }
 
 #[test]
@@ -99,10 +98,10 @@ fn submit_rich_transaction_should_not_cause_error() {
 	let h: H256 = blake2_256(&xt).into();
 
 	assert_matches!(
-		AuthorApi::submit_extrinsic(&p, xt.clone().into()).wait(),
+		executor::block_on(AuthorApi::submit_extrinsic(&p, xt.clone().into())),
 		Ok(h2) if h == h2
 	);
-	assert!(AuthorApi::submit_extrinsic(&p, xt.into()).wait().is_err());
+	assert!(executor::block_on(AuthorApi::submit_extrinsic(&p, xt.into())).is_err());
 }
 
 #[test]
@@ -120,7 +119,7 @@ fn should_watch_extrinsic() {
 		uxt(AccountKeyring::Alice, 0).encode().into(),
 	);
 
-	let id = executor::block_on(id_rx.compat()).unwrap().unwrap();
+	let id = executor::block_on(id_rx).unwrap().unwrap();
 	assert_matches!(id, SubscriptionId::String(_));
 
 	let id = match id {
@@ -138,8 +137,8 @@ fn should_watch_extrinsic() {
 		};
 		tx.into_signed_tx()
 	};
-	AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap();
-	let (res, data) = executor::block_on(data.into_future().compat()).unwrap();
+	executor::block_on(AuthorApi::submit_extrinsic(&p, replacement.encode().into())).unwrap();
+	let (res, data) = executor::block_on(data.into_future());
 
 	let expected = Some(format!(
 		r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":"ready","subscription":"{}"}}}}"#,
@@ -154,7 +153,7 @@ fn should_watch_extrinsic() {
 		id,
 	));
 
-	let res = executor::block_on(data.into_future().compat()).unwrap().0;
+	let res = executor::block_on(data.into_future()).0;
 	assert_eq!(res, expected);
 }
 
@@ -174,7 +173,7 @@ fn should_return_watch_validation_error() {
 	);
 
 	// then
-	let res = executor::block_on(id_rx.compat()).unwrap();
+	let res = executor::block_on(id_rx).unwrap();
 	assert!(res.is_err(), "Expected the transaction to be rejected as invalid.");
 }
 
@@ -183,7 +182,7 @@ fn should_return_pending_extrinsics() {
 	let p = TestSetup::default().author();
 
 	let ex = uxt(AccountKeyring::Alice, 0);
-	AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap();
+	executor::block_on(AuthorApi::submit_extrinsic(&p, ex.encode().into())).unwrap();
 	assert_matches!(
 		p.pending_extrinsics(),
 		Ok(ref expected) if *expected == vec![Bytes(ex.encode())]
@@ -196,11 +195,11 @@ fn should_remove_extrinsics() {
 	let p = setup.author();
 
 	let ex1 = uxt(AccountKeyring::Alice, 0);
-	p.submit_extrinsic(ex1.encode().into()).wait().unwrap();
+	executor::block_on(p.submit_extrinsic(ex1.encode().into())).unwrap();
 	let ex2 = uxt(AccountKeyring::Alice, 1);
-	p.submit_extrinsic(ex2.encode().into()).wait().unwrap();
+	executor::block_on(p.submit_extrinsic(ex2.encode().into())).unwrap();
 	let ex3 = uxt(AccountKeyring::Bob, 0);
-	let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap();
+	let hash3 = executor::block_on(p.submit_extrinsic(ex3.encode().into())).unwrap();
 	assert_eq!(setup.pool.status().ready, 3);
 
 	// now remove all 3
diff --git a/substrate/client/rpc/src/chain/chain_full.rs b/substrate/client/rpc/src/chain/chain_full.rs
index 8d0f622d1e7aa905fb1ef189d0b146fe5d6d42e4..96d5b86f42498db3c17ecf2e3e9c5ead53ebf49a 100644
--- a/substrate/client/rpc/src/chain/chain_full.rs
+++ b/substrate/client/rpc/src/chain/chain_full.rs
@@ -18,19 +18,16 @@
 
 //! Blockchain API backend for full nodes.
 
+use super::{client_err, error::FutureResult, ChainBackend};
+use futures::FutureExt;
 use jsonrpc_pubsub::manager::SubscriptionManager;
-use rpc::futures::future::result;
-use std::sync::Arc;
-
 use sc_client_api::{BlockBackend, BlockchainEvents};
+use sp_blockchain::HeaderBackend;
 use sp_runtime::{
 	generic::{BlockId, SignedBlock},
 	traits::Block as BlockT,
 };
-
-use super::{client_err, error::FutureResult, ChainBackend};
-use sp_blockchain::HeaderBackend;
-use std::marker::PhantomData;
+use std::{marker::PhantomData, sync::Arc};
 
 /// Blockchain API backend for full nodes. Reads all the data from local database.
 pub struct FullChain<Block: BlockT, Client> {
@@ -52,6 +49,7 @@ impl<Block: BlockT, Client> FullChain<Block, Client> {
 impl<Block, Client> ChainBackend<Client, Block> for FullChain<Block, Client>
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: BlockBackend<Block> + HeaderBackend<Block> + BlockchainEvents<Block> + 'static,
 {
 	fn client(&self) -> &Arc<Client> {
@@ -63,14 +61,12 @@ where
 	}
 
 	fn header(&self, hash: Option<Block::Hash>) -> FutureResult<Option<Block::Header>> {
-		Box::new(result(
-			self.client.header(BlockId::Hash(self.unwrap_or_best(hash))).map_err(client_err),
-		))
+		let res = self.client.header(BlockId::Hash(self.unwrap_or_best(hash))).map_err(client_err);
+		async move { res }.boxed()
 	}
 
 	fn block(&self, hash: Option<Block::Hash>) -> FutureResult<Option<SignedBlock<Block>>> {
-		Box::new(result(
-			self.client.block(&BlockId::Hash(self.unwrap_or_best(hash))).map_err(client_err),
-		))
+		let res = self.client.block(&BlockId::Hash(self.unwrap_or_best(hash))).map_err(client_err);
+		async move { res }.boxed()
 	}
 }
diff --git a/substrate/client/rpc/src/chain/chain_light.rs b/substrate/client/rpc/src/chain/chain_light.rs
index ebca664c0f23d9f154b3dba6185034852c24a9b5..2d15c819e1dab4043150501b8c5506ad84c7fafa 100644
--- a/substrate/client/rpc/src/chain/chain_light.rs
+++ b/substrate/client/rpc/src/chain/chain_light.rs
@@ -20,7 +20,6 @@
 
 use futures::{future::ready, FutureExt, TryFutureExt};
 use jsonrpc_pubsub::manager::SubscriptionManager;
-use rpc::futures::future::{result, Either, Future};
 use std::sync::Arc;
 
 use sc_client_api::light::{Fetcher, RemoteBlockchain, RemoteBodyRequest};
@@ -61,6 +60,7 @@ impl<Block: BlockT, Client, F: Fetcher<Block>> LightChain<Block, Client, F> {
 impl<Block, Client, F> ChainBackend<Client, Block> for LightChain<Block, Client, F>
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: BlockchainEvents<Block> + HeaderBackend<Block> + Send + Sync + 'static,
 	F: Fetcher<Block> + Send + Sync + 'static,
 {
@@ -82,33 +82,33 @@ where
 			BlockId::Hash(hash),
 		);
 
-		Box::new(
-			maybe_header
-				.then(move |result| ready(result.map_err(client_err)))
-				.boxed()
-				.compat(),
-		)
+		maybe_header.then(move |result| ready(result.map_err(client_err))).boxed()
 	}
 
 	fn block(&self, hash: Option<Block::Hash>) -> FutureResult<Option<SignedBlock<Block>>> {
 		let fetcher = self.fetcher.clone();
-		let block = self.header(hash).and_then(move |header| match header {
-			Some(header) => Either::A(
-				fetcher
-					.remote_body(RemoteBodyRequest {
-						header: header.clone(),
-						retry_count: Default::default(),
-					})
-					.boxed()
-					.compat()
-					.map(move |body| {
-						Some(SignedBlock { block: Block::new(header, body), justifications: None })
-					})
-					.map_err(client_err),
-			),
-			None => Either::B(result(Ok(None))),
-		});
-
-		Box::new(block)
+		self.header(hash)
+			.and_then(move |header| async move {
+				match header {
+					Some(header) => {
+						let body = fetcher
+							.remote_body(RemoteBodyRequest {
+								header: header.clone(),
+								retry_count: Default::default(),
+							})
+							.await;
+
+						body.map(|body| {
+							Some(SignedBlock {
+								block: Block::new(header, body),
+								justifications: None,
+							})
+						})
+						.map_err(client_err)
+					},
+					None => Ok(None),
+				}
+			})
+			.boxed()
 	}
 }
diff --git a/substrate/client/rpc/src/chain/mod.rs b/substrate/client/rpc/src/chain/mod.rs
index f78188249f6fde11d21cd5d9cb7e2a4df2449090..8685b3f93c4effbc13129c80ccf6bd3397cdb708 100644
--- a/substrate/client/rpc/src/chain/mod.rs
+++ b/substrate/client/rpc/src/chain/mod.rs
@@ -27,7 +27,7 @@ mod tests;
 use futures::{future, StreamExt, TryStreamExt};
 use log::warn;
 use rpc::{
-	futures::{stream, Future, Sink, Stream},
+	futures::{stream, FutureExt, SinkExt, Stream},
 	Result as RpcResult,
 };
 use std::sync::Arc;
@@ -53,6 +53,7 @@ use sp_blockchain::HeaderBackend;
 trait ChainBackend<Client, Block: BlockT>: Send + Sync + 'static
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: HeaderBackend<Block> + BlockchainEvents<Block> + 'static,
 {
 	/// Get client reference.
@@ -120,8 +121,7 @@ where
 			|| {
 				self.client()
 					.import_notification_stream()
-					.map(|notification| Ok::<_, ()>(notification.header))
-					.compat()
+					.map(|notification| Ok::<_, rpc::Error>(notification.header))
 			},
 		)
 	}
@@ -150,8 +150,7 @@ where
 				self.client()
 					.import_notification_stream()
 					.filter(|notification| future::ready(notification.is_new_best))
-					.map(|notification| Ok::<_, ()>(notification.header))
-					.compat()
+					.map(|notification| Ok::<_, rpc::Error>(notification.header))
 			},
 		)
 	}
@@ -179,8 +178,7 @@ where
 			|| {
 				self.client()
 					.finality_notification_stream()
-					.map(|notification| Ok::<_, ()>(notification.header))
-					.compat()
+					.map(|notification| Ok::<_, rpc::Error>(notification.header))
 			},
 		)
 	}
@@ -202,6 +200,7 @@ pub fn new_full<Block: BlockT, Client>(
 ) -> Chain<Block, Client>
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: BlockBackend<Block> + HeaderBackend<Block> + BlockchainEvents<Block> + 'static,
 {
 	Chain { backend: Box::new(self::chain_full::FullChain::new(client, subscriptions)) }
@@ -216,6 +215,7 @@ pub fn new_light<Block: BlockT, Client, F: Fetcher<Block>>(
 ) -> Chain<Block, Client>
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: BlockBackend<Block> + HeaderBackend<Block> + BlockchainEvents<Block> + 'static,
 	F: Send + Sync + 'static,
 {
@@ -238,6 +238,7 @@ impl<Block, Client> ChainApi<NumberFor<Block>, Block::Hash, Block::Header, Signe
 	for Chain<Block, Client>
 where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: HeaderBackend<Block> + BlockchainEvents<Block> + 'static,
 {
 	type Metadata = crate::Metadata;
@@ -312,7 +313,7 @@ where
 }
 
 /// Subscribe to new headers.
-fn subscribe_headers<Block, Client, F, G, S, ERR>(
+fn subscribe_headers<Block, Client, F, G, S>(
 	client: &Arc<Client>,
 	subscriptions: &SubscriptionManager,
 	subscriber: Subscriber<Block::Header>,
@@ -320,27 +321,28 @@ fn subscribe_headers<Block, Client, F, G, S, ERR>(
 	stream: F,
 ) where
 	Block: BlockT + 'static,
+	Block::Header: Unpin,
 	Client: HeaderBackend<Block> + 'static,
 	F: FnOnce() -> S,
 	G: FnOnce() -> Block::Hash,
-	ERR: ::std::fmt::Debug,
-	S: Stream<Item = Block::Header, Error = ERR> + Send + 'static,
+	S: Stream<Item = std::result::Result<Block::Header, rpc::Error>> + Send + 'static,
 {
 	subscriptions.add(subscriber, |sink| {
 		// send current head right at the start.
 		let header = client
 			.header(BlockId::Hash(best_block_hash()))
 			.map_err(client_err)
-			.and_then(|header| header.ok_or_else(|| "Best header missing.".to_owned().into()))
+			.and_then(|header| header.ok_or_else(|| "Best header missing.".to_string().into()))
 			.map_err(Into::into);
 
 		// send further subscriptions
 		let stream = stream()
-			.map(|res| Ok(res))
-			.map_err(|e| warn!("Block notification stream error: {:?}", e));
+			.inspect_err(|e| warn!("Block notification stream error: {:?}", e))
+			.map(|res| Ok(res));
 
-		sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-			.send_all(stream::iter_result(vec![Ok(header)]).chain(stream))
+		stream::iter(vec![Ok(header)])
+			.chain(stream)
+			.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 			// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
 			.map(|_| ())
 	});
diff --git a/substrate/client/rpc/src/chain/tests.rs b/substrate/client/rpc/src/chain/tests.rs
index bf682a57a341a8744a3846586431d6ce11ed7f7e..caa9f33138b86b1d1988f4666beaa95b454ceb20 100644
--- a/substrate/client/rpc/src/chain/tests.rs
+++ b/substrate/client/rpc/src/chain/tests.rs
@@ -19,10 +19,7 @@
 use super::*;
 use crate::testing::TaskExecutor;
 use assert_matches::assert_matches;
-use futures::{
-	compat::{Future01CompatExt, Stream01CompatExt},
-	executor,
-};
+use futures::executor;
 use sc_block_builder::BlockBuilderProvider;
 use sp_consensus::BlockOrigin;
 use sp_rpc::list::ListOrValue;
@@ -37,7 +34,7 @@ fn should_return_header() {
 	let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor)));
 
 	assert_matches!(
-		api.header(Some(client.genesis_hash()).into()).wait(),
+		executor::block_on(api.header(Some(client.genesis_hash()).into())),
 		Ok(Some(ref x)) if x == &Header {
 			parent_hash: H256::from_low_u64_be(0),
 			number: 0,
@@ -49,7 +46,7 @@ fn should_return_header() {
 	);
 
 	assert_matches!(
-		api.header(None.into()).wait(),
+		executor::block_on(api.header(None.into())),
 		Ok(Some(ref x)) if x == &Header {
 			parent_hash: H256::from_low_u64_be(0),
 			number: 0,
@@ -60,7 +57,10 @@ fn should_return_header() {
 		}
 	);
 
-	assert_matches!(api.header(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None));
+	assert_matches!(
+		executor::block_on(api.header(Some(H256::from_low_u64_be(5)).into())),
+		Ok(None)
+	);
 }
 
 #[test]
@@ -74,12 +74,12 @@ fn should_return_a_block() {
 
 	// Genesis block is not justified
 	assert_matches!(
-		api.block(Some(client.genesis_hash()).into()).wait(),
+		executor::block_on(api.block(Some(client.genesis_hash()).into())),
 		Ok(Some(SignedBlock { justifications: None, .. }))
 	);
 
 	assert_matches!(
-		api.block(Some(block_hash).into()).wait(),
+		executor::block_on(api.block(Some(block_hash).into())),
 		Ok(Some(ref x)) if x.block == Block {
 			header: Header {
 				parent_hash: client.genesis_hash(),
@@ -94,7 +94,7 @@ fn should_return_a_block() {
 	);
 
 	assert_matches!(
-		api.block(None.into()).wait(),
+		executor::block_on(api.block(None.into())),
 		Ok(Some(ref x)) if x.block == Block {
 			header: Header {
 				parent_hash: client.genesis_hash(),
@@ -108,7 +108,7 @@ fn should_return_a_block() {
 		}
 	);
 
-	assert_matches!(api.block(Some(H256::from_low_u64_be(5)).into()).wait(), Ok(None));
+	assert_matches!(executor::block_on(api.block(Some(H256::from_low_u64_be(5)).into())), Ok(None));
 }
 
 #[test]
@@ -182,7 +182,7 @@ fn should_return_finalized_hash() {
 
 #[test]
 fn should_notify_about_latest_block() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let mut client = Arc::new(substrate_test_runtime_client::new());
@@ -191,25 +191,20 @@ fn should_notify_about_latest_block() {
 		api.subscribe_all_heads(Default::default(), subscriber);
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 
 		let block = client.new_block(Default::default()).unwrap().build().unwrap().block;
 		executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
 	}
 
-	// assert initial head sent.
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// assert notification sent to transport
-	let (notification, next) = executor::block_on(next.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None);
+	// Check for the correct number of notifications
+	executor::block_on((&mut transport).take(2).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
 
 #[test]
 fn should_notify_about_best_block() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let mut client = Arc::new(substrate_test_runtime_client::new());
@@ -218,25 +213,20 @@ fn should_notify_about_best_block() {
 		api.subscribe_new_heads(Default::default(), subscriber);
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 
 		let block = client.new_block(Default::default()).unwrap().build().unwrap().block;
 		executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
 	}
 
-	// assert initial head sent.
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// assert notification sent to transport
-	let (notification, next) = executor::block_on(next.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(Stream01CompatExt::compat(next).into_future()).0, None);
+	// Assert that the correct number of notifications have been sent.
+	executor::block_on((&mut transport).take(2).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
 
 #[test]
 fn should_notify_about_finalized_block() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let mut client = Arc::new(substrate_test_runtime_client::new());
@@ -245,19 +235,14 @@ fn should_notify_about_finalized_block() {
 		api.subscribe_finalized_heads(Default::default(), subscriber);
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 
 		let block = client.new_block(Default::default()).unwrap().build().unwrap().block;
 		executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
 		client.finalize_block(BlockId::number(1), None).unwrap();
 	}
 
-	// assert initial head sent.
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// assert notification sent to transport
-	let (notification, next) = executor::block_on(next.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None);
+	// Assert that the correct number of notifications have been sent.
+	executor::block_on((&mut transport).take(2).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
diff --git a/substrate/client/rpc/src/lib.rs b/substrate/client/rpc/src/lib.rs
index ebdec6647f43ab319a6cf8fc999b1261a166bb65..832585db4854c0e284d65e41fdd6b8742d7344cf 100644
--- a/substrate/client/rpc/src/lib.rs
+++ b/substrate/client/rpc/src/lib.rs
@@ -22,8 +22,10 @@
 
 #![warn(missing_docs)]
 
-use futures::{compat::Future01CompatExt, FutureExt};
-use rpc::futures::future::{ExecuteError, Executor, Future};
+use futures::{
+	task::{FutureObj, Spawn, SpawnError},
+	FutureExt,
+};
 use sp_core::traits::SpawnNamed;
 use std::sync::Arc;
 
@@ -50,12 +52,13 @@ impl SubscriptionTaskExecutor {
 	}
 }
 
-impl Executor<Box<dyn Future<Item = (), Error = ()> + Send>> for SubscriptionTaskExecutor {
-	fn execute(
-		&self,
-		future: Box<dyn Future<Item = (), Error = ()> + Send>,
-	) -> Result<(), ExecuteError<Box<dyn Future<Item = (), Error = ()> + Send>>> {
-		self.0.spawn("substrate-rpc-subscription", future.compat().map(drop).boxed());
+impl Spawn for SubscriptionTaskExecutor {
+	fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
+		self.0.spawn("substrate-rpc-subscription", future.map(drop).boxed());
+		Ok(())
+	}
+
+	fn status(&self) -> Result<(), SpawnError> {
 		Ok(())
 	}
 }
diff --git a/substrate/client/rpc/src/state/mod.rs b/substrate/client/rpc/src/state/mod.rs
index 472e50c74991cb6a0069f4caaf335b6bcd7491b7..042225042d80c4a97e41ebe616037a04c5b69639 100644
--- a/substrate/client/rpc/src/state/mod.rs
+++ b/substrate/client/rpc/src/state/mod.rs
@@ -24,11 +24,9 @@ mod state_light;
 #[cfg(test)]
 mod tests;
 
+use futures::FutureExt;
 use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
-use rpc::{
-	futures::{future::result, Future},
-	Result as RpcResult,
-};
+use rpc::Result as RpcResult;
 use std::sync::Arc;
 
 use sc_client_api::light::{Fetcher, RemoteBlockchain};
@@ -192,6 +190,7 @@ pub fn new_full<BE, Block: BlockT, Client>(
 ) -> (State<Block, Client>, ChildState<Block, Client>)
 where
 	Block: BlockT + 'static,
+	Block::Hash: Unpin,
 	BE: Backend<Block> + 'static,
 	Client: ExecutorProvider<Block>
 		+ StorageProvider<Block, BE>
@@ -227,6 +226,7 @@ pub fn new_light<BE, Block: BlockT, Client, F: Fetcher<Block>>(
 ) -> (State<Block, Client>, ChildState<Block, Client>)
 where
 	Block: BlockT + 'static,
+	Block::Hash: Unpin,
 	BE: Backend<Block> + 'static,
 	Client: ExecutorProvider<Block>
 		+ StorageProvider<Block, BE>
@@ -287,7 +287,7 @@ where
 		block: Option<Block::Hash>,
 	) -> FutureResult<Vec<(StorageKey, StorageData)>> {
 		if let Err(err) = self.deny_unsafe.check_if_safe() {
-			return Box::new(result(Err(err.into())))
+			return async move { Err(err.into()) }.boxed()
 		}
 
 		self.backend.storage_pairs(block, key_prefix)
@@ -301,10 +301,10 @@ where
 		block: Option<Block::Hash>,
 	) -> FutureResult<Vec<StorageKey>> {
 		if count > STORAGE_KEYS_PAGED_MAX_COUNT {
-			return Box::new(result(Err(Error::InvalidCount {
-				value: count,
-				max: STORAGE_KEYS_PAGED_MAX_COUNT,
-			})))
+			return async move {
+				Err(Error::InvalidCount { value: count, max: STORAGE_KEYS_PAGED_MAX_COUNT })
+			}
+			.boxed()
 		}
 		self.backend.storage_keys_paged(block, prefix, count, start_key)
 	}
@@ -344,7 +344,7 @@ where
 		to: Option<Block::Hash>,
 	) -> FutureResult<Vec<StorageChangeSet<Block::Hash>>> {
 		if let Err(err) = self.deny_unsafe.check_if_safe() {
-			return Box::new(result(Err(err.into())))
+			return async move { Err(err.into()) }.boxed()
 		}
 
 		self.backend.query_storage(from, to, keys)
@@ -415,7 +415,7 @@ where
 		storage_keys: Option<String>,
 	) -> FutureResult<sp_rpc::tracing::TraceBlockResponse> {
 		if let Err(err) = self.deny_unsafe.check_if_safe() {
-			return Box::new(result(Err(err.into())))
+			return async move { Err(err.into()) }.boxed()
 		}
 
 		self.backend.trace_block(block, targets, storage_keys)
@@ -478,7 +478,9 @@ where
 		storage_key: PrefixedStorageKey,
 		key: StorageKey,
 	) -> FutureResult<Option<u64>> {
-		Box::new(self.storage(block, storage_key, key).map(|x| x.map(|x| x.0.len() as u64)))
+		self.storage(block, storage_key, key)
+			.map(|x| x.map(|r| r.map(|v| v.0.len() as u64)))
+			.boxed()
 	}
 }
 
diff --git a/substrate/client/rpc/src/state/state_full.rs b/substrate/client/rpc/src/state/state_full.rs
index 242a78d58579fc21bb7fb28feff6fd03ffc35282..ef008700f6d5adad949b40637910278f23003b03 100644
--- a/substrate/client/rpc/src/state/state_full.rs
+++ b/substrate/client/rpc/src/state/state_full.rs
@@ -18,13 +18,10 @@
 
 //! State API backend for full nodes.
 
-use futures::{future, StreamExt as _, TryStreamExt as _};
+use futures::{future, stream, FutureExt, SinkExt, StreamExt};
 use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
 use log::warn;
-use rpc::{
-	futures::{future::result, stream, Future, Sink, Stream},
-	Result as RpcResult,
-};
+use rpc::Result as RpcResult;
 use std::{
 	collections::{BTreeMap, HashMap},
 	ops::Range,
@@ -263,6 +260,7 @@ where
 impl<BE, Block, Client> StateBackend<Block, Client> for FullState<BE, Block, Client>
 where
 	Block: BlockT + 'static,
+	Block::Hash: Unpin,
 	BE: Backend<Block> + 'static,
 	Client: ExecutorProvider<Block>
 		+ StorageProvider<Block, BE>
@@ -299,7 +297,7 @@ where
 					.map(Into::into)
 			})
 			.map_err(client_err);
-		Box::new(result(r))
+		async move { r }.boxed()
 	}
 
 	fn storage_keys(
@@ -307,11 +305,11 @@ where
 		block: Option<Block::Hash>,
 		prefix: StorageKey,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| self.client.storage_keys(&BlockId::Hash(block), &prefix))
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| self.client.storage_keys(&BlockId::Hash(block), &prefix))
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn storage_pairs(
@@ -319,11 +317,11 @@ where
 		block: Option<Block::Hash>,
 		prefix: StorageKey,
 	) -> FutureResult<Vec<(StorageKey, StorageData)>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| self.client.storage_pairs(&BlockId::Hash(block), &prefix))
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| self.client.storage_pairs(&BlockId::Hash(block), &prefix))
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn storage_keys_paged(
@@ -333,18 +331,18 @@ where
 		count: u32,
 		start_key: Option<StorageKey>,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					self.client.storage_keys_iter(
-						&BlockId::Hash(block),
-						prefix.as_ref(),
-						start_key.as_ref(),
-					)
-				})
-				.map(|iter| iter.take(count as usize).collect())
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				self.client.storage_keys_iter(
+					&BlockId::Hash(block),
+					prefix.as_ref(),
+					start_key.as_ref(),
+				)
+			})
+			.map(|iter| iter.take(count as usize).collect())
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn storage(
@@ -352,11 +350,11 @@ where
 		block: Option<Block::Hash>,
 		key: StorageKey,
 	) -> FutureResult<Option<StorageData>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| self.client.storage(&BlockId::Hash(block), &key))
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| self.client.storage(&BlockId::Hash(block), &key))
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn storage_size(
@@ -366,28 +364,28 @@ where
 	) -> FutureResult<Option<u64>> {
 		let block = match self.block_or_best(block) {
 			Ok(b) => b,
-			Err(e) => return Box::new(result(Err(client_err(e)))),
+			Err(e) => return async move { Err(client_err(e)) }.boxed(),
 		};
 
 		match self.client.storage(&BlockId::Hash(block), &key) {
-			Ok(Some(d)) => return Box::new(result(Ok(Some(d.0.len() as u64)))),
-			Err(e) => return Box::new(result(Err(client_err(e)))),
+			Ok(Some(d)) => return async move { Ok(Some(d.0.len() as u64)) }.boxed(),
+			Err(e) => return async move { Err(client_err(e)) }.boxed(),
 			Ok(None) => {},
 		}
 
-		Box::new(result(
-			self.client
-				.storage_pairs(&BlockId::Hash(block), &key)
-				.map(|kv| {
-					let item_sum = kv.iter().map(|(_, v)| v.0.len() as u64).sum::<u64>();
-					if item_sum > 0 {
-						Some(item_sum)
-					} else {
-						None
-					}
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.client
+			.storage_pairs(&BlockId::Hash(block), &key)
+			.map(|kv| {
+				let item_sum = kv.iter().map(|(_, v)| v.0.len() as u64).sum::<u64>();
+				if item_sum > 0 {
+					Some(item_sum)
+				} else {
+					None
+				}
+			})
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn storage_hash(
@@ -395,29 +393,31 @@ where
 		block: Option<Block::Hash>,
 		key: StorageKey,
 	) -> FutureResult<Option<Block::Hash>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| self.client.storage_hash(&BlockId::Hash(block), &key))
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| self.client.storage_hash(&BlockId::Hash(block), &key))
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn metadata(&self, block: Option<Block::Hash>) -> FutureResult<Bytes> {
-		Box::new(result(self.block_or_best(block).map_err(client_err).and_then(|block| {
+		let r = self.block_or_best(block).map_err(client_err).and_then(|block| {
 			self.client
 				.runtime_api()
 				.metadata(&BlockId::Hash(block))
 				.map(Into::into)
 				.map_err(|e| Error::Client(Box::new(e)))
-		})))
+		});
+		async move { r }.boxed()
 	}
 
 	fn runtime_version(&self, block: Option<Block::Hash>) -> FutureResult<RuntimeVersion> {
-		Box::new(result(self.block_or_best(block).map_err(client_err).and_then(|block| {
+		let r = self.block_or_best(block).map_err(client_err).and_then(|block| {
 			self.client
 				.runtime_version_at(&BlockId::Hash(block))
 				.map_err(|e| Error::Client(Box::new(e)))
-		})))
+		});
+		async move { r }.boxed()
 	}
 
 	fn query_storage(
@@ -434,7 +434,9 @@ where
 			self.query_storage_filtered(&range, &keys, &last_values, &mut changes)?;
 			Ok(changes)
 		};
-		Box::new(result(call_fn()))
+
+		let r = call_fn();
+		async move { r }.boxed()
 	}
 
 	fn query_storage_at(
@@ -451,19 +453,16 @@ where
 		block: Option<Block::Hash>,
 		keys: Vec<StorageKey>,
 	) -> FutureResult<ReadProof<Block::Hash>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					self.client
-						.read_proof(
-							&BlockId::Hash(block),
-							&mut keys.iter().map(|key| key.0.as_ref()),
-						)
-						.map(|proof| proof.iter_nodes().map(|node| node.into()).collect())
-						.map(|proof| ReadProof { at: block, proof })
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				self.client
+					.read_proof(&BlockId::Hash(block), &mut keys.iter().map(|key| key.0.as_ref()))
+					.map(|proof| proof.iter_nodes().map(|node| node.into()).collect())
+					.map(|proof| ReadProof { at: block, proof })
+			})
+			.map_err(client_err);
+		async move { r }.boxed()
 	}
 
 	fn subscribe_runtime_version(
@@ -483,29 +482,34 @@ where
 		};
 
 		self.subscriptions.add(subscriber, |sink| {
-			let version = self.runtime_version(None.into()).map_err(Into::into).wait();
+			let version = self
+				.block_or_best(None)
+				.and_then(|block| {
+					self.client.runtime_version_at(&BlockId::Hash(block)).map_err(Into::into)
+				})
+				.map_err(client_err)
+				.map_err(Into::into);
 
 			let client = self.client.clone();
 			let mut previous_version = version.clone();
 
-			let stream = stream
-				.filter_map(move |_| {
-					let info = client.info();
-					let version = client
-						.runtime_version_at(&BlockId::hash(info.best_hash))
-						.map_err(|e| Error::Client(Box::new(e)))
-						.map_err(Into::into);
-					if previous_version != version {
-						previous_version = version.clone();
-						future::ready(Some(Ok::<_, ()>(version)))
-					} else {
-						future::ready(None)
-					}
-				})
-				.compat();
+			let stream = stream.filter_map(move |_| {
+				let info = client.info();
+				let version = client
+					.runtime_version_at(&BlockId::hash(info.best_hash))
+					.map_err(|e| Error::Client(Box::new(e)))
+					.map_err(Into::into);
+				if previous_version != version {
+					previous_version = version.clone();
+					future::ready(Some(Ok::<_, ()>(version)))
+				} else {
+					future::ready(None)
+				}
+			});
 
-			sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-				.send_all(stream::iter_result(vec![Ok(version)]).chain(stream))
+			stream::iter(vec![Ok(version)])
+				.chain(stream)
+				.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 				// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
 				.map(|_| ())
 		});
@@ -538,16 +542,14 @@ where
 		};
 
 		// initial values
-		let initial = stream::iter_result(
+		let initial = stream::iter(
 			keys.map(|keys| {
 				let block = self.client.info().best_hash;
 				let changes = keys
 					.into_iter()
 					.map(|key| {
-						StateBackend::storage(self, Some(block.clone()).into(), key.clone())
-							.map(|val| (key.clone(), val))
-							.wait()
-							.unwrap_or_else(|_| (key, None))
+						let v = self.client.storage(&BlockId::Hash(block), &key).ok().flatten();
+						(key, v)
 					})
 					.collect();
 				vec![Ok(Ok(StorageChangeSet { block, changes }))]
@@ -556,26 +558,19 @@ where
 		);
 
 		self.subscriptions.add(subscriber, |sink| {
-			let stream = stream
-				.map(|(block, changes)| {
-					Ok::<_, ()>(Ok(StorageChangeSet {
-						block,
-						changes: changes
-							.iter()
-							.filter_map(|(o_sk, k, v)| {
-								if o_sk.is_none() {
-									Some((k.clone(), v.cloned()))
-								} else {
-									None
-								}
-							})
-							.collect(),
-					}))
-				})
-				.compat();
-
-			sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-				.send_all(initial.chain(stream))
+			let stream = stream.map(|(block, changes)| {
+				Ok(Ok::<_, rpc::Error>(StorageChangeSet {
+					block,
+					changes: changes
+						.iter()
+						.filter_map(|(o_sk, k, v)| o_sk.is_none().then(|| (k.clone(), v.cloned())))
+						.collect(),
+				}))
+			});
+
+			initial
+				.chain(stream)
+				.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 				// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
 				.map(|_| ())
 		});
@@ -602,11 +597,10 @@ where
 			storage_keys,
 			self.rpc_max_payload,
 		);
-		Box::new(result(
-			block_executor
-				.trace_block()
-				.map_err(|e| invalid_block::<Block>(block, None, e.to_string())),
-		))
+		let r = block_executor
+			.trace_block()
+			.map_err(|e| invalid_block::<Block>(block, None, e.to_string()));
+		async move { r }.boxed()
 	}
 }
 
@@ -634,25 +628,26 @@ where
 		storage_key: PrefixedStorageKey,
 		keys: Vec<StorageKey>,
 	) -> FutureResult<ReadProof<Block::Hash>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					let child_info = match ChildType::from_prefixed_key(&storage_key) {
-						Some((ChildType::ParentKeyId, storage_key)) =>
-							ChildInfo::new_default(storage_key),
-						None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
-					};
-					self.client
-						.read_child_proof(
-							&BlockId::Hash(block),
-							&child_info,
-							&mut keys.iter().map(|key| key.0.as_ref()),
-						)
-						.map(|proof| proof.iter_nodes().map(|node| node.into()).collect())
-						.map(|proof| ReadProof { at: block, proof })
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				let child_info = match ChildType::from_prefixed_key(&storage_key) {
+					Some((ChildType::ParentKeyId, storage_key)) =>
+						ChildInfo::new_default(storage_key),
+					None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
+				};
+				self.client
+					.read_child_proof(
+						&BlockId::Hash(block),
+						&child_info,
+						&mut keys.iter().map(|key| key.0.as_ref()),
+					)
+					.map(|proof| proof.iter_nodes().map(|node| node.into()).collect())
+					.map(|proof| ReadProof { at: block, proof })
+			})
+			.map_err(client_err);
+
+		async move { r }.boxed()
 	}
 
 	fn storage_keys(
@@ -661,18 +656,19 @@ where
 		storage_key: PrefixedStorageKey,
 		prefix: StorageKey,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					let child_info = match ChildType::from_prefixed_key(&storage_key) {
-						Some((ChildType::ParentKeyId, storage_key)) =>
-							ChildInfo::new_default(storage_key),
-						None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
-					};
-					self.client.child_storage_keys(&BlockId::Hash(block), &child_info, &prefix)
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				let child_info = match ChildType::from_prefixed_key(&storage_key) {
+					Some((ChildType::ParentKeyId, storage_key)) =>
+						ChildInfo::new_default(storage_key),
+					None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
+				};
+				self.client.child_storage_keys(&BlockId::Hash(block), &child_info, &prefix)
+			})
+			.map_err(client_err);
+
+		async move { r }.boxed()
 	}
 
 	fn storage_keys_paged(
@@ -683,24 +679,25 @@ where
 		count: u32,
 		start_key: Option<StorageKey>,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					let child_info = match ChildType::from_prefixed_key(&storage_key) {
-						Some((ChildType::ParentKeyId, storage_key)) =>
-							ChildInfo::new_default(storage_key),
-						None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
-					};
-					self.client.child_storage_keys_iter(
-						&BlockId::Hash(block),
-						child_info,
-						prefix.as_ref(),
-						start_key.as_ref(),
-					)
-				})
-				.map(|iter| iter.take(count as usize).collect())
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				let child_info = match ChildType::from_prefixed_key(&storage_key) {
+					Some((ChildType::ParentKeyId, storage_key)) =>
+						ChildInfo::new_default(storage_key),
+					None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
+				};
+				self.client.child_storage_keys_iter(
+					&BlockId::Hash(block),
+					child_info,
+					prefix.as_ref(),
+					start_key.as_ref(),
+				)
+			})
+			.map(|iter| iter.take(count as usize).collect())
+			.map_err(client_err);
+
+		async move { r }.boxed()
 	}
 
 	fn storage(
@@ -709,18 +706,19 @@ where
 		storage_key: PrefixedStorageKey,
 		key: StorageKey,
 	) -> FutureResult<Option<StorageData>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					let child_info = match ChildType::from_prefixed_key(&storage_key) {
-						Some((ChildType::ParentKeyId, storage_key)) =>
-							ChildInfo::new_default(storage_key),
-						None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
-					};
-					self.client.child_storage(&BlockId::Hash(block), &child_info, &key)
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				let child_info = match ChildType::from_prefixed_key(&storage_key) {
+					Some((ChildType::ParentKeyId, storage_key)) =>
+						ChildInfo::new_default(storage_key),
+					None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
+				};
+				self.client.child_storage(&BlockId::Hash(block), &child_info, &key)
+			})
+			.map_err(client_err);
+
+		async move { r }.boxed()
 	}
 
 	fn storage_hash(
@@ -729,18 +727,19 @@ where
 		storage_key: PrefixedStorageKey,
 		key: StorageKey,
 	) -> FutureResult<Option<Block::Hash>> {
-		Box::new(result(
-			self.block_or_best(block)
-				.and_then(|block| {
-					let child_info = match ChildType::from_prefixed_key(&storage_key) {
-						Some((ChildType::ParentKeyId, storage_key)) =>
-							ChildInfo::new_default(storage_key),
-						None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
-					};
-					self.client.child_storage_hash(&BlockId::Hash(block), &child_info, &key)
-				})
-				.map_err(client_err),
-		))
+		let r = self
+			.block_or_best(block)
+			.and_then(|block| {
+				let child_info = match ChildType::from_prefixed_key(&storage_key) {
+					Some((ChildType::ParentKeyId, storage_key)) =>
+						ChildInfo::new_default(storage_key),
+					None => return Err(sp_blockchain::Error::InvalidChildStorageKey),
+				};
+				self.client.child_storage_hash(&BlockId::Hash(block), &child_info, &key)
+			})
+			.map_err(client_err);
+
+		async move { r }.boxed()
 	}
 }
 
diff --git a/substrate/client/rpc/src/state/state_light.rs b/substrate/client/rpc/src/state/state_light.rs
index 274eabe376d988e94cad39b7b166c67b9cb982ff..cdb3a77e8d709aeb9a1585324dc8cc9e9100cd76 100644
--- a/substrate/client/rpc/src/state/state_light.rs
+++ b/substrate/client/rpc/src/state/state_light.rs
@@ -22,20 +22,13 @@ use codec::Decode;
 use futures::{
 	channel::oneshot::{channel, Sender},
 	future::{ready, Either},
-	FutureExt, StreamExt as _, TryFutureExt, TryStreamExt as _,
+	Future, FutureExt, SinkExt, Stream, StreamExt as _, TryFutureExt, TryStreamExt as _,
 };
 use hash_db::Hasher;
 use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
 use log::warn;
 use parking_lot::Mutex;
-use rpc::{
-	futures::{
-		future::{result, Future},
-		stream::Stream,
-		Sink,
-	},
-	Result as RpcResult,
-};
+use rpc::Result as RpcResult;
 use std::{
 	collections::{hash_map::Entry, HashMap, HashSet},
 	sync::Arc,
@@ -171,6 +164,7 @@ where
 impl<Block, F, Client> StateBackend<Block, Client> for LightState<Block, F, Client>
 where
 	Block: BlockT,
+	Block::Hash: Unpin,
 	Client: BlockchainEvents<Block> + HeaderBackend<Block> + Send + Sync + 'static,
 	F: Fetcher<Block> + 'static,
 {
@@ -180,17 +174,14 @@ where
 		method: String,
 		call_data: Bytes,
 	) -> FutureResult<Bytes> {
-		Box::new(
-			call(
-				&*self.remote_blockchain,
-				self.fetcher.clone(),
-				self.block_or_best(block),
-				method,
-				call_data,
-			)
-			.boxed()
-			.compat(),
+		call(
+			&*self.remote_blockchain,
+			self.fetcher.clone(),
+			self.block_or_best(block),
+			method,
+			call_data,
 		)
+		.boxed()
 	}
 
 	fn storage_keys(
@@ -198,7 +189,7 @@ where
 		_block: Option<Block::Hash>,
 		_prefix: StorageKey,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage_pairs(
@@ -206,7 +197,7 @@ where
 		_block: Option<Block::Hash>,
 		_prefix: StorageKey,
 	) -> FutureResult<Vec<(StorageKey, StorageData)>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage_keys_paged(
@@ -216,11 +207,11 @@ where
 		_count: u32,
 		_start_key: Option<StorageKey>,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage_size(&self, _: Option<Block::Hash>, _: StorageKey) -> FutureResult<Option<u64>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage(
@@ -228,21 +219,18 @@ where
 		block: Option<Block::Hash>,
 		key: StorageKey,
 	) -> FutureResult<Option<StorageData>> {
-		Box::new(
-			storage(
-				&*self.remote_blockchain,
-				self.fetcher.clone(),
-				self.block_or_best(block),
-				vec![key.0.clone()],
-			)
-			.boxed()
-			.compat()
-			.map(move |mut values| {
-				values
-					.remove(&key)
-					.expect("successful request has entries for all requested keys; qed")
-			}),
+		storage(
+			&*self.remote_blockchain,
+			self.fetcher.clone(),
+			self.block_or_best(block),
+			vec![key.0.clone()],
 		)
+		.map_ok(move |mut values| {
+			values
+				.remove(&key)
+				.expect("successful request has entries for all requested keys; qed")
+		})
+		.boxed()
 	}
 
 	fn storage_hash(
@@ -250,38 +238,28 @@ where
 		block: Option<Block::Hash>,
 		key: StorageKey,
 	) -> FutureResult<Option<Block::Hash>> {
-		Box::new(StateBackend::storage(self, block, key).and_then(|maybe_storage| {
-			result(Ok(maybe_storage.map(|storage| HashFor::<Block>::hash(&storage.0))))
-		}))
+		let res = StateBackend::storage(self, block, key);
+		async move { res.await.map(|r| r.map(|s| HashFor::<Block>::hash(&s.0))) }.boxed()
 	}
 
 	fn metadata(&self, block: Option<Block::Hash>) -> FutureResult<Bytes> {
-		let metadata =
-			self.call(block, "Metadata_metadata".into(), Bytes(Vec::new()))
-				.and_then(|metadata| {
-					OpaqueMetadata::decode(&mut &metadata.0[..]).map(Into::into).map_err(
-						|decode_err| {
-							client_err(ClientError::CallResultDecode(
-								"Unable to decode metadata",
-								decode_err,
-							))
-						},
-					)
-				});
-
-		Box::new(metadata)
+		self.call(block, "Metadata_metadata".into(), Bytes(Vec::new()))
+			.and_then(|metadata| async move {
+				OpaqueMetadata::decode(&mut &metadata.0[..])
+					.map(Into::into)
+					.map_err(|decode_err| {
+						client_err(ClientError::CallResultDecode(
+							"Unable to decode metadata",
+							decode_err,
+						))
+					})
+			})
+			.boxed()
 	}
 
 	fn runtime_version(&self, block: Option<Block::Hash>) -> FutureResult<RuntimeVersion> {
-		Box::new(
-			runtime_version(
-				&*self.remote_blockchain,
-				self.fetcher.clone(),
-				self.block_or_best(block),
-			)
+		runtime_version(&*self.remote_blockchain, self.fetcher.clone(), self.block_or_best(block))
 			.boxed()
-			.compat(),
-		)
 	}
 
 	fn query_storage(
@@ -290,7 +268,7 @@ where
 		_to: Option<Block::Hash>,
 		_keys: Vec<StorageKey>,
 	) -> FutureResult<Vec<StorageChangeSet<Block::Hash>>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn query_storage_at(
@@ -298,7 +276,7 @@ where
 		_keys: Vec<StorageKey>,
 		_at: Option<Block::Hash>,
 	) -> FutureResult<Vec<StorageChangeSet<Block::Hash>>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn read_proof(
@@ -306,7 +284,7 @@ where
 		_block: Option<Block::Hash>,
 		_keys: Vec<StorageKey>,
 	) -> FutureResult<ReadProof<Block::Hash>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn subscribe_storage(
@@ -334,10 +312,7 @@ where
 
 			let changes_stream = subscription_stream::<Block, _, _, _, _, _, _, _, _>(
 				storage_subscriptions.clone(),
-				self.client
-					.import_notification_stream()
-					.map(|notification| Ok::<_, ()>(notification.hash))
-					.compat(),
+				self.client.import_notification_stream().map(|notification| notification.hash),
 				display_error(
 					storage(&*remote_blockchain, fetcher.clone(), initial_block, initial_keys)
 						.map(move |r| r.map(|r| (initial_block, r))),
@@ -365,21 +340,17 @@ where
 						.as_ref()
 						.map(|old_value| **old_value != new_value)
 						.unwrap_or(true);
-					match value_differs {
-						true => Some(StorageChangeSet {
-							block,
-							changes: new_value
-								.iter()
-								.map(|(k, v)| (k.clone(), v.clone()))
-								.collect(),
-						}),
-						false => None,
-					}
+
+					value_differs.then(|| StorageChangeSet {
+						block,
+						changes: new_value.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
+					})
 				},
 			);
 
-			sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-				.send_all(changes_stream.map(|changes| Ok(changes)))
+			changes_stream
+				.map_ok(Ok)
+				.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 				// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
 				.map(|_| ())
 		});
@@ -441,10 +412,7 @@ where
 
 			let versions_stream = subscription_stream::<Block, _, _, _, _, _, _, _, _>(
 				version_subscriptions,
-				self.client
-					.import_notification_stream()
-					.map(|notification| Ok::<_, ()>(notification.hash))
-					.compat(),
+				self.client.import_notification_stream().map(|notification| notification.hash),
 				display_error(
 					runtime_version(&*remote_blockchain, fetcher.clone(), initial_block)
 						.map(move |r| r.map(|r| (initial_block, r))),
@@ -455,15 +423,14 @@ where
 						.as_ref()
 						.map(|old_version| *old_version != new_version)
 						.unwrap_or(true);
-					match version_differs {
-						true => Some(new_version.clone()),
-						false => None,
-					}
+
+					version_differs.then(|| new_version.clone())
 				},
 			);
 
-			sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
-				.send_all(versions_stream.map(|version| Ok(version)))
+			versions_stream
+				.map_ok(Ok)
+				.forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)))
 				// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
 				.map(|_| ())
 		});
@@ -483,7 +450,7 @@ where
 		_targets: Option<String>,
 		_storage_keys: Option<String>,
 	) -> FutureResult<sp_rpc::tracing::TraceBlockResponse> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 }
 
@@ -499,7 +466,7 @@ where
 		_storage_key: PrefixedStorageKey,
 		_keys: Vec<StorageKey>,
 	) -> FutureResult<ReadProof<Block::Hash>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage_keys(
@@ -508,7 +475,7 @@ where
 		_storage_key: PrefixedStorageKey,
 		_prefix: StorageKey,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage_keys_paged(
@@ -519,7 +486,7 @@ where
 		_count: u32,
 		_start_key: Option<StorageKey>,
 	) -> FutureResult<Vec<StorageKey>> {
-		Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
+		async move { Err(client_err(ClientError::NotAvailableOnLightClient)) }.boxed()
 	}
 
 	fn storage(
@@ -560,7 +527,7 @@ where
 				}
 			});
 
-		Box::new(child_storage.boxed().compat())
+		child_storage.boxed()
 	}
 
 	fn storage_hash(
@@ -569,11 +536,9 @@ where
 		storage_key: PrefixedStorageKey,
 		key: StorageKey,
 	) -> FutureResult<Option<Block::Hash>> {
-		Box::new(ChildStateBackend::storage(self, block, storage_key, key).and_then(
-			|maybe_storage| {
-				result(Ok(maybe_storage.map(|storage| HashFor::<Block>::hash(&storage.0))))
-			},
-		))
+		let child_storage = ChildStateBackend::storage(self, block, storage_key, key);
+
+		async move { child_storage.await.map(|r| r.map(|s| HashFor::<Block>::hash(&s.0))) }.boxed()
 	}
 }
 
@@ -687,54 +652,50 @@ fn subscription_stream<
 	initial_request: InitialRequestFuture,
 	issue_request: IssueRequest,
 	compare_values: CompareValues,
-) -> impl Stream<Item = N, Error = ()>
+) -> impl Stream<Item = std::result::Result<N, ()>>
 where
 	Block: BlockT,
 	Requests: 'static + SharedRequests<Block::Hash, V>,
-	FutureBlocksStream: Stream<Item = Block::Hash, Error = ()>,
+	FutureBlocksStream: Stream<Item = Block::Hash>,
 	V: Send + 'static + Clone,
-	InitialRequestFuture:
-		std::future::Future<Output = Result<(Block::Hash, V), ()>> + Send + 'static,
+	InitialRequestFuture: Future<Output = Result<(Block::Hash, V), ()>> + Send + 'static,
 	IssueRequest: 'static + Fn(Block::Hash) -> IssueRequestFuture,
-	IssueRequestFuture: std::future::Future<Output = Result<V, Error>> + Send + 'static,
+	IssueRequestFuture: Future<Output = Result<V, Error>> + Send + 'static,
 	CompareValues: Fn(Block::Hash, Option<&V>, &V) -> Option<N>,
 {
 	// we need to send initial value first, then we'll only be sending if value has changed
 	let previous_value = Arc::new(Mutex::new(None));
 
 	// prepare 'stream' of initial values
-	let initial_value_stream = ignore_error(initial_request).boxed().compat().into_stream();
+	let initial_value_stream = initial_request.into_stream();
 
 	// prepare stream of future values
 	//
 	// we do not want to stop stream if single request fails
 	// (the warning should have been already issued by the request issuer)
-	let future_values_stream = future_blocks_stream.and_then(move |block| {
-		ignore_error(
+	let future_values_stream = future_blocks_stream
+		.then(move |block| {
 			maybe_share_remote_request::<Block, _, _, _, _>(
 				shared_requests.clone(),
 				block,
 				&issue_request,
 			)
-			.map(move |r| r.map(|v| (block, v))),
-		)
-		.boxed()
-		.compat()
-	});
+			.map(move |r| r.map(|v| (block, v)))
+		})
+		.filter(|r| ready(r.is_ok()));
 
 	// now let's return changed values for selected blocks
 	initial_value_stream
 		.chain(future_values_stream)
-		.filter_map(move |block_and_new_value| {
-			block_and_new_value.and_then(|(block, new_value)| {
-				let mut previous_value = previous_value.lock();
-				compare_values(block, previous_value.as_ref(), &new_value).map(
-					|notification_value| {
-						*previous_value = Some(new_value);
-						notification_value
-					},
-				)
-			})
+		.try_filter_map(move |(block, new_value)| {
+			let mut previous_value = previous_value.lock();
+			let res = compare_values(block, previous_value.as_ref(), &new_value).map(
+				|notification_value| {
+					*previous_value = Some(new_value);
+					notification_value
+				},
+			);
+			async move { Ok(res) }
 		})
 		.map_err(|_| ())
 }
@@ -789,24 +750,10 @@ where
 	})
 }
 
-/// Convert successful future result into Ok(Some(result)) and error into Ok(None),
-/// displaying warning.
-fn ignore_error<F, T>(future: F) -> impl std::future::Future<Output = Result<Option<T>, ()>>
-where
-	F: std::future::Future<Output = Result<T, ()>>,
-{
-	future.then(|result| {
-		ready(match result {
-			Ok(result) => Ok(Some(result)),
-			Err(()) => Ok(None),
-		})
-	})
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use rpc::futures::stream::futures_ordered;
+	use futures::{executor, stream};
 	use sp_core::H256;
 	use substrate_test_runtime_client::runtime::Block;
 
@@ -814,7 +761,7 @@ mod tests {
 	fn subscription_stream_works() {
 		let stream = subscription_stream::<Block, _, _, _, _, _, _, _, _>(
 			SimpleSubscriptions::default(),
-			futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]),
+			stream::iter(vec![H256::from([2; 32]), H256::from([3; 32])]),
 			ready(Ok((H256::from([1; 32]), 100))),
 			|block| match block[0] {
 				2 => ready(Ok(100)),
@@ -827,14 +774,14 @@ mod tests {
 			},
 		);
 
-		assert_eq!(stream.collect().wait(), Ok(vec![100, 200]));
+		assert_eq!(executor::block_on(stream.collect::<Vec<_>>()), vec![Ok(100), Ok(200)]);
 	}
 
 	#[test]
 	fn subscription_stream_ignores_failed_requests() {
 		let stream = subscription_stream::<Block, _, _, _, _, _, _, _, _>(
 			SimpleSubscriptions::default(),
-			futures_ordered(vec![result(Ok(H256::from([2; 32]))), result(Ok(H256::from([3; 32])))]),
+			stream::iter(vec![H256::from([2; 32]), H256::from([3; 32])]),
 			ready(Ok((H256::from([1; 32]), 100))),
 			|block| match block[0] {
 				2 => ready(Err(client_err(ClientError::NotAvailableOnLightClient))),
@@ -847,7 +794,7 @@ mod tests {
 			},
 		);
 
-		assert_eq!(stream.collect().wait(), Ok(vec![100, 200]));
+		assert_eq!(executor::block_on(stream.collect::<Vec<_>>()), vec![Ok(100), Ok(200)]);
 	}
 
 	#[test]
diff --git a/substrate/client/rpc/src/state/tests.rs b/substrate/client/rpc/src/state/tests.rs
index 6754a68296a6491aa0c8f273212c95f8fe6dc43b..ef13b37ce42feaa59f5574fa2ebb7d3332c830dc 100644
--- a/substrate/client/rpc/src/state/tests.rs
+++ b/substrate/client/rpc/src/state/tests.rs
@@ -18,11 +18,9 @@
 
 use self::error::Error;
 use super::{state_full::split_range, *};
-
 use crate::testing::TaskExecutor;
 use assert_matches::assert_matches;
-use futures::{compat::Future01CompatExt, executor};
-use futures01::stream::Stream;
+use futures::{executor, StreamExt};
 use sc_block_builder::BlockBuilderProvider;
 use sc_rpc_api::DenyUnsafe;
 use sp_consensus::BlockOrigin;
@@ -63,37 +61,33 @@ fn should_return_storage() {
 	let key = StorageKey(KEY.to_vec());
 
 	assert_eq!(
-		client
-			.storage(key.clone(), Some(genesis_hash).into())
-			.wait()
+		executor::block_on(client.storage(key.clone(), Some(genesis_hash).into()))
 			.map(|x| x.map(|x| x.0.len()))
 			.unwrap()
 			.unwrap() as usize,
 		VALUE.len(),
 	);
 	assert_matches!(
-		client
-			.storage_hash(key.clone(), Some(genesis_hash).into())
-			.wait()
+		executor::block_on(client.storage_hash(key.clone(), Some(genesis_hash).into()))
 			.map(|x| x.is_some()),
 		Ok(true)
 	);
 	assert_eq!(
-		client.storage_size(key.clone(), None).wait().unwrap().unwrap() as usize,
+		executor::block_on(client.storage_size(key.clone(), None)).unwrap().unwrap() as usize,
 		VALUE.len(),
 	);
 	assert_eq!(
-		client.storage_size(StorageKey(b":map".to_vec()), None).wait().unwrap().unwrap() as usize,
+		executor::block_on(client.storage_size(StorageKey(b":map".to_vec()), None))
+			.unwrap()
+			.unwrap() as usize,
 		2 + 3,
 	);
 	assert_eq!(
 		executor::block_on(
 			child
 				.storage(prefixed_storage_key(), key, Some(genesis_hash).into())
-				.map(|x| x.map(|x| x.0.len()))
-				.compat(),
+				.map(|x| x.map(|x| x.unwrap().0.len()))
 		)
-		.unwrap()
 		.unwrap() as usize,
 		CHILD_VALUE.len(),
 	);
@@ -114,21 +108,26 @@ fn should_return_child_storage() {
 	let key = StorageKey(b"key".to_vec());
 
 	assert_matches!(
-		child.storage(
+		executor::block_on(child.storage(
 			child_key.clone(),
 			key.clone(),
 			Some(genesis_hash).into(),
-		).wait(),
+		)),
 		Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1
 	);
 	assert_matches!(
-		child
-			.storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into(),)
-			.wait()
-			.map(|x| x.is_some()),
+		executor::block_on(child.storage_hash(
+			child_key.clone(),
+			key.clone(),
+			Some(genesis_hash).into(),
+		))
+		.map(|x| x.is_some()),
 		Ok(true)
 	);
-	assert_matches!(child.storage_size(child_key.clone(), key.clone(), None).wait(), Ok(Some(1)));
+	assert_matches!(
+		executor::block_on(child.storage_size(child_key.clone(), key.clone(), None)),
+		Ok(Some(1))
+	);
 }
 
 #[test]
@@ -139,16 +138,18 @@ fn should_call_contract() {
 		new_full(client, SubscriptionManager::new(Arc::new(TaskExecutor)), DenyUnsafe::No, None);
 
 	assert_matches!(
-		client
-			.call("balanceOf".into(), Bytes(vec![1, 2, 3]), Some(genesis_hash).into())
-			.wait(),
+		executor::block_on(client.call(
+			"balanceOf".into(),
+			Bytes(vec![1, 2, 3]),
+			Some(genesis_hash).into()
+		)),
 		Err(Error::Client(_))
 	)
 }
 
 #[test]
 fn should_notify_about_storage_changes() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let mut client = Arc::new(substrate_test_runtime_client::new());
@@ -162,7 +163,7 @@ fn should_notify_about_storage_changes() {
 		api.subscribe_storage(Default::default(), subscriber, None.into());
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 
 		let mut builder = client.new_block(Default::default()).unwrap();
 		builder
@@ -177,16 +178,14 @@ fn should_notify_about_storage_changes() {
 		executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
 	}
 
-	// assert notification sent to transport
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None);
+	// Check notification sent to transport
+	executor::block_on((&mut transport).take(2).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
 
 #[test]
 fn should_send_initial_storage_changes_and_notifications() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let mut client = Arc::new(substrate_test_runtime_client::new());
@@ -207,7 +206,7 @@ fn should_send_initial_storage_changes_and_notifications() {
 		);
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 
 		let mut builder = client.new_block(Default::default()).unwrap();
 		builder
@@ -222,14 +221,9 @@ fn should_send_initial_storage_changes_and_notifications() {
 		executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
 	}
 
-	// assert initial values sent to transport
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// assert notification sent to transport
-	let (notification, next) = executor::block_on(next.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None);
+	// Check for the correct number of notifications
+	executor::block_on((&mut transport).take(2).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
 
 #[test]
@@ -299,7 +293,7 @@ fn should_query_storage() {
 		let keys = (1..6).map(|k| StorageKey(vec![k])).collect::<Vec<_>>();
 		let result = api.query_storage(keys.clone(), genesis_hash, Some(block1_hash).into());
 
-		assert_eq!(result.wait().unwrap(), expected);
+		assert_eq!(executor::block_on(result).unwrap(), expected);
 
 		// Query all changes
 		let result = api.query_storage(keys.clone(), genesis_hash, None.into());
@@ -312,18 +306,18 @@ fn should_query_storage() {
 				(StorageKey(vec![5]), Some(StorageData(vec![1]))),
 			],
 		});
-		assert_eq!(result.wait().unwrap(), expected);
+		assert_eq!(executor::block_on(result).unwrap(), expected);
 
 		// Query changes up to block2.
 		let result = api.query_storage(keys.clone(), genesis_hash, Some(block2_hash));
 
-		assert_eq!(result.wait().unwrap(), expected);
+		assert_eq!(executor::block_on(result).unwrap(), expected);
 
 		// Inverted range.
 		let result = api.query_storage(keys.clone(), block1_hash, Some(genesis_hash));
 
 		assert_eq!(
-			result.wait().map_err(|e| e.to_string()),
+			executor::block_on(result).map_err(|e| e.to_string()),
 			Err(Error::InvalidBlockRange {
 				from: format!("1 ({:?})", block1_hash),
 				to: format!("0 ({:?})", genesis_hash),
@@ -339,7 +333,7 @@ fn should_query_storage() {
 		let result = api.query_storage(keys.clone(), genesis_hash, Some(random_hash1));
 
 		assert_eq!(
-			result.wait().map_err(|e| e.to_string()),
+			executor::block_on(result).map_err(|e| e.to_string()),
 			Err(Error::InvalidBlockRange {
 				from: format!("{:?}", genesis_hash),
 				to: format!("{:?}", Some(random_hash1)),
@@ -355,7 +349,7 @@ fn should_query_storage() {
 		let result = api.query_storage(keys.clone(), random_hash1, Some(genesis_hash));
 
 		assert_eq!(
-			result.wait().map_err(|e| e.to_string()),
+			executor::block_on(result).map_err(|e| e.to_string()),
 			Err(Error::InvalidBlockRange {
 				from: format!("{:?}", random_hash1),
 				to: format!("{:?}", Some(genesis_hash)),
@@ -371,7 +365,7 @@ fn should_query_storage() {
 		let result = api.query_storage(keys.clone(), random_hash1, None);
 
 		assert_eq!(
-			result.wait().map_err(|e| e.to_string()),
+			executor::block_on(result).map_err(|e| e.to_string()),
 			Err(Error::InvalidBlockRange {
 				from: format!("{:?}", random_hash1),
 				to: format!("{:?}", Some(block2_hash)), // Best block hash.
@@ -387,7 +381,7 @@ fn should_query_storage() {
 		let result = api.query_storage(keys.clone(), random_hash1, Some(random_hash2));
 
 		assert_eq!(
-			result.wait().map_err(|e| e.to_string()),
+			executor::block_on(result).map_err(|e| e.to_string()),
 			Err(Error::InvalidBlockRange {
 				from: format!("{:?}", random_hash1), // First hash not found.
 				to: format!("{:?}", Some(random_hash2)),
@@ -403,7 +397,7 @@ fn should_query_storage() {
 		let result = api.query_storage_at(keys.clone(), Some(block1_hash));
 
 		assert_eq!(
-			result.wait().unwrap(),
+			executor::block_on(result).unwrap(),
 			vec![StorageChangeSet {
 				block: block1_hash,
 				changes: vec![
@@ -454,7 +448,7 @@ fn should_return_runtime_version() {
 		[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]],\
 		\"transactionVersion\":1}";
 
-	let runtime_version = api.runtime_version(None.into()).wait().unwrap();
+	let runtime_version = executor::block_on(api.runtime_version(None.into())).unwrap();
 	let serialized = serde_json::to_string(&runtime_version).unwrap();
 	assert_eq!(serialized, result);
 
@@ -464,7 +458,7 @@ fn should_return_runtime_version() {
 
 #[test]
 fn should_notify_on_runtime_version_initially() {
-	let (subscriber, id, transport) = Subscriber::new_test("test");
+	let (subscriber, id, mut transport) = Subscriber::new_test("test");
 
 	{
 		let client = Arc::new(substrate_test_runtime_client::new());
@@ -478,14 +472,12 @@ fn should_notify_on_runtime_version_initially() {
 		api.subscribe_runtime_version(Default::default(), subscriber);
 
 		// assert id assigned
-		assert!(matches!(executor::block_on(id.compat()), Ok(Ok(SubscriptionId::String(_)))));
+		assert!(matches!(executor::block_on(id), Ok(Ok(SubscriptionId::String(_)))));
 	}
 
 	// assert initial version sent.
-	let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap();
-	assert!(notification.is_some());
-	// no more notifications on this channel
-	assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None);
+	executor::block_on((&mut transport).take(1).collect::<Vec<_>>());
+	assert!(executor::block_on(transport.next()).is_none());
 }
 
 #[test]
diff --git a/substrate/client/rpc/src/system/mod.rs b/substrate/client/rpc/src/system/mod.rs
index 08258640ad7a090f19b89443f4418d72dd985a99..798f3f035ad501b706c3c9e7c464097af8269e47 100644
--- a/substrate/client/rpc/src/system/mod.rs
+++ b/substrate/client/rpc/src/system/mod.rs
@@ -18,28 +18,27 @@
 
 //! Substrate system API.
 
-#[cfg(test)]
-mod tests;
-
-use futures::{channel::oneshot, compat::Compat, future::BoxFuture, FutureExt, TryFutureExt};
+use self::error::Result;
+use futures::{channel::oneshot, FutureExt};
 use sc_rpc_api::{DenyUnsafe, Receiver};
 use sc_tracing::logging;
 use sp_runtime::traits::{self, Header as HeaderT};
 use sp_utils::mpsc::TracingUnboundedSender;
 
-use self::error::Result;
-
 pub use self::{
 	gen_client::Client as SystemClient,
 	helpers::{Health, NodeRole, PeerInfo, SyncState, SystemInfo},
 };
 pub use sc_rpc_api::system::*;
 
+#[cfg(test)]
+mod tests;
+
 /// Early exit for RPCs that require `--rpc-methods=Unsafe` to be enabled
 macro_rules! bail_if_unsafe {
 	($value: expr) => {
 		if let Err(err) = $value.check_if_safe() {
-			return async move { Err(err.into()) }.boxed().compat()
+			return async move { Err(err.into()) }.boxed()
 		}
 	};
 }
@@ -114,51 +113,42 @@ impl<B: traits::Block> SystemApi<B::Hash, <B::Header as HeaderT>::Number> for Sy
 	fn system_health(&self) -> Receiver<Health> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::Health(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
 	fn system_local_peer_id(&self) -> Receiver<String> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::LocalPeerId(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
 	fn system_local_listen_addresses(&self) -> Receiver<Vec<String>> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::LocalListenAddresses(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
 	fn system_peers(
 		&self,
-	) -> Compat<
-		BoxFuture<'static, rpc::Result<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>>>,
-	> {
+	) -> rpc::BoxFuture<rpc::Result<Vec<PeerInfo<B::Hash, <B::Header as HeaderT>::Number>>>> {
 		bail_if_unsafe!(self.deny_unsafe);
 
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::Peers(tx));
 
-		async move { rx.await.map_err(|_| rpc::Error::internal_error()) }
-			.boxed()
-			.compat()
+		async move { rx.await.map_err(|_| rpc::Error::internal_error()) }.boxed()
 	}
 
-	fn system_network_state(&self) -> Compat<BoxFuture<'static, rpc::Result<rpc::Value>>> {
+	fn system_network_state(&self) -> rpc::BoxFuture<rpc::Result<rpc::Value>> {
 		bail_if_unsafe!(self.deny_unsafe);
 
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::NetworkState(tx));
 
-		async move { rx.await.map_err(|_| rpc::Error::internal_error()) }
-			.boxed()
-			.compat()
+		async move { rx.await.map_err(|_| rpc::Error::internal_error()) }.boxed()
 	}
 
-	fn system_add_reserved_peer(
-		&self,
-		peer: String,
-	) -> Compat<BoxFuture<'static, std::result::Result<(), rpc::Error>>> {
+	fn system_add_reserved_peer(&self, peer: String) -> rpc::BoxFuture<rpc::Result<()>> {
 		bail_if_unsafe!(self.deny_unsafe);
 
 		let (tx, rx) = oneshot::channel();
@@ -171,13 +161,9 @@ impl<B: traits::Block> SystemApi<B::Hash, <B::Header as HeaderT>::Number> for Sy
 			}
 		}
 		.boxed()
-		.compat()
 	}
 
-	fn system_remove_reserved_peer(
-		&self,
-		peer: String,
-	) -> Compat<BoxFuture<'static, std::result::Result<(), rpc::Error>>> {
+	fn system_remove_reserved_peer(&self, peer: String) -> rpc::BoxFuture<rpc::Result<()>> {
 		bail_if_unsafe!(self.deny_unsafe);
 
 		let (tx, rx) = oneshot::channel();
@@ -190,34 +176,33 @@ impl<B: traits::Block> SystemApi<B::Hash, <B::Header as HeaderT>::Number> for Sy
 			}
 		}
 		.boxed()
-		.compat()
 	}
 
 	fn system_reserved_peers(&self) -> Receiver<Vec<String>> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::NetworkReservedPeers(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
 	fn system_node_roles(&self) -> Receiver<Vec<NodeRole>> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::NodeRoles(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
 	fn system_sync_state(&self) -> Receiver<SyncState<<B::Header as HeaderT>::Number>> {
 		let (tx, rx) = oneshot::channel();
 		let _ = self.send_back.unbounded_send(Request::SyncState(tx));
-		Receiver(Compat::new(rx))
+		Receiver(rx)
 	}
 
-	fn system_add_log_filter(&self, directives: String) -> std::result::Result<(), rpc::Error> {
+	fn system_add_log_filter(&self, directives: String) -> rpc::Result<()> {
 		self.deny_unsafe.check_if_safe()?;
 		logging::add_directives(&directives);
 		logging::reload_filter().map_err(|_e| rpc::Error::internal_error())
 	}
 
-	fn system_reset_log_filter(&self) -> std::result::Result<(), rpc::Error> {
+	fn system_reset_log_filter(&self) -> rpc::Result<()> {
 		self.deny_unsafe.check_if_safe()?;
 		logging::reset_log_filter().map_err(|_e| rpc::Error::internal_error())
 	}
diff --git a/substrate/client/rpc/src/system/tests.rs b/substrate/client/rpc/src/system/tests.rs
index a29859e3e9f9f786514ac72b70030e75f166a28f..15b53c3ff462c589c2e6387b5dec1e0f6306c2b2 100644
--- a/substrate/client/rpc/src/system/tests.rs
+++ b/substrate/client/rpc/src/system/tests.rs
@@ -19,7 +19,7 @@
 use super::*;
 
 use assert_matches::assert_matches;
-use futures::prelude::*;
+use futures::{executor, prelude::*};
 use sc_network::{self, config::Role, PeerId};
 use sp_utils::mpsc::tracing_unbounded;
 use std::{
@@ -139,8 +139,7 @@ fn api<T: Into<Option<Status>>>(sync: T) -> System<Block> {
 }
 
 fn wait_receiver<T>(rx: Receiver<T>) -> T {
-	let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
-	runtime.block_on(rx).unwrap()
+	futures::executor::block_on(rx).unwrap()
 }
 
 #[test]
@@ -223,12 +222,10 @@ fn system_local_listen_addresses_works() {
 
 #[test]
 fn system_peers() {
-	let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
-
 	let peer_id = PeerId::random();
 	let req = api(Status { peer_id: peer_id.clone(), peers: 1, is_syncing: false, is_dev: true })
 		.system_peers();
-	let res = runtime.block_on(req).unwrap();
+	let res = executor::block_on(req).unwrap();
 
 	assert_eq!(
 		res,
@@ -243,9 +240,8 @@ fn system_peers() {
 
 #[test]
 fn system_network_state() {
-	let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
 	let req = api(None).system_network_state();
-	let res = runtime.block_on(req).unwrap();
+	let res = executor::block_on(req).unwrap();
 
 	assert_eq!(
 		serde_json::from_value::<sc_network::network_state::NetworkState>(res).unwrap(),
@@ -278,12 +274,11 @@ fn system_network_add_reserved() {
 	let good_peer_id =
 		"/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV";
 	let bad_peer_id = "/ip4/198.51.100.19/tcp/30333";
-	let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
 
 	let good_fut = api(None).system_add_reserved_peer(good_peer_id.into());
 	let bad_fut = api(None).system_add_reserved_peer(bad_peer_id.into());
-	assert_eq!(runtime.block_on(good_fut), Ok(()));
-	assert!(runtime.block_on(bad_fut).is_err());
+	assert_eq!(executor::block_on(good_fut), Ok(()));
+	assert!(executor::block_on(bad_fut).is_err());
 }
 
 #[test]
@@ -291,12 +286,11 @@ fn system_network_remove_reserved() {
 	let good_peer_id = "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV";
 	let bad_peer_id =
 		"/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV";
-	let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
 
 	let good_fut = api(None).system_remove_reserved_peer(good_peer_id.into());
 	let bad_fut = api(None).system_remove_reserved_peer(bad_peer_id.into());
-	assert_eq!(runtime.block_on(good_fut), Ok(()));
-	assert!(runtime.block_on(bad_fut).is_err());
+	assert_eq!(executor::block_on(good_fut), Ok(()));
+	assert!(executor::block_on(bad_fut).is_err());
 }
 
 #[test]
diff --git a/substrate/client/rpc/src/testing.rs b/substrate/client/rpc/src/testing.rs
index e6b30ecdb42b47e513466d6e8d0fdbe156d66852..23071ba10e0d67e821b2a12d3d2f1e152b92a7c9 100644
--- a/substrate/client/rpc/src/testing.rs
+++ b/substrate/client/rpc/src/testing.rs
@@ -18,8 +18,10 @@
 
 //! Testing utils used by the RPC tests.
 
-use futures::{compat::Future01CompatExt, executor, FutureExt};
-use rpc::futures::future as future01;
+use futures::{
+	executor,
+	task::{FutureObj, Spawn, SpawnError},
+};
 
 // Executor shared by all tests.
 //
@@ -30,16 +32,15 @@ lazy_static::lazy_static! {
 		.expect("Failed to create thread pool executor for tests");
 }
 
-type Boxed01Future01 = Box<dyn future01::Future<Item = (), Error = ()> + Send + 'static>;
-
 /// Executor for use in testing
 pub struct TaskExecutor;
-impl future01::Executor<Boxed01Future01> for TaskExecutor {
-	fn execute(
-		&self,
-		future: Boxed01Future01,
-	) -> std::result::Result<(), future01::ExecuteError<Boxed01Future01>> {
-		EXECUTOR.spawn_ok(future.compat().map(drop));
+impl Spawn for TaskExecutor {
+	fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
+		EXECUTOR.spawn_ok(future);
+		Ok(())
+	}
+
+	fn status(&self) -> Result<(), SpawnError> {
 		Ok(())
 	}
 }
diff --git a/substrate/client/service/Cargo.toml b/substrate/client/service/Cargo.toml
index 17aa41536388788512a139cdb2e82eb3e6422a02..c5b7fc7c1e09eab3e60936c484f59f6185145f5c 100644
--- a/substrate/client/service/Cargo.toml
+++ b/substrate/client/service/Cargo.toml
@@ -25,10 +25,9 @@ test-helpers = []
 
 [dependencies]
 thiserror = "1.0.21"
-futures01 = { package = "futures", version = "0.1.29" }
-futures = { version = "0.3.4", features = ["compat"] }
-jsonrpc-pubsub = "15.1"
-jsonrpc-core = "15.1"
+futures = "0.3.16"
+jsonrpc-pubsub = "18.0"
+jsonrpc-core = "18.0"
 rand = "0.7.3"
 parking_lot = "0.11.1"
 lazy_static = "1.4.0"
diff --git a/substrate/client/service/src/builder.rs b/substrate/client/service/src/builder.rs
index f9b68c4ae396d2fef72c70ea986e8679f54d3169..fc9fbad1ef475c08a59fde9984bf5b753b87ca8d 100644
--- a/substrate/client/service/src/builder.rs
+++ b/substrate/client/service/src/builder.rs
@@ -561,6 +561,8 @@ where
 		+ sp_session::SessionKeys<TBl>
 		+ sp_api::ApiExt<TBl, StateBackend = TBackend::State>,
 	TBl: BlockT,
+	TBl::Hash: Unpin,
+	TBl::Header: Unpin,
 	TBackend: 'static + sc_client_api::backend::Backend<TBl> + Send,
 	TExPool: MaintainedTransactionPool<Block = TBl, Hash = <TBl as BlockT>::Hash>
 		+ MallocSizeOfWasm
@@ -762,6 +764,8 @@ where
 	TBackend: sc_client_api::backend::Backend<TBl> + 'static,
 	TRpc: sc_rpc::RpcExtension<sc_rpc::Metadata>,
 	<TCl as ProvideRuntimeApi<TBl>>::Api: sp_session::SessionKeys<TBl> + sp_api::Metadata<TBl>,
+	TBl::Hash: Unpin,
+	TBl::Header: Unpin,
 {
 	use sc_rpc::{author, chain, offchain, state, system};
 
diff --git a/substrate/client/service/src/lib.rs b/substrate/client/service/src/lib.rs
index e9a6d2160676d80c85761dfc632cb6be8927fb99..24506a977e1f7146d8d2bed819a89656d3dc7b16 100644
--- a/substrate/client/service/src/lib.rs
+++ b/substrate/client/service/src/lib.rs
@@ -37,7 +37,7 @@ mod task_manager;
 use std::{collections::HashMap, io, net::SocketAddr, pin::Pin, task::Poll};
 
 use codec::{Decode, Encode};
-use futures::{compat::*, stream, Future, FutureExt, Stream, StreamExt};
+use futures::{stream, Future, FutureExt, Stream, StreamExt};
 use log::{debug, error, warn};
 use parity_util_mem::MallocSizeOf;
 use sc_network::PeerId;
@@ -112,11 +112,7 @@ impl RpcHandlers {
 		mem: &RpcSession,
 		request: &str,
 	) -> Pin<Box<dyn Future<Output = Option<String>> + Send>> {
-		self.0
-			.handle_request(request, mem.metadata.clone())
-			.compat()
-			.map(|res| res.expect("this should never fail"))
-			.boxed()
+		self.0.handle_request(request, mem.metadata.clone()).boxed()
 	}
 
 	/// Provides access to the underlying `MetaIoHandler`
@@ -354,7 +350,7 @@ fn start_rpc_servers<
 	config: &Configuration,
 	mut gen_handler: H,
 	rpc_metrics: sc_rpc_server::RpcMetrics,
-) -> Result<Box<dyn std::any::Any + Send + Sync>, Error> {
+) -> Result<Box<dyn std::any::Any + Send>, Error> {
 	fn maybe_start_server<T, F>(
 		address: Option<SocketAddr>,
 		mut start: F,
@@ -388,16 +384,20 @@ fn start_rpc_servers<
 	}
 
 	Ok(Box::new((
-		config.rpc_ipc.as_ref().map(|path| {
-			sc_rpc_server::start_ipc(
-				&*path,
-				gen_handler(
-					sc_rpc::DenyUnsafe::No,
-					sc_rpc_server::RpcMiddleware::new(rpc_metrics.clone(), "ipc"),
-				)?,
-			)
-			.map_err(Error::from)
-		}),
+		config
+			.rpc_ipc
+			.as_ref()
+			.map(|path| {
+				sc_rpc_server::start_ipc(
+					&*path,
+					gen_handler(
+						sc_rpc::DenyUnsafe::No,
+						sc_rpc_server::RpcMiddleware::new(rpc_metrics.clone(), "ipc"),
+					)?,
+				)
+				.map_err(Error::from)
+			})
+			.transpose()?,
 		maybe_start_server(config.rpc_http, |address| {
 			sc_rpc_server::start_http(
 				address,
@@ -441,7 +441,7 @@ fn start_rpc_servers<
 	_: &Configuration,
 	_: H,
 	_: sc_rpc_server::RpcMetrics,
-) -> Result<Box<dyn std::any::Any + Send + Sync>, error::Error> {
+) -> Result<Box<dyn std::any::Any + Send>, error::Error> {
 	Ok(Box::new(()))
 }
 
@@ -459,7 +459,7 @@ impl RpcSession {
 	/// messages.
 	///
 	/// The `RpcSession` must be kept alive in order to receive messages on the sender.
-	pub fn new(sender: futures01::sync::mpsc::Sender<String>) -> RpcSession {
+	pub fn new(sender: futures::channel::mpsc::UnboundedSender<String>) -> RpcSession {
 		RpcSession { metadata: sender.into() }
 	}
 }
diff --git a/substrate/client/service/src/task_manager/mod.rs b/substrate/client/service/src/task_manager/mod.rs
index d759798f744b685fff187f222e1e19865037f1fa..ae89b785870f0f4d72cb29c173d2ab44375b4a1c 100644
--- a/substrate/client/service/src/task_manager/mod.rs
+++ b/substrate/client/service/src/task_manager/mod.rs
@@ -232,7 +232,7 @@ pub struct TaskManager {
 	/// A receiver for spawned essential-tasks concluding.
 	essential_failed_rx: TracingUnboundedReceiver<()>,
 	/// Things to keep alive until the task manager is dropped.
-	keep_alive: Box<dyn std::any::Any + Send + Sync>,
+	keep_alive: Box<dyn std::any::Any + Send>,
 	/// A sender to a stream of background tasks. This is used for the completion future.
 	task_notifier: TracingUnboundedSender<JoinFuture>,
 	/// This future will complete when all the tasks are joined and the stream is closed.
@@ -359,7 +359,7 @@ impl TaskManager {
 	}
 
 	/// Set what the task manager should keep alive, can be called multiple times.
-	pub fn keep_alive<T: 'static + Send + Sync>(&mut self, to_keep_alive: T) {
+	pub fn keep_alive<T: 'static + Send>(&mut self, to_keep_alive: T) {
 		// allows this fn to safely called multiple times.
 		use std::mem;
 		let old = mem::replace(&mut self.keep_alive, Box::new(()));
diff --git a/substrate/client/service/test/Cargo.toml b/substrate/client/service/test/Cargo.toml
index d0081b32491178b9a251b53157348891d98556dc..e64bb30045bb18ac2d63d61342271f9f869586a4 100644
--- a/substrate/client/service/test/Cargo.toml
+++ b/substrate/client/service/test/Cargo.toml
@@ -27,7 +27,7 @@ sp-externalities = { version = "0.10.0-dev", path = "../../../primitives/externa
 sp-trie = { version = "4.0.0-dev", path = "../../../primitives/trie" }
 sp-storage = { version = "4.0.0-dev", path = "../../../primitives/storage" }
 sc-client-db = { version = "0.10.0-dev", default-features = false, path = "../../db" }
-futures = { version = "0.3.1", features = ["compat"] }
+futures = "0.3.16"
 sc-service = { version = "0.10.0-dev", features = ["test-helpers"], path = "../../service" }
 sc-network = { version = "0.10.0-dev", path = "../../network" }
 sp-consensus = { version = "0.10.0-dev", path = "../../../primitives/consensus/common" }
diff --git a/substrate/client/sync-state-rpc/Cargo.toml b/substrate/client/sync-state-rpc/Cargo.toml
index a96b80ff930deb6e7f66d403ad64aaeec5d6c151..9da9944a54547c13e75ec4709a83e0cd4662c9b5 100644
--- a/substrate/client/sync-state-rpc/Cargo.toml
+++ b/substrate/client/sync-state-rpc/Cargo.toml
@@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 thiserror = "1.0.21"
-jsonrpc-core = "15.0"
-jsonrpc-core-client = "15.0"
-jsonrpc-derive = "15.0"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 sc-chain-spec = { version = "4.0.0-dev", path = "../chain-spec" }
 sc-client-api = { version = "4.0.0-dev", path = "../api" }
 sc-consensus-babe = { version = "0.10.0-dev", path = "../consensus/babe" }
diff --git a/substrate/client/transaction-pool/Cargo.toml b/substrate/client/transaction-pool/Cargo.toml
index ef50d17268c95e99ec79ad9aa56095bb415c45a3..931043da09e3aed6001abb954523a72850e8bafd 100644
--- a/substrate/client/transaction-pool/Cargo.toml
+++ b/substrate/client/transaction-pool/Cargo.toml
@@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.0.0" }
 thiserror = "1.0.21"
-futures = { version = "0.3.1", features = ["compat"] }
+futures = "0.3.16"
 intervalier = "0.4.0"
 log = "0.4.8"
 parity-util-mem = { version = "0.10.0", default-features = false, features = ["primitive-types"] }
diff --git a/substrate/client/transaction-pool/api/src/lib.rs b/substrate/client/transaction-pool/api/src/lib.rs
index e861e6e0424d77afb6d6d095246c7b45dac451ec..4a083ad2e15a2784ec07c4fd468018b319cbdead 100644
--- a/substrate/client/transaction-pool/api/src/lib.rs
+++ b/substrate/client/transaction-pool/api/src/lib.rs
@@ -126,7 +126,7 @@ pub enum TransactionStatus<Hash, BlockHash> {
 
 /// The stream of transaction events.
 pub type TransactionStatusStream<Hash, BlockHash> =
-	dyn Stream<Item = TransactionStatus<Hash, BlockHash>> + Send + Unpin;
+	dyn Stream<Item = TransactionStatus<Hash, BlockHash>> + Send;
 
 /// The import notification event stream.
 pub type ImportNotificationStream<H> = futures::channel::mpsc::Receiver<H>;
@@ -210,7 +210,7 @@ pub trait TransactionPool: Send + Sync {
 		at: &BlockId<Self::Block>,
 		source: TransactionSource,
 		xt: TransactionFor<Self>,
-	) -> PoolFuture<Box<TransactionStatusStreamFor<Self>>, Self::Error>;
+	) -> PoolFuture<Pin<Box<TransactionStatusStreamFor<Self>>>, Self::Error>;
 
 	// *** Block production / Networking
 	/// Get an iterator for ready transactions ordered by priority.
diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs
index 302c7a1b59b65afeea807f190b47acae04ddf22b..c35bba8d2a98d6a97e238db5a963bea32e502003 100644
--- a/substrate/client/transaction-pool/src/lib.rs
+++ b/substrate/client/transaction-pool/src/lib.rs
@@ -290,16 +290,16 @@ where
 		at: &BlockId<Self::Block>,
 		source: TransactionSource,
 		xt: TransactionFor<Self>,
-	) -> PoolFuture<Box<TransactionStatusStreamFor<Self>>, Self::Error> {
+	) -> PoolFuture<Pin<Box<TransactionStatusStreamFor<Self>>>, Self::Error> {
 		let at = *at;
 		let pool = self.pool.clone();
 
 		self.metrics.report(|metrics| metrics.submitted_transactions.inc());
 
 		async move {
-			pool.submit_and_watch(&at, source, xt)
-				.map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _))
-				.await
+			let watcher = pool.submit_and_watch(&at, source, xt).await?;
+
+			Ok(watcher.into_stream().boxed())
 		}
 		.boxed()
 	}
diff --git a/substrate/frame/contracts/rpc/Cargo.toml b/substrate/frame/contracts/rpc/Cargo.toml
index 32aa9e21a1a0f99b259de5586dd164791b7b211c..b73039ba7191e2d10b792bd7c4ade5ddc53fd1fb 100644
--- a/substrate/frame/contracts/rpc/Cargo.toml
+++ b/substrate/frame/contracts/rpc/Cargo.toml
@@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2" }
-jsonrpc-core = "15"
-jsonrpc-core-client = "15"
-jsonrpc-derive = "15"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 serde = { version = "1", features = ["derive"] }
 
 # Substrate Dependencies
diff --git a/substrate/frame/merkle-mountain-range/rpc/Cargo.toml b/substrate/frame/merkle-mountain-range/rpc/Cargo.toml
index 637abe60c2e459a09fab4a299a0af420904757e3..fe2d9cfc552b9b34035aed363e7f2f6bc8356e4f 100644
--- a/substrate/frame/merkle-mountain-range/rpc/Cargo.toml
+++ b/substrate/frame/merkle-mountain-range/rpc/Cargo.toml
@@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 serde = { version = "1.0.126", features = ["derive"] }
 
 sp-api = { version = "4.0.0-dev", path = "../../../primitives/api" }
diff --git a/substrate/frame/transaction-payment/rpc/Cargo.toml b/substrate/frame/transaction-payment/rpc/Cargo.toml
index 785a7c9c96abc4bf9f963eb0a652d3894b625894..3858c41a38763f36abb773aa52d66e02d8fe4850 100644
--- a/substrate/frame/transaction-payment/rpc/Cargo.toml
+++ b/substrate/frame/transaction-payment/rpc/Cargo.toml
@@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 
 sp-api = { version = "4.0.0-dev", path = "../../../primitives/api" }
 sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain" }
diff --git a/substrate/test-utils/Cargo.toml b/substrate/test-utils/Cargo.toml
index e59d0556522f689f5ec402a88bd1c2dffc232a26..d828e418d906004e9a06e283411adba340a77d32 100644
--- a/substrate/test-utils/Cargo.toml
+++ b/substrate/test-utils/Cargo.toml
@@ -12,7 +12,7 @@ description = "Substrate test utilities"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-futures = { version = "0.3.1", features = ["compat"] }
+futures = "0.3.16"
 substrate-test-utils-derive = { version = "0.10.0-dev", path = "./derive" }
 tokio = { version = "0.2.13", features = ["macros"] }
 
diff --git a/substrate/test-utils/client/Cargo.toml b/substrate/test-utils/client/Cargo.toml
index a647aeaedc4f1a1b4e233ff23520072538e44540..425cac7eb776a893d36f6bcf8e87756ddbc9ec1d 100644
--- a/substrate/test-utils/client/Cargo.toml
+++ b/substrate/test-utils/client/Cargo.toml
@@ -13,8 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-futures = "0.3.9"
-futures01 = { package = "futures", version = "0.1.29" }
+futures = "0.3.16"
 hash-db = "0.15.2"
 hex = "0.4"
 serde = "1.0.126"
diff --git a/substrate/test-utils/client/src/lib.rs b/substrate/test-utils/client/src/lib.rs
index a8d7818ace6da018a53d12f5c17b09f39af3b7df..3eb7eb0b7174ce71b5a7f2c583a1e661e7c12e76 100644
--- a/substrate/test-utils/client/src/lib.rs
+++ b/substrate/test-utils/client/src/lib.rs
@@ -307,7 +307,7 @@ pub struct RpcTransactionOutput {
 	/// The session object.
 	pub session: RpcSession,
 	/// An async receiver if data will be returned via a callback.
-	pub receiver: futures01::sync::mpsc::Receiver<String>,
+	pub receiver: futures::channel::mpsc::UnboundedReceiver<String>,
 }
 
 impl std::fmt::Debug for RpcTransactionOutput {
@@ -347,7 +347,7 @@ impl RpcHandlersExt for RpcHandlers {
 		&self,
 		extrinsic: OpaqueExtrinsic,
 	) -> Pin<Box<dyn Future<Output = Result<RpcTransactionOutput, RpcTransactionError>> + Send>> {
-		let (tx, rx) = futures01::sync::mpsc::channel(0);
+		let (tx, rx) = futures::channel::mpsc::unbounded();
 		let mem = RpcSession::new(tx.into());
 		Box::pin(
 			self.rpc_query(
@@ -370,7 +370,7 @@ impl RpcHandlersExt for RpcHandlers {
 pub(crate) fn parse_rpc_result(
 	result: Option<String>,
 	session: RpcSession,
-	receiver: futures01::sync::mpsc::Receiver<String>,
+	receiver: futures::channel::mpsc::UnboundedReceiver<String>,
 ) -> Result<RpcTransactionOutput, RpcTransactionError> {
 	if let Some(ref result) = result {
 		let json: serde_json::Value =
@@ -426,8 +426,9 @@ where
 mod tests {
 	use sc_service::RpcSession;
 
-	fn create_session_and_receiver() -> (RpcSession, futures01::sync::mpsc::Receiver<String>) {
-		let (tx, rx) = futures01::sync::mpsc::channel(0);
+	fn create_session_and_receiver(
+	) -> (RpcSession, futures::channel::mpsc::UnboundedReceiver<String>) {
+		let (tx, rx) = futures::channel::mpsc::unbounded();
 		let mem = RpcSession::new(tx.into());
 
 		(mem, rx)
diff --git a/substrate/test-utils/runtime/transaction-pool/Cargo.toml b/substrate/test-utils/runtime/transaction-pool/Cargo.toml
index 420d052829aabb72d99c79e93de54771a9e5f5ab..09839ebae6ffe1a925ec43cdda68a2e715e3d0b6 100644
--- a/substrate/test-utils/runtime/transaction-pool/Cargo.toml
+++ b/substrate/test-utils/runtime/transaction-pool/Cargo.toml
@@ -19,5 +19,5 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain"
 sp-runtime = { version = "4.0.0-dev", path = "../../../primitives/runtime" }
 sc-transaction-pool = { version = "4.0.0-dev", path = "../../../client/transaction-pool", features = ["test-helpers"] }
 sc-transaction-pool-api = { version = "4.0.0-dev", path = "../../../client/transaction-pool/api" }
-futures = { version = "0.3.1", features = ["compat"] }
+futures = "0.3.16"
 derive_more = "0.99.2"
diff --git a/substrate/test-utils/test-runner/Cargo.toml b/substrate/test-utils/test-runner/Cargo.toml
index 06454ee24eaed808e5185a7e673d9ead19dee96a..dc443d5d8d51689135b829df01705e07a3ada54a 100644
--- a/substrate/test-utils/test-runner/Cargo.toml
+++ b/substrate/test-utils/test-runner/Cargo.toml
@@ -48,8 +48,8 @@ sp-runtime-interface = { path = "../../primitives/runtime-interface" }
 frame-system = { path = "../../frame/system" }
 
 log = "0.4.8"
-futures = { package = "futures", version = "0.3", features = ["compat"] }
+futures = "0.3.16"
 tokio = { version = "0.2", features = ["signal"] }
 # Calling RPC
-jsonrpc-core = "15.1"
+jsonrpc-core = "18.0"
 num-traits = "0.2.14"
diff --git a/substrate/test-utils/test-runner/src/client.rs b/substrate/test-utils/test-runner/src/client.rs
index 17117e0b5ee674b12cadb0bdf4b7d5b5edb6a9b8..80b11e7bff7fc9aa13e759ec83fb1fed3a5ee15f 100644
--- a/substrate/test-utils/test-runner/src/client.rs
+++ b/substrate/test-utils/test-runner/src/client.rs
@@ -94,7 +94,8 @@ where
 		+ ApiExt<T::Block, StateBackend = <TFullBackend<T::Block> as Backend<T::Block>>::State>
 		+ GrandpaApi<T::Block>,
 	<T::Runtime as frame_system::Config>::Call: From<frame_system::Call<T::Runtime>>,
-	<<T as ChainInfo>::Block as BlockT>::Hash: FromStr,
+	<<T as ChainInfo>::Block as BlockT>::Hash: FromStr + Unpin,
+	<<T as ChainInfo>::Block as BlockT>::Header: Unpin,
 	<<<T as ChainInfo>::Block as BlockT>::Header as Header>::Number:
 		num_traits::cast::AsPrimitive<usize>,
 {
diff --git a/substrate/utils/browser/Cargo.toml b/substrate/utils/browser/Cargo.toml
index c1f4c20c3645a2115b03507a238f1c2815be2f90..3522432001a0d0b6e32834430617d4a3ef8d91f5 100644
--- a/substrate/utils/browser/Cargo.toml
+++ b/substrate/utils/browser/Cargo.toml
@@ -13,8 +13,7 @@ readme = "README.md"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-futures = { version = "0.3", features = ["compat"] }
-futures01 = { package = "futures", version = "0.1.29" }
+futures = "0.3.16"
 log = "0.4.8"
 libp2p-wasm-ext = { version = "0.28.1", features = ["websocket"] }
 console_error_panic_hook = "0.1.6"
diff --git a/substrate/utils/browser/src/lib.rs b/substrate/utils/browser/src/lib.rs
index 6cd35f22bffba817671fc376f362957eadf1cae1..49f5c7ad4bd1bcf779e3f4b57dee9cae56678540 100644
--- a/substrate/utils/browser/src/lib.rs
+++ b/substrate/utils/browser/src/lib.rs
@@ -17,11 +17,9 @@
 
 use futures::{
 	channel::{mpsc, oneshot},
-	compat::*,
-	future::{ok, ready, select},
+	future::{ready, select},
 	prelude::*,
 };
-use futures01::sync::mpsc as mpsc01;
 use libp2p_wasm_ext::{ffi, ExtTransport};
 use log::{debug, info};
 use sc_chain_spec::Extension;
@@ -166,7 +164,7 @@ impl Client {
 	/// Allows starting an RPC request. Returns a `Promise` containing the result of that request.
 	#[wasm_bindgen(js_name = "rpcSend")]
 	pub fn rpc_send(&mut self, rpc: &str) -> js_sys::Promise {
-		let rpc_session = RpcSession::new(mpsc01::channel(1).0);
+		let rpc_session = RpcSession::new(mpsc::unbounded().0);
 		let (tx, rx) = oneshot::channel();
 		let _ = self.rpc_send_tx.unbounded_send(RpcMessage {
 			rpc_json: rpc.to_owned(),
@@ -184,7 +182,7 @@ impl Client {
 	/// Subscribes to an RPC pubsub endpoint.
 	#[wasm_bindgen(js_name = "rpcSubscribe")]
 	pub fn rpc_subscribe(&mut self, rpc: &str, callback: js_sys::Function) {
-		let (tx, rx) = mpsc01::channel(4);
+		let (tx, rx) = mpsc::unbounded();
 		let rpc_session = RpcSession::new(tx);
 		let (fut_tx, fut_rx) = oneshot::channel();
 		let _ = self.rpc_send_tx.unbounded_send(RpcMessage {
@@ -200,10 +198,9 @@ impl Client {
 
 		wasm_bindgen_futures::spawn_local(async move {
 			let _ = rx
-				.compat()
-				.try_for_each(|s| {
+				.for_each(|s| {
 					let _ = callback.call1(&callback, &JsValue::from_str(&s));
-					ok(())
+					ready(())
 				})
 				.await;
 
diff --git a/substrate/utils/frame/rpc/support/Cargo.toml b/substrate/utils/frame/rpc/support/Cargo.toml
index 4d4631be2025e9a58766944d8eb3b5e23c8ccc24..5651b1da3aab26299246c51f61ea67d3b6762ce8 100644
--- a/substrate/utils/frame/rpc/support/Cargo.toml
+++ b/substrate/utils/frame/rpc/support/Cargo.toml
@@ -12,9 +12,9 @@ description = "Substrate RPC for FRAME's support"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-futures = { version = "0.3.0", features = ["compat"] }
-jsonrpc-client-transports = { version = "15.1.0", default-features = false, features = ["http"] }
-jsonrpc-core = "15.1.0"
+futures = "0.3.16"
+jsonrpc-client-transports = { version = "18.0.0", features = ["http"] }
+jsonrpc-core = "18.0.0"
 codec = { package = "parity-scale-codec", version = "2.0.0" }
 serde = "1"
 frame-support = { version = "4.0.0-dev", path = "../../../../frame/support" }
diff --git a/substrate/utils/frame/rpc/support/src/lib.rs b/substrate/utils/frame/rpc/support/src/lib.rs
index 37d85f41825d3da4d2b9b077011bbb420d4d9ee3..1b2453c361d9768845c9fe42df24702f6da91eb8 100644
--- a/substrate/utils/frame/rpc/support/src/lib.rs
+++ b/substrate/utils/frame/rpc/support/src/lib.rs
@@ -23,7 +23,6 @@
 use codec::{DecodeAll, FullCodec, FullEncode};
 use core::marker::PhantomData;
 use frame_support::storage::generator::{StorageDoubleMap, StorageMap, StorageValue};
-use futures::compat::Future01CompatExt;
 use jsonrpc_client_transports::RpcError;
 use sc_rpc_api::state::StateClient;
 use serde::{de::DeserializeOwned, Serialize};
@@ -32,7 +31,6 @@ use sp_storage::{StorageData, StorageKey};
 /// A typed query on chain state usable from an RPC client.
 ///
 /// ```no_run
-/// # use futures::compat::Future01CompatExt;
 /// # use jsonrpc_client_transports::RpcError;
 /// # use jsonrpc_client_transports::transports::http;
 /// # use codec::Encode;
@@ -69,7 +67,7 @@ use sp_storage::{StorageData, StorageKey};
 /// }
 ///
 /// # async fn test() -> Result<(), RpcError> {
-/// let conn = http::connect("http://[::1]:9933").compat().await?;
+/// let conn = http::connect("http://[::1]:9933").await?;
 /// let cl = StateClient::<Hash>::new(conn);
 ///
 /// let q = StorageQuery::value::<LastActionId>();
@@ -127,9 +125,9 @@ impl<V: FullCodec> StorageQuery<V> {
 		state_client: &StateClient<Hash>,
 		block_index: Option<Hash>,
 	) -> Result<Option<V>, RpcError> {
-		let opt: Option<StorageData> = state_client.storage(self.key, block_index).compat().await?;
+		let opt: Option<StorageData> = state_client.storage(self.key, block_index).await?;
 		opt.map(|encoded| V::decode_all(&encoded.0))
 			.transpose()
-			.map_err(|decode_err| RpcError::Other(decode_err.into()))
+			.map_err(|decode_err| RpcError::Other(Box::new(decode_err)))
 	}
 }
diff --git a/substrate/utils/frame/rpc/system/Cargo.toml b/substrate/utils/frame/rpc/system/Cargo.toml
index 909da94624a1da3c57ca4047a53ff4c42008288b..9d56d039134491631805ec85ff7fb30806296310 100644
--- a/substrate/utils/frame/rpc/system/Cargo.toml
+++ b/substrate/utils/frame/rpc/system/Cargo.toml
@@ -15,10 +15,10 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 sc-client-api = { version = "4.0.0-dev", path = "../../../../client/api" }
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-futures = { version = "0.3.4", features = ["compat"] }
-jsonrpc-core = "15.1.0"
-jsonrpc-core-client = "15.1.0"
-jsonrpc-derive = "15.1.0"
+futures = "0.3.16"
+jsonrpc-core = "18.0.0"
+jsonrpc-core-client = "18.0.0"
+jsonrpc-derive = "18.0.0"
 log = "0.4.8"
 serde = { version = "1.0.126", features = ["derive"] }
 sp-runtime = { version = "4.0.0-dev", path = "../../../../primitives/runtime" }
diff --git a/substrate/utils/frame/rpc/system/src/lib.rs b/substrate/utils/frame/rpc/system/src/lib.rs
index 64c25157dbe216c15d1438f30283ee5bcb502ff7..f0f37f0b206750786c5a51e949a3973b8661b54d 100644
--- a/substrate/utils/frame/rpc/system/src/lib.rs
+++ b/substrate/utils/frame/rpc/system/src/lib.rs
@@ -19,12 +19,9 @@
 
 use std::sync::Arc;
 
-use codec::{self, Codec, Decode, Encode};
-use futures::future::{ready, TryFutureExt};
-use jsonrpc_core::{
-	futures::future::{self as rpc_future, result, Future},
-	Error as RpcError, ErrorCode,
-};
+use codec::{Codec, Decode, Encode};
+use futures::{future::ready, FutureExt, TryFutureExt};
+use jsonrpc_core::{Error as RpcError, ErrorCode};
 use jsonrpc_derive::rpc;
 use sc_client_api::light::{future_header, Fetcher, RemoteBlockchain, RemoteCallRequest};
 use sc_rpc_api::DenyUnsafe;
@@ -38,7 +35,7 @@ pub use self::gen_client::Client as SystemClient;
 pub use frame_system_rpc_runtime_api::AccountNonceApi;
 
 /// Future that resolves to account nonce.
-pub type FutureResult<T> = Box<dyn Future<Item = T, Error = RpcError> + Send>;
+type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T, RpcError>>;
 
 /// System RPC methods.
 #[rpc]
@@ -116,7 +113,8 @@ where
 			Ok(adjust_nonce(&*self.pool, account, nonce))
 		};
 
-		Box::new(result(get_nonce()))
+		let res = get_nonce();
+		async move { res }.boxed()
 	}
 
 	fn dry_run(
@@ -125,7 +123,7 @@ where
 		at: Option<<Block as traits::Block>::Hash>,
 	) -> FutureResult<Bytes> {
 		if let Err(err) = self.deny_unsafe.check_if_safe() {
-			return Box::new(rpc_future::err(err.into()))
+			return async move { Err(err.into()) }.boxed()
 		}
 
 		let dry_run = || {
@@ -150,7 +148,9 @@ where
 			Ok(Encode::encode(&result).into())
 		};
 
-		Box::new(result(dry_run()))
+		let res = dry_run();
+
+		async move { res }.boxed()
 	}
 }
 
@@ -197,19 +197,19 @@ where
 					.ok_or_else(|| ClientError::UnknownBlock(format!("{}", best_hash))),
 			)
 		});
-		let future_nonce = future_best_header
-			.and_then(move |best_header| {
-				fetcher.remote_call(RemoteCallRequest {
-					block: best_hash,
-					header: best_header,
-					method: "AccountNonceApi_account_nonce".into(),
-					call_data,
-					retry_count: None,
-				})
+
+		let future_nonce = future_best_header.and_then(move |best_header| {
+			fetcher.remote_call(RemoteCallRequest {
+				block: best_hash,
+				header: best_header,
+				method: "AccountNonceApi_account_nonce".into(),
+				call_data,
+				retry_count: None,
 			})
-			.compat();
-		let future_nonce = future_nonce.and_then(|nonce| {
-			Decode::decode(&mut &nonce[..])
+		});
+
+		let future_nonce = future_nonce.and_then(|nonce| async move {
+			Index::decode(&mut &nonce[..])
 				.map_err(|e| ClientError::CallResultDecode("Cannot decode account nonce", e))
 		});
 		let future_nonce = future_nonce.map_err(|e| RpcError {
@@ -219,9 +219,7 @@ where
 		});
 
 		let pool = self.pool.clone();
-		let future_nonce = future_nonce.map(move |nonce| adjust_nonce(&*pool, account, nonce));
-
-		Box::new(future_nonce)
+		future_nonce.map_ok(move |nonce| adjust_nonce(&*pool, account, nonce)).boxed()
 	}
 
 	fn dry_run(
@@ -229,11 +227,14 @@ where
 		_extrinsic: Bytes,
 		_at: Option<<Block as traits::Block>::Hash>,
 	) -> FutureResult<Bytes> {
-		Box::new(result(Err(RpcError {
-			code: ErrorCode::MethodNotFound,
-			message: "Unable to dry run extrinsic.".into(),
-			data: None,
-		})))
+		async {
+			Err(RpcError {
+				code: ErrorCode::MethodNotFound,
+				message: "Unable to dry run extrinsic.".into(),
+				data: None,
+			})
+		}
+		.boxed()
 	}
 }
 
@@ -317,7 +318,7 @@ mod tests {
 		let nonce = accounts.nonce(AccountKeyring::Alice.into());
 
 		// then
-		assert_eq!(nonce.wait().unwrap(), 2);
+		assert_eq!(block_on(nonce).unwrap(), 2);
 	}
 
 	#[test]
@@ -336,7 +337,7 @@ mod tests {
 		let res = accounts.dry_run(vec![].into(), None);
 
 		// then
-		assert_eq!(res.wait(), Err(RpcError::method_not_found()));
+		assert_eq!(block_on(res), Err(RpcError::method_not_found()));
 	}
 
 	#[test]
@@ -363,7 +364,7 @@ mod tests {
 		let res = accounts.dry_run(tx.encode().into(), None);
 
 		// then
-		let bytes = res.wait().unwrap().0;
+		let bytes = block_on(res).unwrap().0;
 		let apply_res: ApplyExtrinsicResult = Decode::decode(&mut bytes.as_slice()).unwrap();
 		assert_eq!(apply_res, Ok(Ok(())));
 	}
@@ -392,7 +393,7 @@ mod tests {
 		let res = accounts.dry_run(tx.encode().into(), None);
 
 		// then
-		let bytes = res.wait().unwrap().0;
+		let bytes = block_on(res).unwrap().0;
 		let apply_res: ApplyExtrinsicResult = Decode::decode(&mut bytes.as_slice()).unwrap();
 		assert_eq!(apply_res, Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)));
 	}