Browse Source

Add set_lead() to the bureacracy module

- add set_lead() to the bureacracy module
- temporary remove mocks
- temporary remove hiring related code
Shamil Gadelshin 4 years ago
parent
commit
5f7ad95925

+ 0 - 40
runtime-modules/bureaucracy/src/constraints.rs

@@ -1,40 +0,0 @@
-use codec::{Decode, Encode};
-#[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
-
-/// Length constraint for input validation
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
-pub struct InputValidationLengthConstraint {
-    /// Minimum length
-    pub min: u16,
-
-    /// Difference between minimum length and max length.
-    /// While having max would have been more direct, this
-    /// way makes max < min unrepresentable semantically,
-    /// which is safer.
-    pub max_min_diff: u16,
-}
-
-impl InputValidationLengthConstraint {
-    /// Helper for computing max
-    pub fn max(&self) -> u16 {
-        self.min + self.max_min_diff
-    }
-
-    pub fn ensure_valid(
-        &self,
-        len: usize,
-        too_short_msg: &'static str,
-        too_long_msg: &'static str,
-    ) -> Result<(), &'static str> {
-        let length = len as u16;
-        if length < self.min {
-            Err(too_short_msg)
-        } else if length > self.max() {
-            Err(too_long_msg)
-        } else {
-            Ok(())
-        }
-    }
-}

+ 50 - 230
runtime-modules/bureaucracy/src/lib.rs

@@ -1,36 +1,26 @@
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
 
-mod constraints;
 mod types;
 
-use rstd::collections::btree_set::BTreeSet;
-use sr_primitives::traits::One; // Member, SimpleArithmetic, MaybeSerialize, Zero
+use sr_primitives::traits::One;
 use srml_support::traits::Currency;
 use srml_support::{decl_module, decl_storage, dispatch, ensure};
 use system::{self, ensure_signed};
 
-use constraints::InputValidationLengthConstraint;
-use types::{CuratorOpening, Lead, OpeningPolicyCommitment};
+use membership::role_types::{ActorInRole, Role};
+use types::{Lead, LeadRoleState};
 
 pub static MSG_CHANNEL_DESCRIPTION_TOO_SHORT: &str = "Channel description too short";
 pub static MSG_CHANNEL_DESCRIPTION_TOO_LONG: &str = "Channel description too long";
 pub static MSG_ORIGIN_IS_NOT_LEAD: &str = "Origin is not lead";
 pub static MSG_CURRENT_LEAD_NOT_SET: &str = "Current lead is not set";
+pub static MSG_CURRENT_LEAD_ALREADY_SET: &str = "Current lead is already set";
 
-/// Type constraint for identifer used for actors in members module in this runtime.
-pub type ActorIdInMembersModule<T> = <T as membership::members::Trait>::ActorId;
+/// Type identifier for lead role, which must be same as membership actor identifier
+pub type LeadId<T> = <T as membership::members::Trait>::ActorId;
 
-/// Type identifier for lead role, which must be same as membership actor identifeir
-pub type LeadId<T> = ActorIdInMembersModule<T>;
-
-/// Type for the identifer for an opening for a curator.
-pub type CuratorOpeningId<T> = <T as hiring::Trait>::OpeningId;
-
-/// Tyoe for the indentifier for an application as a curator.
-pub type CuratorApplicationId<T> = <T as hiring::Trait>::ApplicationId;
-
-/// Type of mintin reward relationship identifiers
+/// Type of minting reward relationship identifiers
 pub type RewardRelationshipId<T> = <T as recurringrewards::Trait>::RewardRelationshipId;
 
 /// Balance type of runtime
