Prechádzať zdrojové kódy

Merge pull request #1829 from shamil-gadelshin/separate_staking_handler

Move StakingHandler trait and implementation in the separate crate.
Bedeho Mender 4 rokov pred
rodič
commit
4181cf1e84
28 zmenil súbory, kde vykonal 453 pridanie a 550 odobranie
  1. 24 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 0 1
      runtime-modules/membership/src/lib.rs
  4. 0 41
      runtime-modules/membership/src/staking_handler.rs
  5. 1 0
      runtime-modules/proposals/codex/Cargo.toml
  6. 0 2
      runtime-modules/proposals/codex/src/tests/mock.rs
  7. 0 98
      runtime-modules/proposals/codex/src/tests/mock/staking_handler.rs
  8. 2 0
      runtime-modules/proposals/engine/Cargo.toml
  9. 1 1
      runtime-modules/proposals/engine/src/lib.rs
  10. 0 1
      runtime-modules/proposals/engine/src/tests/mock/mod.rs
  11. 0 98
      runtime-modules/proposals/engine/src/tests/mock/staking_handler.rs
  12. 1 0
      runtime-modules/service-discovery/Cargo.toml
  13. 0 2
      runtime-modules/service-discovery/src/mock.rs
  14. 0 98
      runtime-modules/service-discovery/src/mock/staking_handler.rs
  15. 32 0
      runtime-modules/staking-handler/Cargo.toml
  16. 54 1
      runtime-modules/staking-handler/src/lib.rs
  17. 106 0
      runtime-modules/staking-handler/src/mock.rs
  18. 222 0
      runtime-modules/staking-handler/src/test.rs
  19. 1 0
      runtime-modules/storage/Cargo.toml
  20. 0 2
      runtime-modules/storage/src/tests/mock.rs
  21. 0 98
      runtime-modules/storage/src/tests/mock/staking_handler.rs
  22. 2 0
      runtime-modules/working-group/Cargo.toml
  23. 1 1
      runtime-modules/working-group/src/lib.rs
  24. 0 2
      runtime-modules/working-group/src/tests/mock.rs
  25. 0 98
      runtime-modules/working-group/src/tests/mock/staking_handler.rs
  26. 2 0
      runtime/Cargo.toml
  27. 0 1
      runtime/src/integration/mod.rs
  28. 3 5
      runtime/src/lib.rs

+ 24 - 0
Cargo.lock

@@ -2423,6 +2423,7 @@ dependencies = [
  "sp-std",
  "sp-transaction-pool",
  "sp-version",
+ "staking-handler",
  "strum 0.19.5",
  "substrate-wasm-builder-runner",
 ]
@@ -4059,6 +4060,7 @@ dependencies = [
  "sp-runtime",
  "sp-staking",
  "sp-std",
+ "staking-handler",
  "strum 0.19.5",
 ]
 
@@ -4098,6 +4100,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]
@@ -4150,6 +4153,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]
@@ -4259,6 +4263,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]
@@ -4423,6 +4428,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]
@@ -7362,6 +7368,24 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
+[[package]]
+name = "staking-handler"
+version = "1.0.0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "pallet-balances",
+ "pallet-common",
+ "pallet-membership",
+ "pallet-timestamp",
+ "parity-scale-codec",
+ "sp-arithmetic",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
 [[package]]
 name = "static_assertions"
 version = "1.1.0"

+ 1 - 0
Cargo.toml

@@ -21,6 +21,7 @@ members = [
 	"runtime-modules/working-group",
 	"runtime-modules/content-directory",
 	"runtime-modules/constitution",
+	"runtime-modules/staking-handler",
 	"node",
 	"utils/chain-spec-builder/"
 ]

+ 0 - 1
runtime-modules/membership/src/lib.rs

@@ -7,7 +7,6 @@
 
 pub mod genesis;
 pub(crate) mod mock;
-pub mod staking_handler;
 mod tests;
 
 use codec::{Codec, Decode, Encode};

+ 0 - 41
runtime-modules/membership/src/staking_handler.rs

