diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 353df1156ad7d..b51ad28c97b97 100644 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index 604500c98b590..3b0e6e0b0f864 100755 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ diff --git a/polkadot/runtime/src/lib.rs b/polkadot/runtime/src/lib.rs index 7c366e30e7a8a..9e47ad54e792e 100644 --- a/polkadot/runtime/src/lib.rs +++ b/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/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 72aa4463a3ed7..b04b146ea1c7b 100644 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index c50030ecaadf3..fa48cfe95fb57 100755 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 790eb1909f21d..bd930a1e4cc7a 100644 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index 51a27fe0197ad..15312bde3b2a0 100755 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/runtime/session/src/lib.rs b/substrate/runtime/session/src/lib.rs index 6e320a73575f9..8e53428de63a0 100644 --- a/substrate/runtime/session/src/lib.rs +++ b/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; @@ -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 Module { } /// 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 { + >::put(normal_rotation); Ok(()) } @@ -153,13 +157,16 @@ impl Module { let block_number = >::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); + >::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 = >::get(); let time_elapsed = now.clone() - Self::current_start(); @@ -168,9 +175,14 @@ impl Module { >::put(now); // Enact era length change. - if let Some(next_len) = >::take() { - let block_number = >::block_number(); + let len_changed = if let Some(next_len) = >::take() { >::put(next_len); + true + } else { + false + }; + if len_changed || !is_final_block { + let block_number = >::block_number(); >::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/runtime/staking/src/lib.rs b/substrate/runtime/staking/src/lib.rs index ba71c6ec3f1e9..b0436c5fa30ae 100644 --- a/substrate/runtime/staking/src/lib.rs +++ b/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 ]; + // 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 Module { Ok(()) } - /// Force there to be a new era. This also forces a new session immediately after. - fn force_new_era() -> Result { - >::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 { + >::put(()); + >::force_new_session(!should_slash) } // PUBLIC MUTABLES (DANGEROUS) @@ -621,7 +625,10 @@ impl Module { } } } - if ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero() || !normal_rotation { + if >::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/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 6356848ee723a..d449d647e20ce 100644 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index 3dbbf9b9f3ba1..2fe9433d00c92 100755 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