@@ -44,95 +34,64 @@ pub trait Trait<I: Instance>:
 
 decl_storage! {
     trait Store for Module<T: Trait<I>, I: Instance> as Bureaucracy {
-        pub TestData get(test_data): u32;
-
-        /// Next identifier value for new curator opening.
-        pub NextCuratorOpeningId get(next_curator_opening_id): CuratorOpeningId<T>;
-
-        /// Maps identifier to curator opening.
-        pub CuratorOpeningById get(curator_opening_by_id): linked_map CuratorOpeningId<T> => CuratorOpening<T::OpeningId, T::BlockNumber, BalanceOf<T>, CuratorApplicationId<T>>;
-
         /// The current lead.
         pub CurrentLeadId get(current_lead_id) : Option<LeadId<T>>;
 
         /// Maps identifier to corresponding lead.
         pub LeadById get(lead_by_id): linked_map LeadId<T> => Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber>;
 
-
-        pub OpeningHumanReadableText get(opening_human_readable_text): InputValidationLengthConstraint;
+        /// Next identifier for new current lead.
+        pub NextLeadId get(next_lead_id): LeadId<T>;
     }
 }
 
 decl_module! {
     pub struct Module<T: Trait<I>, I: Instance> for enum Call where origin: T::Origin {
-        /// Add an opening for a curator role.
-        pub fn add_curator_opening(origin, activate_at: hiring::ActivateOpeningAt<T::BlockNumber>, commitment: OpeningPolicyCommitment<T::BlockNumber, BalanceOf<T>>, human_readable_text: Vec<u8>)  {
-
-            // Ensure lead is set and is origin signer
-            Self::ensure_origin_is_set_lead(origin)?;
-
-            Self::ensure_opening_human_readable_text_is_valid(&human_readable_text)?;
-
-            // Add opening
-            // NB: This call can in principle fail, because the staking policies
-            // may not respect the minimum currency requirement.
-
-            let policy_commitment = commitment.clone();
-
-            // let opening_id = ensure_on_wrapped_error!(
-            //     hiring::Module::<T>::add_opening(
-            //         activate_at,
-            //         commitment.max_review_period_length,
-            //         commitment.application_rationing_policy,
-            //         commitment.application_staking_policy,
-            //         commitment.role_staking_policy,
-            //         human_readable_text,
-            //     ))?;
-
-            let opening_id = hiring::Module::<T>::add_opening(
-                activate_at,
-                commitment.max_review_period_length,
-                commitment.application_rationing_policy,
-                commitment.application_staking_policy,
-                commitment.role_staking_policy,
-                human_readable_text,
-            ).unwrap(); //TODO
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let new_curator_opening_id = NextCuratorOpeningId::<T, I>::get();
-
-            // Create and add curator opening.
-            let new_opening_by_id = CuratorOpening::<CuratorOpeningId<T>, T::BlockNumber, BalanceOf<T>, CuratorApplicationId<T>> {
-                opening_id : opening_id,
-                curator_applications: BTreeSet::new(),
-                policy_commitment: policy_commitment
-            };
-
-            CuratorOpeningById::<T, I>::insert(new_curator_opening_id, new_opening_by_id);
-
-            // Update NextCuratorOpeningId
-            NextCuratorOpeningId::<T, I>::mutate(|id| *id += <CuratorOpeningId<T> as One>::one());
-
-            // Trigger event
-            //Self::deposit_event(RawEvent::CuratorOpeningAdded(new_curator_opening_id));
-        }
+
     }
 }
 
 impl<T: Trait<I>, I: Instance> Module<T, I> {
-    pub fn set_test_data(data: u32) {
-        <TestData<I>>::put(data);
-    }
+    /// Introduce a lead when one is not currently set.
+    pub fn set_lead(member: T::MemberId, role_account: T::AccountId) -> dispatch::Result {
+        // Ensure there is no current lead
+        ensure!(
+            <CurrentLeadId<T, I>>::get().is_none(),
+            MSG_CURRENT_LEAD_ALREADY_SET
+        );
+
+        let new_lead_id = <NextLeadId<T, I>>::get();
+
+        let new_lead_role = ActorInRole::new(Role::CuratorLead, new_lead_id);
+
+        //
+        // == MUTATION SAFE ==
+        //
+
+        // Register in role - will fail if member cannot become lead
+        membership::members::Module::<T>::register_role_on_member(member, &new_lead_role)?;
 
-    fn ensure_opening_human_readable_text_is_valid(text: &Vec<u8>) -> dispatch::Result {
-        <OpeningHumanReadableText<I>>::get().ensure_valid(
-            text.len(),
-            MSG_CHANNEL_DESCRIPTION_TOO_SHORT,
-            MSG_CHANNEL_DESCRIPTION_TOO_LONG,
-        )
+        // Construct lead
+        let new_lead = Lead {
+            role_account: role_account.clone(),
+            reward_relationship: None,
+            inducted: <system::Module<T>>::block_number(),
+            stage: LeadRoleState::Active,
+        };
+
+        // Store lead
+        <LeadById<T, I>>::insert(new_lead_id, new_lead);
+
+        // Update current lead
+        <CurrentLeadId<T, I>>::put(new_lead_id); // Some(new_lead_id)
+
+        // Update next lead counter
+        <NextLeadId<T, I>>::mutate(|id| *id += <LeadId<T> as One>::one());
+
+        // Trigger event
+//        Self::deposit_event(RawEvent::LeadSet(new_lead_id));
+
+        Ok(())
     }
 
     pub fn ensure_lead_is_set() -> Result<
@@ -162,7 +121,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         }
     }
 