@@ -1,41 +0,0 @@
-use frame_support::dispatch::DispatchResult;
-
-// Type alias for member id.
-pub type MemberId<T> = <T as crate::Trait>::MemberId;
-
-/// Balance alias for `balances` module.
-pub type BalanceOf<T> = <T as balances::Trait>::Balance;
-
-/// Defines abstract staking handler to manage user stakes for different activities
-/// like adding a proposal. Implementation should use built-in LockableCurrency
-/// and LockIdentifier to lock balance consistently with pallet_staking.
-pub trait StakingHandler<T: frame_system::Trait + crate::Trait + balances::Trait> {
-    /// Locks the specified balance on the account using specific lock identifier.
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>);
-
-    /// Removes the specified lock on the account.
-    fn unlock(account_id: &T::AccountId);
-
-    /// Slash the specified balance on the account using specific lock identifier.
-    /// No limits, no actions on zero stake.
-    /// If slashing balance greater than the existing stake - stake is slashed to zero.
-    /// Returns actually slashed balance.
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T>;
-
-    /// Sets the new stake to a given amount.
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult;
-
-    /// Verifies that staking account bound to the member.
-    fn is_member_staking_account(member_id: &MemberId<T>, account_id: &T::AccountId) -> bool;
-
-    /// Verifies that there no conflicting stakes on the staking account.
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool;
-
-    /// Verifies that staking account balance is sufficient for staking.
-    /// During the balance check we should consider already locked stake. Effective balance to check
-    /// is 'already locked funds' + 'usable funds'.
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool;
-
-    /// Returns the current stake on the account.
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T>;
-}

+ 1 - 0
runtime-modules/proposals/codex/Cargo.toml

@@ -33,6 +33,7 @@ sp-staking = { package = 'sp-staking', default-features = false, git = 'https://
 pallet-staking-reward-curve = { package = 'pallet-staking-reward-curve', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 recurring-rewards = { package = 'pallet-recurring-reward', default-features = false, path = '../../recurring-reward'}
 strum = {version = "0.19", default-features = false}
+staking-handler = { package = 'staking-handler', default-features = false, path = '../../staking-handler'}
 
 [features]
 default = ['std']

+ 0 - 2
runtime-modules/proposals/codex/src/tests/mock/mod.rs → runtime-modules/proposals/codex/src/tests/mock.rs

@@ -16,8 +16,6 @@ use crate::{ProposalDetailsOf, ProposalEncoder, ProposalParameters};
 use proposals_engine::VotersParameters;
 use sp_runtime::testing::TestXt;
 
-mod staking_handler;
-
 impl_outer_origin! {
     pub enum Origin for Test {}
 }

+ 0 - 98
runtime-modules/proposals/codex/src/tests/mock/staking_handler.rs

@@ -1,98 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
-use sp_arithmetic::traits::Zero;
-use sp_std::marker::PhantomData;
-
-/// Implementation of the StakingHandler.
-pub struct StakingManager<
-    T: frame_system::Trait + membership::Trait + balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<T: frame_system::Trait + membership::Trait + balances::Trait, LockId: Get<LockIdentifier>>
-    StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <balances::Module<T>>::set_lock(LockId::get(), &account_id, amount, WithdrawReasons::all())
-    }
-
-    fn unlock(account_id: &T::AccountId) {
-        T::Currency::remove_lock(LockId::get(), &account_id);
-    }
-
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        let mut actually_slashed_balance = Default::default();
-        if let Some(existing_lock) = existing_lock {
-            Self::unlock(&account_id);
-
-            let mut slashable_amount = existing_lock.amount;
-            if let Some(amount) = amount {
-                if existing_lock.amount > amount {
-                    let new_amount = existing_lock.amount - amount;
-                    Self::lock(&account_id, new_amount);
-
-                    slashable_amount = amount;
-                }
-            }
-
-            let _ = <balances::Module<T>>::slash(&account_id, slashable_amount);
-
-            actually_slashed_balance = slashable_amount
-        }
-
-        actually_slashed_balance
-    }
-
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult {
-        let current_stake = Self::current_stake(account_id);
-
-        //Unlock previous stake if its not zero.
-        if current_stake > Zero::zero() {
-            Self::unlock(account_id);
-        }
-
-        if !Self::is_enough_balance_for_stake(account_id, new_stake) {
-            //Restore previous stake if its not zero.
-            if current_stake > Zero::zero() {
-                Self::lock(account_id, current_stake);
-            }
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
-
-        Self::lock(account_id, new_stake);
-
-        Ok(())
-    }
-
-    fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
-        true
-    }
-
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.is_none()
-    }
-
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool {
-        <balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.map_or(Zero::zero(), |lock| lock.amount)
-    }
-}

