From a0094e72e5780ee636339c99929b5945876549d1 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 25 Oct 2019 15:14:49 +0200 Subject: [PATCH] Add force_unstake to staking as root operation. (#3918) * Add force_unstake to staking as root operation. * Bump runtime * Tests * Update srml/staking/src/lib.rs Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- substrate/node/runtime/src/lib.rs | 2 +- substrate/srml/staking/src/lib.rs | 11 +++++++++++ substrate/srml/staking/src/tests.rs | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 6d596b197d..2c02a8be17 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 184, + spec_version: 185, impl_version: 185, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/srml/staking/src/lib.rs b/substrate/srml/staking/src/lib.rs index e7d7c073a1..e5c0277f57 100644 --- a/substrate/srml/staking/src/lib.rs +++ b/substrate/srml/staking/src/lib.rs @@ -993,6 +993,17 @@ decl_module! { ensure_root(origin)?; >::put(validators); } + + /// Force a current staker to become completely unstaked, immediately. + #[weight = sr_primitives::SimpleDispatchInfo::FreeOperational] + fn force_unstake(origin, stash: T::AccountId) { + ensure_root(origin)?; + + // remove the lock. + T::Currency::remove_lock(STAKING_ID, &stash); + // remove all staking-related information. + Self::kill_stash(&stash); + } } } diff --git a/substrate/srml/staking/src/tests.rs b/substrate/srml/staking/src/tests.rs index 2cb7981154..2b82176457 100644 --- a/substrate/srml/staking/src/tests.rs +++ b/substrate/srml/staking/src/tests.rs @@ -22,6 +22,28 @@ use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; use support::{assert_ok, assert_noop, assert_eq_uvec, traits::{Currency, ReservableCurrency}}; +#[test] +fn force_unstake_works() { + // Verifies initial conditions of mock + ExtBuilder::default().build().execute_with(|| { + // Account 11 is stashed and locked, and account 10 is the controller + assert_eq!(Staking::bonded(&11), Some(10)); + // Cant transfer + assert_noop!( + Balances::transfer(Origin::signed(11), 1, 10), + "account liquidity restrictions prevent withdrawal" + ); + // Force unstake requires root. + assert_noop!(Staking::force_unstake(Origin::signed(11), 11), "RequireRootOrigin"); + // We now force them to unstake + assert_ok!(Staking::force_unstake(Origin::ROOT, 11)); + // No longer bonded. + assert_eq!(Staking::bonded(&11), None); + // Transfer works. + assert_ok!(Balances::transfer(Origin::signed(11), 1, 10)); + }); +} + #[test] fn basic_setup_works() { // Verifies initial conditions of mock