-    fn ensure_origin_is_set_lead(
+    pub fn ensure_origin_is_set_lead(
         origin: T::Origin,
     ) -> Result<
         (
@@ -183,142 +142,3 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         Ok((lead_id, lead))
     }
 }
-
-#[cfg(test)]
-mod test {
-
-    use primitives::H256;
-    use sr_primitives::{
-        testing::Header,
-        traits::{BlakeTwo256, IdentityLookup},
-        Perbill,
-    };
-    use srml_support::{impl_outer_origin, parameter_types};
-
-    use crate::{Module, Trait};
-
-    impl_outer_origin! {
-            pub enum Origin for Test {}
-    }
-
-    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 InitialMembersBalance: u64 = 2000;
-        pub const StakePoolId: [u8; 8] = *b"joystake";
-        pub const ExistentialDeposit: u32 = 0;
-        pub const TransferFee: u32 = 0;
-        pub const CreationFee: u32 = 0;
-    }
-
-    // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
-    #[derive(Clone, PartialEq, Eq, Debug)]
-    pub struct Test;
-
-    impl system::Trait for Test {
-        type Origin = Origin;
-        type Index = u64;
-        type BlockNumber = u64;
-        type Call = ();
-        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 MaximumBlockLength = MaximumBlockLength;
-        type AvailableBlockRatio = AvailableBlockRatio;
-        type Version = ();
-    }
-
-    impl recurringrewards::Trait for Test {
-        type PayoutStatusHandler = ();
-        type RecipientId = u64;
-        type RewardRelationshipId = u64;
-    }
-
-    impl hiring::Trait for Test {
-        type OpeningId = u64;
-        type ApplicationId = u64;
-        type ApplicationDeactivatedHandler = ();
-        type StakeHandlerProvider = hiring::Module<Self>;
-    }
-
-    impl minting::Trait for Test {
-        type Currency = Balances;
-        type MintId = u64;
-    }
-
-    impl stake::Trait for Test {
-        type Currency = Balances;
-        type StakePoolId = StakePoolId;
-        type StakingEventsHandler = ();
-        type StakeId = u64;
-        type SlashId = u64;
-    }
-
-    impl membership::members::Trait for Test {
-        type Event = ();
-        type MemberId = u64;
-        type PaidTermId = u64;
-        type SubscriptionId = u64;
-        type ActorId = u64;
-        type InitialMembersBalance = InitialMembersBalance;
-    }
-
-    impl common::currency::GovernanceCurrency for Test {
-        type Currency = Balances;
-    }
-
-    impl timestamp::Trait for Test {
-        type Moment = u64;
-        type OnTimestampSet = ();
-        type MinimumPeriod = MinimumPeriod;
-    }
-
-    impl balances::Trait for Test {
-        type Balance = u64;
-        type OnFreeBalanceZero = ();
-        type OnNewAccount = ();
-        type Event = ();
-        type DustRemoval = ();
-        type TransferPayment = ();
-        type ExistentialDeposit = ExistentialDeposit;
-        type TransferFee = TransferFee;
-        type CreationFee = CreationFee;
-    }
-
-    pub type Balances = balances::Module<Test>;
-
-    impl Trait<Instance1> for Test {}
-    impl Trait<Instance2> for Test {}
-
-    use crate::Instance1;
-    use crate::Instance2;
-
-    type Bureaucracy1 = Module<Test, Instance1>;
-    type Bureaucracy2 = Module<Test, Instance2>;
-
-    pub fn build_test_externalities() -> runtime_io::TestExternalities {
-        let t = system::GenesisConfig::default()
-            .build_storage::<Test>()
-            .unwrap();
-
-        t.into()
-    }
-
-    #[test]
-    fn test_instances_storage_separation() {
-        build_test_externalities().execute_with(|| {
-            Bureaucracy1::set_test_data(10);
-
-            assert_eq!(Bureaucracy1::test_data(), 10);
-            assert_eq!(Bureaucracy2::test_data(), 10);
-        });
-    }
-}