+ 2 - 0
runtime-modules/proposals/engine/Cargo.toml

@@ -16,6 +16,7 @@ sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://
 balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 membership = { package = 'pallet-membership', default-features = false, path = '../../membership'}
 common = { package = 'pallet-common', default-features = false, path = '../../common'}
+staking-handler = { package = 'staking-handler', default-features = false, path = '../../staking-handler'}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
@@ -35,4 +36,5 @@ std = [
 	'balances/std',
     'membership/std',
     'common/std',
+    'staking-handler/std',
 ]

+ 1 - 1
runtime-modules/proposals/engine/src/lib.rs

@@ -134,7 +134,7 @@ use sp_arithmetic::traits::Zero;
 use sp_std::vec::Vec;
 
 use common::origin::ActorOriginValidator;
-use membership::staking_handler::StakingHandler;
+use staking_handler::StakingHandler;
 
 /// Proposals engine trait.
 pub trait Trait:

+ 0 - 1
runtime-modules/proposals/engine/src/tests/mock/mod.rs

@@ -17,7 +17,6 @@ use sp_runtime::{
 };
 
 pub(crate) mod proposals;
-pub(crate) mod staking_handler;
 
 use crate::ProposalObserver;
 pub use proposals::*;

+ 0 - 98
runtime-modules/proposals/engine/src/tests/mock/staking_handler.rs

@@ -1,98 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
-use sp_arithmetic::traits::Zero;
-use sp_std::marker::PhantomData;
-
-/// Implementation of the StakingHandler.
-pub struct StakingManager<
-    T: frame_system::Trait + membership::Trait + balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<T: frame_system::Trait + membership::Trait + balances::Trait, LockId: Get<LockIdentifier>>
-    StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <balances::Module<T>>::set_lock(LockId::get(), &account_id, amount, WithdrawReasons::all())
-    }
-
-    fn unlock(account_id: &T::AccountId) {
-        T::Currency::remove_lock(LockId::get(), &account_id);
-    }
-
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        let mut actually_slashed_balance = Default::default();
-        if let Some(existing_lock) = existing_lock {
-            Self::unlock(&account_id);
-
-            let mut slashable_amount = existing_lock.amount;
-            if let Some(amount) = amount {
-                if existing_lock.amount > amount {
-                    let new_amount = existing_lock.amount - amount;
-                    Self::lock(&account_id, new_amount);
-
-                    slashable_amount = amount;
-                }
-            }
-
-            let _ = <balances::Module<T>>::slash(&account_id, slashable_amount);
-
-            actually_slashed_balance = slashable_amount
-        }
-
-        actually_slashed_balance
-    }
-
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult {
-        let current_stake = Self::current_stake(account_id);
-
-        //Unlock previous stake if its not zero.
-        if current_stake > Zero::zero() {
-            Self::unlock(account_id);
-        }
-
-        if !Self::is_enough_balance_for_stake(account_id, new_stake) {
-            //Restore previous stake if its not zero.
-            if current_stake > Zero::zero() {
-                Self::lock(account_id, current_stake);
-            }
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
-
-        Self::lock(account_id, new_stake);
-
-        Ok(())
-    }
-
-    fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
-        true
-    }
-
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.is_none()
-    }
-
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool {
-        <balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.map_or(Zero::zero(), |lock| lock.amount)
-    }
-}

+ 1 - 0
runtime-modules/service-discovery/Cargo.toml

