Преглед изворни кода

runtime: Change compatible locks combination.

Shamil Gadelshin пре 3 година
родитељ
комит
5a153fa183

+ 11 - 135
runtime/src/constants.rs

@@ -2,7 +2,7 @@ use super::Balance;
 use crate::{BlockNumber, Moment};
 use frame_support::parameter_types;
 use frame_support::traits::LockIdentifier;
-use sp_std::collections::btree_set::BTreeSet;
+use sp_std::vec::Vec;
 
 /// Constants for Babe.
 
@@ -111,7 +111,7 @@ parameter_types! {
     pub const ForumGroupLockId: LockIdentifier = *b"wg-forum";
     pub const MembershipWorkingGroupLockId: LockIdentifier = *b"wg-membr";
     pub const InvitedMemberLockId: LockIdentifier = *b"invitemb";
-    pub const StakingCandidateLockId: LockIdentifier = *b"stakcand";
+    pub const BoundStakingAccountLockId: LockIdentifier = *b"boundsta";
     pub const BountyLockId: LockIdentifier = *b"bounty  ";
     pub const OperationsWorkingGroupAlphaLockId: LockIdentifier = *b"wg-opera";
     pub const GatewayWorkingGroupLockId: LockIdentifier = *b"wg-gatew";
@@ -122,142 +122,18 @@ parameter_types! {
 
 // Staking lock ID used by nomination and validation in the staking pallet.
 // This is a copye because the current Substrate staking lock ID is not exported.
-const STAKING_LOCK_ID: LockIdentifier = *b"staking ";
+pub const STAKING_LOCK_ID: LockIdentifier = *b"staking ";
+
+pub const VESTING_LOCK_ID: LockIdentifier = *b"vesting ";
 
 lazy_static! {
-    // pairs of allowed lock combinations
-    pub static ref ALLOWED_LOCK_COMBINATIONS: BTreeSet<(LockIdentifier, LockIdentifier)> = [
-        // format: `(lock_id, [all_compatible_lock_ids, ...])`
-        (InvitedMemberLockId::get(), [
-            VotingLockId::get(),
-            CandidacyLockId::get(),
-            CouncilorLockId::get(),
-            STAKING_LOCK_ID,
-            ProposalsLockId::get(),
-            ForumGroupLockId::get(),
-            ContentWorkingGroupLockId::get(),
-            StorageWorkingGroupLockId::get(),
-            MembershipWorkingGroupLockId::get(),
-            GatewayWorkingGroupLockId::get(),
-            OperationsWorkingGroupAlphaLockId::get(),
-            OperationsWorkingGroupBetaLockId::get(),
-            OperationsWorkingGroupGammaLockId::get(),
-            DistributionWorkingGroupLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (StakingCandidateLockId::get(), [
-            VotingLockId::get(),
-            CandidacyLockId::get(),
-            CouncilorLockId::get(),
-            STAKING_LOCK_ID,
-            ProposalsLockId::get(),
-            ForumGroupLockId::get(),
-            ContentWorkingGroupLockId::get(),
-            StorageWorkingGroupLockId::get(),
-            MembershipWorkingGroupLockId::get(),
-            GatewayWorkingGroupLockId::get(),
-            DistributionWorkingGroupLockId::get(),
-            OperationsWorkingGroupAlphaLockId::get(),
-            OperationsWorkingGroupBetaLockId::get(),
-            OperationsWorkingGroupGammaLockId::get(),
-            InvitedMemberLockId::get(),
-        ].to_vec()),
-        (VotingLockId::get(), [
-            InvitedMemberLockId::get(),
-            CandidacyLockId::get(),
-            CouncilorLockId::get(),
-            STAKING_LOCK_ID,
-            ProposalsLockId::get(),
-            ForumGroupLockId::get(),
-            ContentWorkingGroupLockId::get(),
-            StorageWorkingGroupLockId::get(),
-            MembershipWorkingGroupLockId::get(),
-            GatewayWorkingGroupLockId::get(),
-            DistributionWorkingGroupLockId::get(),
-            OperationsWorkingGroupAlphaLockId::get(),
-            OperationsWorkingGroupBetaLockId::get(),
-            OperationsWorkingGroupGammaLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (CandidacyLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            CouncilorLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (CouncilorLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            CandidacyLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        // Proposals
-        (ProposalsLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        // Working Groups
-        (ForumGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (ContentWorkingGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (StorageWorkingGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (MembershipWorkingGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (GatewayWorkingGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (DistributionWorkingGroupLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (OperationsWorkingGroupAlphaLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (OperationsWorkingGroupBetaLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        (OperationsWorkingGroupGammaLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
-        // Bounty
-        (BountyLockId::get(), [
-            InvitedMemberLockId::get(),
-            VotingLockId::get(),
-            StakingCandidateLockId::get(),
-        ].to_vec()),
+    pub static ref NON_RIVALROUS_LOCKS: Vec<LockIdentifier> = [
+        VotingLockId::get(),
+        VESTING_LOCK_ID,
+        InvitedMemberLockId::get(),
+        BoundStakingAccountLockId::get(),
     ]
-    .iter()
-    .fold(BTreeSet::new(), |mut acc, item| {
-        for lock_id in &item.1 {
-            acc.insert((item.0, *lock_id));
-        }
-
-        acc
-    });
+    .to_vec();
 }
 
 // Change it when changing the currency constants!

+ 11 - 8
runtime/src/lib.rs

@@ -58,7 +58,6 @@ use sp_runtime::curve::PiecewiseLinear;
 use sp_runtime::traits::{BlakeTwo256, Block as BlockT, IdentityLookup, OpaqueKeys, Saturating};
 use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ModuleId, Perbill};
 use sp_std::boxed::Box;
-use sp_std::collections::btree_set::BTreeSet;
 use sp_std::vec::Vec;
 #[cfg(feature = "std")]
 use sp_version::NativeVersion;
@@ -72,7 +71,6 @@ pub use runtime_api::*;
 use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder};
 
 use common::working_group::{WorkingGroup, WorkingGroupAuthenticator, WorkingGroupBudgetHandler};
-use common::AllowedLockCombinationProvider;
 use council::ReferendumConnection;
 use referendum::{CastVote, OptionResult};
 use staking_handler::{LockComparator, StakingManager};
@@ -502,7 +500,7 @@ parameter_types! {
 impl referendum::Trait<ReferendumInstance> for Runtime {
     type Event = Event;
     type MaxSaltLength = MaxSaltLength;
-    type StakingHandler = staking_handler::StakingManager<Self, VotingLockId>;
+    type StakingHandler = VotingStakingManager;
     type ManagerOrigin =
         EnsureOneOf<Self::AccountId, EnsureSigned<Self::AccountId>, EnsureRoot<Self::AccountId>>;
     type VotePower = Balance;
@@ -664,7 +662,7 @@ impl membership::Trait for Runtime {
     type DefaultMembershipPrice = DefaultMembershipPrice;
     type DefaultInitialInvitationBalance = DefaultInitialInvitationBalance;
     type InvitedMemberStakingHandler = InvitedMemberStakingManager;
-    type StakingCandidateStakingHandler = StakingCandidateStakingHandler;
+    type StakingCandidateStakingHandler = BoundStakingAccountStakingManager;
     type WorkingGroup = MembershipWorkingGroup;
     type WeightInfo = weights::membership::WeightInfo;
     type ReferralCutMaximumPercent = ReferralCutMaximumPercent;
@@ -716,9 +714,13 @@ impl forum::Trait for Runtime {
 
 impl LockComparator<<Runtime as pallet_balances::Trait>::Balance> for Runtime {
     fn are_locks_conflicting(new_lock: &LockIdentifier, existing_locks: &[LockIdentifier]) -> bool {
-        existing_locks
+        let other_locks_present = !existing_locks.is_empty();
+        let new_lock_is_rivalrous = !NON_RIVALROUS_LOCKS.contains(new_lock);
+        let existing_locks_contain_rivalrous_lock = existing_locks
             .iter()
-            .any(|lock| !ALLOWED_LOCK_COMBINATIONS.contains(&(*new_lock, *lock)))
+            .any(|lock_id| !NON_RIVALROUS_LOCKS.contains(lock_id));
+
+        other_locks_present && new_lock_is_rivalrous && existing_locks_contain_rivalrous_lock
     }
 }
 
@@ -747,6 +749,7 @@ parameter_types! {
 // Staking managers type aliases.
 pub type ForumWorkingGroupStakingManager =
     staking_handler::StakingManager<Runtime, ForumGroupLockId>;
+pub type VotingStakingManager = staking_handler::StakingManager<Runtime, VotingLockId>;
 pub type ContentWorkingGroupStakingManager =
     staking_handler::StakingManager<Runtime, ContentWorkingGroupLockId>;
 pub type StorageWorkingGroupStakingManager =
@@ -755,8 +758,8 @@ pub type MembershipWorkingGroupStakingManager =
     staking_handler::StakingManager<Runtime, MembershipWorkingGroupLockId>;
 pub type InvitedMemberStakingManager =
     staking_handler::StakingManager<Runtime, InvitedMemberLockId>;
-pub type StakingCandidateStakingHandler =
-    staking_handler::StakingManager<Runtime, StakingCandidateLockId>;
+pub type BoundStakingAccountStakingManager =
+    staking_handler::StakingManager<Runtime, BoundStakingAccountLockId>;
 pub type GatewayWorkingGroupStakingManager =
     staking_handler::StakingManager<Runtime, GatewayWorkingGroupLockId>;
 pub type OperationsWorkingGroupAlphaStakingManager =

+ 64 - 0
runtime/src/tests/locks.rs

@@ -0,0 +1,64 @@
+use super::{increase_total_balance_issuance_using_account_id, initial_test_ext};
+use crate::{
+    BoundStakingAccountStakingManager, ContentWorkingGroupStakingManager,
+    GatewayWorkingGroupStakingManager,
+};
+use frame_support::sp_runtime::AccountId32;
+use staking_handler::StakingHandler;
+
+#[test]
+fn compatible_stakes_check_passed_successfully() {
+    initial_test_ext().execute_with(|| {
+        let account_id = AccountId32::default();
+        let total_amout = 10000;
+        let stake_amount = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id.clone().into(), total_amout);
+
+        assert_eq!(
+            BoundStakingAccountStakingManager::set_stake(&account_id, stake_amount),
+            Ok(())
+        );
+        assert!(
+            ContentWorkingGroupStakingManager::is_account_free_of_conflicting_stakes(&account_id)
+        );
+    });
+}
+
+#[test]
+fn compatible_stakes_check_reversed_order_passed_successfully() {
+    initial_test_ext().execute_with(|| {
+        let account_id = AccountId32::default();
+        let total_amout = 10000;
+        let stake_amount = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id.clone().into(), total_amout);
+
+        assert_eq!(
+            ContentWorkingGroupStakingManager::set_stake(&account_id, stake_amount),
+            Ok(())
+        );
+        assert!(
+            BoundStakingAccountStakingManager::is_account_free_of_conflicting_stakes(&account_id)
+        );
+    });
+}
+
+#[test]
+fn incompatible_stakes_check_passed_successfully() {
+    initial_test_ext().execute_with(|| {
+        let account_id = AccountId32::default();
+        let total_amout = 10000;
+        let stake_amount = 100;
+
+        increase_total_balance_issuance_using_account_id(account_id.clone().into(), total_amout);
+
+        assert_eq!(
+            GatewayWorkingGroupStakingManager::set_stake(&account_id, stake_amount),
+            Ok(())
+        );
+        assert!(
+            !ContentWorkingGroupStakingManager::is_account_free_of_conflicting_stakes(&account_id)
+        );
+    });
+}

+ 8 - 8
runtime/src/tests/mod.rs

@@ -5,6 +5,7 @@
 
 mod proposals_integration;
 mod fee_tests;
+mod locks;
 
 use crate::{BlockNumber, ReferendumInstance, Runtime};
 use frame_support::traits::{Currency, OnFinalize, OnInitialize};
@@ -43,21 +44,21 @@ fn get_account_membership(account: AccountId32, i: usize) -> u64 {
     member_id
 }
 
-pub(crate) fn elect_council(council: Vec<AccountId32>, cycle_id: u64) {
+// council = Vec<(ID - membership handle helper, ACCOUNT_ID)>
+pub(crate) fn elect_council(council: Vec<(u8, AccountId32)>, cycle_id: u64) {
     let mut voters = Vec::<AccountId32>::new();
 
     let councilor_stake: u128 = <Runtime as council::Trait>::MinCandidateStake::get().into();
     let extra_candidates = <Runtime as council::Trait>::MinNumberOfExtraCandidates::get() + 1;
     let mut council_member_ids = Vec::new();
 
-    for (i, councilor) in council.iter().enumerate() {
+    for (i, councilor) in council.iter() {
         increase_total_balance_issuance_using_account_id(
             councilor.clone().into(),
             councilor_stake + 1,
         );
 
-        let member_id = get_account_membership(councilor.clone(), i);
-
+        let member_id = get_account_membership(councilor.clone(), *i as usize);
         Council::announce_candidacy(
             RawOrigin::Signed(councilor.clone()).into(),
             member_id,
@@ -69,13 +70,13 @@ pub(crate) fn elect_council(council: Vec<AccountId32>, cycle_id: u64) {
         // Make sure to use different voters in each election cycle to prevent problems with
         // staking
         voters.push(
-            [(council.len() as u8 + extra_candidates as u8) * (cycle_id as u8 + 1) + i as u8; 32]
-                .into(),
+            [(council.len() as u8 + extra_candidates as u8) * (cycle_id as u8 + 1) + *i; 32].into(),
         );
         council_member_ids.push(member_id);
     }
 
-    for i in council.len()..(council.len() + extra_candidates as usize) {
+    let council_index = (council.clone().last().unwrap().0 + 10) as usize;
+    for i in council_index..(council_index + extra_candidates as usize) {
         let extra_councilor: AccountId32 = [i as u8; 32].into();
 
         let member_id = get_account_membership(extra_councilor.clone(), i);
@@ -88,7 +89,6 @@ pub(crate) fn elect_council(council: Vec<AccountId32>, cycle_id: u64) {
             extra_councilor.clone().into(),
             councilor_stake + 1,
         );
-
         Council::announce_candidacy(
             RawOrigin::Signed(extra_councilor.clone()).into(),
             member_id,

+ 39 - 9
runtime/src/tests/proposals_integration/mod.rs

@@ -49,11 +49,40 @@ fn setup_members(count: u8) {
 
 // Max Council size is 3
 fn setup_council(cycle_id: u64) {
-    let councilor0 = AccountId32::default();
-    let councilor1: [u8; 32] = [1; 32];
-    let councilor2: [u8; 32] = [2; 32];
+    let id0 = 0u8;
+    let id1 = 1u8;
+    let id2 = 2u8;
+
+    let councilor0: [u8; 32] = [id0; 32];
+    let councilor1: [u8; 32] = [id1; 32];
+    let councilor2: [u8; 32] = [id2; 32];
+
     elect_council(
-        vec![councilor0, councilor1.into(), councilor2.into()],
+        vec![
+            (id0, councilor0.into()),
+            (id1, councilor1.into()),
+            (id2, councilor2.into()),
+        ],
+        cycle_id,
+    );
+}
+
+// Max Council size is 3
+fn setup_different_council(cycle_id: u64) {
+    let id3 = 3u8;
+    let id4 = 4u8;
+    let id5 = 5u8;
+
+    let councilor3: [u8; 32] = [id3; 32];
+    let councilor4: [u8; 32] = [id4; 32];
+    let councilor5: [u8; 32] = [id5; 32];
+
+    elect_council(
+        vec![
+            (id3, councilor3.into()),
+            (id4, councilor4.into()),
+            (id5, councilor5.into()),
+        ],
         cycle_id,
     );
 }
@@ -322,8 +351,9 @@ fn proposal_cancellation_with_slashes_with_balance_checks_succeeds() {
 #[test]
 fn proposal_reset_succeeds() {
     initial_test_ext().execute_with(|| {
-        setup_members(4);
+        setup_members(30);
         setup_council(0);
+
         // create proposal
         let dummy_proposal = DummyProposalFixture::default().with_voting_period(100);
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
@@ -367,7 +397,7 @@ fn proposal_reset_succeeds() {
         //<Runtime as governance::election::Trait>::CouncilElected::council_elected(Vec::new(), 10);
 
         end_idle_period();
-        setup_council(1);
+        setup_different_council(1);
 
         let updated_proposal = ProposalsEngine::proposals(proposal_id);
 
@@ -573,7 +603,7 @@ fn funding_request_proposal_execution_succeeds() {
         let council_budget = 5_000_000;
         let funding = 5000;
 
-        let target_account_id: [u8; 32] = [12; 32];
+        let target_account_id: [u8; 32] = [111; 32];
         let target_account_id: AccountId32 = target_account_id.clone().into();
 
         assert!(Council::set_budget(RawOrigin::Root.into(), council_budget).is_ok());
@@ -1122,7 +1152,7 @@ fn set_councilor_reward_proposal_succeds() {
 #[test]
 fn proposal_reactivation_succeeds() {
     initial_test_ext().execute_with(|| {
-        setup_members(5);
+        setup_members(25);
         setup_council(0);
 
         let starting_block = System::block_number();
@@ -1155,7 +1185,7 @@ fn proposal_reactivation_succeeds() {
         assert_eq!(CouncilManager::<Runtime>::total_voters_count(), 3);
 
         end_idle_period();
-        setup_council(1);
+        setup_different_council(1);
 
         run_to_block(10);