+ 0 - 88
runtime-modules/bureaucracy/src/types.rs

@@ -1,95 +1,7 @@
 use codec::{Decode, Encode};
-use rstd::collections::btree_set::BTreeSet;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
-/// Terms for slashings applied to a given role
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq)]
-pub struct SlashableTerms {
-    /// Maximum number of slashes.
-    pub max_count: u16,
-
-    /// Maximum percentage points of remaining stake which may be slashed in a single slash.
-    pub max_percent_pts_per_time: u16,
-}
-
-/// Terms for what slashing can be applied in some context
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq)]
-pub enum SlashingTerms {
-    Unslashable,
-    Slashable(SlashableTerms),
-}
-
-/// Must be default constructible because it indirectly is a value in a storage map.
-/// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
-impl Default for SlashingTerms {
-    fn default() -> Self {
-        Self::Unslashable
-    }
-}
-
-/// A commitment to the set of policy variables relevant to an opening.
-/// An applicant can observe this commitment and be secure that the terms
-/// of the application process cannot be changed ex-post.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct OpeningPolicyCommitment<BlockNumber, Balance> {
-    /// Rationing to be used
-    pub application_rationing_policy: Option<hiring::ApplicationRationingPolicy>,
-
-    /// Maximum length of review period of applications
-    pub max_review_period_length: BlockNumber,
-
-    /// Staking policy for application
-    pub application_staking_policy: Option<hiring::StakingPolicy<Balance, BlockNumber>>,
-
-    /// Staking policy for role itself
-    pub role_staking_policy: Option<hiring::StakingPolicy<Balance, BlockNumber>>,
-
-    // Slashing terms during application
-    // pub application_slashing_terms: SlashingTerms,
-
-    // Slashing terms during role, NOT application itself!
-    pub role_slashing_terms: SlashingTerms,
-
-    /// When filling an opening: Unstaking period for application stake of successful applicants
-    pub fill_opening_successful_applicant_application_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When filling an opening:
-    pub fill_opening_failed_applicant_application_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When filling an opening:
-    pub fill_opening_failed_applicant_role_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When terminating a curator:
-    pub terminate_curator_application_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When terminating a curator:
-    pub terminate_curator_role_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When a curator exists: ..
-    pub exit_curator_role_application_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When a curator exists: ..
-    pub exit_curator_role_stake_unstaking_period: Option<BlockNumber>,
-}
-
-/// An opening for a curator role.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct CuratorOpening<OpeningId, BlockNumber, Balance, CuratorApplicationId: core::cmp::Ord> {
-    /// Identifer for underlying opening in the hiring module.
-    pub opening_id: OpeningId,
-
-    /// Set of identifiers for all curator applications ever added
-    pub curator_applications: BTreeSet<CuratorApplicationId>,
-
-    /// Commitment to policies in opening.
-    pub policy_commitment: OpeningPolicyCommitment<BlockNumber, Balance>,
-}
-
 /// The exit stage of a lead involvement in the working group.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Debug, Clone, PartialEq)]