@@ -25,6 +25,7 @@ hiring = { package = 'pallet-hiring', default-features = false, path = '../hirin
 minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
 recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
 common = { package = 'pallet-common', default-features = false, path = '../common'}
+staking-handler = { package = 'staking-handler', default-features = false, path = '../staking-handler'}
 
 [features]
 default = ['std']

+ 0 - 2
runtime-modules/service-discovery/src/mock/mod.rs → runtime-modules/service-discovery/src/mock.rs

@@ -13,8 +13,6 @@ use sp_runtime::{
 // The storage working group instance alias.
 pub type StorageWorkingGroupInstance = working_group::Instance2;
 
-mod staking_handler;
-
 mod working_group_mod {
     pub use super::StorageWorkingGroupInstance;
     pub use working_group::Event;

+ 0 - 98
runtime-modules/service-discovery/src/mock/staking_handler.rs

@@ -1,98 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
-use sp_arithmetic::traits::Zero;
-use sp_std::marker::PhantomData;
-
-/// Implementation of the StakingHandler.
-pub struct StakingManager<
-    T: frame_system::Trait + membership::Trait + balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<T: frame_system::Trait + membership::Trait + balances::Trait, LockId: Get<LockIdentifier>>
-    StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <balances::Module<T>>::set_lock(LockId::get(), &account_id, amount, WithdrawReasons::all())
-    }
-
-    fn unlock(account_id: &T::AccountId) {
-        T::Currency::remove_lock(LockId::get(), &account_id);
-    }
-
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        let mut actually_slashed_balance = Default::default();
-        if let Some(existing_lock) = existing_lock {
-            Self::unlock(&account_id);
-
-            let mut slashable_amount = existing_lock.amount;
-            if let Some(amount) = amount {
-                if existing_lock.amount > amount {
-                    let new_amount = existing_lock.amount - amount;
-                    Self::lock(&account_id, new_amount);
-
-                    slashable_amount = amount;
-                }
-            }
-
-            let _ = <balances::Module<T>>::slash(&account_id, slashable_amount);
-
-            actually_slashed_balance = slashable_amount
-        }
-
-        actually_slashed_balance
-    }
-
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult {
-        let current_stake = Self::current_stake(account_id);
-
-        //Unlock previous stake if its not zero.
-        if current_stake > Zero::zero() {
-            Self::unlock(account_id);
-        }
-
-        if !Self::is_enough_balance_for_stake(account_id, new_stake) {
-            //Restore previous stake if its not zero.
-            if current_stake > Zero::zero() {
-                Self::lock(account_id, current_stake);
-            }
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
-
-        Self::lock(account_id, new_stake);
-
-        Ok(())
-    }
-
-    fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
-        true
-    }
-
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.is_none()
-    }
-
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool {
-        <balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.map_or(Zero::zero(), |lock| lock.amount)
-    }
-}

+ 32 - 0
runtime-modules/staking-handler/Cargo.toml

@@ -0,0 +1,32 @@
+[package]
+name = 'staking-handler'
+version = '1.0.0'
+authors = ['Joystream contributors']
+edition = '2018'
+
+[dependencies]
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+frame-system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+pallet-balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+
+[features]
+default = ['std']
+std = [
+    'sp-std/std',
+    'frame-support/std',
+    'frame-system/std',
+    'sp-arithmetic/std',
+    'pallet-balances/std',
+    'membership/std',
+]

+ 54 - 1
runtime/src/integration/staking_handler.rs → runtime-modules/staking-handler/src/lib.rs

@@ -1,9 +1,61 @@
+//! Staking handler module.
+//! Contains StakingHandler trait and its implementation - StakingManager.
+//! StakingHandler is responsible for staking logic in the Joystream runtime:
+//! https://joystream.gitbook.io/joystream-handbook/key-concepts/stakingmock.rs
+
+// Ensure we're `no_std` when compiling for Wasm.
+#![cfg_attr(not(feature = "std"), no_std)]
+
 use frame_support::dispatch::{DispatchError, DispatchResult};
 use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
 use sp_arithmetic::traits::Zero;
 use sp_std::marker::PhantomData;
 
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod test;
+
+/// Type alias for member id.
+pub type MemberId<T> = <T as membership::Trait>::MemberId;
+
+/// Balance alias for `balances` module.
+pub type BalanceOf<T> = <T as pallet_balances::Trait>::Balance;
+
+/// Defines abstract staking handler to manage user stakes for different activities
+/// like adding a proposal. Implementation should use built-in LockableCurrency
+/// and LockIdentifier to lock balance consistently with pallet_staking.
+pub trait StakingHandler<T: frame_system::Trait + membership::Trait + pallet_balances::Trait> {
+    /// Locks the specified balance on the account using specific lock identifier.
+    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>);
+
+    /// Removes the specified lock on the account.
+    fn unlock(account_id: &T::AccountId);
+
+    /// Slash the specified balance on the account using specific lock identifier.
+    /// No limits, no actions on zero stake.
+    /// If slashing balance greater than the existing stake - stake is slashed to zero.
+    /// Returns actually slashed balance.
+    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T>;
+
+    /// Sets the new stake to a given amount.
+    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult;
+
+    /// Verifies that staking account bound to the member.
+    fn is_member_staking_account(member_id: &MemberId<T>, account_id: &T::AccountId) -> bool;
+
+    /// Verifies that there no conflicting stakes on the staking account.
+    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool;
+
+    /// Verifies that staking account balance is sufficient for staking.
+    /// During the balance check we should consider already locked stake. Effective balance to check
+    /// is 'already locked funds' + 'usable funds'.
+    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool;
+
+    /// Returns the current stake on the account.
+    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T>;
+}
+
 /// Implementation of the StakingHandler.
 pub struct StakingManager<
     T: frame_system::Trait + membership::Trait + pallet_balances::Trait,
