diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm
index 353df1156ad7dcd239ebe9040fa180d9b6d45349..b51ad28c97b97445aa4a093e179e6f2db831ea77 100644
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ
diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm
index 604500c98b5906b45c697793e0a78031b592f250..3b0e6e0b0f864375ab5e96fc6145a8ab5082b396 100755
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ
diff --git a/substrate/polkadot/runtime/src/lib.rs b/substrate/polkadot/runtime/src/lib.rs
index 7c366e30e7a8a2a136b07e5c545f1853a67e8bdd..9e47ad54e792e742c656e944d338cb254241f3ed 100644
--- a/substrate/polkadot/runtime/src/lib.rs
+++ b/substrate/polkadot/runtime/src/lib.rs
@@ -110,7 +110,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: ver_str!("polkadot"),
 	impl_name: ver_str!("parity-polkadot"),
 	authoring_version: 1,
-	spec_version: 2,
+	spec_version: 100,
 	impl_version: 0,
 };
 
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm
index 72aa4463a3ed7c3970fdba4d6368d715f0062ff6..b04b146ea1c7b828cb50c7497aa5c9a1879473c5 100644
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm
index c50030ecaadf3464350b1e255608a0ab10c21995..fa48cfe95fb570990592018a817366eee413b086 100755
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ
diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm
index 790eb1909f21d08d5121dd7f3078666581a35502..bd930a1e4cc7abbb9e55e31ad36b3273ea1232eb 100644
Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ
diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm
index 51a27fe0197ad7753aa77d13599aa7b7fbd194d2..15312bde3b2a0e7d6ff6a5f81c0edfd6274238db 100755
Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ
diff --git a/substrate/substrate/runtime/session/src/lib.rs b/substrate/substrate/runtime/session/src/lib.rs
index 6e320a73575f931a361cb62db92a3deec7dd864f..8e53428de63a080be03aba508ed073bd1199166b 100644
--- a/substrate/substrate/runtime/session/src/lib.rs
+++ b/substrate/substrate/runtime/session/src/lib.rs
@@ -79,6 +79,7 @@ decl_module! {
 		fn force_new_session(normal_rotation: bool) -> Result = 1;
 	}
 }
