Browse Source

runtime: Migrate to separate staking-handler crate.

Shamil Gadelshin 4 years ago
parent
commit
3868b1246e

+ 3 - 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",
 ]
@@ -4098,6 +4099,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]
@@ -4423,6 +4425,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std",
+ "staking-handler",
 ]
 
 [[package]]

+ 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>;
-}

+ 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:

+ 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>:

+ 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;

+ 0 - 105
runtime/src/integration/staking_handler.rs

@@ -1,105 +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 + pallet_balances::Trait,
-    LockId: Get<LockIdentifier>,
-> {
-    trait_marker: PhantomData<T>,
-    lock_id_marker: PhantomData<LockId>,
-}
-
-impl<
-        T: frame_system::Trait + membership::Trait + pallet_balances::Trait,
-        LockId: Get<LockIdentifier>,
-    > StakingHandler<T> for StakingManager<T, LockId>
-{
-    fn lock(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        <pallet_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 = <pallet_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 _ = <pallet_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 = <pallet_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 {
-        <pallet_balances::Module<T>>::usable_balance(account_id) >= amount
-    }
-
-    fn current_stake(account_id: &T::AccountId) -> BalanceOf<T> {
-        let locks = <pallet_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)
-    }
-}

+ 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;