@@ -79,6 +131,7 @@ impl<
         Ok(())
     }
 
+    // Membership support for staking accounts required.
     fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
         true
     }

+ 106 - 0
runtime-modules/staking-handler/src/mock.rs

@@ -0,0 +1,106 @@
+use frame_support::{impl_outer_origin, parameter_types};
+use frame_system;
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
+};
+
+impl_outer_origin! {
+    pub enum Origin for Test {}
+}
+
+mod membership_mod {
+    pub use membership::Event;
+}
+
+parameter_types! {
+    pub const BlockHashCount: u64 = 250;
+    pub const MaximumBlockWeight: u32 = 1024;
+    pub const MaximumBlockLength: u32 = 2 * 1024;
+    pub const AvailableBlockRatio: Perbill = Perbill::one();
+    pub const MinimumPeriod: u64 = 5;
+    pub const StakePoolId: [u8; 8] = *b"joystake";
+    pub const ExistentialDeposit: u32 = 0;
+}
+
+// Workaround for https://github.com/rust-lang/rust/issues/26925 - remove when sorted.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct Test;
+
+impl frame_system::Trait for Test {
+    type BaseCallFilter = ();
+    type Origin = Origin;
+    type Call = ();
+    type Index = u64;
+    type BlockNumber = u64;
+    type Hash = H256;
+    type Hashing = BlakeTwo256;
+    type AccountId = u64;
+    type Lookup = IdentityLookup<Self::AccountId>;
+    type Header = Header;
+    type Event = ();
+    type BlockHashCount = BlockHashCount;
+    type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
+    type MaximumBlockLength = MaximumBlockLength;
+    type AvailableBlockRatio = AvailableBlockRatio;
+    type Version = ();
+    type PalletInfo = ();
+    type AccountData = pallet_balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
+    type SystemWeightInfo = ();
+}
+
+impl pallet_balances::Trait for Test {
+    type Balance = u64;
+    type DustRemoval = ();
+    type Event = ();
+    type ExistentialDeposit = ExistentialDeposit;
+    type AccountStore = System;
+    type WeightInfo = ();
+    type MaxLocks = ();
+}
+
+impl membership::Trait for Test {
+    type Event = ();
+    type MemberId = u64;
+    type PaidTermId = u64;
+    type SubscriptionId = u64;
+    type ActorId = u64;
+}
+
+impl common::currency::GovernanceCurrency for Test {
+    type Currency = Balances;
+}
+
+impl pallet_timestamp::Trait for Test {
+    type Moment = u64;
+    type OnTimestampSet = ();
+    type MinimumPeriod = MinimumPeriod;
+    type WeightInfo = ();
+}
+
+pub type Balances = pallet_balances::Module<Test>;
+pub type System = frame_system::Module<Test>;
+pub type TestStakingManager = crate::StakingManager<Test, LockId>;
+
+parameter_types! {
+    pub const RewardPeriod: u32 = 2;
+    pub const MaxWorkerNumberLimit: u32 = 3;
+    pub const MinUnstakingPeriodLimit: u64 = 3;
+    pub const LockId: [u8; 8] = [1; 8];
+}
+
+pub fn build_test_externalities() -> sp_io::TestExternalities {
+    let t = frame_system::GenesisConfig::default()
+        .build_storage::<Test>()
+        .unwrap();
+
+    t.into()
+}

+ 222 - 0
runtime-modules/staking-handler/src/test.rs

