浏览代码

Merge pull request #3191 from shamil-gadelshin/olympia-fix-staking

Olympia. Runtime. Fix staking bug in the staking-handler pallet.
Lezek123 3 年之前
父节点
当前提交
419be1eec7

+ 6 - 6
runtime-modules/staking-handler/src/lib.rs

@@ -7,6 +7,7 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
 use frame_support::dispatch::{DispatchError, DispatchResult};
+use frame_support::ensure;
 use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons};
 use sp_arithmetic::traits::Zero;
 use sp_std::marker::PhantomData;
@@ -152,11 +153,10 @@ impl<
             return Ok(());
         }
 
-        let usable_balance = <pallet_balances::Module<T>>::usable_balance(account_id);
-
-        if new_stake > current_stake + usable_balance {
-            return Err(DispatchError::Other("Not enough balance for a new stake."));
-        }
+        ensure!(
+            Self::is_enough_balance_for_stake(account_id, new_stake),
+            DispatchError::Other("Not enough balance for a new stake.")
+        );
 
         Self::lock(account_id, new_stake);
 
@@ -175,7 +175,7 @@ impl<
         account_id: &<T as frame_system::Trait>::AccountId,
         amount: <T as pallet_balances::Trait>::Balance,
     ) -> bool {
-        <pallet_balances::Module<T>>::usable_balance(account_id) >= amount
+        <pallet_balances::Module<T>>::free_balance(account_id) >= amount
     }
 
     fn lock_id() -> LockIdentifier {

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

@@ -91,12 +91,14 @@ impl pallet_timestamp::Trait for Test {
 pub type Balances = pallet_balances::Module<Test>;
 pub type System = frame_system::Module<Test>;
 pub type TestStakingManager = crate::StakingManager<Test, LockId>;
+pub type TestStakingManager2 = crate::StakingManager<Test, LockId2>;
 
 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 const LockId2: [u8; 8] = [2; 8];
 }
 
 pub fn build_test_externalities() -> sp_io::TestExternalities {

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

@@ -200,3 +200,37 @@ fn set_stake_succeeds() {
         assert_eq!(TestStakingManager::current_stake(&account_id), stake);
     });
 }
+
+#[test]
+fn is_enough_balance_for_stake_succeeds_with_two_stakes() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 200;
+        let stake1 = 100;
+        let stake2 = 200;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        assert!(TestStakingManager::set_stake(&account_id, stake1).is_ok());
+
+        assert!(TestStakingManager2::is_enough_balance_for_stake(
+            &account_id,
+            stake2
+        ));
+    });
+}
+
+#[test]
+fn set_stake_succeeds_with_two_stakes() {
+    build_test_externalities().execute_with(|| {
+        let account_id = 1;
+        let total_amount = 200;
+        let stake1 = 100;
+        let stake2 = 200;
+
+        increase_total_balance_issuance_using_account_id(account_id, total_amount);
+
+        assert!(TestStakingManager::set_stake(&account_id, stake1).is_ok());
+        assert!(TestStakingManager2::set_stake(&account_id, stake2).is_ok());
+    });
+}

+ 4 - 4
runtime-modules/working-group/src/checks.rs

@@ -45,11 +45,11 @@ pub(crate) fn ensure_stake_for_opening_type<T: Trait<I>, I: Instance>(
         ensure_origin_is_active_leader::<T, I>(origin)?;
         let lead = crate::Module::<T, I>::worker_by_id(ensure_lead_is_set::<T, I>()?);
 
+        let new_stake = T::LeaderOpeningStake::get()
+            + T::StakingHandler::current_stake(&lead.staking_account_id);
+
         ensure!(
-            T::StakingHandler::is_enough_balance_for_stake(
-                &lead.staking_account_id,
-                T::LeaderOpeningStake::get()
-            ),
+            T::StakingHandler::is_enough_balance_for_stake(&lead.staking_account_id, new_stake),
             Error::<T, I>::InsufficientBalanceToCoverStake
         );
     }

+ 5 - 2
runtime-modules/working-group/src/tests/mod.rs

@@ -115,10 +115,13 @@ fn add_opening_fails_with_zero_reward() {
 fn add_opening_fails_with_insufficient_balance() {
     build_test_externalities().execute_with(|| {
         HireLeadFixture::default()
-            .with_initial_balance(<Test as Trait>::MinimumApplicationStake::get() + 1)
+            .with_initial_balance(<Test as Trait>::MinimumApplicationStake::get())
             .hire_lead();
 
-        let add_opening_fixture = AddOpeningFixture::default();
+        let add_opening_fixture = AddOpeningFixture::default().with_stake_policy(StakePolicy {
+            stake_amount: <Test as Trait>::MinimumApplicationStake::get(),
+            leaving_unstaking_period: <Test as Trait>::MinUnstakingPeriodLimit::get() + 1,
+        });
 
         add_opening_fixture.call_and_assert(Err(
             Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),