+
 decl_storage! {
 	trait Store for Module<T: Trait>;
 
@@ -93,6 +94,9 @@ decl_storage! {
 	// Percent by which the session must necessarily finish late before we early-exit the session.
 	pub BrokenPercentLate get(broken_percent_late): b"ses:broken_percent_late" => required T::Moment;
 
+	// New session is being forced is this entry exists; in which case, the boolean value is whether
+	// the new session should be considered a normal rotation (rewardable) or exceptional (slashable).
+	pub ForcingNewSession get(forcing_new_session): b"ses:forcing_new_session" => bool;
 	// Block at which the session length last changed.
 	LastLengthChange: b"ses:llc" => T::BlockNumber;
 	// The next key for a given validator.
@@ -127,8 +131,8 @@ impl<T: Trait> Module<T> {
 	}
 
 	/// Forces a new session.
-	fn force_new_session(normal_rotation: bool) -> Result {
-		Self::rotate_session(normal_rotation);
+	pub fn force_new_session(normal_rotation: bool) -> Result {
+		<ForcingNewSession<T>>::put(normal_rotation);
 		Ok(())
 	}
 
@@ -153,13 +157,16 @@ impl<T: Trait> Module<T> {
 		let block_number = <system::Module<T>>::block_number();
 		let is_final_block = ((block_number - Self::last_length_change()) % Self::length()).is_zero();
 		let broken_validation = Self::broken_validation();
-		if is_final_block || broken_validation {
-			Self::rotate_session(!broken_validation);
+		if let Some(normal_rotation) = Self::forcing_new_session() {
+			Self::rotate_session(normal_rotation, is_final_block);
+			<ForcingNewSession<T>>::kill();
+		} else if is_final_block || broken_validation {
+			Self::rotate_session(!broken_validation, is_final_block);
 		}
 	}
 
 	/// Move onto next session: register the new authority set.
-	pub fn rotate_session(normal_rotation: bool) {
+	pub fn rotate_session(normal_rotation: bool, is_final_block: bool) {
 		let now = <timestamp::Module<T>>::get();
 		let time_elapsed = now.clone() - Self::current_start();
 
@@ -168,9 +175,14 @@ impl<T: Trait> Module<T> {
 		<CurrentStart<T>>::put(now);
 
 		// Enact era length change.
-		if let Some(next_len) = <NextSessionLength<T>>::take() {
-			let block_number = <system::Module<T>>::block_number();
+		let len_changed = if let Some(next_len) = <NextSessionLength<T>>::take() {
 			<SessionLength<T>>::put(next_len);
+			true
+		} else {
+			false
+		};
+		if len_changed || !is_final_block {
+			let block_number = <system::Module<T>>::block_number();
 			<LastLengthChange<T>>::put(block_number);
 		}
 
@@ -354,6 +366,40 @@ mod tests {
 		});
 	}
 
+	#[test]
+	fn should_work_with_early_exit() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(1);
+			assert_ok!(Session::set_length(10));
+			assert_eq!(Session::blocks_remaining(), 1);
+			Session::check_rotate_session();
+
+			System::set_block_number(2);
+			assert_eq!(Session::blocks_remaining(), 0);
+			Session::check_rotate_session();
+			assert_eq!(Session::length(), 10);
+		
+			System::set_block_number(7);
+			assert_eq!(Session::current_index(), 1);
+			assert_eq!(Session::blocks_remaining(), 5);
+			assert_ok!(Session::force_new_session(false));
+			Session::check_rotate_session();
+
+			System::set_block_number(8);
+			assert_eq!(Session::current_index(), 2);
+			assert_eq!(Session::blocks_remaining(), 9);
+			Session::check_rotate_session();
+
+			System::set_block_number(17);
+			assert_eq!(Session::current_index(), 2);
+			assert_eq!(Session::blocks_remaining(), 0);
+			Session::check_rotate_session();
+
+			System::set_block_number(18);
+			assert_eq!(Session::current_index(), 3);
+		});
+	}
+
 	#[test]
 	fn session_length_change_should_work() {
 		with_externalities(&mut new_test_ext(), || {
diff --git a/substrate/substrate/runtime/staking/src/lib.rs b/substrate/substrate/runtime/staking/src/lib.rs
index ba71c6ec3f1e9d769775446f0a26f4e16f73824e..b0436c5fa30ae7135b6f852c06fd786d16ba867f 100644
--- a/substrate/substrate/runtime/staking/src/lib.rs
+++ b/substrate/substrate/runtime/staking/src/lib.rs
@@ -127,7 +127,7 @@ decl_module! {
 		fn set_sessions_per_era(new: T::BlockNumber) -> Result = 0;
 		fn set_bonding_duration(new: T::BlockNumber) -> Result = 1;
 		fn set_validator_count(new: u32) -> Result = 2;
-		fn force_new_era() -> Result = 3;
+		fn force_new_era(should_slash: bool) -> Result = 3;
 	}
 }
 
@@ -182,6 +182,9 @@ decl_storage! {
 	// The enumeration sets.
 	pub EnumSet get(enum_set): b"sta:enum_set" => default map [ T::AccountIndex => Vec<T::AccountId> ];
 
+	// We are forcing a new era.
+	pub ForcingNewEra get(forcing_new_era): b"sta:forcing_new_era" => ();
+
 	// The "free" balance of a given account.
 	//
 	// This is the only balance that matters in terms of most operations on tokens. It is
@@ -403,10 +406,11 @@ impl<T: Trait> Module<T> {
 		Ok(())
 	}
 
-	/// Force there to be a new era. This also forces a new session immediately after.
-	fn force_new_era() -> Result {
-		<session::Module<T>>::rotate_session(false);
-		Ok(())
+	/// Force there to be a new era. This also forces a new session immediately after by
+	/// setting `normal_rotation` to be false. Validators will get slashed.
+	fn force_new_era(should_slash: bool) -> Result {
+		<ForcingNewEra<T>>::put(());
+		<session::Module<T>>::force_new_session(!should_slash)
 	}
 
 	// PUBLIC MUTABLES (DANGEROUS)
@@ -621,7 +625,10 @@ impl<T: Trait> Module<T> {
 				}
 			}
 		}
-		if ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero() || !normal_rotation {
+		if <ForcingNewEra<T>>::take().is_some()
+			|| ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero()
+			|| !normal_rotation
+		{
 			Self::new_era();
 		}
 	}
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
index 6356848ee723a12466e9b961caff6fbf1ec72da0..d449d647e20ce85a16875b1fef48233682c9a83d 100644
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm
index 3dbbf9b9f3ba14c593bff23ac44e4cecbab87538..2fe9433d00c929e740644fdf11d292650cb2e7c9 100755
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