@@ -0,0 +1,222 @@
+use super::mock::*;
+use crate::*;
+
+use frame_support::traits::Currency;
+
+pub(crate) fn increase_total_balance_issuance_using_account_id(account_id: u64, balance: u64) {
+    let initial_balance = Balances::total_issuance();
+    {
+        let _ = <Test as common::currency::GovernanceCurrency>::Currency::deposit_creating(
+            &account_id,
+            balance,
+        );
+    }
+    assert_eq!(Balances::total_issuance(), initial_balance + balance);
+}
+
+#[test]
+fn lock_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+    });
+}
+
+#[test]
+fn unlock_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        TestStakingManager::unlock(&account_id);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount);
+    });
+}
+
+#[test]
+fn slash_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        let slash_amount = 50;
+        TestStakingManager::slash(&account_id, Some(slash_amount));
+        TestStakingManager::unlock(&account_id);
+
+        assert_eq!(
+            Balances::usable_balance(&account_id),
+            total_amount - slash_amount
+        );
+    });
+}
+
+#[test]
+fn slash_full_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        TestStakingManager::slash(&account_id, None);
+        TestStakingManager::unlock(&account_id);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        // Lock was removed.
+        assert!(TestStakingManager::is_account_free_of_conflicting_stakes(
+            &account_id
+        ));
+    });
+}
+
+#[test]
+fn slash_down_to_zero_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        TestStakingManager::slash(&account_id, Some(stake));
+        TestStakingManager::unlock(&account_id);
+
+        assert_eq!(Balances::usable_balance(&account_id), total_amount - stake);
+
+        // Lock was removed.
+        assert!(TestStakingManager::is_account_free_of_conflicting_stakes(
+            &account_id
+        ));
+    });
+}
+
+#[test]
+fn current_stake_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert_eq!(TestStakingManager::current_stake(&account_id), stake);
+    });
+}
+
+#[test]
+fn is_account_free_of_conflicting_stakes_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+        assert!(TestStakingManager::is_account_free_of_conflicting_stakes(
+            &account_id
+        ));
+
+        TestStakingManager::lock(&account_id, stake);
+
+        assert!(!TestStakingManager::is_account_free_of_conflicting_stakes(
+            &account_id
+        ));
+    });
+}
+
+#[test]
+fn is_enough_balance_for_stake_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 100;
+
+        assert!(!TestStakingManager::is_enough_balance_for_stake(
+            &account_id,
+            stake
+        ));
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        assert!(TestStakingManager::is_enough_balance_for_stake(
+            &account_id,
+            stake
+        ));
+    });
+}
+
+// Test stub: not implemented yet.
+#[ignore]
+#[test]
+fn is_member_staking_account_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let member_id = 1;
+
+        assert!(TestStakingManager::is_member_staking_account(
+            &member_id,
+            &account_id
+        ));
+    });
+}
+
+#[test]
+fn set_stake_succeeds() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 300;
+        let stake = 300;
+        let invalid_stake = 600;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        assert_eq!(
+            TestStakingManager::set_stake(&account_id, stake),
+            DispatchResult::Ok(())
+        );
+
+        assert_eq!(TestStakingManager::current_stake(&account_id), stake);
+
+        assert_eq!(
+            TestStakingManager::set_stake(&account_id, invalid_stake),
+            DispatchResult::Err(DispatchError::Other("Not enough balance for a new stake."))
+        );
+
+        assert_eq!(TestStakingManager::current_stake(&account_id), stake);
+    });
+}

+ 1 - 0
runtime-modules/storage/Cargo.toml

@@ -25,6 +25,7 @@ stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
 hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
 minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
 recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+staking-handler = { package = 'staking-handler', default-features = false, path = '../staking-handler'}
 
 [features]
 default = ['std']

+ 0 - 2
runtime-modules/storage/src/tests/mock/mod.rs → runtime-modules/storage/src/tests/mock.rs

