diff --git a/substrate/.gitlab-ci.yml b/substrate/.gitlab-ci.yml
index b803ce3d57252629b1785724ee29679ad4ee7670..c87cdae7c3562ad2a90ce0b8cbcace2aec64b620 100644
--- a/substrate/.gitlab-ci.yml
+++ b/substrate/.gitlab-ci.yml
@@ -2,7 +2,7 @@ stages:
   - test
   - build
 
-image:                             parity/rust:substrate
+image:                             parity/rust:nightly
 
 variables:
   CI_SERVER_NAME:                  "GitLab CI"
diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index df76975816b72f11d52ef325cb5a331f6fef3f84..ab11df3d8a09734c3745d6ff6ec8f8c26e3a5d5f 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -5,7 +5,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -329,8 +329,8 @@ dependencies = [
  "isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "simplelog 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -427,7 +427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "ctr"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -451,7 +451,7 @@ dependencies = [
  "base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "chashmap 2.2.1 (git+https://github.com/redox-os/tfs)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -704,7 +704,7 @@ dependencies = [
 
 [[package]]
 name = "h2"
-version = "0.1.12"
+version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -805,13 +805,13 @@ dependencies = [
 
 [[package]]
 name = "hyper"
-version = "0.12.11"
+version = "0.12.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -894,21 +894,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 [[package]]
 name = "jsonrpc-core"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "jsonrpc-http-server"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
- "hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -919,17 +919,17 @@ dependencies = [
 [[package]]
 name = "jsonrpc-macros"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
  "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "jsonrpc-pubsub"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
  "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -939,7 +939,7 @@ dependencies = [
 [[package]]
 name = "jsonrpc-server-utils"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
  "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -955,7 +955,7 @@ dependencies = [
 [[package]]
 name = "jsonrpc-ws-server"
 version = "9.0.0"
-source = "git+https://github.com/paritytech/jsonrpc.git#8d41129955e9abf08399cd052b4a6df4e0743ad6"
+source = "git+https://github.com/paritytech/jsonrpc.git#207a277b098943864ecaf22dbab7a5e309866d6b"
 dependencies = [
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
@@ -1216,8 +1216,8 @@ dependencies = [
  "libp2p-core 0.1.0 (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)",
  "multiaddr 0.3.0 (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1276,7 +1276,7 @@ dependencies = [
  "aes-ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "asn1_der 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "libp2p-core 0.1.0 (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)",
@@ -1514,7 +1514,7 @@ dependencies = [
  "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "multihash 0.8.1-pre (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "unsigned-varint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1598,11 +1598,16 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "node-executor 0.1.0",
- "node-network 0.1.0",
  "node-primitives 0.1.0",
  "node-runtime 0.1.0",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "substrate-cli 0.3.0",
+ "substrate-client 0.1.0",
+ "substrate-consensus-aura 0.1.0",
  "substrate-network 0.1.0",
  "substrate-primitives 0.1.0",
  "substrate-service 0.3.0",
@@ -1611,28 +1616,6 @@ dependencies = [
  "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "node-consensus"
-version = "0.1.0"
-dependencies = [
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "node-primitives 0.1.0",
- "node-runtime 0.1.0",
- "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "sr-primitives 0.1.0",
- "srml-system 0.1.0",
- "substrate-client 0.1.0",
- "substrate-keyring 0.1.0",
- "substrate-primitives 0.1.0",
- "substrate-transaction-pool 0.1.0",
- "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "node-executor"
 version = "0.1.0"
@@ -1661,21 +1644,6 @@ dependencies = [
  "wabt 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "node-network"
-version = "0.1.0"
-dependencies = [
- "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "node-consensus 0.1.0",
- "node-primitives 0.1.0",
- "rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "substrate-consensus-rhd 0.1.0",
- "substrate-network 0.1.0",
- "substrate-primitives 0.1.0",
- "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "node-primitives"
 version = "0.1.0"
@@ -1683,8 +1651,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
  "substrate-primitives 0.1.0",
@@ -1701,8 +1669,8 @@ dependencies = [
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-api 0.1.0",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
@@ -1720,6 +1688,7 @@ dependencies = [
  "srml-system 0.1.0",
  "srml-timestamp 0.1.0",
  "srml-treasury 0.1.0",
+ "srml-upgrade-key 0.1.0",
  "substrate-keyring 0.1.0",
  "substrate-primitives 0.1.0",
 ]
@@ -1794,12 +1763,12 @@ dependencies = [
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl"
-version = "0.10.13"
+version = "0.10.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1807,12 +1776,12 @@ dependencies = [
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.37"
+version = "0.9.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1834,21 +1803,13 @@ name = "parity-bytes"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "parity-codec"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "parity-codec"
 version = "2.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2201,20 +2162,10 @@ dependencies = [
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "rhododendron"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "rhododendron"
 version = "0.4.0"
-source = "git+https://github.com/paritytech/rhododendron.git#64b46b577479a3b6c493fa6db5420a265a445ff9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2357,20 +2308,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.79"
+version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.79"
+version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2380,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2468,7 +2416,7 @@ version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2529,8 +2477,8 @@ dependencies = [
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-std 0.1.0",
@@ -2563,8 +2511,8 @@ version = "0.1.0"
 dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
 ]
@@ -2576,8 +2524,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2594,8 +2542,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2612,8 +2560,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2631,8 +2579,8 @@ dependencies = [
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-sandbox 0.1.0",
@@ -2652,8 +2600,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2672,8 +2620,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2690,8 +2638,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2708,8 +2656,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2727,8 +2675,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2747,8 +2695,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2771,8 +2719,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2787,8 +2735,8 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2803,8 +2751,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2821,8 +2769,8 @@ dependencies = [
  "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-std 0.1.0",
@@ -2832,6 +2780,24 @@ dependencies = [
  "substrate-primitives 0.1.0",
 ]
 
+[[package]]
+name = "srml-upgrade-key"
+version = "0.1.0"
+dependencies = [
+ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0",
+ "sr-primitives 0.1.0",
+ "sr-std 0.1.0",
+ "srml-consensus 0.1.0",
+ "srml-support 0.1.0",
+ "srml-system 0.1.0",
+ "substrate-primitives 0.1.0",
+]
+
 [[package]]
 name = "stable_deref_trait"
 version = "1.1.1"
@@ -2877,7 +2843,7 @@ dependencies = [
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "node-cli 0.1.0",
- "vergen 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vergen 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2929,7 +2895,7 @@ dependencies = [
  "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-api 0.1.0",
  "sr-primitives 0.1.0",
- "substrate-consensus-rhd 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-executor 0.1.0",
  "substrate-keyring 0.1.0",
  "substrate-primitives 0.1.0",
@@ -2962,12 +2928,44 @@ dependencies = [
  "substrate-trie 0.4.0",
 ]
 
+[[package]]
+name = "substrate-consensus-aura"
+version = "0.1.0"
+dependencies = [
+ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0",
+ "sr-primitives 0.1.0",
+ "sr-version 0.1.0",
+ "srml-consensus 0.1.0",
+ "srml-support 0.1.0",
+ "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
+ "substrate-executor 0.1.0",
+ "substrate-keyring 0.1.0",
+ "substrate-network 0.1.0",
+ "substrate-primitives 0.1.0",
+ "substrate-service 0.3.0",
+ "substrate-test-client 0.1.0",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "substrate-consensus-common"
 version = "0.1.0"
 dependencies = [
+ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
+ "sr-version 0.1.0",
  "substrate-primitives 0.1.0",
+ "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2975,21 +2973,25 @@ name = "substrate-consensus-rhd"
 version = "0.1.0"
 dependencies = [
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "parity-codec 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rhododendron 0.4.0 (git+https://github.com/paritytech/rhododendron.git)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rhododendron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "sr-version 0.1.0",
  "srml-consensus 0.1.0",
  "srml-support 0.1.0",
+ "srml-system 0.1.0",
+ "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-executor 0.1.0",
  "substrate-keyring 0.1.0",
  "substrate-primitives 0.1.0",
+ "substrate-transaction-pool 0.1.0",
  "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3005,8 +3007,8 @@ dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-version 0.1.0",
  "substrate-primitives 0.1.0",
@@ -3053,8 +3055,8 @@ dependencies = [
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "substrate-primitives 0.1.0",
  "subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3067,8 +3069,8 @@ version = "0.1.0"
 dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3088,6 +3090,7 @@ dependencies = [
  "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-keyring 0.1.0",
  "substrate-network-libp2p 0.1.0",
  "substrate-primitives 0.1.0",
@@ -3110,8 +3113,8 @@ dependencies = [
  "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3137,8 +3140,8 @@ dependencies = [
  "pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-std 0.1.0",
  "substrate-serializer 0.1.0",
  "twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3164,6 +3167,7 @@ dependencies = [
  "sr-primitives 0.1.0",
  "sr-version 0.1.0",
  "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-executor 0.1.0",
  "substrate-primitives 0.1.0",
  "substrate-test-client 0.1.0",
@@ -3179,7 +3183,7 @@ dependencies = [
  "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "substrate-rpc 0.1.0",
 ]
@@ -3188,7 +3192,7 @@ dependencies = [
 name = "substrate-serializer"
 version = "0.1.0"
 dependencies = [
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3203,14 +3207,15 @@ dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
  "substrate-client 0.1.0",
  "substrate-client-db 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-executor 0.1.0",
  "substrate-keystore 0.1.0",
  "substrate-network 0.1.0",
@@ -3233,6 +3238,7 @@ dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-network 0.1.0",
  "substrate-primitives 0.1.0",
  "substrate-service 0.3.0",
@@ -3289,6 +3295,7 @@ dependencies = [
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "substrate-client 0.1.0",
+ "substrate-consensus-common 0.1.0",
  "substrate-executor 0.1.0",
  "substrate-keyring 0.1.0",
  "substrate-primitives 0.1.0",
@@ -3303,8 +3310,8 @@ dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-api 0.1.0",
  "sr-io 0.1.0",
  "sr-primitives 0.1.0",
@@ -3324,8 +3331,8 @@ dependencies = [
  "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "sr-primitives 0.1.0",
  "substrate-test-runtime 0.1.0",
 ]
@@ -3391,7 +3398,7 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "0.15.9"
+version = "0.15.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3916,7 +3923,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "vergen"
-version = "2.1.2"
+version = "2.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3940,8 +3947,8 @@ name = "wabt"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "wabt-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -4070,7 +4077,7 @@ dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.10.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4163,7 +4170,7 @@ dependencies = [
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
 "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
-"checksum ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50ac3add446ec1f8fe3dc007cd838f5b22bbf33186394feac505451ecc43c018"
+"checksum ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4b669fcb8e20124db86dbd9b01e74ec0e9e420e65381311ce5249864fc7ff0c0"
 "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e"
 "checksum datastore 0.1.0 (git+https://github.com/tomaka/libp2p-rs?rev=8111062f0177fd7423626f2db9560273644a4c4d)" = "<none>"
 "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
@@ -4197,7 +4204,7 @@ dependencies = [
 "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
 "checksum getset 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54c7f36a235738bb25904d6a2b3dbb28f6f5736cd3918c4bf80d6bb236200782"
 "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865"
-"checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
+"checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed"
 "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "<none>"
 "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "<none>"
 "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
@@ -4208,7 +4215,7 @@ dependencies = [
 "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
-"checksum hyper 0.12.11 (registry+https://github.com/rust-lang/crates.io-index)" = "78d50abbd1790e0f4c74cb1d4a2211b439bac661d54107ad5564c55e77906762"
+"checksum hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca412c241a2dd53af261efc7adf7736fdebd67dc0d1cc1ffdbcb9407e0e810"
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
 "checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
 "checksum integer-sqrt 0.1.0 (git+https://github.com/paritytech/integer-sqrt-rs.git)" = "<none>"
@@ -4286,12 +4293,11 @@ dependencies = [
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
 "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7"
-"checksum openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5af9e83eb3c51ee806387d26a43056f3246d865844caa6dd704d2ba7e831c264"
+"checksum openssl 0.10.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6285ab297861546af7a2753593b3160bfc09f0ab9d1f5bb009e39d81a169b499"
 "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
-"checksum openssl-sys 0.9.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d4edbc8dfa63f557aee3a498179af2cc6a989e12ba1751840046c79afc9e615a"
+"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c"
-"checksum parity-codec 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bee4edfcfa19892f7178cb299a659866015dc131459865a1d808269cf7e7eb9e"
 "checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c"
 "checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189"
 "checksum parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1117f6574377d21309bfa1f7d69ff734120685d92b02c3f362b122585758840"
@@ -4334,8 +4340,7 @@ dependencies = [
 "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
 "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
 "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
-"checksum rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e20523445e693f394c0e487113ae656071311c9ee4c1e914441bece8c929b21d"
-"checksum rhododendron 0.4.0 (git+https://github.com/paritytech/rhododendron.git)" = "<none>"
+"checksum rhododendron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a09bc21b21795c366c8bf0e87afb71175f5f736b3a5b279b6f4e81839d0a877b"
 "checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c"
 "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
 "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
@@ -4354,8 +4359,8 @@ dependencies = [
 "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
-"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
+"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
+"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c"
 "checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
 "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
 "checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e"
@@ -4380,7 +4385,7 @@ dependencies = [
 "checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb"
 "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b"
 "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
-"checksum syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b10ee269228fb723234fce98e9aac0eaed2bd5f1ad2f6930e8d5b93f04445a1a"
+"checksum syn 0.15.12 (registry+https://github.com/rust-lang/crates.io-index)" = "34ab9797e47d24cb76b8dc4d24ff36807018c7cc549c4cba050b068be0c586b0"
 "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
 "checksum sysinfo 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5f6e8a7a7146f26ffed9a5ff8bab2706f1ac8a413a415e1d211b819d5c24d"
 "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
@@ -4437,7 +4442,7 @@ dependencies = [
 "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
 "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
 "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
-"checksum vergen 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4cae5a72131fdf47d4fbc9286393ec8622ec7a5502fbe77b291d9aba21d3f179"
+"checksum vergen 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "93fb2d57fbc535fcd45548c99b141d2d960995daaf04b864c4d9fe1ea011c819"
 "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum wabt 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "182ae543249ccf2705f324d233891c1176fca142e137b55ba43d9dbfe93f18a2"
diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml
index f47fa42507b6235472859a6ef4ed284f18e0d820..54ae7d9d82355cd57ee0b61404a3c6c8a32a6329 100644
--- a/substrate/Cargo.toml
+++ b/substrate/Cargo.toml
@@ -23,6 +23,7 @@ members = [
 	"core/client",
 	"core/client/db",
 	"core/consensus/common",
+	"core/consensus/aura",
 	"core/consensus/rhd",
 	"core/executor",
 	"core/finality-grandpa",
@@ -54,6 +55,7 @@ members = [
 	"srml/system",
 	"srml/timestamp",
 	"srml/treasury",
+	"srml/upgrade-key",
 	"core/serializer",
 	"core/service",
 	"core/service/test",
@@ -64,9 +66,7 @@ members = [
 	"core/trie",
 	"core/keystore",
 	"node/cli",
-	"node/consensus",
 	"node/executor",
-	"node/network",
 	"node/primitives",
 	"node/runtime",
 	"subkey",
diff --git a/substrate/README.adoc b/substrate/README.adoc
index f0aa15c4f9317208c04301869c2987f3ce7aef9b..11fdd616b239235fb77b392bd493f9ce36b68f36 100644
--- a/substrate/README.adoc
+++ b/substrate/README.adoc
@@ -221,11 +221,112 @@ cargo run
 
 include::doc/packages/packages.adoc[]
 
-include::CONTRIBUTING.adoc[leveloffset=+1]
+== Documentation
 
-include::CODE_OF_CONDUCT.adoc[leveloffset=+1]
+=== Viewing documentation for Substrate packages
+
+You can generate documentation for a Substrate Rust package and have it automatically open in your web browser using https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html#using-rustdoc-with-cargo[rustdoc with Cargo],
+(of the The Rustdoc Book), by running the the following command:
+
+```
+cargo doc --package <spec> --open
+```
+
+Replacing `<spec>` with one of the following (i.e. `cargo doc --package node-cli --open`):
+
+* Substrate Core
+[source, shell]
+substrate, substrate-bft, substrate-cli, substrate-client, substrate-client-db,
+substrate-executor, substrate-finality-grandpa, substrate-keyring, substrate-keystore,
+substrate-metadata, substrate-misbehavior-check, substrate-network,
+substrate-network-libp2p, substrate-primitives, substrate-rpc, substrate-rpc-servers,
+substrate-serializer, substrate-service, substrate-service-test, substrate-state-db,
+substrate-state-machine, substrate-telemetry, substrate-test-client,
+substrate-test-runtime, substrate-transaction-graph, substrate-transaction-pool,
+substrate-trie
+* Substrate Runtime
+[source, shell]
+sr-api, sr-io, sr-primitives, sr-sandbox, sr-std, sr-version
+* Substrate Runtime Module Library (SRML)
+[source, shell]
+srml-balances, srml-consensus, srml-contract, srml-council, srml-democracy, srml-example,
+srml-executive, srml-session, srml-staking, srml-support, srml-system, srml-timestamp,
+srml-treasury
+* Node
+[source, shell]
+node-cli, node-consensus, node-executor, node-network, node-primitives, node-runtime, node-service
+* Subkey
+[source, shell]
+subkey
+
+
+=== Contributing to documentation for Substrate packages
+
+https://doc.rust-lang.org/1.9.0/book/documentation.html[Document source code] for Substrate packages by annotating the source code with documentation comments.
+
+Example (generic):
+```markdown
+/// Summary
+///
+/// Description
+///
+/// # Panics
+///
+/// # Errors
+///
+/// # Safety
+///
+/// # Examples
+///
+/// Summary of Example 1
+///
+/// ```rust
+/// // insert example 1 code here
+/// ```
+/// 
+```
+
+* Important notes:
+** Documentation comments must use annotations with a triple slash `///`
+** Modules are documented using `//!` 
+```
+//! Summary (of module)
+//!
+//! Description (of module)
+```
+* Special section header is indicated with a hash `#`. 
+** `Panics` section requires an explanation if the function triggers a panic
+** `Errors` section is for describing conditions under which a function of method returns `Err(E)` if it returns a `Result<T, E>`
+** `Safety` section requires an explanation if the function is `unsafe`
+** `Examples` section includes examples of using the function or method
+* Code block annotations for examples are included between triple graves, as shown above.
+Instead of including the programming language to use for syntax highlighting as the annotation
+after the triple graves, alternative annotations include the `ignore`, `text`, `should_panic`, or `no_run`.
+* Summary sentence is a short high level sinngle sentence of its functionality
+* Description paragraph is for details additional to the summary sentence
+* Missing documentation annotations may be used to identify where to generate warnings with `#![warn(missing_docs)]`
+or errors `#![deny(missing_docs)]`
+* Hide documentation for items with `#[doc(hidden)]`
+
+=== Contributing to documentation (tests, extended examples, macros) for Substrate packages
+
+The code block annotations in the `# Example` section may be used as https://doc.rust-lang.org/1.9.0/book/documentation.html#documentation-as-tests[documentation as tests and for extended examples].
+
+* Important notes:
+** Rustdoc will automatically add a `main()` wrapper around the code block to test it
+** https://doc.rust-lang.org/1.9.0/book/documentation.html#documenting-macros[Documentating macros].
+** Documentation as tests examples are included when running `cargo test`
+
+== Contributing
+
+=== Contributing Guidelines
+
+include::CONTRIBUTING.adoc[]
+
+=== Contributor Code of Conduct
+
+include::CODE_OF_CONDUCT.adoc[]
 
 == License
-----
-include::LICENSE[]
-----
+
+https://github.com/paritytech/substrate/blob/master/LICENSE[LICENSE]
diff --git a/substrate/core/client/Cargo.toml b/substrate/core/client/Cargo.toml
index ba457fbb9cbc01db618e1f4caee80cadb187f08b..5eeb75940d4b188270921d440bd5469624ebf86b 100644
--- a/substrate/core/client/Cargo.toml
+++ b/substrate/core/client/Cargo.toml
@@ -12,7 +12,7 @@ hex-literal = "0.1"
 futures = "0.1.17"
 slog = "^2"
 heapsize = "0.4"
-substrate-consensus-rhd = { path = "../consensus/rhd" }
+substrate-consensus-common = { path = "../consensus/common" }
 parity-codec = "2.1"
 substrate-executor = { path = "../executor" }
 substrate-primitives = { path = "../primitives" }
diff --git a/substrate/core/transaction-pool/src/README.adoc b/substrate/core/client/db/README.adoc
similarity index 87%
rename from substrate/core/transaction-pool/src/README.adoc
rename to substrate/core/client/db/README.adoc
index 48052d0fde96f171d25fcf8ddb849f4297b690eb..c0b123392c81687523fc582182c6278ebf085a53 100644
--- a/substrate/core/transaction-pool/src/README.adoc
+++ b/substrate/core/client/db/README.adoc
@@ -1,5 +1,5 @@
 
-= transaction-pool
+= Client DB
 
 .Summary
 [source, toml]
diff --git a/substrate/core/client/db/src/lib.rs b/substrate/core/client/db/src/lib.rs
index f35dd8a05da1d80eb94c28360d31323e6cdac2ee..36ab5f4b2a58c0748ab57a30c2340ca437b3a9b9 100644
--- a/substrate/core/client/db/src/lib.rs
+++ b/substrate/core/client/db/src/lib.rs
@@ -534,7 +534,9 @@ impl<Block: BlockT> Backend<Block> {
 						meta.finalized_hash, f_hash),
 				).into())
 			}
-			transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, f_hash.as_ref());
+
+			let lookup_key = ::utils::number_to_lookup_key(f_num);
+			transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key);
 
 			let commit = self.storage.state_db.canonicalize_block(&f_hash);
 			apply_state_commit(transaction, commit);
@@ -586,11 +588,20 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
 		-> Result<(), client::error::Error>
 	{
 		let mut transaction = DBTransaction::new();
+
 		if let Some(pending_block) = operation.pending_block {
 			let hash = pending_block.header.hash();
 			let parent_hash = *pending_block.header.parent_hash();
 			let number = pending_block.header.number().clone();
 
+			// blocks in longest chain are keyed by number
+			let lookup_key = if pending_block.leaf_state.is_best() {
+				::utils::number_to_lookup_key(number).to_vec()
+			} else {
+				// other blocks are keyed by number + hash
+				::utils::number_and_hash_to_lookup_key(number, hash)
+			};
+
 			if pending_block.leaf_state.is_best() {
 				let meta = self.blockchain.meta.read();
 
@@ -678,17 +689,9 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
 					}
 				}
 
-				transaction.put(columns::META, meta_keys::BEST_BLOCK, hash.as_ref());
+				transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key);
 			}
 
-			// blocks in longest chain are keyed by number
-			let lookup_key = if pending_block.leaf_state.is_best() {
-				::utils::number_to_lookup_key(number).to_vec()
-			} else {
-			// other blocks are keyed by number + hash
-				::utils::number_and_hash_to_lookup_key(number, hash)
-			};
-
 			transaction.put(columns::HEADER, &lookup_key, &pending_block.header.encode());
 			if let Some(body) = pending_block.body {
 				transaction.put(columns::BODY, &lookup_key, &body.encode());
@@ -700,7 +703,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
 			transaction.put(columns::HASH_LOOKUP, hash.as_ref(), &lookup_key);
 
 			if number == Zero::zero() {
-				transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, hash.as_ref());
+				transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key);
 				transaction.put(columns::META, meta_keys::GENESIS_HASH, hash.as_ref());
 			}
 
@@ -797,7 +800,8 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
 						|| client::error::ErrorKind::UnknownBlock(
 							format!("Error reverting to {}. Block header not found.", best)))?;
 
-					transaction.put(columns::META, meta_keys::BEST_BLOCK, header.hash().as_ref());
+					let lookup_key = ::utils::number_to_lookup_key(header.number().clone());
+					transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key);
 					transaction.delete(columns::HASH_LOOKUP, header.hash().as_ref());
 					self.storage.db.write(transaction).map_err(db_err)?;
 					self.blockchain.update_meta(header.hash().clone(), best.clone(), true, false);
@@ -927,40 +931,49 @@ mod tests {
 
 	#[test]
 	fn block_hash_inserted_correctly() {
-		let db = Backend::<Block>::new_test(1, 0);
-		for i in 0..10 {
-			assert!(db.blockchain().hash(i).unwrap().is_none());
-
-			{
-				let id = if i == 0 {
-					BlockId::Hash(Default::default())
-				} else {
-					BlockId::Number(i - 1)
-				};
-
-				let mut op = db.begin_operation(id).unwrap();
-				let header = Header {
-					number: i,
-					parent_hash: if i == 0 {
-						Default::default()
+		let backing = {
+			let db = Backend::<Block>::new_test(1, 0);
+			for i in 0..10 {
+				assert!(db.blockchain().hash(i).unwrap().is_none());
+
+				{
+					let id = if i == 0 {
+						BlockId::Hash(Default::default())
 					} else {
-						db.blockchain.hash(i - 1).unwrap().unwrap()
-					},
-					state_root: Default::default(),
-					digest: Default::default(),
-					extrinsics_root: Default::default(),
-				};
-
-				op.set_block_data(
-					header,
-					Some(vec![]),
-					None,
-					NewBlockState::Best,
-				).unwrap();
-				db.commit_operation(op).unwrap();
+						BlockId::Number(i - 1)
+					};
+
+					let mut op = db.begin_operation(id).unwrap();
+					let header = Header {
+						number: i,
+						parent_hash: if i == 0 {
+							Default::default()
+						} else {
+							db.blockchain.hash(i - 1).unwrap().unwrap()
+						},
+						state_root: Default::default(),
+						digest: Default::default(),
+						extrinsics_root: Default::default(),
+					};
+
+					op.set_block_data(
+						header,
+						Some(vec![]),
+						None,
+						NewBlockState::Best,
+					).unwrap();
+					db.commit_operation(op).unwrap();
+				}
+
+				assert!(db.blockchain().hash(i).unwrap().is_some())
 			}
+			db.storage.db.clone()
+		};
 
-			assert!(db.blockchain().hash(i).unwrap().is_some())
+		let backend = Backend::<Block>::from_kvdb(backing, PruningMode::keep_blocks(1), 0).unwrap();
+		assert_eq!(backend.blockchain().info().unwrap().best_number, 9);
+		for i in 0..10 {
+			assert!(backend.blockchain().hash(i).unwrap().is_some())
 		}
 	}
 
diff --git a/substrate/core/client/db/src/light.rs b/substrate/core/client/db/src/light.rs
index 49e5e85be1bf51406597796033df129c6d1ebc73..f336df4d28effc231b3cf37504c71a13f8b7a250 100644
--- a/substrate/core/client/db/src/light.rs
+++ b/substrate/core/client/db/src/light.rs
@@ -196,7 +196,8 @@ impl<Block: BlockT> LightStorage<Block> {
 			).into())
 		}
 
-		transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, hash.as_ref());
+		let lookup_key = ::utils::number_to_lookup_key(header.number().clone());
+		transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key);
 
 		// build new CHT if required
 		if let Some(new_cht_number) = cht::is_build_required(cht::SIZE, *header.number()) {
@@ -244,6 +245,14 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
 		let number = *header.number();
 		let parent_hash = *header.parent_hash();
 
+		// blocks in longest chain are keyed by number
+		let lookup_key = if leaf_state.is_best() {
+			::utils::number_to_lookup_key(number).to_vec()
+		} else {
+		// other blocks are keyed by number + hash
+			::utils::number_and_hash_to_lookup_key(number, hash)
+		};
+
 		if leaf_state.is_best() {
 			// handle reorg.
 			{
@@ -298,17 +307,9 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
 				}
 			}
 
-			transaction.put(columns::META, meta_keys::BEST_BLOCK, hash.as_ref());
+			transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key);
 		}
 
-		// blocks in longest chain are keyed by number
-		let lookup_key = if leaf_state.is_best() {
-			::utils::number_to_lookup_key(number).to_vec()
-		} else {
-		// other blocks are keyed by number + hash
-			::utils::number_and_hash_to_lookup_key(number, hash)
-		};
-
 		transaction.put(columns::HEADER, &lookup_key, &header.encode());
 		transaction.put(columns::HASH_LOOKUP, hash.as_ref(), &lookup_key);
 
diff --git a/substrate/core/client/db/src/utils.rs b/substrate/core/client/db/src/utils.rs
index b32b56bccc8593997b8cd6fba95bdfac0b3ba0ca..f7b81845e8e7ca93edb184722a74942147e0f6a2 100644
--- a/substrate/core/client/db/src/utils.rs
+++ b/substrate/core/client/db/src/utils.rs
@@ -53,6 +53,7 @@ pub mod meta_keys {
 }
 
 /// Database metadata.
+#[derive(Debug)]
 pub struct Meta<N, H> {
 	/// Hash of the best known block.
 	pub best_hash: H,
diff --git a/substrate/core/client/src/call_executor.rs b/substrate/core/client/src/call_executor.rs
index 2b442a35695847e2092da832e420bbf4b0a4880d..168d0a26c5fc0040f8f2b50b5fb34466cddae3ea 100644
--- a/substrate/core/client/src/call_executor.rs
+++ b/substrate/core/client/src/call_executor.rs
@@ -150,7 +150,7 @@ where
 		let heap_pages = state.storage(well_known_keys::HEAP_PAGES)
 			.map_err(|e| error::ErrorKind::Execution(Box::new(e)))?
 			.and_then(|v| u64::decode(&mut &v[..]))
-			.unwrap_or(8) as usize;
+			.unwrap_or(1024) as usize;
 
 		let mut ext = Ext::new(&mut overlay, &state, self.backend.changes_trie_storage());
 		self.executor.runtime_version(&mut ext, heap_pages, &code)
diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs
index 2567e43a951a1db63aa02ab8f24eb287299fbed9..a82b2133f0e10354e3e4e21e566b00a31bc03c1f 100644
--- a/substrate/core/client/src/client.rs
+++ b/substrate/core/client/src/client.rs
@@ -26,6 +26,7 @@ use runtime_primitives::{
 	generic::{BlockId, SignedBlock, Block as RuntimeBlock},
 	transaction_validity::{TransactionValidity, TransactionTag},
 };
+use consensus::{ImportBlock, ImportResult, BlockOrigin};
 use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash};
 use runtime_primitives::{ApplyResult, BuildStorage};
 use runtime_api as api;
@@ -44,7 +45,7 @@ use blockchain::{self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend
 use call_executor::{CallExecutor, LocalCallExecutor};
 use executor::{RuntimeVersion, RuntimeInfo};
 use notifications::{StorageNotifications, StorageEventStream};
-use {cht, error, in_mem, block_builder, genesis};
+use {cht, error, in_mem, block_builder, genesis, consensus};
 
 /// Type that implements `futures::Stream` of block import events.
 pub type ImportNotifications<Block> = mpsc::UnboundedReceiver<BlockImportNotification<Block>>;
@@ -106,21 +107,6 @@ pub struct ClientInfo<Block: BlockT> {
 	pub best_queued_hash: Option<Block::Hash>,
 }
 
-/// Block import result.
-#[derive(Debug)]
-pub enum ImportResult {
-	/// Added to the import queue.
-	Queued,
-	/// Already in the import queue.
-	AlreadyQueued,
-	/// Already in the blockchain.
-	AlreadyInChain,
-	/// Block or parent is known to be bad.
-	KnownBad,
-	/// Block parent is not in the chain.
-	UnknownParent,
-}
-
 /// Block status.
 #[derive(Debug, PartialEq, Eq)]
 pub enum BlockStatus {
@@ -134,70 +120,6 @@ pub enum BlockStatus {
 	Unknown,
 }
 
-/// Block data origin.
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum BlockOrigin {
-	/// Genesis block built into the client.
-	Genesis,
-	/// Block is part of the initial sync with the network.
-	NetworkInitialSync,
-	/// Block was broadcasted on the network.
-	NetworkBroadcast,
-	/// Block that was received from the network and validated in the consensus process.
-	ConsensusBroadcast,
-	/// Block that was collated by this node.
-	Own,
-	/// Block was imported from a file.
-	File,
-}
-
-/// Data required to import a Block
-pub struct ImportBlock<Block: BlockT> {
-	/// Origin of the Block
-	pub origin: BlockOrigin,
-	/// Header
-	pub header: Block::Header,
-	/// Justification provided for this block from the outside
-	pub external_justification: Justification,
-	/// Internal Justification for the block
-	pub internal_justification: Vec<u8>, // Block::Digest::DigestItem?
-	/// Block's body
-	pub body: Option<Vec<Block::Extrinsic>>,
-	/// Is this block finalized already?
-	/// `true` implies instant finality.
-	pub finalized: bool,
-	/// Auxiliary consensus data produced by the block.
-	/// Contains a list of key-value pairs. If values are `None`, the keys
-	/// will be deleted.
-	pub auxiliary: Vec<(Vec<u8>, Option<Vec<u8>>)>,
-}
-
-impl<Block: BlockT> ImportBlock<Block> {
-	/// Deconstruct the justified header into parts.
-	pub fn into_inner(self)
-		-> (
-			BlockOrigin,
-			<Block as BlockT>::Header,
-			Justification,
-			Justification,
-			Option<Vec<<Block as BlockT>::Extrinsic>>,
-			bool,
-			Vec<(Vec<u8>, Option<Vec<u8>>)>,
-		) {
-		(
-			self.origin,
-			self.header,
-			self.external_justification,
-			self.internal_justification,
-			self.body,
-			self.finalized,
-			self.auxiliary,
-		)
-	}
-}
-
-
-
 /// Summary of an imported block
 #[derive(Clone, Debug)]
 pub struct BlockImportNotification<Block: BlockT> {
@@ -222,6 +144,41 @@ pub struct FinalityNotification<Block: BlockT> {
 	pub header: Block::Header,
 }
 
+// used in importing a block, where additional changes are made after the runtime
+// executed.
+enum PrePostHeader<H> {
+	// they are the same: no post-runtime digest items.
+	Same(H),
+	// different headers (pre, post).
+	Different(H, H),
+}
+
+impl<H> PrePostHeader<H> {
+	// get a reference to the "pre-header" -- the header as it should be just after the runtime.
+	fn pre(&self) -> &H {
+		match *self {
+			PrePostHeader::Same(ref h) => h,
+			PrePostHeader::Different(ref h, _) => h,
+		}
+	}
+
+	// get a reference to the "post-header" -- the header as it should be after all changes are applied.
+	fn post(&self) -> &H {
+		match *self {
+			PrePostHeader::Same(ref h) => h,
+			PrePostHeader::Different(_, ref h) => h,
+		}
+	}
+
+	// convert to the "post-header" -- the header as it should be after all changes are applied.
+	fn into_post(self) -> H {
+		match self {
+			PrePostHeader::Same(h) => h,
+			PrePostHeader::Different(_, h) => h,
+		}
+	}
+}
+
 /// Create an instance of in-memory client.
 pub fn new_in_mem<E, Block, S>(
 	executor: E,
@@ -346,11 +303,6 @@ impl<B, E, Block> Client<B, E, Block> where
 		&self.executor
 	}
 
-	/// Returns the runtime metadata.
-	pub fn metadata(&self, id: &BlockId<Block>) -> error::Result<Vec<u8>> {
-		self.executor.call(id, "metadata",&[]).map(|v| v.return_data)
-	}
-
 	/// Reads storage value at a given block + key, returning read proof.
 	pub fn read_proof(&self, id: &BlockId<Block>, key: &[u8]) -> error::Result<Vec<Vec<u8>>> {
 		self.state_at(id)
@@ -518,52 +470,6 @@ impl<B, E, Block> Client<B, E, Block> where
 		)
 	}
 
-	/// Import a checked and validated block
-	pub fn import_block(
-		&self,
-		import_block: ImportBlock<Block>,
-		new_authorities: Option<Vec<AuthorityId>>,
-	) -> error::Result<ImportResult> {
-
-		let (
-			origin,
-			header,
-			_,
-			justification,
-			body,
-			finalized,
-			_aux, // TODO: write this to DB also
-		) = import_block.into_inner();
-		let parent_hash = header.parent_hash().clone();
-
-		match self.backend.blockchain().status(BlockId::Hash(parent_hash))? {
-			blockchain::BlockStatus::InChain => {},
-			blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent),
-		}
-		let hash = header.hash();
-		let _import_lock = self.import_lock.lock();
-		let height: u64 = header.number().as_();
-		*self.importing_block.write() = Some(hash);
-
-		let result = self.execute_and_import_block(
-			origin,
-			hash,
-			header,
-			justification,
-			body,
-			new_authorities,
-			finalized,
-		);
-
-		*self.importing_block.write() = None;
-		telemetry!("block.import";
-			"height" => height,
-			"best" => ?hash,
-			"origin" => ?origin
-		);
-		result
-	}
-
 	// TODO [ToDr] Optimize and re-use tags from the pool.
 	fn transaction_tags(&self, at: Block::Hash, body: &Option<Vec<Block::Extrinsic>>) -> error::Result<Vec<TransactionTag>> {
 		let id = BlockId::Hash(at);
@@ -592,13 +498,13 @@ impl<B, E, Block> Client<B, E, Block> where
 		&self,
 		origin: BlockOrigin,
 		hash: Block::Hash,
-		header: Block::Header,
+		import_headers: PrePostHeader<Block::Header>,
 		justification: Justification,
 		body: Option<Vec<Block::Extrinsic>>,
 		authorities: Option<Vec<AuthorityId>>,
 		finalized: bool,
 	) -> error::Result<ImportResult> {
-		let parent_hash = header.parent_hash().clone();
+		let parent_hash = import_headers.post().parent_hash().clone();
 		match self.backend.blockchain().status(BlockId::Hash(hash))? {
 			blockchain::BlockStatus::InChain => return Ok(ImportResult::AlreadyInChain),
 			blockchain::BlockStatus::Unknown => {},
@@ -632,12 +538,13 @@ impl<B, E, Block> Client<B, E, Block> where
 					transaction_state,
 					&mut overlay,
 					"execute_block",
-					&<Block as BlockT>::new(header.clone(), body.clone().unwrap_or_default()).encode(),
+					&<Block as BlockT>::new(import_headers.pre().clone(), body.clone().unwrap_or_default()).encode(),
 					match (origin, self.block_execution_strategy) {
 						(BlockOrigin::NetworkInitialSync, _) | (_, ExecutionStrategy::NativeWhenPossible) =>
 							ExecutionManager::NativeWhenPossible,
 						(_, ExecutionStrategy::AlwaysWasm) => ExecutionManager::AlwaysWasm,
 						_ => ExecutionManager::Both(|wasm_result, native_result| {
+							let header = import_headers.post();
 							warn!("Consensus error between wasm and native block execution at block {}", hash);
 							warn!("   Header {:?}", header);
 							warn!("   Native result {:?}", native_result);
@@ -659,7 +566,7 @@ impl<B, E, Block> Client<B, E, Block> where
 		};
 
 		// TODO: non longest-chain rule.
-		let is_new_best = finalized || header.number() > &last_best_number;
+		let is_new_best = finalized || import_headers.post().number() > &last_best_number;
 		let leaf_state = if finalized {
 			::backend::NewBlockState::Final
 		} else if is_new_best {
@@ -668,10 +575,10 @@ impl<B, E, Block> Client<B, E, Block> where
 			::backend::NewBlockState::Normal
 		};
 
-		trace!("Imported {}, (#{}), best={}, origin={:?}", hash, header.number(), is_new_best, origin);
+		trace!("Imported {}, (#{}), best={}, origin={:?}", hash, import_headers.post().number(), is_new_best, origin);
 
 		transaction.set_block_data(
-			header.clone(),
+			import_headers.post().clone(),
 			body,
 			Some(justification),
 			leaf_state,
@@ -698,7 +605,7 @@ impl<B, E, Block> Client<B, E, Block> where
 			if finalized {
 				let notification = FinalityNotification::<Block> {
 					hash,
-					header: header.clone(),
+					header: import_headers.post().clone(),
 				};
 
 				self.finality_notification_sinks.lock()
@@ -708,7 +615,7 @@ impl<B, E, Block> Client<B, E, Block> where
 			let notification = BlockImportNotification::<Block> {
 				hash,
 				origin,
-				header,
+				header: import_headers.into_post(),
 				is_new_best,
 				tags,
 			};
@@ -986,6 +893,84 @@ impl<B, E, Block> Client<B, E, Block> where
 	}
 }
 
+
+impl<B, E, Block> consensus::BlockImport<Block> for Client<B, E, Block> where
+	B: backend::Backend<Block, Blake2Hasher>,
+	E: CallExecutor<Block, Blake2Hasher> + Clone,
+	Block: BlockT,
+{
+	type Error = Error;
+
+	/// Import a checked and validated block
+	fn import_block(
+		&self,
+		import_block: ImportBlock<Block>,
+		new_authorities: Option<Vec<AuthorityId>>,
+	) -> Result<ImportResult, Self::Error> {
+		use runtime_primitives::traits::Digest;
+
+		let ImportBlock {
+			origin,
+			header,
+			external_justification,
+			post_runtime_digests,
+			body,
+			finalized,
+			..
+		} = import_block;
+		let parent_hash = header.parent_hash().clone();
+
+		match self.backend.blockchain().status(BlockId::Hash(parent_hash))? {
+			blockchain::BlockStatus::InChain => {},
+			blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent),
+		}
+
+		let import_headers = if post_runtime_digests.is_empty() {
+			PrePostHeader::Same(header)
+		} else {
+			let mut post_header = header.clone();
+			for item in post_runtime_digests {
+				post_header.digest_mut().push(item);
+			}
+			PrePostHeader::Different(header, post_header)
+		};
+
+		let hash = import_headers.post().hash();
+		let _import_lock = self.import_lock.lock();
+		let height: u64 = import_headers.post().number().as_();
+		*self.importing_block.write() = Some(hash);
+
+		let result = self.execute_and_import_block(
+			origin,
+			hash,
+			import_headers,
+			external_justification,
+			body,
+			new_authorities,
+			finalized,
+		);
+
+		*self.importing_block.write() = None;
+		telemetry!("block.import";
+			"height" => height,
+			"best" => ?hash,
+			"origin" => ?origin
+		);
+		result.map_err(|e| e.into())
+	}
+}
+
+impl<B, E, Block> consensus::Authorities<Block> for Client<B, E, Block> where
+	B: backend::Backend<Block, Blake2Hasher>,
+	E: CallExecutor<Block, Blake2Hasher> + Clone,
+	Block: BlockT,
+{
+	type Error = Error;
+	fn authorities(&self, at: &BlockId<Block>) -> Result<Vec<AuthorityId>, Self::Error> {
+		self.authorities_at(at).map_err(|e| e.into())
+	}
+}
+
 impl<B, E, Block> CurrentHeight for Client<B, E, Block> where
 	B: backend::Backend<Block, Blake2Hasher>,
 	E: CallExecutor<Block, Blake2Hasher> + Clone,
@@ -1076,7 +1061,7 @@ impl<B, E, Block> api::Core<Block, AuthorityId> for Client<B, E, Block> where
 	}
 }
 
-impl<B, E, Block> api::Metadata<Block> for Client<B, E, Block> where
+impl<B, E, Block> api::Metadata<Block, Vec<u8>> for Client<B, E, Block> where
 	B: backend::Backend<Block, Blake2Hasher>,
 	E: CallExecutor<Block, Blake2Hasher>,
 	Block: BlockT,
@@ -1084,7 +1069,7 @@ impl<B, E, Block> api::Metadata<Block> for Client<B, E, Block> where
 	type Error = Error;
 
 	fn metadata(&self, at: &BlockId<Block>) -> Result<Vec<u8>, Self::Error> {
-		self.call_api_at(at, "metadata", &())
+		self.executor.call(at, "metadata",&[]).map(|v| v.return_data)
 	}
 }
 
@@ -1142,26 +1127,6 @@ impl<B, E, Block> api::BlockBuilder<Block> for Client<B, E, Block> where
 	}
 }
 
-impl<B, E, Block> api::OldTxQueue<Block> for Client<B, E, Block> where
-	B: backend::Backend<Block, Blake2Hasher>,
-	E: CallExecutor<Block, Blake2Hasher>,
-	Block: BlockT,
-{
-	type Error = Error;
-
-	fn account_nonce<AccountId: Encode + Decode, Index: Encode + Decode>(
-		&self, at: &BlockId<Block>, account: &AccountId
-	) -> Result<Index, Self::Error> {
-		self.call_api_at(at, "account_nonce", &(account))
-	}
-
-	fn lookup_address<Address: Encode + Decode, AccountId: Encode + Decode>(
-		&self, at: &BlockId<Block>, address: &Address
-	) -> Result<Option<AccountId>, Self::Error> {
-		self.call_api_at(at, "lookup_address", &(address))
-	}
-}
-
 impl<B, E, Block> api::TaggedTransactionQueue<Block> for Client<B, E, Block> where
 	B: backend::Backend<Block, Blake2Hasher>,
 	E: CallExecutor<Block, Blake2Hasher>,
@@ -1176,30 +1141,6 @@ impl<B, E, Block> api::TaggedTransactionQueue<Block> for Client<B, E, Block> whe
 	}
 }
 
-impl<B, E, Block> api::Miscellaneous<Block> for Client<B, E, Block> where
-	B: backend::Backend<Block, Blake2Hasher>,
-	E: CallExecutor<Block, Blake2Hasher>,
-	Block: BlockT,
-{
-	type Error = Error;
-
-	fn validator_count(&self, at: &BlockId<Block>) -> Result<u32, Self::Error> {
-		self.call_api_at(at, "validator_count", &())
-	}
-
-	fn validators<AccountId: Encode + Decode>(
-		&self, at: &BlockId<Block>
-	) -> Result<Vec<AccountId>, Self::Error> {
-		self.call_api_at(at, "validators", &())
-	}
-
-	fn timestamp<Moment: Encode + Decode>(
-		&self, at: &BlockId<Block>
-	) -> Result<Moment, Self::Error> {
-		self.call_api_at(at, "timestamp", &())
-	}
-}
-
 #[cfg(test)]
 pub(crate) mod tests {
 	use std::collections::HashMap;
@@ -1209,7 +1150,7 @@ pub(crate) mod tests {
 	use runtime_primitives::traits::{Digest as DigestT, DigestItem as DigestItemT};
 	use runtime_primitives::generic::DigestItem;
 	use test_client::{self, TestClient};
-	use test_client::client::BlockOrigin;
+	use consensus::BlockOrigin;
 	use test_client::client::backend::Backend as TestBackend;
 	use test_client::BlockBuilderExt;
 	use test_client::runtime::{self, Block, Transfer};
diff --git a/substrate/core/client/src/error.rs b/substrate/core/client/src/error.rs
index 5abc2617b2964d9e8c9ca1fcb4a5fae4b3db36e7..139cef13daba54de5c869d222ebc6159d4bbddfe 100644
--- a/substrate/core/client/src/error.rs
+++ b/substrate/core/client/src/error.rs
@@ -16,11 +16,17 @@
 
 //! Substrate client possible errors.
 
+#![allow(missing_docs)]
+
 use std;
 use state_machine;
 use runtime_primitives::ApplyError;
+use consensus;
 
 error_chain! {
+	links {
+		Consensus(consensus::Error, consensus::ErrorKind);
+	}
 	errors {
 		/// Backend error.
 		Backend(s: String) {
diff --git a/substrate/core/client/src/lib.rs b/substrate/core/client/src/lib.rs
index 9526091dadebd03352b21f3051f4ea6f5f84887c..a0332779052b48414607b0460af3eefb88ec2243 100644
--- a/substrate/core/client/src/lib.rs
+++ b/substrate/core/client/src/lib.rs
@@ -14,7 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
+// tag::description[]
 //! Substrate Client and associated logic.
+// end::description[]
 
 #![warn(missing_docs)]
 #![recursion_limit="128"]
@@ -24,6 +26,7 @@ extern crate parity_codec as codec;
 extern crate substrate_primitives as primitives;
 extern crate sr_primitives as runtime_primitives;
 extern crate substrate_state_machine as state_machine;
+extern crate substrate_consensus_common as consensus;
 #[cfg(test)] extern crate substrate_keyring as keyring;
 #[cfg(test)] extern crate substrate_test_client as test_client;
 #[macro_use] extern crate substrate_telemetry;
@@ -61,8 +64,8 @@ pub use call_executor::{CallResult, CallExecutor, LocalCallExecutor};
 pub use client::{
 	new_with_backend,
 	new_in_mem,
-	BlockBody, BlockStatus, BlockOrigin, ImportNotifications, FinalityNotifications, BlockchainEvents,
-	Client, ClientInfo, ChainHead, ImportResult, ImportBlock,
+	BlockBody, BlockStatus, ImportNotifications, FinalityNotifications, BlockchainEvents,
+	Client, ClientInfo, ChainHead,
 };
 pub use notifications::{StorageEventStream, StorageChangeSet};
 pub use state_machine::ExecutionStrategy;
diff --git a/substrate/core/client/src/light/fetcher.rs b/substrate/core/client/src/light/fetcher.rs
index 702c9b703458f84ca33b002be1d7e768a2c1995f..38a46c7d68dc6172af32d041e842bfaa1519c5e7 100644
--- a/substrate/core/client/src/light/fetcher.rs
+++ b/substrate/core/client/src/light/fetcher.rs
@@ -270,7 +270,8 @@ pub mod tests {
 	use error::Error as ClientError;
 	use test_client::{self, TestClient};
 	use test_client::runtime::{self, Hash, Block, Header};
-	use test_client::client::BlockOrigin;
+	use consensus::BlockOrigin;
+
 	use in_mem::{Blockchain as InMemoryBlockchain};
 	use light::fetcher::{Fetcher, FetchChecker, LightDataChecker,
 		RemoteCallRequest, RemoteHeaderRequest};
diff --git a/substrate/core/consensus/aura/Cargo.toml b/substrate/core/consensus/aura/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..0f403ab2ff65f59b9039e55fa42c5267d5cc3bfb
--- /dev/null
+++ b/substrate/core/consensus/aura/Cargo.toml
@@ -0,0 +1,42 @@
+[package]
+name = "substrate-consensus-aura"
+version = "0.1.0"
+authors = ["Parity Technologies <admin@parity.io>"]
+description = "Rhododendron Round-Based consensus-algorithm for substrate"
+
+[dependencies]
+futures = "0.1.17"
+parity-codec = { version = "2.1" }
+substrate-consensus-common = { path = "../common" }
+substrate-client = { path = "../../client" }
+substrate-primitives = { path = "../../primitives" }
+substrate-network = { path = "../../network" }
+srml-support = { path = "../../../srml/support" }
+sr-primitives = { path = "../../sr-primitives" }
+sr-version = { path = "../../sr-version" }
+sr-io = { path = "../../sr-io" }
+srml-consensus = { path = "../../../srml/consensus" }
+tokio = "0.1.7"
+parking_lot = "0.4"
+error-chain = "0.12"
+log = "0.3"
+
+[dev-dependencies]
+substrate-keyring = { path = "../../keyring" }
+substrate-executor = { path = "../../executor" }
+substrate-service = { path = "../../service" }
+substrate-test-client = { path = "../../test-client" }
+env_logger = { version = "0.4" }
+
+[target.'cfg(test)'.dependencies]
+substrate-network = { path = "../../network", features = ["test-helpers"] }
+
+[features]
+default = ["std"]
+std = [
+	"substrate-primitives/std",
+	"srml-support/std",
+	"sr-primitives/std",
+	"sr-version/std",
+]
+
diff --git a/substrate/core/consensus/aura/src/lib.rs b/substrate/core/consensus/aura/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7355119074eba88b7f51fc8cf24fb5ee90a026a7
--- /dev/null
+++ b/substrate/core/consensus/aura/src/lib.rs
@@ -0,0 +1,560 @@
+// Copyright 2018 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Aura (Authority-round) consensus in substrate.
+//!
+//! Aura works by having a list of authorities A who are expected to roughly
+//! agree on the current time. Time is divided up into discrete slots of t
+//! seconds each. For each slot s, the author of that slot is A[s % |A|].
+//!
+//! The author is allowed to issue one block but not more during that slot,
+//! and it will be built upon the longest valid chain that has been seen.
+//!
+//! Blocks from future steps will be either deferred or rejected depending on how
+//! far in the future they are.
+
+extern crate parity_codec as codec;
+extern crate substrate_consensus_common as consensus_common;
+extern crate substrate_client as client;
+extern crate substrate_primitives as primitives;
+extern crate substrate_network as network;
+extern crate srml_support as runtime_support;
+extern crate sr_primitives as runtime_primitives;
+extern crate sr_version as runtime_version;
+extern crate sr_io as runtime_io;
+extern crate tokio;
+
+#[cfg(test)]
+extern crate substrate_keyring as keyring;
+#[cfg(test)]
+extern crate substrate_service as service;
+#[cfg(test)]
+extern crate substrate_test_client as test_client;
+#[cfg(test)]
+extern crate env_logger;
+
+extern crate parking_lot;
+
+#[macro_use]
+extern crate log;
+
+extern crate futures;
+
+use std::sync::Arc;
+use std::time::{Duration, Instant};
+
+use codec::Encode;
+use consensus_common::{Authorities, BlockImport, Environment, Proposer};
+use client::ChainHead;
+use consensus_common::{ImportBlock, BlockOrigin};
+use runtime_primitives::{generic, generic::BlockId};
+use runtime_primitives::traits::{Block, Header, Digest, DigestItemFor};
+use network::import_queue::{Verifier, BasicQueue};
+use primitives::{AuthorityId, ed25519};
+
+use futures::{Stream, Future, IntoFuture, future::{self, Either}};
+use tokio::timer::Interval;
+
+pub use consensus_common::SyncOracle;
+
+/// A handle to the network. This is generally implemented by providing some
+/// handle to a gossip service or similar.
+///
+/// Intended to be a lightweight handle such as an `Arc`.
+pub trait Network: Clone {
+	/// A stream of input messages for a topic.
+	type In: Stream<Item=Vec<u8>,Error=()>;
+
+	/// Send a message at a specific round out.
+	fn send_message(&self, slot: u64, message: Vec<u8>);
+}
+
+/// Configuration for Aura consensus.
+#[derive(Clone)]
+pub struct Config {
+	/// The local authority keypair. Can be none if this is just an observer.
+	pub local_key: Option<Arc<ed25519::Pair>>,
+	/// The slot duration in seconds.
+	pub slot_duration: u64
+}
+
+/// Get slot author for given block along with authorities.
+fn slot_author(slot_num: u64, authorities: &[AuthorityId]) -> Option<AuthorityId> {
+	if authorities.is_empty() { return None }
+
+	let idx = slot_num % (authorities.len() as u64);
+	assert!(idx <= usize::max_value() as u64,
+		"It is impossible to have a vector with length beyond the address space; qed");
+
+	let current_author = *authorities.get(idx as usize)
+		.expect("authorities not empty; index constrained to list length;\
+				this is a valid index; qed");
+
+	Some(current_author)
+}
+
+fn duration_now() -> Option<Duration> {
+	use std::time::SystemTime;
+
+	let now = SystemTime::now();
+	now.duration_since(SystemTime::UNIX_EPOCH).map_err(|e| {
+			warn!("Current time {:?} is before unix epoch. Something is wrong: {:?}", now, e);
+	}).ok()
+}
+
+/// Get the slot for now.
+fn slot_now(slot_duration: u64) -> Option<u64> {
+	duration_now().map(|s| s.as_secs() / slot_duration)
+}
+
+/// A digest item which is usable with aura consensus.
+pub trait CompatibleDigestItem: Sized {
+	/// Construct a digest item which is a slot number and a signature on the
+	/// hash.
+	fn aura_seal(slot_number: u64, signature: ed25519::Signature) -> Self;
+
+	/// If this item is an Aura seal, return the slot number and signature.
+	fn as_aura_seal(&self) -> Option<(u64, &ed25519::Signature)>;
+}
+
+impl CompatibleDigestItem for generic::DigestItem<primitives::H256, u64> {
+	/// Construct a digest item which is a slot number and a signature on the
+	/// hash.
+	fn aura_seal(slot_number: u64, signature: ed25519::Signature) -> Self {
+		generic::DigestItem::Seal(slot_number, signature)
+	}
+	/// If this item is an Aura seal, return the slot number and signature.
+	fn as_aura_seal(&self) -> Option<(u64, &ed25519::Signature)> {
+		match self {
+			generic::DigestItem::Seal(slot, ref sign) => Some((*slot, sign)),
+			_ => None
+		}
+	}
+}
+
+impl CompatibleDigestItem for generic::DigestItem<primitives::H256, primitives::AuthorityId> {
+	/// Construct a digest item which is a slot number and a signature on the
+	/// hash.
+	fn aura_seal(slot_number: u64, signature: ed25519::Signature) -> Self {
+		generic::DigestItem::Seal(slot_number, signature)
+	}
+	/// If this item is an Aura seal, return the slot number and signature.
+	fn as_aura_seal(&self) -> Option<(u64, &ed25519::Signature)> {
+		match self {
+			generic::DigestItem::Seal(slot, ref sign) => Some((*slot, sign)),
+			_ => None
+		}
+	}
+}
+
+/// Start the aura worker. This should be run in a tokio runtime.
+pub fn start_aura<B, C, E, SO, Error>(
+	config: Config,
+	client: Arc<C>,
+	env: Arc<E>,
+	sync_oracle: SO,
+)
+	-> impl Future<Item=(),Error=()> where
+	B: Block,
+	C: Authorities<B, Error=Error> + BlockImport<B, Error=Error> + ChainHead<B>,
+	E: Environment<B, Error=Error>,
+	E::Proposer: Proposer<B, Error=Error>,
+	SO: SyncOracle + Send + Clone,
+	DigestItemFor<B>: CompatibleDigestItem,
+	Error: ::std::error::Error + Send + 'static + From<::consensus_common::Error>,
+{
+	let make_authorship = move || {
+		let config = config.clone();
+		let client = client.clone();
+		let env = env.clone();
+		let sync_oracle = sync_oracle.clone();
+
+		let local_keys = config.local_key.map(|pair| (pair.public(), pair));
+		let slot_duration = config.slot_duration;
+		let mut last_authored_slot = 0;
+		let next_slot_start = duration_now().map(|now| {
+			let remaining_full_secs = slot_duration - (now.as_secs() % slot_duration) - 1;
+			let remaining_nanos = 1_000_000_000 - now.subsec_nanos();
+			Instant::now() + Duration::new(remaining_full_secs, remaining_nanos)
+		}).unwrap_or_else(|| Instant::now());
+
+		Interval::new(next_slot_start, Duration::from_secs(slot_duration))
+			.filter(move |_| !sync_oracle.is_major_syncing()) // only propose when we are not syncing.
+			.filter_map(move |_| local_keys.clone()) // skip if not authoring.
+			.map_err(|e|  debug!(target: "aura", "Faulty timer: {:?}", e))
+			.for_each(move |(public_key, key)| {
+				use futures::future;
+
+				let slot_num = match slot_now(slot_duration) {
+					Some(n) => n,
+					None => return Either::B(future::err(())),
+				};
+
+				if last_authored_slot >= slot_num { return Either::B(future::ok(())) }
+				last_authored_slot = slot_num;
+
+				let chain_head = match client.best_block_header() {
+					Ok(x) => x,
+					Err(e) => {
+						warn!(target:"aura", "Unable to author block in slot {}. no best block header: {:?}", slot_num, e);
+						return Either::B(future::ok(()))
+					}
+				};
+
+				let authorities = match client.authorities(&BlockId::Hash(chain_head.hash())){
+					Ok(authorities) => authorities,
+					Err(e) => {
+						warn!("Unable to fetch authorities at block {:?}: {:?}", chain_head.hash(), e);
+						return Either::B(future::ok(()));
+					}
+				};
+
+				let proposal_work = match slot_author(slot_num, &authorities) {
+					None => return Either::B(future::ok(())),
+					Some(author) => if author.0 == public_key.0 {
+						// we are the slot author. make a block and sign it.
+						let proposer = match env.init(&chain_head, &authorities, key.clone()) {
+							Ok(p) => p,
+							Err(e) => {
+								warn!("Unable to author block in slot {:?}: {:?}", slot_num, e);
+								return Either::B(future::ok(()))
+							}
+						};
+
+						proposer.propose().into_future()
+					} else {
+						return Either::B(future::ok(()));
+					}
+				};
+
+				let block_import = client.clone();
+				Either::A(proposal_work
+					.map(move |b| {
+						let (header, body) = b.deconstruct();
+						let pre_hash = header.hash();
+						let parent_hash = header.parent_hash().clone();
+
+						// sign the pre-sealed hash of the block and then
+						// add it to a digest item.
+						let to_sign = (slot_num, pre_hash).encode();
+						let signature = key.sign(&to_sign[..]);
+						let item = <DigestItemFor<B> as CompatibleDigestItem>::aura_seal(slot_num, signature);
+						let import_block = ImportBlock {
+							origin: BlockOrigin::Own,
+							header,
+							external_justification: Vec::new(),
+							post_runtime_digests: vec![item],
+							body: Some(body),
+							finalized: false,
+							auxiliary: Vec::new(),
+						};
+
+						if let Err(e) = block_import.import_block(import_block, None) {
+							warn!(target: "aura", "Error with block built on {:?}: {:?}", parent_hash, e);
+						}
+					})
+					.map_err(|e| warn!("Failed to construct block: {:?}", e))
+				)
+			})
+	};
+
+	future::loop_fn((), move |()| {
+		let authorship_task = ::std::panic::AssertUnwindSafe(make_authorship());
+		authorship_task.catch_unwind().then(|res| {
+			match res {
+				Ok(Ok(())) => (),
+				Ok(Err(())) => warn!("Aura authorship task terminated unexpectedly. Restarting"),
+				Err(e) => {
+					if let Some(s) = e.downcast_ref::<&'static str>() {
+						warn!("Aura authorship task panicked at {:?}", s);
+					}
+
+					warn!("Restarting Aura authorship task");
+				}
+			}
+
+			Ok(future::Loop::Continue(()))
+		})
+	})
+}
+
+// a header which has been checked
+enum CheckedHeader<H> {
+	// a header which has slot in the future. this is the full header (not stripped)
+	// and the slot in which it should be processed.
+	Deferred(H, u64),
+	// a header which is fully checked, including signature. This is the pre-header
+	// accompanied by the seal components.
+	Checked(H, u64, ed25519::Signature),
+}
+
+
+/// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned.
+/// if it's successful, returns the pre-header, the slot number, and the signat.
+//
+// FIXME: needs misbehavior types - https://github.com/paritytech/substrate/issues/1018
+fn check_header<B: Block>(slot_now: u64, mut header: B::Header, hash: B::Hash, authorities: &[AuthorityId])
+	-> Result<CheckedHeader<B::Header>, String>
+	where DigestItemFor<B>: CompatibleDigestItem
+{
+	let digest_item = match header.digest_mut().pop() {
+		Some(x) => x,
+		None => return Err(format!("Header {:?} is unsealed", hash)),
+	};
+	let (slot_num, &sig) = match digest_item.as_aura_seal() {
+		Some(x) => x,
+		None => return Err(format!("Header {:?} is unsealed", hash)),
+	};
+
+	if slot_num > slot_now {
+		header.digest_mut().push(digest_item);
+		Ok(CheckedHeader::Deferred(header, slot_num))
+	} else {
+		// check the signature is valid under the expected authority and
+		// chain state.
+
+		let expected_author = match slot_author(slot_num, &authorities) {
+			None => return Err("Slot Author not found".to_string()),
+			Some(author) => author
+		};
+
+		let pre_hash = header.hash();
+		let to_sign = (slot_num, pre_hash).encode();
+		let public = ed25519::Public(expected_author.0);
+
+		if ed25519::verify_strong(&sig, &to_sign[..], public) {
+			Ok(CheckedHeader::Checked(header, slot_num, sig))
+		} else {
+			Err(format!("Bad signature on {:?}", hash))
+		}
+	}
+}
+
+/// A verifier for Aura blocks.
+pub struct AuraVerifier<C> {
+	config: Config,
+	client: Arc<C>,
+}
+
+impl<B: Block, C> Verifier<B> for AuraVerifier<C> where
+	C: Authorities<B> + BlockImport<B> + Send + Sync,
+	DigestItemFor<B>: CompatibleDigestItem,
+{
+	fn verify(
+		&self,
+		origin: BlockOrigin,
+		header: B::Header,
+		_justification: Vec<u8>,
+		body: Option<Vec<B::Extrinsic>>
+	) -> Result<(ImportBlock<B>, Option<Vec<AuthorityId>>), String> {
+		let slot_now = slot_now(self.config.slot_duration)
+			.ok_or("System time is before UnixTime?".to_owned())?;
+		let hash = header.hash();
+		let parent_hash = *header.parent_hash();
+		let authorities = self.client.authorities(&BlockId::Hash(parent_hash))
+			.map_err(|e| format!("Could not fetch authorities at {:?}: {:?}", parent_hash, e))?;
+
+		// we add one to allow for some small drift.
+		// FIXME: in the future, alter this queue to allow deferring of headers
+		// https://github.com/paritytech/substrate/issues/1019
+		let checked_header = check_header::<B>(slot_now + 1, header, hash, &authorities[..])?;
+		match checked_header {
+			CheckedHeader::Checked(pre_header, slot_num, sig) => {
+				let item = <DigestItemFor<B>>::aura_seal(slot_num, sig);
+
+				debug!(target: "aura", "Checked {:?}; importing.", pre_header);
+
+				let import_block = ImportBlock {
+					origin,
+					header: pre_header,
+					external_justification: Vec::new(),
+					post_runtime_digests: vec![item],
+					body,
+					finalized: false,
+					auxiliary: Vec::new(),
+				};
+
+				// FIXME: extract authorities - https://github.com/paritytech/substrate/issues/1019
+				Ok((import_block, None))
+			}
+			CheckedHeader::Deferred(a, b) => {
+				debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b);
+				Err(format!("Header {:?} rejected: too far in the future", hash))
+			}
+		}
+	}
+}
+
+/// The Aura import queue type.
+pub type AuraImportQueue<B, C> = BasicQueue<B, AuraVerifier<C>>;
+
+/// Start an import queue for the Aura consensus algorithm.
+pub fn import_queue<B, C>(config: Config, client: Arc<C>) -> AuraImportQueue<B, C> where
+	B: Block,
+	C: Authorities<B> + BlockImport<B> + Send + Sync,
+	DigestItemFor<B>: CompatibleDigestItem,
+{
+	let verifier = Arc::new(AuraVerifier { config, client });
+	BasicQueue::new(verifier)
+}
+
+
+
+#[cfg(test)]
+mod tests {
+	use super::*;
+	use consensus_common::NoNetwork as DummyOracle;
+	use network::test::*;
+	use network::test::{Block as TestBlock, PeersClient};
+	use runtime_primitives::traits::Block as BlockT;
+	use network::ProtocolConfig;
+	use parking_lot::Mutex;
+	use tokio::runtime::current_thread;
+	use keyring::Keyring;
+	use client::BlockchainEvents;
+	use test_client;
+
+	type Error = client::error::Error;
+
+	type TestClient = client::Client<test_client::Backend, test_client::Executor, TestBlock>;
+
+	struct DummyFactory(Arc<TestClient>);
+	struct DummyProposer(u64, Arc<TestClient>);
+
+	impl Environment<TestBlock> for DummyFactory {
+		type Proposer = DummyProposer;
+		type Error = Error;
+
+		fn init(&self, parent_header: &<TestBlock as BlockT>::Header, _authorities: &[AuthorityId], _sign_with: Arc<ed25519::Pair>)
+			-> Result<DummyProposer, Error>
+		{
+			Ok(DummyProposer(parent_header.number + 1, self.0.clone()))
+		}
+	}
+
+	impl Proposer<TestBlock> for DummyProposer {
+		type Error = Error;
+		type Create = Result<TestBlock, Error>;
+
+		fn propose(&self) -> Result<TestBlock, Error> {
+			self.1.new_block().unwrap().bake().map_err(|e| e.into())
+		}
+	}
+
+	const SLOT_DURATION: u64 = 1;
+	const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50);
+
+	pub struct AuraTestNet {
+		peers: Vec<Arc<Peer<AuraVerifier<PeersClient>>>>,
+		started: bool
+	}
+
+	impl TestNetFactory for AuraTestNet {
+		type Verifier = AuraVerifier<PeersClient>;
+
+		/// Create new test network with peers and given config.
+		fn from_config(_config: &ProtocolConfig) -> Self {
+			AuraTestNet {
+				peers: Vec::new(),
+				started: false
+			}
+		}
+
+		fn make_verifier(&self, client: Arc<PeersClient>, _cfg: &ProtocolConfig)
+			-> Arc<Self::Verifier>
+		{
+			let config = Config { local_key: None, slot_duration: SLOT_DURATION };
+			Arc::new(AuraVerifier { client, config })
+		}
+
+		fn peer(&self, i: usize) -> &Peer<Self::Verifier> {
+			&self.peers[i]
+		}
+
+		fn peers(&self) -> &Vec<Arc<Peer<Self::Verifier>>> {
+			&self.peers
+		}
+
+		fn mut_peers<F: Fn(&mut Vec<Arc<Peer<Self::Verifier>>>)>(&mut self, closure: F ) {
+			closure(&mut self.peers);
+		}
+
+		fn started(&self) -> bool {
+			self.started
+		}
+
+		fn set_started(&mut self, new: bool) {
+			self.started = new;
+		}
+	}
+
+	#[test]
+	fn authoring_blocks() {
+		::env_logger::init().ok();
+		let mut net = AuraTestNet::new(3);
+
+		net.start();
+
+		let peers = &[
+			(0, Keyring::Alice),
+			(1, Keyring::Bob),
+			(2, Keyring::Charlie),
+		];
+
+		let net = Arc::new(Mutex::new(net));
+		let mut import_notifications = Vec::new();
+
+		let mut runtime = current_thread::Runtime::new().unwrap();
+		for (peer_id, key) in peers {
+			let mut client = net.lock().peer(*peer_id).client().clone();
+			let environ = Arc::new(DummyFactory(client.clone()));
+			import_notifications.push(
+				client.import_notification_stream()
+					.take_while(|n| {
+						Ok(!(n.origin != BlockOrigin::Own && n.header.number() < &5))
+					})
+					.for_each(move |_| Ok(()))
+			);
+			let aura = start_aura(
+				Config {
+					local_key: Some(Arc::new(key.clone().into())),
+					slot_duration: SLOT_DURATION
+				},
+				client,
+				environ.clone(),
+				DummyOracle,
+			);
+
+			runtime.spawn(aura);
+		}
+
+		// wait for all finalized on each.
+		let wait_for = ::futures::future::join_all(import_notifications)
+			.map(|_| ())
+			.map_err(|_| ());
+
+		let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL)
+			.for_each(move |_| {
+				net.lock().send_import_notifications();
+				net.lock().sync();
+				Ok(())
+			})
+			.map(|_| ())
+			.map_err(|_| ());
+
+		runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
+	}
+}
diff --git a/substrate/core/consensus/common/Cargo.toml b/substrate/core/consensus/common/Cargo.toml
index ed39cf8fd4a0513fc4b7fba763655596ae304445..08689721a03fcba87158cce42c9fe3b8c14abbbb 100644
--- a/substrate/core/consensus/common/Cargo.toml
+++ b/substrate/core/consensus/common/Cargo.toml
@@ -5,5 +5,11 @@ authors = ["Parity Technologies <admin@parity.io>"]
 description = "Common utilities for substrate consensus"
 
 [dependencies]
-substrate-primitives = { path = "../../primitives"}
+substrate-primitives = { path= "../../primitives" }
+error-chain = "0.12"
+futures = "0.1"
+sr-version = { path = "../../sr-version" }
 sr-primitives = { path = "../../sr-primitives" }
+tokio = "0.1.7"
+parity-codec = "2.1"
+parity-codec-derive = "2.0"
diff --git a/substrate/core/consensus/common/README.adoc b/substrate/core/consensus/common/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..d8f9e1daf28d915bd78ed693d8f40933323aca2f
--- /dev/null
+++ b/substrate/core/consensus/common/README.adoc
@@ -0,0 +1,12 @@
+= Consensus Common
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/consensus/common/src/block_import.rs b/substrate/core/consensus/common/src/block_import.rs
new file mode 100644
index 0000000000000000000000000000000000000000..582886d8272e1f853d6f4ee3483807c69bf48bed
--- /dev/null
+++ b/substrate/core/consensus/common/src/block_import.rs
@@ -0,0 +1,104 @@
+
+use primitives::AuthorityId;
+use runtime_primitives::traits::{Block as BlockT, DigestItemFor};
+use runtime_primitives::Justification;
+
+/// Block import result.
+#[derive(Debug)]
+pub enum ImportResult {
+	/// Added to the import queue.
+	Queued,
+	/// Already in the import queue.
+	AlreadyQueued,
+	/// Already in the blockchain.
+	AlreadyInChain,
+	/// Block or parent is known to be bad.
+	KnownBad,
+	/// Block parent is not in the chain.
+	UnknownParent,
+}
+
+/// Block data origin.
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum BlockOrigin {
+	/// Genesis block built into the client.
+	Genesis,
+	/// Block is part of the initial sync with the network.
+	NetworkInitialSync,
+	/// Block was broadcasted on the network.
+	NetworkBroadcast,
+	/// Block that was received from the network and validated in the consensus process.
+	ConsensusBroadcast,
+	/// Block that was collated by this node.
+	Own,
+	/// Block was imported from a file.
+	File,
+}
+
+/// Data required to import a Block
+pub struct ImportBlock<Block: BlockT> {
+	/// Origin of the Block
+	pub origin: BlockOrigin,
+	/// The header, without consensus post-digests applied. This should be in the same
+	/// state as it comes out of the runtime.
+	///
+	/// Consensus engines which alter the header (by adding post-runtime digests)
+	/// should strip those off in the initial verification process and pass them
+	/// via the `post_runtime_digests` field. During block authorship, they should
+	/// not be pushed to the header directly.
+	///
+	/// The reason for this distinction is so the header can be directly
+	/// re-executed in a runtime that checks digest equivalence -- the
+	/// post-runtime digests are pushed back on after.
+	pub header: Block::Header,
+	/// Justification provided for this block from the outside:.
+	pub external_justification: Justification,
+	/// Digest items that have been added after the runtime for external
+	/// work, like a consensus signature.
+	pub post_runtime_digests: Vec<DigestItemFor<Block>>,
+	/// Block's body
+	pub body: Option<Vec<Block::Extrinsic>>,
+	/// Is this block finalized already?
+	/// `true` implies instant finality.
+	pub finalized: bool,
+	/// Auxiliary consensus data produced by the block.
+	/// Contains a list of key-value pairs. If values are `None`, the keys
+	/// will be deleted.
+	pub auxiliary: Vec<(Vec<u8>, Option<Vec<u8>>)>,
+}
+
+impl<Block: BlockT> ImportBlock<Block> {
+	/// Deconstruct the justified header into parts.
+	pub fn into_inner(self)
+		-> (
+			BlockOrigin,
+			<Block as BlockT>::Header,
+			Justification,
+			Vec<DigestItemFor<Block>>,
+			Option<Vec<<Block as BlockT>::Extrinsic>>,
+			bool,
+			Vec<(Vec<u8>, Option<Vec<u8>>)>,
+		) {
+		(
+			self.origin,
+			self.header,
+			self.external_justification,
+			self.post_runtime_digests,
+			self.body,
+			self.finalized,
+			self.auxiliary,
+		)
+	}
+}
+
+
+
+/// Block import trait.
+pub trait BlockImport<B: BlockT> {
+	type Error: ::std::error::Error + Send + 'static;
+	/// Import a Block alongside the new authorities valid form this block forward
+	fn import_block(&self,
+		block: ImportBlock<B>,
+		new_authorities: Option<Vec<AuthorityId>>
+	) -> Result<ImportResult, Self::Error>;
+}
\ No newline at end of file
diff --git a/substrate/core/consensus/common/src/error.rs b/substrate/core/consensus/common/src/error.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ccf57adb9f1be04fb4960c69c7380b62520a069c
--- /dev/null
+++ b/substrate/core/consensus/common/src/error.rs
@@ -0,0 +1,88 @@
+// Copyright 2017-2018 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Error types in Consensus
+use runtime_version::RuntimeVersion;
+
+error_chain! {
+	errors {
+		/// Missing state at block with given descriptor.
+		StateUnavailable(b: String) {
+			description("State missing at given block."),
+			display("State unavailable at block {}", b),
+		}
+
+		/// I/O terminated unexpectedly
+		IoTerminated {
+			description("I/O terminated unexpectedly."),
+			display("I/O terminated unexpectedly."),
+		}
+
+		/// Unable to schedule wakeup.
+		FaultyTimer(e: ::tokio::timer::Error) {
+			description("Timer error"),
+			display("Timer error: {}", e),
+		}
+
+		/// Unable to propose a block.
+		CannotPropose {
+			description("Unable to create block proposal."),
+			display("Unable to create block proposal."),
+		}
+
+		/// Error checking signature
+		InvalidSignature(s: ::primitives::ed25519::Signature, a: ::primitives::AuthorityId) {
+			description("Message signature is invalid"),
+			display("Message signature {:?} by {:?} is invalid.", s, a),
+		}
+
+		/// Account is not an authority.
+		InvalidAuthority(a: ::primitives::AuthorityId) {
+			description("Message sender is not a valid authority"),
+			display("Message sender {:?} is not a valid authority.", a),
+		}
+
+		/// Authoring interface does not match the runtime.
+		IncompatibleAuthoringRuntime(native: RuntimeVersion, on_chain: RuntimeVersion) {
+			description("Authoring for current runtime is not supported"),
+			display("Authoring for current runtime is not supported. Native ({}) cannot author for on-chain ({}).", native, on_chain),
+		}
+
+		/// Authoring interface does not match the runtime.
+		RuntimeVersionMissing {
+			description("Current runtime has no version"),
+			display("Authoring for current runtime is not supported since it has no version."),
+		}
+
+		/// Authoring interface does not match the runtime.
+		NativeRuntimeMissing {
+			description("This build has no native runtime"),
+			display("Authoring in current build is not supported since it has no runtime."),
+		}
+
+		/// Justification requirements not met.
+		InvalidJustification {
+			description("Invalid justification"),
+			display("Invalid justification."),
+		}
+
+		/// Some other error.
+		Other(e: Box<::std::error::Error + Send>) {
+			description("Other error")
+			display("Other error: {}", e.description())
+		}
+	}
+}
diff --git a/substrate/node/consensus/src/evaluation.rs b/substrate/core/consensus/common/src/evaluation.rs
similarity index 73%
rename from substrate/node/consensus/src/evaluation.rs
rename to substrate/core/consensus/common/src/evaluation.rs
index c21c202e960bb7b1929180a099343cbf18aeb573..db35e2f4115c3c7bac0a1ec2db40be1b9d4d989b 100644
--- a/substrate/node/consensus/src/evaluation.rs
+++ b/substrate/core/consensus/common/src/evaluation.rs
@@ -18,11 +18,10 @@
 
 use super::MAX_TRANSACTIONS_SIZE;
 
-use codec::{Decode, Encode};
-use node_runtime::{Block as GenericBlock};
-use node_primitives::{Hash, BlockNumber};
+use codec::Encode;
 use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As};
 
+type BlockNumber = u64;
 
 error_chain! {
 	errors {
@@ -30,13 +29,13 @@ error_chain! {
 			description("Proposal provided not a block."),
 			display("Proposal provided not a block."),
 		}
-		WrongParentHash(expected: Hash, got: Hash) {
+		WrongParentHash(expected: String, got: String) {
 			description("Proposal had wrong parent hash."),
 			display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got),
 		}
 		WrongNumber(expected: BlockNumber, got: BlockNumber) {
 			description("Proposal had wrong number."),
-			display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got),
+			display("Proposal had wrong number. Expected {}, got {}", expected, got),
 		}
 		ProposalTooLarge(size: usize) {
 			description("Proposal exceeded the maximum size."),
@@ -50,20 +49,17 @@ error_chain! {
 
 /// Attempt to evaluate a substrate block as a node block, returning error
 /// upon any initial validity checks failing.
-pub fn evaluate_initial<Block: BlockT, Hash>(
+pub fn evaluate_initial<Block: BlockT>(
 	proposal: &Block,
-	parent_hash: &Hash,
+	parent_hash: &<Block as BlockT>::Hash,
 	parent_number: <<Block as BlockT>::Header as HeaderT>::Number,
-) -> Result<()>
-where
-	Hash: PartialEq<<<GenericBlock as BlockT>::Header as HeaderT>::Hash>,
-	Hash: Into<self::Hash> + Clone,
-{
+) -> Result<()> {
+
 	let encoded = Encode::encode(proposal);
-	let proposal = GenericBlock::decode(&mut &encoded[..])
+	let proposal = Block::decode(&mut &encoded[..])
 		.ok_or_else(|| ErrorKind::BadProposalFormat)?;
 
-	let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| {
+	let transactions_size = proposal.extrinsics().iter().fold(0, |a, tx| {
 		a + Encode::encode(tx).len()
 	});
 
@@ -72,11 +68,14 @@ where
 	}
 
 	if *parent_hash != *proposal.header().parent_hash() {
-		bail!(ErrorKind::WrongParentHash((*parent_hash).clone().into(), proposal.header.parent_hash));
+		bail!(ErrorKind::WrongParentHash(
+			format!("{:?}", *parent_hash),
+			format!("{:?}", proposal.header().parent_hash())
+		));
 	}
 
-	if parent_number.as_() + 1 != *proposal.header().number() {
-		bail!(ErrorKind::WrongNumber(parent_number.as_() + 1, proposal.header.number));
+	if parent_number.as_() + 1 != proposal.header().number().as_() {
+		bail!(ErrorKind::WrongNumber(parent_number.as_() + 1, proposal.header().number().as_()));
 	}
 
 	Ok(())
diff --git a/substrate/core/consensus/common/src/lib.rs b/substrate/core/consensus/common/src/lib.rs
index 390e7beadeabc9ba4e5e9f1997b4895480d2826a..12d5cfa70df2f27833997ca7adc7d65a9eafc71c 100644
--- a/substrate/core/consensus/common/src/lib.rs
+++ b/substrate/core/consensus/common/src/lib.rs
@@ -14,21 +14,119 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate Consensus Common.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Tracks offline validators.
+// tag::description[]
+//! Consensus basics and common features
+// end::description[]
+
+// This provides "unused" building blocks to other crates
 #![allow(dead_code)]
 
+// our error-chain could potentially blow up otherwise
+#![recursion_limit="128"]
+
 extern crate substrate_primitives as primitives;
-extern crate sr_primitives;
+extern crate futures;
+extern crate sr_version as runtime_version;
+extern crate sr_primitives as runtime_primitives;
+extern crate tokio;
 
-use sr_primitives::{generic::BlockId};
-use sr_primitives::traits::{Block, Header};
-use sr_primitives::Justification;
-use primitives::AuthorityId;
+extern crate parity_codec as codec;
+#[macro_use]
+extern crate parity_codec_derive;
 
-/// Block import trait.
-pub trait BlockImport<B: Block> {
-	/// Import a block alongside its corresponding justification.
-	fn import_block(&self, block: B, justification: Justification, authorities: &[AuthorityId]) -> bool;
-}
+#[macro_use]
+extern crate error_chain;
+
+use std::sync::Arc;
+
+use primitives::{ed25519, AuthorityId};
+use runtime_primitives::generic::BlockId;
+use runtime_primitives::traits::Block;
+use futures::prelude::*;
 
 pub mod offline_tracker;
+pub mod error;
+mod block_import;
+pub mod evaluation;
+
+// block size limit.
+const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024;
+
+pub use self::error::{Error, ErrorKind};
+pub use block_import::{BlockImport, ImportBlock, BlockOrigin, ImportResult};
+
+/// Trait for getting the authorities at a given block.
+pub trait Authorities<B: Block> {
+	type Error: ::std::error::Error + Send + 'static;	/// Get the authorities at the given block.
+	fn authorities(&self, at: &BlockId<B>) -> Result<Vec<AuthorityId>, Self::Error>;
+}
+
+/// Environment producer for a Consensus instance. Creates proposer instance and communication streams.
+pub trait Environment<B: Block> {
+	/// The proposer type this creates.
+	type Proposer: Proposer<B>;
+	/// Error which can occur upon creation.
+	type Error: From<Error>;
+
+	/// Initialize the proposal logic on top of a specific header. Provide
+	/// the authorities at that header, and a local key to sign any additional
+	/// consensus messages with as well.
+	fn init(&self, parent_header: &B::Header, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>)
+		-> Result<Self::Proposer, Self::Error>;
+}
+
+/// Logic for a proposer.
+///
+/// This will encapsulate creation and evaluation of proposals at a specific
+/// block.
+pub trait Proposer<B: Block> {
+	/// Error type which can occur when proposing or evaluating.
+	type Error: From<Error> + ::std::fmt::Debug + 'static;
+	/// Future that resolves to a committed proposal.
+	type Create: IntoFuture<Item=B,Error=Self::Error>;
+	/// Create a proposal.
+	fn propose(&self) -> Self::Create;
+}
+
+/// Inherent data to include in a block.
+#[derive(Encode, Decode)]
+pub struct InherentData {
+	/// Current timestamp.
+	pub timestamp: u64,
+	/// Indices of offline validators.
+	pub offline_indices: Vec<u32>,
+}
+
+impl InherentData {
+	/// Create a new `InherentData` instance.
+	pub fn new(timestamp: u64, offline_indices: Vec<u32>) -> Self {
+		Self {
+			timestamp,
+			offline_indices
+		}
+	}
+}
+
+/// An oracle for when major synchronization work is being undertaken.
+///
+/// Generally, consensus authoring work isn't undertaken while well behind
+/// the head of the chain.
+pub trait SyncOracle {
+	/// Whether the synchronization service is undergoing major sync.
+	/// Returns true if so.
+	fn is_major_syncing(&self) -> bool;
+}
+
+/// A synchronization oracle for when there is no network.
+#[derive(Clone, Copy, Debug)]
+pub struct NoNetwork;
+
+impl SyncOracle for NoNetwork {
+	fn is_major_syncing(&self) -> bool { false }
+}
+
+impl<T: SyncOracle> SyncOracle for Arc<T> {
+	fn is_major_syncing(&self) -> bool {
+		T::is_major_syncing(&*self)
+	}
+}
diff --git a/substrate/core/consensus/rhd/Cargo.toml b/substrate/core/consensus/rhd/Cargo.toml
index f5b928c42920bf03e4e1f31427297dd8b86c8d9f..dce6a6d7f445abd16193672ea726cdf266f2f339 100644
--- a/substrate/core/consensus/rhd/Cargo.toml
+++ b/substrate/core/consensus/rhd/Cargo.toml
@@ -6,30 +6,33 @@ description = "Rhododendron Round-Based consensus-algorithm for substrate"
 
 [dependencies]
 futures = "0.1.17"
-parity-codec = { version = "1.1" }
+parity-codec = { version = "2.1" }
 parity-codec-derive = { version = "2.0" }
 substrate-primitives = { path = "../../primitives" }
+substrate-consensus-common = { path = "../common" }
+substrate-client = { path = "../../client" }
+substrate-transaction-pool = { path = "../../transaction-pool" }
 srml-support = { path = "../../../srml/support" }
+srml-system = { path = "../../../srml/system" }
+srml-consensus = { path = "../../../srml/consensus" }
 sr-primitives = { path = "../../sr-primitives" }
 sr-version = { path = "../../sr-version" }
 sr-io = { path = "../../sr-io" }
-srml-consensus = { path = "../../../srml/consensus" }
 tokio = "0.1.7"
 parking_lot = "0.4"
 error-chain = "0.12"
-log = "0.3"
-rhododendron = { git = "https://github.com/paritytech/rhododendron.git", features = ["codec"] }
-serde = { version = "1.0", features = ["derive"] }
+log = "0.4"
+rhododendron = { version = "0.4.0", features = ["codec"] }
+exit-future = "0.1"
+
 
 [dev-dependencies]
 substrate-keyring = { path = "../../keyring" }
 substrate-executor = { path = "../../executor" }
 
-
 [features]
 default = ["std"]
 std = [
-	"serde/std",
 	"substrate-primitives/std",
 	"srml-support/std",
 	"sr-primitives/std",
diff --git a/substrate/core/consensus/rhd/README.adoc b/substrate/core/consensus/rhd/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..ff7bde17146ad5e84d317517c6580347f4221112
--- /dev/null
+++ b/substrate/core/consensus/rhd/README.adoc
@@ -0,0 +1,12 @@
+= Consensus Rhododendron (RHD)
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/consensus/rhd/src/error.rs b/substrate/core/consensus/rhd/src/error.rs
index 806ba5624a3ad717e38127797fadd6321accbaf5..c18c36f679c830d20e623af83bc6f7b059349171 100644
--- a/substrate/core/consensus/rhd/src/error.rs
+++ b/substrate/core/consensus/rhd/src/error.rs
@@ -1,4 +1,4 @@
-// Copyright 2017-2018 Parity Technologies (UK) Ltd.
+// Copyright 2018 Parity Technologies (UK) Ltd.
 // This file is part of Substrate.
 
 // Substrate is free software: you can redistribute it and/or modify
@@ -14,81 +14,44 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Error types in the BFT service.
-use runtime_version::RuntimeVersion;
+//! Error types in the rhododendron Consensus service.
+use consensus::error::{Error as CommonError, ErrorKind as CommonErrorKind};
+use primitives::AuthorityId;
+use client;
 
 error_chain! {
+	links {
+		Client(client::error::Error, client::error::ErrorKind);
+		Common(CommonError, CommonErrorKind);
+	}
 	errors {
-		/// Missing state at block with given descriptor.
-		StateUnavailable(b: String) {
-			description("State missing at given block."),
-			display("State unavailable at block {}", b),
-		}
-
-		/// I/O terminated unexpectedly
-		IoTerminated {
-			description("I/O terminated unexpectedly."),
-			display("I/O terminated unexpectedly."),
-		}
-
-		/// Unable to schedule wakeup.
-		FaultyTimer(e: ::tokio::timer::Error) {
-			description("Timer error"),
-			display("Timer error: {}", e),
-		}
-
-		/// Unable to propose a block.
-		CannotPropose {
-			description("Unable to create block proposal."),
-			display("Unable to create block proposal."),
-		}
-
-		/// Error checking signature
-		InvalidSignature(s: ::primitives::ed25519::Signature, a: ::primitives::AuthorityId) {
-			description("Message signature is invalid"),
-			display("Message signature {:?} by {:?} is invalid.", s, a),
-		}
-
-		/// Account is not an authority.
-		InvalidAuthority(a: ::primitives::AuthorityId) {
-			description("Message sender is not a valid authority"),
-			display("Message sender {:?} is not a valid authority.", a),
-		}
-
-		/// Authoring interface does not match the runtime.
-		IncompatibleAuthoringRuntime(native: RuntimeVersion, on_chain: RuntimeVersion) {
-			description("Authoring for current runtime is not supported"),
-			display("Authoring for current runtime is not supported. Native ({}) cannot author for on-chain ({}).", native, on_chain),
-		}
-
-		/// Authoring interface does not match the runtime.
-		RuntimeVersionMissing {
-			description("Current runtime has no version"),
-			display("Authoring for current runtime is not supported since it has no version."),
+		NotValidator(id: AuthorityId) {
+			description("Local account ID not a validator at this block."),
+			display("Local account ID ({:?}) not a validator at this block.", id),
 		}
-
-		/// Authoring interface does not match the runtime.
-		NativeRuntimeMissing {
-			description("This build has no native runtime"),
-			display("Authoring in current build is not supported since it has no runtime."),
+		PrematureDestruction {
+			description("Proposer destroyed before finishing proposing or evaluating"),
+			display("Proposer destroyed before finishing proposing or evaluating"),
 		}
-
-		/// Justification requirements not met.
-		InvalidJustification {
-			description("Invalid justification"),
-			display("Invalid justification."),
+		Timer(e: ::tokio::timer::Error) {
+			description("Failed to register or resolve async timer."),
+			display("Timer failed: {}", e),
 		}
-
-		/// Some other error.
-		Other(e: Box<::std::error::Error + Send>) {
-			description("Other error")
-			display("Other error: {}", e.description())
+		Executor(e: ::futures::future::ExecuteErrorKind) {
+			description("Unable to dispatch agreement future"),
+			display("Unable to dispatch agreement future: {:?}", e),
 		}
 	}
 }
 
 impl From<::rhododendron::InputStreamConcluded> for Error {
-	fn from(_: ::rhododendron::InputStreamConcluded) -> Error {
-		ErrorKind::IoTerminated.into()
+	fn from(_: ::rhododendron::InputStreamConcluded) -> Self {
+		CommonErrorKind::IoTerminated.into()
 	}
 }
+
+impl From<CommonErrorKind> for Error {
+	fn from(e: CommonErrorKind) -> Self {
+		CommonError::from(e).into()
+	}
+}
\ No newline at end of file
diff --git a/substrate/core/consensus/rhd/src/lib.rs b/substrate/core/consensus/rhd/src/lib.rs
index 4edc8fc89337fecf8a65c07a9bcda1e05c4588a4..b99ea4a24c71593654f223aee2edc67153a4e133 100644
--- a/substrate/core/consensus/rhd/src/lib.rs
+++ b/substrate/core/consensus/rhd/src/lib.rs
@@ -14,6 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
+// tag::description[]
 //! BFT Agreement based on a rotating proposer in different rounds.
 //!
 //! Where this crate refers to input stream, should never logically conclude.
@@ -29,61 +30,76 @@
 //! conclude without having witnessed the conclusion.
 //! In general, this future should be pre-empted by the import of a justification
 //! set for this block height.
+// end::description[]
 
-#![cfg(feature = "rhd")]
-
-#![recursion_limit="128"]
+#![cfg(feature="rhd")]
+// FIXME: doesn't compile - https://github.com/paritytech/substrate/issues/1020
 
 extern crate parity_codec as codec;
 extern crate substrate_primitives as primitives;
+extern crate substrate_client as client;
+extern crate substrate_consensus_common as consensus;
+extern crate substrate_transaction_pool as transaction_pool;
+extern crate srml_system;
 extern crate srml_support as runtime_support;
 extern crate sr_primitives as runtime_primitives;
 extern crate sr_version as runtime_version;
 extern crate sr_io as runtime_io;
-extern crate tokio;
 
-#[cfg(test)]
-extern crate substrate_keyring as keyring;
 extern crate parking_lot;
 extern crate rhododendron;
+extern crate futures;
+extern crate exit_future;
+extern crate tokio;
 
 #[macro_use]
 extern crate log;
 
-
-extern crate futures;
-
 #[macro_use]
 extern crate error_chain;
 
-#[macro_use]
-extern crate serde;
-
 #[macro_use]
 extern crate parity_codec_derive;
 
-
-pub mod error;
+#[cfg(test)]
+extern crate substrate_keyring;
 
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
-use std::time::{Instant, Duration};
-
-use codec::Encode;
-use runtime_primitives::{generic::BlockId, Justification};
+use std::time::{self, Instant, Duration};
+
+use codec::{Decode, Encode};
+use consensus::offline_tracker::OfflineTracker;
+use consensus::error::{ErrorKind as CommonErrorKind};
+use consensus::{Authorities, BlockImport, Environment, Proposer as BaseProposer};
+use client::{Client as SubstrateClient, CallExecutor};
+use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, OldTxQueue, BlockBuilderError};
+use runtime_primitives::generic::{BlockId, Era, ImportResult, ImportBlock, BlockOrigin};
 use runtime_primitives::traits::{Block, Header};
-use primitives::{AuthorityId, ed25519, ed25519::LocalizedSignature};
+use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, As, BlockNumberToHash};
+use runtime_primitives::Justification;
+use primitives::{AuthorityId, ed25519, Blake2Hasher, ed25519::LocalizedSignature};
+use srml_system::Trait as SystemT;
 
-use futures::{Async, Stream, Sink, Future, IntoFuture};
+use node_runtime::Runtime;
+use transaction_pool::txpool::{self, Pool as TransactionPool};
+
+use futures::prelude::*;
+use futures::future;
 use futures::sync::oneshot;
+use tokio::runtime::TaskExecutor;
 use tokio::timer::Delay;
-use parking_lot::Mutex;
+use parking_lot::{RwLock, Mutex};
 
-pub use rhododendron::{InputStreamConcluded, AdvanceRoundReason,
-	Message as RhdMessage, Vote as RhdMessageVote};
-pub use error::{Error, ErrorKind};
+pub use rhododendron::{
+	self, InputStreamConcluded, AdvanceRoundReason, Message as RhdMessage,
+	Vote as RhdMessageVote, Communication as RhdCommunication,
+};
+pub use self::error::{Error, ErrorKind};
 
 // pub mod misbehaviour_check;
+mod error;
+mod service;
 
 // statuses for an agreement
 mod status {
@@ -92,6 +108,10 @@ mod status {
 	pub const GOOD: usize = 2;
 }
 
+pub type Timestamp = u64;
+
+pub type AccountId = ::primitives::H256;
+
 /// Localized message type.
 pub type LocalizedMessage<B> = rhododendron::LocalizedMessage<
 	B,
@@ -100,8 +120,6 @@ pub type LocalizedMessage<B> = rhododendron::LocalizedMessage<
 	LocalizedSignature
 >;
 
-
-
 /// Justification of some hash.
 pub struct RhdJustification<H>(rhododendron::Justification<H, LocalizedSignature>);
 
@@ -109,11 +127,12 @@ pub struct RhdJustification<H>(rhododendron::Justification<H, LocalizedSignature
 pub struct PrepareJustification<H>(rhododendron::PrepareJustification<H, LocalizedSignature>);
 
 /// Unchecked justification.
+#[derive(Encode, Decode)]
 pub struct UncheckedJustification<H>(rhododendron::UncheckedJustification<H, LocalizedSignature>);
 
 impl<H> UncheckedJustification<H> {
 	/// Create a new, unchecked justification.
-	pub fn new(digest: H, signatures: Vec<LocalizedSignature>, round_number: usize) -> Self {
+	pub fn new(digest: H, signatures: Vec<LocalizedSignature>, round_number: u32) -> Self {
 		UncheckedJustification(rhododendron::UncheckedJustification {
 			digest,
 			signatures,
@@ -122,40 +141,24 @@ impl<H> UncheckedJustification<H> {
 	}
 }
 
-impl<H> Into<Justification> for RhdJustification<H> {
-	fn into(self) -> Justification {
-		let p : Justification = UncheckedJustification(self.0.uncheck()).into();
-		p
-	}
-}
-
+impl<H: Decode> UncheckedJustification<H> {
+	/// Decode a justification.
+	pub fn decode_justification(justification: Justification) -> Option<Self> {
+		let inner: rhododendron::UncheckedJustification<_, _> = Decode::decode(&mut &justification[..])?;
 
-impl<H> From<rhododendron::UncheckedJustification<H, LocalizedSignature>> for UncheckedJustification<H> {
-	fn from(inner: rhododendron::UncheckedJustification<H, LocalizedSignature>) -> Self {
-		UncheckedJustification(inner)
+		Some(UncheckedJustification(inner))
 	}
 }
 
-impl<H> From<Justification> for UncheckedJustification<H> {
-	fn from(just: Justification) -> Self {
-		UncheckedJustification(rhododendron::UncheckedJustification {
-			round_number: just.round_number as usize,
-			digest: just.hash,
-			signatures: just.signatures.into_iter().map(|(from, sig)| LocalizedSignature {
-				signer: from.into(),
-				signature: sig,
-			}).collect(),
-		})
+impl<H: Encode> Into<Justification> for UncheckedJustification<H> {
+	fn into(self) -> Justification {
+		self.0.encode()
 	}
 }
 
-impl<H> Into<Justification> for UncheckedJustification<H> {
-	fn into(self) -> Justification {
-		Justification {
-			round_number: self.0.round_number as u32,
-			hash: self.0.digest,
-			signatures: self.0.signatures.into_iter().map(|s| (s.signer.into(), s.signature)).collect(),
-		}
+impl<H> From<rhododendron::UncheckedJustification<H, LocalizedSignature>> for UncheckedJustification<H> {
+	fn from(inner: rhododendron::UncheckedJustification<H, LocalizedSignature>) -> Self {
+		UncheckedJustification(inner)
 	}
 }
 
@@ -168,59 +171,72 @@ pub type Communication<B> = rhododendron::Communication<B, <B as Block>::Hash, A
 /// Misbehavior observed from BFT participants.
 pub type Misbehavior<H> = rhododendron::Misbehavior<H, LocalizedSignature>;
 
-/// Environment producer for a BFT instance. Creates proposer instance and communication streams.
-pub trait Environment<B: Block> {
-	/// The proposer type this creates.
-	type Proposer: Proposer<B>;
-	/// The input stream type.
-	type Input: Stream<Item=Communication<B>, Error=<Self::Proposer as Proposer<B>>::Error>;
-	/// The output stream type.
-	type Output: Sink<SinkItem=Communication<B>, SinkError=<Self::Proposer as Proposer<B>>::Error>;
-	/// Error which can occur upon creation.
-	type Error: From<Error>;
-
-	/// Initialize the proposal logic on top of a specific header.
-	/// Produces the proposer and message streams for this instance of BFT agreement.
-	// TODO: provide state context explicitly?
-	fn init(&self, parent_header: &B::Header, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>)
-		-> Result<(Self::Proposer, Self::Input, Self::Output), Self::Error>;
-}
+/// Shared offline validator tracker.
+pub type SharedOfflineTracker = Arc<RwLock<OfflineTracker>>;
 
-/// Logic for a proposer.
-///
-/// This will encapsulate creation and evaluation of proposals at a specific
-/// block.
-pub trait Proposer<B: Block> {
-	/// Error type which can occur when proposing or evaluating.
-	type Error: From<Error> + From<InputStreamConcluded> + ::std::fmt::Debug + 'static;
-	/// Future that resolves to a committed proposal.
-	type Create: IntoFuture<Item=B,Error=Self::Error>;
-	/// Future that resolves when a proposal is evaluated.
-	type Evaluate: IntoFuture<Item=bool,Error=Self::Error>;
-
-	/// Create a proposal.
-	fn propose(&self) -> Self::Create;
-
-	/// Evaluate proposal. True means valid.
-	fn evaluate(&self, proposal: &B) -> Self::Evaluate;
-
-	/// Import witnessed misbehavior.
+/// A proposer for a rhododendron instance. This must implement the base proposer logic.
+pub trait LocalProposer<B: Block>: BaseProposer<B, Error=Error> {
+	/// Import witnessed rhododendron misbehavior.
 	fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, Misbehavior<B::Hash>)>);
 
 	/// Determine the proposer for a given round. This should be a deterministic function
 	/// with consistent results across all authorities.
-	fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId;
+	fn round_proposer(&self, round_number: u32, authorities: &[AuthorityId]) -> AuthorityId;
 
 	/// Hook called when a BFT round advances without a proposal.
-	fn on_round_end(&self, _round_number: usize, _proposed: bool) { }
+	fn on_round_end(&self, _round_number: u32, _proposed: bool) { }
+}
+
+
+/// Build new blocks.
+pub trait BlockBuilder<Block: BlockT> {
+	/// Push an extrinsic onto the block. Fails if the extrinsic is invalid.
+	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<(), Error>;
 }
 
-/// Trait for getting the authorities at a given block.
-pub trait Authorities<B: Block> {
-	/// Get the authorities at the given block.
-	fn authorities(&self, at: &BlockId<B>) -> Result<Vec<AuthorityId>, Error>;
+/// Local client abstraction for the consensus.
+pub trait AuthoringApi:
+	Send
+	+ Sync
+	+ BlockBuilderAPI<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
+	+ Core<<Self as AuthoringApi>::Block, AuthorityId, Error=<Self as AuthoringApi>::Error>
+	+ OldTxQueue<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
+{
+	/// The block used for this API type.
+	type Block: BlockT;
+	/// The error used by this API type.
+	type Error: std::error::Error;
+
+	/// Build a block on top of the given, with inherent extrinsics pre-pushed.
+	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
+		&self,
+		at: &BlockId<Self::Block>,
+		inherent_data: InherentData,
+		build_ctx: F,
+	) -> Result<Self::Block, Error>;
 }
 
+/// A long-lived network which can create BFT message routing processes on demand.
+pub trait Network {
+	/// The block used for this API type.
+	type Block: BlockT;
+	/// The input stream of BFT messages. Should never logically conclude.
+	type Input: Stream<Item=Communication<Self::Block>,Error=Error>;
+	/// The output sink of BFT messages. Messages sent here should eventually pass to all
+	/// current authorities.
+	type Output: Sink<SinkItem=Communication<Self::Block>,SinkError=Error>;
+
+	/// Instantiate input and output streams.
+	fn communication_for(
+		&self,
+		validators: &[AuthorityId],
+		local_id: AuthorityId,
+		parent_hash: <Self::Block as BlockT>::Hash,
+		task_executor: TaskExecutor
+	) -> (Self::Input, Self::Output);
+}
+
+
 // caches the round number to start at if we end up with BFT consensus on the same
 // parent hash more than once (happens if block is bad).
 //
@@ -229,7 +245,7 @@ pub trait Authorities<B: Block> {
 #[derive(Debug)]
 struct RoundCache<H> {
 	hash: Option<H>,
-	start_round: usize,
+	start_round: u32,
 }
 
 /// Instance of BFT agreement.
@@ -242,19 +258,19 @@ struct BftInstance<B: Block, P> {
 	proposer: P,
 }
 
-impl<B: Block, P: Proposer<B>> BftInstance<B, P>
+impl<B: Block, P: LocalProposer<B>> BftInstance<B, P>
 	where
 		B: Clone + Eq,
 		B::Hash: ::std::hash::Hash
 
 {
-	fn round_timeout_duration(&self, round: usize) -> Duration {
+	fn round_timeout_duration(&self, round: u32) -> Duration {
 		// 2^(min(6, x/8)) * 10
 		// Grows exponentially starting from 10 seconds, capped at 640 seconds.
-		const ROUND_INCREMENT_STEP: usize = 8;
+		const ROUND_INCREMENT_STEP: u32 = 8;
 
 		let round = round / ROUND_INCREMENT_STEP;
-		let round = ::std::cmp::min(6, round) as u32;
+		let round = ::std::cmp::min(6, round);
 
 		let timeout = 1u64.checked_shl(round)
 			.unwrap_or_else(u64::max_value)
@@ -263,7 +279,7 @@ impl<B: Block, P: Proposer<B>> BftInstance<B, P>
 		Duration::from_secs(timeout)
 	}
 
-	fn update_round_cache(&self, current_round: usize) {
+	fn update_round_cache(&self, current_round: u32) {
 		let mut cache = self.cache.lock();
 		if cache.hash.as_ref() == Some(&self.parent_hash) {
 			cache.start_round = current_round + 1;
@@ -271,7 +287,7 @@ impl<B: Block, P: Proposer<B>> BftInstance<B, P>
 	}
 }
 
-impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
+impl<B: Block, P: LocalProposer<B>> rhododendron::Context for BftInstance<B, P>
 	where
 		B: Clone + Eq,
 		B::Hash: ::std::hash::Hash,
@@ -301,7 +317,7 @@ impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
 		sign_message(message, &*self.key, self.parent_hash.clone())
 	}
 
-	fn round_proposer(&self, round: usize) -> AuthorityId {
+	fn round_proposer(&self, round: u32) -> AuthorityId {
 		self.proposer.round_proposer(round, &self.authorities[..])
 	}
 
@@ -309,10 +325,10 @@ impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
 		self.proposer.evaluate(proposal).into_future()
 	}
 
-	fn begin_round_timeout(&self, round: usize) -> Self::RoundTimeout {
+	fn begin_round_timeout(&self, round: u32) -> Self::RoundTimeout {
 		let timeout = self.round_timeout_duration(round);
 		let fut = Delay::new(Instant::now() + timeout)
-			.map_err(|e| Error::from(ErrorKind::FaultyTimer(e)))
+			.map_err(|e| Error::from(CommonErrorKind::FaultyTimer(e)))
 			.map_err(Into::into);
 
 		Box::new(fut)
@@ -320,9 +336,9 @@ impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
 
 	fn on_advance_round(
 		&self,
-		accumulator: &::rhododendron::Accumulator<B, B::Hash, Self::AuthorityId, Self::Signature>,
-		round: usize,
-		next_round: usize,
+		accumulator: &rhododendron::Accumulator<B, B::Hash, Self::AuthorityId, Self::Signature>,
+		round: u32,
+		next_round: u32,
 		reason: AdvanceRoundReason,
 	) {
 		use std::collections::HashSet;
@@ -332,12 +348,12 @@ impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
 			.collect::<Vec<_>>();
 
 		let round_timeout = self.round_timeout_duration(next_round);
-		debug!(target: "bft", "Advancing to round {} from {}", next_round, round);
-		debug!(target: "bft", "Participating authorities: {:?}",
+		debug!(target: "rhd", "Advancing to round {} from {}", next_round, round);
+		debug!(target: "rhd", "Participating authorities: {:?}",
 			collect_pubkeys(accumulator.participants()));
-		debug!(target: "bft", "Voting authorities: {:?}",
+		debug!(target: "rhd", "Voting authorities: {:?}",
 			collect_pubkeys(accumulator.voters()));
-		debug!(target: "bft", "Round {} should end in at most {} seconds from now", next_round, round_timeout.as_secs());
+		debug!(target: "rhd", "Round {} should end in at most {} seconds from now", next_round, round_timeout.as_secs());
 
 		self.update_round_cache(next_round);
 
@@ -352,9 +368,10 @@ impl<B: Block, P: Proposer<B>> rhododendron::Context for BftInstance<B, P>
 pub struct BftFuture<B, P, I, InStream, OutSink> where
 	B: Block + Clone + Eq,
 	B::Hash: ::std::hash::Hash,
-	P: Proposer<B>,
-	InStream: Stream<Item=Communication<B>, Error=P::Error>,
-	OutSink: Sink<SinkItem=Communication<B>, SinkError=P::Error>,
+	P: LocalProposer<B>,
+	P: BaseProposer<B, Error=Error>,
+	InStream: Stream<Item=Communication<B>, Error=Error>,
+	OutSink: Sink<SinkItem=Communication<B>, SinkError=Error>,
 {
 	inner: rhododendron::Agreement<BftInstance<B, P>, InStream, OutSink>,
 	status: Arc<AtomicUsize>,
@@ -365,11 +382,11 @@ pub struct BftFuture<B, P, I, InStream, OutSink> where
 impl<B, P, I, InStream, OutSink> Future for BftFuture<B, P, I, InStream, OutSink> where
 	B: Block + Clone + Eq,
 	B::Hash: ::std::hash::Hash,
-	P: Proposer<B>,
-	P::Error: ::std::fmt::Display,
+	P: LocalProposer<B>,
+	P: BaseProposer<B, Error=Error>,
 	I: BlockImport<B>,
-	InStream: Stream<Item=Communication<B>, Error=P::Error>,
-	OutSink: Sink<SinkItem=Communication<B>, SinkError=P::Error>,
+	InStream: Stream<Item=Communication<B>, Error=Error>,
+	OutSink: Sink<SinkItem=Communication<B>, SinkError=Error>,
 {
 	type Item = ();
 	type Error = ();
@@ -381,7 +398,6 @@ impl<B, P, I, InStream, OutSink> Future for BftFuture<B, P, I, InStream, OutSink
 			Ok(Async::NotReady) => false,
 		};
 
-		// TODO: handle and log this error in a way which isn't noisy on exit.
 		let committed = match self.inner.poll().map_err(|_| ()) {
 			Ok(Async::Ready(x)) => x,
 			Ok(Async::NotReady) =>
@@ -396,23 +412,36 @@ impl<B, P, I, InStream, OutSink> Future for BftFuture<B, P, I, InStream, OutSink
 		// we will get the block from the network later.
 		if let Some(justified_block) = committed.candidate {
 			let hash = justified_block.hash();
-			info!(target: "bft", "Importing block #{} ({}) directly from BFT consensus",
+			info!(target: "rhd", "Importing block #{} ({}) directly from BFT consensus",
 				justified_block.header().number(), hash);
-			let just : Justification = RhdJustification(committed.justification).into();
+			let just: Justification = UncheckedJustification(committed.justification.uncheck()).into();
+			let (header, body) = justified_block.deconstruct();
+			let import_block = ImportBlock {
+				origin: BlockOrigin::ConsensusBroadcast,
+				header: header,
+				external_justification: just.into(),
+				body: Some(body),
+				finalized: true,
+				post_runtime_digests: Default::default(),
+				auxiliary: Default::default()
+			};
+
+			let new_status = match self.import.import_block(import_block, None) {
+				Err(e) => {
+					warn!(target: "rhd", "Error importing block {:?} in round #{}: {:?}",
+						hash, committed.round_number, e);
+					status::BAD
+				}
+				Ok(ImportResult::KnownBad) => {
+					warn!(target: "rhd", "{:?} was bad block agreed on in round #{}",
+						hash, committed.round_number);
+					status::BAD
+				}
+				_ => status::GOOD
+			};
+
+			self.status.store(new_status, Ordering::Release);
 
-			let import_ok = self.import.import_block(
-				justified_block,
-				just,
-				&self.inner.context().authorities
-			);
-
-			if !import_ok {
-				warn!(target: "bft", "{:?} was bad block agreed on in round #{}",
-					hash, committed.round_number);
-				self.status.store(status::BAD, Ordering::Release);
-			} else {
-				self.status.store(status::GOOD, Ordering::Release);
-			}
 		} else {
 			// assume good unless we received the proposal.
 			self.status.store(status::GOOD, Ordering::Release);
@@ -427,9 +456,10 @@ impl<B, P, I, InStream, OutSink> Future for BftFuture<B, P, I, InStream, OutSink
 impl<B, P, I, InStream, OutSink> Drop for BftFuture<B, P, I, InStream, OutSink> where
 	B: Block + Clone + Eq,
 	B::Hash: ::std::hash::Hash,
-	P: Proposer<B>,
-	InStream: Stream<Item=Communication<B>, Error=P::Error>,
-	OutSink: Sink<SinkItem=Communication<B>, SinkError=P::Error>,
+	P: LocalProposer<B>,
+	P: BaseProposer<B, Error=Error>,
+	InStream: Stream<Item=Communication<B>, Error=Error>,
+	OutSink: Sink<SinkItem=Communication<B>, SinkError=Error>,
 {
 	fn drop(&mut self) {
 		// TODO: have a trait member to pass misbehavior reports into.
@@ -474,10 +504,10 @@ impl<B, P, I> BftService<B, P, I>
 	where
 		B: Block + Clone + Eq,
 		P: Environment<B>,
-		<P::Proposer as Proposer<B>>::Error: ::std::fmt::Display,
+		P::Proposer: LocalProposer<B>,
+		P::Proposer: BaseProposer<B,Error=Error>,
 		I: BlockImport<B> + Authorities<B>,
 {
-
 	/// Create a new service instance.
 	pub fn new(client: Arc<I>, key: Arc<ed25519::Pair>, factory: P) -> BftService<B, P, I> {
 		BftService {
@@ -500,20 +530,29 @@ impl<B, P, I> BftService<B, P, I>
 	}
 
 	/// Signal that a valid block with the given header has been imported.
+	/// Provide communication streams that are localized to this block.
+	/// It's recommended to use the communication primitives provided by this
+	/// module for signature checking and decoding. See `CheckedStream` and
+	/// `SigningSink` for more details.
+	///
+	/// Messages received on the stream that don't match the expected format
+	/// will be dropped.
 	///
 	/// If the local signing key is an authority, this will begin the consensus process to build a
 	/// block on top of it. If the executor fails to run the future, an error will be returned.
 	/// Returns `None` if the agreement on the block with given parent is already in progress.
-	pub fn build_upon(&self, header: &B::Header)
+	pub fn build_upon<In, Out>(&self, header: &B::Header, input: In, output: Out)
 		-> Result<Option<
 			BftFuture<
 				B,
 				<P as Environment<B>>::Proposer,
 				I,
-				<P as Environment<B>>::Input,
-				<P as Environment<B>>::Output,
+				In,
+				Out,
 			>>, P::Error>
 		where
+			In: Stream<Item=Communication<B>, Error=Error>,
+			Out: Sink<SinkItem=Communication<B>, SinkError=Error>,
 	{
 		let hash = header.hash();
 
@@ -525,22 +564,23 @@ impl<B, P, I> BftService<B, P, I>
 			return Ok(None)
 		}
 
-		let authorities = self.client.authorities(&BlockId::Hash(hash.clone()))?;
+		let authorities = self.client.authorities(&BlockId::Hash(hash.clone()))
+			.map_err(|e| CommonErrorKind::Other(Box::new(e)).into())?;
 
 		let n = authorities.len();
 		let max_faulty = max_faulty_of(n);
-		trace!(target: "bft", "Initiating agreement on top of #{}, {:?}", header.number(), hash);
-		trace!(target: "bft", "max_faulty_of({})={}", n, max_faulty);
+		trace!(target: "rhd", "Initiating agreement on top of #{}, {:?}", header.number(), hash);
+		trace!(target: "rhd", "max_faulty_of({})={}", n, max_faulty);
 
 		let local_id = self.local_id();
 
 		if !authorities.contains(&local_id) {
 			// cancel current agreement
 			live_agreement.take();
-			Err(ErrorKind::InvalidAuthority(local_id).into())?;
+			Err(CommonErrorKind::InvalidAuthority(local_id).into())?;
 		}
 
-		let (proposer, input, output) = self.factory.init(header, &authorities, self.key.clone())?;
+		let proposer = self.factory.init(header, &authorities, self.key.clone())?;
 
 		let bft_instance = BftInstance {
 			proposer,
@@ -562,9 +602,9 @@ impl<B, P, I> BftService<B, P, I>
 		// fast forward round number if necessary.
 		{
 			let mut cache = self.round_cache.lock();
-			trace!(target: "bft", "Round cache: {:?}", &*cache);
+			trace!(target: "rhd", "Round cache: {:?}", &*cache);
 			if cache.hash.as_ref() == Some(&hash) {
-				trace!(target: "bft", "Fast-forwarding to round {}", cache.start_round);
+				trace!(target: "rhd", "Fast-forwarding to round {}", cache.start_round);
 				let start_round = cache.start_round;
 				cache.start_round += 1;
 
@@ -620,6 +660,103 @@ impl<B, P, I> BftService<B, P, I>
 	}
 }
 
+/// Stream that decodes rhododendron messages and checks signatures.
+///
+/// This stream is localized to a specific parent block-hash, as all messages
+/// will be signed in a way that accounts for it. When using this with
+/// `BftService::build_upon`, the user should take care to use the same hash as for that.
+pub struct CheckedStream<B: Block, S> {
+	inner: S,
+	local_id: AuthorityId,
+	authorities: Vec<AuthorityId>,
+	parent_hash: B::Hash,
+}
+
+impl<B: Block, S> CheckedStream<B, S> {
+	/// Construct a new checked stream.
+	pub fn new(
+		inner: S,
+		local_id: AuthorityId,
+		authorities: Vec<AuthorityId>,
+		parent_hash: B::Hash,
+	) -> Self {
+		CheckedStream {
+			inner,
+			local_id,
+			authorities,
+			parent_hash,
+		}
+	}
+}
+
+impl<B: Block, S: Stream<Item=Vec<u8>>> Stream for CheckedStream<B, S>
+	where S::Error: From<InputStreamConcluded>,
+{
+	type Item = Communication<B>;
+	type Error = S::Error;
+
+	fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
+		use rhododendron::LocalizedMessage as RhdLocalized;
+		loop {
+			match self.inner.poll()? {
+				Async::Ready(Some(item)) => {
+					let comms: Communication<B> = match Decode::decode(&mut &item[..]) {
+						Some(x) => x,
+						None => continue,
+					};
+
+					match comms {
+						RhdCommunication::Auxiliary(prepare_just) => {
+							let checked = check_prepare_justification::<B>(
+								&self.authorities,
+								self.parent_hash,
+								UncheckedJustification(prepare_just.uncheck()),
+							);
+							if let Ok(checked) = checked {
+								return Ok(Async::Ready(
+									Some(RhdCommunication::Auxiliary(checked.0))
+								));
+							}
+						}
+						RhdCommunication::Consensus(RhdLocalized::Propose(p)) => {
+							if p.sender == self.local_id { continue }
+
+							let checked = check_proposal::<B>(
+								&self.authorities,
+								&self.parent_hash,
+								&p,
+							);
+
+							if let Ok(()) = checked {
+								return Ok(Async::Ready(
+									Some(RhdCommunication::Consensus(RhdLocalized::Propose(p)))
+								));
+							}
+						}
+						RhdCommunication::Consensus(RhdLocalized::Vote(v)) => {
+							if v.sender == self.local_id { continue }
+
+							let checked = check_vote::<B>(
+								&self.authorities,
+								&self.parent_hash,
+								&v,
+							);
+
+							if let Ok(()) = checked {
+								return Ok(Async::Ready(
+									Some(RhdCommunication::Consensus(RhdLocalized::Vote(v)))
+								));
+							}
+						}
+					}
+				}
+				Async::Ready(None) => return Ok(Async::Ready(None)),
+				Async::NotReady => return Ok(Async::NotReady),
+			}
+		}
+	}
+}
+
 /// Given a total number of authorities, yield the maximum faulty that would be allowed.
 /// This will always be under 1/3.
 pub fn max_faulty_of(n: usize) -> usize {
@@ -632,7 +769,116 @@ pub fn bft_threshold(n: usize) -> usize {
 	n - max_faulty_of(n)
 }
 
-// /// Sign a BFT message with the given key.
+// actions in the signature scheme.
+#[derive(Encode)]
+enum Action<B, H> {
+	Prepare(u32, H),
+	Commit(u32, H),
+	AdvanceRound(u32),
+	// signatures of header hash and full candidate are both included.
+	ProposeHeader(u32, H),
+	Propose(u32, B),
+}
+
+// encode something in a way which is localized to a specific parent-hash
+fn localized_encode<H: Encode, E: Encode>(parent_hash: H, value: E) -> Vec<u8> {
+	(parent_hash, value).encode()
+}
+
+fn check_justification_signed_message<H>(
+	authorities: &[AuthorityId],
+	message: &[u8],
+	just: UncheckedJustification<H>)
+-> Result<RhdJustification<H>, UncheckedJustification<H>> {
+	// additional error information could be useful here.
+	just.0.check(authorities.len() - max_faulty_of(authorities.len()), |_, _, sig| {
+		let auth_id = sig.signer.clone().into();
+		if !authorities.contains(&auth_id) { return None }
+
+		if ed25519::verify_strong(&sig.signature, message, &sig.signer) {
+			Some(sig.signer.0)
+		} else {
+			None
+		}
+	}).map(RhdJustification).map_err(UncheckedJustification)
+}
+
+/// Check a full justification for a header hash.
+/// Provide all valid authorities.
+///
+/// On failure, returns the justification back.
+pub fn check_justification<B: Block>(
+	authorities: &[AuthorityId],
+	parent: B::Hash,
+	just: UncheckedJustification<B::Hash>
+) -> Result<RhdJustification<B::Hash>, UncheckedJustification<B::Hash>> {
+	let vote: Action<B, B::Hash> = Action::Commit(just.0.round_number as u32, just.0.digest.clone());
+	let message = localized_encode(parent, vote);
+
+	check_justification_signed_message(authorities, &message[..], just)
+}
+
+/// Check a prepare justification for a header hash.
+/// Provide all valid authorities.
+///
+/// On failure, returns the justification back.
+pub fn check_prepare_justification<B: Block>(authorities: &[AuthorityId], parent: B::Hash, just: UncheckedJustification<B::Hash>)
+	-> Result<PrepareJustification<B::Hash>, UncheckedJustification<B::Hash>>
+{
+	let vote: Action<B, B::Hash> = Action::Prepare(just.0.round_number as u32, just.0.digest.clone());
+	let message = localized_encode(parent, vote);
+
+	check_justification_signed_message(authorities, &message[..], just).map(|e| PrepareJustification(e.0))
+}
+
+/// Check proposal message signatures and authority.
+/// Provide all valid authorities.
+pub fn check_proposal<B: Block + Clone>(
+	authorities: &[AuthorityId],
+	parent_hash: &B::Hash,
+	propose: &rhododendron::LocalizedProposal<B, B::Hash, AuthorityId, LocalizedSignature>)
+	-> Result<(), Error>
+{
+	if !authorities.contains(&propose.sender) {
+		return Err(CommonErrorKind::InvalidAuthority(propose.sender.into()).into());
+	}
+
+	let action_header = Action::ProposeHeader(propose.round_number as u32, propose.digest.clone());
+	let action_propose = Action::Propose(propose.round_number as u32, propose.proposal.clone());
+	check_action::<B>(action_header, parent_hash, &propose.digest_signature)?;
+	check_action::<B>(action_propose, parent_hash, &propose.full_signature)
+}
+
+/// Check vote message signatures and authority.
+/// Provide all valid authorities.
+pub fn check_vote<B: Block>(
+	authorities: &[AuthorityId],
+	parent_hash: &B::Hash,
+	vote: &rhododendron::LocalizedVote<B::Hash, AuthorityId, LocalizedSignature>)
+	-> Result<(), Error>
+{
+	if !authorities.contains(&vote.sender) {
+		return Err(CommonErrorKind::InvalidAuthority(vote.sender.into()).into());
+	}
+
+	let action = match vote.vote {
+		rhododendron::Vote::Prepare(r, ref h) => Action::Prepare(r as u32, h.clone()),
+		rhododendron::Vote::Commit(r, ref h) => Action::Commit(r as u32, h.clone()),
+		rhododendron::Vote::AdvanceRound(r) => Action::AdvanceRound(r as u32),
+	};
+	check_action::<B>(action, parent_hash, &vote.signature)
+}
+
+fn check_action<B: Block>(action: Action<B, B::Hash>, parent_hash: &B::Hash, sig: &LocalizedSignature) -> Result<(), Error> {
+	let message = localized_encode(*parent_hash, action);
+	if ed25519::verify_strong(&sig.signature, &message, &sig.signer) {
+		Ok(())
+	} else {
+		Err(CommonErrorKind::InvalidSignature(sig.signature.into(), sig.signer.clone().into()).into())
+	}
+}
+
+/// Sign a BFT message with the given key.
 pub fn sign_message<B: Block + Clone>(
 	message: RhdMessage<B, B::Hash>,
 	key: &ed25519::Pair,
@@ -640,13 +886,9 @@ pub fn sign_message<B: Block + Clone>(
 ) -> LocalizedMessage<B> {
 	let signer = key.public();
 
-	let sign_action = |action: ::rhododendron::Vote<B>| {
-		let primitive = ::rhododendron::LocalizedVote {
-			parent: parent_hash.clone(),
-			action,
-		};
+	let sign_action = |action: Action<B, B::Hash>| {
+		let to_sign = localized_encode(parent_hash.clone(), action);
 
-		let to_sign = Encode::encode(&primitive);
 		LocalizedSignature {
 			signer: signer.clone(),
 			signature: key.sign(&to_sign),
@@ -656,10 +898,10 @@ pub fn sign_message<B: Block + Clone>(
 	match message {
 		RhdMessage::Propose(r, proposal) => {
 			let header_hash = proposal.hash();
-			let action_header = ::rhododendron::ProposeHeader(r as u32, header_hash.clone());
-			let action_propose = ::rhododendron::Propose(r as u32, proposal.clone());
+			let action_header = Action::ProposeHeader(r as u32, header_hash.clone());
+			let action_propose = Action::Propose(r as u32, proposal.clone());
 
-			::rhododendron::LocalizedMessage::Propose(::rhododendron::LocalizedProposal {
+			rhododendron::LocalizedMessage::Propose(rhododendron::LocalizedProposal {
 				round_number: r,
 				proposal,
 				digest: header_hash,
@@ -668,20 +910,443 @@ pub fn sign_message<B: Block + Clone>(
 				full_signature: sign_action(action_propose),
 			})
 		}
-		RhdMessage::Vote(vote) => ::rhododendron::LocalizedMessage::Vote(
-			::rhododendron::LocalizedVote {
+		RhdMessage::Vote(vote) => rhododendron::LocalizedMessage::Vote({
+			let action = match vote {
+				RhdMessageVote::Prepare(r, h) => Action::Prepare(r as u32, h),
+				RhdMessageVote::Commit(r, h) => Action::Commit(r as u32, h),
+				RhdMessageVote::AdvanceRound(r) => Action::AdvanceRound(r as u32),
+			};
+
+			rhododendron::LocalizedVote {
 				vote: vote,
 				sender: signer.clone().into(),
 				signature: sign_action(action),
 			}
-		)
+		})
+	}
+}
+
+
+impl<'a, B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where
+	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
+	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
+	Block: BlockT
+{
+	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<(), Error> {
+		client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into)
+	}
+}
+
+impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
+	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
+	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
+	Block: BlockT,
+{
+	type Block = Block;
+	type Error = client::error::Error;
+
+	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
+		&self,
+		at: &BlockId<Self::Block>,
+		inherent_data: InherentData,
+		mut build_ctx: F,
+	) -> Result<Self::Block, Error> {
+		let runtime_version = self.runtime_version_at(at)?;
+
+		let mut block_builder = self.new_block_at(at)?;
+		if runtime_version.has_api(*b"blkbuild", 1) {
+			for inherent in self.inherent_extrinsics(at, &inherent_data)? {
+				block_builder.push(inherent)?;
+			}
+		}
+
+		build_ctx(&mut block_builder);
+
+		block_builder.bake().map_err(Into::into)
+	}
+}
+
+
+/// Proposer factory.
+pub struct ProposerFactory<N, C, A> where
+	C: AuthoringApi,
+	A: txpool::ChainApi,
+{
+	/// The client instance.
+	pub client: Arc<C>,
+	/// The transaction pool.
+	pub transaction_pool: Arc<TransactionPool<A>>,
+	/// The backing network handle.
+	pub network: N,
+	/// handle to remote task executor
+	pub handle: TaskExecutor,
+	/// Offline-tracker.
+	pub offline: SharedOfflineTracker,
+	/// Force delay in evaluation this long.
+	pub force_delay: u64,
+}
+
+impl<N, C, A> consensus::Environment<<C as AuthoringApi>::Block> for ProposerFactory<N, C, A> where
+	N: Network<Block=<C as AuthoringApi>::Block>,
+	C: AuthoringApi + BlockNumberToHash,
+	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
+	// <<C as AuthoringApi>::Block as BlockT>::Hash:
+		// Into<<Runtime as SystemT>::Hash> + PartialEq<primitives::H256> + Into<primitives::H256>,
+	Error: From<<C as AuthoringApi>::Error>
+{
+	type Proposer = Proposer<C, A>;
+	type Error = Error;
+
+	fn init(
+		&self,
+		parent_header: &<<C as AuthoringApi>::Block as BlockT>::Header,
+		authorities: &[AuthorityId],
+		sign_with: Arc<ed25519::Pair>,
+	) -> Result<Self::Proposer, Error> {
+		use runtime_primitives::traits::Hash as HashT;
+		let parent_hash = parent_header.hash();
+
+		let id = BlockId::hash(parent_hash);
+		let random_seed = self.client.random_seed(&id)?;
+		let random_seed = <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Hashing::hash(random_seed.as_ref());
+
+		let validators = self.client.validators(&id)?;
+		self.offline.write().note_new_block(&validators[..]);
+
+		info!("Starting consensus session on top of parent {:?}", parent_hash);
+
+		let local_id = sign_with.public().0.into();
+		let (input, output) = self.network.communication_for(
+			authorities,
+			local_id,
+			parent_hash.clone(),
+			self.handle.clone(),
+		);
+		let now = Instant::now();
+		let proposer = Proposer {
+			client: self.client.clone(),
+			start: now,
+			local_key: sign_with,
+			parent_hash,
+			parent_id: id,
+			parent_number: *parent_header.number(),
+			random_seed,
+			transaction_pool: self.transaction_pool.clone(),
+			offline: self.offline.clone(),
+			validators,
+			minimum_timestamp: current_timestamp() + self.force_delay,
+			network: self.network.clone()
+		};
+
+		Ok(proposer)
 	}
 }
 
+/// The proposer logic.
+pub struct Proposer<C: AuthoringApi, A: txpool::ChainApi, N: Network> {
+	client: Arc<C>,
+	start: Instant,
+	local_key: Arc<ed25519::Pair>,
+	parent_hash: <<C as AuthoringApi>::Block as BlockT>::Hash,
+	parent_id: BlockId<<C as AuthoringApi>::Block>,
+	parent_number: <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Number,
+	random_seed: <<C as AuthoringApi>::Block as BlockT>::Hash,
+	transaction_pool: Arc<TransactionPool<A>>,
+	offline: SharedOfflineTracker,
+	validators: Vec<AuthorityId>,
+	minimum_timestamp: u64,
+	network: N,
+}
+
+impl<C: AuthoringApi, A: txpool::ChainApi> Proposer<C, A> {
+	fn primary_index(&self, round_number: u32, len: usize) -> usize {
+		use primitives::uint::U256;
+
+		let big_len = U256::from(len);
+		let offset = U256::from_big_endian(self.random_seed.as_ref()) % big_len;
+		let offset = offset.low_u64() as usize + round_number as usize;
+		offset % len
+	}
+}
+
+impl<C, A> BaseProposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
+	C: AuthoringApi + BlockNumberToHash,
+	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
+	<<C as AuthoringApi>::Block as BlockT>::Hash:
+		Into<<Runtime as SystemT>::Hash> + PartialEq<primitives::H256> + Into<primitives::H256>,
+	error::Error: From<<C as AuthoringApi>::Error>
+{
+	type Create = Result<<C as AuthoringApi>::Block, Error>;
+	type Error = Error;
+	type Evaluate = Box<Future<Item=bool, Error=Error>>;
+
+	fn propose(&self) -> Self::Create {
+		use runtime_primitives::traits::BlakeTwo256;
+
+		const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60);
+
+		let timestamp = ::std::cmp::max(self.minimum_timestamp, current_timestamp());
+
+		let elapsed_since_start = self.start.elapsed();
+		let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS {
+			Vec::new()
+		} else {
+			self.offline.read().reports(&self.validators[..])
+		};
+
+		if !offline_indices.is_empty() {
+			info!(
+				"Submitting offline validators {:?} for slash-vote",
+				offline_indices.iter().map(|&i| self.validators[i as usize]).collect::<Vec<_>>(),
+				)
+		}
+
+		let inherent_data = InherentData {
+			timestamp,
+			offline_indices,
+		};
+
+		let block = self.client.build_block(
+			&self.parent_id,
+			inherent_data,
+			|block_builder| {
+				let mut unqueue_invalid = Vec::new();
+				self.transaction_pool.ready(|pending_iterator| {
+					let mut pending_size = 0;
+					for pending in pending_iterator {
+						// TODO [ToDr] Probably get rid of it, and validate in runtime.
+						let encoded_size = pending.data.encode().len();
+						if pending_size + encoded_size >= MAX_TRANSACTIONS_SIZE { break }
+
+						match block_builder.push_extrinsic(pending.data.clone()) {
+							Ok(()) => {
+								pending_size += encoded_size;
+							}
+							Err(e) => {
+								trace!(target: "transaction-pool", "Invalid transaction: {}", e);
+								unqueue_invalid.push(pending.hash.clone());
+							}
+						}
+					}
+				});
+
+				self.transaction_pool.remove_invalid(&unqueue_invalid);
+			})?;
+
+		info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
+			block.header().number(),
+			<<C as AuthoringApi>::Block as BlockT>::Hash::from(block.header().hash()),
+			block.header().parent_hash(),
+			block.extrinsics().iter()
+			.map(|xt| format!("{}", BlakeTwo256::hash_of(xt)))
+			.collect::<Vec<_>>()
+			.join(", ")
+		);
+
+		let substrate_block = Decode::decode(&mut block.encode().as_slice())
+			.expect("blocks are defined to serialize to substrate blocks correctly; qed");
+
+		assert!(evaluation::evaluate_initial(
+			&substrate_block,
+			&self.parent_hash,
+			self.parent_number,
+		).is_ok());
+
+		Ok(substrate_block)
+	}
+
+	fn evaluate(&self, unchecked_proposal: &<C as AuthoringApi>::Block) -> Self::Evaluate {
+		debug!(target: "rhd", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash);
+
+		// do initial serialization and structural integrity checks.
+		if let Err(e) = evaluation::evaluate_initial(
+			unchecked_proposal,
+			&self.parent_hash,
+			self.parent_number,
+		) {
+			debug!(target: "rhd", "Invalid proposal: {:?}", e);
+			return Box::new(future::ok(false));
+		};
+
+		let current_timestamp = current_timestamp();
+		let inherent = InherentData::new(
+			current_timestamp,
+			self.offline.read().reports(&self.validators)
+		);
+		let proposed_timestamp = match self.client.check_inherents(
+			&self.parent_id,
+			&unchecked_proposal,
+			&inherent
+		) {
+			Ok(Ok(())) => None,
+			Ok(Err(BlockBuilderError::TimestampInFuture(timestamp))) => Some(timestamp),
+			Ok(Err(e)) => {
+				debug!(target: "rhd", "Invalid proposal (check_inherents): {:?}", e);
+				return Box::new(future::ok(false));
+			},
+			Err(e) => {
+				debug!(target: "rhd", "Could not call into runtime: {:?}", e);
+				return Box::new(future::ok(false));
+			}
+		};
+
+		let vote_delays = {
+
+			// the duration until the given timestamp is current
+			let proposed_timestamp = ::std::cmp::max(self.minimum_timestamp, proposed_timestamp.unwrap_or(0));
+			let timestamp_delay = if proposed_timestamp > current_timestamp {
+				let delay_s = proposed_timestamp - current_timestamp;
+				debug!(target: "rhd", "Delaying evaluation of proposal for {} seconds", delay_s);
+				Some(Instant::now() + Duration::from_secs(delay_s))
+			} else {
+				None
+			};
+
+			match timestamp_delay {
+				Some(duration) => future::Either::A(
+					Delay::new(duration).map_err(|e| ErrorKind::Timer(e).into())
+				),
+				None => future::Either::B(future::ok(())),
+			}
+		};
+
+		// evaluate whether the block is actually valid.
+		// it may be better to delay this until the delays are finished
+		let evaluated = match self.client.execute_block(&self.parent_id, &unchecked_proposal.clone())
+				.map_err(Error::from) {
+			Ok(()) => Ok(true),
+			Err(err) => match err.kind() {
+				error::ErrorKind::Client(client::error::ErrorKind::Execution(_)) => Ok(false),
+				_ => Err(err)
+			}
+		};
+
+		let future = future::result(evaluated).and_then(move |good| {
+			let end_result = future::ok(good);
+			if good {
+				// delay a "good" vote.
+				future::Either::A(vote_delays.and_then(|_| end_result))
+			} else {
+				// don't delay a "bad" evaluation.
+				future::Either::B(end_result)
+			}
+		});
+
+		Box::new(future) as Box<_>
+	}
+}
+
+impl<C, A> LocalProposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
+	C: AuthoringApi + BlockNumberToHash,
+	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
+	Self: BaseProposer<<C as AuthoringApi>::Block, Error=Error>,
+	<<C as AuthoringApi>::Block as BlockT>::Hash:
+		Into<<Runtime as SystemT>::Hash> + PartialEq<primitives::H256> + Into<primitives::H256>,
+	error::Error: From<<C as AuthoringApi>::Error>
+{
+
+	fn round_proposer(&self, round_number: u32, authorities: &[AuthorityId]) -> AuthorityId {
+		let offset = self.primary_index(round_number, authorities.len());
+		let proposer = authorities[offset as usize].clone();
+		trace!(target: "rhd", "proposer for round {} is {}", round_number, proposer);
+
+		proposer
+	}
+
+	fn import_misbehavior(&self, _misbehavior: Vec<(AuthorityId, Misbehavior<<<C as AuthoringApi>::Block as BlockT>::Hash>)>) {
+		use rhododendron::Misbehavior as GenericMisbehavior;
+		use runtime_primitives::bft::{MisbehaviorKind, MisbehaviorReport};
+		use node_runtime::{Call, UncheckedExtrinsic, ConsensusCall};
+
+		let mut next_index = {
+			let local_id = self.local_key.public().0;
+			let cur_index = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending| pending
+				.filter(|tx| tx.verified.sender == local_id)
+				.last()
+				.map(|tx| Ok(tx.verified.index()))
+				.unwrap_or_else(|| self.client.account_nonce(&self.parent_id, local_id))
+				.map_err(Error::from)
+			);
+
+			match cur_index {
+				Ok(cur_index) => cur_index + 1,
+				Err(e) => {
+					warn!(target: "consensus", "Error computing next transaction index: {:?}", e);
+					return;
+				}
+			}
+		};
+
+		for (target, misbehavior) in misbehavior {
+			let report = MisbehaviorReport {
+				parent_hash: self.parent_hash.into(),
+				parent_number: self.parent_number.as_(),
+				target,
+				misbehavior: match misbehavior {
+					GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue,
+					GenericMisbehavior::DoublePropose(_, _, _) => continue,
+					GenericMisbehavior::DoublePrepare(round, (h1, s1), (h2, s2))
+						=> MisbehaviorKind::BftDoublePrepare(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)),
+					GenericMisbehavior::DoubleCommit(round, (h1, s1), (h2, s2))
+						=> MisbehaviorKind::BftDoubleCommit(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)),
+				}
+			};
+			let payload = (
+				next_index,
+				Call::Consensus(ConsensusCall::report_misbehavior(report)),
+				Era::immortal(),
+				self.client.genesis_hash()
+			);
+			let signature = self.local_key.sign(&payload.encode()).into();
+			next_index += 1;
+
+			let local_id = self.local_key.public().0.into();
+			let extrinsic = UncheckedExtrinsic {
+				signature: Some((node_runtime::RawAddress::Id(local_id), signature, payload.0, Era::immortal())),
+				function: payload.1,
+			};
+			let uxt: <<C as AuthoringApi>::Block as BlockT>::Extrinsic = Decode::decode(
+				&mut extrinsic.encode().as_slice()).expect("Encoded extrinsic is valid");
+			let hash = BlockId::<<C as AuthoringApi>::Block>::hash(self.parent_hash);
+			if let Err(e) = self.transaction_pool.submit_one(&hash, uxt) {
+				warn!("Error importing misbehavior report: {:?}", e);
+			}
+		}
+	}
+
+	fn on_round_end(&self, round_number: u32, was_proposed: bool) {
+		let primary_validator = self.validators[
+			self.primary_index(round_number, self.validators.len())
+		];
+
+		// alter the message based on whether we think the empty proposer was forced to skip the round.
+		// this is determined by checking if our local validator would have been forced to skip the round.
+		if !was_proposed {
+			let public = ed25519::Public::from_raw(primary_validator.0);
+			info!(
+				"Potential Offline Validator: {} failed to propose during assigned slot: {}",
+				public,
+				round_number,
+			);
+		}
+
+		self.offline.write().note_round_end(primary_validator, was_proposed);
+	}
+}
+
+fn current_timestamp() -> u64 {
+	time::SystemTime::now().duration_since(time::UNIX_EPOCH)
+		.expect("now always later than unix epoch; qed")
+		.as_secs()
+}
+
+
 #[cfg(test)]
 mod tests {
 	use super::*;
 	use std::collections::HashSet;
+	use std::marker::PhantomData;
+
 	use runtime_primitives::testing::{Block as GenericTestBlock, Header as TestHeader};
 	use primitives::H256;
 	use self::keyring::Keyring;
@@ -696,14 +1361,21 @@ mod tests {
 	}
 
 	impl BlockImport<TestBlock> for FakeClient {
-		fn import_block(&self, block: TestBlock, _justification: Justification, _authorities: &[AuthorityId]) -> bool {
+		type Error = Error;
+
+		fn import_block(&self,
+			block: ImportBlock<TestBlock>,
+			_new_authorities: Option<Vec<AuthorityId>>
+		) -> Result<ImportResult, Self::Error> {
 			assert!(self.imported_heights.lock().insert(block.header.number));
-			true
+			Ok(ImportResult::Queued)
 		}
 	}
 
 	impl Authorities<TestBlock> for FakeClient {
-		fn authorities(&self, _at: &BlockId<TestBlock>) -> Result<Vec<AuthorityId>, Error> {
+		type Error = Error;
+
+		fn authorities(&self, _at: &BlockId<TestBlock>) -> Result<Vec<AuthorityId>, Self::Error> {
 			Ok(self.authorities.clone())
 		}
 	}
@@ -738,18 +1410,16 @@ mod tests {
 
 	impl Environment<TestBlock> for DummyFactory {
 		type Proposer = DummyProposer;
-		type Input = Comms<Error>;
-		type Output = Comms<Error>;
 		type Error = Error;
 
 		fn init(&self, parent_header: &TestHeader, _authorities: &[AuthorityId], _sign_with: Arc<ed25519::Pair>)
-			-> Result<(DummyProposer, Self::Input, Self::Output), Error>
+			-> Result<DummyProposer, Error>
 		{
-			Ok((DummyProposer(parent_header.number + 1), Comms(::std::marker::PhantomData), Comms(::std::marker::PhantomData)))
+			Ok(DummyProposer(parent_header.number + 1))
 		}
 	}
 
-	impl Proposer<TestBlock> for DummyProposer {
+	impl BaseProposer<TestBlock> for DummyProposer {
 		type Error = Error;
 		type Create = Result<TestBlock, Error>;
 		type Evaluate = Result<bool, Error>;
@@ -765,11 +1435,13 @@ mod tests {
 		fn evaluate(&self, proposal: &TestBlock) -> Result<bool, Error> {
 			Ok(proposal.header.number == self.0)
 		}
+	}
 
+	impl LocalProposer<TestBlock> for DummyProposer {
 		fn import_misbehavior(&self, _misbehavior: Vec<(AuthorityId, Misbehavior<H256>)>) {}
 
-		fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId {
-			authorities[round_number % authorities.len()].clone()
+		fn round_proposer(&self, round_number: u32, authorities: &[AuthorityId]) -> AuthorityId {
+			authorities[(round_number as usize) % authorities.len()].clone()
 		}
 	}
 
@@ -789,9 +1461,9 @@ mod tests {
 		}
 	}
 
-	fn sign_vote(vote: ::rhododendron::Vote<H256>, key: &ed25519::Pair, parent_hash: H256) -> LocalizedSignature {
+	fn sign_vote(vote: rhododendron::Vote<H256>, key: &ed25519::Pair, parent_hash: H256) -> LocalizedSignature {
 		match sign_message::<TestBlock>(vote.into(), key, parent_hash) {
-			::rhododendron::LocalizedMessage::Vote(vote) => vote.signature,
+			rhododendron::LocalizedMessage::Vote(vote) => vote.signature,
 			_ => panic!("signing vote leads to signed vote"),
 		}
 	}
@@ -827,10 +1499,10 @@ mod tests {
 		second.parent_hash = first_hash;
 		let _second_hash = second.hash();
 
-		let mut first_bft = service.build_upon(&first).unwrap().unwrap();
+		let mut first_bft = service.build_upon(&first, Comms(PhantomData), Comms(PhantomData)).unwrap().unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == first);
 
-		let _second_bft = service.build_upon(&second).unwrap();
+		let _second_bft = service.build_upon(&second, Comms(PhantomData), Comms(PhantomData)).unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 != first);
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == second);
 
@@ -927,8 +1599,8 @@ mod tests {
 			extrinsics: Default::default()
 		};
 
-		let proposal = sign_message(::rhododendron::Message::Propose(1, block.clone()), &Keyring::Alice.pair(), parent_hash);;
-		if let ::rhododendron::LocalizedMessage::Propose(proposal) = proposal {
+		let proposal = sign_message(rhododendron::Message::Propose(1, block.clone()), &Keyring::Alice.pair(), parent_hash);;
+		if let rhododendron::LocalizedMessage::Propose(proposal) = proposal {
 			assert!(check_proposal(&authorities, &parent_hash, &proposal).is_ok());
 			let mut invalid_round = proposal.clone();
 			invalid_round.round_number = 0;
@@ -941,8 +1613,8 @@ mod tests {
 		}
 
 		// Not an authority
-		let proposal = sign_message::<TestBlock>(::rhododendron::Message::Propose(1, block), &Keyring::Bob.pair(), parent_hash);;
-		if let ::rhododendron::LocalizedMessage::Propose(proposal) = proposal {
+		let proposal = sign_message::<TestBlock>(rhododendron::Message::Propose(1, block), &Keyring::Bob.pair(), parent_hash);;
+		if let rhododendron::LocalizedMessage::Propose(proposal) = proposal {
 			assert!(check_proposal(&authorities, &parent_hash, &proposal).is_err());
 		} else {
 			assert!(false);
@@ -959,8 +1631,8 @@ mod tests {
 			Keyring::Eve.to_raw_public().into(),
 		];
 
-		let vote = sign_message::<TestBlock>(::rhododendron::Message::Vote(::rhododendron::Vote::Prepare(1, hash)), &Keyring::Alice.pair(), parent_hash);;
-		if let ::rhododendron::LocalizedMessage::Vote(vote) = vote {
+		let vote = sign_message::<TestBlock>(rhododendron::Message::Vote(rhododendron::Vote::Prepare(1, hash)), &Keyring::Alice.pair(), parent_hash);;
+		if let rhododendron::LocalizedMessage::Vote(vote) = vote {
 			assert!(check_vote::<TestBlock>(&authorities, &parent_hash, &vote).is_ok());
 			let mut invalid_sender = vote.clone();
 			invalid_sender.signature.signer = Keyring::Eve.into();
@@ -970,8 +1642,8 @@ mod tests {
 		}
 
 		// Not an authority
-		let vote = sign_message::<TestBlock>(::rhododendron::Message::Vote(::rhododendron::Vote::Prepare(1, hash)), &Keyring::Bob.pair(), parent_hash);;
-		if let ::rhododendron::LocalizedMessage::Vote(vote) = vote {
+		let vote = sign_message::<TestBlock>(rhododendron::Message::Vote(rhododendron::Vote::Prepare(1, hash)), &Keyring::Bob.pair(), parent_hash);;
+		if let rhododendron::LocalizedMessage::Vote(vote) = vote {
 			assert!(check_vote::<TestBlock>(&authorities, &parent_hash, &vote).is_err());
 		} else {
 			assert!(false);
@@ -998,7 +1670,7 @@ mod tests {
 		let mut second = from_block_number(3);
 		second.parent_hash = first_hash;
 
-		let _ = service.build_upon(&first).unwrap();
+		let _ = service.build_upon(&first, Comms(PhantomData), Comms(PhantomData)).unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == first);
 		service.live_agreement.lock().take();
 	}
@@ -1026,14 +1698,14 @@ mod tests {
 		let mut third = from_block_number(4);
 		third.parent_hash = second.hash();
 
-		let _ = service.build_upon(&first).unwrap();
+		let _ = service.build_upon(&first, Comms(PhantomData), Comms(PhantomData)).unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == first);
 		// BFT has not seen second, but will move forward on third
-		service.build_upon(&third).unwrap();
+		service.build_upon(&third, Comms(PhantomData), Comms(PhantomData)).unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == third);
 
 		// but we are not walking backwards
-		service.build_upon(&second).unwrap();
+		service.build_upon(&second, Comms(PhantomData), Comms(PhantomData)).unwrap();
 		assert!(service.live_agreement.lock().as_ref().unwrap().0 == third);
 	}
 }
diff --git a/substrate/node/consensus/src/service.rs b/substrate/core/consensus/rhd/src/service.rs
similarity index 89%
rename from substrate/node/consensus/src/service.rs
rename to substrate/core/consensus/rhd/src/service.rs
index f8ebd6f421e543e170ff0f7b9e09a2a80ead901f..34efc942d4dae2a4e77b58d023ea5405be30e0e9 100644
--- a/substrate/node/consensus/src/service.rs
+++ b/substrate/core/consensus/rhd/src/service.rs
@@ -22,12 +22,9 @@ use std::thread;
 use std::time::{Duration, Instant};
 use std::sync::Arc;
 
-use rhd::{self, BftService};
 use client::{BlockchainEvents, ChainHead, BlockBody};
-use ed25519;
 use futures::prelude::*;
 use transaction_pool::txpool::{Pool as TransactionPool, ChainApi as PoolChainApi};
-use primitives;
 use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, BlockNumberToHash};
 
 use tokio::executor::current_thread::TaskExecutor as LocalThreadHandle;
@@ -35,8 +32,11 @@ use tokio::runtime::TaskExecutor as ThreadPoolHandle;
 use tokio::runtime::current_thread::Runtime as LocalRuntime;
 use tokio::timer::Interval;
 
+use parking_lot::RwLock;
+use consensus::offline_tracker::OfflineTracker;
+
 use super::{Network, ProposerFactory, AuthoringApi};
-use error;
+use {consensus, primitives, ed25519, error, BftService, LocalProposer};
 
 const TIMER_DELAY_MS: u64 = 5000;
 const TIMER_INTERVAL_MS: u64 = 500;
@@ -47,11 +47,12 @@ fn start_bft<F, C, Block>(
 	header: <Block as BlockT>::Header,
 	bft_service: Arc<BftService<Block, F, C>>,
 ) where
-	F: rhd::Environment<Block> + 'static,
-	C: rhd::BlockImport<Block> + rhd::Authorities<Block> + 'static,
+	F: consensus::Environment<Block> + 'static,
+	C: consensus::BlockImport<Block> + consensus::Authorities<Block> + 'static,
 	F::Error: ::std::fmt::Debug,
-	<F::Proposer as rhd::Proposer<Block>>::Error: ::std::fmt::Display + Into<error::Error>,
-	<F as rhd::Environment<Block>>::Error: ::std::fmt::Display,
+	<F::Proposer as consensus::Proposer<Block>>::Error: ::std::fmt::Display + Into<error::Error>,
+	<F as consensus::Environment<Block>>::Proposer : LocalProposer<Block>,
+	<F as consensus::Environment<Block>>::Error: ::std::fmt::Display,
 	Block: BlockT,
 {
 	let mut handle = LocalThreadHandle::current();
@@ -88,14 +89,12 @@ impl Service {
 			C: BlockchainEvents<<A as AuthoringApi>::Block>
 				+ ChainHead<<A as AuthoringApi>::Block>
 				+ BlockBody<<A as AuthoringApi>::Block>,
-			C: bft::BlockImport<<A as AuthoringApi>::Block>
-				+ bft::Authorities<<A as AuthoringApi>::Block> + Send + Sync + 'static,
+			C: consensus::BlockImport<<A as AuthoringApi>::Block>
+				+ consensus::Authorities<<A as AuthoringApi>::Block> + Send + Sync + 'static,
 			primitives::H256: From<<<A as AuthoringApi>::Block as BlockT>::Hash>,
 			<<A as AuthoringApi>::Block as BlockT>::Hash: PartialEq<primitives::H256> + PartialEq,
 			N: Network<Block = <A as AuthoringApi>::Block> + Send + 'static,
 	{
-		use parking_lot::RwLock;
-		use super::OfflineTracker;
 
 		let (signal, exit) = ::exit_future::signal();
 		let thread = thread::spawn(move || {
diff --git a/substrate/core/executor/src/lib.rs b/substrate/core/executor/src/lib.rs
index df67db587fe586af42fffa4f8f1948200cbc62bc..64442b7f8e2b6e33e356681afa96fbefbddbf56f 100644
--- a/substrate/core/executor/src/lib.rs
+++ b/substrate/core/executor/src/lib.rs
@@ -24,7 +24,7 @@
 //! - execute_block(bytes)
 //! - init_block(PrevBlock?) -> InProgressBlock
 //! - add_transaction(InProgressBlock) -> InProgressBlock
-//! I leave it as is for now as it might be removed before this is ever done.
+//! It is left as is for now as it might be removed before this is ever done.
 // end::description[]
 
 #![warn(missing_docs)]
diff --git a/substrate/core/executor/src/native_executor.rs b/substrate/core/executor/src/native_executor.rs
index 685aa485728f442e5a5b1a14872f39cd97e83d45..b51b43e14dd1976607b5fc3431ae527cef402fc6 100644
--- a/substrate/core/executor/src/native_executor.rs
+++ b/substrate/core/executor/src/native_executor.rs
@@ -196,13 +196,9 @@ impl<D: NativeExecutionDispatch> CodeExecutor<Blake2Hasher> for NativeExecutor<D
 
 #[macro_export]
 macro_rules! native_executor_instance {
-	(pub $name:ident, $dispatcher:path, $version:path, $code:expr) => {
-		pub struct $name;
-		native_executor_instance!(IMPL $name, $dispatcher, $version, $code);
-	};
-	($name:ident, $dispatcher:path, $version:path, $code:expr) => {
+	( $pub:vis $name:ident, $dispatcher:path, $version:path, $code:expr) => {
 		/// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
-		struct $name;
+		$pub struct $name;
 		native_executor_instance!(IMPL $name, $dispatcher, $version, $code);
 	};
 	(IMPL $name:ident, $dispatcher:path, $version:path, $code:expr) => {
diff --git a/substrate/core/finality-grandpa/README.adoc b/substrate/core/finality-grandpa/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..5338cf9e8cc715c589c2e812a9f65c92426b1eb5
--- /dev/null
+++ b/substrate/core/finality-grandpa/README.adoc
@@ -0,0 +1,12 @@
+= Finality GRANDPA (aka SHAFT)
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/finality-grandpa/src/lib.rs b/substrate/core/finality-grandpa/src/lib.rs
index 8b45ab56411e1a000839d1a107340f900436148c..988a13d74de1677f2a180197834e0be44911c752 100644
--- a/substrate/core/finality-grandpa/src/lib.rs
+++ b/substrate/core/finality-grandpa/src/lib.rs
@@ -14,9 +14,11 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
+// tag::description[]
 //! Integration of the GRANDPA finality gadget into substrate.
 //!
 //! This is a long-running future that produces finality notifications.
+// end::description[]
 
 extern crate finality_grandpa as grandpa;
 extern crate futures;
@@ -45,11 +47,11 @@ use futures::stream::Fuse;
 use futures::sync::mpsc;
 use client::{Client, error::Error as ClientError, ImportNotifications, backend::Backend, CallExecutor};
 use codec::{Encode, Decode};
-use consensus_common::BlockImport;
+use consensus_common::{BlockImport, ImportBlock, ImportResult};
 use runtime_primitives::traits::{
 	NumberFor, Block as BlockT, Header as HeaderT, DigestItemFor,
 };
-use runtime_primitives::{generic::BlockId, Justification};
+use runtime_primitives::generic::BlockId;
 use substrate_primitives::{ed25519, AuthorityId, Blake2Hasher};
 use tokio::timer::Interval;
 
@@ -702,21 +704,24 @@ pub struct GrandpaBlockImport<B, E, Block: BlockT> {
 
 impl<B, E, Block: BlockT> BlockImport<Block> for GrandpaBlockImport<B, E, Block> where
 	B: Backend<Block, Blake2Hasher> + 'static,
-	E: CallExecutor<Block, Blake2Hasher> + 'static,
+	E: CallExecutor<Block, Blake2Hasher> + 'static + Clone,
 	DigestItemFor<Block>: CompatibleDigestItem<NumberFor<Block>>,
 {
-	fn import_block(&self, block: Block, _justification: Justification, _authorities: &[AuthorityId]) -> bool {
+	type Error = ClientError;
+
+	fn import_block(&self, block: ImportBlock<Block>, new_authorities: Option<Vec<AuthorityId>>)
+		-> Result<ImportResult, Self::Error>
+	{
 		use runtime_primitives::traits::Digest;
 		use authorities::PendingChange;
 
-		let maybe_event = block.header().digest().logs().iter()
+		let maybe_event = block.header.digest().logs().iter()
 			.filter_map(|log| log.scheduled_change())
 			.next()
-			.map(|change| (block.header().hash(), *block.header().number(), change));
+			.map(|change| (block.header.hash(), *block.header.number(), change));
 
-		// TODO [now]: use import-block trait for client when implemented
-		let result = self.inner.import_block(unimplemented!(), unimplemented!()).is_ok();
-		if let (true, Some((hash, number, change))) = (result, maybe_event) {
+		let result = self.inner.import_block(block, new_authorities);
+		if let (true, Some((hash, number, change))) = (result.is_ok(), maybe_event) {
 			self.authority_set.add_pending_change(PendingChange {
 				next_authorities: change.next_authorities,
 				finalization_depth: number + change.delay,
@@ -726,6 +731,7 @@ impl<B, E, Block: BlockT> BlockImport<Block> for GrandpaBlockImport<B, E, Block>
 
 			// TODO [now]: write to DB, and what to do on failure?
 		}
+
 		result
 	}
 }
diff --git a/substrate/core/keyring/src/lib.rs b/substrate/core/keyring/src/lib.rs
index 3fab7c576972eb97b85063abcc7f92e28f4e33b2..6ba79d146cd920c79c72410629803206a0e112ad 100644
--- a/substrate/core/keyring/src/lib.rs
+++ b/substrate/core/keyring/src/lib.rs
@@ -15,7 +15,7 @@
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
 // tag::description[]
-//! Support code for the runtime.
+//! Support code for the runtime. A set of test accounts.
 // end::description[]
 
 #[macro_use] extern crate hex_literal;
diff --git a/substrate/core/network/Cargo.toml b/substrate/core/network/Cargo.toml
index db4f6c34e2e13c5e63459f849f5a92ad34e4e04e..7eadefb3637f3ec2607f2534a6ba108e60cc3cdb 100644
--- a/substrate/core/network/Cargo.toml
+++ b/substrate/core/network/Cargo.toml
@@ -17,6 +17,7 @@ linked-hash-map = "0.5"
 rustc-hex = "1.0"
 rand = "0.5"
 substrate-primitives = { path = "../../core/primitives" }
+substrate-consensus-common = { path = "../../core/consensus/common" }
 substrate-client = { path = "../../core/client" }
 sr-primitives = { path = "../../core/sr-primitives" }
 parity-codec = "2.1"
diff --git a/substrate/core/network/src/chain.rs b/substrate/core/network/src/chain.rs
index 97c2322989e66b7a4d8817fcf7f997946d587174..74a01577a75dafb81e57ac772ada2ffc0d27f8bd 100644
--- a/substrate/core/network/src/chain.rs
+++ b/substrate/core/network/src/chain.rs
@@ -16,10 +16,12 @@
 
 //! Blockchain access trait
 
-use client::{self, Client as SubstrateClient, ImportBlock, ImportResult, ClientInfo, BlockStatus, CallExecutor};
+use client::{self, Client as SubstrateClient, ClientInfo, BlockStatus, CallExecutor};
 use client::error::Error;
+use consensus::BlockImport;
 use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor};
-use runtime_primitives::generic::BlockId;
+use runtime_primitives::generic::{BlockId};
+use consensus::{ImportBlock, ImportResult};
 use runtime_primitives::Justification;
 use primitives::{Blake2Hasher, AuthorityId};
 
@@ -69,9 +71,12 @@ pub trait Client<Block: BlockT>: Send + Sync {
 impl<B, E, Block> Client<Block> for SubstrateClient<B, E, Block> where
 	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
 	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
-	Block: BlockT,
+	Self: BlockImport<Block, Error=Error>,
+	Block: BlockT
 {
-	fn import(&self, block: ImportBlock<Block>, new_authorities: Option<Vec<AuthorityId>>) -> Result<ImportResult, Error> {
+	fn import(&self, block: ImportBlock<Block>, new_authorities: Option<Vec<AuthorityId>>)
+		-> Result<ImportResult, Error>
+	{
 		(self as &SubstrateClient<B, E, Block>).import_block(block, new_authorities)
 	}
 
diff --git a/substrate/core/network/src/import_queue.rs b/substrate/core/network/src/import_queue.rs
index 328dc478dc5d097f8796c8daea72dcdd4f8d5fe4..4a6775a2a9def6921e0038d9af9a912200e11da5 100644
--- a/substrate/core/network/src/import_queue.rs
+++ b/substrate/core/network/src/import_queue.rs
@@ -28,8 +28,6 @@ use std::collections::{HashSet, VecDeque};
 use std::sync::{Arc, Weak};
 use std::sync::atomic::{AtomicBool, Ordering};
 use parking_lot::{Condvar, Mutex, RwLock};
-
-pub use client::{BlockOrigin, ImportBlock, ImportResult};
 use network_libp2p::{NodeIndex, Severity};
 use primitives::AuthorityId;
 
@@ -42,6 +40,9 @@ use protocol::Context;
 use service::ExecuteInContext;
 use sync::ChainSync;
 
+pub use consensus::{ImportBlock, ImportResult, BlockOrigin};
+
+
 #[cfg(any(test, feature = "test-helpers"))]
 use std::cell::RefCell;
 
@@ -428,7 +429,6 @@ fn import_single_block<B: BlockT, V: Verifier<B>>(
 				trace!(target: "sync", "Verifying {}({}) failed: {}", number, hash, msg);
 			}
 			BlockImportError::VerificationFailed(peer, msg)
-
 		})?;
 
 	match chain.import(import_block, new_authorities) {
@@ -552,7 +552,7 @@ impl<B: BlockT> Verifier<B> for PassThroughVerifier {
 			body,
 			finalized: self.0,
 			external_justification: justification,
-			internal_justification: vec![],
+			post_runtime_digests: vec![],
 			auxiliary: Vec::new(),
 		}, None))
 	}
@@ -615,7 +615,6 @@ pub mod tests {
 	use message;
 	use test_client::{self, TestClient};
 	use test_client::runtime::{Block, Hash};
-	use on_demand::tests::DummyExecutor;
 	use runtime_primitives::generic::BlockId;
 	use std::cell::Cell;
 	use super::*;
diff --git a/substrate/core/network/src/lib.rs b/substrate/core/network/src/lib.rs
index 82bdf0a877d62870f5727ffa935b49c6b2e7b00c..4a441dcc6fed0f84dd3dc0570005ae5b88f1d8de 100644
--- a/substrate/core/network/src/lib.rs
+++ b/substrate/core/network/src/lib.rs
@@ -28,6 +28,7 @@ extern crate substrate_primitives as primitives;
 extern crate substrate_client as client;
 extern crate sr_primitives as runtime_primitives;
 extern crate substrate_network_libp2p as network_libp2p;
+extern crate substrate_consensus_common as consensus;
 extern crate parity_codec as codec;
 extern crate futures;
 extern crate rustc_hex;
diff --git a/substrate/core/network/src/protocol.rs b/substrate/core/network/src/protocol.rs
index a8edaaceb670978419cae5b9ec94d81d2fdfe52e..4e98ee8f80f24712176dd9e6035ed826bf1bb3a9 100644
--- a/substrate/core/network/src/protocol.rs
+++ b/substrate/core/network/src/protocol.rs
@@ -776,41 +776,41 @@ macro_rules! construct_simple_protocol {
 
 			fn on_connect(
 				&mut self,
-				ctx: &mut $crate::Context<$block>,
-				who: $crate::NodeIndex,
-				status: $crate::StatusMessage<$block>
+				_ctx: &mut $crate::Context<$block>,
+				_who: $crate::NodeIndex,
+				_status: $crate::StatusMessage<$block>
 			) {
-				$( self.$sub_protocol_name.on_connect(ctx, who, status); )*
+				$( self.$sub_protocol_name.on_connect(_ctx, _who, _status); )*
 			}
 
-			fn on_disconnect(&mut self, ctx: &mut $crate::Context<$block>, who: $crate::NodeIndex) {
-				$( self.$sub_protocol_name.on_disconnect(ctx, who); )*
+			fn on_disconnect(&mut self, _ctx: &mut $crate::Context<$block>, _who: $crate::NodeIndex) {
+				$( self.$sub_protocol_name.on_disconnect(_ctx, _who); )*
 			}
 
 			fn on_message(
 				&mut self,
-				ctx: &mut $crate::Context<$block>,
-				who: $crate::NodeIndex,
-				message: &mut Option<$crate::message::Message<$block>>
+				_ctx: &mut $crate::Context<$block>,
+				_who: $crate::NodeIndex,
+				_message: &mut Option<$crate::message::Message<$block>>
 			) {
-				$( self.$sub_protocol_name.on_message(ctx, who, message); )*
+				$( self.$sub_protocol_name.on_message(_ctx, _who, _message); )*
 			}
 
 			fn on_abort(&mut self) {
 				$( self.$sub_protocol_name.on_abort(); )*
 			}
 
-			fn maintain_peers(&mut self, ctx: &mut $crate::Context<$block>) {
-				$( self.$sub_protocol_name.maintain_peers(ctx); )*
+			fn maintain_peers(&mut self, _ctx: &mut $crate::Context<$block>) {
+				$( self.$sub_protocol_name.maintain_peers(_ctx); )*
 			}
 
 			fn on_block_imported(
 				&mut self,
-				ctx: &mut $crate::Context<$block>,
-				hash: <$block as $crate::BlockT>::Hash,
-				header: &<$block as $crate::BlockT>::Header
+				_ctx: &mut $crate::Context<$block>,
+				_hash: <$block as $crate::BlockT>::Hash,
+				_header: &<$block as $crate::BlockT>::Header
 			) {
-				$( self.$sub_protocol_name.on_block_imported(ctx, hash, header); )*
+				$( self.$sub_protocol_name.on_block_imported(_ctx, _hash, _header); )*
 			}
 		}
 	}
diff --git a/substrate/core/network/src/service.rs b/substrate/core/network/src/service.rs
index 52db914d6ea0b96cc795b6e011a79b2e9f400dc5..0e46f50998b2331c7cd905e98b9538309b54b480 100644
--- a/substrate/core/network/src/service.rs
+++ b/substrate/core/network/src/service.rs
@@ -181,6 +181,12 @@ impl<B: BlockT + 'static, S: Specialization<B>, H: ExHashT> Service<B, S, H> {
 	}
 }
 
+impl<B: BlockT + 'static, S: Specialization<B>, H: ExHashT> ::consensus::SyncOracle for Service<B, S, H> {
+	fn is_major_syncing(&self) -> bool {
+		self.handler.sync().read().status().is_major_syncing()
+	}
+}
+
 impl<B: BlockT + 'static, S: Specialization<B>, H:ExHashT> Drop for Service<B, S, H> {
 	fn drop(&mut self) {
 		self.handler.stop();
diff --git a/substrate/core/network/src/specialization.rs b/substrate/core/network/src/specialization.rs
index ccd1071adb4cef806ca97a1d307a795fe7be8a4e..70ad9e9b2e655fd88d9d585ac15eaed29834d643 100644
--- a/substrate/core/network/src/specialization.rs
+++ b/substrate/core/network/src/specialization.rs
@@ -25,9 +25,6 @@ pub trait Specialization<B: BlockT>: Send + Sync + 'static {
 	/// Get the current specialization-status.
 	fn status(&self) -> Vec<u8>;
 
-	/// Called on start-up.
-	fn on_start(&mut self) { }
-
 	/// Called when a peer successfully handshakes.
 	fn on_connect(&mut self, ctx: &mut Context<B>, who: NodeIndex, status: ::message::Status<B>);
 
diff --git a/substrate/core/network/src/sync.rs b/substrate/core/network/src/sync.rs
index b758b8f205b43faf445aa3ecfe2ef1df1d05baa3..e69b22fc578f148ebf2c936b602d38e65506e282 100644
--- a/substrate/core/network/src/sync.rs
+++ b/substrate/core/network/src/sync.rs
@@ -18,7 +18,8 @@ use std::collections::HashMap;
 use std::sync::Arc;
 use protocol::Context;
 use network_libp2p::{Severity, NodeIndex};
-use client::{BlockStatus, BlockOrigin, ClientInfo};
+use client::{BlockStatus, ClientInfo};
+use consensus::BlockOrigin;
 use client::error::Error as ClientError;
 use blocks::{self, BlockCollection};
 use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor};
@@ -77,6 +78,17 @@ pub struct Status<B: BlockT> {
 	pub best_seen_block: Option<NumberFor<B>>,
 }
 
+impl<B: BlockT> Status<B> {
+	/// Whether the synchronization status is doing major downloading work or
+	/// is near the head of the chain.
+	pub fn is_major_syncing(&self) -> bool {
+		match self.state {
+			SyncState::Idle => false,
+			SyncState::Downloading => true,
+		}
+	}
+}
+
 impl<B: BlockT> ChainSync<B> {
 	/// Create a new instance.
 	pub(crate) fn new(role: Roles, info: &ClientInfo<B>, import_queue: Arc<ImportQueue<B>>) -> Self {
diff --git a/substrate/core/network/src/test/mod.rs b/substrate/core/network/src/test/mod.rs
index 50e644c2612175e49de290556678a66938aa55d5..34eb873cc640e8a452c800351d8671f5a9d9d256 100644
--- a/substrate/core/network/src/test/mod.rs
+++ b/substrate/core/network/src/test/mod.rs
@@ -34,14 +34,16 @@ use service::TransactionPool;
 use network_libp2p::{NodeIndex, PeerId, Severity};
 use keyring::Keyring;
 use codec::Encode;
-use import_queue::{SyncImportQueue, PassThroughVerifier};
-use test_client::{self, TestClient};
+use import_queue::{SyncImportQueue, PassThroughVerifier, Verifier};
+use consensus::BlockOrigin;
 use specialization::Specialization;
 use consensus_gossip::ConsensusGossip;
 use import_queue::ImportQueue;
 use service::ExecuteInContext;
+use test_client;
 
 pub use test_client::runtime::{Block, Hash, Transfer, Extrinsic};
+pub use test_client::TestClient;
 
 struct DummyContextExecutor(Arc<Protocol<Block, DummySpecialization, Hash>>, Arc<RwLock<VecDeque<TestPacket>>>);
 unsafe impl Send for DummyContextExecutor {}
@@ -135,20 +137,22 @@ pub struct TestPacket {
 	recipient: NodeIndex,
 }
 
-pub struct Peer {
-	client: Arc<client::Client<test_client::Backend, test_client::Executor, Block>>,
+pub type PeersClient = client::Client<test_client::Backend, test_client::Executor, Block>;
+
+pub struct Peer<V: Verifier<Block>> {
+	client: Arc<PeersClient>,
 	pub sync: Arc<Protocol<Block, DummySpecialization, Hash>>,
 	pub queue: Arc<RwLock<VecDeque<TestPacket>>>,
-	import_queue: Arc<SyncImportQueue<Block, PassThroughVerifier>>,
+	import_queue: Arc<SyncImportQueue<Block, V>>,
 	executor: Arc<DummyContextExecutor>,
 }
 
-impl Peer {
+impl<V: 'static + Verifier<Block>> Peer<V> {
 	fn new(
-		client: Arc<client::Client<test_client::Backend, test_client::Executor, Block>>,
+		client: Arc<PeersClient>,
 		sync: Arc<Protocol<Block, DummySpecialization, Hash>>,
 		queue: Arc<RwLock<VecDeque<TestPacket>>>,
-		import_queue: Arc<SyncImportQueue<Block, PassThroughVerifier>>,
+		import_queue: Arc<SyncImportQueue<Block, V>>,
 	) -> Self {
 		let executor = Arc::new(DummyContextExecutor(sync.clone(), queue.clone()));
 		Peer { client, sync, queue, import_queue, executor}
@@ -204,6 +208,13 @@ impl Peer {
 		self.sync.tick(&mut TestIo::new(&self.queue, None));
 	}
 
+	/// Send block import notifications.
+	fn send_import_notifications(&self) {
+		let info = self.client.info().expect("In-mem client does not fail");
+		let header = self.client.header(&BlockId::Hash(info.chain.best_hash)).unwrap().unwrap();
+		self.sync.on_block_imported(&mut TestIo::new(&self.queue, None), info.chain.best_hash, &header);
+	}
+
 	/// Restart sync for a peer.
 	fn restart_sync(&self) {
 		self.sync.abort();
@@ -221,15 +232,18 @@ impl Peer {
 	}
 
 	/// Add blocks to the peer -- edit the block before adding
-	pub fn generate_blocks<F>(&self, count: usize, mut edit_block: F)
+	pub fn generate_blocks<F>(&self, count: usize, origin: BlockOrigin, mut edit_block: F)
 	where F: FnMut(&mut BlockBuilder<test_client::Backend, test_client::Executor, Block, Blake2Hasher>)
 	{
 		for _ in 0 .. count {
 			let mut builder = self.client.new_block().unwrap();
 			edit_block(&mut builder);
 			let block = builder.bake().unwrap();
-			trace!("Generating {}, (#{}, parent={})", block.header.hash(), block.header.number, block.header.parent_hash);
-			self.client.justify_and_import(client::BlockOrigin::File, block).unwrap();
+			let hash = block.header.hash();
+			trace!("Generating {}, (#{}, parent={})", hash, block.header.number, block.header.parent_hash);
+			let header = block.header.clone();
+			self.client.justify_and_import(origin, block).unwrap();
+			self.sync.on_block_imported(&mut TestIo::new(&self.queue, None), hash, &header);
 		}
 	}
 
@@ -237,7 +251,7 @@ impl Peer {
 	pub fn push_blocks(&self, count: usize, with_tx: bool) {
 		let mut nonce = 0;
 		if with_tx {
-			self.generate_blocks(count, |builder| {
+			self.generate_blocks(count, BlockOrigin::File, |builder| {
 				let transfer = Transfer {
 					from: Keyring::Alice.to_raw_public().into(),
 					to: Keyring::Alice.to_raw_public().into(),
@@ -249,7 +263,7 @@ impl Peer {
 				nonce = nonce + 1;
 			});
 		} else {
-			self.generate_blocks(count, |_| ());
+			self.generate_blocks(count, BlockOrigin::File, |_| ());
 		}
 	}
 
@@ -261,7 +275,7 @@ impl Peer {
 	}
 
 	/// Get a reference to the client.
-	pub fn client(&self) -> &Arc<client::Client<test_client::Backend, test_client::Executor, Block>> {
+	pub fn client(&self) -> &Arc<PeersClient> {
 		&self.client
 	}
 }
@@ -280,25 +294,30 @@ impl TransactionPool<Hash, Block> for EmptyTransactionPool {
 	fn on_broadcasted(&self, _: HashMap<Hash, Vec<String>>) {}
 }
 
-pub struct TestNet {
-	peers: Vec<Arc<Peer>>,
-	started: bool,
-	disconnect_events: Vec<(NodeIndex, NodeIndex)>, //disconnected (initiated by, to)
-}
+pub trait TestNetFactory: Sized {
+	type Verifier: 'static + Verifier<Block>;
 
-impl TestNet {
-	/// Create new test network with this many peers.
-	pub fn new(n: usize) -> Self {
-		Self::new_with_config(n, ProtocolConfig::default())
+	/// These two need to be implemented!
+	fn from_config(config: &ProtocolConfig) -> Self;
+	fn make_verifier(&self, client: Arc<PeersClient>, config: &ProtocolConfig) -> Arc<Self::Verifier>;
+
+
+	/// Get reference to peer.
+	fn peer(&self, i: usize) -> &Peer<Self::Verifier>;
+	fn peers(&self) -> &Vec<Arc<Peer<Self::Verifier>>>;
+	fn mut_peers<F: Fn(&mut Vec<Arc<Peer<Self::Verifier>>>)>(&mut self, closure: F );
+
+	fn started(&self) -> bool;
+	fn set_started(&mut self, now: bool); 
+
+	fn default_config() -> ProtocolConfig {
+		ProtocolConfig::default()
 	}
 
-	/// Create new test network with peers and given config.
-	pub fn new_with_config(n: usize, config: ProtocolConfig) -> Self {
-		let mut net = TestNet {
-			peers: Vec::new(),
-			started: false,
-			disconnect_events: Vec::new(),
-		};
+	/// Create new test network with this many peers.
+	fn new(n: usize) -> Self {
+		let config = Self::default_config();
+		let mut net = Self::from_config(&config);
 
 		for _ in 0..n {
 			net.add_peer(&config);
@@ -307,10 +326,11 @@ impl TestNet {
 	}
 
 	/// Add a peer.
-	pub fn add_peer(&mut self, config: &ProtocolConfig) {
+	fn add_peer(&mut self, config: &ProtocolConfig) {
 		let client = Arc::new(test_client::new());
 		let tx_pool = Arc::new(EmptyTransactionPool);
-		let import_queue = Arc::new(SyncImportQueue::new(Arc::new(PassThroughVerifier(false))));
+		let verifier = self.make_verifier(client.clone(), config);
+		let import_queue = Arc::new(SyncImportQueue::new(verifier));
 		let specialization = DummySpecialization {
 			gossip: ConsensusGossip::new(),
 		};
@@ -323,93 +343,107 @@ impl TestNet {
 			specialization
 		).unwrap();
 
-		self.peers.push(Arc::new(Peer::new(
+		let peer = Arc::new(Peer::new(
 			client,
 			Arc::new(sync),
 			Arc::new(RwLock::new(VecDeque::new())),
 			import_queue
-		)));
-	}
+		));
 
-	/// Get reference to peer.
-	pub fn peer(&self, i: usize) -> &Peer {
-		&self.peers[i]
+		self.mut_peers(|peers| {
+			peers.push(peer.clone())
+		});
 	}
 
 	/// Start network.
 	fn start(&mut self) {
-		if self.started {
+		if self.started() {
 			return;
 		}
-		for peer in 0..self.peers.len() {
-			self.peers[peer].start();
-			for client in 0..self.peers.len() {
-				if peer != client {
-					self.peers[peer].on_connect(client as NodeIndex);
+		self.mut_peers(|peers| {
+			for peer in 0..peers.len() {
+				peers[peer].start();
+				for client in 0..peers.len() {
+					if peer != client {
+						peers[peer].on_connect(client as NodeIndex);
+					}
 				}
 			}
-		}
-		self.started = true;
+		});
+		self.set_started(true);
 	}
 
 	/// Do one step of routing.
-	pub fn route(&mut self) {
-		for peer in 0..self.peers.len() {
-			let packet = self.peers[peer].pending_message();
-			if let Some(packet) = packet {
-				let disconnecting = {
-					let recipient = packet.recipient;
-					trace!("--- {} -> {} ---", peer, recipient);
-					let to_disconnect = self.peers[recipient].receive_message(peer as NodeIndex, packet);
-					for d in &to_disconnect {
-						// notify this that disconnecting peers are disconnecting
-						self.peers[recipient].on_disconnect(*d as NodeIndex);
-						self.disconnect_events.push((peer, *d));
+	fn route(&mut self) {
+		self.mut_peers(move |peers| {
+			for peer in 0..peers.len() {
+				let packet = peers[peer].pending_message();
+				if let Some(packet) = packet {
+					let disconnecting = {
+						let recipient = packet.recipient;
+						trace!(target: "sync", "--- {} -> {} ---", peer, recipient);
+						let to_disconnect = peers[recipient].receive_message(peer as NodeIndex, packet);
+						for d in &to_disconnect {
+							// notify this that disconnecting peers are disconnecting
+							peers[recipient].on_disconnect(*d as NodeIndex);
+						}
+						to_disconnect
+					};
+					for d in &disconnecting {
+						// notify other peers that this peer is disconnecting
+						peers[*d].on_disconnect(peer as NodeIndex);
 					}
-					to_disconnect
-				};
-				for d in &disconnecting {
-					// notify other peers that this peer is disconnecting
-					self.peers[*d].on_disconnect(peer as NodeIndex);
 				}
 			}
-		}
+		});
 	}
 
 	/// Route messages between peers until all queues are empty.
-	pub fn route_until_complete(&mut self) {
+	fn route_until_complete(&mut self) {
 		while !self.done() {
 			self.route()
 		}
 	}
 
 	/// Do a step of synchronization.
-	pub fn sync_step(&mut self) {
+	fn sync_step(&mut self) {
 		self.route();
 
-		for peer in &mut self.peers {
-			peer.sync_step();
-		}
+		self.mut_peers(|peers| {
+			for peer in peers {
+				peer.sync_step();
+			}
+		})
+	}
+
+	/// Send block import notifications for all peers.
+	fn send_import_notifications(&mut self) {
+		self.mut_peers(|peers| {
+			for peer in peers {
+				peer.send_import_notifications();
+			}
+		})
 	}
 
 	/// Restart sync for a peer.
-	pub fn restart_peer(&mut self, i: usize) {
-		self.peers[i].restart_sync();
+	fn restart_peer(&mut self, i: usize) {
+		self.peers()[i].restart_sync();
 	}
 
 	/// Perform synchronization until complete.
-	pub fn sync(&mut self) -> u32 {
+	fn sync(&mut self) -> u32 {
 		self.start();
 		let mut total_steps = 0;
 		while !self.done() {
 			self.sync_step();
 			total_steps += 1;
+			self.route();
 		}
 		total_steps
 	}
 
 	/// Do the given amount of sync steps.
-	pub fn sync_steps(&mut self, count: usize) {
+	fn sync_steps(&mut self, count: usize) {
 		self.start();
 		for _ in 0..count {
 			self.sync_step();
@@ -417,7 +451,50 @@ impl TestNet {
 	}
 
 	/// Whether all peers have synced.
-	pub fn done(&self) -> bool {
-		self.peers.iter().all(|p| p.is_done())
+	fn done(&self) -> bool {
+		self.peers().iter().all(|p| p.is_done())
+	}
+}
+
+pub struct TestNet {
+	peers: Vec<Arc<Peer<PassThroughVerifier>>>,
+	started: bool
+}
+
+impl TestNetFactory for TestNet {
+	type Verifier = PassThroughVerifier;
+
+	/// Create new test network with peers and given config.
+	fn from_config(_config: &ProtocolConfig) -> Self {
+		TestNet {
+			peers: Vec::new(),
+			started: false
+		}
+	}
+	
+	fn make_verifier(&self, _client: Arc<PeersClient>, _config: &ProtocolConfig)
+		-> Arc<Self::Verifier>
+	{
+		Arc::new(PassThroughVerifier(false))
+	}
+
+	fn peer(&self, i: usize) -> &Peer<Self::Verifier> {
+		&self.peers[i]
+	}
+
+	fn peers(&self) -> &Vec<Arc<Peer<Self::Verifier>>> {
+		&self.peers
+	}
+
+	fn mut_peers<F: Fn(&mut Vec<Arc<Peer<Self::Verifier>>>)>(&mut self, closure: F ) {
+		closure(&mut self.peers);
+	}
+
+	fn started(&self) -> bool {
+		self.started
+	}
+
+	fn set_started(&mut self, new: bool) {
+		self.started = new;
 	}
 }
diff --git a/substrate/core/network/src/test/sync.rs b/substrate/core/network/src/test/sync.rs
index 02531259f25f41485d693c73f3238c7b13d9820a..0f9e40782873b964cca30e80ba5423cef081e836 100644
--- a/substrate/core/network/src/test/sync.rs
+++ b/substrate/core/network/src/test/sync.rs
@@ -16,6 +16,7 @@
 
 use client::backend::Backend;
 use client::blockchain::HeaderBackend as BlockchainHeaderBackend;
+use consensus::BlockOrigin;
 use sync::SyncState;
 use Roles;
 use super::*;
@@ -68,6 +69,7 @@ fn sync_no_common_longer_chain_fails() {
 fn sync_after_fork_works() {
 	::env_logger::init().ok();
 	let mut net = TestNet::new(3);
+	net.sync_step();
 	net.peer(0).push_blocks(30, false);
 	net.peer(1).push_blocks(30, false);
 	net.peer(2).push_blocks(30, false);
@@ -87,6 +89,20 @@ fn sync_after_fork_works() {
 	assert!(net.peer(2).client.backend().blockchain().canon_equals_to(&peer1_chain));
 }
 
+#[test]
+fn own_blocks_are_announced() {
+	::env_logger::init().ok();
+	let mut net = TestNet::new(3);
+	net.sync(); // connect'em
+	net.peer(0).generate_blocks(1, BlockOrigin::Own, |_| ());
+	net.sync();
+	assert_eq!(net.peer(0).client.backend().blockchain().info().unwrap().best_number, 1);
+	assert_eq!(net.peer(1).client.backend().blockchain().info().unwrap().best_number, 1);
+	let peer0_chain = net.peer(0).client.backend().blockchain().clone();
+	assert!(net.peer(1).client.backend().blockchain().canon_equals_to(&peer0_chain));
+	assert!(net.peer(2).client.backend().blockchain().canon_equals_to(&peer0_chain));
+}
+
 #[test]
 fn blocks_are_not_announced_by_light_nodes() {
 	::env_logger::init().ok();
diff --git a/substrate/core/primitives/src/ed25519.rs b/substrate/core/primitives/src/ed25519.rs
index 2047a0c7afc173b88a12505d068566152588b4ef..027298b4b1628ee45facad79c9bdd4a34e51d880 100644
--- a/substrate/core/primitives/src/ed25519.rs
+++ b/substrate/core/primitives/src/ed25519.rs
@@ -31,7 +31,7 @@ pub type Signature = H512;
 pub const PKCS_LEN: usize = 85;
 
 /// A localized signature also contains sender information.
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)]
 pub struct LocalizedSignature {
 	/// The signer of the signature.
 	pub signer: Public,
@@ -40,6 +40,7 @@ pub struct LocalizedSignature {
 }
 
 /// Verify a message without type checking the parameters' types for the right size.
+/// Returns true if the signature is good.
 pub fn verify<P: AsRef<[u8]>>(sig: &[u8], message: &[u8], public: P) -> bool {
 	let public_key = untrusted::Input::from(public.as_ref());
 	let msg = untrusted::Input::from(message);
@@ -52,7 +53,7 @@ pub fn verify<P: AsRef<[u8]>>(sig: &[u8], message: &[u8], public: P) -> bool {
 }
 
 /// A public key.
-#[derive(PartialEq, Eq, Clone)]
+#[derive(PartialEq, Eq, Clone, Encode, Decode)]
 pub struct Public(pub [u8; 32]);
 
 /// A key pair.
@@ -246,7 +247,7 @@ impl Pair {
 	}
 }
 
-/// Verify a signature on a message.
+/// Verify a signature on a message. Returns true if the signature is good.
 pub fn verify_strong<P: AsRef<Public>>(sig: &Signature, message: &[u8], pubkey: P) -> bool {
 	let public_key = untrusted::Input::from(&pubkey.as_ref().0[..]);
 	let msg = untrusted::Input::from(message);
diff --git a/substrate/core/rpc/Cargo.toml b/substrate/core/rpc/Cargo.toml
index 453b288c9dec1b20a10b6fcd2b69e8b51b905ab2..3f35394c9112928ed9d7176751fb6d089a2bd5b3 100644
--- a/substrate/core/rpc/Cargo.toml
+++ b/substrate/core/rpc/Cargo.toml
@@ -22,5 +22,6 @@ tokio = "0.1.7"
 [dev-dependencies]
 assert_matches = "1.1"
 substrate-test-client = { path = "../test-client" }
+substrate-consensus-common = { path = "../consensus/common" }
 rustc-hex = "2.0"
 hex-literal = "0.1"
diff --git a/substrate/core/rpc/src/chain/mod.rs b/substrate/core/rpc/src/chain/mod.rs
index 6c1724a787070d6d18a106e87728a83085a044a7..f56ec59c1a1222e9df25c3fb2d5aa97ff322fdb2 100644
--- a/substrate/core/rpc/src/chain/mod.rs
+++ b/substrate/core/rpc/src/chain/mod.rs
@@ -26,7 +26,7 @@ use rpc::futures::{stream, Future, Sink, Stream};
 use runtime_primitives::generic::{BlockId, SignedBlock};
 use runtime_primitives::traits::{Block as BlockT, Header, NumberFor};
 use runtime_version::RuntimeVersion;
-use primitives::{Blake2Hasher};
+use primitives::{Blake2Hasher, storage};
 
 use subscriptions::Subscriptions;
 
@@ -68,6 +68,16 @@ build_rpc_trait! {
 			#[rpc(name = "chain_unsubscribeNewHead", alias = ["unsubscribe_newHead", ])]
 			fn unsubscribe_new_head(&self, SubscriptionId) -> RpcResult<bool>;
 		}
+
+		#[pubsub(name = "chain_runtimeVersion")] {
+			/// New runtime version subscription
+			#[rpc(name = "chain_subscribeRuntimeVersion")]
+			fn subscribe_runtime_version(&self, Self::Metadata, pubsub::Subscriber<RuntimeVersion>);
+
+			/// Unsubscribe from runtime version subscription
+			#[rpc(name = "chain_unsubscribeRuntimeVersion")]
+			fn unsubscribe_runtime_version(&self, SubscriptionId) -> RpcResult<bool>;
+		}
 	}
 }
 
@@ -163,4 +173,53 @@ impl<B, E, Block> ChainApi<Block::Hash, Block::Header, NumberFor<Block>, Block::
 	fn unsubscribe_new_head(&self, id: SubscriptionId) -> RpcResult<bool> {
 		Ok(self.subscriptions.cancel(id))
 	}
+
+
+	fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: pubsub::Subscriber<RuntimeVersion>) {
+		let stream = match self.client.storage_changes_notification_stream(Some(&[storage::StorageKey(storage::well_known_keys::CODE.to_vec())])) {
+			Ok(stream) => stream,
+			Err(err) => {
+				let _ = subscriber.reject(error::Error::from(err).into());
+				return;
+			}
+		};
+
+		self.subscriptions.add(subscriber, |sink| {
+			let version = self.runtime_version(None.into())
+				.map_err(Into::into);
+
+			let client = self.client.clone();
+			let mut previous_version = version.clone();
+
+			let stream = stream
+				.map_err(|e| warn!("Error creating storage notification stream: {:?}", e))
+				.filter_map(move |_| {
+					let version = client.info().and_then(|info| {
+							client.runtime_version_at(&BlockId::hash(info.chain.best_hash))
+						})
+						.map_err(error::Error::from)
+						.map_err(Into::into);
+					if previous_version != version {
+						previous_version = version.clone();
+						Some(version)
+					} else {
+						None
+					}
+				});
+
+			sink
+				.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
+				.send_all(
+					stream::iter_result(vec![Ok(version)])
+					.chain(stream)
+				)
+				// we ignore the resulting Stream (if the first stream is over we are unsubscribed)
+				.map(|_| ())
+		});
+	}
+
+
+	fn unsubscribe_runtime_version(&self, id: SubscriptionId) -> RpcResult<bool> {
+		Ok(self.subscriptions.cancel(id))
+	}
 }
diff --git a/substrate/core/rpc/src/chain/tests.rs b/substrate/core/rpc/src/chain/tests.rs
index fc9817140d7a1c1e4ce6c1bebe5cb4b559439018..644c7fed075bf74b26b4d6e057f6afeccb2844e4 100644
--- a/substrate/core/rpc/src/chain/tests.rs
+++ b/substrate/core/rpc/src/chain/tests.rs
@@ -16,9 +16,9 @@
 
 use super::*;
 use jsonrpc_macros::pubsub;
-use client::BlockOrigin;
 use test_client::{self, TestClient};
 use test_client::runtime::{Block, Header};
+use consensus::BlockOrigin;
 
 #[test]
 fn should_return_header() {
diff --git a/substrate/core/rpc/src/lib.rs b/substrate/core/rpc/src/lib.rs
index 9e4bd969789d3feb5c16177b82a60635b710079e..dbbc8e3a6ad4477fb5c90bb9829a3b62ddde41fa 100644
--- a/substrate/core/rpc/src/lib.rs
+++ b/substrate/core/rpc/src/lib.rs
@@ -47,6 +47,8 @@ extern crate hex_literal;
 #[cfg(test)]
 extern crate substrate_test_client as test_client;
 #[cfg(test)]
+extern crate substrate_consensus_common as consensus;
+#[cfg(test)]
 extern crate rustc_hex;
 
 mod errors;
diff --git a/substrate/core/rpc/src/state/mod.rs b/substrate/core/rpc/src/state/mod.rs
index 4c3110f8e14b30a93f59b5b3b5106d3c3dc976e5..3fda746dcb08af45d450f037eacba67e42cb6d0c 100644
--- a/substrate/core/rpc/src/state/mod.rs
+++ b/substrate/core/rpc/src/state/mod.rs
@@ -21,7 +21,7 @@ use std::{
 	sync::Arc,
 };
 
-use client::{self, Client, CallExecutor, BlockchainEvents};
+use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata};
 use jsonrpc_macros::Trailing;
 use jsonrpc_macros::pubsub;
 use jsonrpc_pubsub::SubscriptionId;
diff --git a/substrate/core/rpc/src/state/tests.rs b/substrate/core/rpc/src/state/tests.rs
index 74b5fab8417b0f988c2a672ee3d7e8707463a24b..71978f88ea57f793d14fd22347dc1874d9113820 100644
--- a/substrate/core/rpc/src/state/tests.rs
+++ b/substrate/core/rpc/src/state/tests.rs
@@ -17,7 +17,7 @@
 use super::*;
 use self::error::{Error, ErrorKind};
 
-use client::BlockOrigin;
+use consensus::BlockOrigin;
 use jsonrpc_macros::pubsub;
 use rustc_hex::FromHex;
 use test_client::{self, runtime, keyring::Keyring, TestClient, BlockBuilderExt};
diff --git a/substrate/core/service/Cargo.toml b/substrate/core/service/Cargo.toml
index 694cd5a5534af110f40c1268ed72ea092db21c8e..a15e010d5c477f8147a2acd36ccff77e651562b8 100644
--- a/substrate/core/service/Cargo.toml
+++ b/substrate/core/service/Cargo.toml
@@ -20,6 +20,7 @@ substrate-keystore = { path = "../../core/keystore" }
 sr-io = { path = "../../core/sr-io" }
 sr-primitives = { path = "../../core/sr-primitives" }
 substrate-primitives = { path = "../../core/primitives" }
+substrate-consensus-common = { path = "../../core/consensus/common" }
 substrate-network = { path = "../../core/network" }
 substrate-client = { path = "../../core/client" }
 substrate-client-db = { path = "../../core/client/db" }
diff --git a/substrate/core/service/src/chain_ops.rs b/substrate/core/service/src/chain_ops.rs
index a3cd5bb770f1e5ca4d4e6a465d5ae7a896580606..d23e82b1cfb32b5689d92ae6d9a2784b0aeb2b09 100644
--- a/substrate/core/service/src/chain_ops.rs
+++ b/substrate/core/service/src/chain_ops.rs
@@ -20,11 +20,12 @@ use std::{self, io::{Read, Write}};
 use futures::Future;
 use serde_json;
 
-use client::BlockOrigin;
 use runtime_primitives::generic::{SignedBlock, BlockId};
 use runtime_primitives::traits::{As, Block, Header};
 use network::import_queue::{ImportQueue, Link, BlockData};
 use network::message;
+
+use consensus_common::BlockOrigin;
 use components::{self, Components, ServiceFactory, FactoryFullConfiguration, FactoryBlockNumber, RuntimeGenesis};
 use new_client;
 use codec::{Decode, Encode};
diff --git a/substrate/core/service/src/components.rs b/substrate/core/service/src/components.rs
index a30fb9940e081d4b3a3d43475608259c28cf9bbd..d2503ded239178aa6b9b07e95a949ce062f89ccc 100644
--- a/substrate/core/service/src/components.rs
+++ b/substrate/core/service/src/components.rs
@@ -25,7 +25,7 @@ use chain_spec::ChainSpec;
 use client_db;
 use client::{self, Client};
 use {error, Service};
-use network::{self, OnDemand};
+use network::{self, OnDemand, import_queue::ImportQueue};
 use substrate_executor::{NativeExecutor, NativeExecutionDispatch};
 use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool};
 use runtime_primitives::{traits::Block as BlockT, traits::Header as HeaderT, BuildStorage};
@@ -136,8 +136,10 @@ pub trait ServiceFactory: 'static + Sized {
 	type FullService: Deref<Target = Service<FullComponents<Self>>> + Send + Sync + 'static;
 	/// Extended light service type.
 	type LightService: Deref<Target = Service<LightComponents<Self>>> + Send + Sync + 'static;
-	/// ImportQueue
-	type ImportQueue: network::import_queue::ImportQueue<Self::Block> + 'static;
+	/// ImportQueue for full client
+	type FullImportQueue: network::import_queue::ImportQueue<Self::Block> + 'static;
+	/// ImportQueue for light clients
+	type LightImportQueue: network::import_queue::ImportQueue<Self::Block> + 'static;
 
 	//TODO: replace these with a constructor trait. that TransactionPool implements.
 	/// Extrinsic pool constructor for the full client.
@@ -162,7 +164,7 @@ pub trait ServiceFactory: 'static + Sized {
 	fn build_full_import_queue(
 		config: &FactoryFullConfiguration<Self>,
 		_client: Arc<FullClient<Self>>
-	) -> Result<Self::ImportQueue, error::Error> {
+	) -> Result<Self::FullImportQueue, error::Error> {
 		if let Some(name) = config.chain_spec.consensus_engine() {
 			match name {
 				_ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into())
@@ -177,7 +179,7 @@ pub trait ServiceFactory: 'static + Sized {
 	fn build_light_import_queue(
 		config: &FactoryFullConfiguration<Self>,
 		_client: Arc<LightClient<Self>>
-	) -> Result<Self::ImportQueue, error::Error> {
+	) -> Result<Self::LightImportQueue, error::Error> {
 		if let Some(name) = config.chain_spec.consensus_engine() {
 			match name {
 				_ => Err(format!("Chain Specification defines unknown consensus engine '{}'", name).into())
@@ -196,13 +198,16 @@ pub trait Components: 'static {
 	/// Client backend.
 	type Backend: 'static + client::backend::Backend<FactoryBlock<Self::Factory>, Blake2Hasher>;
 	/// Client executor.
-	type Executor: 'static + client::CallExecutor<FactoryBlock<Self::Factory>, Blake2Hasher> + Send + Sync;
+	type Executor: 'static + client::CallExecutor<FactoryBlock<Self::Factory>, Blake2Hasher> + Send + Sync + Clone;
 	/// Extrinsic pool type.
 	type TransactionPoolApi: 'static + txpool::ChainApi<
 		Hash = <<Self::Factory as ServiceFactory>::Block as BlockT>::Hash,
 		Block = FactoryBlock<Self::Factory>
 	>;
 
+	/// Our Import Queue
+	type ImportQueue: ImportQueue<FactoryBlock<Self::Factory>> + 'static;
+
 	/// Create client.
 	fn build_client(
 		config: &FactoryFullConfiguration<Self::Factory>,
@@ -221,7 +226,7 @@ pub trait Components: 'static {
 	fn build_import_queue(
 		config: &FactoryFullConfiguration<Self::Factory>,
 		client: Arc<ComponentClient<Self>>
-	) -> Result<<Self::Factory as ServiceFactory>::ImportQueue, error::Error>;
+	) -> Result<Self::ImportQueue, error::Error>;
 }
 
 /// A struct that implement `Components` for the full client.
@@ -234,6 +239,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
 	type Executor = FullExecutor<Factory>;
 	type Backend = FullBackend<Factory>;
 	type TransactionPoolApi = <Factory as ServiceFactory>::FullTransactionPoolApi;
+	type ImportQueue = Factory::FullImportQueue;
 
 	fn build_client(
 		config: &FactoryFullConfiguration<Factory>,
@@ -267,7 +273,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
 	fn build_import_queue(
 		config: &FactoryFullConfiguration<Self::Factory>,
 		client: Arc<ComponentClient<Self>>
-	) -> Result<<Self::Factory as ServiceFactory>::ImportQueue, error::Error> {
+	) -> Result<Self::ImportQueue, error::Error> {
 		Factory::build_full_import_queue(config, client)
 	}
 }
@@ -282,6 +288,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
 	type Executor = LightExecutor<Factory>;
 	type Backend = LightBackend<Factory>;
 	type TransactionPoolApi = <Factory as ServiceFactory>::LightTransactionPoolApi;
+	type ImportQueue = <Factory as ServiceFactory>::LightImportQueue;
 
 	fn build_client(
 		config: &FactoryFullConfiguration<Factory>,
@@ -316,7 +323,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
 	fn build_import_queue(
 		config: &FactoryFullConfiguration<Self::Factory>,
 		client: Arc<ComponentClient<Self>>
-	) -> Result<<Self::Factory as ServiceFactory>::ImportQueue, error::Error> {
+	) -> Result<Self::ImportQueue, error::Error> {
 		Factory::build_light_import_queue(config, client)
 	}
 }
diff --git a/substrate/core/service/src/consensus.rs b/substrate/core/service/src/consensus.rs
new file mode 100644
index 0000000000000000000000000000000000000000..61968ee04d41b09aab57548eee630347509dadef
--- /dev/null
+++ b/substrate/core/service/src/consensus.rs
@@ -0,0 +1,263 @@
+// Copyright 2018 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+//! provide consensus service to substrate.
+
+// FIXME: move this into substrate-consensus-common - https://github.com/paritytech/substrate/issues/1021
+
+use std::sync::Arc;
+use std::time::{self, Duration, Instant};
+use std;
+
+use client::{self, error, Client as SubstrateClient, CallExecutor};
+use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, id::BLOCK_BUILDER};
+use codec::{Decode, Encode};
+use consensus_common::{self, InherentData, evaluation, offline_tracker::OfflineTracker};
+use primitives::{AuthorityId, ed25519, Blake2Hasher};
+use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT};
+use runtime_primitives::generic::BlockId;
+use transaction_pool::txpool::{self, Pool as TransactionPool};
+
+use parking_lot::RwLock;
+
+/// Shared offline validator tracker.
+pub type SharedOfflineTracker = Arc<RwLock<OfflineTracker>>;
+type Timestamp = u64;
+
+// block size limit.
+const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024;
+
+/// Build new blocks.
+pub trait BlockBuilder<Block: BlockT> {
+	/// Push an extrinsic onto the block. Fails if the extrinsic is invalid.
+	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<(), error::Error>;
+}
+
+/// Local client abstraction for the consensus.
+pub trait AuthoringApi:
+	Send
+	+ Sync
+	+ BlockBuilderAPI<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
+	+ Core<<Self as AuthoringApi>::Block, AuthorityId, Error=<Self as AuthoringApi>::Error>
+{
+	/// The block used for this API type.
+	type Block: BlockT;
+	/// The error used by this API type.
+	type Error: std::error::Error;
+
+	/// Build a block on top of the given, with inherent extrinsics pre-pushed.
+	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
+		&self,
+		at: &BlockId<Self::Block>,
+		inherent_data: InherentData,
+		build_ctx: F,
+	) -> Result<Self::Block, error::Error>;
+}
+
+impl<'a, B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where
+	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
+	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
+	Block: BlockT
+{
+	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<(), error::Error> {
+		client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into)
+	}
+}
+
+impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
+	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
+	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
+	Block: BlockT,
+{
+	type Block = Block;
+	type Error = client::error::Error;
+
+	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
+		&self,
+		at: &BlockId<Self::Block>,
+		inherent_data: InherentData,
+		mut build_ctx: F,
+	) -> Result<Self::Block, error::Error> {
+		let runtime_version = self.runtime_version_at(at)?;
+
+		let mut block_builder = self.new_block_at(at)?;
+		if runtime_version.has_api(BLOCK_BUILDER, 1) {
+			self.inherent_extrinsics(at, &inherent_data)?
+				.into_iter().try_for_each(|i| block_builder.push(i))?;
+		}
+
+		build_ctx(&mut block_builder);
+
+		block_builder.bake().map_err(Into::into)
+	}
+}
+
+/// Proposer factory.
+pub struct ProposerFactory<C, A> where
+	C: AuthoringApi,
+	A: txpool::ChainApi,
+{
+	/// The client instance.
+	pub client: Arc<C>,
+	/// The transaction pool.
+	pub transaction_pool: Arc<TransactionPool<A>>,
+	/// Offline-tracker.
+	pub offline: SharedOfflineTracker,
+	/// Force delay in evaluation this long.
+	pub force_delay: Timestamp,
+}
+
+impl<C, A> consensus_common::Environment<<C as AuthoringApi>::Block> for ProposerFactory<C, A> where
+	C: AuthoringApi,
+	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
+	client::error::Error: From<<C as AuthoringApi>::Error>
+{
+	type Proposer = Proposer<C, A>;
+	type Error = error::Error;
+
+	fn init(
+		&self,
+		parent_header: &<<C as AuthoringApi>::Block as BlockT>::Header,
+		_: &[AuthorityId],
+		_: Arc<ed25519::Pair>,
+	) -> Result<Self::Proposer, error::Error> {
+		let parent_hash = parent_header.hash();
+
+		let id = BlockId::hash(parent_hash);
+
+		let authorities: Vec<AuthorityId> = self.client.authorities(&id)?;
+		self.offline.write().note_new_block(&authorities[..]);
+
+		info!("Starting consensus session on top of parent {:?}", parent_hash);
+
+		let now = Instant::now();
+		let proposer = Proposer {
+			client: self.client.clone(),
+			start: now,
+			parent_hash,
+			parent_id: id,
+			parent_number: *parent_header.number(),
+			transaction_pool: self.transaction_pool.clone(),
+			offline: self.offline.clone(),
+			authorities,
+			minimum_timestamp: current_timestamp() + self.force_delay,
+		};
+
+		Ok(proposer)
+	}
+}
+
+/// The proposer logic.
+pub struct Proposer<C: AuthoringApi, A: txpool::ChainApi> {
+	client: Arc<C>,
+	start: Instant,
+	parent_hash: <<C as AuthoringApi>::Block as BlockT>::Hash,
+	parent_id: BlockId<<C as AuthoringApi>::Block>,
+	parent_number: <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Number,
+	transaction_pool: Arc<TransactionPool<A>>,
+	offline: SharedOfflineTracker,
+	authorities: Vec<AuthorityId>,
+	minimum_timestamp: u64,
+}
+
+impl<C, A> consensus_common::Proposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
+	C: AuthoringApi,
+	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
+	client::error::Error: From<<C as AuthoringApi>::Error>
+{
+	type Create = Result<<C as AuthoringApi>::Block, error::Error>;
+	type Error = error::Error;
+
+	fn propose(&self) -> Result<<C as AuthoringApi>::Block, error::Error> {
+		use runtime_primitives::traits::BlakeTwo256;
+
+		const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60);
+
+		let timestamp = ::std::cmp::max(self.minimum_timestamp, current_timestamp());
+
+		let elapsed_since_start = self.start.elapsed();
+		let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS {
+			Vec::new()
+		} else {
+			self.offline.read().reports(&self.authorities[..])
+		};
+
+		if !offline_indices.is_empty() {
+			info!("Submitting offline authorities {:?} for slash-vote",
+				offline_indices.iter().map(|&i| self.authorities[i as usize]).collect::<Vec<_>>(),
+			)
+		}
+
+		let inherent_data = InherentData {
+			timestamp,
+			offline_indices,
+		};
+
+		let block = self.client.build_block(
+			&self.parent_id,
+			inherent_data,
+			|block_builder| {
+				let mut unqueue_invalid = Vec::new();
+				let mut pending_size = 0;
+				let pending_iterator = self.transaction_pool.ready();
+
+				for pending in pending_iterator {
+					// TODO [ToDr] Probably get rid of it, and validate in runtime.
+					let encoded_size = pending.data.encode().len();
+					if pending_size + encoded_size >= MAX_TRANSACTIONS_SIZE { break }
+
+					match block_builder.push_extrinsic(pending.data.clone()) {
+						Ok(()) => {
+							pending_size += encoded_size;
+						}
+						Err(e) => {
+							trace!(target: "transaction-pool", "Invalid transaction: {}", e);
+							unqueue_invalid.push(pending.hash.clone());
+						}
+					}
+				}
+
+				self.transaction_pool.remove_invalid(&unqueue_invalid);
+			})?;
+
+		info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
+			  block.header().number(),
+			  <<C as AuthoringApi>::Block as BlockT>::Hash::from(block.header().hash()),
+			  block.header().parent_hash(),
+			  block.extrinsics().iter()
+			  .map(|xt| format!("{}", BlakeTwo256::hash_of(xt)))
+			  .collect::<Vec<_>>()
+			  .join(", ")
+			 );
+
+		let substrate_block = Decode::decode(&mut block.encode().as_slice())
+			.expect("blocks are defined to serialize to substrate blocks correctly; qed");
+
+		assert!(evaluation::evaluate_initial(
+			&substrate_block,
+			&self.parent_hash,
+			self.parent_number,
+		).is_ok());
+
+		Ok(substrate_block)
+	}
+}
+
+fn current_timestamp() -> Timestamp {
+	time::SystemTime::now().duration_since(time::UNIX_EPOCH)
+		.expect("now always later than unix epoch; qed")
+		.as_secs()
+}
diff --git a/substrate/core/service/src/lib.rs b/substrate/core/service/src/lib.rs
index 848c96ae90a6784b53abfc3b36f13ff391ce7ff0..9e7c201e8f05724c7fdb2f22007e2e96ac5a5e6c 100644
--- a/substrate/core/service/src/lib.rs
+++ b/substrate/core/service/src/lib.rs
@@ -15,7 +15,7 @@
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
 // tag::description[]
-//! Substrate service. Starts a thread that spins the network, the client and the extrinsic pool.
+//! Substrate service. Starts a thread that spins up the network, client, and extrinsic pool.
 //! Manages communication between them.
 // end::description[]
 
@@ -29,6 +29,7 @@ extern crate parking_lot;
 extern crate substrate_keystore as keystore;
 extern crate substrate_primitives as primitives;
 extern crate sr_primitives as runtime_primitives;
+extern crate substrate_consensus_common as consensus_common;
 extern crate substrate_network as network;
 extern crate substrate_executor;
 extern crate substrate_client as client;
@@ -56,6 +57,7 @@ mod error;
 mod chain_spec;
 pub mod config;
 pub mod chain_ops;
+pub mod consensus;
 
 use std::io;
 use std::net::SocketAddr;
@@ -63,7 +65,7 @@ use std::collections::HashMap;
 #[doc(hidden)]
 pub use std::{ops::Deref, result::Result, sync::Arc};
 use futures::prelude::*;
-use parking_lot::Mutex;
+use parking_lot::{Mutex, RwLock};
 use keystore::Store as Keystore;
 use client::BlockchainEvents;
 use runtime_primitives::traits::{Header, As};
@@ -80,6 +82,8 @@ pub use chain_spec::ChainSpec;
 pub use transaction_pool::txpool::{self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError};
 pub use client::ExecutionStrategy;
 
+use consensus_common::offline_tracker::OfflineTracker;
+pub use consensus::ProposerFactory;
 pub use components::{ServiceFactory, FullBackend, FullExecutor, LightBackend,
 	LightExecutor, Components, PoolApi, ComponentClient,
 	ComponentBlock, FullClient, LightClient, FullComponents, LightComponents,
@@ -98,6 +102,7 @@ pub struct Service<Components: components::Components> {
 	keystore: Keystore,
 	exit: ::exit_future::Exit,
 	signal: Option<Signal>,
+	proposer: Arc<ProposerFactory<ComponentClient<Components>, Components::TransactionPoolApi>>,
 	_rpc_http: Option<rpc::HttpServer>,
 	_rpc_ws: Option<Mutex<rpc::WsServer>>, // WsServer is not `Sync`, but the service needs to be.
 	_telemetry: Option<tel::Telemetry>,
@@ -118,6 +123,7 @@ pub fn new_client<Factory: components::ServiceFactory>(config: &FactoryFullConfi
 impl<Components> Service<Components>
 	where
 		Components: components::Components,
+		<Components as components::Components>::Executor: std::clone::Clone,
 		txpool::ExHash<Components::TransactionPoolApi>: serde::de::DeserializeOwned + serde::Serialize,
 		txpool::ExtrinsicFor<Components::TransactionPoolApi>: serde::de::DeserializeOwned + serde::Serialize,
 {
@@ -254,6 +260,13 @@ impl<Components> Service<Components>
 			)
 		};
 
+		let proposer = Arc::new(ProposerFactory {
+			client: client.clone(),
+			transaction_pool: transaction_pool.clone(),
+			offline: Arc::new(RwLock::new(OfflineTracker::new())),
+			force_delay: 0 // FIXME: allow this to be configured
+		});
+
 		// Telemetry
 		let telemetry = match config.telemetry_url {
 			Some(url) => {
@@ -287,6 +300,7 @@ impl<Components> Service<Components>
 			transaction_pool: transaction_pool,
 			signal: Some(signal),
 			keystore: keystore,
+			proposer,
 			exit,
 			_rpc_http: rpc_http,
 			_rpc_ws: rpc_ws.map(Mutex::new),
@@ -303,6 +317,13 @@ impl<Components> Service<Components> where
 		self.client.clone()
 	}
 
+	/// Get shared proposer instance
+	pub fn proposer(&self)
+		-> Arc<ProposerFactory<ComponentClient<Components>, Components::TransactionPoolApi>>
+	{
+		self.proposer.clone()
+	}
+
 	/// Get shared network instance.
 	pub fn network(&self) -> Arc<components::NetworkService<Components::Factory>> {
 		self.network.as_ref().expect("self.network always Some").clone()
@@ -324,6 +345,7 @@ impl<Components> Service<Components> where
 	}
 }
 
+
 impl<Components> Drop for Service<Components> where Components: components::Components {
 	fn drop(&mut self) {
 		debug!(target: "service", "Substrate service shutdown");
@@ -450,7 +472,7 @@ macro_rules! construct_simple_service {
 		$name: ident
 	) => {
 		pub struct $name<C: $crate::Components> {
-			inner: $crate::Service<C>,
+			inner: $crate::Arc<$crate::Service<C>>,
 		}
 
 		impl<C: $crate::Components> $name<C> {
@@ -460,7 +482,7 @@ macro_rules! construct_simple_service {
 			) -> $crate::Result<Self, $crate::Error> {
 				Ok(
 					Self {
-						inner: $crate::Service::new(config, executor)?
+						inner: $crate::Arc::new($crate::Service::new(config, executor)?)
 					}
 				)
 			}
@@ -525,8 +547,9 @@ macro_rules! construct_service_factory {
 			Configuration = $config:ty,
 			FullService = $full_service:ty { $( $full_service_init:tt )* },
 			LightService = $light_service:ty { $( $light_service_init:tt )* },
-			ImportQueue = $import_queue:ty
-				{ $( $full_import_queue_init:tt )* }
+			FullImportQueue = $full_import_queue:ty
+				{ $( $full_import_queue_init:tt )* },
+			LightImportQueue = $light_import_queue:ty
 				{ $( $light_import_queue_init:tt )* },
 		}
 	) => {
@@ -544,7 +567,8 @@ macro_rules! construct_service_factory {
 			type Configuration = $config;
 			type FullService = $full_service;
 			type LightService = $light_service;
-			type ImportQueue = $import_queue;
+			type FullImportQueue = $full_import_queue;
+			type LightImportQueue = $light_import_queue;
 
 			fn build_full_transaction_pool(
 				config: $crate::TransactionPoolOptions,
@@ -571,14 +595,14 @@ macro_rules! construct_service_factory {
 			fn build_full_import_queue(
 				config: &$crate::FactoryFullConfiguration<Self>,
 				client: $crate::Arc<$crate::FullClient<Self>>,
-			) -> $crate::Result<Self::ImportQueue, $crate::Error> {
+			) -> $crate::Result<Self::FullImportQueue, $crate::Error> {
 				( $( $full_import_queue_init )* ) (config, client)
 			}
 
 			fn build_light_import_queue(
 				config: &FactoryFullConfiguration<Self>,
 				client: Arc<$crate::LightClient<Self>>,
-			) -> Result<Self::ImportQueue, $crate::Error> {
+			) -> Result<Self::LightImportQueue, $crate::Error> {
 				( $( $light_import_queue_init )* ) (config, client)
 			}
 
diff --git a/substrate/core/service/test/Cargo.toml b/substrate/core/service/test/Cargo.toml
index cfdfacf4da0e550dab00eb086e00b85bcedc2537..12282b16f15e370771e705c89703406d41cee934 100644
--- a/substrate/core/service/test/Cargo.toml
+++ b/substrate/core/service/test/Cargo.toml
@@ -12,6 +12,7 @@ env_logger = "0.4"
 fdlimit = "0.1"
 substrate-service = { path = "../../../core/service" }
 substrate-network = { path = "../../../core/network" }
+substrate-consensus-common = { path = "../../../core/consensus/common" }
 substrate-primitives = { path = "../../../core/primitives" }
 substrate-client = { path = "../../../core/client" }
 sr-primitives = { path = "../../../core/sr-primitives" }
diff --git a/substrate/core/service/test/src/lib.rs b/substrate/core/service/test/src/lib.rs
index 31ac007c4fbb0aba5dc6f188999ec74cecb8f314..0a967e3cd6c8183c2e3d3176a6e773a7fda6340a 100644
--- a/substrate/core/service/test/src/lib.rs
+++ b/substrate/core/service/test/src/lib.rs
@@ -27,6 +27,7 @@ extern crate substrate_service as service;
 extern crate substrate_network as network;
 extern crate substrate_primitives as primitives;
 extern crate substrate_client as client;
+extern crate substrate_consensus_common as consensus;
 extern crate sr_primitives;
 use std::iter;
 use std::sync::Arc;
@@ -47,9 +48,9 @@ use service::{
 	FactoryExtrinsic,
 };
 use network::{NetworkConfiguration, NonReservedPeerMode, Protocol, SyncProvider, ManageNetwork};
-use client::ImportBlock;
 use sr_primitives::traits::As;
 use sr_primitives::generic::BlockId;
+use consensus::{ImportBlock, BlockImport};
 
 struct TestNet<F: ServiceFactory> {
 	runtime: Runtime,
diff --git a/substrate/core/sr-api/README.adoc b/substrate/core/sr-api/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..debd87e8ebddd4e47449271ae54c7b3c65b41269
--- /dev/null
+++ b/substrate/core/sr-api/README.adoc
@@ -0,0 +1,12 @@
+= Runtime API
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/sr-api/src/lib.rs b/substrate/core/sr-api/src/lib.rs
index 2021e2f2a0b740b18ad1d1f707b9893022ecc9c5..7fffc43590c78049cca3489c236338d90c6e022b 100644
--- a/substrate/core/sr-api/src/lib.rs
+++ b/substrate/core/sr-api/src/lib.rs
@@ -14,7 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
+// tag::description[]
 //! API's for interfacing with the runtime via native/wasm.
+// end::description[]
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
@@ -26,7 +28,7 @@ extern crate sr_version as runtime_version;
 
 #[doc(hidden)]
 pub use primitives::{traits::Block as BlockT, generic::BlockId, transaction_validity::TransactionValidity, ApplyResult};
-use runtime_version::RuntimeVersion;
+use runtime_version::{ApiId, RuntimeVersion};
 use rstd::vec::Vec;
 #[doc(hidden)]
 pub use rstd::slice;
@@ -427,6 +429,20 @@ macro_rules! decl_apis {
 	};
 }
 
+/// The ApiIds for the various standard runtime APIs.
+pub mod id {
+	use super::ApiId;
+	
+	/// ApiId for the BlockBuilder trait.
+	pub const BLOCK_BUILDER: ApiId = *b"blkbuild";
+
+	/// ApiId for the TaggedTransactionQueue trait.
+	pub const TAGGED_TRANSACTION_QUEUE: ApiId = *b"validatx";
+
+	/// ApiId for the Metadata trait.
+	pub const METADATA: ApiId = *b"metadata";
+}
+
 decl_apis! {
 	/// The `Core` api trait that is mandantory for each runtime.
 	pub trait Core<Block: BlockT, AuthorityId> {
@@ -436,8 +452,8 @@ decl_apis! {
 	}
 
 	/// The `Metadata` api trait that returns metadata for the runtime.
-	pub trait Metadata {
-		fn metadata() -> Vec<u8>;
+	pub trait Metadata<Data> {
+		fn metadata() -> Data;
 	}
 
 	/// The `OldTxQueue` api trait for interfering with the old transaction queue.
@@ -451,13 +467,6 @@ decl_apis! {
 		fn validate_transaction<TransactionValidity>(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity;
 	}
 
-	/// The `Miscellaneous` api trait for getting miscellaneous information from the runtime.
-	pub trait Miscellaneous {
-		fn validator_count() -> u32;
-		fn validators<AccountId>() -> Vec<AccountId>;
-		fn timestamp<Moment>() -> Moment;
-	}
-
 	/// The `BlockBuilder` api trait that provides required functions for building a block for a runtime.
 	pub trait BlockBuilder<Block: BlockT> ExtraClientSide <OverlayedChanges> {
 		/// Initialise a block with the given header.
diff --git a/substrate/core/sr-primitives/Cargo.toml b/substrate/core/sr-primitives/Cargo.toml
index df80d43a9f702cb59741aa9c5bf7efca2ee6bc17..45e0396df38a742a8b98b93d1c0b4786fa2c1dfa 100644
--- a/substrate/core/sr-primitives/Cargo.toml
+++ b/substrate/core/sr-primitives/Cargo.toml
@@ -31,3 +31,4 @@ std = [
 	"substrate-primitives/std",
 ]
 api-for-runtime = []
+
diff --git a/substrate/core/sr-primitives/README.adoc b/substrate/core/sr-primitives/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..0e9d6361112734dc4430a9dac3a1fa1fde5e3f0a
--- /dev/null
+++ b/substrate/core/sr-primitives/README.adoc
@@ -0,0 +1,12 @@
+= Runtime Primitives
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/sr-primitives/src/generic/digest.rs b/substrate/core/sr-primitives/src/generic/digest.rs
index 4d44ff5ce01793072e168c399458e93bcf9aa028..41ffd6da0d179667da3fd10e1ae236bd0e0a978d 100644
--- a/substrate/core/sr-primitives/src/generic/digest.rs
+++ b/substrate/core/sr-primitives/src/generic/digest.rs
@@ -21,6 +21,8 @@ use rstd::prelude::*;
 use codec::{Decode, Encode, Codec, Input};
 use traits::{self, Member, DigestItem as DigestItemT};
 
+use substrate_primitives::hash::H512 as Signature;
+
 #[derive(PartialEq, Eq, Clone, Encode, Decode)]
 #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
 pub struct Digest<Item> {
@@ -46,6 +48,10 @@ impl<Item> traits::Digest for Digest<Item> where
 	fn push(&mut self, item: Self::Item) {
 		self.logs.push(item);
 	}
+
+	fn pop(&mut self) -> Option<Self::Item> {
+		self.logs.pop()
+	}
 }
 
 /// Digest item that is able to encode/decode 'system' digest items and
@@ -60,10 +66,13 @@ pub enum DigestItem<Hash, AuthorityId> {
 	/// block. It is created for every block iff runtime supports changes
 	/// trie creation.
 	ChangesTrieRoot(Hash),
+	/// Put a Seal on it
+	Seal(u64, Signature),
 	/// Any 'non-system' digest item, opaque to the native code.
 	Other(Vec<u8>),
 }
 
+
 /// A 'referencing view' for digest item. Does not own its contents. Used by
 /// final runtime implementations for encoding/decoding its log items.
 #[derive(PartialEq, Eq, Clone)]
@@ -73,6 +82,9 @@ pub enum DigestItemRef<'a, Hash: 'a, AuthorityId: 'a> {
 	AuthoritiesChange(&'a [AuthorityId]),
 	/// Reference to `DigestItem::ChangesTrieRoot`.
 	ChangesTrieRoot(&'a Hash),
+	/// A sealed signature for testing
+	Seal(&'a u64, &'a Signature),
+	/// Any 'non-system' digest item, opaque to the native code.
 	/// Reference to `DigestItem::Other`.
 	Other(&'a Vec<u8>),
 }
@@ -87,6 +99,7 @@ enum DigestItemType {
 	Other = 0,
 	AuthoritiesChange,
 	ChangesTrieRoot,
+	Seal,
 }
 
 impl<Hash, AuthorityId> DigestItem<Hash, AuthorityId> {
@@ -103,6 +116,7 @@ impl<Hash, AuthorityId> DigestItem<Hash, AuthorityId> {
 		match *self {
 			DigestItem::AuthoritiesChange(ref v) => DigestItemRef::AuthoritiesChange(v),
 			DigestItem::ChangesTrieRoot(ref v) => DigestItemRef::ChangesTrieRoot(v),
+			DigestItem::Seal(ref v, ref s) => DigestItemRef::Seal(v, s),
 			DigestItem::Other(ref v) => DigestItemRef::Other(v),
 		}
 	}
@@ -137,6 +151,10 @@ impl<Hash: Decode, AuthorityId: Decode> Decode for DigestItem<Hash, AuthorityId>
 			DigestItemType::ChangesTrieRoot => Some(DigestItem::ChangesTrieRoot(
 				Decode::decode(input)?,
 			)),
+			DigestItemType::Seal => {
+				let vals: (u64, Signature) = Decode::decode(input)?;
+				Some(DigestItem::Seal(vals.0, vals.1))
+			},
 			DigestItemType::Other => Some(DigestItem::Other(
 				Decode::decode(input)?,
 			)),
@@ -173,6 +191,10 @@ impl<'a, Hash: Encode, AuthorityId: Encode> Encode for DigestItemRef<'a, Hash, A
 				DigestItemType::ChangesTrieRoot.encode_to(&mut v);
 				changes_trie_root.encode_to(&mut v);
 			},
+			DigestItemRef::Seal(val, sig) => {
+				DigestItemType::Seal.encode_to(&mut v);
+				(val, sig).encode_to(&mut v);
+			},
 			DigestItemRef::Other(val) => {
 				DigestItemType::Other.encode_to(&mut v);
 				val.encode_to(&mut v);
diff --git a/substrate/core/sr-primitives/src/generic/header.rs b/substrate/core/sr-primitives/src/generic/header.rs
index ff8222c59a1fd27527824348f0780446f5873929..fc6f73b5cf1b28a568477b4d8cd3296c0fbbadb6 100644
--- a/substrate/core/sr-primitives/src/generic/header.rs
+++ b/substrate/core/sr-primitives/src/generic/header.rs
@@ -137,6 +137,7 @@ impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestIte
 	fn set_parent_hash(&mut self, hash: Self::Hash) { self.parent_hash = hash }
 
 	fn digest(&self) -> &Self::Digest { &self.digest }
+	fn digest_mut(&mut self) -> &mut Self::Digest { &mut self.digest }
 	fn set_digest(&mut self, digest: Self::Digest) { self.digest = digest }
 
 	fn new(
diff --git a/substrate/core/sr-primitives/src/lib.rs b/substrate/core/sr-primitives/src/lib.rs
index 15b86484a6f670517aaac2ee5ac2d35e624129de..36f5cda20748cfab124b54c3c5ce4b4abb70f573 100644
--- a/substrate/core/sr-primitives/src/lib.rs
+++ b/substrate/core/sr-primitives/src/lib.rs
@@ -14,8 +14,10 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
+// tag::description[]
 //! System manager: Handles all of the top-level stuff; executing block/transaction, setting code
 //! and depositing logs.
+// end::description[]
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
diff --git a/substrate/core/sr-primitives/src/testing.rs b/substrate/core/sr-primitives/src/testing.rs
index ab57f1aa6c82b3e4b4ea96ad1a79697b71477646..847af9a3c2ec4ec344733fa86e3504bfb97bdbd5 100644
--- a/substrate/core/sr-primitives/src/testing.rs
+++ b/substrate/core/sr-primitives/src/testing.rs
@@ -42,6 +42,10 @@ impl traits::Digest for Digest {
 	fn push(&mut self, item: Self::Item) {
 		self.logs.push(item);
 	}
+
+	fn pop(&mut self) -> Option<Self::Item> {
+		self.logs.pop()
+	}
 }
 
 #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
@@ -74,6 +78,7 @@ impl traits::Header for Header {
 	fn set_parent_hash(&mut self, hash: Self::Hash) { self.parent_hash = hash }
 
 	fn digest(&self) -> &Self::Digest { &self.digest }
+	fn digest_mut(&mut self) -> &mut Self::Digest { &mut self.digest }
 	fn set_digest(&mut self, digest: Self::Digest) { self.digest = digest }
 
 	fn new(
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 82d28d013ef34a1eb64e3b322e535b168a5676b0..0ee2db117a2b5e38c50fd3efee71d4d88115e409 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -197,11 +197,13 @@ impl<T: Default + Eq + PartialEq> Clear for T {
 pub trait SimpleBitOps:
 	Sized + Clear +
 	rstd::ops::BitOr<Self, Output = Self> +
+	rstd::ops::BitXor<Self, Output = Self> +
 	rstd::ops::BitAnd<Self, Output = Self>
 {}
 impl<T:
 	Sized + Clear +
 	rstd::ops::BitOr<Self, Output = Self> +
+	rstd::ops::BitXor<Self, Output = Self> +
 	rstd::ops::BitAnd<Self, Output = Self>
 > SimpleBitOps for T {}
 
@@ -429,6 +431,8 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stat
 	fn set_parent_hash(&mut self, Self::Hash);
 
 	fn digest(&self) -> &Self::Digest;
+	/// Get a mutable reference to the digest.
+	fn digest_mut(&mut self) -> &mut Self::Digest;
 	fn set_digest(&mut self, Self::Digest);
 
 	fn hash(&self) -> Self::Hash {
@@ -520,6 +524,8 @@ pub trait Digest: Member + Default {
 	fn logs(&self) -> &[Self::Item];
 	/// Push new digest item.
 	fn push(&mut self, item: Self::Item);
+	/// Pop a digest item.
+	fn pop(&mut self) -> Option<Self::Item>;
 
 	/// Get reference to the first digest item that matches the passed predicate.
 	fn log<T, F: Fn(&Self::Item) -> Option<&T>>(&self, predicate: F) -> Option<&T> {
diff --git a/substrate/core/sr-sandbox/src/lib.rs b/substrate/core/sr-sandbox/src/lib.rs
index 7b6dc67feb28b3720ff6011c2ebce608afbc2396..6ed3243dc8bcbbf111a084d280039c94d93d48fb 100755
--- a/substrate/core/sr-sandbox/src/lib.rs
+++ b/substrate/core/sr-sandbox/src/lib.rs
@@ -15,25 +15,25 @@
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
 // tag::description[]
-//! This crate provides means of instantiation and execution of wasm modules.
+//! This crate provides means to instantiate and execute wasm modules.
 //!
-//! It works even when the user of this library is itself executes
-//! inside the wasm VM. In this case same VM is used for execution
+//! It works even when the user of this library executes from
+//! inside the wasm VM. In this case the same VM is used for execution
 //! of both the sandbox owner and the sandboxed module, without compromising security
-//! and without performance penalty of full wasm emulation inside wasm.
+//! and without the performance penalty of full wasm emulation inside wasm.
 //!
-//! This is achieved by using bindings to wasm VM which are published by the host API.
-//! This API is thin and consists of only handful functions. It contains functions for instantiating
-//! modules and executing them and for example doesn't contain functions for inspecting the module
-//! structure. The user of this library is supposed to read wasm module by it's own means.
+//! This is achieved by using bindings to the wasm VM, which are published by the host API.
+//! This API is thin and consists of only a handful functions. It contains functions for instantiating
+//! modules and executing them, but doesn't contain functions for inspecting the module
+//! structure. The user of this library is supposed to read the wasm module.
 //!
-//! When this crate is used in `std` environment all these functions are implemented by directly
-//! calling wasm VM.
+//! When this crate is used in the `std` environment all these functions are implemented by directly
+//! calling the wasm VM.
 //!
-//! Example of possible use-cases for this library are following:
+//! Example of possible use-cases for this library are the following:
 //!
-//! - implementing smart-contract runtimes which uses wasm for contract code
-//! - executing wasm substrate runtime inside of a wasm parachain
+//! - implementing smart-contract runtimes that use wasm for contract code
+//! - executing a wasm substrate runtime inside of a wasm parachain
 //! - etc
 // end::description[]
 
diff --git a/substrate/core/sr-version/README.adoc b/substrate/core/sr-version/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..28db6c615d3b9f65607882768bd3c5bd326f5013
--- /dev/null
+++ b/substrate/core/sr-version/README.adoc
@@ -0,0 +1,13 @@
+
+= Runtime Version
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/sr-version/src/lib.rs b/substrate/core/sr-version/src/lib.rs
index 8af084da5ef945c75e6334d2fefb4abc8f4abddf..6f91692b8232d7ab12e23089985da944055b70e6 100644
--- a/substrate/core/sr-version/src/lib.rs
+++ b/substrate/core/sr-version/src/lib.rs
@@ -14,7 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Version module for runtime; Provide a function that returns runtime version.
+// tag::description[]
+//! Version module for the Substrate runtime; Provides a function that returns the runtime version.
+// end::description[]
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
diff --git a/substrate/core/state-machine/src/lib.rs b/substrate/core/state-machine/src/lib.rs
index 4853b2afb5f1d9806f7a69f402920bef06755917..9bb91108863192f73beda6ac309e5418661766a0 100644
--- a/substrate/core/state-machine/src/lib.rs
+++ b/substrate/core/state-machine/src/lib.rs
@@ -64,6 +64,9 @@ pub use overlayed_changes::OverlayedChanges;
 pub use trie_backend_essence::Storage;
 pub use trie_backend::TrieBackend;
 
+/// Default num of pages for the heap
+const DEFAULT_HEAP_PAGES :u64 = 1024;
+
 /// State Machine Error bound.
 ///
 /// This should reflect WASM error type bound for future compatibility.
@@ -291,7 +294,7 @@ where
 		.to_vec();
 
 	let heap_pages = try_read_overlay_value(overlay, backend, well_known_keys::HEAP_PAGES)?
-		.and_then(|v| u64::decode(&mut &v[..])).unwrap_or(8) as usize;
+		.and_then(|v| u64::decode(&mut &v[..])).unwrap_or(DEFAULT_HEAP_PAGES) as usize;
 
 	// read changes trie configuration. The reason why we're doing it here instead of the
 	// `OverlayedChanges` constructor is that we need proofs for this read as a part of
diff --git a/substrate/core/telemetry/src/lib.rs b/substrate/core/telemetry/src/lib.rs
index 729f6f76d95b7407e7c5c36f82f88d86acdc9fbb..aa7479cc828372ec44b70419c99c911decf3c9b7 100644
--- a/substrate/core/telemetry/src/lib.rs
+++ b/substrate/core/telemetry/src/lib.rs
@@ -17,7 +17,7 @@
 // tag::description[]
 //! Telemetry utils.
 //!
-//! `telemetry` macro be used from whereever in the Substrate codebase
+//! `telemetry` macro may be used anywhere in the Substrate codebase
 //! in order to send real-time logging information to the telemetry
 //! server (if there is one). We use the async drain adapter of `slog`
 //! so that the logging thread doesn't get held up at all.
diff --git a/substrate/core/test-client/Cargo.toml b/substrate/core/test-client/Cargo.toml
index a1bf2f592e85067fb8847fe7d9d1c5331dbbe96c..aa48f95211131f293a350624736eed429344e7d3 100644
--- a/substrate/core/test-client/Cargo.toml
+++ b/substrate/core/test-client/Cargo.toml
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
 substrate-client = { path = "../client" }
 parity-codec = "2.1"
 substrate-executor = { path = "../executor" }
+substrate-consensus-common = { path = "../consensus/common" }
 substrate-keyring = { path = "../../core/keyring" }
 substrate-primitives = { path = "../primitives" }
 substrate-test-runtime = { path = "../test-runtime" }
diff --git a/substrate/core/test-client/src/client_ext.rs b/substrate/core/test-client/src/client_ext.rs
index 76e9888d0beb3c372d76b5e4cb5d880b34396db0..61133c4d9da811328ffa011537aefc82c1421cdf 100644
--- a/substrate/core/test-client/src/client_ext.rs
+++ b/substrate/core/test-client/src/client_ext.rs
@@ -16,15 +16,17 @@
 
 //! Client extension for tests.
 
-use client::{self, ImportBlock, Client};
+use client::{self, Client};
+use consensus::{ImportBlock, BlockImport, BlockOrigin};
 use runtime_primitives::generic::BlockId;
 use primitives::Blake2Hasher;
 use runtime;
 
 /// Extension trait for a test client.
-pub trait TestClient {
+pub trait TestClient: Sized {
 	/// Justify and import block to the chain. No finality.
-	fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()>;
+	fn justify_and_import(&self, origin: BlockOrigin, block: runtime::Block)
+		-> client::error::Result<()>;
 
 	/// Finalize a block.
 	fn finalize_block(&self, id: BlockId<runtime::Block>) -> client::error::Result<()>;
@@ -36,21 +38,23 @@ pub trait TestClient {
 impl<B, E> TestClient for Client<B, E, runtime::Block>
 	where
 		B: client::backend::Backend<runtime::Block, Blake2Hasher>,
-		E: client::CallExecutor<runtime::Block, Blake2Hasher>
+		E: client::CallExecutor<runtime::Block, Blake2Hasher>,
+		Self: BlockImport<runtime::Block, Error=client::error::Error>
 {
-	fn justify_and_import(&self, origin: client::BlockOrigin, block: runtime::Block) -> client::error::Result<()> {
+	fn justify_and_import(&self, origin: BlockOrigin, block: runtime::Block)
+		-> client::error::Result<()>
+	{
 		let import = ImportBlock {
 			origin,
 			header: block.header,
 			external_justification: vec![],
-			internal_justification: vec![],
+			post_runtime_digests: vec![],
 			body: Some(block.extrinsics),
 			finalized: false,
 			auxiliary: Vec::new(),
 		};
-		self.import_block(import, None)?;
 
-		Ok(())
+		self.import_block(import, None).map(|_| ())
 	}
 
 	fn finalize_block(&self, id: BlockId<runtime::Block>) -> client::error::Result<()> {
diff --git a/substrate/core/test-client/src/lib.rs b/substrate/core/test-client/src/lib.rs
index b692d4858ba49b1b847b68bf0822377ded75e631..ff3cfbac0e59b21f13cee8b545742d3e6fd41687 100644
--- a/substrate/core/test-client/src/lib.rs
+++ b/substrate/core/test-client/src/lib.rs
@@ -28,6 +28,7 @@ extern crate sr_primitives as runtime_primitives;
 pub extern crate substrate_client as client;
 pub extern crate substrate_keyring as keyring;
 pub extern crate substrate_test_runtime as runtime;
+pub extern crate substrate_consensus_common as consensus;
 
 pub mod client_ext;
 pub mod trait_tests;
diff --git a/substrate/core/test-client/src/trait_tests.rs b/substrate/core/test-client/src/trait_tests.rs
index 86d08cd8a51b5be4edc0dde3ca7a9ab404a52f9c..3a05b78600003c324949c8f4e5528db1de57a415 100644
--- a/substrate/core/test-client/src/trait_tests.rs
+++ b/substrate/core/test-client/src/trait_tests.rs
@@ -21,7 +21,7 @@
 
 use std::sync::Arc;
 use keyring::Keyring;
-use client::BlockOrigin;
+use consensus::BlockOrigin;
 use primitives::Blake2Hasher;
 use ::TestClient;
 use runtime_primitives::traits::Block as BlockT;
diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..5d9b1fcac3726fbcf0d4a685d6c9f8481ee438a8
Binary files /dev/null and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/core/transaction-pool/README.adoc b/substrate/core/transaction-pool/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..336a67a8418fd0a3384a0b3f50a4655264fe1e3d
--- /dev/null
+++ b/substrate/core/transaction-pool/README.adoc
@@ -0,0 +1,13 @@
+
+= Transaction Pool
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/trie/README.adoc b/substrate/core/trie/README.adoc
new file mode 100644
index 0000000000000000000000000000000000000000..953724ca12061e90ec22189ef9518c8e5674f5f8
--- /dev/null
+++ b/substrate/core/trie/README.adoc
@@ -0,0 +1,12 @@
+= Substrate Trie
+
+.Summary
+[source, toml]
+----
+include::Cargo.toml[lines=2..5]
+----
+
+.Description
+----
+include::src/lib.rs[tag=description]
+----
diff --git a/substrate/core/trie/README.md b/substrate/core/trie/README.md
deleted file mode 100644
index 57d392057be403de764540e264af8d3843445a09..0000000000000000000000000000000000000000
--- a/substrate/core/trie/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This crate provides utility functions to interact with Substrate's Modified Merkle Patricia tree ("trie").
\ No newline at end of file
diff --git a/substrate/core/trie/src/lib.rs b/substrate/core/trie/src/lib.rs
index 87d955a357fcb6fedcdeeb7a53f6c58c297394b0..68dacf2668bc4c4fadee260593e94ca6bb17c8c2 100644
--- a/substrate/core/trie/src/lib.rs
+++ b/substrate/core/trie/src/lib.rs
@@ -14,7 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Substrate-format Base-16 Modified Merkle Patricia Tree (Trie).
+// tag::description[]
+//! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie").
+// end::description[]
 
 // TODO: no_std
 
diff --git a/substrate/doc/packages/misc.adoc b/substrate/doc/packages/misc.adoc
index 316cf44858c91d8327f5ecd4cb2ae91fffef2bde..2081d34efc471bf1c6aed9dbb9f8c5eb3b478f19 100644
--- a/substrate/doc/packages/misc.adoc
+++ b/substrate/doc/packages/misc.adoc
@@ -3,8 +3,6 @@
 
 :leveloffset: +3
 
-include::../../safe-mix/README.adoc[]
-
 include::../../subkey/README.adoc[]
 
 :leveloffset: -3
diff --git a/substrate/doc/packages/substrate.adoc b/substrate/doc/packages/substrate.adoc
index ee246d090924a3d6bec0ebf167854b670ec0926e..3df3366def95c98bbe831f1835224fa390d1e539 100644
--- a/substrate/doc/packages/substrate.adoc
+++ b/substrate/doc/packages/substrate.adoc
@@ -1,62 +1,66 @@
 
 == Substrate Packages
 
+=== Substrate Core
+
 :leveloffset: +3
 
-include::../../core/bft/README.adoc[]
+include::../../core/client/README.adoc[]
 
-include::../../core/cli/README.adoc[]
+include::../../core/test-client/README.adoc[]
 
-include::../../core/client/README.adoc[]
+include::../../core/client/db/README.adoc[]
+
+include::../../core/state-db/README.adoc[]
 
-include::../../codec/README.adoc[]
+include::../../core/consensus/common/README.adoc[]
 
-include::../../environmental/README.adoc[]
+include::../../core/consensus/rhd/README.adoc[]
 
 include::../../core/executor/README.adoc[]
 
+include::../../core/finality-grandpa/README.adoc[]
+
 include::../../core/transaction-pool/README.adoc[]
 
 include::../../core/keyring/README.adoc[]
 
-include::../../core/keystore/README.adoc[]
-
-include::../../core/misbehavior-check/README.adoc[]
-
 include::../../core/network/README.adoc[]
 
 include::../../core/network-libp2p/README.adoc[]
 
-include::../../core/primitives/README.adoc[]
-
-include::../../pwasm-alloc/README.adoc[]
-
 include::../../core/rpc/README.adoc[]
 
 include::../../core/rpc-servers/README.adoc[]
 
 include::../../srml/README.adoc[]
 
+include::../../core/sr-api/README.adoc[]
+
 include::../../core/sr-io/README.adoc[]
 
+include::../../core/sr-primitives/README.adoc[]
+
 include::../../core/sr-sandbox/README.adoc[]
 
 include::../../core/sr-std/README.adoc[]
 
-include::../../core/runtime-support/README.adoc[]
+include::../../core/state-machine/README.adoc[]
 
-include::../../core/serializer/README.adoc[]
+include::../../core/test-runtime/README.adoc[]
 
-include::../../core/service/README.adoc[]
+include::../../core/telemetry/README.adoc[]
 
-include::../../core/state-db/README.adoc[]
+include::../../core/cli/README.adoc[]
 
-include::../../core/state-machine/README.adoc[]
+include::../../core/service/README.adoc[]
 
-include::../../core/telemetry/README.adoc[]
+include::../../core/trie/README.adoc[]
 
-include::../../core/test-client/README.adoc[]
+include::../../core/keystore/README.adoc[]
 
-include::../../core/test-srml/README.adoc[]
+include::../../core/primitives/README.adoc[]
+
+include::../../core/serializer/README.adoc[]
 
 :leveloffset: -3
diff --git a/substrate/node/cli/Cargo.toml b/substrate/node/cli/Cargo.toml
index 61b31a5f67e74a516398f3975e293e897f1d8a31..6f1f92cc82e4e31c39b6e84fbe283193105afc3a 100644
--- a/substrate/node/cli/Cargo.toml
+++ b/substrate/node/cli/Cargo.toml
@@ -9,14 +9,19 @@ log = "0.4"
 tokio = "0.1.7"
 exit-future = "0.1"
 substrate-cli = { path = "../../core/cli" }
+parity-codec = { version = "2.1" }
+parking_lot = "0.4"
+slog = "^2"
+sr-io = { path = "../../core/sr-io" }
+substrate-client = { path = "../../core/client" }
 substrate-primitives = { path = "../../core/primitives" }
 node-runtime = { path = "../runtime" }
 node-primitives = { path = "../primitives" }
-node-network = { path = "../network" }
 hex-literal = "0.1"
 substrate-service = { path = "../../core/service" }
 substrate-transaction-pool = { path = "../../core/transaction-pool" }
 substrate-network = { path = "../../core/network" }
+substrate-consensus-aura = { path = "../../core/consensus/aura" }
 sr-primitives = { path = "../../core/sr-primitives" }
 node-executor = { path = "../executor" }
 
diff --git a/substrate/node/cli/src/chain_spec.rs b/substrate/node/cli/src/chain_spec.rs
index cc4612f27b8b5d6f8b9a0a34efae36d1fc6b610b..53cf074767b9e917673a65403849d708c0a3ba6c 100644
--- a/substrate/node/cli/src/chain_spec.rs
+++ b/substrate/node/cli/src/chain_spec.rs
@@ -17,8 +17,9 @@
 //! Substrate chain configurations.
 
 use primitives::{AuthorityId, ed25519};
+use node_primitives::AccountId;
 use node_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
-	SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig,
+	SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig, UpgradeKeyConfig,
 	ContractConfig, Permill, Perbill};
 use substrate_service;
 
@@ -45,7 +46,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
 	const CENTS: u128 = 1_000 * MILLICENTS;	// assume this is worth about a cent.
 	const DOLLARS: u128 = 100 * CENTS;
 
-	const SECS_PER_BLOCK: u64 = 5;
+	const SECS_PER_BLOCK: u64 = 4;
 	const MINUTES: u64 = 60 / SECS_PER_BLOCK;
 	const HOURS: u64 = MINUTES * 60;
 	const DAYS: u64 = HOURS * 24;
@@ -121,6 +122,9 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
 			max_depth: 1024,
 			block_gas_limit: 10_000_000,
 		}),
+		upgrade_key: Some(UpgradeKeyConfig {
+			key: endowed_accounts[0].clone(),
+		}),
 	}
 }
 
@@ -139,7 +143,7 @@ pub fn staging_testnet_config() -> ChainSpec {
 	)
 }
 
-fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
+fn testnet_genesis(initial_authorities: Vec<AuthorityId>, upgrade_key: AccountId) -> GenesisConfig {
 	let endowed_accounts = vec![
 		ed25519::Pair::from_seed(b"Alice                           ").public().0.into(),
 		ed25519::Pair::from_seed(b"Bob                             ").public().0.into(),
@@ -220,13 +224,18 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>) -> GenesisConfig {
 			max_depth: 1024,
 			block_gas_limit: 10_000_000,
 		}),
+		upgrade_key: Some(UpgradeKeyConfig {
+			key: upgrade_key,
+		}),
 	}
 }
 
 fn development_config_genesis() -> GenesisConfig {
 	testnet_genesis(vec![
 		ed25519::Pair::from_seed(b"Alice                           ").public().into(),
-	])
+	],
+		ed25519::Pair::from_seed(b"Alice                           ").public().0.into()
+	)
 }
 
 /// Development config (single validator Alice)
@@ -238,7 +247,9 @@ fn local_testnet_genesis() -> GenesisConfig {
 	testnet_genesis(vec![
 		ed25519::Pair::from_seed(b"Alice                           ").public().into(),
 		ed25519::Pair::from_seed(b"Bob                             ").public().into(),
-	])
+	],
+		ed25519::Pair::from_seed(b"Alice                           ").public().0.into()
+	)
 }
 
 /// Local testnet config (multivalidator Alice + Bob)
diff --git a/substrate/node/cli/src/lib.rs b/substrate/node/cli/src/lib.rs
index 0d8c9c4d71df002dcf4cdfd5609a26bb0d222e34..beb47f91ff86812dfffbc6f151ce99db2412fafc 100644
--- a/substrate/node/cli/src/lib.rs
+++ b/substrate/node/cli/src/lib.rs
@@ -30,9 +30,9 @@ extern crate hex_literal;
 #[cfg(test)]
 extern crate substrate_service_test as service_test;
 extern crate substrate_transaction_pool as transaction_pool;
+#[macro_use]
 extern crate substrate_network as network;
-extern crate node_network;
-extern crate sr_primitives as runtime_primitives;
+extern crate substrate_consensus_aura as consensus;
 extern crate node_primitives;
 #[macro_use]
 extern crate substrate_service;
diff --git a/substrate/node/cli/src/service.rs b/substrate/node/cli/src/service.rs
index 4e718816e19d9b357f985218d258829353ba94f7..d02ea48767b19ce900ed3443258faf30fb7115e8 100644
--- a/substrate/node/cli/src/service.rs
+++ b/substrate/node/cli/src/service.rs
@@ -22,38 +22,19 @@ use std::sync::Arc;
 use transaction_pool::{self, txpool::{Pool as TransactionPool}};
 use node_primitives::Block;
 use node_runtime::GenesisConfig;
-use node_network::Protocol as NodeProtocol;
 use substrate_service::{
 	FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
-	LightBackend, FullExecutor, LightExecutor
+	FullClient, LightClient, LightBackend, FullExecutor, LightExecutor,
+	Roles, TaskExecutor,
 };
-use network::import_queue::{BasicQueue, BlockOrigin, ImportBlock, Verifier};
-use runtime_primitives::{traits::Block as BlockT};
-use primitives::AuthorityId;
 use node_executor;
+use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue};
 
-// TODO: Remove me, when we have a functional consensus.
-/// A verifier that doesn't actually do any checks
-pub struct NoneVerifier;
-/// This Verifiyer accepts all data as valid
-impl<B: BlockT> Verifier<B> for NoneVerifier {
-	fn verify(
-		&self,
-		origin: BlockOrigin,
-		header: B::Header,
-		justification: Vec<u8>,
-		body: Option<Vec<B::Extrinsic>>
-	) -> Result<(ImportBlock<B>, Option<Vec<AuthorityId>>), String> {
-		Ok((ImportBlock {
-			origin,
-			header,
-			body,
-			finalized: true,
-			external_justification: justification,
-			internal_justification: vec![],
-			auxiliary: Vec::new(),
-		}, None))
-	}
+const AURA_SLOT_DURATION: u64 = 6;
+
+construct_simple_protocol! {
+	/// Demo protocol attachment for substrate.
+	pub struct NodeProtocol where Block = Block { }
 }
 
 construct_simple_service!(Service);
@@ -70,15 +51,48 @@ construct_service_factory! {
 		Genesis = GenesisConfig,
 		Configuration = (),
 		FullService = Service<FullComponents<Self>>
-			{ |config, executor| Service::<FullComponents<Factory>>::new(config, executor) },
+			{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor| {
+				let is_auth = config.roles == Roles::AUTHORITY;
+				Service::<FullComponents<Factory>>::new(config, executor.clone()).map(move |service|{
+					if is_auth {
+						if let Ok(Some(Ok(key))) = service.keystore().contents()
+							.map(|keys| keys.get(0).map(|k| service.keystore().load(k, "")))
+						{
+							info!("Using authority key {}", key.public());
+							let task = start_aura(
+								AuraConfig {
+									local_key:  Some(Arc::new(key)),
+									slot_duration: AURA_SLOT_DURATION,
+								},
+								service.client(),
+								service.proposer(),
+								service.network(),
+							);
+
+							executor.spawn(task);
+						}
+					}
+
+					service
+				})
+			}
+		},
 		LightService = Service<LightComponents<Self>>
 			{ |config, executor| Service::<LightComponents<Factory>>::new(config, executor) },
-		ImportQueue = BasicQueue<Block, NoneVerifier>
-			{ |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) }
-			{ |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) },
+		FullImportQueue = AuraImportQueue<Self::Block, FullClient<Self>>
+			{ |config, client| Ok(import_queue(AuraConfig {
+						local_key: None,
+						slot_duration: 5
+					}, client)) },
+		LightImportQueue = AuraImportQueue<Self::Block, LightClient<Self>>
+			{ |config, client| Ok(import_queue(AuraConfig {
+						local_key: None,
+						slot_duration: 5
+					}, client)) },
 	}
 }
 
+
 #[cfg(test)]
 mod tests {
 	#[cfg(feature = "rhd")]
diff --git a/substrate/node/consensus/Cargo.toml b/substrate/node/consensus/Cargo.toml
deleted file mode 100644
index c45818ee07ab05edffd42ecfc772eacf27906a8e..0000000000000000000000000000000000000000
--- a/substrate/node/consensus/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-name = "node-consensus"
-version = "0.1.0"
-authors = ["Parity Technologies <admin@parity.io>"]
-
-[dependencies]
-error-chain = "0.12"
-exit-future = "0.1"
-futures = "0.1.17"
-log = "0.4"
-node-primitives = { path = "../primitives" }
-node-runtime = { path = "../runtime" }
-parity-codec = "2.1"
-parking_lot = "0.4"
-rhododendron = "0.3"
-sr-primitives = { path = "../../core/sr-primitives" }
-srml-system = { path = "../../srml/system" }
-substrate-client = { path = "../../core/client" }
-substrate-primitives = { path = "../../core/primitives" }
-substrate-transaction-pool = { path = "../../core/transaction-pool" }
-tokio = "0.1.7"
-
-[dev-dependencies]
-substrate-keyring = { path = "../../core/keyring" }
diff --git a/substrate/node/consensus/README.adoc b/substrate/node/consensus/README.adoc
deleted file mode 100644
index ca2daa9eb2b09be8fe77ab432889c7a75799e6e5..0000000000000000000000000000000000000000
--- a/substrate/node/consensus/README.adoc
+++ /dev/null
@@ -1,5 +0,0 @@
-
-= Substrate Consensus
-
-placeholder
-//TODO Write content :)
diff --git a/substrate/node/consensus/src/error.rs b/substrate/node/consensus/src/error.rs
deleted file mode 100644
index 13192ae2020d3eb09d62c91cb15dd3bf26cc052b..0000000000000000000000000000000000000000
--- a/substrate/node/consensus/src/error.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2018 Parity Technologies (UK) Ltd.
-// This file is part of Substrate.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Errors that can occur during the consensus process.
-
-use primitives::AuthorityId;
-use client;
-
-error_chain! {
-	links {
-		Client(client::error::Error, client::error::ErrorKind);
-		Bft(::bft::Error, ::bft::ErrorKind);
-	}
-
-	errors {
-		NotValidator(id: AuthorityId) {
-			description("Local account ID not a validator at this block."),
-			display("Local account ID ({:?}) not a validator at this block.", id),
-		}
-		PrematureDestruction {
-			description("Proposer destroyed before finishing proposing or evaluating"),
-			display("Proposer destroyed before finishing proposing or evaluating"),
-		}
-		Timer(e: ::tokio::timer::Error) {
-			description("Failed to register or resolve async timer."),
-			display("Timer failed: {}", e),
-		}
-		Executor(e: ::futures::future::ExecuteErrorKind) {
-			description("Unable to dispatch agreement future"),
-			display("Unable to dispatch agreement future: {:?}", e),
-		}
-	}
-}
-
-impl From<::bft::InputStreamConcluded> for Error {
-	fn from(err: ::bft::InputStreamConcluded) -> Self {
-		::bft::Error::from(err).into()
-	}
-}
diff --git a/substrate/node/consensus/src/lib.rs b/substrate/node/consensus/src/lib.rs
deleted file mode 100644
index 9638a39715ff84b9b35933985ee94ed47defa401..0000000000000000000000000000000000000000
--- a/substrate/node/consensus/src/lib.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2018 Parity Technologies (UK) Ltd.
-// This file is part of Substrate.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
-
-//! This service uses BFT consensus provided by the substrate.
-
-#![cfg(feature="rhd")]
-
-extern crate node_runtime;
-extern crate node_primitives;
-
-extern crate parity_codec as codec;
-extern crate sr_primitives as runtime_primitives;
-extern crate srml_system;
-extern crate substrate_bft as bft;
-extern crate substrate_client as client;
-extern crate substrate_primitives as primitives;
-extern crate substrate_transaction_pool as transaction_pool;
-
-extern crate exit_future;
-extern crate futures;
-extern crate parking_lot;
-extern crate rhododendron;
-extern crate tokio;
-
-#[macro_use]
-extern crate error_chain;
-
-#[macro_use]
-extern crate log;
-
-#[cfg(test)]
-extern crate substrate_keyring;
-
-use std::sync::Arc;
-use std::time::{self, Duration, Instant};
-
-use client::{Client as SubstrateClient, CallExecutor};
-use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, Miscellaneous, OldTxQueue};
-use codec::{Decode, Encode};
-use node_primitives::{AccountId, Timestamp, SessionKey};
-use node_runtime::{Runtime, InherentError, TimestampInherentError, InherentData};
-use primitives::{AuthorityId, ed25519, Blake2Hasher};
-use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, As, BlockNumberToHash};
-use runtime_primitives::generic::{BlockId, Era};
-use srml_system::Trait as SystemT;
-use transaction_pool::txpool::{self, Pool as TransactionPool};
-use tokio::runtime::TaskExecutor;
-use tokio::timer::Delay;
-
-use futures::prelude::*;
-use futures::future;
-use parking_lot::RwLock;
-
-pub use self::error::{ErrorKind, Error, Result};
-pub use self::offline_tracker::OfflineTracker;
-pub use service::Service;
-
-mod evaluation;
-mod error;
-mod service;
-
-/// Shared offline validator tracker.
-pub type SharedOfflineTracker = Arc<RwLock<OfflineTracker>>;
-
-// block size limit.
-const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024;
-
-/// Build new blocks.
-pub trait BlockBuilder<Block: BlockT> {
-	/// Push an extrinsic onto the block. Fails if the extrinsic is invalid.
-	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<()>;
-}
-
-/// Local client abstraction for the consensus.
-pub trait AuthoringApi:
-	Send
-	+ Sync
-	+ BlockBuilderAPI<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
-	+ Core<<Self as AuthoringApi>::Block, AuthorityId, Error=<Self as AuthoringApi>::Error>
-	+ Miscellaneous<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
-	+ OldTxQueue<<Self as AuthoringApi>::Block, Error=<Self as AuthoringApi>::Error>
-{
-	/// The block used for this API type.
-	type Block: BlockT;
-	/// The error used by this API type.
-	type Error: std::error::Error;
-
-	/// Build a block on top of the given, with inherent extrinsics pre-pushed.
-	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
-		&self,
-		at: &BlockId<Self::Block>,
-		inherent_data: InherentData,
-		build_ctx: F,
-	) -> Result<Self::Block>;
-}
-
-impl<'a, B, E, Block> BlockBuilder<Block> for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where
-	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
-	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
-	Block: BlockT
-{
-	fn push_extrinsic(&mut self, extrinsic: <Block as BlockT>::Extrinsic) -> Result<()> {
-		client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into)
-	}
-}
-
-impl<'a, B, E, Block> AuthoringApi for SubstrateClient<B, E, Block> where
-	B: client::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
-	E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
-	Block: BlockT,
-{
-	type Block = Block;
-	type Error = client::error::Error;
-
-	fn build_block<F: FnMut(&mut BlockBuilder<Self::Block>) -> ()>(
-		&self,
-		at: &BlockId<Self::Block>,
-		inherent_data: InherentData,
-		mut build_ctx: F,
-	) -> Result<Self::Block> {
-		let runtime_version = self.runtime_version_at(at)?;
-
-		let mut block_builder = self.new_block_at(at)?;
-		if runtime_version.has_api(*b"inherent", 1) {
-			self.inherent_extrinsics(at, &inherent_data)?
-				.into_iter().try_for_each(|i| block_builder.push(i))?;
-		}
-
-		build_ctx(&mut block_builder);
-
-		block_builder.bake().map_err(Into::into)
-	}
-}
-
-/// A long-lived network which can create BFT message routing processes on demand.
-pub trait Network {
-	/// The block used for this API type.
-	type Block: BlockT;
-	/// The input stream of BFT messages. Should never logically conclude.
-	type Input: Stream<Item=bft::Communication<Self::Block>,Error=Error>;
-	/// The output sink of BFT messages. Messages sent here should eventually pass to all
-	/// current authorities.
-	type Output: Sink<SinkItem=bft::Communication<Self::Block>,SinkError=Error>;
-
-	/// Instantiate input and output streams.
-	fn communication_for(
-		&self,
-		validators: &[SessionKey],
-		local_id: SessionKey,
-		parent_hash: <Self::Block as BlockT>::Hash,
-		task_executor: TaskExecutor
-	) -> (Self::Input, Self::Output);
-}
-
-/// Proposer factory.
-pub struct ProposerFactory<N, C, A> where
-	C: AuthoringApi,
-	A: txpool::ChainApi,
-{
-	/// The client instance.
-	pub client: Arc<C>,
-	/// The transaction pool.
-	pub transaction_pool: Arc<TransactionPool<A>>,
-	/// The backing network handle.
-	pub network: N,
-	/// handle to remote task executor
-	pub handle: TaskExecutor,
-	/// Offline-tracker.
-	pub offline: SharedOfflineTracker,
-	/// Force delay in evaluation this long.
-	pub force_delay: Timestamp,
-}
-
-impl<N, C, A> bft::Environment<<C as AuthoringApi>::Block> for ProposerFactory<N, C, A> where
-	N: Network<Block=<C as AuthoringApi>::Block>,
-	C: AuthoringApi + BlockNumberToHash,
-	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
-	<<C as AuthoringApi>::Block as BlockT>::Hash:
-		Into<<Runtime as SystemT>::Hash> + PartialEq<primitives::H256> + Into<primitives::H256>,
-	Error: From<<C as AuthoringApi>::Error>
-{
-	type Proposer = Proposer<C, A>;
-	type Input = N::Input;
-	type Output = N::Output;
-	type Error = Error;
-
-	fn init(
-		&self,
-		parent_header: &<<C as AuthoringApi>::Block as BlockT>::Header,
-		authorities: &[AuthorityId],
-		sign_with: Arc<ed25519::Pair>,
-	) -> Result<(Self::Proposer, Self::Input, Self::Output)> {
-		use runtime_primitives::traits::Hash as HashT;
-		let parent_hash = parent_header.hash();
-
-		let id = BlockId::hash(parent_hash);
-		let random_seed = self.client.random_seed(&id)?;
-		let random_seed = <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Hashing::hash(random_seed.as_ref());
-
-		let validators = self.client.validators(&id)?;
-		self.offline.write().note_new_block(&validators[..]);
-
-		info!("Starting consensus session on top of parent {:?}", parent_hash);
-
-		let local_id = sign_with.public().0.into();
-		let (input, output) = self.network.communication_for(
-			authorities,
-			local_id,
-			parent_hash.clone(),
-			self.handle.clone(),
-		);
-		let now = Instant::now();
-		let proposer = Proposer {
-			client: self.client.clone(),
-			start: now,
-			local_key: sign_with,
-			parent_hash,
-			parent_id: id,
-			parent_number: *parent_header.number(),
-			random_seed,
-			transaction_pool: self.transaction_pool.clone(),
-			offline: self.offline.clone(),
-			validators,
-			minimum_timestamp: current_timestamp() + self.force_delay,
-		};
-
-		Ok((proposer, input, output))
-	}
-}
-
-/// The proposer logic.
-pub struct Proposer<C: AuthoringApi, A: txpool::ChainApi> {
-	client: Arc<C>,
-	start: Instant,
-	local_key: Arc<ed25519::Pair>,
-	parent_hash: <<C as AuthoringApi>::Block as BlockT>::Hash,
-	parent_id: BlockId<<C as AuthoringApi>::Block>,
-	parent_number: <<<C as AuthoringApi>::Block as BlockT>::Header as HeaderT>::Number,
-	random_seed: <<C as AuthoringApi>::Block as BlockT>::Hash,
-	transaction_pool: Arc<TransactionPool<A>>,
-	offline: SharedOfflineTracker,
-	validators: Vec<AccountId>,
-	minimum_timestamp: u64,
-}
-
-impl<C: AuthoringApi, A: txpool::ChainApi> Proposer<C, A> {
-	fn primary_index(&self, round_number: usize, len: usize) -> usize {
-		use primitives::uint::U256;
-
-		let big_len = U256::from(len);
-		let offset = U256::from_big_endian(self.random_seed.as_ref()) % big_len;
-		let offset = offset.low_u64() as usize + round_number;
-		offset % len
-	}
-}
-
-impl<C, A> bft::Proposer<<C as AuthoringApi>::Block> for Proposer<C, A> where
-	C: AuthoringApi + BlockNumberToHash,
-	A: txpool::ChainApi<Block=<C as AuthoringApi>::Block>,
-	<<C as AuthoringApi>::Block as BlockT>::Hash:
-		Into<<Runtime as SystemT>::Hash> + PartialEq<primitives::H256> + Into<primitives::H256>,
-	error::Error: From<<C as AuthoringApi>::Error>
-{
-	type Create = Result<<C as AuthoringApi>::Block>;
-	type Error = Error;
-	type Evaluate = Box<Future<Item=bool, Error=Error>>;
-
-	fn propose(&self) -> Result<<C as AuthoringApi>::Block> {
-		use runtime_primitives::traits::BlakeTwo256;
-
-		const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60);
-
-		// TODO: handle case when current timestamp behind that in state.
-		let timestamp = ::std::cmp::max(self.minimum_timestamp, current_timestamp());
-
-		let elapsed_since_start = self.start.elapsed();
-		let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS {
-			Vec::new()
-		} else {
-			self.offline.read().reports(&self.validators[..])
-		};
-
-		if !offline_indices.is_empty() {
-			info!(
-				"Submitting offline validators {:?} for slash-vote",
-				offline_indices.iter().map(|&i| self.validators[i as usize]).collect::<Vec<_>>(),
-				)
-		}
-
-		let inherent_data = InherentData {
-			timestamp,
-			offline_indices,
-		};
-
-		let block = self.client.build_block(
-			&self.parent_id,
-			inherent_data,
-			|block_builder| {
-				let mut unqueue_invalid = Vec::new();
-				self.transaction_pool.ready(|pending_iterator| {
-					let mut pending_size = 0;
-					for pending in pending_iterator {
-						// TODO [ToDr] Probably get rid of it, and validate in runtime.
-						let encoded_size = pending.data.encode().len();
-						if pending_size + encoded_size >= MAX_TRANSACTIONS_SIZE { break }
-
-						match block_builder.push_extrinsic(pending.data.clone()) {
-							Ok(()) => {
-								pending_size += encoded_size;
-							}
-							Err(e) => {
-								trace!(target: "transaction-pool", "Invalid transaction: {}", e);
-								unqueue_invalid.push(pending.hash.clone());
-							}
-						}
-					}
-				});
-
-				self.transaction_pool.remove_invalid(&unqueue_invalid);
-			})?;
-
-		info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
-			  block.header().number(),
-			  <<C as AuthoringApi>::Block as BlockT>::Hash::from(block.header().hash()),
-			  block.header().parent_hash(),
-			  block.extrinsics().iter()
-			  .map(|xt| format!("{}", BlakeTwo256::hash_of(xt)))
-			  .collect::<Vec<_>>()
-			  .join(", ")
-			 );
-
-		let substrate_block = Decode::decode(&mut block.encode().as_slice())
-			.expect("blocks are defined to serialize to substrate blocks correctly; qed");
-
-		assert!(evaluation::evaluate_initial(
-			&substrate_block,
-			&self.parent_hash,
-			self.parent_number,
-		).is_ok());
-
-		Ok(substrate_block)
-	}
-
-	fn evaluate(&self, unchecked_proposal: &<C as AuthoringApi>::Block) -> Self::Evaluate {
-		debug!(target: "bft", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash);
-
-		// do initial serialization and structural integrity checks.
-		match evaluation::evaluate_initial(
-			unchecked_proposal,
-			&self.parent_hash,
-			self.parent_number,
-		) {
-			Ok(p) => p,
-			Err(e) => {
-				// TODO: these errors are easily re-checked in runtime.
-				debug!(target: "bft", "Invalid proposal (initial evaluation failed): {:?}", e);
-				return Box::new(future::ok(false));
-			}
-		};
-
-		let current_timestamp = current_timestamp();
-		let inherent = InherentData::new(
-			current_timestamp,
-			self.offline.read().reports(&self.validators)
-		);
-		let proposed_timestamp = match self.client.check_inherents(
-			&self.parent_id,
-			&unchecked_proposal,
-			&inherent
-		) {
-			Ok(Ok(())) => None,
-			Ok(Err(InherentError::Timestamp(TimestampInherentError::TimestampInFuture(timestamp)))) => Some(timestamp),
-			Ok(Err(e)) => {
-				debug!(target: "bft", "Invalid proposal (check_inherents): {:?}", e);
-				return Box::new(future::ok(false));
-			},
-			Err(e) => {
-				debug!(target: "bft", "Could not call into runtime: {:?}", e);
-				return Box::new(future::ok(false));
-			}
-		};
-
-		let vote_delays = {
-			// the duration until the given timestamp is current
-			let proposed_timestamp = ::std::cmp::max(self.minimum_timestamp, proposed_timestamp.unwrap_or(0));
-			let timestamp_delay = if proposed_timestamp > current_timestamp {
-				let delay_s = proposed_timestamp - current_timestamp;
-				debug!(target: "bft", "Delaying evaluation of proposal for {} seconds", delay_s);
-				Some(Instant::now() + Duration::from_secs(delay_s))
-			} else {
-				None
-			};
-
-			match timestamp_delay {
-				Some(duration) => future::Either::A(
-					Delay::new(duration).map_err(|e| ErrorKind::Timer(e).into())
-				),
-				None => future::Either::B(future::ok(())),
-			}
-		};
-
-		// evaluate whether the block is actually valid.
-		// TODO: is it better to delay this until the delays are finished?
-		let evaluated = match self.client.execute_block(&self.parent_id, &unchecked_proposal.clone()).map_err(Error::from) {
-			Ok(()) => Ok(true),
-			Err(err) => match err.kind() {
-				error::ErrorKind::Client(client::error::ErrorKind::Execution(_)) => Ok(false),
-				_ => Err(err)
-			}
-		};
-
-		let future = future::result(evaluated).and_then(move |good| {
-			let end_result = future::ok(good);
-			if good {
-				// delay a "good" vote.
-				future::Either::A(vote_delays.and_then(|_| end_result))
-			} else {
-				// don't delay a "bad" evaluation.
-				future::Either::B(end_result)
-			}
-		});
-
-		Box::new(future) as Box<_>
-	}
-
-	fn round_proposer(&self, round_number: usize, authorities: &[AuthorityId]) -> AuthorityId {
-		let offset = self.primary_index(round_number, authorities.len());
-		let proposer = authorities[offset].clone();
-		trace!(target: "bft", "proposer for round {} is {}", round_number, proposer);
-
-		proposer
-	}
-
-	fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior<<<C as AuthoringApi>::Block as BlockT>::Hash>)>) {
-		use rhododendron::Misbehavior as GenericMisbehavior;
-		use runtime_primitives::bft::{MisbehaviorKind, MisbehaviorReport};
-		use node_runtime::{Call, UncheckedExtrinsic, ConsensusCall};
-
-		let mut next_index = {
-			let local_id = self.local_key.public().0;
-			// let cur_index = self.transaction_pool.cull_and_get_pending(&BlockId::hash(self.parent_hash), |pending| pending
-			// 	.filter(|tx| tx.verified.sender == local_id)
-			// 	.last()
-			// 	.map(|tx| Ok(tx.verified.index()))
-			// 	.unwrap_or_else(|| self.client.account_nonce(&self.parent_id, local_id))
-			// 	.map_err(Error::from)
-			// );
-			// TODO [ToDr] Use pool data
-			let cur_index: Result<u64> = self.client.account_nonce(&self.parent_id, &local_id).map_err(Error::from);
-
-			match cur_index {
-				Ok(cur_index) => cur_index + 1,
-				Err(e) => {
-					warn!(target: "consensus", "Error computing next transaction index: {:?}", e);
-					return;
-				}
-			}
-		};
-
-		for (target, misbehavior) in misbehavior {
-			let report = MisbehaviorReport {
-				parent_hash: self.parent_hash.into(),
-				parent_number: self.parent_number.as_(),
-				target,
-				misbehavior: match misbehavior {
-					GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue,
-					GenericMisbehavior::DoublePropose(_, _, _) => continue,
-					GenericMisbehavior::DoublePrepare(round, (h1, s1), (h2, s2))
-						=> MisbehaviorKind::BftDoublePrepare(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)),
-					GenericMisbehavior::DoubleCommit(round, (h1, s1), (h2, s2))
-						=> MisbehaviorKind::BftDoubleCommit(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)),
-				}
-			};
-			let payload = (next_index, Call::Consensus(ConsensusCall::report_misbehavior(report)), Era::immortal(), self.client.genesis_hash());
-			let signature = self.local_key.sign(&payload.encode()).into();
-			next_index += 1;
-
-			let local_id = self.local_key.public().0.into();
-			let extrinsic = UncheckedExtrinsic {
-				signature: Some((node_runtime::RawAddress::Id(local_id), signature, payload.0, Era::immortal())),
-				function: payload.1,
-			};
-			let uxt: <<C as AuthoringApi>::Block as BlockT>::Extrinsic = Decode::decode(&mut extrinsic.encode().as_slice()).expect("Encoded extrinsic is valid");
-			let hash = BlockId::<<C as AuthoringApi>::Block>::hash(self.parent_hash);
-			if let Err(e) = self.transaction_pool.submit_one(&hash, uxt) {
-				warn!("Error importing misbehavior report: {:?}", e);
-			}
-		}
-	}
-
-	fn on_round_end(&self, round_number: usize, was_proposed: bool) {
-		let primary_validator = self.validators[
-			self.primary_index(round_number, self.validators.len())
-		];
-
-
-		// alter the message based on whether we think the empty proposer was forced to skip the round.
-		// this is determined by checking if our local validator would have been forced to skip the round.
-		if !was_proposed {
-			let public = ed25519::Public::from_raw(primary_validator.0);
-			info!(
-				"Potential Offline Validator: {} failed to propose during assigned slot: {}",
-				public,
-				round_number,
-			);
-		}
-
-		self.offline.write().note_round_end(primary_validator, was_proposed);
-	}
-}
-
-fn current_timestamp() -> Timestamp {
-	time::SystemTime::now().duration_since(time::UNIX_EPOCH)
-		.expect("now always later than unix epoch; qed")
-		.as_secs()
-}
diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs
index 6a2b8061c373529ae3eaa66ce4f967b51e1dd435..bdd8b10235214db0c168dce1fa2ff98372ea62a5 100644
--- a/substrate/node/executor/src/lib.rs
+++ b/substrate/node/executor/src/lib.rs
@@ -254,6 +254,7 @@ mod tests {
 			timestamp: Some(Default::default()),
 			treasury: Some(Default::default()),
 			contract: Some(Default::default()),
+			upgrade_key: Some(Default::default()),
 		}.build_storage().unwrap())
 	}
 
@@ -291,9 +292,9 @@ mod tests {
 			1,
 			GENESIS_HASH.into(),
 			if support_changes_trie {
-				hex!("ffa85ed1832eae3e25e684d4f993ff0b5e8b6ac4d7ba0f40a5fb0114fda22f3d").into()
+				hex!("978a3ff733a86638da39d36a349c693b5cf562bcc8db30fec6c2b6c40f925a9b").into()
 			} else {
-				hex!("98971908b8923d07944cdf7ee658c203d17042ef447169adbdfec8160cfabcad").into()
+				hex!("7bbad534e3de3db3c8cda015c4e8ed8ba10dde7e3fca21f4fd4fbc686e6c1410").into()
 			},
 			if support_changes_trie {
 				Some(hex!("1f8f44dcae8982350c14dee720d34b147e73279f5a2ce1f9781195a991970978").into())
@@ -317,7 +318,7 @@ mod tests {
 		construct_block(
 			2,
 			block1(false).1,
-			hex!("788a2e8b23e4b30e1bce347ca6415fd0080e989d40741c86995b9ad539bb76b3").into(),
+			hex!("7be30152ee2ee909047cffad5f0a28bf8c2b0a97c124b500aeac112f6917738e").into(),
 			None,
 			vec![
 				CheckedExtrinsic {
@@ -340,7 +341,7 @@ mod tests {
 		construct_block(
 			1,
 			GENESIS_HASH.into(),
-			hex!("acc03af5b3972deaf9dde4dfd99c5614a5360454313681b6fc299d1644ae8a59").into(),
+			hex!("325a73726dc640af41becb42938e7152e218f130219c0695aae35b6a156f93f3").into(),
 			None,
 			vec![
 				CheckedExtrinsic {
@@ -622,7 +623,7 @@ mod tests {
 		let b = construct_block(
 			1,
 			GENESIS_HASH.into(),
-			hex!("21fb6fb965f012ae3c6e521b71b5b57d6df17c738c52f202ec2809ca235eb082").into(),
+			hex!("d68586d5098535e04ff7a12d71a9c9dc719960f318862e636e78a8e98cf4b8d4").into(),
 			None,
 			vec![
 				CheckedExtrinsic {
diff --git a/substrate/node/network/Cargo.toml b/substrate/node/network/Cargo.toml
deleted file mode 100644
index 44fbdb5abae58196b5732ecf48525bdf64913b6d..0000000000000000000000000000000000000000
--- a/substrate/node/network/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "node-network"
-version = "0.1.0"
-authors = ["Parity Technologies <admin@parity.io>"]
-description = "Substrate node networking protocol"
-
-[dependencies]
-node-consensus = { path = "../consensus" }
-node-primitives = { path = "../primitives" }
-substrate-consensus-rhd = { path = "../../core/consensus/rhd" }
-substrate-network = { path = "../../core/network" }
-substrate-primitives = { path = "../../core/primitives" }
-futures = "0.1"
-tokio = "0.1.7"
-log = "0.4"
-rhododendron = "0.3"
diff --git a/substrate/node/network/src/consensus.rs b/substrate/node/network/src/consensus.rs
deleted file mode 100644
index 44d338d3303982206179c3f7fc5e716125b0a53c..0000000000000000000000000000000000000000
--- a/substrate/node/network/src/consensus.rs
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2018 Parity Technologies (UK) Ltd.
-// This file is part of Substrate.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
-
-//! The "consensus" networking code built on top of the base network service.
-//! This fulfills the `node_consensus::Network` trait, providing a hook to be called
-//! each time consensus begins on a new chain head.
-
-use bft;
-use substrate_primitives::ed25519;
-use substrate_network::{self as net, generic_message as msg};
-use substrate_network::consensus_gossip::ConsensusMessage;
-use node_consensus::{AuthoringApi, Network};
-use node_primitives::{Block, Hash, SessionKey};
-use rhododendron;
-
-use futures::prelude::*;
-use futures::sync::mpsc;
-
-use std::sync::Arc;
-
-use tokio::runtime::TaskExecutor;
-use tokio::executor::Executor;
-
-use super::NetworkService;
-
-/// Sink for output BFT messages.
-pub struct BftSink<E> {
-	network: Arc<NetworkService>,
-	parent_hash: Hash,
-	_marker: ::std::marker::PhantomData<E>,
-}
-
-impl<E> Sink for BftSink<E> {
-	type SinkItem = bft::Communication<Block>;
-	// TODO: replace this with the ! type when that's stabilized
-	type SinkError = E;
-
-	fn start_send(&mut self, message: bft::Communication<Block>)
-		-> ::futures::StartSend<bft::Communication<Block>, E>
-	{
-		let network_message = net::LocalizedBftMessage {
-			message: match message {
-				rhododendron::Communication::Consensus(c) => msg::BftMessage::Consensus(match c {
-					rhododendron::LocalizedMessage::Propose(proposal) => msg::SignedConsensusMessage::Propose(msg::SignedConsensusProposal {
-						round_number: proposal.round_number as u32,
-						proposal: proposal.proposal,
-						digest: proposal.digest,
-						sender: proposal.sender,
-						digest_signature: proposal.digest_signature.signature,
-						full_signature: proposal.full_signature.signature,
-					}),
-					rhododendron::LocalizedMessage::Vote(vote) => msg::SignedConsensusMessage::Vote(msg::SignedConsensusVote {
-						sender: vote.sender,
-						signature: vote.signature.signature,
-						vote: match vote.vote {
-							rhododendron::Vote::Prepare(r, h) => msg::ConsensusVote::Prepare(r as u32, h),
-							rhododendron::Vote::Commit(r, h) => msg::ConsensusVote::Commit(r as u32, h),
-							rhododendron::Vote::AdvanceRound(r) => msg::ConsensusVote::AdvanceRound(r as u32),
-						}
-					}),
-				}),
-				rhododendron::Communication::Auxiliary(justification) => {
-					let unchecked: bft::UncheckedJustification<_> = justification.uncheck().into();
-					msg::BftMessage::Auxiliary(unchecked.into())
-				}
-			},
-			parent_hash: self.parent_hash,
-		};
-		self.network.with_spec(
-			move |spec, ctx| spec.consensus_gossip.multicast_bft_message(ctx, network_message)
-		);
-		Ok(::futures::AsyncSink::Ready)
-	}
-
-	fn poll_complete(&mut self) -> ::futures::Poll<(), E> {
-		Ok(Async::Ready(()))
-	}
-}
-
-// check signature and authority validity of message.
-fn process_bft_message(
-	msg: msg::LocalizedBftMessage<Block, Hash>,
-	local_id: &SessionKey,
-	authorities: &[SessionKey]
-	) -> Result<Option<bft::Communication<Block>>, bft::Error>
-{
-	Ok(Some(match msg.message {
-		msg::BftMessage::Consensus(c) => rhododendron::Communication::Consensus(match c {
-			msg::SignedConsensusMessage::Propose(proposal) => rhododendron::LocalizedMessage::Propose({
-				if &proposal.sender == local_id { return Ok(None) }
-				let proposal = rhododendron::LocalizedProposal {
-					round_number: proposal.round_number as usize,
-					proposal: proposal.proposal,
-					digest: proposal.digest,
-					sender: proposal.sender,
-					digest_signature: ed25519::LocalizedSignature {
-						signature: proposal.digest_signature,
-						signer: ed25519::Public(proposal.sender.into()),
-					},
-					full_signature: ed25519::LocalizedSignature {
-						signature: proposal.full_signature,
-						signer: ed25519::Public(proposal.sender.into()),
-					}
-				};
-				bft::check_proposal(authorities, &msg.parent_hash, &proposal)?;
-
-				trace!(target: "bft", "importing proposal message for round {} from {}", proposal.round_number, Hash::from(proposal.sender.0));
-				proposal
-			}),
-			msg::SignedConsensusMessage::Vote(vote) => rhododendron::LocalizedMessage::Vote({
-				if &vote.sender == local_id { return Ok(None) }
-				let vote = rhododendron::LocalizedVote {
-					sender: vote.sender,
-					signature: ed25519::LocalizedSignature {
-						signature: vote.signature,
-						signer: ed25519::Public(vote.sender.0),
-					},
-					vote: match vote.vote {
-						msg::ConsensusVote::Prepare(r, h) => rhododendron::Vote::Prepare(r as usize, h),
-						msg::ConsensusVote::Commit(r, h) => rhododendron::Vote::Commit(r as usize, h),
-						msg::ConsensusVote::AdvanceRound(r) => rhododendron::Vote::AdvanceRound(r as usize),
-					}
-				};
-				bft::check_vote::<Block>(authorities, &msg.parent_hash, &vote)?;
-
-				trace!(target: "bft", "importing vote {:?} from {}", vote.vote, Hash::from(vote.sender.0));
-				vote
-			}),
-		}),
-		msg::BftMessage::Auxiliary(a) => {
-			let justification = bft::UncheckedJustification::from(a);
-			// TODO: get proper error
-			let justification: Result<_, bft::Error> = bft::check_prepare_justification::<Block>(authorities, msg.parent_hash, justification)
-				.map_err(|_| bft::ErrorKind::InvalidJustification.into());
-			rhododendron::Communication::Auxiliary(justification?)
-		},
-	}))
-}
-
-// task that processes all gossipped consensus messages,
-// checking signatures
-struct MessageProcessTask {
-	inner_stream: mpsc::UnboundedReceiver<ConsensusMessage<Block>>,
-	bft_messages: mpsc::UnboundedSender<bft::Communication<Block>>,
-	validators: Vec<SessionKey>,
-	local_id: SessionKey,
-}
-
-impl MessageProcessTask {
-	fn process_message(&self, msg: ConsensusMessage<Block>) -> Option<Async<()>> {
-		match msg {
-			ConsensusMessage::Bft(msg) => {
-				match process_bft_message(msg, &self.local_id, &self.validators[..]) {
-					Ok(Some(msg)) => {
-						if let Err(_) = self.bft_messages.unbounded_send(msg) {
-							// if the BFT receiving stream has ended then
-							// we should just bail.
-							trace!(target: "bft", "BFT message stream appears to have closed");
-							return Some(Async::Ready(()));
-						}
-					}
-					Ok(None) => {} // ignored local message
-					Err(e) => {
-						debug!("Message validation failed: {:?}", e);
-					}
-				}
-			}
-			ConsensusMessage::ChainSpecific(_, _) => {
-				panic!("ChainSpecific messages are not allowed by the top level message handler");
-			}
-		}
-
-		None
-	}
-}
-
-impl Future for MessageProcessTask {
-	type Item = ();
-	type Error = ();
-
-	fn poll(&mut self) -> Poll<(), ()> {
-		loop {
-			match self.inner_stream.poll() {
-				Ok(Async::Ready(Some(val))) => if let Some(async) = self.process_message(val) {
-					return Ok(async);
-				},
-				Ok(Async::Ready(None)) => return Ok(Async::Ready(())),
-				Ok(Async::NotReady) => return Ok(Async::NotReady),
-				Err(e) => {
-					debug!(target: "node-network", "Error getting consensus message: {:?}", e);
-					return Err(e);
-				},
-			}
-		}
-	}
-}
-
-/// Input stream from the consensus network.
-pub struct InputAdapter {
-	input: mpsc::UnboundedReceiver<bft::Communication<Block>>,
-}
-
-impl Stream for InputAdapter {
-	type Item = bft::Communication<Block>;
-	type Error = ::node_consensus::Error;
-
-	fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
-		match self.input.poll() {
-			Err(_) | Ok(Async::Ready(None)) => Err(bft::InputStreamConcluded.into()),
-			Ok(x) => Ok(x)
-		}
-	}
-}
-
-/// Wrapper around the network service
-pub struct ConsensusNetwork<P> {
-	network: Arc<NetworkService>,
-	api: Arc<P>,
-}
-
-impl<P> ConsensusNetwork<P> {
-	/// Create a new consensus networking object.
-	pub fn new(network: Arc<NetworkService>, api: Arc<P>) -> Self {
-		ConsensusNetwork { network, api }
-	}
-}
-
-impl<P> Clone for ConsensusNetwork<P> {
-	fn clone(&self) -> Self {
-		ConsensusNetwork {
-			network: self.network.clone(),
-			api: self.api.clone(),
-		}
-	}
-}
-
-/// A long-lived network which can create parachain statement and BFT message routing processes on demand.
-impl<P: AuthoringApi + Send + Sync + 'static> Network for ConsensusNetwork<P> {
-	/// The input stream of BFT messages. Should never logically conclude.
-	type Input = InputAdapter;
-	/// The output sink of BFT messages. Messages sent here should eventually pass to all
-	/// current validators.
-	type Output = BftSink<::node_consensus::Error>;
-	type Block = Block;
-
-	/// Get input and output streams of BFT messages.
-	fn communication_for(
-		&self, validators: &[SessionKey],
-		local_id: SessionKey,
-		parent_hash: Hash,
-		mut task_executor: TaskExecutor
-	) -> (Self::Input, Self::Output)
-	{
-		let sink = BftSink {
-			network: self.network.clone(),
-			parent_hash,
-			_marker: Default::default(),
-		};
-
-		let (bft_send, bft_recv) = mpsc::unbounded();
-
-		// spin up a task in the background that processes all incoming statements
-		// TODO: propagate statements on a timer?
-		let process_task = self.network.with_spec(|spec, _ctx| {
-			spec.consensus_gossip.new_session(parent_hash);
-			MessageProcessTask {
-				inner_stream: spec.consensus_gossip.messages_for(parent_hash),
-				bft_messages: bft_send,
-				validators: validators.to_vec(),
-				local_id,
-			}
-		});
-
-		if let Err(e) = Executor::spawn(&mut task_executor, Box::new(process_task)) {
-			debug!(target: "node-network", "Cannot spawn message processing: {:?}", e)
-		}
-
-		(InputAdapter { input: bft_recv }, sink)
-	}
-}
diff --git a/substrate/node/network/src/lib.rs b/substrate/node/network/src/lib.rs
deleted file mode 100644
index 9e2f96d5f75aa45f946798e50bca77509499ea84..0000000000000000000000000000000000000000
--- a/substrate/node/network/src/lib.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 Parity Technologies (UK) Ltd.
-// This file is part of Substrate.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Substrate-specific network implementation.
-//!
-//! This manages gossip of consensus messages for BFT.
-
-#![warn(unused_extern_crates)]
-
-#[macro_use]
-extern crate substrate_network;
-extern crate node_primitives;
-
-use node_primitives::{Block, Hash};
-use substrate_network::consensus_gossip::ConsensusGossip;
-
-/// Specialization of the network service for the node protocol.
-pub type NetworkService = ::substrate_network::Service<Block, Protocol, Hash>;
-
-construct_simple_protocol! {
-	/// Demo protocol attachment for substrate.
-	pub struct Protocol where Block = Block {
-		consensus_gossip: ConsensusGossip<Block>,
-	}
-}
diff --git a/substrate/node/runtime/Cargo.toml b/substrate/node/runtime/Cargo.toml
index ac37cff45632da9643ab9765f3e44bdbc90104a1..8add782018ad71762ab2e98ea63f8b983820975f 100644
--- a/substrate/node/runtime/Cargo.toml
+++ b/substrate/node/runtime/Cargo.toml
@@ -29,6 +29,7 @@ srml-staking = { path = "../../srml/staking" }
 srml-system = { path = "../../srml/system" }
 srml-timestamp = { path = "../../srml/timestamp" }
 srml-treasury = { path = "../../srml/treasury" }
+srml-upgrade-key = { path = "../../srml/upgrade-key" }
 sr-version = { path = "../../core/sr-version" }
 node-primitives = { path = "../primitives" }
 
@@ -53,6 +54,7 @@ std = [
 	"srml-system/std",
 	"srml-timestamp/std",
 	"srml-treasury/std",
+	"srml-upgrade-key/std",
 	"sr-version/std",
 	"node-primitives/std",
 	"serde_derive",
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 36dcd347b9651e3e7fac819867b60321bb3ee4b9..998bb6640b047f9e2927fa7e64c934853ad79f65 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -52,6 +52,7 @@ extern crate srml_staking as staking;
 extern crate srml_system as system;
 extern crate srml_timestamp as timestamp;
 extern crate srml_treasury as treasury;
+extern crate srml_upgrade_key as upgrade_key;
 #[macro_use]
 extern crate sr_version as version;
 extern crate node_primitives;
@@ -62,12 +63,12 @@ use node_primitives::{
 	AccountId, AccountIndex, Balance, BlockNumber, Hash, Index,
 	SessionKey, Signature
 };
-use runtime_api::runtime::*;
+use runtime_api::{runtime::*, id::*};
 use runtime_primitives::ApplyResult;
 use runtime_primitives::transaction_validity::TransactionValidity;
 use runtime_primitives::generic;
 use runtime_primitives::traits::{Convert, BlakeTwo256, Block as BlockT};
-use version::{RuntimeVersion, ApiId};
+use version::RuntimeVersion;
 use council::{motions as council_motions, voting as council_voting};
 #[cfg(feature = "std")]
 use council::seats as council_seats;
@@ -81,14 +82,11 @@ pub use timestamp::Call as TimestampCall;
 pub use balances::Call as BalancesCall;
 pub use runtime_primitives::{Permill, Perbill};
 pub use timestamp::BlockPeriod;
-pub use srml_support::StorageValue;
+pub use srml_support::{StorageValue, RuntimeMetadata};
 
 const TIMESTAMP_SET_POSITION: u32 = 0;
 const NOTE_OFFLINE_POSITION: u32 = 1;
 
-const INHERENT: ApiId = *b"inherent";
-const VALIDATX: ApiId = *b"validatx";
-
 /// Runtime version.
 pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: ver_str!("node"),
@@ -96,7 +94,11 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	authoring_version: 1,
 	spec_version: 1,
 	impl_version: 0,
-	apis: apis_vec!([(INHERENT, 1), (VALIDATX, 1)]),
+	apis: apis_vec!([
+		(BLOCK_BUILDER, 1),
+		(TAGGED_TRANSACTION_QUEUE, 1),
+		(METADATA, 1)
+	]),
 };
 
 /// Native version.
@@ -191,15 +193,19 @@ impl contract::Trait for Runtime {
 	type Event = Event;
 }
 
+impl upgrade_key::Trait for Runtime {
+	type Event = Event;
+}
+
 construct_runtime!(
 	pub enum Runtime with Log(InternalLog: DigestItem<Hash, SessionKey>) where
 		Block = Block,
 		UncheckedExtrinsic = UncheckedExtrinsic
 	{
 		System: system::{default, Log(ChangesTrieRoot)},
+		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
 		Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
 		Balances: balances,
-		Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
 		Session: session,
 		Staking: staking,
 		Democracy: democracy,
@@ -209,6 +215,7 @@ construct_runtime!(
 		CouncilSeats: council_seats::{Config<T>},
 		Treasury: treasury,
 		Contract: contract::{Module, Call, Config<T>, Event<T>},
+		UpgradeKey: upgrade_key,
 	}
 );
 
@@ -246,8 +253,8 @@ impl_apis! {
 		}
 	}
 
-	impl Metadata for Runtime {
-		fn metadata() -> Vec<u8> {
+	impl Metadata<RuntimeMetadata> for Runtime {
+		fn metadata() -> RuntimeMetadata {
 			Runtime::metadata()
 		}
 	}
@@ -278,33 +285,9 @@ impl_apis! {
 		}
 	}
 
-	impl OldTxQueue<AccountId, Index, Address, AccountId> for Runtime {
-		fn account_nonce(account: AccountId) -> Index {
-			System::account_nonce(&account)
-		}
-
-		fn lookup_address(address: Address) -> Option<AccountId> {
-			Balances::lookup_address(address)
-		}
-	}
-
 	impl TaggedTransactionQueue<Block, TransactionValidity> for Runtime {
 		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
 			Executive::validate_transaction(tx)
 		}
 	}
-
-	impl Miscellaneous<AccountId, u64> for Runtime {
-		fn validator_count() -> u32 {
-			Session::validator_count()
-		}
-
-		fn validators() -> Vec<AccountId> {
-			Session::validators()
-		}
-
-		fn timestamp() -> u64 {
-			Timestamp::get()
-		}
-	}
 }
diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock
index fc45e6f94c531a6a7ad856d4dc40d58e01b2ce31..0aa58928c2a2dc926b3ec6e4ed254306657294b5 100644
--- a/substrate/node/runtime/wasm/Cargo.lock
+++ b/substrate/node/runtime/wasm/Cargo.lock
@@ -285,6 +285,7 @@ dependencies = [
  "srml-system 0.1.0",
  "srml-timestamp 0.1.0",
  "srml-treasury 0.1.0",
+ "srml-upgrade-key 0.1.0",
  "substrate-primitives 0.1.0",
 ]
 
@@ -817,6 +818,24 @@ dependencies = [
  "substrate-primitives 0.1.0",
 ]
 
+[[package]]
+name = "srml-upgrade-key"
+version = "0.1.0"
+dependencies = [
+ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sr-io 0.1.0",
+ "sr-primitives 0.1.0",
+ "sr-std 0.1.0",
+ "srml-consensus 0.1.0",
+ "srml-support 0.1.0",
+ "srml-system 0.1.0",
+ "substrate-primitives 0.1.0",
+]
+
 [[package]]
 name = "stable_deref_trait"
 version = "1.1.1"
diff --git a/substrate/node/runtime/wasm/Cargo.toml b/substrate/node/runtime/wasm/Cargo.toml
index 7fb33ff26b4c8fe82b9439adae28b6083ac5f0e1..7df582a8f0c92aac179af3b9ae46fd5282d470ed 100644
--- a/substrate/node/runtime/wasm/Cargo.toml
+++ b/substrate/node/runtime/wasm/Cargo.toml
@@ -28,6 +28,7 @@ srml-staking = { path = "../../../srml/staking", default-features = false }
 srml-system = { path = "../../../srml/system", default-features = false }
 srml-timestamp = { path = "../../../srml/timestamp", default-features = false }
 srml-treasury = { path = "../../../srml/treasury", default-features = false }
+srml-upgrade-key = { path = "../../../srml/upgrade-key", default-features = false }
 sr-version = { path = "../../../core/sr-version", default-features = false }
 node-primitives = { path = "../../primitives", default-features = false }
 
@@ -53,6 +54,7 @@ std = [
 	"srml-system/std",
 	"srml-timestamp/std",
 	"srml-treasury/std",
+	"srml-upgrade-key/std",
 	"sr-version/std",
 	"node-primitives/std",
 ]
diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm
index 392b360796baf5f93c2a1b99150e48df37ed35c3..2a48d20c98d216742495a038849834566e6ccc45 100644
Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ
diff --git a/substrate/srml/assets/src/lib.rs b/substrate/srml/assets/src/lib.rs
index 61b36dc3c1c8e42210d1be9f3e54e323a9a8c139..bde551e8863ee22c13ae73becae63bc990170fc7 100644
--- a/substrate/srml/assets/src/lib.rs
+++ b/substrate/srml/assets/src/lib.rs
@@ -52,7 +52,6 @@ extern crate sr_primitives as primitives;
 // depend on it being around.
 extern crate srml_system as system;
 
-use primitives::traits::OnFinalise;
 use runtime_support::{StorageValue, StorageMap, dispatch::Result, Parameter};
 use primitives::traits::{Member, SimpleArithmetic, Zero};
 use system::ensure_signed;
@@ -70,16 +69,47 @@ type AssetId = u32;
 decl_module! {
 	// Simple declaration of the `Module` type. Lets the macro know what its working on.
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		fn deposit_event() = default;
 		/// Issue a new class of fungible assets. There are, and will only ever be, `total`
 		/// such assets and they'll all belong to the `origin` initially. It will have an
 		/// identifier `AssetId` instance: this will be specified in the `Issued` event.
-		fn issue(origin, total: T::Balance) -> Result;
+		fn issue(origin, total: T::Balance) -> Result {
+			let origin = ensure_signed(origin)?;
+
+			let id = Self::next_asset_id();
+			<NextAssetId<T>>::mutate(|id| *id += 1);
+
+			<Balances<T>>::insert((id, origin.clone()), total);
+
+			Self::deposit_event(RawEvent::Issued(id, origin, total));
+			Ok(())
+		}
 
 		/// Move some assets from one holder to another.
-		fn transfer(origin, id: AssetId, target: T::AccountId, total: T::Balance) -> Result;
+		fn transfer(origin, id: AssetId, target: T::AccountId, amount: T::Balance) -> Result {
+			let origin = ensure_signed(origin)?;
+			let origin_account = (id, origin.clone());
+			let origin_balance = <Balances<T>>::get(&origin_account);
+			ensure!(origin_balance >= amount, "origin account balance must be greater than amount");
+
+			Self::deposit_event(RawEvent::Transfered(id, origin, target.clone(), amount));
+			<Balances<T>>::insert(origin_account, origin_balance - amount);
+			<Balances<T>>::mutate((id, target), |balance| *balance += amount);
+
+			Ok(())
+		}
 
 		/// Destroy any assets of `id` owned by `origin`.
-		fn destroy(origin, id: AssetId) -> Result;
+		fn destroy(origin, id: AssetId) -> Result {
+			let origin = ensure_signed(origin)?;
+
+			let balance = <Balances<T>>::take((id, origin.clone()));
+			ensure!(!balance.is_zero(), "origin balance should be non-zero");
+
+			Self::deposit_event(RawEvent::Destroyed(id, origin, balance));
+
+			Ok(())
+		}
 	}
 }
 
@@ -108,62 +138,14 @@ decl_storage! {
 
 // The main implementation block for the module.
 impl<T: Trait> Module<T> {
-	/// Deposit one of this module's events.
-	// TODO: move into `decl_module` macro.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	// Public immutables
 
 	/// Get the asset `id` balance of `who`.
 	pub fn balance(id: AssetId, who: T::AccountId) -> T::Balance {
 		<Balances<T>>::get((id, who))
 	}
-
-	// Implement Calls and add public immutables and private mutables.
-
-	fn issue(origin: T::Origin, total: T::Balance) -> Result {
-		let origin = ensure_signed(origin)?;
-
-		let id = Self::next_asset_id();
-		<NextAssetId<T>>::mutate(|id| *id += 1);
-
-
-		<Balances<T>>::insert((id, origin.clone()), total);
-
-		Self::deposit_event(RawEvent::Issued(id, origin, total));
-		Ok(())
-	}
-
-	fn transfer(origin: T::Origin, id: AssetId, target: T::AccountId, amount: T::Balance) -> Result {
-		let origin = ensure_signed(origin)?;
-		let origin_account = (id, origin.clone());
-		let origin_balance = <Balances<T>>::get(&origin_account);
-		ensure!(origin_balance >= amount, "origin account balance must be greater than amount");
-
-		Self::deposit_event(RawEvent::Transfered(id, origin, target.clone(), amount));
-		<Balances<T>>::insert(origin_account, origin_balance - amount);
-		<Balances<T>>::mutate((id, target), |balance| *balance += amount);
-
-		Ok(())
-	}
-
-	fn destroy(origin: T::Origin, id: AssetId) -> Result {
-		let origin = ensure_signed(origin)?;
-
-		let balance = <Balances<T>>::take((id, origin.clone()));
-		ensure!(!balance.is_zero(), "origin balance should be non-zero");
-
-		Self::deposit_event(RawEvent::Destroyed(id, origin, balance));
-
-		Ok(())
-	}
 }
 
-// This trait expresses what should happen when the block is finalised.
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/balances/src/lib.rs b/substrate/srml/balances/src/lib.rs
index 50c9b27d76a54fd24ae4b087ec94f823b4b6730c..224d02c0d1362446021f458acf9eb165ab84d943 100644
--- a/substrate/srml/balances/src/lib.rs
+++ b/substrate/srml/balances/src/lib.rs
@@ -44,7 +44,7 @@ use rstd::{cmp, result};
 use codec::{Encode, Decode, Codec, Input, Output, HasCompact};
 use runtime_support::{StorageValue, StorageMap, Parameter};
 use runtime_support::dispatch::Result;
-use primitives::traits::{Zero, One, SimpleArithmetic, OnFinalise, MakePayment,
+use primitives::traits::{Zero, One, SimpleArithmetic, MakePayment,
 	As, Lookup, Member, CheckedAdd, CheckedSub, CurrentHeight, BlockNumberToHash};
 use address::Address as RawAddress;
 use system::ensure_signed;
@@ -125,8 +125,64 @@ pub trait Trait: system::Trait {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn transfer(origin, dest: RawAddress<T::AccountId, T::AccountIndex>, value: <T::Balance as HasCompact>::Type) -> Result;
-		fn set_balance(who: RawAddress<T::AccountId, T::AccountIndex>, free: <T::Balance as HasCompact>::Type, reserved: <T::Balance as HasCompact>::Type) -> Result;
+		fn deposit_event() = default;
+
+		/// Transfer some liquid free balance to another staker.
+		pub fn transfer(
+			origin,
+			dest: RawAddress<T::AccountId, T::AccountIndex>,
+			value: <T::Balance as HasCompact>::Type
+		) -> Result {
+			let transactor = ensure_signed(origin)?;
+
+			let dest = Self::lookup(dest)?;
+			let value = value.into();
+			let from_balance = Self::free_balance(&transactor);
+			let to_balance = Self::free_balance(&dest);
+			let would_create = to_balance.is_zero();
+			let fee = if would_create { Self::creation_fee() } else { Self::transfer_fee() };
+			let liability = match value.checked_add(&fee) {
+				Some(l) => l,
+				None => return Err("got overflow after adding a fee to value"),
+			};
+
+			let new_from_balance = match from_balance.checked_sub(&liability) {
+				Some(b) => b,
+				None => return Err("balance too low to send value"),
+			};
+			if would_create && value < Self::existential_deposit() {
+				return Err("value too low to create account");
+			}
+			T::EnsureAccountLiquid::ensure_account_liquid(&transactor)?;
+
+			// NOTE: total stake being stored in the same type means that this could never overflow
+			// but better to be safe than sorry.
+			let new_to_balance = match to_balance.checked_add(&value) {
+				Some(b) => b,
+				None => return Err("destination balance too high to receive value"),
+			};
+
+			if transactor != dest {
+				Self::set_free_balance(&transactor, new_from_balance);
+				Self::decrease_total_stake_by(fee);
+				Self::set_free_balance_creating(&dest, new_to_balance);
+				Self::deposit_event(RawEvent::Transfer(transactor, dest, value, fee));
+			}
+
+			Ok(())
+		}
+
+		/// Set the balances of a given account.
+		fn set_balance(
+			who: RawAddress<T::AccountId, T::AccountIndex>,
+			free: <T::Balance as HasCompact>::Type,
+			reserved: <T::Balance as HasCompact>::Type
+		) -> Result {
+			let who = Self::lookup(who)?;
+			Self::set_free_balance(&who, free.into());
+			Self::set_reserved_balance(&who, reserved.into());
+			Ok(())
+		}
 	}
 }
 
@@ -232,12 +288,6 @@ pub enum UpdateBalanceOutcome {
 }
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	// PUBLIC IMMUTABLES
 
 	/// The combined balance of `who`.
@@ -285,58 +335,7 @@ impl<T: Trait> Module<T> {
 		}
 	}
 
-	// PUBLIC DISPATCH
-
-	/// Transfer some liquid free balance to another staker.
-	pub fn transfer(origin: T::Origin, dest: Address<T>, value: <T::Balance as HasCompact>::Type) -> Result {
-		let transactor = ensure_signed(origin)?;
-
-		let dest = Self::lookup(dest)?;
-		let value = value.into();
-		let from_balance = Self::free_balance(&transactor);
-		let to_balance = Self::free_balance(&dest);
-		let would_create = to_balance.is_zero();
-		let fee = if would_create { Self::creation_fee() } else { Self::transfer_fee() };
-		let liability = match value.checked_add(&fee) {
-			Some(l) => l,
-			None => return Err("got overflow after adding a fee to value"),
-		};
-
-		let new_from_balance = match from_balance.checked_sub(&liability) {
-			Some(b) => b,
-			None => return Err("balance too low to send value"),
-		};
-		if would_create && value < Self::existential_deposit() {
-			return Err("value too low to create account");
-		}
-		T::EnsureAccountLiquid::ensure_account_liquid(&transactor)?;
-
-		// NOTE: total stake being stored in the same type means that this could never overflow
-		// but better to be safe than sorry.
-		let new_to_balance = match to_balance.checked_add(&value) {
-			Some(b) => b,
-			None => return Err("destination balance too high to receive value"),
-		};
-
-		if transactor != dest {
-			Self::set_free_balance(&transactor, new_from_balance);
-			Self::decrease_total_stake_by(fee);
-			Self::set_free_balance_creating(&dest, new_to_balance);
-			Self::deposit_event(RawEvent::Transfer(transactor, dest, value, fee));
-		}
-
-		Ok(())
-	}
-
-	/// Set the balances of a given account.
-	fn set_balance(who: Address<T>, free: <T::Balance as HasCompact>::Type, reserved: <T::Balance as HasCompact>::Type) -> Result {
-		let who = Self::lookup(who)?;
-		Self::set_free_balance(&who, free.into());
-		Self::set_reserved_balance(&who, reserved.into());
-		Ok(())
-	}
-
-	// PUBLIC MUTABLES (DANGEROUS)
+	//PUBLIC MUTABLES (DANGEROUS)
 
 	/// Set the free balance of an account to some new value.
 	///
@@ -424,6 +423,23 @@ impl<T: Trait> Module<T> {
 		Self::set_free_balance_creating(who, Self::free_balance(who) + value)
 	}
 
+	/// Substrates `value` from the free balance of `who`. If the whole amount cannot be
+	/// deducted, an error is returned.
+	///
+	/// NOTE: This assumes that the total stake remains unchanged after this operation. If
+	/// you mean to actually burn value out of existence, then use `slash` instead.
+	pub fn decrease_free_balance(
+		who: &T::AccountId,
+		value: T::Balance
+	) -> result::Result<UpdateBalanceOutcome, &'static str> {
+		T::EnsureAccountLiquid::ensure_account_liquid(who)?;
+		let b = Self::free_balance(who);
+		if b < value {
+			return Err("account has too few funds")
+		}
+		Ok(Self::set_free_balance(who, b - value))
+	}
+
 	/// Deducts up to `value` from the combined balance of `who`, preferring to deduct from the
 	/// free balance. This function cannot fail.
 	///
@@ -652,11 +668,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-	}
-}
-
 pub struct ChainContext<T>(::rstd::marker::PhantomData<T>);
 impl<T> Default for ChainContext<T> {
 	fn default() -> Self {
diff --git a/substrate/srml/balances/src/tests.rs b/substrate/srml/balances/src/tests.rs
index b9c5b85902a49c8964b3a9ce5ffdf93f9a226d8c..9ad100fe6179c0e86552a9c1c9c768f8193e2569 100644
--- a/substrate/srml/balances/src/tests.rs
+++ b/substrate/srml/balances/src/tests.rs
@@ -280,6 +280,17 @@ fn balance_transfer_works() {
 	});
 }
 
+#[test]
+fn balance_reduction_works() {
+	with_externalities(&mut ExtBuilder::default().build(), || {
+		Balances::set_free_balance(&1, 111);
+		Balances::increase_total_stake_by(111);
+		assert_ok!(Balances::decrease_free_balance(&1, 69).map(|_| ()));
+		assert_eq!(Balances::total_balance(&1), 42);
+		assert_noop!(Balances::decrease_free_balance(&1, 69).map(|_| ()), "account has too few funds");
+	});
+}
+
 #[test]
 fn reserving_balance_should_work() {
 	with_externalities(&mut ExtBuilder::default().build(), || {
diff --git a/substrate/srml/consensus/src/lib.rs b/substrate/srml/consensus/src/lib.rs
index 835d39a44cee237d57aecf5b1baa76532a2860cd..1c46e38541ed24aa230032ec56ef669cc69a851a 100644
--- a/substrate/srml/consensus/src/lib.rs
+++ b/substrate/srml/consensus/src/lib.rs
@@ -29,6 +29,7 @@ extern crate srml_support as runtime_support;
 #[macro_use]
 extern crate serde_derive;
 
+extern crate parity_codec;
 #[macro_use]
 extern crate parity_codec_derive;
 
@@ -42,13 +43,14 @@ extern crate sr_io as runtime_io;
 
 use rstd::prelude::*;
 use rstd::result;
+use parity_codec::Encode;
 use runtime_support::{storage, Parameter};
 use runtime_support::dispatch::Result;
 use runtime_support::storage::StorageValue;
 use runtime_support::storage::unhashed::StorageVec;
 use primitives::RuntimeString;
 use primitives::traits::{
-	MaybeSerializeDebug, OnFinalise, Member, ProvideInherent, Block as BlockT
+	MaybeSerializeDebug, Member, ProvideInherent, Block as BlockT
 };
 use substrate_primitives::storage::well_known_keys;
 use system::{ensure_signed, ensure_inherent};
@@ -143,63 +145,72 @@ decl_storage! {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn report_misbehavior(origin, report: Vec<u8>) -> Result;
-		fn note_offline(origin, offline_val_indices: Vec<u32>) -> Result;
-		fn remark(origin, remark: Vec<u8>) -> Result;
-		fn set_code(new: Vec<u8>) -> Result;
-		fn set_storage(items: Vec<KeyValue>) -> Result;
-	}
-}
+		/// Report some misbehaviour.
+		fn report_misbehavior(origin, _report: Vec<u8>) -> Result {
+			ensure_signed(origin)?;
+			// TODO.
+			Ok(())
+		}
 
-impl<T: Trait> Module<T> {
-	/// Get the current set of authorities. These are the session keys.
-	pub fn authorities() -> Vec<T::SessionKey> {
-		AuthorityStorageVec::<T::SessionKey>::items()
-	}
+		/// Note the previous block's validator missed their opportunity to propose a block.
+		/// This only comes in if 2/3+1 of the validators agree that no proposal was submitted.
+		/// It's only relevant for the previous block.
+		fn note_offline(origin, offline_val_indices: Vec<u32>) -> Result {
+			ensure_inherent(origin)?;
+			assert!(
+				<system::Module<T>>::extrinsic_index() == Some(T::NOTE_OFFLINE_POSITION),
+				"note_offline extrinsic must be at position {} in the block",
+				T::NOTE_OFFLINE_POSITION
+			);
+
+			for validator_index in offline_val_indices.into_iter() {
+				T::OnOfflineValidator::on_offline_validator(validator_index as usize);
+			}
 
-	/// Set the new code.
-	fn set_code(new: Vec<u8>) -> Result {
-		storage::unhashed::put_raw(well_known_keys::CODE, &new);
-		Ok(())
-	}
+			Ok(())
+		}
 
-	/// Set some items of storage.
-	fn set_storage(items: Vec<KeyValue>) -> Result {
-		for i in &items {
-			storage::unhashed::put_raw(&i.0, &i.1);
+		/// Make some on-chain remark.
+		fn remark(origin, _remark: Vec<u8>) -> Result {
+			ensure_signed(origin)?;
+			Ok(())
 		}
-		Ok(())
-	}
 
-	/// Report some misbehaviour.
-	fn report_misbehavior(origin: T::Origin, _report: Vec<u8>) -> Result {
-		ensure_signed(origin)?;
-		// TODO.
-		Ok(())
-	}
+		/// Set the number of pages in the WebAssembly environment's heap.
+		fn set_heap_pages(pages: u64) -> Result {
+			storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
+			Ok(())
+		}
 
-	/// Note the previous block's validator missed their opportunity to propose a block. This only comes in
-	/// if 2/3+1 of the validators agree that no proposal was submitted. It's only relevant
-	/// for the previous block.
-	fn note_offline(origin: T::Origin, offline_val_indices: Vec<u32>) -> Result {
-		ensure_inherent(origin)?;
-		assert!(
-			<system::Module<T>>::extrinsic_index() == Some(T::NOTE_OFFLINE_POSITION),
-			"note_offline extrinsic must be at position {} in the block",
-			T::NOTE_OFFLINE_POSITION
-		);
-
-		for validator_index in offline_val_indices.into_iter() {
-			T::OnOfflineValidator::on_offline_validator(validator_index as usize);
+		/// Set the new code.
+		pub fn set_code(new: Vec<u8>) -> Result {
+			storage::unhashed::put_raw(well_known_keys::CODE, &new);
+			Ok(())
 		}
 
-		Ok(())
+		/// Set some items of storage.
+		fn set_storage(items: Vec<KeyValue>) -> Result {
+			for i in &items {
+				storage::unhashed::put_raw(&i.0, &i.1);
+			}
+			Ok(())
+		}
+
+		fn on_finalise() {
+			if let Some(original_authorities) = <OriginalAuthorities<T>>::take() {
+				let current_authorities = AuthorityStorageVec::<T::SessionKey>::items();
+				if current_authorities != original_authorities {
+					Self::deposit_log(RawLog::AuthoritiesChange(current_authorities));
+				}
+			}
+		}
 	}
+}
 
-	/// Make some on-chain remark.
-	fn remark(origin: T::Origin, _remark: Vec<u8>) -> Result {
-		ensure_signed(origin)?;
-		Ok(())
+impl<T: Trait> Module<T> {
+	/// Get the current set of authorities. These are the session keys.
+	pub fn authorities() -> Vec<T::SessionKey> {
+		AuthorityStorageVec::<T::SessionKey>::items()
 	}
 
 	/// Set the current set of authorities' session keys.
@@ -267,15 +278,3 @@ impl<T: Trait> ProvideInherent for Module<T> {
 		)
 	}
 }
-
-/// Finalization hook for the consensus module.
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-		if let Some(original_authorities) = <OriginalAuthorities<T>>::take() {
-			let current_authorities = AuthorityStorageVec::<T::SessionKey>::items();
-			if current_authorities != original_authorities {
-				Self::deposit_log(RawLog::AuthoritiesChange(current_authorities));
-			}
-		}
-	}
-}
diff --git a/substrate/srml/consensus/src/tests.rs b/substrate/srml/consensus/src/tests.rs
index e27f617115109db50e93c2fae37b5b9c5624b1e9..b823367c15458f792d254f824f85a2fe4dfa76dc 100644
--- a/substrate/srml/consensus/src/tests.rs
+++ b/substrate/srml/consensus/src/tests.rs
@@ -18,8 +18,7 @@
 
 #![cfg(test)]
 
-use super::*;
-use primitives::{generic, testing};
+use primitives::{generic, testing, traits::OnFinalise};
 use runtime_io::with_externalities;
 use substrate_primitives::H256;
 use mock::{Consensus, System, new_test_ext};
diff --git a/substrate/srml/contract/src/lib.rs b/substrate/srml/contract/src/lib.rs
index 31a7d4ed22b952cb06c6c8667884fc58bdbf3f80..5e3722bb04040e31fe002491fe1ddfa7e21ad486 100644
--- a/substrate/srml/contract/src/lib.rs
+++ b/substrate/srml/contract/src/lib.rs
@@ -103,7 +103,7 @@ use double_map::StorageDoubleMap;
 use rstd::prelude::*;
 use rstd::marker::PhantomData;
 use codec::{Codec, HasCompact};
-use runtime_primitives::traits::{Hash, As, SimpleArithmetic, OnFinalise};
+use runtime_primitives::traits::{Hash, As, SimpleArithmetic};
 use runtime_support::dispatch::Result;
 use runtime_support::{Parameter, StorageMap, StorageValue};
 use system::ensure_signed;
@@ -151,22 +151,110 @@ where
 decl_module! {
 	/// Contracts module.
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		fn deposit_event() = default;
 		// TODO: Change AccountId to staking::Address
+		/// Make a call to a specified account, optionally transferring some balance.
+		/// Make a call to a specified account, optionally transferring some balance.
 		fn call(
 			origin,
 			dest: T::AccountId,
 			value: <T::Balance as HasCompact>::Type,
 			gas_limit: <T::Gas as HasCompact>::Type,
 			data: Vec<u8>
-		) -> Result;
+		) -> Result {
+			let origin = ensure_signed(origin)?;
+			let value = value.into();
+			let gas_limit = gas_limit.into();
+
+			// Pay for the gas upfront.
+			//
+			// NOTE: it is very important to avoid any state changes before
+			// paying for the gas.
+			let mut gas_meter = gas::buy_gas::<T>(&origin, gas_limit)?;
+
+			let mut ctx = ExecutionContext {
+				self_account: origin.clone(),
+				depth: 0,
+				overlay: OverlayAccountDb::<T>::new(&account_db::DirectAccountDb),
+				events: Vec::new(),
+			};
+
+			let mut output_data = Vec::new();
+			let result = ctx.call(origin.clone(), dest, value, &mut gas_meter, &data, &mut output_data);
+
+			if let Ok(_) = result {
+				// Commit all changes that made it thus far into the persistant storage.
+				account_db::DirectAccountDb.commit(ctx.overlay.into_change_set());
+
+				// Then deposit all events produced.
+				ctx.events.into_iter().for_each(Self::deposit_event);
+			}
+
+			// Refund cost of the unused gas.
+			//
+			// NOTE: this should go after the commit to the storage, since the storage changes
+			// can alter the balance of the caller.
+			gas::refund_unused_gas::<T>(&origin, gas_meter);
+
+			result.map(|_| ())
+		}
 
+		/// Create a new contract, optionally transfering some balance to the created account.
+		///
+		/// Creation is executed as follows:
+		///
+		/// - the destination address is computed based on the sender and hash of the code.
+		/// - account is created at the computed address.
+		/// - the `ctor_code` is executed in the context of the newly created account. Buffer returned
+		///   after the execution is saved as the `code` of the account. That code will be invoked
+		///   upon any message received by this account.
 		fn create(
 			origin,
-			value: <T::Balance as HasCompact>::Type,
+			endowment: <T::Balance as HasCompact>::Type,
 			gas_limit: <T::Gas as HasCompact>::Type,
-			init_code: Vec<u8>,
+			ctor_code: Vec<u8>,
 			data: Vec<u8>
-		) -> Result;
+		) -> Result {
+			let origin = ensure_signed(origin)?;
+			let endowment = endowment.into();
+			let gas_limit = gas_limit.into();
+
+			// Pay for the gas upfront.
+			//
+			// NOTE: it is very important to avoid any state changes before
+			// paying for the gas.
+			let mut gas_meter = gas::buy_gas::<T>(&origin, gas_limit)?;
+
+			let mut ctx = ExecutionContext {
+				self_account: origin.clone(),
+				depth: 0,
+				overlay: OverlayAccountDb::<T>::new(&account_db::DirectAccountDb),
+				events: Vec::new(),
+			};
+			let result = ctx.create(origin.clone(), endowment, &mut gas_meter, &ctor_code, &data);
+
+			if let Ok(ref r) = result {
+				// Commit all changes that made it thus far into the persistant storage.
+				account_db::DirectAccountDb.commit(ctx.overlay.into_change_set());
+
+				// Then deposit all events produced.
+				ctx.events.into_iter().for_each(Self::deposit_event);
+
+				Self::deposit_event(RawEvent::Created(origin.clone(), r.address.clone()));
+			}
+
+			// Refund cost of the unused gas.
+			//
+			// NOTE: this should go after the commit to the storage, since the storage changes
+			// can alter the balance of the caller.
+			gas::refund_unused_gas::<T>(&origin, gas_meter);
+
+			result.map(|_| ())
+		}
+
+		fn on_finalise() {
+			<GasSpent<T>>::kill();
+		}
 	}
 }
 
@@ -178,6 +266,9 @@ decl_event! {
 	{
 		/// Transfer happened `from` -> `to` with given `value` as part of a `message-call` or `create`.
 		Transfer(AccountId, AccountId, Balance),
+
+		/// Contract deployed by address at the specified address.
+		Created(AccountId, AccountId),
 	}
 }
 
@@ -217,119 +308,9 @@ impl<T: Trait> double_map::StorageDoubleMap for StorageOf<T> {
 	type Value = Vec<u8>;
 }
 
-impl<T: Trait> Module<T> {
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
-	/// Make a call to a specified account, optionally transferring some balance.
-	fn call(
-		origin: <T as system::Trait>::Origin,
-		dest: T::AccountId,
-		value: <T::Balance as HasCompact>::Type,
-		gas_limit: <T::Gas as HasCompact>::Type,
-		data: Vec<u8>,
-	) -> Result {
-		let origin = ensure_signed(origin)?;
-		let value = value.into();
-		let gas_limit = gas_limit.into();
-
-		// Pay for the gas upfront.
-		//
-		// NOTE: it is very important to avoid any state changes before
-		// paying for the gas.
-		let mut gas_meter = gas::buy_gas::<T>(&origin, gas_limit)?;
-
-		let mut ctx = ExecutionContext {
-			self_account: origin.clone(),
-			depth: 0,
-			overlay: OverlayAccountDb::<T>::new(&account_db::DirectAccountDb),
-			events: Vec::new(),
-		};
-
-		let mut output_data = Vec::new();
-		let result = ctx.call(origin.clone(), dest, value, &mut gas_meter, &data, &mut output_data);
-
-		if let Ok(_) = result {
-			// Commit all changes that made it thus far into the persistant storage.
-			account_db::DirectAccountDb.commit(ctx.overlay.into_change_set());
-
-			// Then deposit all events produced.
-			ctx.events.into_iter().for_each(Self::deposit_event);
-		}
-
-		// Refund cost of the unused gas.
-		//
-		// NOTE: this should go after the commit to the storage, since the storage changes
-		// can alter the balance of the caller.
-		gas::refund_unused_gas::<T>(&origin, gas_meter);
-
-		result.map(|_| ())
-	}
-
-	/// Create a new contract, optionally transfering some balance to the created account.
-	///
-	/// Creation is executed as follows:
-	///
-	/// - the destination address is computed based on the sender and hash of the code.
-	/// - account is created at the computed address.
-	/// - the `ctor_code` is executed in the context of the newly created account. Buffer returned
-	///   after the execution is saved as the `code` of the account. That code will be invoked
-	///   upon any message received by this account.
-	fn create(
-		origin: <T as system::Trait>::Origin,
-		endowment: <T::Balance as HasCompact>::Type,
-		gas_limit: <T::Gas as HasCompact>::Type,
-		ctor_code: Vec<u8>,
-		data: Vec<u8>,
-	) -> Result {
-		let origin = ensure_signed(origin)?;
-		let endowment = endowment.into();
-		let gas_limit = gas_limit.into();
-
-		// Pay for the gas upfront.
-		//
-		// NOTE: it is very important to avoid any state changes before
-		// paying for the gas.
-		let mut gas_meter = gas::buy_gas::<T>(&origin, gas_limit)?;
-
-		let mut ctx = ExecutionContext {
-			self_account: origin.clone(),
-			depth: 0,
-			overlay: OverlayAccountDb::<T>::new(&account_db::DirectAccountDb),
-			events: Vec::new(),
-		};
-		let result = ctx.create(origin.clone(), endowment, &mut gas_meter, &ctor_code, &data);
-
-		if let Ok(_) = result {
-			// Commit all changes that made it thus far into the persistant storage.
-			account_db::DirectAccountDb.commit(ctx.overlay.into_change_set());
-
-			// Then deposit all events produced.
-			ctx.events.into_iter().for_each(Self::deposit_event);
-		}
-
-		// Refund cost of the unused gas.
-		//
-		// NOTE: this should go after the commit to the storage, since the storage changes
-		// can alter the balance of the caller.
-		gas::refund_unused_gas::<T>(&origin, gas_meter);
-
-		result.map(|_| ())
-	}
-}
-
 impl<T: Trait> balances::OnFreeBalanceZero<T::AccountId> for Module<T> {
 	fn on_free_balance_zero(who: &T::AccountId) {
 		<CodeOf<T>>::remove(who);
 		<StorageOf<T>>::remove_prefix(who.clone());
 	}
 }
-
-/// Finalization hook for the smart-contract module.
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-		<GasSpent<T>>::kill();
-	}
-}
diff --git a/substrate/srml/contract/src/tests.rs b/substrate/srml/contract/src/tests.rs
index f48769c97831bd39362b6c7118001ab82457d6f6..9e2d2f1f6800fa40ca0fdf4e4e6d044cf387aeae 100644
--- a/substrate/srml/contract/src/tests.rs
+++ b/substrate/srml/contract/src/tests.rs
@@ -617,6 +617,10 @@ fn top_level_create() {
 				phase: Phase::ApplyExtrinsic(0),
 				event: MetaEvent::contract(RawEvent::Transfer(0, derived_address, 11)),
 			},
+			EventRecord {
+				phase: Phase::ApplyExtrinsic(0),
+				event: MetaEvent::contract(RawEvent::Created(0, 1)),
+			},
 		]);
 	});
 }
diff --git a/substrate/srml/council/src/motions.rs b/substrate/srml/council/src/motions.rs
index ab6ea5f4ef01923fce184a8066afba494b8df7ac..a2c5115633f191504208cd0fccc3066ae48a6dc0 100644
--- a/substrate/srml/council/src/motions.rs
+++ b/substrate/srml/council/src/motions.rs
@@ -20,7 +20,7 @@ use rstd::prelude::*;
 use rstd::result;
 use codec::Compact;
 use substrate_primitives::u32_trait::Value as U32;
-use primitives::traits::{Hash, EnsureOrigin, MaybeSerializeDebug, OnFinalise};
+use primitives::traits::{Hash, EnsureOrigin, MaybeSerializeDebug};
 use srml_support::dispatch::{Result, Dispatchable, Parameter};
 use srml_support::{StorageValue, StorageMap};
 use super::{Trait as CouncilTrait, Module as Council};
@@ -68,8 +68,96 @@ decl_event!(
 decl_module! {
 	#[cfg_attr(feature = "std", serde(bound(deserialize = "<T as Trait>::Proposal: ::serde::de::DeserializeOwned")))]
 	pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {
-		fn propose(origin, threshold: Compact<u32>, proposal: Box<<T as Trait>::Proposal>) -> Result;
-		fn vote(origin, proposal: T::Hash, index: Compact<ProposalIndex>, approve: bool) -> Result;
+		fn deposit_event() = default;
+		fn propose(origin, threshold: Compact<u32>, proposal: Box<<T as Trait>::Proposal>) -> Result {
+			let who = ensure_signed(origin)?;
+			let threshold = threshold.into();
+
+			ensure!(Self::is_councillor(&who), "proposer not on council");
+
+			let proposal_hash = T::Hashing::hash_of(&proposal);
+
+			ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
+
+			if threshold < 2 {
+				let ok = proposal.dispatch(Origin::Members(1).into()).is_ok();
+				Self::deposit_event(RawEvent::Executed(proposal_hash, ok));
+			} else {
+				let index = Self::proposal_count();
+				<ProposalCount<T>>::mutate(|i| *i += 1);
+				<Proposals<T>>::mutate(|proposals| proposals.push(proposal_hash));
+				<ProposalOf<T>>::insert(proposal_hash, *proposal);
+				<Voting<T>>::insert(proposal_hash, (index, threshold, vec![who.clone()], vec![]));
+
+				Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold));
+			}
+			Ok(())
+		}
+
+		fn vote(origin, proposal: T::Hash, index: Compact<ProposalIndex>, approve: bool) -> Result {
+			let who = ensure_signed(origin)?;
+			let index = index.into();
+
+			ensure!(Self::is_councillor(&who), "voter not on council");
+
+			let mut voting = Self::voting(&proposal).ok_or("proposal must exist")?;
+			ensure!(voting.0 == index, "mismatched index");
+
+			let position_yes = voting.2.iter().position(|a| a == &who);
+			let position_no = voting.3.iter().position(|a| a == &who);
+
+			if approve {
+				if position_yes.is_none() {
+					voting.2.push(who.clone());
+				} else {
+					return Err("duplicate vote ignored")
+				}
+				if let Some(pos) = position_no {
+					voting.3.swap_remove(pos);
+				}
+			} else {
+				if position_no.is_none() {
+					voting.3.push(who.clone());
+				} else {
+					return Err("duplicate vote ignored")
+				}
+				if let Some(pos) = position_yes {
+					voting.2.swap_remove(pos);
+				}
+			}
+
+			let yes_votes = voting.2.len() as u32;
+			let no_votes = voting.3.len() as u32;
+			Self::deposit_event(RawEvent::Voted(who, proposal, approve, yes_votes, no_votes));
+
+			let threshold = voting.1;
+			let potential_votes = <Council<T>>::active_council().len() as u32;
+			let approved = yes_votes >= threshold;
+			let disapproved = potential_votes.saturating_sub(no_votes) < threshold;
+			if approved || disapproved {
+				if approved {
+					Self::deposit_event(RawEvent::Approved(proposal));
+
+					// execute motion, assuming it exists.
+					if let Some(p) = <ProposalOf<T>>::take(&proposal) {
+						let ok = p.dispatch(Origin::Members(threshold).into()).is_ok();
+						Self::deposit_event(RawEvent::Executed(proposal, ok));
+					}
+				} else {
+					// disapproved
+					Self::deposit_event(RawEvent::Disapproved(proposal));
+				}
+
+				// remove vote
+				<Voting<T>>::remove(&proposal);
+				<Proposals<T>>::mutate(|proposals| proposals.retain(|h| h != &proposal));
+			} else {
+				// update voting
+				<Voting<T>>::insert(&proposal, voting);
+			}
+
+			Ok(())
+		}
 	}
 }
 
@@ -91,112 +179,10 @@ decl_storage! {
 }
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	pub fn is_councillor(who: &T::AccountId) -> bool {
 		<Council<T>>::active_council().iter()
 			.any(|&(ref a, _)| a == who)
 	}
-
-	// Dispatch
-	fn propose(origin: <T as system::Trait>::Origin, threshold: Compact<u32>, proposal: Box<<T as Trait>::Proposal>) -> Result {
-		let who = ensure_signed(origin)?;
-		let threshold = threshold.into();
-
-		ensure!(Self::is_councillor(&who), "proposer not on council");
-
-		let proposal_hash = T::Hashing::hash_of(&proposal);
-
-		ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
-
-		if threshold < 2 {
-			let ok = proposal.dispatch(Origin::Members(1).into()).is_ok();
-			Self::deposit_event(RawEvent::Executed(proposal_hash, ok));
-		} else {
-			let index = Self::proposal_count();
-			<ProposalCount<T>>::mutate(|i| *i += 1);
-			<Proposals<T>>::mutate(|proposals| proposals.push(proposal_hash));
-			<ProposalOf<T>>::insert(proposal_hash, *proposal);
-			<Voting<T>>::insert(proposal_hash, (index, threshold, vec![who.clone()], vec![]));
-
-			Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold));
-		}
-		Ok(())
-	}
-
-	fn vote(origin: <T as system::Trait>::Origin, proposal: T::Hash, index: Compact<ProposalIndex>, approve: bool) -> Result {
-		let who = ensure_signed(origin)?;
-		let index = index.into();
-
-		ensure!(Self::is_councillor(&who), "voter not on council");
-
-		let mut voting = Self::voting(&proposal).ok_or("proposal must exist")?;
-		ensure!(voting.0 == index, "mismatched index");
-
-		let position_yes = voting.2.iter().position(|a| a == &who);
-		let position_no = voting.3.iter().position(|a| a == &who);
-
-		if approve {
-			if position_yes.is_none() {
-				voting.2.push(who.clone());
-			} else {
-				return Err("duplicate vote ignored")
-			}
-			if let Some(pos) = position_no {
-				voting.3.swap_remove(pos);
-			}
-		} else {
-			if position_no.is_none() {
-				voting.3.push(who.clone());
-			} else {
-				return Err("duplicate vote ignored")
-			}
-			if let Some(pos) = position_yes {
-				voting.2.swap_remove(pos);
-			}
-		}
-
-		let yes_votes = voting.2.len() as u32;
-		let no_votes = voting.3.len() as u32;
-		Self::deposit_event(RawEvent::Voted(who, proposal, approve, yes_votes, no_votes));
-
-		let threshold = voting.1;
-		let potential_votes = <Council<T>>::active_council().len() as u32;
-		let approved = yes_votes >= threshold;
-		let disapproved = potential_votes.saturating_sub(no_votes) < threshold;
-		if approved || disapproved {
-			if approved {
-				Self::deposit_event(RawEvent::Approved(proposal));
-
-				// execute motion, assuming it exists.
-				if let Some(p) = <ProposalOf<T>>::take(&proposal) {
-					let ok = p.dispatch(Origin::Members(threshold).into()).is_ok();
-					Self::deposit_event(RawEvent::Executed(proposal, ok));
-				}
-			} else {
-				// disapproved
-				Self::deposit_event(RawEvent::Disapproved(proposal));
-			}
-
-			// remove vote
-			<Voting<T>>::remove(&proposal);
-			<Proposals<T>>::mutate(|proposals| proposals.retain(|h| h != &proposal));
-		} else {
-			// update voting
-			<Voting<T>>::insert(&proposal, voting);
-		}
-
-		Ok(())
-	}
-}
-
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-	}
 }
 
 /// Ensure that the origin `o` represents at least `n` council members. Returns
diff --git a/substrate/srml/council/src/seats.rs b/substrate/srml/council/src/seats.rs
index 42c3858efbaee2073ea35f71ea807cfdd78baab3..957b69bdfe0a8479d5aacfae03ff197185fe69a8 100644
--- a/substrate/srml/council/src/seats.rs
+++ b/substrate/srml/council/src/seats.rs
@@ -18,7 +18,7 @@
 
 use rstd::prelude::*;
 use codec::{Compact, HasCompact};
-use primitives::traits::{Zero, One, As, OnFinalise};
+use primitives::traits::{Zero, One, As};
 use runtime_io::print;
 use srml_support::{StorageValue, StorageMap, dispatch::Result};
 use democracy;
@@ -87,16 +87,234 @@ pub trait Trait: democracy::Trait {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn set_approvals(origin, votes: Vec<bool>, index: Compact<VoteIndex>) -> Result;
-		fn reap_inactive_voter(origin, reporter_index: Compact<u32>, who: Address<T::AccountId, T::AccountIndex>, who_index: Compact<u32>, assumed_vote_index: Compact<VoteIndex>) -> Result;
-		fn retract_voter(origin, index: Compact<u32>) -> Result;
-		fn submit_candidacy(origin, slot: Compact<u32>) -> Result;
-		fn present_winner(origin, candidate: Address<T::AccountId, T::AccountIndex>, total: <T::Balance as HasCompact>::Type, index: Compact<VoteIndex>) -> Result;
-
-		fn set_desired_seats(count: Compact<u32>) -> Result;
-		fn remove_member(who: Address<T::AccountId, T::AccountIndex>) -> Result;
-		fn set_presentation_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result;
-		fn set_term_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result;
+		fn deposit_event() = default;
+
+		/// Set candidate approvals. Approval slots stay valid as long as candidates in those slots
+		/// are registered.
+		fn set_approvals(origin, votes: Vec<bool>, index: Compact<VoteIndex>) -> Result {
+			let who = ensure_signed(origin)?;
+			let index: VoteIndex = index.into();
+
+			ensure!(!Self::presentation_active(), "no approval changes during presentation period");
+			ensure!(index == Self::vote_index(), "incorrect vote index");
+			if !<LastActiveOf<T>>::exists(&who) {
+				// not yet a voter - deduct bond.
+				// NOTE: this must be the last potential bailer, since it changes state.
+				<balances::Module<T>>::reserve(&who, Self::voting_bond())?;
+
+				<Voters<T>>::put({
+					let mut v = Self::voters();
+					v.push(who.clone());
+					v
+				});
+			}
+			<LastActiveOf<T>>::insert(&who, index);
+			<ApprovalsOf<T>>::insert(&who, votes);
+			Ok(())
+		}
+
+		/// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices
+		/// must now be either unregistered or registered to a candidate that registered the slot after
+		/// the voter gave their last approval set.
+		///
+		/// May be called by anyone. Returns the voter deposit to `signed`.
+		fn reap_inactive_voter(
+			origin,
+			reporter_index: Compact<u32>,
+			who: Address<T::AccountId, T::AccountIndex>,
+			who_index: Compact<u32>,
+			assumed_vote_index: Compact<VoteIndex>
+		) -> Result {
+			let reporter = ensure_signed(origin)?;
+			let assumed_vote_index: VoteIndex = assumed_vote_index.into();
+
+			let who = <balances::Module<T>>::lookup(who)?;
+			ensure!(!Self::presentation_active(), "cannot reap during presentation period");
+			ensure!(Self::voter_last_active(&reporter).is_some(), "reporter must be a voter");
+			let last_active = Self::voter_last_active(&who).ok_or("target for inactivity cleanup must be active")?;
+			ensure!(assumed_vote_index == Self::vote_index(), "vote index not current");
+			ensure!(last_active < assumed_vote_index - Self::inactivity_grace_period(), "cannot reap during grace perid");
+			let voters = Self::voters();
+			let reporter_index: u32 = reporter_index.into();
+			let reporter_index = reporter_index as usize;
+			let who_index: u32 = who_index.into();
+			let who_index = who_index as usize;
+			ensure!(reporter_index < voters.len() && voters[reporter_index] == reporter, "bad reporter index");
+			ensure!(who_index < voters.len() && voters[who_index] == who, "bad target index");
+
+			// will definitely kill one of signed or who now.
+
+			let valid = !Self::approvals_of(&who).iter()
+				.zip(Self::candidates().iter())
+				.any(|(&appr, addr)|
+					 appr &&
+					 *addr != T::AccountId::default() &&
+					 Self::candidate_reg_info(addr).map_or(false, |x| x.0 <= last_active)/*defensive only: all items in candidates list are registered*/
+				);
+
+			Self::remove_voter(
+				if valid { &who } else { &reporter },
+				if valid { who_index } else { reporter_index },
+				voters
+			);
+			if valid {
+				// This only fails if `who` doesn't exist, which it clearly must do since its the origin.
+				// Still, it's no more harmful to propagate any error at this point.
+				<balances::Module<T>>::repatriate_reserved(&who, &reporter, Self::voting_bond())?;
+				Self::deposit_event(RawEvent::VoterReaped(who, reporter));
+			} else {
+				<balances::Module<T>>::slash_reserved(&reporter, Self::voting_bond());
+				Self::deposit_event(RawEvent::BadReaperSlashed(reporter));
+			}
+			Ok(())
+		}
+
+		/// Remove a voter. All votes are cancelled and the voter deposit is returned.
+		fn retract_voter(origin, index: Compact<u32>) -> Result {
+			let who = ensure_signed(origin)?;
+
+			ensure!(!Self::presentation_active(), "cannot retract when presenting");
+			ensure!(<LastActiveOf<T>>::exists(&who), "cannot retract non-voter");
+			let voters = Self::voters();
+			let index: u32 = index.into();
+			let index = index as usize;
+			ensure!(index < voters.len(), "retraction index invalid");
+			ensure!(voters[index] == who, "retraction index mismatch");
+
+			Self::remove_voter(&who, index, voters);
+			<balances::Module<T>>::unreserve(&who, Self::voting_bond());
+			Ok(())
+		}
+
+		/// Submit oneself for candidacy.
+		///
+		/// Account must have enough transferrable funds in it to pay the bond.
+		fn submit_candidacy(origin, slot: Compact<u32>) -> Result {
+			let who = ensure_signed(origin)?;
+
+			ensure!(!Self::is_a_candidate(&who), "duplicate candidate submission");
+			let slot: u32 = slot.into();
+			let slot = slot as usize;
+			let count = Self::candidate_count() as usize;
+			let candidates = Self::candidates();
+			ensure!(
+				(slot == count && count == candidates.len()) ||
+					(slot < candidates.len() && candidates[slot] == T::AccountId::default()),
+				"invalid candidate slot"
+			);
+			// NOTE: This must be last as it has side-effects.
+			<balances::Module<T>>::reserve(&who, Self::candidacy_bond())
+				.map_err(|_| "candidate has not enough funds")?;
+
+			<RegisterInfoOf<T>>::insert(&who, (Self::vote_index(), slot as u32));
+			let mut candidates = candidates;
+			if slot == candidates.len() {
+				candidates.push(who);
+			} else {
+				candidates[slot] = who;
+			}
+			<Candidates<T>>::put(candidates);
+			<CandidateCount<T>>::put(count as u32 + 1);
+			Ok(())
+		}
+
+		/// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates.
+		/// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()``
+		/// `signed` should have at least
+		fn present_winner(
+			origin,
+			candidate: Address<T::AccountId, T::AccountIndex>,
+			total: <T::Balance as HasCompact>::Type,
+			index: Compact<VoteIndex>
+		) -> Result {
+			let who = ensure_signed(origin)?;
+			let total = total.into();
+			let index: VoteIndex = index.into();
+
+			let candidate = <balances::Module<T>>::lookup(candidate)?;
+			ensure!(index == Self::vote_index(), "index not current");
+			let (_, _, expiring) = Self::next_finalise().ok_or("cannot present outside of presentation period")?;
+			let stakes = Self::snapshoted_stakes();
+			let voters = Self::voters();
+			let bad_presentation_punishment = Self::present_slash_per_voter() * T::Balance::sa(voters.len() as u64);
+			ensure!(<balances::Module<T>>::can_slash(&who, bad_presentation_punishment), "presenter must have sufficient slashable funds");
+
+			let mut leaderboard = Self::leaderboard().ok_or("leaderboard must exist while present phase active")?;
+			ensure!(total > leaderboard[0].0, "candidate not worthy of leaderboard");
+
+			if let Some(p) = Self::active_council().iter().position(|&(ref c, _)| c == &candidate) {
+				ensure!(p < expiring.len(), "candidate must not form a duplicated member if elected");
+			}
+
+			let (registered_since, candidate_index): (VoteIndex, u32) =
+				Self::candidate_reg_info(&candidate).ok_or("presented candidate must be current")?;
+			let actual_total = voters.iter()
+				.zip(stakes.iter())
+				.filter_map(|(voter, stake)|
+							match Self::voter_last_active(voter) {
+								Some(b) if b >= registered_since =>
+									Self::approvals_of(voter).get(candidate_index as usize)
+									.and_then(|approved| if *approved { Some(*stake) } else { None }),
+								_ => None,
+							})
+				.fold(Zero::zero(), |acc, n| acc + n);
+			let dupe = leaderboard.iter().find(|&&(_, ref c)| c == &candidate).is_some();
+			if total == actual_total && !dupe {
+				// insert into leaderboard
+				leaderboard[0] = (total, candidate);
+				leaderboard.sort_by_key(|&(t, _)| t);
+				<Leaderboard<T>>::put(leaderboard);
+				Ok(())
+			} else {
+				// we can rest assured it will be Ok since we checked `can_slash` earlier; still
+				// better safe than sorry.
+				let _ = <balances::Module<T>>::slash(&who, bad_presentation_punishment);
+				Err(if dupe { "duplicate presentation" } else { "incorrect total" })
+			}
+		}
+
+		/// Set the desired member count; if lower than the current count, then seats will not be up
+		/// election when they expire. If more, then a new vote will be started if one is not already
+		/// in progress.
+		fn set_desired_seats(count: Compact<u32>) -> Result {
+			let count: u32 = count.into();
+			<DesiredSeats<T>>::put(count);
+			Ok(())
+		}
+
+		/// Remove a particular member. A tally will happen instantly (if not already in a presentation
+		/// period) to fill the seat if removal means that the desired members are not met.
+		/// This is effective immediately.
+		fn remove_member(who: Address<T::AccountId, T::AccountIndex>) -> Result {
+			let who = <balances::Module<T>>::lookup(who)?;
+			let new_council: Vec<(T::AccountId, T::BlockNumber)> = Self::active_council()
+				.into_iter()
+				.filter(|i| i.0 != who)
+				.collect();
+			<ActiveCouncil<T>>::put(new_council);
+			Ok(())
+		}
+
+		/// Set the presentation duration. If there is currently a vote being presented for, will
+		/// invoke `finalise_vote`.
+		fn set_presentation_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<PresentationDuration<T>>::put(count.into());
+			Ok(())
+		}
+
+		/// Set the presentation duration. If there is current a vote being presented for, will
+		/// invoke `finalise_vote`.
+		fn set_term_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<TermDuration<T>>::put(count.into());
+			Ok(())
+		}
+
+		fn on_finalise(n: T::BlockNumber) {
+			if let Err(e) = Self::end_block(n) {
+				print("Guru meditation");
+				print(e);
+			}
+		}
 	}
 }
 
@@ -170,12 +388,6 @@ decl_event!(
 );
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	// exposed immutables.
 
 	/// True if we're currently in a presentation period.
@@ -224,230 +436,7 @@ impl<T: Trait> Module<T> {
 		}
 	}
 
-	// dispatch
-
-	/// Set candidate approvals. Approval slots stay valid as long as candidates in those slots
-	/// are registered.
-	fn set_approvals(origin: T::Origin, votes: Vec<bool>, index: Compact<VoteIndex>) -> Result {
-		let who = ensure_signed(origin)?;
-		let index: VoteIndex = index.into();
-
-		ensure!(!Self::presentation_active(), "no approval changes during presentation period");
-		ensure!(index == Self::vote_index(), "incorrect vote index");
-		if !<LastActiveOf<T>>::exists(&who) {
-			// not yet a voter - deduct bond.
-			// NOTE: this must be the last potential bailer, since it changes state.
-			<balances::Module<T>>::reserve(&who, Self::voting_bond())?;
-
-			<Voters<T>>::put({
-				let mut v = Self::voters();
-				v.push(who.clone());
-				v
-			});
-		}
-		<LastActiveOf<T>>::insert(&who, index);
-		<ApprovalsOf<T>>::insert(&who, votes);
-		Ok(())
-	}
-
-	/// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices
-	/// must now be either unregistered or registered to a candidate that registered the slot after
-	/// the voter gave their last approval set.
-	///
-	/// May be called by anyone. Returns the voter deposit to `signed`.
-	fn reap_inactive_voter(
-		origin: T::Origin,
-		reporter_index: Compact<u32>,
-		who: Address<T::AccountId, T::AccountIndex>,
-		who_index: Compact<u32>,
-		assumed_vote_index: Compact<VoteIndex>
-	) -> Result {
-		let reporter = ensure_signed(origin)?;
-		let assumed_vote_index: VoteIndex = assumed_vote_index.into();
-
-		let who = <balances::Module<T>>::lookup(who)?;
-		ensure!(!Self::presentation_active(), "cannot reap during presentation period");
-		ensure!(Self::voter_last_active(&reporter).is_some(), "reporter must be a voter");
-		let last_active = Self::voter_last_active(&who).ok_or("target for inactivity cleanup must be active")?;
-		ensure!(assumed_vote_index == Self::vote_index(), "vote index not current");
-		ensure!(last_active < assumed_vote_index - Self::inactivity_grace_period(), "cannot reap during grace perid");
-		let voters = Self::voters();
-		let reporter_index: u32 = reporter_index.into();
-		let reporter_index = reporter_index as usize;
-		let who_index: u32 = who_index.into();
-		let who_index = who_index as usize;
-		ensure!(reporter_index < voters.len() && voters[reporter_index] == reporter, "bad reporter index");
-		ensure!(who_index < voters.len() && voters[who_index] == who, "bad target index");
-
-		// will definitely kill one of signed or who now.
-
-		let valid = !Self::approvals_of(&who).iter()
-			.zip(Self::candidates().iter())
-			.any(|(&appr, addr)|
-				appr &&
-				*addr != T::AccountId::default() &&
-				Self::candidate_reg_info(addr).map_or(false, |x| x.0 <= last_active)/*defensive only: all items in candidates list are registered*/
-			);
-
-		Self::remove_voter(
-			if valid { &who } else { &reporter },
-			if valid { who_index } else { reporter_index },
-			voters
-		);
-		if valid {
-			// This only fails if `who` doesn't exist, which it clearly must do since its the origin.
-			// Still, it's no more harmful to propagate any error at this point.
-			<balances::Module<T>>::repatriate_reserved(&who, &reporter, Self::voting_bond())?;
-			Self::deposit_event(RawEvent::VoterReaped(who, reporter));
-		} else {
-			<balances::Module<T>>::slash_reserved(&reporter, Self::voting_bond());
-			Self::deposit_event(RawEvent::BadReaperSlashed(reporter));
-		}
-		Ok(())
-	}
-
-	/// Remove a voter. All votes are cancelled and the voter deposit is returned.
-	fn retract_voter(origin: T::Origin, index: Compact<u32>) -> Result {
-		let who = ensure_signed(origin)?;
-
-		ensure!(!Self::presentation_active(), "cannot retract when presenting");
-		ensure!(<LastActiveOf<T>>::exists(&who), "cannot retract non-voter");
-		let voters = Self::voters();
-		let index: u32 = index.into();
-		let index = index as usize;
-		ensure!(index < voters.len(), "retraction index invalid");
-		ensure!(voters[index] == who, "retraction index mismatch");
-
-		Self::remove_voter(&who, index, voters);
-		<balances::Module<T>>::unreserve(&who, Self::voting_bond());
-		Ok(())
-	}
-
-	/// Submit oneself for candidacy.
-	///
-	/// Account must have enough transferrable funds in it to pay the bond.
-	fn submit_candidacy(origin: T::Origin, slot: Compact<u32>) -> Result {
-		let who = ensure_signed(origin)?;
-
-		ensure!(!Self::is_a_candidate(&who), "duplicate candidate submission");
-		let slot: u32 = slot.into();
-		let slot = slot as usize;
-		let count = Self::candidate_count() as usize;
-		let candidates = Self::candidates();
-		ensure!(
-			(slot == count && count == candidates.len()) ||
-			(slot < candidates.len() && candidates[slot] == T::AccountId::default()),
-			"invalid candidate slot"
-		);
-		// NOTE: This must be last as it has side-effects.
-		<balances::Module<T>>::reserve(&who, Self::candidacy_bond())
-			.map_err(|_| "candidate has not enough funds")?;
-
-		<RegisterInfoOf<T>>::insert(&who, (Self::vote_index(), slot as u32));
-		let mut candidates = candidates;
-		if slot == candidates.len() {
-			candidates.push(who);
-		} else {
-			candidates[slot] = who;
-		}
-		<Candidates<T>>::put(candidates);
-		<CandidateCount<T>>::put(count as u32 + 1);
-		Ok(())
-	}
-
-	/// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates.
-	/// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()``
-	/// `signed` should have at least
-	fn present_winner(
-		origin: T::Origin,
-		candidate: Address<T::AccountId, T::AccountIndex>,
-		total: <T::Balance as HasCompact>::Type,
-		index: Compact<VoteIndex>
-	) -> Result {
-		let who = ensure_signed(origin)?;
-		let total = total.into();
-		let index: VoteIndex = index.into();
-
-		let candidate = <balances::Module<T>>::lookup(candidate)?;
-		ensure!(index == Self::vote_index(), "index not current");
-		let (_, _, expiring) = Self::next_finalise().ok_or("cannot present outside of presentation period")?;
-		let stakes = Self::snapshoted_stakes();
-		let voters = Self::voters();
-		let bad_presentation_punishment = Self::present_slash_per_voter() * T::Balance::sa(voters.len() as u64);
-		ensure!(<balances::Module<T>>::can_slash(&who, bad_presentation_punishment), "presenter must have sufficient slashable funds");
-
-		let mut leaderboard = Self::leaderboard().ok_or("leaderboard must exist while present phase active")?;
-		ensure!(total > leaderboard[0].0, "candidate not worthy of leaderboard");
-
-		if let Some(p) = Self::active_council().iter().position(|&(ref c, _)| c == &candidate) {
-			ensure!(p < expiring.len(), "candidate must not form a duplicated member if elected");
-		}
-
-		let (registered_since, candidate_index): (VoteIndex, u32) =
-			Self::candidate_reg_info(&candidate).ok_or("presented candidate must be current")?;
-		let actual_total = voters.iter()
-			.zip(stakes.iter())
-			.filter_map(|(voter, stake)|
-				match Self::voter_last_active(voter) {
-					Some(b) if b >= registered_since =>
-						Self::approvals_of(voter).get(candidate_index as usize)
-							.and_then(|approved| if *approved { Some(*stake) } else { None }),
-					_ => None,
-				})
-			.fold(Zero::zero(), |acc, n| acc + n);
-		let dupe = leaderboard.iter().find(|&&(_, ref c)| c == &candidate).is_some();
-		if total == actual_total && !dupe {
-			// insert into leaderboard
-			leaderboard[0] = (total, candidate);
-			leaderboard.sort_by_key(|&(t, _)| t);
-			<Leaderboard<T>>::put(leaderboard);
-			Ok(())
-		} else {
-			// we can rest assured it will be Ok since we checked `can_slash` earlier; still
-			// better safe than sorry.
-			let _ = <balances::Module<T>>::slash(&who, bad_presentation_punishment);
-			Err(if dupe { "duplicate presentation" } else { "incorrect total" })
-		}
-	}
-
-	/// Set the desired member count; if lower than the current count, then seats will not be up
-	/// election when they expire. If more, then a new vote will be started if one is not already
-	/// in progress.
-	fn set_desired_seats(count: Compact<u32>) -> Result {
-		let count: u32 = count.into();
-		<DesiredSeats<T>>::put(count);
-		Ok(())
-	}
-
-	/// Remove a particular member. A tally will happen instantly (if not already in a presentation
-	/// period) to fill the seat if removal means that the desired members are not met.
-	/// This is effective immediately.
-	fn remove_member(who: Address<T::AccountId, T::AccountIndex>) -> Result {
-		let who = <balances::Module<T>>::lookup(who)?;
-		let new_council: Vec<(T::AccountId, T::BlockNumber)> = Self::active_council()
-			.into_iter()
-			.filter(|i| i.0 != who)
-			.collect();
-		<ActiveCouncil<T>>::put(new_council);
-		Ok(())
-	}
-
-	/// Set the presentation duration. If there is currently a vote being presented for, will
-	/// invoke `finalise_vote`.
-	fn set_presentation_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<PresentationDuration<T>>::put(count.into());
-		Ok(())
-	}
-
-	/// Set the presentation duration. If there is current a vote being presented for, will
-	/// invoke `finalise_vote`.
-	fn set_term_duration(count: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<TermDuration<T>>::put(count.into());
-		Ok(())
-	}
-
-	// private
-
+	// Private
 	/// Check there's nothing to do this block
 	fn end_block(block_number: T::BlockNumber) -> Result {
 		if (block_number % Self::voting_period()).is_zero() {
@@ -560,15 +549,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(n: T::BlockNumber) {
-		if let Err(e) = Self::end_block(n) {
-			print("Guru meditation");
-			print(e);
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/council/src/voting.rs b/substrate/srml/council/src/voting.rs
index 094066327c07013942e54901b378f8ef6e8e2bf2..b598e8ca05257b1b91708148f389fe7431c06bcc 100644
--- a/substrate/srml/council/src/voting.rs
+++ b/substrate/srml/council/src/voting.rs
@@ -19,7 +19,7 @@
 use rstd::prelude::*;
 use rstd::borrow::Borrow;
 use codec::HasCompact;
-use primitives::traits::{OnFinalise, Hash, As};
+use primitives::traits::{Hash, As};
 use runtime_io::print;
 use srml_support::dispatch::Result;
 use srml_support::{StorageValue, StorageMap, IsSubType};
@@ -33,12 +33,88 @@ pub trait Trait: CouncilTrait {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn propose(origin, proposal: Box<T::Proposal>) -> Result;
-		fn vote(origin, proposal: T::Hash, approve: bool) -> Result;
-		fn veto(origin, proposal_hash: T::Hash) -> Result;
+		fn deposit_event() = default;
 
-		fn set_cooloff_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result;
-		fn set_voting_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result;
+		fn propose(origin, proposal: Box<T::Proposal>) -> Result {
+			let who = ensure_signed(origin)?;
+
+			let expiry = <system::Module<T>>::block_number() + Self::voting_period();
+			ensure!(Self::will_still_be_councillor_at(&who, expiry), "proposer would not be on council");
+
+			let proposal_hash = T::Hashing::hash_of(&proposal);
+
+			ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
+			ensure!(!Self::is_vetoed(&proposal_hash), "proposal is vetoed");
+
+			let mut proposals = Self::proposals();
+			proposals.push((expiry, proposal_hash));
+			proposals.sort_by_key(|&(expiry, _)| expiry);
+			Self::set_proposals(&proposals);
+
+			<ProposalOf<T>>::insert(proposal_hash, *proposal);
+			<ProposalVoters<T>>::insert(proposal_hash, vec![who.clone()]);
+			<CouncilVoteOf<T>>::insert((proposal_hash, who.clone()), true);
+
+			Ok(())
+		}
+
+		fn vote(origin, proposal: T::Hash, approve: bool) -> Result {
+			let who = ensure_signed(origin)?;
+
+			ensure!(Self::is_councillor(&who), "only councillors may vote on council proposals");
+
+			if Self::vote_of((proposal, who.clone())).is_none() {
+				<ProposalVoters<T>>::mutate(proposal, |voters| voters.push(who.clone()));
+			}
+			<CouncilVoteOf<T>>::insert((proposal, who), approve);
+			Ok(())
+		}
+
+		fn veto(origin, proposal_hash: T::Hash) -> Result {
+			let who = ensure_signed(origin)?;
+
+			ensure!(Self::is_councillor(&who), "only councillors may veto council proposals");
+			ensure!(<ProposalVoters<T>>::exists(&proposal_hash), "proposal must exist to be vetoed");
+
+			let mut existing_vetoers = Self::veto_of(&proposal_hash)
+				.map(|pair| pair.1)
+				.unwrap_or_else(Vec::new);
+			let insert_position = existing_vetoers.binary_search(&who)
+				.err().ok_or("a councillor may not veto a proposal twice")?;
+			existing_vetoers.insert(insert_position, who);
+			Self::set_veto_of(
+				&proposal_hash,
+				<system::Module<T>>::block_number() + Self::cooloff_period(),
+				existing_vetoers
+			);
+
+			Self::set_proposals(
+				&Self::proposals().into_iter().filter(|&(_, h)| h != proposal_hash
+			).collect::<Vec<_>>());
+			<ProposalVoters<T>>::remove(proposal_hash);
+			<ProposalOf<T>>::remove(proposal_hash);
+			for (c, _) in <Council<T>>::active_council() {
+				<CouncilVoteOf<T>>::remove((proposal_hash, c));
+			}
+			Ok(())
+		}
+
+		fn set_cooloff_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<CooloffPeriod<T>>::put(blocks.into());
+			Ok(())
+		}
+
+		fn set_voting_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<VotingPeriod<T>>::put(blocks.into());
+			Ok(())
+		}
+
+		fn on_finalise(n: T::BlockNumber) {
+			if let Err(e) = Self::end_block(n) {
+				print("Guru meditation");
+				print(e);
+			}
+		}
 	}
 }
 
@@ -67,12 +143,6 @@ decl_event!(
 );
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	pub fn is_vetoed<B: Borrow<T::Hash>>(proposal: B) -> bool {
 		Self::veto_of(proposal.borrow())
 			.map(|(expiry, _): (T::BlockNumber, Vec<T::AccountId>)| <system::Module<T>>::block_number() < expiry)
@@ -95,78 +165,7 @@ impl<T: Trait> Module<T> {
 		Self::generic_tally(proposal_hash, |w: &T::AccountId, p: &T::Hash| Self::vote_of((*p, w.clone())))
 	}
 
-	// Dispatch
-	fn propose(origin: T::Origin, proposal: Box<T::Proposal>) -> Result {
-		let who = ensure_signed(origin)?;
-
-		let expiry = <system::Module<T>>::block_number() + Self::voting_period();
-		ensure!(Self::will_still_be_councillor_at(&who, expiry), "proposer would not be on council");
-
-		let proposal_hash = T::Hashing::hash_of(&proposal);
-
-		ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
-		ensure!(!Self::is_vetoed(&proposal_hash), "proposal is vetoed");
-
-		let mut proposals = Self::proposals();
-		proposals.push((expiry, proposal_hash));
-		proposals.sort_by_key(|&(expiry, _)| expiry);
-		Self::set_proposals(&proposals);
-
-		<ProposalOf<T>>::insert(proposal_hash, *proposal);
-		<ProposalVoters<T>>::insert(proposal_hash, vec![who.clone()]);
-		<CouncilVoteOf<T>>::insert((proposal_hash, who.clone()), true);
-
-		Ok(())
-	}
-
-	fn vote(origin: T::Origin, proposal: T::Hash, approve: bool) -> Result {
-		let who = ensure_signed(origin)?;
-
-		ensure!(Self::is_councillor(&who), "only councillors may vote on council proposals");
-
-		if Self::vote_of((proposal, who.clone())).is_none() {
-			<ProposalVoters<T>>::mutate(proposal, |voters| voters.push(who.clone()));
-		}
-		<CouncilVoteOf<T>>::insert((proposal, who), approve);
-		Ok(())
-	}
-
-	fn veto(origin: T::Origin, proposal_hash: T::Hash) -> Result {
-		let who = ensure_signed(origin)?;
-
-		ensure!(Self::is_councillor(&who), "only councillors may veto council proposals");
-		ensure!(<ProposalVoters<T>>::exists(&proposal_hash), "proposal must exist to be vetoed");
-
-		let mut existing_vetoers = Self::veto_of(&proposal_hash)
-			.map(|pair| pair.1)
-			.unwrap_or_else(Vec::new);
-		let insert_position = existing_vetoers.binary_search(&who)
-			.err().ok_or("a councillor may not veto a proposal twice")?;
-		existing_vetoers.insert(insert_position, who);
-		Self::set_veto_of(&proposal_hash, <system::Module<T>>::block_number() + Self::cooloff_period(), existing_vetoers);
-
-		Self::set_proposals(&Self::proposals().into_iter().filter(|&(_, h)| h != proposal_hash).collect::<Vec<_>>());
-		<ProposalVoters<T>>::remove(proposal_hash);
-		<ProposalOf<T>>::remove(proposal_hash);
-		for (c, _) in <Council<T>>::active_council() {
-			<CouncilVoteOf<T>>::remove((proposal_hash, c));
-		}
-		Ok(())
-	}
-
-	fn set_cooloff_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<CooloffPeriod<T>>::put(blocks.into());
-		Ok(())
-	}
-
-	fn set_voting_period(blocks: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<VotingPeriod<T>>::put(blocks.into());
-		Ok(())
-	}
-
-	// private
-
-
+	// Private
 	fn set_veto_of(proposal: &T::Hash, expiry: T::BlockNumber, vetoers: Vec<T::AccountId>) {
 		<VetoedProposal<T>>::insert(proposal, (expiry, vetoers));
 	}
@@ -227,15 +226,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(n: T::BlockNumber) {
-		if let Err(e) = Self::end_block(n) {
-			print("Guru meditation");
-			print(e);
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs
index f5c3153251c57e6f57f05bc9674bc6df7762e8a3..9acacb2ea96512d3bfd19ced571a8986b09e4e6f 100644
--- a/substrate/srml/democracy/src/lib.rs
+++ b/substrate/srml/democracy/src/lib.rs
@@ -41,7 +41,7 @@ extern crate srml_system as system;
 use rstd::prelude::*;
 use rstd::result;
 use codec::{HasCompact, Compact};
-use primitives::traits::{Zero, OnFinalise, As, MaybeSerializeDebug};
+use primitives::traits::{Zero, As, MaybeSerializeDebug};
 use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType};
 use srml_support::dispatch::Result;
 use system::ensure_signed;
@@ -62,12 +62,79 @@ pub trait Trait: balances::Trait + Sized {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn propose(origin, proposal: Box<T::Proposal>, value: <T::Balance as HasCompact>::Type) -> Result;
-		fn second(origin, proposal: Compact<PropIndex>) -> Result;
-		fn vote(origin, ref_index: Compact<ReferendumIndex>, approve_proposal: bool) -> Result;
+		fn deposit_event() = default;
+
+		/// Propose a sensitive action to be taken.
+		fn propose(
+			origin,
+			proposal: Box<T::Proposal>,
+			value: <T::Balance as HasCompact>::Type
+		) -> Result {
+			let who = ensure_signed(origin)?;
+			let value = value.into();
+
+			ensure!(value >= Self::minimum_deposit(), "value too low");
+			<balances::Module<T>>::reserve(&who, value)
+				.map_err(|_| "proposer's balance too low")?;
+
+			let index = Self::public_prop_count();
+			<PublicPropCount<T>>::put(index + 1);
+			<DepositOf<T>>::insert(index, (value, vec![who.clone()]));
+
+			let mut props = Self::public_props();
+			props.push((index, (*proposal).clone(), who));
+			<PublicProps<T>>::put(props);
+			Ok(())
+		}
+
+		/// Propose a sensitive action to be taken.
+		fn second(origin, proposal: Compact<PropIndex>) -> Result {
+			let who = ensure_signed(origin)?;
+			let proposal: PropIndex = proposal.into();
+			let mut deposit = Self::deposit_of(proposal)
+				.ok_or("can only second an existing proposal")?;
+			<balances::Module<T>>::reserve(&who, deposit.0)
+				.map_err(|_| "seconder's balance too low")?;
+			deposit.1.push(who);
+			<DepositOf<T>>::insert(proposal, deposit);
+			Ok(())
+		}
+
+		/// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal;
+		/// false would be a vote to keep the status quo.
+		fn vote(origin, ref_index: Compact<ReferendumIndex>, approve_proposal: bool) -> Result {
+			let who = ensure_signed(origin)?;
+			let ref_index = ref_index.into();
+			ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum.");
+			ensure!(!<balances::Module<T>>::total_balance(&who).is_zero(),
+					"transactor must have balance to signal approval.");
+			if !<VoteOf<T>>::exists(&(ref_index, who.clone())) {
+				<VotersFor<T>>::mutate(ref_index, |voters| voters.push(who.clone()));
+			}
+			<VoteOf<T>>::insert(&(ref_index, who), approve_proposal);
+			Ok(())
+		}
+
+		/// Start a referendum.
+		fn start_referendum(proposal: Box<T::Proposal>, vote_threshold: VoteThreshold) -> Result {
+			Self::inject_referendum(
+				<system::Module<T>>::block_number() + Self::voting_period(),
+				*proposal,
+				vote_threshold
+			).map(|_| ())
+		}
+
+		/// Remove a referendum.
+		fn cancel_referendum(ref_index: Compact<ReferendumIndex>) -> Result {
+			Self::clear_referendum(ref_index.into());
+			Ok(())
+		}
 
-		fn start_referendum(proposal: Box<T::Proposal>, vote_threshold: VoteThreshold) -> Result;
-		fn cancel_referendum(ref_index: Compact<ReferendumIndex>) -> Result;
+		fn on_finalise(n: T::BlockNumber) {
+			if let Err(e) = Self::end_block(n) {
+				runtime_io::print(e);
+			}
+		}
 	}
 }
 
@@ -116,12 +183,6 @@ decl_event!(
 );
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	// exposed immutables.
 
 	/// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal
@@ -162,71 +223,7 @@ impl<T: Trait> Module<T> {
 			.fold((Zero::zero(), Zero::zero()), |(a, b), (c, d)| (a + c, b + d))
 	}
 
-	// dispatching.
-
-	/// Propose a sensitive action to be taken.
-	fn propose(origin: T::Origin, proposal: Box<T::Proposal>, value: <T::Balance as HasCompact>::Type) -> Result {
-		let who = ensure_signed(origin)?;
-		let value = value.into();
-
-		ensure!(value >= Self::minimum_deposit(), "value too low");
-		<balances::Module<T>>::reserve(&who, value)
-			.map_err(|_| "proposer's balance too low")?;
-
-		let index = Self::public_prop_count();
-		<PublicPropCount<T>>::put(index + 1);
-		<DepositOf<T>>::insert(index, (value, vec![who.clone()]));
-
-		let mut props = Self::public_props();
-		props.push((index, (*proposal).clone(), who));
-		<PublicProps<T>>::put(props);
-		Ok(())
-	}
-
-	/// Propose a sensitive action to be taken.
-	fn second(origin: T::Origin, proposal: Compact<PropIndex>) -> Result {
-		let who = ensure_signed(origin)?;
-		let proposal: PropIndex = proposal.into();
-		let mut deposit = Self::deposit_of(proposal)
-			.ok_or("can only second an existing proposal")?;
-		<balances::Module<T>>::reserve(&who, deposit.0)
-			.map_err(|_| "seconder's balance too low")?;
-		deposit.1.push(who);
-		<DepositOf<T>>::insert(proposal, deposit);
-		Ok(())
-	}
-
-	/// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal;
-	/// false would be a vote to keep the status quo.
-	fn vote(origin: T::Origin, ref_index: Compact<ReferendumIndex>, approve_proposal: bool) -> Result {
-		let who = ensure_signed(origin)?;
-		let ref_index = ref_index.into();
-		ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum.");
-		ensure!(!<balances::Module<T>>::total_balance(&who).is_zero(),
-			"transactor must have balance to signal approval.");
-		if !<VoteOf<T>>::exists(&(ref_index, who.clone())) {
-			<VotersFor<T>>::mutate(ref_index, |voters| voters.push(who.clone()));
-		}
-		<VoteOf<T>>::insert(&(ref_index, who), approve_proposal);
-		Ok(())
-	}
-
-	/// Start a referendum.
-	fn start_referendum(proposal: Box<T::Proposal>, vote_threshold: VoteThreshold) -> Result {
-		Self::inject_referendum(
-			<system::Module<T>>::block_number() + Self::voting_period(),
-			*proposal,
-			vote_threshold
-		).map(|_| ())
-	}
-
-	/// Remove a referendum.
-	fn cancel_referendum(ref_index: Compact<ReferendumIndex>) -> Result {
-		Self::clear_referendum(ref_index.into());
-		Ok(())
-	}
-
-	// exposed mutables.
+	// Exposed mutables.
 
 	/// Start a referendum. Can be called directly by the council.
 	pub fn internal_start_referendum(proposal: T::Proposal, vote_threshold: VoteThreshold) -> result::Result<ReferendumIndex, &'static str> {
@@ -308,14 +305,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(n: T::BlockNumber) {
-		if let Err(e) = Self::end_block(n) {
-			runtime_io::print(e);
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/example/src/lib.rs b/substrate/srml/example/src/lib.rs
index f60168d37b3e9d0680a3af4a351ba225997c30df..d6d7ea31faf5f6d39f33754d8261c66298a5de25 100644
--- a/substrate/srml/example/src/lib.rs
+++ b/substrate/srml/example/src/lib.rs
@@ -57,7 +57,6 @@ extern crate srml_system as system;
 // might find it useful).
 extern crate srml_balances as balances;
 
-use sr_primitives::traits::OnFinalise;
 use support::{StorageValue, dispatch::Result};
 use system::ensure_signed;
 
@@ -104,13 +103,97 @@ pub trait Trait: balances::Trait {
 decl_module! {
 	// Simple declaration of the `Module` type. Lets the macro know what its working on.
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		/// Deposit one of this module's events by using the default implementation.
+		/// It is also possible to provide a custom implementation.
+		fn deposit_event() = default;
 		/// This is your public interface. Be extremely careful.
 		/// This is just a simple example of how to interact with the module from the external
 		/// world.
-		fn accumulate_dummy(origin, increase_by: T::Balance) -> Result;
+		// This just increases the value of `Dummy` by `increase_by`.
+		//
+		// Since this is a dispatched function there are two extremely important things to
+		// remember:
+		//
+		// - MUST NOT PANIC: Under no circumstances (save, perhaps, storage getting into an
+		// irreparably damaged state) must this function panic.
+		// - NO SIDE-EFFECTS ON ERROR: This function must either complete totally (and return
+		// `Ok(())` or it must have no side-effects on storage and return `Err('Some reason')`.
+		//
+		// The first is relatively easy to audit for - just ensure all panickers are removed from
+		// logic that executes in production (which you do anyway, right?!). To ensure the second
+		// is followed, you should do all tests for validity at the top of your function. This
+		// is stuff like checking the sender (`origin`) or that state is such that the operation
+		// makes sense.
+		//
+		// Once you've determined that it's all good, then enact the operation and change storage.
+		// If you can't be certain that the operation will succeed without substantial computation
+		// then you have a classic blockchain attack scenario. The normal way of managing this is
+		// to attach a bond to the operation. As the first major alteration of storage, reserve
+		// some value from the sender's account (`Balances` module has a `reserve` function for
+		// exactly this scenario). This amount should be enough to cover any costs of the
+		// substantial execution in case it turns out that you can't proceed with the operation.
+		//
+		// If it eventually transpires that the operation is fine and, therefore, that the
+		// expense of the checks should be borne by the network, then you can refund the reserved
+		// deposit. If, however, the operation turns out to be invalid and the computation is
+		// wasted, then you can burn it or repatriate elsewhere.
+		//
+		// Security bonds ensure that attackers can't game it by ensuring that anyone interacting
+		// with the system either progresses it or pays for the trouble of faffing around with
+		// no progress.
+		//
+		// If you don't respect these rules, it is likely that your chain will be attackable.
+		fn accumulate_dummy(origin, increase_by: T::Balance) -> Result {
+			// This is a public call, so we ensure that the origin is some signed account.
+			let _sender = ensure_signed(origin)?;
+
+			// Read the value of dummy from storage.
+			// let dummy = Self::dummy();
+			// Will also work using the `::get` on the storage item type itself:
+			// let dummy = <Dummy<T>>::get();
+
+			// Calculate the new value.
+			// let new_dummy = dummy.map_or(increase_by, |dummy| dummy + increase_by);
+
+			// Put the new value into storage.
+			// <Dummy<T>>::put(new_dummy);
+			// Will also work with a reference:
+			// <Dummy<T>>::put(&new_dummy);
+
+			// Here's the new one of read and then modify the value.
+			<Dummy<T>>::mutate(|dummy| {
+				let new_dummy = dummy.map_or(increase_by, |dummy| dummy + increase_by);
+				*dummy = Some(new_dummy);
+			});
+
+			// Let's deposit an event to let the outside world know this happened.
+			Self::deposit_event(RawEvent::Dummy(increase_by));
+
+			// All good.
+			Ok(())
+		}
 
 		/// A privileged call; in this case it resets our dummy value to something new.
-		fn set_dummy(new_dummy: T::Balance) -> Result;
+		// Implementation of a privileged call. This doesn't have an `origin` parameter because
+		// it's not (directly) from an extrinsic, but rather the system as a whole has decided
+		// to execute it. Different runtimes have different reasons for allow privileged
+		// calls to be executed - we don't need to care why. Because it's privileged, we can
+		// assume it's a one-off operation and substantial processing/storage/memory can be used
+		// without worrying about gameability or attack scenarios.
+		fn set_dummy(new_value: T::Balance) -> Result {
+			// Put the new value into storage.
+			<Dummy<T>>::put(new_value);
+
+			// All good.
+			Ok(())
+		}
+
+		// The signature could also look like: `fn on_finalise()`
+		fn on_finalise(_n: T::BlockNumber) {
+			// Anything that needs to be done at the end of the block.
+			// We just kill our dummy storage item.
+			<Dummy<T>>::kill();
+		}
 	}
 }
 
@@ -162,119 +245,27 @@ decl_storage! {
 
 // The main implementation block for the module. Functions here fall into three broad
 // categories:
-// - Implementations of dispatch functions. The dispatch code generated by the module macro
-// expects each of its functions to be implemented.
 // - Public interface. These are functions that are `pub` and generally fall into inspector
 // functions that do not write to storage and operation functions that do.
 // - Private functions. These are your usual private utilities unavailable to other modules.
 impl<T: Trait> Module<T> {
-	/// Deposit one of this module's events.
-	// TODO: move into `decl_module` macro.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
-	// Implement Calls and add public immutables and private mutables.
-
-	// Implement dispatched function `accumulate_dummy`. This just increases the value
-	// of `Dummy` by `increase_by`.
-	//
-	// Since this is a dispatched function there are two extremely important things to
-	// remember:
-	//
-	// - MUST NOT PANIC: Under no circumstances (save, perhaps, storage getting into an
-	// irreparably damaged state) must this function panic.
-	// - NO SIDE-EFFECTS ON ERROR: This function must either complete totally (and return
-	// `Ok(())` or it must have no side-effects on storage and return `Err('Some reason')`.
-	//
-	// The first is relatively easy to audit for - just ensure all panickers are removed from
-	// logic that executes in production (which you do anyway, right?!). To ensure the second
-	// is followed, you should do all tests for validity at the top of your function. This
-	// is stuff like checking the sender (`origin`) or that state is such that the operation
-	// makes sense.
-	//
-	// Once you've determined that it's all good, then enact the operation and change storage.
-	// If you can't be certain that the operation will succeed without substantial computation
-	// then you have a classic blockchain attack scenario. The normal way of managing this is
-	// to attach a bond to the operation. As the first major alteration of storage, reserve
-	// some value from the sender's account (`Balances` module has a `reserve` function for
-	// exactly this scenario). This amount should be enough to cover any costs of the
-	// substantial execution in case it turns out that you can't proceed with the operation.
-	//
-	// If it eventually transpires that the operation is fine and, therefore, that the
-	// expense of the checks should be borne by the network, then you can refund the reserved
-	// deposit. If, however, the operation turns out to be invalid and the computation is
-	// wasted, then you can burn it or repatriate elsewhere.
-	//
-	// Security bonds ensure that attackers can't game it by ensuring that anyone interacting
-	// with the system either progresses it or pays for the trouble of faffing around with
-	// no progress.
-	//
-	// If you don't respect these rules, it is likely that your chain will be attackable.
-	fn accumulate_dummy(origin: T::Origin, increase_by: T::Balance) -> Result {
-		// This is a public call, so we ensure that the origin is some signed account.
-		let _sender = ensure_signed(origin)?;
-
-		// Read the value of dummy from storage.
-		// let dummy = Self::dummy();
-		// Will also work using the `::get` on the storage item type itself:
-		// let dummy = <Dummy<T>>::get();
-
-		// Calculate the new value.
-		// let new_dummy = dummy.map_or(increase_by, |dummy| dummy + increase_by);
-
-		// Put the new value into storage.
-		// <Dummy<T>>::put(new_dummy);
-		// Will also work with a reference:
-		// <Dummy<T>>::put(&new_dummy);
-
-		// Here's the new one of read and then modify the value.
-		<Dummy<T>>::mutate(|dummy| {
-			let new_dummy = dummy.map_or(increase_by, |dummy| dummy + increase_by);
-			*dummy = Some(new_dummy);
-		});
-
-		// Let's deposit an event to let the outside world know this happened.
-		Self::deposit_event(RawEvent::Dummy(increase_by));
-
-		// All good.
-		Ok(())
-	}
-
+	// Add public immutables and private mutables.
 	#[allow(dead_code)]
 	fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> Result {
 		let _sender = ensure_signed(origin)?;
 
+		let prev = <Foo<T>>::get();
 		// Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an Option<> type.
-		<Foo<T>>::mutate(|foo| *foo = *foo + increase_by);
-
-		Ok(())
-	}
+		let result = <Foo<T>>::mutate(|foo| {
+			*foo = *foo + increase_by;
+			*foo
+		});
+		assert!(prev + increase_by == result);
 
-	// Implementation of a privileged call. This doesn't have an `origin` parameter because
-	// it's not (directly) from an extrinsic, but rather the system as a whole has decided
-	// to execute it. Different runtimes have different reasons for allow privileged
-	// calls to be executed - we don't need to care why. Because it's privileged, we can
-	// assume it's a one-off operation and substantial processing/storage/memory can be used
-	// without worrying about gameability or attack scenarios.
-	fn set_dummy(new_value: T::Balance) -> Result {
-		// Put the new value into storage.
-		<Dummy<T>>::put(new_value);
-
-		// All good.
 		Ok(())
 	}
 }
 
-// This trait expresses what should happen when the block is finalised.
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_: T::BlockNumber) {
-		// Anything that needs to be done at the end of the block.
-		// We just kill our dummy storage item.
-		<Dummy<T>>::kill();
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
@@ -283,7 +274,9 @@ mod tests {
 	use substrate_primitives::{H256, Blake2Hasher};
 	// The testing primitives are very useful for avoiding having to work with signatures
 	// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
-	use sr_primitives::{BuildStorage, traits::{BlakeTwo256}, testing::{Digest, DigestItem, Header}};
+	use sr_primitives::{
+		BuildStorage, traits::{BlakeTwo256, OnFinalise}, testing::{Digest, DigestItem, Header}
+	};
 
 	impl_outer_origin! {
 		pub enum Origin for Test {}
diff --git a/substrate/srml/session/src/lib.rs b/substrate/srml/session/src/lib.rs
index 087e37ecfe9a888cc98133eda2dab6bee626473b..cc75c75bc52b650d97f70b974a0e29bddbffb47c 100644
--- a/substrate/srml/session/src/lib.rs
+++ b/substrate/srml/session/src/lib.rs
@@ -42,7 +42,7 @@ extern crate srml_system as system;
 extern crate srml_timestamp as timestamp;
 
 use rstd::prelude::*;
-use primitives::traits::{As, Zero, One, OnFinalise, Convert};
+use primitives::traits::{As, Zero, One, Convert};
 use codec::HasCompact;
 use runtime_support::{StorageValue, StorageMap};
 use runtime_support::dispatch::Result;
@@ -67,10 +67,31 @@ pub trait Trait: timestamp::Trait {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn set_key(origin, key: T::SessionKey) -> Result;
+		fn deposit_event() = default;
+
+		/// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next
+		/// session.
+		fn set_key(origin, key: T::SessionKey) -> Result {
+			let who = ensure_signed(origin)?;
+			// set new value for next session
+			<NextKeyFor<T>>::insert(who, key);
+			Ok(())
+		}
+
+		/// Set a new session length. Won't kick in until the next session change (at current length).
+		fn set_length(new: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<NextSessionLength<T>>::put(new.into());
+			Ok(())
+		}
 
-		fn set_length(new: <T::BlockNumber as HasCompact>::Type) -> Result;
-		fn force_new_session(apply_rewards: bool) -> Result;
+		/// Forces a new session.
+		fn force_new_session(apply_rewards: bool) -> Result {
+			Self::apply_force_new_session(apply_rewards)
+		}
+
+		fn on_finalise(n: T::BlockNumber) {
+			Self::check_rotate_session(n);
+		}
 	}
 }
 
@@ -108,12 +129,6 @@ decl_storage! {
 }
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
 	/// The number of validators currently.
 	pub fn validator_count() -> u32 {
 		<Validators<T>>::get().len() as u32	// TODO: can probably optimised
@@ -124,28 +139,7 @@ impl<T: Trait> Module<T> {
 		<LastLengthChange<T>>::get().unwrap_or_else(T::BlockNumber::zero)
 	}
 
-	/// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next
-	/// session.
-	fn set_key(origin: T::Origin, key: T::SessionKey) -> Result {
-		let who = ensure_signed(origin)?;
-		// set new value for next session
-		<NextKeyFor<T>>::insert(who, key);
-		Ok(())
-	}
-
-	/// Set a new session length. Won't kick in until the next session change (at current length).
-	fn set_length(new: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<NextSessionLength<T>>::put(new.into());
-		Ok(())
-	}
-
-	/// Forces a new session.
-	pub fn force_new_session(apply_rewards: bool) -> Result {
-		Self::apply_force_new_session(apply_rewards)
-	}
-
 	// INTERNAL API (available to other runtime modules)
-
 	/// Forces a new session, no origin.
 	pub fn apply_force_new_session(apply_rewards: bool) -> Result {
 		<ForcingNewSession<T>>::put(apply_rewards);
@@ -228,12 +222,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(n: T::BlockNumber) {
-		Self::check_rotate_session(n);
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/staking/src/lib.rs b/substrate/srml/staking/src/lib.rs
index 6b47e01c33c1cd66da581004a868e8965c40cdb3..680da340c54c53a1633b05f718a2d8be813188a6 100644
--- a/substrate/srml/staking/src/lib.rs
+++ b/substrate/srml/staking/src/lib.rs
@@ -55,7 +55,7 @@ use codec::{HasCompact, Compact};
 use runtime_support::{Parameter, StorageValue, StorageMap};
 use runtime_support::dispatch::Result;
 use session::OnSessionChange;
-use primitives::{Perbill, traits::{Zero, One, Bounded, OnFinalise, As}};
+use primitives::{Perbill, traits::{Zero, One, Bounded, As}};
 use balances::{address::Address, OnDilution};
 use system::ensure_signed;
 
@@ -76,7 +76,7 @@ pub enum LockStatus<BlockNumber: Parameter> {
 /// Preference of what happens on a slash event.
 #[derive(PartialEq, Eq, Clone, Encode, Decode)]
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-pub struct ValidatorPrefs<Balance: HasCompact + Copy> { // TODO: @bkchr shouldn't need this Copy but derive(Encode) breaks otherwise 
+pub struct ValidatorPrefs<Balance: HasCompact + Copy> { // TODO: @bkchr shouldn't need this Copy but derive(Encode) breaks otherwise
 	/// Validator should ensure this many more slashes than is necessary before being unstaked.
 	#[codec(compact)]
 	pub unstake_threshold: u32,
@@ -105,17 +105,140 @@ pub trait Trait: balances::Trait + session::Trait {
 decl_module! {
 	#[cfg_attr(feature = "std", serde(bound(deserialize = "T::Balance: ::serde::de::DeserializeOwned")))]
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn stake(origin) -> Result;
-		fn unstake(origin, intentions_index: Compact<u32>) -> Result;
-		fn nominate(origin, target: Address<T::AccountId, T::AccountIndex>) -> Result;
-		fn unnominate(origin, target_index: Compact<u32>) -> Result;
-		fn register_preferences(origin, intentions_index: Compact<u32>, prefs: ValidatorPrefs<T::Balance>) -> Result;
-
-		fn set_sessions_per_era(new: <T::BlockNumber as HasCompact>::Type) -> Result;
-		fn set_bonding_duration(new: <T::BlockNumber as HasCompact>::Type) -> Result;
-		fn set_validator_count(new: Compact<u32>) -> Result;
-		fn force_new_era(apply_rewards: bool) -> Result;
-		fn set_offline_slash_grace(new: Compact<u32>) -> Result;
+		fn deposit_event() = default;
+
+		/// Declare the desire to stake for the transactor.
+		///
+		/// Effects will be felt at the beginning of the next era.
+		fn stake(origin) -> Result {
+			let who = ensure_signed(origin)?;
+			ensure!(Self::nominating(&who).is_none(), "Cannot stake if already nominating.");
+			let mut intentions = <Intentions<T>>::get();
+			// can't be in the list twice.
+			ensure!(intentions.iter().find(|&t| t == &who).is_none(), "Cannot stake if already staked.");
+
+			<Bondage<T>>::insert(&who, T::BlockNumber::max_value());
+			intentions.push(who);
+			<Intentions<T>>::put(intentions);
+			Ok(())
+		}
+
+		/// Retract the desire to stake for the transactor.
+		///
+		/// Effects will be felt at the beginning of the next era.
+		fn unstake(origin, intentions_index: Compact<u32>) -> Result {
+			let who = ensure_signed(origin)?;
+			let intentions_index: u32 = intentions_index.into();
+			// unstake fails in degenerate case of having too few existing staked parties
+			if Self::intentions().len() <= Self::minimum_validator_count() as usize {
+				return Err("cannot unstake when there are too few staked participants")
+			}
+			Self::apply_unstake(&who, intentions_index as usize)
+		}
+
+		fn nominate(origin, target: Address<T::AccountId, T::AccountIndex>) -> Result {
+			let who = ensure_signed(origin)?;
+			let target = <balances::Module<T>>::lookup(target)?;
+
+			ensure!(Self::nominating(&who).is_none(), "Cannot nominate if already nominating.");
+			ensure!(Self::intentions().iter().find(|&t| t == &who).is_none(), "Cannot nominate if already staked.");
+
+			// update nominators_for
+			let mut t = Self::nominators_for(&target);
+			t.push(who.clone());
+			<NominatorsFor<T>>::insert(&target, t);
+
+			// update nominating
+			<Nominating<T>>::insert(&who, &target);
+
+			// Update bondage
+			<Bondage<T>>::insert(&who, T::BlockNumber::max_value());
+
+			Ok(())
+		}
+
+		/// Will panic if called when source isn't currently nominating target.
+		/// Updates Nominating, NominatorsFor and NominationBalance.
+		fn unnominate(origin, target_index: Compact<u32>) -> Result {
+			let source = ensure_signed(origin)?;
+			let target_index: u32 = target_index.into();
+			let target_index = target_index as usize;
+
+			let target = <Nominating<T>>::get(&source).ok_or("Account must be nominating")?;
+
+			let mut t = Self::nominators_for(&target);
+			if t.get(target_index) != Some(&source) {
+				return Err("Invalid target index")
+			}
+
+			// Ok - all valid.
+
+			// update nominators_for
+			t.swap_remove(target_index);
+			<NominatorsFor<T>>::insert(&target, t);
+
+			// update nominating
+			<Nominating<T>>::remove(&source);
+
+			// update bondage
+			<Bondage<T>>::insert(
+				source,
+				<system::Module<T>>::block_number() + Self::bonding_duration()
+			);
+			Ok(())
+		}
+
+		/// Set the given account's preference for slashing behaviour should they be a validator.
+		///
+		/// An error (no-op) if `Self::intentions()[intentions_index] != origin`.
+		fn register_preferences(
+			origin,
+			intentions_index: Compact<u32>,
+			prefs: ValidatorPrefs<T::Balance>
+		) -> Result {
+			let who = ensure_signed(origin)?;
+			let intentions_index: u32 = intentions_index.into();
+
+			if Self::intentions().get(intentions_index as usize) != Some(&who) {
+				return Err("Invalid index")
+			}
+
+			<ValidatorPreferences<T>>::insert(who, prefs);
+
+			Ok(())
+		}
+
+		/// Set the number of sessions in an era.
+		fn set_sessions_per_era(new: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<NextSessionsPerEra<T>>::put(new.into());
+			Ok(())
+		}
+
+		/// The length of the bonding duration in eras.
+		fn set_bonding_duration(new: <T::BlockNumber as HasCompact>::Type) -> Result {
+			<BondingDuration<T>>::put(new.into());
+			Ok(())
+		}
+
+		/// The length of a staking era in sessions.
+		fn set_validator_count(new: Compact<u32>) -> Result {
+			let new: u32 = new.into();
+			<ValidatorCount<T>>::put(new);
+			Ok(())
+		}
+
+		/// Force there to be a new era. This also forces a new session immediately after.
+		/// `apply_rewards` should be true for validators to get the session reward.
+		fn force_new_era(apply_rewards: bool) -> Result {
+			Self::apply_force_new_era(apply_rewards)
+		}
+
+		/// Set the offline slash grace period.
+		fn set_offline_slash_grace(new: Compact<u32>) -> Result {
+			let new: u32 = new.into();
+			<OfflineSlashGrace<T>>::put(new);
+			Ok(())
+		}
 	}
 }
 
@@ -189,10 +312,10 @@ decl_storage! {
 }
 
 impl<T: Trait> Module<T> {
-
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
+	// Just force_new_era without origin check.
+	fn apply_force_new_era(apply_rewards: bool) -> Result {
+		<ForcingNewEra<T>>::put(());
+		<session::Module<T>>::apply_force_new_session(apply_rewards)
 	}
 
 	// PUBLIC IMMUTABLES
@@ -225,147 +348,6 @@ impl<T: Trait> Module<T> {
 		}
 	}
 
-	// PUBLIC DISPATCH
-
-	/// Declare the desire to stake for the transactor.
-	///
-	/// Effects will be felt at the beginning of the next era.
-	fn stake(origin: T::Origin) -> Result {
-		let who = ensure_signed(origin)?;
-		ensure!(Self::nominating(&who).is_none(), "Cannot stake if already nominating.");
-		let mut intentions = <Intentions<T>>::get();
-		// can't be in the list twice.
-		ensure!(intentions.iter().find(|&t| t == &who).is_none(), "Cannot stake if already staked.");
-
-		<Bondage<T>>::insert(&who, T::BlockNumber::max_value());
-		intentions.push(who);
-		<Intentions<T>>::put(intentions);
-		Ok(())
-	}
-
-	/// Retract the desire to stake for the transactor.
-	///
-	/// Effects will be felt at the beginning of the next era.
-	fn unstake(origin: T::Origin, intentions_index: Compact<u32>) -> Result {
-		let who = ensure_signed(origin)?;
-		let intentions_index: u32 = intentions_index.into();
-		// unstake fails in degenerate case of having too few existing staked parties
-		if Self::intentions().len() <= Self::minimum_validator_count() as usize {
-			return Err("cannot unstake when there are too few staked participants")
-		}
-		Self::apply_unstake(&who, intentions_index as usize)
-	}
-
-	fn nominate(origin: T::Origin, target: Address<T::AccountId, T::AccountIndex>) -> Result {
-		let who = ensure_signed(origin)?;
-		let target = <balances::Module<T>>::lookup(target)?;
-
-		ensure!(Self::nominating(&who).is_none(), "Cannot nominate if already nominating.");
-		ensure!(Self::intentions().iter().find(|&t| t == &who).is_none(), "Cannot nominate if already staked.");
-
-		// update nominators_for
-		let mut t = Self::nominators_for(&target);
-		t.push(who.clone());
-		<NominatorsFor<T>>::insert(&target, t);
-
-		// update nominating
-		<Nominating<T>>::insert(&who, &target);
-
-		// Update bondage
-		<Bondage<T>>::insert(&who, T::BlockNumber::max_value());
-
-		Ok(())
-	}
-
-	/// Will panic if called when source isn't currently nominating target.
-	/// Updates Nominating, NominatorsFor and NominationBalance.
-	fn unnominate(origin: T::Origin, target_index: Compact<u32>) -> Result {
-		let source = ensure_signed(origin)?;
-		let target_index: u32 = target_index.into();
-		let target_index = target_index as usize;
-
-		let target = <Nominating<T>>::get(&source).ok_or("Account must be nominating")?;
-
-		let mut t = Self::nominators_for(&target);
-		if t.get(target_index) != Some(&source) {
-			return Err("Invalid target index")
-		}
-
-		// Ok - all valid.
-
-		// update nominators_for
-		t.swap_remove(target_index);
-		<NominatorsFor<T>>::insert(&target, t);
-
-		// update nominating
-		<Nominating<T>>::remove(&source);
-
-		// update bondage
-		<Bondage<T>>::insert(source, <system::Module<T>>::block_number() + Self::bonding_duration());
-		Ok(())
-	}
-
-	/// Set the given account's preference for slashing behaviour should they be a validator.
-	///
-	/// An error (no-op) if `Self::intentions()[intentions_index] != origin`.
-	fn register_preferences(
-		origin: T::Origin,
-		intentions_index: Compact<u32>,
-		prefs: ValidatorPrefs<T::Balance>
-	) -> Result {
-		let who = ensure_signed(origin)?;
-		let intentions_index: u32 = intentions_index.into();
-
-		if Self::intentions().get(intentions_index as usize) != Some(&who) {
-			return Err("Invalid index")
-		}
-
-		<ValidatorPreferences<T>>::insert(who, prefs);
-
-		Ok(())
-	}
-
-	// PRIV DISPATCH
-
-	/// Set the number of sessions in an era.
-	fn set_sessions_per_era(new: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<NextSessionsPerEra<T>>::put(new.into());
-		Ok(())
-	}
-
-	/// The length of the bonding duration in eras.
-	fn set_bonding_duration(new: <T::BlockNumber as HasCompact>::Type) -> Result {
-		<BondingDuration<T>>::put(new.into());
-		Ok(())
-	}
-
-	/// The length of a staking era in sessions.
-	fn set_validator_count(new: Compact<u32>) -> Result {
-		let new: u32 = new.into();
-		<ValidatorCount<T>>::put(new);
-		Ok(())
-	}
-
-	/// Force there to be a new era. This also forces a new session immediately after.
-	/// `apply_rewards` should be true for validators to get the session reward.
-	fn force_new_era(apply_rewards: bool) -> Result {
-		Self::apply_force_new_era(apply_rewards)
-	}
-
-	// Just force_new_era without origin check.
-	fn apply_force_new_era(apply_rewards: bool) -> Result {
-		<ForcingNewEra<T>>::put(());
-		<session::Module<T>>::apply_force_new_session(apply_rewards)
-	}
-
-
-	/// Set the offline slash grace period.
-	fn set_offline_slash_grace(new: Compact<u32>) -> Result {
-		let new: u32 = new.into();
-		<OfflineSlashGrace<T>>::put(new);
-		Ok(())
-	}
-
 	// PUBLIC MUTABLES (DANGEROUS)
 
 	/// Slash a given validator by a specific amount. Removes the slash from their balance by preference,
@@ -525,11 +507,6 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-	}
-}
-
 impl<T: Trait> OnSessionChange<T::Moment> for Module<T> {
 	fn on_session_change(elapsed: T::Moment, should_reward: bool) {
 		Self::new_session(elapsed, should_reward);
diff --git a/substrate/srml/support/src/dispatch.rs b/substrate/srml/support/src/dispatch.rs
index a413f06b0f58694fdbd6e9593ae0f608295c1e68..dd52e35b3cf844673bf68f5b22354325ca69e563 100644
--- a/substrate/srml/support/src/dispatch.rs
+++ b/substrate/srml/support/src/dispatch.rs
@@ -75,7 +75,9 @@ macro_rules! decl_module {
 		decl_module!(@normalize
 			$(#[$attr])*
 			pub struct $mod_type<$trait_instance: $trait_name>
-			for enum $call_type where origin: $origin_type where system = system
+			for enum $call_type where origin: $origin_type, system = system
+			{}
+			{}
 			[]
 			$($t)*
 		);
@@ -83,14 +85,16 @@ macro_rules! decl_module {
 	(
 		$(#[$attr:meta])*
 		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
-		for enum $call_type:ident where origin: $origin_type:ty where system = $system:ident {
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident {
 			$($t:tt)*
 		}
 	) => {
 		decl_module!(@normalize
 			$(#[$attr])*
 			pub struct $mod_type<$trait_instance: $trait_name>
-			for enum $call_type where origin: $origin_type where system = $system
+			for enum $call_type where origin: $origin_type, system = $system
+			{}
+			{}
 			[]
 			$($t)*
 		);
@@ -99,58 +103,135 @@ macro_rules! decl_module {
 	(@normalize
 		$(#[$attr:meta])*
 		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
-		for enum $call_type:ident where origin: $origin_type:ty where system = $system:ident
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+		{}
+		{ $( $on_finalise:tt )* }
+		[ $($t:tt)* ]
+		$(#[doc = $doc_attr:tt])*
+		$vis:vis fn deposit_event() = default;
+		$($rest:tt)*
+	) => {
+		decl_module!(@normalize
+			$(#[$attr])*
+			pub struct $mod_type<$trait_instance: $trait_name>
+			for enum $call_type where origin: $origin_type, system = $system
+			{ $vis fn deposit_event() = default; }
+			{ $( $on_finalise )* }
+			[ $($t)* ]
+			$($rest)*
+		);
+	};
+	(@normalize
+		$(#[$attr:meta])*
+		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+		{}
+		{ $( $on_finalise:tt )* }
 		[ $($t:tt)* ]
 		$(#[doc = $doc_attr:tt])*
-		fn $fn_name:ident(origin $(, $param_name:ident : $param:ty)* ) -> $result:ty ;
+		$vis:vis fn deposit_event($($param_name:ident : $param:ty),* ) { $( $impl:tt )* }
 		$($rest:tt)*
 	) => {
 		decl_module!(@normalize
 			$(#[$attr])*
 			pub struct $mod_type<$trait_instance: $trait_name>
-			for enum $call_type where origin: $origin_type where system = $system
-			[ $($t)* $(#[doc = $doc_attr])* fn $fn_name(origin $( , $param_name : $param )* ) -> $result; ]
+			for enum $call_type where origin: $origin_type, system = $system
+			{ $vis fn deposit_event($( $param_name: $param ),* ) { $( $impl )* } }
+			{ $( $on_finalise )* }
+			[ $($t)* ]
 			$($rest)*
 		);
 	};
 	(@normalize
 		$(#[$attr:meta])*
 		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
-		for enum $call_type:ident where origin: $origin_type:ty where system = $system:ident
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+	    { $( $deposit_event:tt )* }
+		{}
 		[ $($t:tt)* ]
 		$(#[doc = $doc_attr:tt])*
-		fn $fn_name:ident($( $param_name:ident : $param:ty),* ) -> $result:ty ;
+		fn on_finalise($($param_name:ident : $param:ty),* ) { $( $impl:tt )* }
 		$($rest:tt)*
 	) => {
 		decl_module!(@normalize
 			$(#[$attr])*
 			pub struct $mod_type<$trait_instance: $trait_name>
-			for enum $call_type where origin: $origin_type where system = $system
-			[ $($t)* $(#[doc = $doc_attr])* fn $fn_name(root $( , $param_name : $param )* ) -> $result; ]
+			for enum $call_type where origin: $origin_type, system = $system
+			{ $( $deposit_event )* }
+			{ fn on_finalise( $( $param_name : $param ),* ) { $( $impl )* } }
+			[ $($t)* ]
 			$($rest)*
 		);
 	};
 	(@normalize
 		$(#[$attr:meta])*
 		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
-		for enum $call_type:ident where origin: $origin_type:ty where system = $system:ident
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+		{ $( $deposit_event:tt )* }
+		{ $( $on_finalise:tt )* }
+		[ $($t:tt)* ]
+		$(#[doc = $doc_attr:tt])*
+		$fn_vis:vis fn $fn_name:ident($origin:ident $(, $param_name:ident : $param:ty)* ) -> $result:ty { $( $impl:tt )* }
+		$($rest:tt)*
+	) => {
+		decl_module!(@normalize
+			$(#[$attr])*
+			pub struct $mod_type<$trait_instance: $trait_name>
+			for enum $call_type where origin: $origin_type, system = $system
+			{ $( $deposit_event )* }
+			{ $( $on_finalise )* }
+			[
+				$($t)*
+				$(#[doc = $doc_attr])*
+				$fn_vis fn $fn_name($origin $( , $param_name : $param )* ) -> $result { $( $impl )* }
+			]
+			$($rest)*
+		);
+	};
+	(@normalize
+		$(#[$attr:meta])*
+		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+		{ $( $deposit_event:tt )* }
+		{ $( $on_finalise:tt )* }
+		[ $($t:tt)* ]
+		$(#[doc = $doc_attr:tt])*
+		$fn_vis:vis fn $fn_name:ident($( $param_name:ident : $param:ty),* ) -> $result:ty { $( $impl:tt )* }
+		$($rest:tt)*
+	) => {
+		decl_module!(@normalize
+			$(#[$attr])*
+			pub struct $mod_type<$trait_instance: $trait_name>
+			for enum $call_type where origin: $origin_type, system = $system
+			{ $( $deposit_event )* }
+			{ $( $on_finalise )* }
+			[
+				$($t)*
+				$(#[doc = $doc_attr])*
+				$fn_vis fn $fn_name(root $( , $param_name : $param )* ) -> $result { $( $impl )* }
+			]
+			$($rest)*
+		);
+	};
+	(@normalize
+		$(#[$attr:meta])*
+		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
+		{ $( $deposit_event:tt )* }
+		{ $( $on_finalise:tt )* }
 		[ $($t:tt)* ]
 	) => {
 		decl_module!(@imp
 			$(#[$attr])*
 			pub struct $mod_type<$trait_instance: $trait_name>
-			for enum $call_type where origin: $origin_type where system = $system {
+			for enum $call_type where origin: $origin_type, system = $system {
 				$($t)*
 			}
+			{ $( $deposit_event )* }
+			{ $( $on_finalise )* }
 		);
 	};
 
-	(@call
-		origin
-		$mod_type:ident $trait_instance:ident $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ]
-	) => {
-		<$mod_type<$trait_instance>>::$fn_name( $origin $(, $param_name )* )
-	};
 	(@call
 		root
 		$mod_type:ident $trait_instance:ident $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ]
@@ -160,15 +241,113 @@ macro_rules! decl_module {
 			<$mod_type<$trait_instance>>::$fn_name( $( $param_name ),* )
 		}
 	};
+	(@call
+		$ingore:ident
+		$mod_type:ident $trait_instance:ident $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ]
+	) => {
+		<$mod_type<$trait_instance>>::$fn_name( $origin $(, $param_name )* )
+	};
+
+	// no `deposit_event` function wanted
+	(@impl_deposit_event
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		$system:ident;
+	) => {};
+
+	(@impl_deposit_event
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		$system:ident;
+		$vis:vis fn deposit_event() = default;
+	) => {
+		impl<$trait_instance: $trait_name> $module<$trait_instance> {
+			$vis fn deposit_event(event: Event<$trait_instance>) {
+				<$system::Module<$trait_instance>>::deposit_event(
+					<$trait_instance as $trait_name>::Event::from(event).into()
+				);
+			}
+		}
+	};
+
+	(@impl_deposit_event
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		$system:ident;
+		$vis:vis fn deposit_event($param:ident : $param_ty:ty) { $( $impl:tt )* }
+	) => {
+		impl<$trait_instance: $trait_name> $module<$trait_instance> {
+			$vis fn deposit_event($param: $param_ty) {
+				$( $impl )*
+			}
+		}
+	};
+
+	(@impl_on_finalise
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		fn on_finalise() { $( $impl:tt )* }
+	) => {
+		impl<$trait_instance: $trait_name>
+			$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
+			for $module<$trait_instance> {
+			fn on_finalise(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* }
+		}
+	};
+
+	(@impl_on_finalise
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		fn on_finalise($param:ident : $param_ty:ty) { $( $impl:tt )* }
+	) => {
+		impl<$trait_instance: $trait_name>
+			$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
+			for $module<$trait_instance> {
+			fn on_finalise($param: $param_ty) { $( $impl )* }
+		}
+	};
+
+	(@impl_on_finalise
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+	) => {
+		impl<$trait_instance: $trait_name>
+			$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
+			for $module<$trait_instance> {}
+	};
+
+	(@impl_function
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		$origin_ty:ty;
+		root;
+		$vis:vis fn $name:ident ( root $(, $param:ident : $param_ty:ty )* ) -> $result:ty { $( $impl:tt )* }
+	) => {
+		impl<$trait_instance: $trait_name> $module<$trait_instance> {
+			$vis fn $name($( $param: $param_ty ),* ) -> $result {
+				$( $impl )*
+			}
+		}
+	};
+	(@impl_function
+		$module:ident<$trait_instance:ident: $trait_name:ident>;
+		$origin_ty:ty;
+		$ignore:ident;
+		$vis:vis fn $name:ident ( $origin:ident $(, $param:ident : $param_ty:ty )* ) -> $result:ty { $( $impl:tt )* }
+	) => {
+		impl<$trait_instance: $trait_name> $module<$trait_instance> {
+			$vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result {
+				$( $impl )*
+			}
+		}
+	};
 
 	(@imp
 		$(#[$attr:meta])*
 		pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
-		for enum $call_type:ident where origin: $origin_type:ty where system = $system:ident {
-		$(
-			$(#[doc = $doc_attr:tt])*
-			fn $fn_name:ident($from:ident $( , $param_name:ident : $param:ty)*) -> $result:ty;
-		)*}
+		for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident {
+			$(
+				$(#[doc = $doc_attr:tt])*
+				$fn_vis:vis fn $fn_name:ident(
+					$from:ident $( , $param_name:ident : $param:ty)*
+				) -> $result:ty { $( $impl:tt )* }
+			)*
+		}
+		{ $( $deposit_event:tt )* }
+		{ $( $on_finalise:tt )* }
 	) => {
 		// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
 		#[derive(Clone, Copy, PartialEq, Eq)]
@@ -185,6 +364,29 @@ macro_rules! decl_module {
 		#[cfg(not(feature = "std"))]
 		pub struct $mod_type<$trait_instance: $trait_name>(::core::marker::PhantomData<$trait_instance>);
 
+		decl_module! {
+			@impl_on_finalise
+			$mod_type<$trait_instance: $trait_name>;
+			$( $on_finalise )*
+		}
+
+		decl_module! {
+			@impl_deposit_event
+			$mod_type<$trait_instance: $trait_name>;
+			$system;
+			$( $deposit_event )*
+		}
+
+		$(
+			decl_module! {
+				@impl_function
+				$mod_type<$trait_instance: $trait_name>;
+				$origin_type;
+				$from;
+				$fn_vis fn $fn_name ($from $(, $param_name : $param )* ) -> $result { $( $impl )* }
+			}
+		)*
+
 		#[cfg(feature = "std")]
 		$(#[$attr])*
 		#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
@@ -292,7 +494,11 @@ macro_rules! decl_module {
 				match self {
 					$(
 						$call_type::$fn_name( $( $param_name ),* ) => {
-							decl_module!(@call $from $mod_type $trait_instance $fn_name _origin $system [ $( $param_name ),* ])
+							decl_module!(
+								@call
+								$from
+								$mod_type $trait_instance $fn_name _origin $system [ $( $param_name ),* ]
+							)
 						},
 					)*
 					_ => { panic!("__PhantomItem should never be used.") },
@@ -615,6 +821,7 @@ mod tests {
 
 	pub trait Trait {
 		type Origin;
+		type BlockNumber;
 	}
 
 	pub mod system {
@@ -628,11 +835,11 @@ mod tests {
 	decl_module! {
 		pub struct Module<T: Trait> for enum Call where origin: T::Origin {
 			/// Hi, this is a comment.
-			fn aux_0(origin) -> Result;
-			fn aux_1(origin, data: i32) -> Result;
-			fn aux_2(origin, data: i32, data2: String) -> Result;
-			fn aux_3() -> Result;
-			fn aux_4(data: i32) -> Result;
+			fn aux_0(_origin) -> Result { unreachable!() }
+			fn aux_1(_origin, _data: i32) -> Result { unreachable!() }
+			fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() }
+			fn aux_3() -> Result { unreachable!() }
+			fn aux_4(_data: i32) -> Result { unreachable!() }
 		}
 	}
 
@@ -654,7 +861,7 @@ mod tests {
 					name: DecodeDifferent::Encode("aux_1"),
 					arguments: DecodeDifferent::Encode(&[
 						FunctionArgumentMetadata {
-							name: DecodeDifferent::Encode("data"),
+							name: DecodeDifferent::Encode("_data"),
 							ty: DecodeDifferent::Encode("i32"),
 						}
 					]),
@@ -665,11 +872,11 @@ mod tests {
 					name: DecodeDifferent::Encode("aux_2"),
 					arguments: DecodeDifferent::Encode(&[
 						FunctionArgumentMetadata {
-							name: DecodeDifferent::Encode("data"),
+							name: DecodeDifferent::Encode("_data"),
 							ty: DecodeDifferent::Encode("i32"),
 						},
 						FunctionArgumentMetadata {
-							name: DecodeDifferent::Encode("data2"),
+							name: DecodeDifferent::Encode("_data2"),
 							ty: DecodeDifferent::Encode("String"),
 						}
 					]),
@@ -686,7 +893,7 @@ mod tests {
 					name: DecodeDifferent::Encode("aux_4"),
 					arguments: DecodeDifferent::Encode(&[
 						FunctionArgumentMetadata {
-							name: DecodeDifferent::Encode("data"),
+							name: DecodeDifferent::Encode("_data"),
 							ty: DecodeDifferent::Encode("i32"),
 						}
 					]),
@@ -696,32 +903,11 @@ mod tests {
 		},
 	};
 
-	impl<T: Trait> Module<T> {
-		fn aux_0(_: T::Origin) -> Result {
-			unreachable!()
-		}
-
-		fn aux_1(_: T::Origin, _: i32) -> Result {
-			unreachable!()
-		}
-
-		fn aux_2(_: T::Origin, _: i32, _: String) -> Result {
-			unreachable!()
-		}
-
-		fn aux_3() -> Result {
-			unreachable!()
-		}
-
-		fn aux_4(_: i32) -> Result {
-			unreachable!()
-		}
-	}
-
 	struct TraitImpl {}
 
 	impl Trait for TraitImpl {
 		type Origin = u32;
+		type BlockNumber = u32;
 	}
 
 	#[test]
diff --git a/substrate/srml/support/src/event.rs b/substrate/srml/support/src/event.rs
index 8a6c153029fe13bb7307940c4d33eee6fa9414aa..ae7ddea4124eb5bc0ba5ac4c92e183c18e60f32c 100644
--- a/substrate/srml/support/src/event.rs
+++ b/substrate/srml/support/src/event.rs
@@ -433,6 +433,7 @@ mod tests {
 	mod system {
 		pub trait Trait {
 			type Origin;
+			type BlockNumber;
 		}
 
 		decl_module! {
@@ -449,6 +450,7 @@ mod tests {
 	mod system_renamed {
 		pub trait Trait {
 			type Origin;
+			type BlockNumber;
 		}
 
 		decl_module! {
@@ -466,6 +468,7 @@ mod tests {
 		pub trait Trait {
 			type Origin;
 			type Balance;
+			type BlockNumber;
 		}
 
 		decl_module! {
@@ -488,6 +491,7 @@ mod tests {
 		pub trait Trait {
 			type Origin;
 			type Balance;
+			type BlockNumber;
 		}
 
 		decl_module! {
@@ -539,29 +543,35 @@ mod tests {
 	impl event_module::Trait for TestRuntime {
 		type Origin = u32;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl event_module2::Trait for TestRuntime {
 		type Origin = u32;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl system::Trait for TestRuntime {
 		type Origin = u32;
+		type BlockNumber = u32;
 	}
 
 	impl event_module::Trait for TestRuntime2 {
 		type Origin = u32;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl event_module2::Trait for TestRuntime2 {
 		type Origin = u32;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl system_renamed::Trait for TestRuntime2 {
 		type Origin = u32;
+		type BlockNumber = u32;
 	}
 
 	const EXPECTED_METADATA: OuterEventMetadata = OuterEventMetadata {
diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs
index 02747b199ae1a3760b9f9f13bfc4b2819a7010c1..e9cd35afa56781ac2aa44e5750150f70a466df26 100644
--- a/substrate/srml/support/src/lib.rs
+++ b/substrate/srml/support/src/lib.rs
@@ -24,7 +24,8 @@
 #[cfg(feature = "std")]
 extern crate serde;
 
-extern crate sr_std as rstd;
+#[doc(hidden)]
+pub extern crate sr_std as rstd;
 extern crate sr_io as runtime_io;
 #[doc(hidden)]
 pub extern crate sr_primitives as runtime_primitives;
@@ -65,6 +66,7 @@ pub mod inherent;
 pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap};
 pub use self::hashable::Hashable;
 pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType};
+pub use self::metadata::RuntimeMetadata;
 pub use runtime_io::print;
 
 #[macro_export]
diff --git a/substrate/srml/support/src/metadata.rs b/substrate/srml/support/src/metadata.rs
index a3095851a6158ca658a0e0f9d7be6fbbc8d07b1d..c1c4966442fbb7494ab7c5887920ccbba69be0ac 100644
--- a/substrate/srml/support/src/metadata.rs
+++ b/substrate/srml/support/src/metadata.rs
@@ -33,14 +33,12 @@ macro_rules! impl_runtime_metadata {
 		$( $rest:tt )*
 	) => {
 		impl $runtime {
-			pub fn metadata() -> Vec<u8> {
-				$crate::codec::Encode::encode(
-					&$crate::metadata::RuntimeMetadata {
-						outer_event: Self::outer_event_metadata(),
-						modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*),
-						outer_dispatch: Self::outer_dispatch_metadata(),
-					}
-				)
+			pub fn metadata() -> $crate::metadata::RuntimeMetadata {
+				$crate::metadata::RuntimeMetadata {
+					outer_event: Self::outer_event_metadata(),
+					modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*),
+					outer_dispatch: Self::outer_dispatch_metadata(),
+				}
 			}
 		}
 	}
@@ -105,12 +103,13 @@ mod tests {
 		StorageFunctionModifier, StorageFunctionType, FunctionMetadata,
 		StorageMetadata, StorageFunctionMetadata, OuterDispatchMetadata, OuterDispatchCall
 	};
-	use codec::Decode;
+	use codec::{Decode, Encode};
 
 	mod system {
 		pub trait Trait {
 			type Origin: Into<Option<RawOrigin<Self::AccountId>>> + From<RawOrigin<Self::AccountId>>;
 			type AccountId;
+			type BlockNumber;
 		}
 
 		decl_module! {
@@ -148,6 +147,7 @@ mod tests {
 		pub trait Trait {
 			type Origin;
 			type Balance;
+			type BlockNumber;
 		}
 
 		decl_event!(
@@ -160,13 +160,7 @@ mod tests {
 
 		decl_module! {
 			pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-				fn aux_0(origin) -> Result;
-			}
-		}
-
-		impl<T: Trait> Module<T> {
-			fn aux_0(_: T::Origin) -> Result {
-				unreachable!()
+				fn aux_0(_origin) -> Result { unreachable!() }
 			}
 		}
 	}
@@ -175,6 +169,7 @@ mod tests {
 		pub trait Trait {
 			type Origin;
 			type Balance;
+			type BlockNumber;
 		}
 
 		decl_event!(
@@ -226,16 +221,19 @@ mod tests {
 	impl event_module::Trait for TestRuntime {
 		type Origin = Origin;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl event_module2::Trait for TestRuntime {
 		type Origin = Origin;
 		type Balance = u32;
+		type BlockNumber = u32;
 	}
 
 	impl system::Trait for TestRuntime {
 		type Origin = Origin;
 		type AccountId = u32;
+		type BlockNumber = u32;
 	}
 
 	impl_runtime_metadata!(
@@ -346,7 +344,7 @@ mod tests {
 
 	#[test]
 	fn runtime_metadata() {
-		let metadata_encoded = TestRuntime::metadata();
+		let metadata_encoded = TestRuntime::metadata().encode();
 		let metadata_decoded = RuntimeMetadata::decode(&mut &metadata_encoded[..]);
 
 		assert_eq!(EXPECTED_METADATA, metadata_decoded.unwrap());
diff --git a/substrate/srml/support/src/storage/generator.rs b/substrate/srml/support/src/storage/generator.rs
index 8398819ebe5644b2a014d27d36915a10693afa43..4604c5b3b01bacc0cfcd30cd83a1e8bc74a2732c 100644
--- a/substrate/srml/support/src/storage/generator.rs
+++ b/substrate/srml/support/src/storage/generator.rs
@@ -119,7 +119,7 @@ pub trait StorageValue<T: codec::Codec> {
 	}
 
 	/// Mutate this value
-	fn mutate<F: FnOnce(&mut Self::Query), S: Storage>(f: F, storage: &S);
+	fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: Storage>(f: F, storage: &S) -> R;
 
 	/// Clear the storage value.
 	fn kill<S: Storage>(storage: &S) {
@@ -190,7 +190,7 @@ pub trait StorageMap<K: codec::Codec, V: codec::Codec> {
 	}
 
 	/// Mutate the value under a key.
-	fn mutate<F: FnOnce(&mut Self::Query), S: Storage>(key: &K, f: F, storage: &S);
+	fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: Storage>(key: &K, f: F, storage: &S) -> R;
 }
 
 // TODO: Remove this in favour of `decl_storage` macro.
@@ -342,10 +342,10 @@ macro_rules! __storage_items_internal {
 			}
 
 			/// Mutate this value.
-			fn mutate<F: FnOnce(&mut Self::Query), S: $crate::GenericStorage>(f: F, storage: &S) {
+			fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: $crate::GenericStorage>(f: F, storage: &S) -> R {
 				let mut val = <Self as $crate::storage::generator::StorageValue<$ty>>::get(storage);
 
-				f(&mut val);
+				let ret = f(&mut val);
 
 				__handle_wrap_internal!($wraptype {
 					// raw type case
@@ -353,10 +353,12 @@ macro_rules! __storage_items_internal {
 				} {
 					// Option<> type case
 					match val {
-						Some(val) => <Self as $crate::storage::generator::StorageValue<$ty>>::put(&val, storage),
+						Some(ref val) => <Self as $crate::storage::generator::StorageValue<$ty>>::put(&val, storage),
 						None => <Self as $crate::storage::generator::StorageValue<$ty>>::kill(storage),
 					}
 				});
+
+				ret
 			}
 		}
 	};
@@ -379,7 +381,7 @@ macro_rules! __storage_items_internal {
 			}
 
 			/// Get the storage key used to fetch a value corresponding to a specific key.
-			fn key_for(x: &$kty) -> Vec<u8> {
+			fn key_for(x: &$kty) -> $crate::rstd::vec::Vec<u8> {
 				let mut key = $prefix.to_vec();
 				$crate::codec::Encode::encode_to(x, &mut key);
 				key
@@ -398,10 +400,10 @@ macro_rules! __storage_items_internal {
 			}
 
 			/// Mutate the value under a key.
-			fn mutate<F: FnOnce(&mut Self::Query), S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) {
+			fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R {
 				let mut val = <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::take(key, storage);
 
-				f(&mut val);
+				let ret = f(&mut val);
 
 				__handle_wrap_internal!($wraptype {
 					// raw type case
@@ -409,10 +411,12 @@ macro_rules! __storage_items_internal {
 				} {
 					// Option<> type case
 					match val {
-						Some(val) => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::insert(key, &val, storage),
+						Some(ref val) => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::insert(key, &val, storage),
 						None => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::remove(key, storage),
 					}
 				});
+
+				ret
 			}
 		}
 	};
@@ -441,21 +445,21 @@ macro_rules! __storage_items_internal {
 
 			/// Get the key used to put the length field.
 			// TODO: concat macro should accept byte literals.
-			fn len_key() -> Vec<u8> {
+			fn len_key() -> $crate::rstd::vec::Vec<u8> {
 				let mut key = $prefix.to_vec();
 				key.extend(b"len");
 				key
 			}
 
 			/// Get the storage key used to fetch a value at a given index.
-			fn key_for(index: u32) -> Vec<u8> {
+			fn key_for(index: u32) -> $crate::rstd::vec::Vec<u8> {
 				let mut key = $prefix.to_vec();
 				$crate::codec::Encode::encode_to(&index, &mut key);
 				key
 			}
 
 			/// Read out all the items.
-			fn items<S: $crate::GenericStorage>(storage: &S) -> Vec<$ty> {
+			fn items<S: $crate::GenericStorage>(storage: &S) -> $crate::rstd::vec::Vec<$ty> {
 				(0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage))
 					.map(|i| <$name as $crate::storage::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed"))
 					.collect()
@@ -677,7 +681,7 @@ macro_rules! __generate_genesis_config {
 #[macro_export]
 macro_rules! decl_storage {
 	(
-		trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
+		$pub:vis trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
 			$($t:tt)*
 		}
 		add_extra_genesis {
@@ -686,7 +690,7 @@ macro_rules! decl_storage {
 		}
 	) => {
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-		trait $storetype {
+		$pub trait $storetype {
 			__decl_store_items!($($t)*);
 		}
 		impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> {
@@ -699,33 +703,12 @@ macro_rules! decl_storage {
 		__decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [$( $(#[$attr])* $extrafield : $extraty $(= $default)* ; )* ] [$call] $($t)*);
 	};
 	(
-		pub trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
+		$pub:vis trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
 			$($t:tt)*
 		}
-		add_extra_genesis {
-			$( $(#[$attr:meta])* config($extrafield:ident) : $extraty:ty $(= $default:expr)* ;)*
-			build($call:expr);
-		}
 	) => {
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-		pub trait $storetype {
-			__decl_store_items!($($t)*);
-		}
-		impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> {
-			__impl_store_items!($traitinstance $($t)*);
-		}
-		impl<$traitinstance: $traittype> $modulename<$traitinstance> {
-			__impl_store_fns!($traitinstance $($t)*);
-		}
-		__decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [$( $(#[$attr])* $extrafield : $extraty $(= $default)* ; )* ] [$call] $($t)*);
-	};
-	(
-		trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
-			$($t:tt)*
-		}
-	) => {
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-		trait $storetype {
+		$pub trait $storetype {
 			__decl_store_items!($($t)*);
 		}
 		impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> {
@@ -737,26 +720,8 @@ macro_rules! decl_storage {
 		}
 		__decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [] [|_, _|{}] $($t)*);
 	};
-	(
-		pub trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident {
-			$($t:tt)*
-		}
-	) => {
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-		pub trait $storetype {
-			__decl_store_items!($($t)*);
-		}
-		impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> {
-			__impl_store_items!($traitinstance $($t)*);
-		}
-		impl<$traitinstance: $traittype> $modulename<$traitinstance> {
-			__impl_store_fns!($traitinstance $($t)*);
-		}
-		__decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [] [|_, _|{}] $($t)*);
-	}
 }
 
-// TODO: when 'vis' is stablized, we could save the lines by half.
 #[macro_export]
 #[doc(hidden)]
 macro_rules! __decl_genesis_config_items {
@@ -765,25 +730,13 @@ macro_rules! __decl_genesis_config_items {
 	//  - $default
 	// we don't allow any config() or build() on this pattern.
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*);
@@ -793,23 +746,8 @@ macro_rules! __decl_genesis_config_items {
 	//  - pub
 	//  - build()
 	//  - $default
-	// so there are 8 cases here.
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : map $kty:ty => $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : map $kty:ty => $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : map $kty:ty => $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -823,36 +761,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)* $name ($build);]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)* $name ($build);]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : map $kty:ty => $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : map $kty:ty => $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -866,35 +775,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : map $kty:ty => $ty:ty = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)* $name ($build);]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -907,395 +788,32 @@ macro_rules! __decl_genesis_config_items {
 			$($t)*
 		);
 	};
-
-	// simple values without getters:
-	//  - pub
-	//  - $default
-	// so there are 4 cases here.
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident : $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident : $ty:ty = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident : $ty:ty;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident : $ty:ty = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-
-	// simple values with getters:
-	//  - pub
-	//  - (empty) / config() / config(myname)
-	//  - build()
-	//  - $default
-	// so there are 24 cases here.
-	// Option<> types
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = Default::default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = Default::default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	// build
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = Default::default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = Default::default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-
-	// pub
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)*]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = Default::default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = Default::default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	// build
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty>;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)*]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty>;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = Default::default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
-			[$($extras)*]
-			[$call]
-			$($t)*
-		);
-	};
-	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty> = $default:expr;
-		$($t:tt)*
-	) => {
-		__decl_genesis_config_items!(
-			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name ($build);]
-			[$($mapcur)*]
+		__decl_genesis_config_items!(
+			[$traittype $traitinstance]
+			[$($cur)*]
+			[$($nb)*]
+			[$($mapcur)* $name ($build);]
 			[$($extras)*]
 			[$call]
 			$($t)*
 		);
 	};
+
+	// simple values without getters:
+	//  - pub
+	//  - $default
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty>;
+		$(#[$doc:meta])* $pub:vis $name:ident : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = Default::default();]
-			[$($nb)* $name ($build);]
+			[$($cur)*]
+			[$($nb)*]
 			[$($mapcur)*]
 			[$($extras)*]
 			[$call]
@@ -1303,13 +821,13 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
-			[$($nb)* $name ($build);]
+			[$($cur)*]
+			[$($nb)*]
 			[$($mapcur)*]
 			[$($extras)*]
 			[$call]
@@ -1317,10 +835,14 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 
-
-	// raw types
+	// simple values with getters:
+	//  - pub
+	//  - (empty) / config() / config(myname)
+	//  - build()
+	//  - $default
+	// Option<> types
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1334,7 +856,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1348,7 +870,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1362,12 +884,12 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default;]
+			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
 			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());]
 			[$($mapcur)*]
 			[$($extras)*]
@@ -1376,7 +898,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1390,12 +912,12 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default;]
+			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
 			[$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ]
 			[$($mapcur)*]
 			[$($extras)*]
@@ -1405,7 +927,7 @@ macro_rules! __decl_genesis_config_items {
 	};
 	// build
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1419,7 +941,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1433,7 +955,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1447,12 +969,12 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $getfn : $ty = $default;]
+			[$($cur)* $getfn : $ty = $default.unwrap_or_default();]
 			[$($nb)* $name ($build);]
 			[$($mapcur)*]
 			[$($extras)*]
@@ -1461,7 +983,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty>;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1475,12 +997,12 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty> = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
 			[$traittype $traitinstance]
-			[$($cur)* $myname : $ty = $default;]
+			[$($cur)* $myname : $ty = $default.unwrap_or_default();]
 			[$($nb)* $name ($build);]
 			[$($mapcur)*]
 			[$($extras)*]
@@ -1489,9 +1011,9 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 
-	// pub
+	// raw types
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1505,7 +1027,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1519,7 +1041,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1533,7 +1055,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1547,7 +1069,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1561,7 +1083,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1576,7 +1098,7 @@ macro_rules! __decl_genesis_config_items {
 	};
 	// build
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1590,7 +1112,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1604,7 +1126,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1618,7 +1140,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1632,7 +1154,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1646,7 +1168,7 @@ macro_rules! __decl_genesis_config_items {
 		);
 	};
 	([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]
-		$(#[$doc:meta])* pub $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty = $default:expr;
+		$(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty = $default:expr;
 		$($t:tt)*
 	) => {
 		__decl_genesis_config_items!(
@@ -1676,42 +1198,24 @@ macro_rules! __decl_storage_items {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
 	// maps with getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
@@ -1719,42 +1223,24 @@ macro_rules! __decl_storage_items {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
@@ -1762,21 +1248,12 @@ macro_rules! __decl_storage_items {
 	// simple values without getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : Option<$ty:ty>; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
@@ -1785,42 +1262,24 @@ macro_rules! __decl_storage_items {
 	//  - config()
 	//  - build()
 	//  - $default
-	// config() and build() can be combined, so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty>; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty>; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
 	// simple values without getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
@@ -1829,21 +1288,12 @@ macro_rules! __decl_storage_items {
 	//  - config()
 	//  - build()
 	//  - $default
-	// config() and build() can be combined, so there are 4 cases here.
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!(() ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default());
-		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
-	};
-	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_storage_item!((pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
+	($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
+		__decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default);
 		__decl_storage_items!($cratename $traittype $traitinstance $($t)*);
 	};
 
@@ -1855,8 +1305,8 @@ macro_rules! __decl_storage_items {
 #[doc(hidden)]
 macro_rules! __decl_storage_item {
 	// generator for maps.
-	(($($vis:tt)*) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : map $kty:ty => $ty:ty = $default:expr) => {
-		$($vis)* struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>);
+	(($pub:vis) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : map $kty:ty => $ty:ty = $default:expr) => {
+		$pub struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>);
 
 		impl<$traitinstance: $traittype> $crate::storage::generator::StorageMap<$kty, $ty> for $name<$traitinstance> {
 			type Query = $gettype;
@@ -1867,7 +1317,7 @@ macro_rules! __decl_storage_item {
 			}
 
 			/// Get the storage key used to fetch a value corresponding to a specific key.
-			fn key_for(x: &$kty) -> Vec<u8> {
+			fn key_for(x: &$kty) -> $crate::rstd::vec::Vec<u8> {
 				let mut key = <$name<$traitinstance> as $crate::storage::generator::StorageMap<$kty, $ty>>::prefix().to_vec();
 				$crate::codec::Encode::encode_to(x, &mut key);
 				key
@@ -1900,10 +1350,10 @@ macro_rules! __decl_storage_item {
 			}
 
 			/// Mutate the value under a key
-			fn mutate<F: FnOnce(&mut Self::Query), S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) {
+			fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R {
 				let mut val = <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::take(key, storage);
 
-				f(&mut val);
+				let ret = f(&mut val);
 
 				__handle_wrap_internal!($wraptype {
 					// raw type case
@@ -1911,16 +1361,18 @@ macro_rules! __decl_storage_item {
 				} {
 					// Option<> type case
 					match val {
-						Some(val) => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::insert(key, &val, storage),
+						Some(ref val) => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::insert(key, &val, storage),
 						None => <Self as $crate::storage::generator::StorageMap<$kty, $ty>>::remove(key, storage),
 					}
 				});
+
+				ret
 			}
 		}
 	};
 	// generator for values.
-	(($($vis:tt)*) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : $ty:ty = $default:expr) => {
-		$($vis)* struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>);
+	(($pub:vis) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : $ty:ty = $default:expr) => {
+		$pub struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>);
 
 		impl<$traitinstance: $traittype> $crate::storage::generator::StorageValue<$ty> for $name<$traitinstance> {
 			type Query = $gettype;
@@ -1959,10 +1411,10 @@ macro_rules! __decl_storage_item {
 			}
 
 			/// Mutate the value under a key.
-			fn mutate<F: FnOnce(&mut Self::Query), S: $crate::GenericStorage>(f: F, storage: &S) {
+			fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: $crate::GenericStorage>(f: F, storage: &S) -> R {
 				let mut val = <Self as $crate::storage::generator::StorageValue<$ty>>::get(storage);
 
-				f(&mut val);
+				let ret = f(&mut val);
 
 				__handle_wrap_internal!($wraptype {
 					// raw type case
@@ -1970,10 +1422,12 @@ macro_rules! __decl_storage_item {
 				} {
 					// Option<> type case
 					match val {
-						Some(val) => <Self as $crate::storage::generator::StorageValue<$ty>>::put(&val, storage),
+						Some(ref val) => <Self as $crate::storage::generator::StorageValue<$ty>>::put(&val, storage),
 						None => <Self as $crate::storage::generator::StorageValue<$ty>>::kill(storage),
 					}
 				});
+
+				ret
 			}
 		}
 	};
@@ -1985,68 +1439,40 @@ macro_rules! __decl_store_items {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
-	($(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
 
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
-	($(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
 
 	// simple values without getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($(#[$doc:meta])* $name:ident : $ty:ty; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident : $ty:ty; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
-	($(#[$doc:meta])* pub $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
 
 	// simple values with getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
-	($(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
-		__decl_store_item!($name); __decl_store_items!($($t)*);
-	};
-	($(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
+	($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
 		__decl_store_item!($name); __decl_store_items!($($t)*);
 	};
 
@@ -2067,20 +1493,11 @@ macro_rules! __impl_store_fns {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
@@ -2089,37 +1506,21 @@ macro_rules! __impl_store_fns {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_fns!($traitinstance $($t)*);
 	};
 
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
@@ -2128,20 +1529,11 @@ macro_rules! __impl_store_fns {
 	// simple values with getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty>; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty>; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty>; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
@@ -2150,37 +1542,21 @@ macro_rules! __impl_store_fns {
 	// simple values without getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty; $($t:tt)*) => {
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => {
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty; $($t:tt)*) => {
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_fns!($traitinstance $($t)*);
 	};
 
 	// simple values with getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn ($ty) $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_fn!($traitinstance $name $getfn ($ty) $ty);
-		__impl_store_fns!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn ($ty) $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_fn!($traitinstance $name $getfn ($ty) $ty);
 		__impl_store_fns!($traitinstance $($t)*);
 	};
@@ -2210,20 +1586,11 @@ macro_rules! __impl_store_items {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
@@ -2231,20 +1598,11 @@ macro_rules! __impl_store_items {
 	// maps:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
@@ -2252,20 +1610,11 @@ macro_rules! __impl_store_items {
 	// simple values without getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
@@ -2273,20 +1622,11 @@ macro_rules! __impl_store_items {
 	// simple values with getters:
 	//  - pub
 	//  - $default
-	// so there are 4 cases here.
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
-		__impl_store_item!($name $traitinstance);
-		__impl_store_items!($traitinstance $($t)*);
-	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
-	($traitinstance:ident $(#[$doc:meta])* pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
+	($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => {
 		__impl_store_item!($name $traitinstance);
 		__impl_store_items!($traitinstance $($t)*);
 	};
@@ -2325,23 +1665,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident :
-			map $kty:ty => Option<$ty:ty> $(= $default:expr)*;
-		$( $t:tt )*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty);
-				$crate::storage::generator::StorageFunctionModifier::Optional
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident :
+		$pub:vis $name:ident :
 			map $kty:ty => Option<$ty:ty> $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2359,23 +1683,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident :
-			map $kty:ty => $ty:ty $(= $default:expr)*;
-		$( $t:tt )*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty);
-				$crate::storage::generator::StorageFunctionModifier::Default
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident :
+		$pub:vis $name:ident :
 			map $kty:ty => $ty:ty $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2394,23 +1702,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident get($getfn:ident) $(build($build:expr))* :
-			map $kty:ty => Option<$ty:ty> $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty);
-				$crate::storage::generator::StorageFunctionModifier::Optional
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident get($getfn:ident) $(build($build:expr))* :
+		$pub:vis $name:ident get($getfn:ident) $(build($build:expr))* :
 			map $kty:ty => Option<$ty:ty> $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2429,23 +1721,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident get($getfn:ident) $(build($build:expr))* :
-			map $kty:ty => $ty:ty $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty);
-				$crate::storage::generator::StorageFunctionModifier::Default
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident get($getfn:ident) $(build($build:expr))* :
+		$pub:vis $name:ident get($getfn:ident) $(build($build:expr))* :
 			map $kty:ty => $ty:ty $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2463,22 +1739,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident : Option<$ty:ty> $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($ty);
-				$crate::storage::generator::StorageFunctionModifier::Optional
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident : Option<$ty:ty> $(= $default:expr)*;
+		$pub:vis $name:ident : Option<$ty:ty> $(= $default:expr)*;
 		$($t:tt)*
 	) => {
 		__store_functions_to_metadata!(
@@ -2494,22 +1755,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident : $ty:ty $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($ty);
-				$crate::storage::generator::StorageFunctionModifier::Default
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident : $ty:ty $(= $default:expr)*;
+		$pub:vis $name:ident : $ty:ty $(= $default:expr)*;
 		$($t:tt)*
 	) => {
 		__store_functions_to_metadata!(
@@ -2527,23 +1773,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
-			Option<$ty:ty> $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($ty);
-				$crate::storage::generator::StorageFunctionModifier::Optional
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
+		$pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
 			Option<$ty:ty> $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2561,23 +1791,7 @@ macro_rules! __store_functions_to_metadata {
 	(
 		$( $metadata:expr ),*;
 		$(#[doc = $doc_attr:tt])*
-		$name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
-			$ty:ty $(= $default:expr)*;
-		$($t:tt)*
-	) => {
-		__store_functions_to_metadata!(
-			$( $metadata, )*
-			__store_function_to_metadata!(
-				$( $doc_attr ),*; $name; __store_type_to_metadata!($ty);
-				$crate::storage::generator::StorageFunctionModifier::Default
-			);
-			$( $t )*
-		)
-	};
-	(
-		$( $metadata:expr ),*;
-		$(#[doc = $doc_attr:tt])*
-		pub $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
+		$pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* :
 			$ty:ty $(= $default:expr)*;
 		$($t:tt)*
 	) => {
@@ -2702,7 +1916,8 @@ mod tests {
 	}
 
 	pub trait Trait {
-		 type Origin: codec::Encode + codec::Decode + ::std::default::Default;
+		type Origin: codec::Encode + codec::Decode + ::std::default::Default;
+		type BlockNumber;
 	}
 
 	decl_module! {
@@ -2754,6 +1969,7 @@ mod tests {
 
 	impl Trait for TraitImpl {
 		type Origin = u32;
+		type BlockNumber = u32;
 	}
 
 	const EXPECTED_METADATA: StorageMetadata = StorageMetadata {
@@ -2932,7 +2148,8 @@ mod tests {
 #[allow(dead_code)]
 mod test2 {
 	pub trait Trait {
-		 type Origin;
+		type Origin;
+		type BlockNumber;
 	}
 
 	decl_module! {
@@ -2959,5 +2176,6 @@ mod test2 {
 
 	impl Trait for TraitImpl {
 		type Origin = u32;
+		type BlockNumber = u32;
 	}
 }
diff --git a/substrate/srml/support/src/storage/mod.rs b/substrate/srml/support/src/storage/mod.rs
index 637ecc688abc05399571f8c0564b16d069450ce3..6e1302718abd1bf574f107c4f8b755f159a33186 100644
--- a/substrate/srml/support/src/storage/mod.rs
+++ b/substrate/srml/support/src/storage/mod.rs
@@ -169,7 +169,7 @@ pub trait StorageValue<T: Codec> {
 	fn put<Arg: Borrow<T>>(val: Arg);
 
 	/// Mutate the value
-	fn mutate<F: FnOnce(&mut Self::Query)>(f: F);
+	fn mutate<R, F: FnOnce(&mut Self::Query) -> R>(f: F) -> R;
 
 	/// Clear the storage value.
 	fn kill();
@@ -193,7 +193,7 @@ impl<T: Codec, U> StorageValue<T> for U where U: generator::StorageValue<T> {
 	fn put<Arg: Borrow<T>>(val: Arg) {
 		U::put(val.borrow(), &RuntimeStorage)
 	}
-	fn mutate<F: FnOnce(&mut Self::Query)>(f: F) {
+	fn mutate<R, F: FnOnce(&mut Self::Query) -> R>(f: F) -> R {
 		U::mutate(f, &RuntimeStorage)
 	}
 	fn kill() {
@@ -296,7 +296,7 @@ pub trait StorageMap<K: Codec, V: Codec> {
 	fn remove<KeyArg: Borrow<K>>(key: KeyArg);
 
 	/// Mutate the value under a key.
-	fn mutate<KeyArg: Borrow<K>, F: FnOnce(&mut Self::Query)>(key: KeyArg, f: F);
+	fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R;
 
 	/// Take the value under a key.
 	fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
@@ -329,7 +329,7 @@ impl<K: Codec, V: Codec, U> StorageMap<K, V> for U where U: generator::StorageMa
 		U::remove(key.borrow(), &RuntimeStorage)
 	}
 
-	fn mutate<KeyArg: Borrow<K>, F: FnOnce(&mut Self::Query)>(key: KeyArg, f: F) {
+	fn mutate<KeyArg: Borrow<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
 		U::mutate(key.borrow(), f, &RuntimeStorage)
 	}
 
diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs
index ad8957c3491d947f211cc8de41bda21bd7cb14eb..c34f11bf8dbd78835753a4e6a30711829637b2fa 100644
--- a/substrate/srml/system/src/lib.rs
+++ b/substrate/srml/system/src/lib.rs
@@ -86,7 +86,16 @@ pub trait Trait: Eq + Clone {
 pub type DigestItemOf<T> = <<T as Trait>::Digest as traits::Digest>::Item;
 
 decl_module! {
-	pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
+	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		/// Deposits an event onto this block's event record.
+		pub fn deposit_event(event: T::Event) {
+			let extrinsic_index = Self::extrinsic_index();
+			let phase = extrinsic_index.map_or(Phase::Finalization, |c| Phase::ApplyExtrinsic(c));
+			let mut events = Self::events();
+			events.push(EventRecord { phase, event });
+			<Events<T>>::put(events);
+		}
+	}
 }
 
 /// A phase of a block's execution.
@@ -301,15 +310,6 @@ impl<T: Trait> Module<T> {
 		<Digest<T>>::put(l);
 	}
 
-	/// Deposits an event onto this block's event record.
-	pub fn deposit_event(event: T::Event) {
-		let extrinsic_index = Self::extrinsic_index();
-		let phase = extrinsic_index.map_or(Phase::Finalization, |c| Phase::ApplyExtrinsic(c));
-		let mut events = Self::events();
-		events.push(EventRecord { phase, event });
-		<Events<T>>::put(events);
-	}
-
 	/// Calculate the current block's random seed.
 	fn calculate_random() -> T::Hash {
 		assert!(Self::block_number() > Zero::zero(), "Block number may never be zero");
diff --git a/substrate/srml/timestamp/src/lib.rs b/substrate/srml/timestamp/src/lib.rs
index c13972c7da808c3c10e7e2b4639db55f502a0856..1779807af137becd16fbbc0cd54010e30c2cebdc 100644
--- a/substrate/srml/timestamp/src/lib.rs
+++ b/substrate/srml/timestamp/src/lib.rs
@@ -59,7 +59,7 @@ use runtime_support::{StorageValue, Parameter};
 use runtime_support::dispatch::Result;
 use runtime_primitives::RuntimeString;
 use runtime_primitives::traits::{
-	As, OnFinalise, SimpleArithmetic, Zero, ProvideInherent, Block as BlockT, Extrinsic
+	As, SimpleArithmetic, Zero, ProvideInherent, Block as BlockT, Extrinsic
 };
 use system::ensure_inherent;
 use rstd::{result, ops::{Mul, Div}, vec::Vec};
@@ -74,7 +74,36 @@ pub trait Trait: consensus::Trait + system::Trait {
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn set(origin, now: <T::Moment as HasCompact>::Type) -> Result;
+		/// Set the current time.
+		///
+		/// Extrinsic with this call should be placed at the specific position in the each block
+		/// (specified by the Trait::TIMESTAMP_SET_POSITION) typically at the start of the each block.
+		/// This call should be invoked exactly once per block. It will panic at the finalization phase,
+		/// if this call hasn't been invoked by that time.
+		///
+		/// The timestamp should be greater than the previous one by the amount specified by `block_period`.
+		fn set(origin, now: <T::Moment as HasCompact>::Type) -> Result {
+			ensure_inherent(origin)?;
+			let now = now.into();
+
+			assert!(!<Self as Store>::DidUpdate::exists(), "Timestamp must be updated only once in the block");
+			assert!(
+				<system::Module<T>>::extrinsic_index() == Some(T::TIMESTAMP_SET_POSITION),
+				"Timestamp extrinsic must be at position {} in the block",
+				T::TIMESTAMP_SET_POSITION
+			);
+			assert!(
+				Self::now().is_zero() || now >= Self::now() + Self::block_period(),
+				"Timestamp must increment by at least <BlockPeriod> between sequential blocks"
+			);
+			<Self as Store>::Now::put(now);
+			<Self as Store>::DidUpdate::put(true);
+			Ok(())
+		}
+
+		fn on_finalise() {
+			assert!(<Self as Store>::DidUpdate::take(), "Timestamp must be updated once in the block");
+		}
 	}
 }
 
@@ -100,33 +129,6 @@ impl<T: Trait> Module<T> {
 		Self::now()
 	}
 
-	/// Set the current time.
-	///
-	/// Extrinsic with this call should be placed at the specific position in the each block
-	/// (specified by the Trait::TIMESTAMP_SET_POSITION) typically at the start of the each block.
-	/// This call should be invoked exactly once per block. It will panic at the finalization phase,
-	/// if this call hasn't been invoked by that time.
-	///
-	/// The timestamp should be greater than the previous one by the amount specified by `block_period`.
-	fn set(origin: T::Origin, now: <T::Moment as HasCompact>::Type) -> Result {
-		ensure_inherent(origin)?;
-		let now = now.into();
-
-		assert!(!<Self as Store>::DidUpdate::exists(), "Timestamp must be updated only once in the block");
-		assert!(
-			<system::Module<T>>::extrinsic_index() == Some(T::TIMESTAMP_SET_POSITION),
-			"Timestamp extrinsic must be at position {} in the block",
-			T::TIMESTAMP_SET_POSITION
-		);
-		assert!(
-			Self::now().is_zero() || now >= Self::now() + Self::block_period(),
-			"Timestamp must increment by at least <BlockPeriod> between sequential blocks"
-		);
-		<Self as Store>::Now::put(now);
-		<Self as Store>::DidUpdate::put(true);
-		Ok(())
-	}
-
 	/// Set the timestamp to something in particular. Only used for tests.
 	#[cfg(feature = "std")]
 	pub fn set_timestamp(now: T::Moment) {
@@ -171,12 +173,6 @@ impl<T: Trait> ProvideInherent for Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(_n: T::BlockNumber) {
-		assert!(<Self as Store>::DidUpdate::take(), "Timestamp must be updated once in the block");
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/substrate/srml/treasury/src/lib.rs b/substrate/srml/treasury/src/lib.rs
index febe5fed891d5c6ecea25c85b4bf02c8fb4953ca..7d314674bc3925c743c9f13f37164e138ae0f3f5 100644
--- a/substrate/srml/treasury/src/lib.rs
+++ b/substrate/srml/treasury/src/lib.rs
@@ -45,7 +45,7 @@ extern crate srml_balances as balances;
 use rstd::prelude::*;
 use runtime_support::{StorageValue, StorageMap};
 use runtime_support::dispatch::Result;
-use runtime_primitives::{Permill, traits::{OnFinalise, Zero, EnsureOrigin}};
+use runtime_primitives::{Permill, traits::{Zero, EnsureOrigin}};
 use codec::{HasCompact, Compact};
 use balances::{OnDilution, address::Address};
 use system::ensure_signed;
@@ -73,23 +73,87 @@ type ProposalIndex = u32;
 decl_module! {
 	// Simple declaration of the `Module` type. Lets the macro know what its working on.
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		// Put forward a suggestion for spending. A deposit proportional to the value
-		// is reserved and slashed if the proposal is rejected. It is returned once the
-		// proposal is awarded.
-		fn propose_spend(origin, value: <T::Balance as HasCompact>::Type, beneficiary: Address<T::AccountId, T::AccountIndex>) -> Result;
+		fn deposit_event() = default;
+		/// Put forward a suggestion for spending. A deposit proportional to the value
+		/// is reserved and slashed if the proposal is rejected. It is returned once the
+		/// proposal is awarded.
+		fn propose_spend(
+			origin,
+			value: <T::Balance as HasCompact>::Type,
+			beneficiary: Address<T::AccountId, T::AccountIndex>
+		) -> Result {
+			let proposer = ensure_signed(origin)?;
+			let beneficiary = <balances::Module<T>>::lookup(beneficiary)?;
+			let value = value.into();
+
+			let bond = Self::calculate_bond(value);
+			<balances::Module<T>>::reserve(&proposer, bond)
+				.map_err(|_| "Proposer's balance too low")?;
+
+			let c = Self::proposal_count();
+			<ProposalCount<T>>::put(c + 1);
+			<Proposals<T>>::insert(c, Proposal { proposer, value, beneficiary, bond });
+
+			Self::deposit_event(RawEvent::Proposed(c));
+
+			Ok(())
+		}
+
+		/// Set the balance of funds available to spend.
+		fn set_pot(new_pot: <T::Balance as HasCompact>::Type) -> Result {
+			// Put the new value into storage.
+			<Pot<T>>::put(new_pot.into());
+
+			// All good.
+			Ok(())
+		}
+
+		/// (Re-)configure this module.
+		fn configure(
+			proposal_bond: Permill,
+			proposal_bond_minimum: <T::Balance as HasCompact>::Type,
+			spend_period: <T::BlockNumber as HasCompact>::Type,
+			burn: Permill
+		) -> Result {
+			<ProposalBond<T>>::put(proposal_bond);
+			<ProposalBondMinimum<T>>::put(proposal_bond_minimum.into());
+			<SpendPeriod<T>>::put(spend_period.into());
+			<Burn<T>>::put(burn);
+			Ok(())
+		}
+
+		/// Reject a proposed spend. The original deposit will be slashed.
+		fn reject_proposal(origin, proposal_id: Compact<ProposalIndex>) -> Result {
+			T::RejectOrigin::ensure_origin(origin)?;
+			let proposal_id: ProposalIndex = proposal_id.into();
+
+			let proposal = <Proposals<T>>::take(proposal_id).ok_or("No proposal at that index")?;
+
+			let value = proposal.bond;
+			let _ = <balances::Module<T>>::slash_reserved(&proposal.proposer, value);
+
+			Ok(())
+		}
 
-		// Set the balance of funds available to spend.
-		fn set_pot(new_pot: <T::Balance as HasCompact>::Type) -> Result;
+		/// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary
+		/// and the original deposit will be returned.
+		fn approve_proposal(origin, proposal_id: Compact<ProposalIndex>) -> Result {
+			T::ApproveOrigin::ensure_origin(origin)?;
+			let proposal_id = proposal_id.into();
 
-		// (Re-)configure this module.
-		fn configure(proposal_bond: Permill, proposal_bond_minimum: <T::Balance as HasCompact>::Type, spend_period: <T::BlockNumber as HasCompact>::Type, burn: Permill) -> Result;
+			ensure!(<Proposals<T>>::exists(proposal_id), "No proposal at that index");
 
-		// Reject a proposed spend. The original deposit will be slashed.
-		fn reject_proposal(origin, proposal_id: Compact<ProposalIndex>) -> Result;
+			<Approvals<T>>::mutate(|v| v.push(proposal_id));
 
-		// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary
-		// and the original deposit will be returned.
-		fn approve_proposal(origin, proposal_id: Compact<ProposalIndex>) -> Result;
+			Ok(())
+		}
+
+		fn on_finalise(n: T::BlockNumber) {
+			// Check to see if we should spend some funds!
+			if (n % Self::spend_period()).is_zero() {
+				Self::spend_funds();
+			}
+		}
 	}
 }
 
@@ -153,74 +217,7 @@ decl_event!(
 );
 
 impl<T: Trait> Module<T> {
-	/// Deposit one of this module's events.
-	fn deposit_event(event: Event<T>) {
-		<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
-	}
-
-	// Implement Calls and add public immutables and private mutables.
-
-	fn propose_spend(origin: T::Origin, value: <T::Balance as HasCompact>::Type, beneficiary: Address<T::AccountId, T::AccountIndex>) -> Result {
-		let proposer = ensure_signed(origin)?;
-		let beneficiary = <balances::Module<T>>::lookup(beneficiary)?;
-		let value = value.into();
-
-		let bond = Self::calculate_bond(value);
-		<balances::Module<T>>::reserve(&proposer, bond)
-			.map_err(|_| "Proposer's balance too low")?;
-
-		let c = Self::proposal_count();
-		<ProposalCount<T>>::put(c + 1);
-		<Proposals<T>>::insert(c, Proposal { proposer, value, beneficiary, bond });
-
-		Self::deposit_event(RawEvent::Proposed(c));
-
-		Ok(())
-	}
-
-	fn reject_proposal(origin: T::Origin, proposal_id: Compact<ProposalIndex>) -> Result {
-		T::RejectOrigin::ensure_origin(origin)?;
-		let proposal_id: ProposalIndex = proposal_id.into();
-
-		let proposal = <Proposals<T>>::take(proposal_id).ok_or("No proposal at that index")?;
-
-		let value = proposal.bond;
-		let _ = <balances::Module<T>>::slash_reserved(&proposal.proposer, value);
-
-		Ok(())
-	}
-
-	fn approve_proposal(origin: T::Origin, proposal_id: Compact<ProposalIndex>) -> Result {
-		T::ApproveOrigin::ensure_origin(origin)?;
-		let proposal_id = proposal_id.into();
-
-		ensure!(<Proposals<T>>::exists(proposal_id), "No proposal at that index");
-
-		<Approvals<T>>::mutate(|v| v.push(proposal_id));
-
-		Ok(())
-	}
-
-	fn set_pot(new_pot: <T::Balance as HasCompact>::Type) -> Result {
-		// Put the new value into storage.
-		<Pot<T>>::put(new_pot.into());
-
-		// All good.
-		Ok(())
-	}
-
-	fn configure(
-		proposal_bond: Permill,
-		proposal_bond_minimum: <T::Balance as HasCompact>::Type,
-		spend_period: <T::BlockNumber as HasCompact>::Type,
-		burn: Permill
-	) -> Result {
-		<ProposalBond<T>>::put(proposal_bond);
-		<ProposalBondMinimum<T>>::put(proposal_bond_minimum.into());
-		<SpendPeriod<T>>::put(spend_period.into());
-		<Burn<T>>::put(burn);
-		Ok(())
-	}
+	// Add public immutables and private mutables.
 
 	/// The needed bond for a proposal whose spend is `value`.
 	fn calculate_bond(value: T::Balance) -> T::Balance {
@@ -284,15 +281,6 @@ impl<T: Trait> OnDilution<T::Balance> for Module<T> {
 	}
 }
 
-impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
-	fn on_finalise(n: T::BlockNumber) {
-		// Check to see if we should spend some funds!
-		if (n % Self::spend_period()).is_zero() {
-			Self::spend_funds();
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
@@ -300,7 +288,7 @@ mod tests {
 	use runtime_io::with_externalities;
 	use substrate_primitives::{H256, Blake2Hasher};
 	use runtime_primitives::BuildStorage;
-	use runtime_primitives::traits::{BlakeTwo256};
+	use runtime_primitives::traits::{BlakeTwo256, OnFinalise};
 	use runtime_primitives::testing::{Digest, DigestItem, Header};
 
 	impl_outer_origin! {
diff --git a/substrate/srml/upgrade-key/Cargo.toml b/substrate/srml/upgrade-key/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..980a7240a90aa41ba30961c33e03be6179b3ebf0
--- /dev/null
+++ b/substrate/srml/upgrade-key/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+name = "srml-upgrade-key"
+version = "0.1.0"
+authors = ["Parity Technologies <admin@parity.io>"]
+
+[dependencies]
+hex-literal = "0.1.0"
+serde = { version = "1.0", default-features = false }
+serde_derive = { version = "1.0", optional = true }
+parity-codec = { version = "2.1", default-features = false }
+parity-codec-derive = { version = "2.1", default-features = false }
+substrate-primitives = { path = "../../core/primitives", default-features = false }
+sr-std = { path = "../../core/sr-std", default-features = false }
+sr-io = { path = "../../core/sr-io", default-features = false }
+sr-primitives = { path = "../../core/sr-primitives", default-features = false }
+srml-support = { path = "../support", default-features = false }
+srml-system = { path = "../system", default-features = false }
+srml-consensus = { path = "../consensus", default-features = false }
+
+[features]
+default = ["std"]
+std = [
+	"serde/std",
+	"serde_derive",
+	"parity-codec/std",
+	"parity-codec-derive/std",
+	"sr-std/std",
+	"sr-io/std",
+	"sr-primitives/std",
+	"substrate-primitives/std",
+	"srml-support/std",
+	"srml-system/std",
+	"srml-consensus/std",
+]
diff --git a/substrate/srml/upgrade-key/src/lib.rs b/substrate/srml/upgrade-key/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..28433d8fbd5db4d4955f30f3365042eda1e76d7e
--- /dev/null
+++ b/substrate/srml/upgrade-key/src/lib.rs
@@ -0,0 +1,90 @@
+// Copyright 2017-2018 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+//! The Example: A simple example of a runtime module demonstrating
+//! concepts, APIs and structures common to most runtime modules.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate sr_std;
+#[cfg(test)]
+extern crate sr_io;
+#[cfg(test)]
+extern crate substrate_primitives;
+extern crate sr_primitives;
+#[cfg(feature = "std")]
+#[macro_use]
+extern crate serde_derive;
+#[macro_use]
+extern crate parity_codec_derive;
+extern crate parity_codec as codec;
+#[macro_use]
+extern crate srml_support as support;
+extern crate srml_system as system;
+extern crate srml_consensus as consensus;
+
+use sr_std::prelude::*;
+use support::{StorageValue, dispatch::Result};
+use system::ensure_signed;
+
+pub trait Trait: consensus::Trait + system::Trait {
+	/// The overarching event type.
+	type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+}
+
+decl_module! {
+	// Simple declaration of the `Module` type. Lets the macro know what its working on.
+	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+		fn deposit_event() = default;
+		fn upgrade(origin, new: Vec<u8>) -> Result {
+			// This is a public call, so we ensure that the origin is some signed account.
+			let _sender = ensure_signed(origin)?;
+			ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module");
+
+			<consensus::Module<T>>::set_code(new)?;
+			Self::deposit_event(RawEvent::Upgraded);
+
+			Ok(())
+		}
+
+		fn set_key(origin, new: T::AccountId) -> Result {
+			// This is a public call, so we ensure that the origin is some signed account.
+			let _sender = ensure_signed(origin)?;
+			ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module");
+
+			Self::deposit_event(RawEvent::KeyChanged(Self::key()));
+			<Key<T>>::put(new);
+
+			Ok(())
+		}
+	}
+}
+
+/// An event in this module.
+decl_event!(
+	pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
+		/// An upgrade just happened.
+		Upgraded,
+		/// An upgrade just happened; old key is supplied as an argument.
+		KeyChanged(AccountId),
+	}
+);
+
+decl_storage! {
+	trait Store for Module<T: Trait> as UpgradeKey {
+		Key get(key) config(): T::AccountId;
+	}
+}