From 0bb44f5024600d6f0ae9d5336099e25e41c13e59 Mon Sep 17 00:00:00 2001
From: Gautam Dhameja <gautamdhameja@users.noreply.github.com>
Date: Mon, 19 Aug 2019 09:17:33 +0200
Subject: [PATCH] Make node-template in sync with node. (#3422)

* Make node-template in sync with node.

* Update service.rs

* Updated babe constants.

* Added SignedExtra for CheckVersion in node-template and subkey.

* Added CheckVersion SignedExtra for node.

* Fixed tests.

* Try fix integration test.

* Attempt 2 at fixing integration test.

* Update node-template/runtime/src/lib.rs
---
 substrate/Cargo.lock                          |  11 +-
 substrate/node-template/Cargo.toml            |   5 +-
 substrate/node-template/README.md             |  18 +-
 substrate/node-template/runtime/Cargo.toml    |  13 +-
 substrate/node-template/runtime/src/lib.rs    | 186 ++++++++---
 substrate/node-template/src/chain_spec.rs     |  83 +++--
 substrate/node-template/src/service.rs        | 288 +++++++++++++-----
 substrate/node/cli/src/factory_impl.rs        |   5 +-
 substrate/node/cli/src/service.rs             |   7 +-
 substrate/node/executor/src/lib.rs            |   9 +-
 substrate/node/runtime/src/lib.rs             |   1 +
 substrate/subkey/src/main.rs                  |   1 +
 .../transaction-factory/src/complex_mode.rs   |   2 +
 .../test-utils/transaction-factory/src/lib.rs |   4 +
 .../transaction-factory/src/simple_modes.rs   |   2 +
 15 files changed, 455 insertions(+), 180 deletions(-)

diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index fc3be28b208..35afd37dbb3 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -2406,9 +2406,10 @@ dependencies = [
  "substrate-basic-authorship 2.0.0",
  "substrate-cli 2.0.0",
  "substrate-client 2.0.0",
- "substrate-consensus-aura 2.0.0",
- "substrate-consensus-aura-primitives 2.0.0",
+ "substrate-consensus-babe 2.0.0",
+ "substrate-consensus-babe-primitives 2.0.0",
  "substrate-executor 2.0.0",
+ "substrate-finality-grandpa 2.0.0",
  "substrate-finality-grandpa-primitives 2.0.0",
  "substrate-inherents 2.0.0",
  "substrate-network 2.0.0",
@@ -2431,16 +2432,18 @@ dependencies = [
  "sr-primitives 2.0.0",
  "sr-std 2.0.0",
  "sr-version 2.0.0",
- "srml-aura 2.0.0",
+ "srml-babe 2.0.0",
  "srml-balances 2.0.0",
  "srml-executive 2.0.0",
+ "srml-grandpa 2.0.0",
  "srml-indices 2.0.0",
  "srml-sudo 2.0.0",
  "srml-support 2.0.0",
  "srml-system 2.0.0",
  "srml-timestamp 2.0.0",
  "substrate-client 2.0.0",
- "substrate-consensus-aura-primitives 2.0.0",
+ "substrate-consensus-babe-primitives 2.0.0",
+ "substrate-consensus-common-primitives 2.0.0",
  "substrate-offchain-primitives 2.0.0",
  "substrate-primitives 2.0.0",
  "substrate-session 2.0.0",
diff --git a/substrate/node-template/Cargo.toml b/substrate/node-template/Cargo.toml
index 4112452b272..73aefc3a282 100644
--- a/substrate/node-template/Cargo.toml
+++ b/substrate/node-template/Cargo.toml
@@ -27,8 +27,9 @@ substrate-service = { path = "../core/service" }
 inherents = { package = "substrate-inherents", path = "../core/inherents" }
 transaction-pool = { package = "substrate-transaction-pool", path = "../core/transaction-pool" }
 network = { package = "substrate-network", path = "../core/network" }
-consensus = { package = "substrate-consensus-aura", path = "../core/consensus/aura" }
-aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../core/consensus/aura/primitives" }
+babe = { package = "substrate-consensus-babe", path = "../core/consensus/babe" }
+babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../core/consensus/babe/primitives" }
+grandpa = { package = "substrate-finality-grandpa", path = "../core/finality-grandpa" }
 grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../core/finality-grandpa/primitives" }
 substrate-client = {  path = "../core/client" }
 basic-authorship = { package = "substrate-basic-authorship", path = "../core/basic-authorship" }
diff --git a/substrate/node-template/README.md b/substrate/node-template/README.md
index 497ed84a52b..5a59652c1b3 100644
--- a/substrate/node-template/README.md
+++ b/substrate/node-template/README.md
@@ -1,8 +1,8 @@
-# Template Node
+# Substrate Node Template
 
 A new SRML-based Substrate node, ready for hacking.
 
-# Building
+## Build
 
 Install Rust:
 
@@ -16,13 +16,15 @@ Install required tools:
 ./scripts/init.sh
 ```
 
-Build all native code:
+Build Wasm and native code:
 
 ```bash
 cargo build
 ```
 
-# Run
+## Run
+
+### Single node development chain
 
 You can start a development chain with:
 
@@ -32,7 +34,13 @@ cargo run -- --dev
 
 Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.
 
-If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.
+### Multi-node local testnet
+
+If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units.
+
+Optionally, give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet).
+
+You'll need two terminal windows open.
 
 We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below:
 
diff --git a/substrate/node-template/runtime/Cargo.toml b/substrate/node-template/runtime/Cargo.toml
index 2f41513048d..54aee700f8c 100644
--- a/substrate/node-template/runtime/Cargo.toml
+++ b/substrate/node-template/runtime/Cargo.toml
@@ -5,7 +5,6 @@ authors = ["Anonymous"]
 edition = "2018"
 
 [dependencies]
-
 serde = { version = "1.0", optional = true, features = ["derive"] }
 safe-mix = { version = "1.0", default-features = false }
 codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
@@ -16,15 +15,17 @@ support = { package = "srml-support", path = "../../srml/support", default_featu
 primitives = { package = "substrate-primitives", path = "../../core/primitives", default_features = false }
 substrate-session = { path = "../../core/session", default-features = false }
 balances = { package = "srml-balances", path = "../../srml/balances", default_features = false }
-aura = { package = "srml-aura", path = "../../srml/aura", default_features = false }
+babe = { package = "srml-babe", path = "../../srml/babe", default-features = false }
+babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false }
 executive = { package = "srml-executive", path = "../../srml/executive", default_features = false }
 indices = { package = "srml-indices", path = "../../srml/indices", default_features = false }
+grandpa = { package = "srml-grandpa", path = "../../srml/grandpa", default-features = false }
 system = { package = "srml-system", path = "../../srml/system", default_features = false }
 timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false }
 sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false }
 sr-primitives = { path = "../../core/sr-primitives", default_features = false }
 client = { package = "substrate-client", path = "../../core/client", default_features = false }
-consensus-aura = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false }
+consensus-primitives = { package = "substrate-consensus-common-primitives", path = "../../core/consensus/common/primitives", default-features = false }
 offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false }
 
 [build-dependencies]
@@ -39,9 +40,11 @@ std = [
 	"runtime-io/std",
 	"support/std",
 	"balances/std",
+	"babe/std",
+	"babe-primitives/std",
 	"executive/std",
-	"aura/std",
 	"indices/std",
+	"grandpa/std",
 	"primitives/std",
 	"sr-primitives/std",
 	"system/std",
@@ -50,7 +53,7 @@ std = [
 	"version/std",
 	"serde",
 	"safe-mix/std",
-	"consensus-aura/std",
+	"consensus-primitives/std",
 	"offchain-primitives/std",
 	"substrate-session/std",
 ]
diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs
index 3f298f1032e..9f520971ad9 100644
--- a/substrate/node-template/runtime/src/lib.rs
+++ b/substrate/node-template/runtime/src/lib.rs
@@ -9,16 +9,19 @@
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
 use rstd::prelude::*;
-use primitives::{sr25519, OpaqueMetadata, crypto::key_types};
+use primitives::{OpaqueMetadata, crypto::key_types};
 use sr_primitives::{
 	ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
-	impl_opaque_keys,
+	impl_opaque_keys, AnySignature
 };
-use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto};
+use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto};
 use sr_primitives::weights::Weight;
+use babe::{AuthorityId as BabeId};
+use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight};
+use grandpa::fg_primitives::{self, ScheduledChange};
 use client::{
 	block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
-	runtime_api, impl_runtime_apis
+	runtime_api as client_api, impl_runtime_apis
 };
 use version::RuntimeVersion;
 #[cfg(feature = "std")]
@@ -32,29 +35,31 @@ pub use balances::Call as BalancesCall;
 pub use sr_primitives::{Permill, Perbill};
 pub use support::{StorageValue, construct_runtime, parameter_types};
 
-/// Alias to the signature scheme used for Aura authority signatures.
-pub type AuraSignature = consensus_aura::sr25519::AuthoritySignature;
+/// An index to a block.
+pub type BlockNumber = u32;
 
-/// The Ed25519 pub key of an session that belongs to an Aura authority of the chain.
-pub type AuraId = consensus_aura::sr25519::AuthorityId;
+/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
+pub type Signature = AnySignature;
 
-/// Alias to pubkey that identifies an account on the chain.
-pub type AccountId = <AccountSignature as Verify>::Signer;
+/// Some way of identifying an account on the chain. We intentionally make it equivalent
+/// to the public key of our transaction signing scheme.
+pub type AccountId = <Signature as Verify>::Signer;
 
-/// The type used by authorities to prove their ID.
-pub type AccountSignature = sr25519::Signature;
+/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
+/// never know...
+pub type AccountIndex = u32;
 
-/// A hash of some data used by the chain.
-pub type Hash = primitives::H256;
+/// Balance of an account.
+pub type Balance = u128;
 
-/// Index of a block number in the chain.
-pub type BlockNumber = u32;
+/// Index of a transaction in the chain.
+pub type Index = u32;
 
-/// Index of an account's extrinsic in the chain.
-pub type Nonce = u32;
+/// A hash of some data used by the chain.
+pub type Hash = primitives::H256;
 
-/// Balance type for the node.
-pub type Balance = u128;
+/// Digest item type.
+pub type DigestItem = generic::DigestItem<Hash>;
 
 /// Used for the module template in `./template.rs`
 mod template;
@@ -75,10 +80,14 @@ pub mod opaque {
 	/// Opaque block identifier type.
 	pub type BlockId = generic::BlockId<Block>;
 
+	pub type SessionHandlers = (Grandpa, Babe);
+
 	impl_opaque_keys! {
 		pub struct SessionKeys {
-			#[id(key_types::AURA)]
-			pub aura: AuraId,
+			#[id(key_types::GRANDPA)]
+			pub grandpa: GrandpaId,
+			#[id(key_types::BABE)]
+			pub babe: BabeId,
 		}
 	}
 }
@@ -93,6 +102,34 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	apis: RUNTIME_API_VERSIONS,
 };
 
+/// Constants for Babe.
+
+/// Since BABE is probabilistic this is the average expected block time that
+/// we are targetting. Blocks will be produced at a minimum duration defined
+/// by `SLOT_DURATION`, but some slots will not be allocated to any
+/// authority and hence no block will be produced. We expect to have this
+/// block time on average following the defined slot duration and the value
+/// of `c` configured for BABE (where `1 - c` represents the probability of
+/// a slot being empty).
+/// This value is only used indirectly to define the unit constants below
+/// that are expressed in blocks. The rest of the code should use
+/// `SLOT_DURATION` instead (like the timestamp module for calculating the
+/// minimum period).
+/// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
+pub const MILLISECS_PER_BLOCK: u64 = 6000;
+
+pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
+
+pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES;
+
+// These time units are defined in number of blocks.
+pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
+pub const HOURS: BlockNumber = MINUTES * 60;
+pub const DAYS: BlockNumber = HOURS * 24;
+
+// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
+pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
+
 /// The version infromation used to identify this runtime when compiled natively.
 #[cfg(feature = "std")]
 pub fn native_version() -> NativeVersion {
@@ -118,7 +155,7 @@ impl system::Trait for Runtime {
 	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
 	type Lookup = Indices;
 	/// The index type for storing how many extrinsics an account has signed.
-	type Index = Nonce;
+	type Index = Index;
 	/// The index type for blocks.
 	type BlockNumber = BlockNumber;
 	/// The type for hashing blocks and tries.
@@ -144,8 +181,18 @@ impl system::Trait for Runtime {
 	type Version = Version;
 }
 
-impl aura::Trait for Runtime {
-	type AuthorityId = AuraId;
+parameter_types! {
+	pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
+	pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
+}
+
+impl babe::Trait for Runtime {
+	type EpochDuration = EpochDuration;
+	type ExpectedBlockTime = ExpectedBlockTime;
+}
+
+impl grandpa::Trait for Runtime {
+	type Event = Event;
 }
 
 impl indices::Trait for Runtime {
@@ -167,7 +214,7 @@ parameter_types! {
 impl timestamp::Trait for Runtime {
 	/// A timestamp: milliseconds since the unix epoch.
 	type Moment = u64;
-	type OnTimestampSet = Aura;
+	type OnTimestampSet = Babe;
 	type MinimumPeriod = MinimumPeriod;
 }
 
@@ -201,7 +248,6 @@ impl balances::Trait for Runtime {
 }
 
 impl sudo::Trait for Runtime {
-	/// The ubiquitous event type.
 	type Event = Event;
 	type Proposal = Call;
 }
@@ -219,7 +265,8 @@ construct_runtime!(
 	{
 		System: system::{Module, Call, Storage, Config, Event},
 		Timestamp: timestamp::{Module, Call, Storage, Inherent},
-		Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
+		Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
+		Grandpa: grandpa::{Module, Call, Storage, Config, Event},
 		Indices: indices::{default, Config<T>},
 		Balances: balances,
 		Sudo: sudo,
@@ -228,28 +275,34 @@ construct_runtime!(
 	}
 );
 
-/// The type used as a helper for interpreting the sender of transactions.
-type Context = system::ChainContext<Runtime>;
 /// The address format for describing accounts.
-type Address = <Indices as StaticLookup>::Source;
+pub type Address = <Indices as StaticLookup>::Source;
 /// Block header type as expected by this runtime.
 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
 /// Block type as expected by this runtime.
 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+/// A Block signed with a Justification
+pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 /// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (system::CheckNonce<Runtime>, system::CheckWeight<Runtime>, balances::TakeFees<Runtime>);
+pub type SignedExtra = (
+	system::CheckVersion<Runtime>,
+	system::CheckGenesis<Runtime>,
+	system::CheckEra<Runtime>,
+	system::CheckNonce<Runtime>,
+	system::CheckWeight<Runtime>,
+	balances::TakeFees<Runtime>
+);
 /// Unchecked extrinsic type as expected by this runtime.
-pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, AccountSignature, SignedExtra>;
+pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
 /// Extrinsic type that has already been checked.
 pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
 /// Executive: handles dispatch to the various modules.
-pub type Executive = executive::Executive<Runtime, Block, Context, Runtime, AllModules>;
+pub type Executive = executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
 
-// Implement our runtime API endpoints. This is just a bunch of proxying.
 impl_runtime_apis! {
-	impl runtime_api::Core<Block> for Runtime {
+	impl client_api::Core<Block> for Runtime {
 		fn version() -> RuntimeVersion {
 			VERSION
 		}
@@ -263,7 +316,7 @@ impl_runtime_apis! {
 		}
 	}
 
-	impl runtime_api::Metadata<Block> for Runtime {
+	impl client_api::Metadata<Block> for Runtime {
 		fn metadata() -> OpaqueMetadata {
 			Runtime::metadata().into()
 		}
@@ -291,24 +344,65 @@ impl_runtime_apis! {
 		}
 	}
 
-	impl runtime_api::TaggedTransactionQueue<Block> for Runtime {
+	impl client_api::TaggedTransactionQueue<Block> for Runtime {
 		fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
 			Executive::validate_transaction(tx)
 		}
 	}
 
-	impl consensus_aura::AuraApi<Block, AuraId> for Runtime {
-		fn slot_duration() -> u64 {
-			Aura::slot_duration()
+	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
+		fn offchain_worker(number: NumberFor<Block>) {
+			Executive::offchain_worker(number)
+		}
+	}
+
+	impl fg_primitives::GrandpaApi<Block> for Runtime {
+		fn grandpa_pending_change(digest: &DigestFor<Block>)
+			-> Option<ScheduledChange<NumberFor<Block>>>
+		{
+			Grandpa::pending_change(digest)
 		}
-		fn authorities() -> Vec<AuraId> {
-			Aura::authorities()
+
+		fn grandpa_forced_change(digest: &DigestFor<Block>)
+			-> Option<(NumberFor<Block>, ScheduledChange<NumberFor<Block>>)>
+		{
+			Grandpa::forced_change(digest)
+		}
+
+		fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> {
+			Grandpa::grandpa_authorities()
 		}
 	}
 
-	impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
-		fn offchain_worker(n: NumberFor<Block>) {
-			Executive::offchain_worker(n)
+	impl babe_primitives::BabeApi<Block> for Runtime {
+		fn startup_data() -> babe_primitives::BabeConfiguration {
+			// The choice of `c` parameter (where `1 - c` represents the
+			// probability of a slot being empty), is done in accordance to the
+			// slot duration and expected target block time, for safely
+			// resisting network delays of maximum two seconds.
+			// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
+			babe_primitives::BabeConfiguration {
+				median_required_blocks: 1000,
+				slot_duration: Babe::slot_duration(),
+				c: PRIMARY_PROBABILITY,
+			}
+		}
+
+		fn epoch() -> babe_primitives::Epoch {
+			babe_primitives::Epoch {
+				start_slot: Babe::epoch_start_slot(),
+				authorities: Babe::authorities(),
+				epoch_index: Babe::epoch_index(),
+				randomness: Babe::randomness(),
+				duration: EpochDuration::get(),
+				secondary_slots: Babe::secondary_slots().0,
+			}
+		}
+	}
+
+	impl consensus_primitives::ConsensusApi<Block, babe_primitives::AuthorityId> for Runtime {
+		fn authorities() -> Vec<babe_primitives::AuthorityId> {
+			Babe::authorities().into_iter().map(|(a, _)| a).collect()
 		}
 	}
 
diff --git a/substrate/node-template/src/chain_spec.rs b/substrate/node-template/src/chain_spec.rs
index 65caab70dbe..9fdc6ee2ca6 100644
--- a/substrate/node-template/src/chain_spec.rs
+++ b/substrate/node-template/src/chain_spec.rs
@@ -1,9 +1,10 @@
-use primitives::{sr25519, Pair};
+use primitives::{Pair, Public};
 use node_template_runtime::{
-	AccountId, GenesisConfig, AuraConfig, BalancesConfig,
-	SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, AuraId
+	AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig,
+	SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, 
 };
-use aura_primitives::sr25519::AuthorityPair as AuraPair;
+use babe_primitives::{AuthorityId as BabeId};
+use grandpa_primitives::{AuthorityId as GrandpaId};
 use substrate_service;
 
 // Note this is the URL for the telemetry server
@@ -23,16 +24,21 @@ pub enum Alternative {
 	LocalTestnet,
 }
 
-fn authority_key(s: &str) -> AuraId {
-	AuraPair::from_string(&format!("//{}", s), None)
+/// Helper function to generate a crypto pair from seed
+pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
+	TPublic::Pair::from_string(&format!("//{}", seed), None)
 		.expect("static values are valid; qed")
 		.public()
 }
 
-fn account_key(s: &str) -> AccountId {
-	sr25519::Pair::from_string(&format!("//{}", s), None)
-		.expect("static values are valid; qed")
-		.public()
+/// Helper function to generate stash, controller and session key from seed
+pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId) {
+	(
+		get_from_seed::<AccountId>(&format!("{}//stash", seed)),
+		get_from_seed::<AccountId>(seed),
+		get_from_seed::<GrandpaId>(seed),
+		get_from_seed::<BabeId>(seed),
+	)
 }
 
 impl Alternative {
@@ -43,12 +49,16 @@ impl Alternative {
 				"Development",
 				"dev",
 				|| testnet_genesis(vec![
-					authority_key("Alice")
-				], vec![
-					account_key("Alice")
+					get_authority_keys_from_seed("Alice"),
+				],
+				get_from_seed::<AccountId>("Alice"),
+				vec![
+					get_from_seed::<AccountId>("Alice"),
+					get_from_seed::<AccountId>("Bob"),
+					get_from_seed::<AccountId>("Alice//stash"),
+					get_from_seed::<AccountId>("Bob//stash"),
 				],
-					account_key("Alice")
-				),
+				true),
 				vec![],
 				None,
 				None,
@@ -59,18 +69,25 @@ impl Alternative {
 				"Local Testnet",
 				"local_testnet",
 				|| testnet_genesis(vec![
-					authority_key("Alice"),
-					authority_key("Bob"),
-				], vec![
-					account_key("Alice"),
-					account_key("Bob"),
-					account_key("Charlie"),
-					account_key("Dave"),
-					account_key("Eve"),
-					account_key("Ferdie"),
+					get_authority_keys_from_seed("Alice"),
+					get_authority_keys_from_seed("Bob"),
+				], 
+				get_from_seed::<AccountId>("Alice"),
+				vec![
+					get_from_seed::<AccountId>("Alice"),
+					get_from_seed::<AccountId>("Bob"),
+					get_from_seed::<AccountId>("Charlie"),
+					get_from_seed::<AccountId>("Dave"),
+					get_from_seed::<AccountId>("Eve"),
+					get_from_seed::<AccountId>("Ferdie"),
+					get_from_seed::<AccountId>("Alice//stash"),
+					get_from_seed::<AccountId>("Bob//stash"),
+					get_from_seed::<AccountId>("Charlie//stash"),
+					get_from_seed::<AccountId>("Dave//stash"),
+					get_from_seed::<AccountId>("Eve//stash"),
+					get_from_seed::<AccountId>("Ferdie//stash"),
 				],
-					account_key("Alice"),
-				),
+				true),
 				vec![],
 				None,
 				None,
@@ -89,15 +106,15 @@ impl Alternative {
 	}
 }
 
-fn testnet_genesis(initial_authorities: Vec<AuraId>, endowed_accounts: Vec<AccountId>, root_key: AccountId) -> GenesisConfig {
+fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>,
+	root_key: AccountId, 
+	endowed_accounts: Vec<AccountId>,
+	_enable_println: bool) -> GenesisConfig {
 	GenesisConfig {
 		system: Some(SystemConfig {
 			code: WASM_BINARY.to_vec(),
 			changes_trie_config: Default::default(),
 		}),
-		aura: Some(AuraConfig {
-			authorities: initial_authorities.clone(),
-		}),
 		indices: Some(IndicesConfig {
 			ids: endowed_accounts.clone(),
 		}),
@@ -108,5 +125,11 @@ fn testnet_genesis(initial_authorities: Vec<AuraId>, endowed_accounts: Vec<Accou
 		sudo: Some(SudoConfig {
 			key: root_key,
 		}),
+		babe: Some(BabeConfig {
+			authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(),
+		}),
+		grandpa: Some(GrandpaConfig {
+			authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
+		}),
 	}
 }
diff --git a/substrate/node-template/src/service.rs b/substrate/node-template/src/service.rs
index 7f2c80c48b2..b4a1a96413c 100644
--- a/substrate/node-template/src/service.rs
+++ b/substrate/node-template/src/service.rs
@@ -1,26 +1,26 @@
-//! Service and ServiceFactory implementation. Specialized wrapper over Substrate service.
-
 #![warn(unused_extern_crates)]
 
+//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
+
 use std::sync::Arc;
-use transaction_pool::{self, txpool::{Pool as TransactionPool}};
+use std::time::Duration;
+use substrate_client::{self as client, LongestChain};
+use babe::{import_queue, start_babe, BabeImportQueue, Config};
+use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
+use futures::prelude::*;
 use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY};
 use substrate_service::{
 	FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
 	FullClient, LightClient, LightBackend, FullExecutor, LightExecutor,
 	error::{Error as ServiceError},
 };
-use basic_authorship::ProposerFactory;
-use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration};
-use futures::prelude::*;
-use substrate_client::{self as client, LongestChain};
+use transaction_pool::{self, txpool::{Pool as TransactionPool}};
 use inherents::InherentDataProviders;
-use network::{config::DummyFinalityProofRequestBuilder, construct_simple_protocol};
+use network::construct_simple_protocol;
 use substrate_executor::native_executor_instance;
-use substrate_service::construct_service_factory;
-use aura_primitives::sr25519::AuthorityPair as AuraAuthorityPair;
-
+use substrate_service::{ServiceFactory, construct_service_factory, TelemetryOnConnect};
 pub use substrate_executor::NativeExecutor;
+
 // Our native executor instance.
 native_executor_instance!(
 	pub Executor,
@@ -29,62 +29,168 @@ native_executor_instance!(
 	WASM_BINARY
 );
 
-#[derive(Default)]
-pub struct NodeConfig {
-	inherent_data_providers: InherentDataProviders,
-}
-
 construct_simple_protocol! {
 	/// Demo protocol attachment for substrate.
 	pub struct NodeProtocol where Block = Block { }
 }
 
+type BabeBlockImportForService<F> = babe::BabeBlockImport<
+	FullBackend<F>,
+	FullExecutor<F>,
+	<F as ServiceFactory>::Block,
+	grandpa::BlockImportForService<F>,
+	<F as ServiceFactory>::RuntimeApi,
+	client::Client<
+		FullBackend<F>,
+		FullExecutor<F>,
+		<F as ServiceFactory>::Block,
+		<F as ServiceFactory>::RuntimeApi
+	>,
+>;
+
+pub struct NodeConfig<F: ServiceFactory> {
+	/// GRANDPA and BABE connection to import block.
+	// FIXME #1134 rather than putting this on the config, let's have an actual intermediate setup state
+	pub import_setup: Option<(
+		BabeBlockImportForService<F>,
+		grandpa::LinkHalfForService<F>,
+		babe::BabeLink,
+	)>,
+	/// Tasks that were created by previous setup steps and should be spawned.
+	pub tasks_to_spawn: Option<Vec<Box<dyn Future<Item = (), Error = ()> + Send>>>,
+	inherent_data_providers: InherentDataProviders,
+}
+
+impl<F> Default for NodeConfig<F> where F: ServiceFactory {
+	fn default() -> NodeConfig<F> {
+		NodeConfig {
+			import_setup: None,
+			inherent_data_providers: InherentDataProviders::new(),
+			tasks_to_spawn: None,
+		}
+	}
+}
+
 construct_service_factory! {
 	struct Factory {
 		Block = Block,
 		RuntimeApi = RuntimeApi,
 		NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) },
 		RuntimeDispatch = Executor,
-		FullTransactionPoolApi = transaction_pool::ChainApi<
-			client::Client<FullBackend<Self>, FullExecutor<Self>, Block, RuntimeApi>,
-			Block
-		> {
-			|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
-		},
-		LightTransactionPoolApi = transaction_pool::ChainApi<
-			client::Client<LightBackend<Self>, LightExecutor<Self>, Block, RuntimeApi>,
-			Block
-		> {
-			|config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
-		},
-		Genesis = GenesisConfig,
-		Configuration = NodeConfig,
-		FullService = FullComponents<Self>
-			{ |config: FactoryFullConfiguration<Self>|
-				FullComponents::<Factory>::new(config)
+		FullTransactionPoolApi =
+			transaction_pool::ChainApi<
+				client::Client<FullBackend<Self>, FullExecutor<Self>, Block, RuntimeApi>,
+				Block
+			> {
+				|config, client|
+					Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
+			},
+		LightTransactionPoolApi =
+			transaction_pool::ChainApi<
+				client::Client<LightBackend<Self>, LightExecutor<Self>, Block, RuntimeApi>,
+				Block
+			> {
+				|config, client|
+					Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client)))
 			},
+		Genesis = GenesisConfig,
+		Configuration = NodeConfig<Self>,
+		FullService = FullComponents<Self> {
+			|config: FactoryFullConfiguration<Self>| FullComponents::<Factory>::new(config)
+		},
 		AuthoritySetup = {
-			|service: Self::FullService| {
+			|mut service: Self::FullService| {
+				let (block_import, link_half, babe_link) =
+					service.config_mut().custom.import_setup.take()
+						.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
+
+				// spawn any futures that were created in the previous setup steps
+				if let Some(tasks) = service.config_mut().custom.tasks_to_spawn.take() {
+					for task in tasks {
+						service.spawn_task(
+							task.select(service.on_exit())
+								.map(|_| ())
+								.map_err(|_| ())
+						);
+					}
+				}
+
 				if service.config().roles.is_authority() {
-					let proposer = ProposerFactory {
+					let proposer = basic_authorship::ProposerFactory {
 						client: service.client(),
 						transaction_pool: service.transaction_pool(),
 					};
+
 					let client = service.client();
 					let select_chain = service.select_chain()
-						.ok_or_else(|| ServiceError::SelectChainRequired)?;
-					let aura = start_aura::<_, _, _, _, _, AuraAuthorityPair, _, _, _>(
-						SlotDuration::get_or_compute(&*client)?,
-						client.clone(),
-						select_chain,
+						.ok_or(ServiceError::SelectChainRequired)?;
+
+					let babe_config = babe::BabeParams {
+						config: Config::get_or_compute(&*client)?,
+						keystore: service.keystore(),
 						client,
-						proposer,
-						service.network(),
-						service.config().custom.inherent_data_providers.clone(),
-						service.config().force_authoring,
-						Some(service.keystore()),
-					)?;
-					service.spawn_task(Box::new(aura.select(service.on_exit()).then(|_| Ok(()))));
+						select_chain,
+						block_import,
+						env: proposer,
+						sync_oracle: service.network(),
+						inherent_data_providers: service.config()
+							.custom.inherent_data_providers.clone(),
+						force_authoring: service.config().force_authoring,
+						time_source: babe_link,
+					};
+
+					let babe = start_babe(babe_config)?;
+					let select = babe.select(service.on_exit()).then(|_| Ok(()));
+
+					// the BABE authoring task is considered infallible, i.e. if it
+					// fails we take down the service with it.
+					service.spawn_essential_task(select);
+				}
+
+				let config = grandpa::Config {
+					// FIXME #1578 make this available through chainspec
+					gossip_duration: Duration::from_millis(333),
+					justification_period: 4096,
+					name: Some(service.config().name.clone()),
+					keystore: Some(service.keystore()),
+				};
+
+				match (service.config().roles.is_authority(), service.config().disable_grandpa) {
+					(false, false) => {
+						// start the lightweight GRANDPA observer
+						service.spawn_task(Box::new(grandpa::run_grandpa_observer(
+							config,
+							link_half,
+							service.network(),
+							service.on_exit(),
+						)?));
+					},
+					(true, false) => {
+						// start the full GRANDPA voter
+						let telemetry_on_connect = TelemetryOnConnect {
+							telemetry_connection_sinks: service.telemetry_on_connect_stream(),
+						};
+						let grandpa_config = grandpa::GrandpaParams {
+							config: config,
+							link: link_half,
+							network: service.network(),
+							inherent_data_providers:
+								service.config().custom.inherent_data_providers.clone(),
+							on_exit: service.on_exit(),
+							telemetry_on_connect: Some(telemetry_on_connect),
+						};
+
+						// the GRANDPA voter task is considered infallible, i.e.
+						// if it fails we take down the service with it.
+						service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?);
+					},
+					(_, true) => {
+						grandpa::setup_disabled_grandpa(
+							service.client(),
+							&service.config().custom.inherent_data_providers,
+							service.network(),
+						)?;
+					},
 				}
 
 				Ok(service)
@@ -92,50 +198,70 @@ construct_service_factory! {
 		},
 		LightService = LightComponents<Self>
 			{ |config| <LightComponents<Factory>>::new(config) },
-		FullImportQueue = AuraImportQueue<
-			Self::Block,
-		>
-			{ |
+		FullImportQueue = BabeImportQueue<Self::Block> {
+			|
 				config: &mut FactoryFullConfiguration<Self>,
 				client: Arc<FullClient<Self>>,
-				_select_chain: Self::SelectChain,
+				select_chain: Self::SelectChain,
 				transaction_pool: Option<Arc<TransactionPool<Self::FullTransactionPoolApi>>>,
 			| {
-					import_queue::<_, _, aura_primitives::sr25519::AuthorityPair, _>(
-						SlotDuration::get_or_compute(&*client)?,
-						Box::new(client.clone()),
-						None,
-						None,
-						client,
-						config.custom.inherent_data_providers.clone(),
-						transaction_pool,
-					).map_err(Into::into)
-				}
-			},
-		LightImportQueue = AuraImportQueue<
-			Self::Block,
-		>
-			{ |config: &mut FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>| {
-					let fprb = Box::new(DummyFinalityProofRequestBuilder::default()) as Box<_>;
-					import_queue::<_, _, AuraAuthorityPair, TransactionPool<Self::FullTransactionPoolApi>>(
-						SlotDuration::get_or_compute(&*client)?,
-						Box::new(client.clone()),
-						None,
-						None,
-						client,
-						config.custom.inherent_data_providers.clone(),
-						None,
-					).map(|q| (q, fprb)).map_err(Into::into)
-				}
-			},
+				let (block_import, link_half) =
+					grandpa::block_import::<_, _, _, RuntimeApi, FullClient<Self>, _>(
+						client.clone(), client.clone(), select_chain
+					)?;
+				let justification_import = block_import.clone();
+				let (import_queue, babe_link, babe_block_import, pruning_task) = import_queue(
+					Config::get_or_compute(&*client)?,
+					block_import,
+					Some(Box::new(justification_import)),
+					None,
+					client.clone(),
+					client,
+					config.custom.inherent_data_providers.clone(),
+					transaction_pool,
+				)?;
+				config.custom.import_setup = Some((babe_block_import.clone(), link_half, babe_link));
+				config.custom.tasks_to_spawn = Some(vec![Box::new(pruning_task)]);
+				Ok(import_queue)
+			}
+		},
+		LightImportQueue = BabeImportQueue<Self::Block>
+			{ |config: &FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>| {
+				#[allow(deprecated)]
+				let fetch_checker = client.backend().blockchain().fetcher()
+					.upgrade()
+					.map(|fetcher| fetcher.checker().clone())
+					.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
+				let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, LightClient<Self>>(
+					client.clone(), Arc::new(fetch_checker), client.clone()
+				)?;
+
+				let finality_proof_import = block_import.clone();
+				let finality_proof_request_builder =
+					finality_proof_import.create_finality_proof_request_builder();
+
+				// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
+				let (import_queue, ..) = import_queue::<_, _, _, _, _, _, TransactionPool<Self::FullTransactionPoolApi>>(
+					Config::get_or_compute(&*client)?,
+					block_import,
+					None,
+					Some(Box::new(finality_proof_import)),
+					client.clone(),
+					client,
+					config.custom.inherent_data_providers.clone(),
+					None,
+				)?;
+
+				Ok((import_queue, finality_proof_request_builder))
+			}},
 		SelectChain = LongestChain<FullBackend<Self>, Self::Block>
 			{ |config: &FactoryFullConfiguration<Self>, client: Arc<FullClient<Self>>| {
 				#[allow(deprecated)]
 				Ok(LongestChain::new(client.backend().clone()))
 			}
 		},
-		FinalityProofProvider = { |_client: Arc<FullClient<Self>>| {
-			Ok(None)
+		FinalityProofProvider = { |client: Arc<FullClient<Self>>| {
+			Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _))
 		}},
 	}
 }
diff --git a/substrate/node/cli/src/factory_impl.rs b/substrate/node/cli/src/factory_impl.rs
index 6345a851f28..e371aef8e08 100644
--- a/substrate/node/cli/src/factory_impl.rs
+++ b/substrate/node/cli/src/factory_impl.rs
@@ -51,6 +51,7 @@ type Number = <<node_primitives::Block as BlockT>::Header as HeaderT>::Number;
 impl<Number> FactoryState<Number> {
 	fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra {
 		(
+			system::CheckVersion::new(),
 			system::CheckGenesis::new(),
 			system::CheckEra::from(Era::mortal(256, phase)),
 			system::CheckNonce::from(index),
@@ -132,12 +133,12 @@ impl RuntimeAdapter for FactoryState<Number> {
 		key: &Self::Secret,
 		destination: &Self::AccountId,
 		amount: &Self::Balance,
+		version: u32,
 		genesis_hash: &<Self::Block as BlockT>::Hash,
 		prior_block_hash: &<Self::Block as BlockT>::Hash,
 	) -> <Self::Block as BlockT>::Extrinsic {
 		let index = self.extract_index(&sender, prior_block_hash);
 		let phase = self.extract_phase(*prior_block_hash);
-
 		sign::<Self>(CheckedExtrinsic {
 			signed: Some((sender.clone(), Self::build_extra(index, phase))),
 			function: Call::Balances(
@@ -146,7 +147,7 @@ impl RuntimeAdapter for FactoryState<Number> {
 					(*amount).into()
 				)
 			)
-		}, key, (genesis_hash.clone(), prior_block_hash.clone(), (), (), ()))
+		}, key, (version, genesis_hash.clone(), prior_block_hash.clone(), (), (), ()))
 	}
 
 	fn inherent_extrinsics(&self) -> InherentData {
diff --git a/substrate/node/cli/src/service.rs b/substrate/node/cli/src/service.rs
index ebd2f29fd51..b691b508fd4 100644
--- a/substrate/node/cli/src/service.rs
+++ b/substrate/node/cli/src/service.rs
@@ -454,18 +454,21 @@ mod tests {
 			let to = AddressPublic::from_raw(bob.public().0);
 			let from = AddressPublic::from_raw(charlie.public().0);
 			let genesis_hash = service.get().client().block_hash(0).unwrap().unwrap();
+			let best_block_id = BlockId::number(service.get().client().info().chain.best_number);
+			let version = service.get().client().runtime_version_at(&best_block_id).unwrap().spec_version;
 			let signer = charlie.clone();
 
 			let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
 
+			let check_version = system::CheckVersion::new();
 			let check_genesis = system::CheckGenesis::new();
 			let check_era = system::CheckEra::from(Era::Immortal);
 			let check_nonce = system::CheckNonce::from(index);
 			let check_weight = system::CheckWeight::new();
 			let take_fees = balances::TakeFees::from(0);
-			let extra = (check_genesis, check_era, check_nonce, check_weight, take_fees);
+			let extra = (check_version, check_genesis, check_era, check_nonce, check_weight, take_fees);
 
-			let raw_payload = (function, extra.clone(), genesis_hash, genesis_hash);
+			let raw_payload = (function, extra.clone(), version, genesis_hash, genesis_hash);
 			let signature = raw_payload.using_encoded(|payload| if payload.len() > 256 {
 				signer.sign(&blake2_256(payload)[..])
 			} else {
diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs
index eece362ea8d..448ab9d8b6f 100644
--- a/substrate/node/executor/src/lib.rs
+++ b/substrate/node/executor/src/lib.rs
@@ -44,7 +44,7 @@ mod tests {
 	use keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring};
 	use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency};
 	use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities};
-	use primitives::{ twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded};
+	use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded};
 	use node_primitives::{Hash, BlockNumber, AccountId, Balance, Index};
 	use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert};
 	use sr_primitives::{generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill};
@@ -55,7 +55,7 @@ mod tests {
 		Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage,
 		GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System, SystemConfig,
 		GrandpaConfig, IndicesConfig, ContractsConfig, Event, SessionKeys, SignedExtra,
-		TransferFee, TransactionBaseFee, TransactionByteFee,
+		TransferFee, TransactionBaseFee, TransactionByteFee
 	};
 	use node_runtime::constants::currency::*;
 	use node_runtime::impls::WeightToFee;
@@ -79,6 +79,8 @@ mod tests {
 
 	const GENESIS_HASH: [u8; 32] = [69u8; 32];
 
+	const VERSION: u32 = node_runtime::VERSION.spec_version;
+
 	type TestExternalities<H> = CoreTestExternalities<H, u64>;
 
 	/// Default transfer fee
@@ -122,7 +124,7 @@ mod tests {
 	fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic {
 		match xt.signed {
 			Some((signed, extra)) => {
-				let payload = (xt.function, extra.clone(), GENESIS_HASH, GENESIS_HASH);
+				let payload = (xt.function, extra.clone(), VERSION, GENESIS_HASH, GENESIS_HASH);
 				let key = AccountKeyring::from_public(&signed).unwrap();
 				let signature = payload.using_encoded(|b| {
 					if b.len() > 256 {
@@ -145,6 +147,7 @@ mod tests {
 
 	fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra {
 		(
+			system::CheckVersion::new(),
 			system::CheckGenesis::new(),
 			system::CheckEra::from(Era::mortal(256, 0)),
 			system::CheckNonce::from(nonce),
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index c2cbe74194e..0a7016770d2 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -463,6 +463,7 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 pub type BlockId = generic::BlockId<Block>;
 /// The SignedExtension to the basic transaction logic.
 pub type SignedExtra = (
+	system::CheckVersion<Runtime>,
 	system::CheckGenesis<Runtime>,
 	system::CheckEra<Runtime>,
 	system::CheckNonce<Runtime>,
diff --git a/substrate/subkey/src/main.rs b/substrate/subkey/src/main.rs
index 8f32ddb7d39..ba9d1a6cce0 100644
--- a/substrate/subkey/src/main.rs
+++ b/substrate/subkey/src/main.rs
@@ -97,6 +97,7 @@ fn execute<C: Crypto>(matches: clap::ArgMatches) where
 {
 	let extra = |i: Index, f: Balance| {
 		(
+			system::CheckVersion::<Runtime>::new(),
 			system::CheckGenesis::<Runtime>::new(),
 			system::CheckEra::<Runtime>::from(Era::Immortal),
 			system::CheckNonce::<Runtime>::from(i),
diff --git a/substrate/test-utils/transaction-factory/src/complex_mode.rs b/substrate/test-utils/transaction-factory/src/complex_mode.rs
index 25170f8c188..85b12248d80 100644
--- a/substrate/test-utils/transaction-factory/src/complex_mode.rs
+++ b/substrate/test-utils/transaction-factory/src/complex_mode.rs
@@ -54,6 +54,7 @@ use crate::{RuntimeAdapter, create_block};
 pub fn next<F, RA>(
 	factory_state: &mut RA,
 	client: &Arc<ComponentClient<FullComponents<F>>>,
+	version: u32,
 	genesis_hash: <RA::Block as BlockT>::Hash,
 	prior_block_hash: <RA::Block as BlockT>::Hash,
 	prior_block_id: BlockId<F::Block>,
@@ -92,6 +93,7 @@ where
 		&from.1,
 		&to,
 		&amount,
+		version,
 		&genesis_hash,
 		&prior_block_hash,
 	);
diff --git a/substrate/test-utils/transaction-factory/src/lib.rs b/substrate/test-utils/transaction-factory/src/lib.rs
index ab7dfb8ceab..16bb08a2b43 100644
--- a/substrate/test-utils/transaction-factory/src/lib.rs
+++ b/substrate/test-utils/transaction-factory/src/lib.rs
@@ -77,6 +77,7 @@ pub trait RuntimeAdapter {
 		key: &Self::Secret,
 		destination: &Self::AccountId,
 		amount: &Self::Balance,
+		version: u32,
 		genesis_hash: &<Self::Block as BlockT>::Hash,
 		prior_block_hash: &<Self::Block as BlockT>::Hash,
 	) -> <Self::Block as BlockT>::Extrinsic;
@@ -119,6 +120,7 @@ where
 		select_chain.best_chain().map_err(|e| format!("{:?}", e).into());
 	let mut best_hash = best_header?.hash();
 	let best_block_id = BlockId::<F::Block>::hash(best_hash);
+	let version = client.runtime_version_at(&best_block_id)?.spec_version;
 	let genesis_hash = client.block_hash(Zero::zero())?
 		.expect("Genesis block always exists; qed").into();
 
@@ -126,6 +128,7 @@ where
 		Mode::MasterToNToM => complex_mode::next::<F, RA>(
 			&mut factory_state,
 			&client,
+			version,
 			genesis_hash,
 			best_hash.into(),
 			best_block_id,
@@ -133,6 +136,7 @@ where
 		_ => simple_modes::next::<F, RA>(
 			&mut factory_state,
 			&client,
+			version,
 			genesis_hash,
 			best_hash.into(),
 			best_block_id,
diff --git a/substrate/test-utils/transaction-factory/src/simple_modes.rs b/substrate/test-utils/transaction-factory/src/simple_modes.rs
index 0554678fbbd..ec4f484fa98 100644
--- a/substrate/test-utils/transaction-factory/src/simple_modes.rs
+++ b/substrate/test-utils/transaction-factory/src/simple_modes.rs
@@ -49,6 +49,7 @@ use crate::{Mode, RuntimeAdapter, create_block};
 pub fn next<F, RA>(
 	factory_state: &mut RA,
 	client: &Arc<ComponentClient<FullComponents<F>>>,
+	version: u32,
 	genesis_hash: <RA::Block as BlockT>::Hash,
 	prior_block_hash: <RA::Block as BlockT>::Hash,
 	prior_block_id: BlockId<F::Block>,
@@ -83,6 +84,7 @@ where
 		&from.1,
 		&to,
 		&amount,
+		version,
 		&genesis_hash,
 		&prior_block_hash,
 	);
-- 
GitLab