@@ -17,8 +17,6 @@ pub use crate::{data_directory, data_object_storage_registry, data_object_type_r
 use common::currency::GovernanceCurrency;
 use membership;
 
-mod staking_handler;
-
 mod working_group_mod {
     pub use super::StorageWorkingGroupInstance;
     pub use working_group::Event;

+ 0 - 98
runtime-modules/storage/src/tests/mock/staking_handler.rs

@@ -1,98 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
-use sp_arithmetic::traits::Zero;
-use sp_std::marker::PhantomData;
-
-/// Implementation of the StakingHandler.
-pub struct StakingManager<
-    T: frame_system::Trait + membership::Trait + balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<T: frame_system::Trait + membership::Trait + balances::Trait, LockId: Get<LockIdentifier>>
-    StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <balances::Module<T>>::set_lock(LockId::get(), &account_id, amount, WithdrawReasons::all())
-    }
-
-    fn unlock(account_id: &T::AccountId) {
-        T::Currency::remove_lock(LockId::get(), &account_id);
-    }
-
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        let mut actually_slashed_balance = Default::default();
-        if let Some(existing_lock) = existing_lock {
-            Self::unlock(&account_id);
-
-            let mut slashable_amount = existing_lock.amount;
-            if let Some(amount) = amount {
-                if existing_lock.amount > amount {
-                    let new_amount = existing_lock.amount - amount;
-                    Self::lock(&account_id, new_amount);
-
-                    slashable_amount = amount;
-                }
-            }
-
-            let _ = <balances::Module<T>>::slash(&account_id, slashable_amount);
-
-            actually_slashed_balance = slashable_amount
-        }
-
-        actually_slashed_balance
-    }
-
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult {
-        let current_stake = Self::current_stake(account_id);
-
-        //Unlock previous stake if its not zero.
-        if current_stake > Zero::zero() {
-            Self::unlock(account_id);
-        }
-
-        if !Self::is_enough_balance_for_stake(account_id, new_stake) {
-            //Restore previous stake if its not zero.
-            if current_stake > Zero::zero() {
-                Self::lock(account_id, current_stake);
-            }
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
-
-        Self::lock(account_id, new_stake);
-
-        Ok(())
-    }
-
-    fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
-        true
-    }
-
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.is_none()
-    }
-
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool {
-        <balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.map_or(Zero::zero(), |lock| lock.amount)
-    }
-}

+ 2 - 0
runtime-modules/working-group/Cargo.toml

@@ -16,6 +16,7 @@ common = { package = 'pallet-common', default-features = false, path = '../commo
 membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
 balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 frame-benchmarking = { package = 'frame-benchmarking', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca', optional = true}
+staking-handler = { package = 'staking-handler', default-features = false, path = '../staking-handler'}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
@@ -36,4 +37,5 @@ std = [
 	'common/std',
 	'membership/std',
 	'balances/std',
+	'staking-handler/std',
 ]

+ 1 - 1
runtime-modules/working-group/src/lib.rs

@@ -56,7 +56,7 @@ use types::{ApplicationInfo, WorkerInfo};
 pub use checks::{ensure_origin_is_active_leader, ensure_worker_exists, ensure_worker_signed};
 
 use common::origin::ActorOriginValidator;
-use membership::staking_handler::StakingHandler;
+use staking_handler::StakingHandler;
 
 /// The _Group_ main _Trait_
 pub trait Trait<I: Instance = DefaultInstance>:

+ 0 - 2
runtime-modules/working-group/src/tests/mock/mod.rs → runtime-modules/working-group/src/tests/mock.rs

@@ -14,8 +14,6 @@ impl_outer_origin! {
     pub enum Origin for Test {}
 }
 
-mod staking_handler;
-
 mod working_group {
     pub use crate::Event;
 }

+ 0 - 98
runtime-modules/working-group/src/tests/mock/staking_handler.rs

@@ -1,98 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
-use membership::staking_handler::{BalanceOf, MemberId, StakingHandler};
-use sp_arithmetic::traits::Zero;
-use sp_std::marker::PhantomData;
-
-/// Implementation of the StakingHandler.
-pub struct StakingManager<
-    T: frame_system::Trait + membership::Trait + balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<T: frame_system::Trait + membership::Trait + balances::Trait, LockId: Get<LockIdentifier>>
-    StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <balances::Module<T>>::set_lock(LockId::get(), &account_id, amount, WithdrawReasons::all())
-    }
-
-    fn unlock(account_id: &T::AccountId) {
-        T::Currency::remove_lock(LockId::get(), &account_id);
-    }
-
-    fn slash(account_id: &T::AccountId, amount: Option<BalanceOf<T>>) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        let mut actually_slashed_balance = Default::default();
-        if let Some(existing_lock) = existing_lock {
-            Self::unlock(&account_id);
-
-            let mut slashable_amount = existing_lock.amount;
-            if let Some(amount) = amount {
-                if existing_lock.amount > amount {
-                    let new_amount = existing_lock.amount - amount;
-                    Self::lock(&account_id, new_amount);
-
-                    slashable_amount = amount;
-                }
-            }
-
-            let _ = <balances::Module<T>>::slash(&account_id, slashable_amount);
-
-            actually_slashed_balance = slashable_amount
-        }
-
-        actually_slashed_balance
-    }
-
-    fn set_stake(account_id: &T::AccountId, new_stake: BalanceOf<T>) -> DispatchResult {
-        let current_stake = Self::current_stake(account_id);
-
-        //Unlock previous stake if its not zero.
-        if current_stake > Zero::zero() {
-            Self::unlock(account_id);
-        }
-
-        if !Self::is_enough_balance_for_stake(account_id, new_stake) {
-            //Restore previous stake if its not zero.
-            if current_stake > Zero::zero() {
-                Self::lock(account_id, current_stake);
-            }
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
-
-        Self::lock(account_id, new_stake);
-
-        Ok(())
-    }
-
-    fn is_member_staking_account(_member_id: &MemberId<T>, _account_id: &T::AccountId) -> bool {
-        true
-    }
-
-    fn is_account_free_of_conflicting_stakes(account_id: &T::AccountId) -> bool {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.is_none()
-    }
-
-    fn is_enough_balance_for_stake(account_id: &T::AccountId, amount: BalanceOf<T>) -> bool {
-        <balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <balances::Module<T>>::locks(&account_id);
-
-        let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-        existing_lock.map_or(Zero::zero(), |lock| lock.amount)
-    }
-}

+ 2 - 0
runtime/Cargo.toml

@@ -82,6 +82,7 @@ proposals-discussion = { package = 'pallet-proposals-discussion', default-featur
 proposals-codex = { package = 'pallet-proposals-codex', default-features = false, path = '../runtime-modules/proposals/codex'}
 content-directory = { package = 'pallet-content-directory', default-features = false, path = '../runtime-modules/content-directory' }
 constitution = { package = 'pallet-constitution', default-features = false, path = '../runtime-modules/constitution' }
+staking-handler = { package = 'staking-handler', default-features = false, path = '../runtime-modules/staking-handler'}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
@@ -160,6 +161,7 @@ std = [
     'proposals-codex/std',
     'content-directory/std',
     'constitution/std',
+    'staking-handler/std',
 ]
 runtime-benchmarks = [
     "frame-system/runtime-benchmarks",

+ 0 - 1
runtime/src/integration/mod.rs

@@ -2,7 +2,6 @@ pub mod content_directory;
 pub mod content_working_group;
 pub mod forum;
 pub mod proposals;
-pub mod staking_handler;
 pub mod storage;
 pub mod transactions;
 pub mod versioned_store_permissions;

+ 3 - 5
runtime/src/lib.rs

@@ -574,8 +574,7 @@ parameter_types! {
 impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-    type StakingHandler =
-        integration::staking_handler::StakingManager<Self, StorageWorkingGroupLockId>;
+    type StakingHandler = staking_handler::StakingManager<Self, StorageWorkingGroupLockId>;
     type MemberOriginValidator = MembershipOriginValidator<Self>;
     type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
     type RewardPeriod = StorageWorkingGroupRewardPeriod;
@@ -584,8 +583,7 @@ impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
 impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-    type StakingHandler =
-        integration::staking_handler::StakingManager<Self, ContentWorkingGroupLockId>;
+    type StakingHandler = staking_handler::StakingManager<Self, ContentWorkingGroupLockId>;
     type MemberOriginValidator = MembershipOriginValidator<Self>;
     type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
     type RewardPeriod = ContentWorkingGroupRewardPeriod;
@@ -610,7 +608,7 @@ impl proposals_engine::Trait for Runtime {
     type VoterOriginValidator = CouncilManager<Self>;
     type TotalVotersCounter = CouncilManager<Self>;
     type ProposalId = u32;
-    type StakingHandler = integration::staking_handler::StakingManager<Self, ProposalsLockId>;
+    type StakingHandler = staking_handler::StakingManager<Self, ProposalsLockId>;
     type CancellationFee = ProposalCancellationFee;
     type RejectionFee = ProposalRejectionFee;
     type TitleMaxLength = ProposalTitleMaxLength;