Browse Source

Merge pull request #1813 from shamil-gadelshin/working_team_rename

Working team integration.
Bedeho Mender 4 years ago
parent
commit
3923690f4d
49 changed files with 2448 additions and 8653 deletions
  1. 4 26
      Cargo.lock
  2. 0 1
      Cargo.toml
  3. 5 22
      node/src/chain_spec/mod.rs
  4. 27 68
      runtime-modules/proposals/codex/src/lib.rs
  5. 21 114
      runtime-modules/proposals/codex/src/proposal_types/mod.rs
  6. 11 1
      runtime-modules/proposals/codex/src/tests/mock/mod.rs
  7. 45 89
      runtime-modules/proposals/codex/src/tests/mod.rs
  8. 3 1
      runtime-modules/service-discovery/Cargo.toml
  9. 4 5
      runtime-modules/service-discovery/src/lib.rs
  10. 25 5
      runtime-modules/service-discovery/src/mock/mod.rs
  11. 0 0
      runtime-modules/service-discovery/src/mock/staking_handler.rs
  12. 1 1
      runtime-modules/storage/Cargo.toml
  13. 6 4
      runtime-modules/storage/src/data_directory.rs
  14. 5 3
      runtime-modules/storage/src/data_object_storage_registry.rs
  15. 7 5
      runtime-modules/storage/src/data_object_type_registry.rs
  16. 0 3
      runtime-modules/storage/src/lib.rs
  17. 8 3
      runtime-modules/storage/src/tests/data_object_type_registry.rs
  18. 24 12
      runtime-modules/storage/src/tests/mock/mod.rs
  19. 98 0
      runtime-modules/storage/src/tests/mock/staking_handler.rs
  20. 14 19
      runtime-modules/working-group/Cargo.toml
  21. 91 91
      runtime-modules/working-group/src/benchmarking.rs
  22. 28 27
      runtime-modules/working-group/src/checks.rs
  23. 45 639
      runtime-modules/working-group/src/errors.rs
  24. 427 482
      runtime-modules/working-group/src/lib.rs
  25. 609 347
      runtime-modules/working-group/src/tests/fixtures.rs
  26. 47 67
      runtime-modules/working-group/src/tests/hiring_workflow.rs
  27. 0 237
      runtime-modules/working-group/src/tests/mock.rs
  28. 4 6
      runtime-modules/working-group/src/tests/mock/mod.rs
  29. 98 0
      runtime-modules/working-group/src/tests/mock/staking_handler.rs
  30. 422 418
      runtime-modules/working-group/src/tests/mod.rs
  31. 179 159
      runtime-modules/working-group/src/types.rs
  32. 0 39
      runtime-modules/working-team/Cargo.toml
  33. 0 90
      runtime-modules/working-team/src/errors.rs
  34. 0 1124
      runtime-modules/working-team/src/lib.rs
  35. 0 1116
      runtime-modules/working-team/src/tests/fixtures.rs
  36. 0 181
      runtime-modules/working-team/src/tests/hiring_workflow.rs
  37. 0 2406
      runtime-modules/working-team/src/tests/mod.rs
  38. 0 263
      runtime-modules/working-team/src/types.rs
  39. 8 4
      runtime/src/integration/content_directory.rs
  40. 0 1
      runtime/src/integration/mod.rs
  41. 22 71
      runtime/src/integration/proposals/proposal_encoder.rs
  42. 0 93
      runtime/src/integration/working_group.rs
  43. 20 8
      runtime/src/lib.rs
  44. 3 3
      runtime/src/proposals_configuration/defaults.rs
  45. 5 5
      runtime/src/proposals_configuration/mod.rs
  46. 1 1
      runtime/src/proposals_configuration/sample_proposal_parameters.json
  47. 20 26
      runtime/src/runtime_api.rs
  48. 108 364
      runtime/src/tests/proposals_integration/working_group_proposals.rs
  49. 3 3
      runtime/src/tests/storage_integration.rs

+ 4 - 26
Cargo.lock

@@ -4130,7 +4130,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-service-discovery"
-version = "3.1.0"
+version = "4.0.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4145,6 +4145,7 @@ dependencies = [
  "pallet-working-group",
  "parity-scale-codec",
  "serde",
+ "sp-arithmetic",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -4238,7 +4239,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-storage"
-version = "3.1.0"
+version = "4.0.0"
 dependencies = [
  "frame-support",
  "frame-system",
@@ -4406,30 +4407,7 @@ dependencies = [
 
 [[package]]
 name = "pallet-working-group"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-hiring",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-timestamp",
- "pallet-token-mint",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-working-team"
-version = "1.0.1"
+version = "4.0.0"
 dependencies = [
  "frame-benchmarking",
  "frame-support",

+ 0 - 1
Cargo.toml

@@ -19,7 +19,6 @@ members = [
 	"runtime-modules/versioned-store",
 	"runtime-modules/versioned-store-permissions",
 	"runtime-modules/working-group",
-	"runtime-modules/working-team",
 	"runtime-modules/content-directory",
 	"runtime-modules/constitution",
 	"node",

+ 5 - 22
node/src/chain_spec/mod.rs

@@ -30,12 +30,11 @@ use sp_runtime::Perbill;
 
 use node_runtime::{
     membership, wasm_binary_unwrap, AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig,
-    ContentDirectoryConfig, ContentDirectoryWorkingGroupConfig, ContentWorkingGroupConfig,
-    CouncilConfig, CouncilElectionConfig, DataDirectoryConfig, DataObjectStorageRegistryConfig,
-    DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig, GrandpaConfig, ImOnlineConfig,
-    MembersConfig, Moment, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
-    StorageWorkingGroupConfig, SudoConfig, SystemConfig, VersionedStoreConfig,
-    VersionedStorePermissionsConfig, DAYS,
+    ContentDirectoryConfig, ContentWorkingGroupConfig, CouncilConfig, CouncilElectionConfig,
+    DataDirectoryConfig, DataObjectStorageRegistryConfig, DataObjectTypeRegistryConfig,
+    ElectionParameters, ForumConfig, GrandpaConfig, ImOnlineConfig, MembersConfig, Moment,
+    SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig, SudoConfig, SystemConfig,
+    VersionedStoreConfig, VersionedStorePermissionsConfig, DAYS,
 };
 
 // Exported to be used by chain-spec-builder
@@ -228,8 +227,6 @@ pub fn testnet_genesis(
     const STASH: Balance = 5_000;
     const ENDOWMENT: Balance = 100_000_000;
 
-    let default_text_constraint = node_runtime::working_group::default_text_constraint();
-
     GenesisConfig {
         frame_system: Some(SystemConfig {
             code: wasm_binary_unwrap().to_vec(),
@@ -310,20 +307,6 @@ pub fn testnet_genesis(
         data_object_storage_registry: Some(DataObjectStorageRegistryConfig {
             first_relationship_id: 1,
         }),
-        working_group_Instance2: Some(StorageWorkingGroupConfig {
-            phantom: Default::default(),
-            working_group_mint_capacity: 0,
-            opening_human_readable_text_constraint: default_text_constraint,
-            worker_application_human_readable_text_constraint: default_text_constraint,
-            worker_exit_rationale_text_constraint: default_text_constraint,
-        }),
-        working_group_Instance3: Some(ContentDirectoryWorkingGroupConfig {
-            phantom: Default::default(),
-            working_group_mint_capacity: 0,
-            opening_human_readable_text_constraint: default_text_constraint,
-            worker_application_human_readable_text_constraint: default_text_constraint,
-            worker_exit_rationale_text_constraint: default_text_constraint,
-        }),
         content_directory: Some({
             ContentDirectoryConfig {
                 class_by_id: vec![],

+ 27 - 68
runtime-modules/proposals/codex/src/lib.rs

@@ -25,7 +25,7 @@
 //! - [create_add_working_group_leader_opening_proposal](./struct.Module.html#method.create_add_working_group_leader_opening_proposal)
 //! - [create_begin_review_working_group_leader_applications_proposal](./struct.Module.html#method.create_begin_review_working_group_leader_applications_proposal)
 //! - [create_fill_working_group_leader_opening_proposal](./struct.Module.html#method.create_fill_working_group_leader_opening_proposal)
-//! - [create_set_working_group_mint_capacity_proposal](./struct.Module.html#method.create_set_working_group_mint_capacity_proposal)
+//! - [create_set_working_group_budget_capacity_proposal](./struct.Module.html#method.create_set_working_group_budget_capacity_proposal)
 //! - [create_decrease_working_group_leader_stake_proposal](./struct.Module.html#method.create_decrease_working_group_leader_stake_proposal)
 //! - [create_slash_working_group_leader_stake_proposal](./struct.Module.html#method.create_slash_working_group_leader_stake_proposal)
 //! - [create_set_working_group_leader_reward_proposal](./struct.Module.html#method.create_set_working_group_leader_reward_proposal)
@@ -53,9 +53,6 @@
 // Disable this lint warning because Substrate generates function without an alias for the ProposalDetailsOf type.
 #![allow(clippy::too_many_arguments)]
 
-// Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
-// #![warn(missing_docs)]
-
 mod proposal_types;
 
 #[cfg(test)]
@@ -70,21 +67,20 @@ use sp_std::clone::Clone;
 use sp_std::str::from_utf8;
 use sp_std::vec::Vec;
 
+pub use crate::proposal_types::{
+    AddOpeningParameters, FillOpeningParameters, TerminateRoleParameters,
+};
 use common::origin::ActorOriginValidator;
 use common::working_group::WorkingGroup;
-use governance::election_params::ElectionParameters;
+pub use proposal_types::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
 use proposals_discussion::ThreadMode;
 use proposals_engine::{
     BalanceOf, ProposalCreationParameters, ProposalObserver, ProposalParameters,
 };
+use working_group::Penalty;
 
-pub use crate::proposal_types::{
-    AddOpeningParameters, FillOpeningParameters, TerminateRoleParameters,
-};
-pub use proposal_types::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
-
-// 'Set working group mint capacity' proposal limit
-const WORKING_GROUP_MINT_CAPACITY_MAX_VALUE: u32 = 5_000_000;
+// 'Set working group budget capacity' proposal limit
+const WORKING_GROUP_BUDGET_CAPACITY_MAX_VALUE: u32 = 5_000_000;
 // Max allowed value for 'spending' proposal
 const MAX_SPENDING_PROPOSAL_VALUE: u32 = 5_000_000_u32;
 // Max validator count for the 'set validator count' proposal
@@ -161,8 +157,8 @@ pub trait Trait:
         ProposalParameters<Self::BlockNumber, BalanceOf<Self>>,
     >;
 
-    /// 'Set working group mint capacity' proposal parameters.
-    type SetWorkingGroupMintCapacityProposalParameters: Get<
+    /// 'Set working group budget capacity' proposal parameters.
+    type SetWorkingGroupBudgetCapacityProposalParameters: Get<
         ProposalParameters<Self::BlockNumber, BalanceOf<Self>>,
     >;
 
@@ -252,11 +248,8 @@ decl_error! {
         /// Invalid council election parameter - announcing_period
         InvalidCouncilElectionParameterAnnouncingPeriod,
 
-        /// Invalid content working group mint capacity parameter
-        InvalidContentWorkingGroupMintCapacity,
-
-        /// Invalid working group mint capacity parameter
-        InvalidWorkingGroupMintCapacity,
+        /// Invalid working group budget capacity parameter
+        InvalidWorkingGroupBudgetCapacity,
 
         /// Invalid 'set lead proposal' parameter - proposed lead cannot be a councilor
         InvalidSetLeadParameterCannotBeCouncilor,
@@ -315,9 +308,9 @@ decl_module! {
         const FillWorkingGroupOpeningProposalParameters: ProposalParameters<T::BlockNumber, BalanceOf<T>>
             = T::FillWorkingGroupOpeningProposalParameters::get();
 
-        /// Exports 'Set working group mint capacity' proposal parameters.
-        const SetWorkingGroupMintCapacityProposalParameters: ProposalParameters<T::BlockNumber, BalanceOf<T>>
-            = T::SetWorkingGroupMintCapacityProposalParameters::get();
+        /// Exports 'Set working group budget capacity' proposal parameters.
+        const SetWorkingGroupBudgetCapacityProposalParameters: ProposalParameters<T::BlockNumber, BalanceOf<T>>
+            = T::SetWorkingGroupBudgetCapacityProposalParameters::get();
 
         /// Exports 'Decrease working group leader stake' proposal parameters.
         const DecreaseWorkingGroupLeaderStakeProposalParameters: ProposalParameters<T::BlockNumber, BalanceOf<T>>
@@ -509,35 +502,6 @@ decl_module! {
             Self::create_proposal(params)?;
         }
 
-        /// Create 'Begin review working group leader applications' proposal type.
-        /// This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn create_begin_review_working_group_leader_applications_proposal(
-            origin,
-            member_id: MemberId<T>,
-            title: Vec<u8>,
-            description: Vec<u8>,
-            staking_account_id: Option<T::AccountId>,
-            opening_id: working_group::OpeningId<T>,
-            working_group: WorkingGroup,
-            exact_execution_block: Option<T::BlockNumber>,
-        ) {
-            let proposal_details = ProposalDetails::BeginReviewWorkingGroupLeaderApplications(opening_id, working_group);
-            let params = CreateProposalParameters{
-                origin,
-                member_id,
-                title,
-                description,
-                staking_account_id,
-                proposal_details: proposal_details.clone(),
-                proposal_parameters: T::BeginReviewWorkingGroupApplicationsProposalParameters::get(),
-                proposal_code: T::ProposalEncoder::encode_proposal(proposal_details),
-                exact_execution_block,
-            };
-
-            Self::create_proposal(params)?;
-        }
-
         /// Create 'Fill working group leader opening' proposal type.
         /// This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
         #[weight = 10_000_000] // TODO: adjust weight
@@ -547,12 +511,7 @@ decl_module! {
             title: Vec<u8>,
             description: Vec<u8>,
             staking_account_id: Option<T::AccountId>,
-            fill_opening_parameters: FillOpeningParameters<
-                T::BlockNumber,
-                BalanceOfMint<T>,
-                working_group::OpeningId<T>,
-                working_group::ApplicationId<T>
-            >,
+            fill_opening_parameters: FillOpeningParameters,
             exact_execution_block: Option<T::BlockNumber>,
         ) {
             let proposal_details = ProposalDetails::FillWorkingGroupLeaderOpening(fill_opening_parameters);
@@ -571,10 +530,10 @@ decl_module! {
             Self::create_proposal(params)?;
         }
 
-        /// Create 'Set working group mint capacity' proposal type.
+        /// Create 'Set working group budget capacity' proposal type.
         /// This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
         #[weight = 10_000_000] // TODO: adjust weight
-        pub fn create_set_working_group_mint_capacity_proposal(
+        pub fn create_set_working_group_budget_capacity_proposal(
             origin,
             member_id: MemberId<T>,
             title: Vec<u8>,
@@ -585,11 +544,11 @@ decl_module! {
             exact_execution_block: Option<T::BlockNumber>,
         ) {
             ensure!(
-                mint_balance <= <BalanceOfMint<T>>::from(WORKING_GROUP_MINT_CAPACITY_MAX_VALUE),
-                Error::<T>::InvalidWorkingGroupMintCapacity
+                mint_balance <= <BalanceOfMint<T>>::from(WORKING_GROUP_BUDGET_CAPACITY_MAX_VALUE),
+                Error::<T>::InvalidWorkingGroupBudgetCapacity
             );
 
-            let proposal_details = ProposalDetails::SetWorkingGroupMintCapacity(mint_balance, working_group);
+            let proposal_details = ProposalDetails::SetWorkingGroupBudgetCapacity(mint_balance, working_group);
             let params = CreateProposalParameters{
                 origin,
                 member_id,
@@ -597,7 +556,7 @@ decl_module! {
                 description,
                 staking_account_id,
                 proposal_details: proposal_details.clone(),
-                proposal_parameters: T::SetWorkingGroupMintCapacityProposalParameters::get(),
+                proposal_parameters: T::SetWorkingGroupBudgetCapacityProposalParameters::get(),
                 proposal_code: T::ProposalEncoder::encode_proposal(proposal_details),
                 exact_execution_block,
             };
@@ -652,15 +611,15 @@ decl_module! {
             description: Vec<u8>,
             staking_account_id: Option<T::AccountId>,
             worker_id: working_group::WorkerId<T>,
-            slashing_stake: BalanceOf<T>,
+            penalty: Penalty<BalanceOf<T>>,
             working_group: WorkingGroup,
             exact_execution_block: Option<T::BlockNumber>,
         ) {
-            ensure!(slashing_stake != Zero::zero(), Error::<T>::SlashingStakeIsZero);
+            ensure!(penalty.slashing_amount != Zero::zero(), Error::<T>::SlashingStakeIsZero);
 
             let proposal_details = ProposalDetails::SlashWorkingGroupLeaderStake(
                 worker_id,
-                slashing_stake,
+                penalty,
                 working_group
             );
 
@@ -689,7 +648,7 @@ decl_module! {
             description: Vec<u8>,
             staking_account_id: Option<T::AccountId>,
             worker_id: working_group::WorkerId<T>,
-            reward_amount: BalanceOfMint<T>,
+            reward_amount: Option<BalanceOfMint<T>>,
             working_group: WorkingGroup,
             exact_execution_block: Option<T::BlockNumber>,
         ) {
@@ -723,7 +682,7 @@ decl_module! {
             title: Vec<u8>,
             description: Vec<u8>,
             staking_account_id: Option<T::AccountId>,
-            terminate_role_parameters: TerminateRoleParameters<working_group::WorkerId<T>>,
+            terminate_role_parameters: TerminateRoleParameters<working_group::WorkerId<T>, BalanceOf<T>>,
             exact_execution_block: Option<T::BlockNumber>,
         ) {
             let proposal_details = ProposalDetails::TerminateWorkingGroupLeaderRole(terminate_role_parameters);

+ 21 - 114
runtime-modules/proposals/codex/src/proposal_types/mod.rs

@@ -5,9 +5,10 @@ use codec::{Decode, Encode};
 use serde::{Deserialize, Serialize};
 use sp_std::vec::Vec;
 
-use crate::ElectionParameters;
 use common::working_group::WorkingGroup;
 
+use working_group::{Penalty, RewardPolicy, StakePolicy};
+
 /// Encodes proposal using its details information.
 pub trait ProposalEncoder<T: crate::Trait> {
     /// Encodes proposal using its details information.
@@ -20,11 +21,8 @@ pub type ProposalDetailsOf<T> = ProposalDetails<
     crate::BalanceOfGovernanceCurrency<T>,
     <T as frame_system::Trait>::BlockNumber,
     <T as frame_system::Trait>::AccountId,
-    working_group::OpeningId<T>,
-    working_group::ApplicationId<T>,
     crate::BalanceOf<T>,
     working_group::WorkerId<T>,
-    crate::MemberId<T>,
 >;
 
 /// Proposal details provide voters the information required for the perceived voting.
@@ -35,11 +33,8 @@ pub enum ProposalDetails<
     CurrencyBalance,
     BlockNumber,
     AccountId,
-    OpeningId,
-    ApplicationId,
     StakeBalance,
     WorkerId,
-    MemberId,
 > {
     /// The text of the `text` proposal
     Text(Vec<u8>),
@@ -47,88 +42,45 @@ pub enum ProposalDetails<
     /// The wasm code for the `runtime upgrade` proposal
     RuntimeUpgrade(Vec<u8>),
 
-    /// ********** Deprecated.
-    /// It is kept only for backward compatibility in the Pioneer. **********
-    /// Election parameters for the `set election parameters` proposal
-    SetElectionParameters(ElectionParameters<CurrencyBalance, BlockNumber>),
-
     /// Balance and destination account for the `spending` proposal
     Spending(MintedBalance, AccountId),
 
-    /// ********** Deprecated during the Babylon release.
-    /// It is kept only for backward compatibility in the Pioneer. **********
-    /// New leader memberId and account_id for the `set lead` proposal
-    DeprecatedSetLead(Option<(MemberId, AccountId)>),
-
-    /// ********** Deprecated during the Babylon release.
-    /// It is kept only for backward compatibility in the Pioneer. **********
-    /// Balance for the `set content working group mint capacity` proposal
-    DeprecatedSetContentWorkingGroupMintCapacity(MintedBalance),
-
-    /// ********** Deprecated during the Nicaea release.
-    /// It is kept only for backward compatibility in the Pioneer. **********
-    /// AccountId for the `evict storage provider` proposal
-    DeprecatedEvictStorageProvider(AccountId),
-
     /// Validator count for the `set validator count` proposal
     SetValidatorCount(u32),
 
-    /// ********** Deprecated during the Nicaea release.
-    /// It is kept only for backward compatibility in the Pioneer. **********
-    /// Role parameters for the `set storage role parameters` proposal
-    DeprecatedSetStorageRoleParameters(RoleParameters<CurrencyBalance, BlockNumber>),
-
     /// Add opening for the working group leader position.
     AddWorkingGroupLeaderOpening(AddOpeningParameters<BlockNumber, CurrencyBalance>),
 
-    /// Begin review applications for the working group leader position.
-    BeginReviewWorkingGroupLeaderApplications(OpeningId, WorkingGroup),
-
     /// Fill opening for the working group leader position.
-    FillWorkingGroupLeaderOpening(
-        FillOpeningParameters<BlockNumber, MintedBalance, OpeningId, ApplicationId>,
-    ),
+    FillWorkingGroupLeaderOpening(FillOpeningParameters),
 
-    /// Set working group mint capacity.
-    SetWorkingGroupMintCapacity(MintedBalance, WorkingGroup),
+    /// Set working group budget capacity.
+    SetWorkingGroupBudgetCapacity(MintedBalance, WorkingGroup),
 
     /// Decrease the working group leader stake.
     DecreaseWorkingGroupLeaderStake(WorkerId, StakeBalance, WorkingGroup),
 
     /// Slash the working group leader stake.
-    SlashWorkingGroupLeaderStake(WorkerId, StakeBalance, WorkingGroup),
+    SlashWorkingGroupLeaderStake(WorkerId, Penalty<StakeBalance>, WorkingGroup),
 
     /// Set working group leader reward balance.
-    SetWorkingGroupLeaderReward(WorkerId, MintedBalance, WorkingGroup),
+    SetWorkingGroupLeaderReward(WorkerId, Option<MintedBalance>, WorkingGroup),
 
     /// Fire the working group leader with possible slashing.
-    TerminateWorkingGroupLeaderRole(TerminateRoleParameters<WorkerId>),
+    TerminateWorkingGroupLeaderRole(TerminateRoleParameters<WorkerId, StakeBalance>),
 
     /// Amend constitution.
     AmendConstitution(Vec<u8>),
 }
 
-impl<
-        MintedBalance,
-        CurrencyBalance,
-        BlockNumber,
-        AccountId,
-        OpeningId,
-        ApplicationId,
-        StakeBalance,
-        WorkerId,
-        MemberId,
-    > Default
+impl<MintedBalance, CurrencyBalance, BlockNumber, AccountId, StakeBalance, WorkerId> Default
     for ProposalDetails<
         MintedBalance,
         CurrencyBalance,
         BlockNumber,
         AccountId,
-        OpeningId,
-        ApplicationId,
         StakeBalance,
         WorkerId,
-        MemberId,
     >
 {
     fn default() -> Self {
@@ -139,15 +91,12 @@ impl<
 /// Parameters for the 'terminate the leader position' proposal.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Debug)]
-pub struct TerminateRoleParameters<WorkerId> {
+pub struct TerminateRoleParameters<WorkerId, Balance> {
     /// Leader worker id to fire.
     pub worker_id: WorkerId,
 
-    /// Terminate role rationale.
-    pub rationale: Vec<u8>,
-
-    /// Slash the leader stake on terminating.
-    pub slash: bool,
+    /// Terminate role slash penalty.
+    pub penalty: Option<Penalty<Balance>>,
 
     /// Defines working group with the open position.
     pub working_group: WorkingGroup,
@@ -156,15 +105,12 @@ pub struct TerminateRoleParameters<WorkerId> {
 /// Parameters for the 'fill opening for the leader position' proposal.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Debug)]
-pub struct FillOpeningParameters<BlockNumber, Balance, OpeningId, ApplicationId> {
+pub struct FillOpeningParameters {
     /// Finalizing opening id.
-    pub opening_id: OpeningId,
+    pub opening_id: working_group::OpeningId,
 
     /// Id of the selected application.
-    pub successful_application_id: ApplicationId,
-
-    /// Position reward policy.
-    pub reward_policy: Option<working_group::RewardPolicy<Balance, BlockNumber>>,
+    pub successful_application_id: working_group::ApplicationId,
 
     /// Defines working group with the open position.
     pub working_group: WorkingGroup,
@@ -174,54 +120,15 @@ pub struct FillOpeningParameters<BlockNumber, Balance, OpeningId, ApplicationId>
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Debug)]
 pub struct AddOpeningParameters<BlockNumber, Balance> {
-    /// Activate opening at block.
-    pub activate_at: hiring::ActivateOpeningAt<BlockNumber>,
+    /// Opening description.
+    pub description: Vec<u8>,
 
-    /// Opening conditions.
-    pub commitment: working_group::OpeningPolicyCommitment<BlockNumber, Balance>,
+    /// Stake policy for the opening.
+    pub stake_policy: Option<StakePolicy<BlockNumber, Balance>>,
 
-    /// Opening description.
-    pub human_readable_text: Vec<u8>,
+    /// Reward policy for the opening.
+    pub reward_policy: Option<RewardPolicy<Balance>>,
 
     /// Defines working group with the open position.
     pub working_group: WorkingGroup,
 }
-
-/// ********** Deprecated during the Nicaea release.
-/// It is kept only for backward compatibility in the Pioneer. **********
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)]
-pub struct RoleParameters<Balance, BlockNumber> {
-    /// Minimum balance required to stake to enter a role.
-    pub min_stake: Balance,
-
-    /// Minimum actors to maintain - if role is unstaking
-    /// and remaining actors would be less that this value - prevent or punish for unstaking.
-    pub min_actors: u32,
-
-    /// The maximum number of spots available to fill for a role.
-    pub max_actors: u32,
-
-    /// Fixed amount of tokens paid to actors' primary account.
-    pub reward: Balance,
-
-    /// Payouts are made at this block interval.
-    pub reward_period: BlockNumber,
-
-    /// Minimum amount of time before being able to unstake.
-    pub bonding_period: BlockNumber,
-
-    /// How long tokens remain locked for after unstaking.
-    pub unbonding_period: BlockNumber,
-
-    /// Minimum period required to be in service. unbonding before this time is highly penalized
-    pub min_service_period: BlockNumber,
-
-    /// "Startup" time allowed for roles that need to sync their infrastructure
-    /// with other providers before they are considered in service and punishable for
-    /// not delivering required level of service.
-    pub startup_grace_period: BlockNumber,
-
-    /// Small fee burned to make a request to enter role.
-    pub entry_request_fee: Balance,
-}

+ 11 - 1
runtime-modules/proposals/codex/src/tests/mock/mod.rs

@@ -166,16 +166,26 @@ pub type StorageWorkingGroupInstance = working_group::Instance2;
 
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 100;
+    pub const LockId1: [u8; 8] = [1; 8];
+    pub const LockId2: [u8; 8] = [2; 8];
 }
 
 impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Test {
     type Event = ();
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler = staking_handler::StakingManager<Self, LockId1>;
+    type MemberOriginValidator = ();
+    type MinUnstakingPeriodLimit = ();
+    type RewardPeriod = ();
 }
 
 impl working_group::Trait<StorageWorkingGroupInstance> for Test {
     type Event = ();
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler = staking_handler::StakingManager<Self, LockId2>;
+    type MemberOriginValidator = ();
+    type MinUnstakingPeriodLimit = ();
+    type RewardPeriod = ();
 }
 
 impl recurring_rewards::Trait for Test {
@@ -284,7 +294,7 @@ impl crate::Trait for Test {
     type AddWorkingGroupOpeningProposalParameters = DefaultProposalParameters;
     type BeginReviewWorkingGroupApplicationsProposalParameters = DefaultProposalParameters;
     type FillWorkingGroupOpeningProposalParameters = DefaultProposalParameters;
-    type SetWorkingGroupMintCapacityProposalParameters = DefaultProposalParameters;
+    type SetWorkingGroupBudgetCapacityProposalParameters = DefaultProposalParameters;
     type DecreaseWorkingGroupLeaderStakeProposalParameters = DefaultProposalParameters;
     type SlashWorkingGroupLeaderStakeProposalParameters = DefaultProposalParameters;
     type SetWorkingGroupLeaderRewardProposalParameters = DefaultProposalParameters;

+ 45 - 89
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -6,9 +6,7 @@ use frame_support::traits::Currency;
 use frame_system::RawOrigin;
 
 use common::working_group::WorkingGroup;
-use hiring::ActivateOpeningAt;
 use proposals_engine::ProposalParameters;
-use working_group::OpeningPolicyCommitment;
 
 use crate::*;
 use crate::{Error, ProposalDetails};
@@ -38,7 +36,7 @@ where
     empty_stake_call: EmptyStakeCall,
     successful_call: SuccessfulCall,
     proposal_parameters: ProposalParameters<u64, u64>,
-    proposal_details: ProposalDetails<u64, u64, u64, u64, u64, u64, u64, u64, u64>,
+    proposal_details: ProposalDetails<u64, u64, u64, u64, u64, u64>,
 }
 
 impl<InsufficientRightsCall, EmptyStakeCall, SuccessfulCall>
@@ -412,9 +410,9 @@ fn run_create_add_working_group_leader_opening_proposal_common_checks_succeed(
 ) {
     initial_test_ext().execute_with(|| {
         let add_opening_parameters = AddOpeningParameters {
-            activate_at: ActivateOpeningAt::CurrentBlock,
-            commitment: OpeningPolicyCommitment::default(),
-            human_readable_text: b"some text".to_vec(),
+            description: b"some text".to_vec(),
+            stake_policy: None,
+            reward_policy: None,
             working_group,
         };
 
@@ -464,69 +462,6 @@ fn run_create_add_working_group_leader_opening_proposal_common_checks_succeed(
     });
 }
 
-#[test]
-fn create_begin_review_working_group_leader_applications_proposal_common_checks_succeed() {
-    // This uses strum crate for enum iteration
-    for group in WorkingGroup::iter() {
-        run_create_begin_review_working_group_leader_applications_proposal_common_checks_succeed(
-            group,
-        );
-    }
-}
-
-fn run_create_begin_review_working_group_leader_applications_proposal_common_checks_succeed(
-    working_group: WorkingGroup,
-) {
-    initial_test_ext().execute_with(|| {
-        let opening_id = 1; // random opening id.
-
-        increase_total_balance_issuance_using_account_id(1, 500000);
-
-        let proposal_fixture = ProposalTestFixture {
-            insufficient_rights_call: || {
-                ProposalCodex::create_begin_review_working_group_leader_applications_proposal(
-                    RawOrigin::None.into(),
-                    1,
-                    b"title".to_vec(),
-                    b"body".to_vec(),
-                    None,
-                    opening_id,
-                    working_group,
- 					None,
-                )
-            },
-            empty_stake_call: || {
-                ProposalCodex::create_begin_review_working_group_leader_applications_proposal(
-                    RawOrigin::Signed(1).into(),
-                    1,
-                    b"title".to_vec(),
-                    b"body".to_vec(),
-                    None,
-                    opening_id,
-                    working_group,
- 					None,
-                )
-            },
-            successful_call: || {
-                ProposalCodex::create_begin_review_working_group_leader_applications_proposal(
-                    RawOrigin::Signed(1).into(),
-                    1,
-                    b"title".to_vec(),
-                    b"body".to_vec(),
-                    Some(1),
-                    opening_id,
-                    working_group,
- 					None,
-                )
-            },
-            proposal_parameters: <Test as crate::Trait>::BeginReviewWorkingGroupApplicationsProposalParameters::get(),
-            proposal_details: ProposalDetails::BeginReviewWorkingGroupLeaderApplications(opening_id,
-                working_group),
-        };
-        proposal_fixture.check_all();
-    });
-}
-
 #[test]
 fn create_fill_working_group_leader_opening_proposal_common_checks_succeed() {
     // This uses strum crate for enum iteration
@@ -544,7 +479,6 @@ fn run_create_fill_working_group_leader_opening_proposal_common_checks_succeed(
         let fill_opening_parameters = FillOpeningParameters {
             opening_id,
             successful_application_id: 1,
-            reward_policy: None,
             working_group,
         };
 
@@ -609,17 +543,17 @@ fn run_create_working_group_mint_capacity_proposal_fails_with_invalid_parameters
         increase_total_balance_issuance_using_account_id(1, 500000);
 
         assert_eq!(
-            ProposalCodex::create_set_working_group_mint_capacity_proposal(
+            ProposalCodex::create_set_working_group_budget_capacity_proposal(
                 RawOrigin::Signed(1).into(),
                 1,
                 b"title".to_vec(),
                 b"body".to_vec(),
                 Some(1),
-                (crate::WORKING_GROUP_MINT_CAPACITY_MAX_VALUE + 1) as u64,
+                (crate::WORKING_GROUP_BUDGET_CAPACITY_MAX_VALUE + 1) as u64,
                 working_group,
                 None,
             ),
-            Err(Error::<Test>::InvalidWorkingGroupMintCapacity.into())
+            Err(Error::<Test>::InvalidWorkingGroupBudgetCapacity.into())
         );
     });
 }
@@ -640,7 +574,7 @@ fn run_create_set_working_group_mint_capacity_proposal_common_checks_succeed(
 
         let proposal_fixture = ProposalTestFixture {
             insufficient_rights_call: || {
-                ProposalCodex::create_set_working_group_mint_capacity_proposal(
+                ProposalCodex::create_set_working_group_budget_capacity_proposal(
                     RawOrigin::None.into(),
                     1,
                     b"title".to_vec(),
@@ -652,7 +586,7 @@ fn run_create_set_working_group_mint_capacity_proposal_common_checks_succeed(
                 )
             },
             empty_stake_call: || {
-                ProposalCodex::create_set_working_group_mint_capacity_proposal(
+                ProposalCodex::create_set_working_group_budget_capacity_proposal(
                     RawOrigin::Signed(1).into(),
                     1,
                     b"title".to_vec(),
@@ -664,7 +598,7 @@ fn run_create_set_working_group_mint_capacity_proposal_common_checks_succeed(
                 )
             },
             successful_call: || {
-                ProposalCodex::create_set_working_group_mint_capacity_proposal(
+                ProposalCodex::create_set_working_group_budget_capacity_proposal(
                     RawOrigin::Signed(1).into(),
                     1,
                     b"title".to_vec(),
@@ -676,8 +610,8 @@ fn run_create_set_working_group_mint_capacity_proposal_common_checks_succeed(
                 )
             },
             proposal_parameters:
-                <Test as crate::Trait>::SetWorkingGroupMintCapacityProposalParameters::get(),
-            proposal_details: ProposalDetails::SetWorkingGroupMintCapacity(10, working_group),
+                <Test as crate::Trait>::SetWorkingGroupBudgetCapacityProposalParameters::get(),
+            proposal_details: ProposalDetails::SetWorkingGroupBudgetCapacity(10, working_group),
         };
         proposal_fixture.check_all();
     });
@@ -772,7 +706,10 @@ fn run_create_slash_working_group_leader_stake_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     None,
                     0,
-                    10,
+                    Penalty {
+                        slashing_amount: 10,
+                        slashing_text: Vec::new(),
+                    },
                     working_group,
                     None,
                 )
@@ -785,7 +722,10 @@ fn run_create_slash_working_group_leader_stake_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     None,
                     0,
-                    10,
+                    Penalty {
+                        slashing_amount: 10,
+                        slashing_text: Vec::new(),
+                    },
                     working_group,
                     None,
                 )
@@ -798,14 +738,24 @@ fn run_create_slash_working_group_leader_stake_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     Some(1),
                     10,
-                    10,
+                    Penalty {
+                        slashing_amount: 10,
+                        slashing_text: Vec::new(),
+                    },
                     working_group,
                     None,
                 )
             },
             proposal_parameters:
                 <Test as crate::Trait>::SlashWorkingGroupLeaderStakeProposalParameters::get(),
-            proposal_details: ProposalDetails::SlashWorkingGroupLeaderStake(10, 10, working_group),
+            proposal_details: ProposalDetails::SlashWorkingGroupLeaderStake(
+                10,
+                Penalty {
+                    slashing_amount: 10,
+                    slashing_text: Vec::new(),
+                },
+                working_group,
+            ),
         };
         proposal_fixture.check_all();
     });
@@ -838,7 +788,10 @@ fn run_slash_stake_with_zero_staking_balance_fails(working_group: WorkingGroup)
                 b"body".to_vec(),
                 Some(1),
                 10,
-                0,
+                Penalty {
+                    slashing_amount: 0,
+                    slashing_text: Vec::new()
+                },
                 working_group,
                 None,
             ),
@@ -904,7 +857,7 @@ fn run_create_set_working_group_leader_reward_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     None,
                     0,
-                    10,
+                    Some(10),
                     working_group,
                     None,
                 )
@@ -917,7 +870,7 @@ fn run_create_set_working_group_leader_reward_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     None,
                     0,
-                    10,
+                    Some(10),
                     working_group,
                     None,
                 )
@@ -930,14 +883,18 @@ fn run_create_set_working_group_leader_reward_proposal_common_checks_succeed(
                     b"body".to_vec(),
                     Some(1),
                     10,
-                    10,
+                    Some(10),
                     working_group,
                     None,
                 )
             },
             proposal_parameters:
                 <Test as crate::Trait>::SlashWorkingGroupLeaderStakeProposalParameters::get(),
-            proposal_details: ProposalDetails::SetWorkingGroupLeaderReward(10, 10, working_group),
+            proposal_details: ProposalDetails::SetWorkingGroupLeaderReward(
+                10,
+                Some(10),
+                working_group,
+            ),
         };
         proposal_fixture.check_all();
     });
@@ -959,8 +916,7 @@ fn run_create_terminate_working_group_leader_role_proposal_common_checks_succeed
 
         let terminate_role_parameters = TerminateRoleParameters {
             worker_id: 10,
-            rationale: Vec::new(),
-            slash: false,
+            penalty: None,
             working_group,
         };
 

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

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-service-discovery'
-version = '3.1.0'
+version = '4.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
@@ -8,6 +8,7 @@ edition = '2018'
 serde = { version = "1.0.101", optional = true, features = ["derive"] }
 codec = { package = 'parity-scale-codec', version = '1.3.4', default-features = false, features = ['derive'] }
 sp-std = { package = 'sp-std', 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'}
 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-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
@@ -31,6 +32,7 @@ std = [
 	'serde',
 	'codec/std',
 	'sp-std/std',
+	'sp-arithmetic/std',
 	'frame-support/std',
 	'frame-system/std',
 	'sp-runtime/std',

+ 4 - 5
runtime-modules/service-discovery/src/lib.rs

@@ -30,6 +30,8 @@ use frame_support::{decl_event, decl_module, decl_storage, ensure};
 use frame_system::ensure_root;
 use sp_std::vec::Vec;
 
+use working_group::ensure_worker_signed;
+
 /*
   Although there is support for ed25519 keys as the IPNS identity key and we could potentially
   reuse the same key for the role account and ipns (and make this discovery module obselete)
@@ -52,9 +54,6 @@ pub type Url = Vec<u8>;
 // The storage working group instance alias.
 pub(crate) type StorageWorkingGroupInstance = working_group::Instance2;
 
-// Alias for storage working group.
-pub(crate) type StorageWorkingGroup<T> = working_group::Module<T, StorageWorkingGroupInstance>;
-
 /// Storage provider is a worker from the  working_group module.
 pub type StorageProviderId<T> = working_group::WorkerId<T>;
 
@@ -124,7 +123,7 @@ decl_module! {
             storage_provider_id: StorageProviderId<T>,
             id: Vec<u8>,
         ) {
-            <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+            ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
             // TODO: ensure id is a valid base58 encoded IPNS identity
 
@@ -144,7 +143,7 @@ decl_module! {
         /// Requires signed storage provider credentials.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn unset_ipns_id(origin, storage_provider_id: StorageProviderId<T>) {
-            <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+            ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
             // == MUTATION SAFE ==
 

+ 25 - 5
runtime-modules/service-discovery/src/mock.rs → runtime-modules/service-discovery/src/mock/mod.rs

@@ -13,6 +13,8 @@ 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;
@@ -136,11 +138,24 @@ impl recurringrewards::Trait for Test {
 
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 3;
+    pub const LockId1: [u8; 8] = [1; 8];
 }
 
 impl working_group::Trait<StorageWorkingGroupInstance> for Test {
     type Event = MetaEvent;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler = staking_handler::StakingManager<Self, LockId1>;
+    type MemberOriginValidator = ();
+    type MinUnstakingPeriodLimit = ();
+    type RewardPeriod = ();
+}
+
+impl common::origin::ActorOriginValidator<Origin, u64, u64> for () {
+    fn ensure_actor_origin(origin: Origin, _: u64) -> Result<u64, &'static str> {
+        let account_id = frame_system::ensure_signed(origin)?;
+
+        Ok(account_id)
+    }
 }
 
 impl pallet_timestamp::Trait for Test {
@@ -163,14 +178,19 @@ pub type System = frame_system::Module<Test>;
 pub type Discovery = Module<Test>;
 
 pub(crate) fn hire_storage_provider() -> (u64, u64) {
-    let storage_provider_id = 1;
-    let role_account_id = 1;
+    let storage_provider_id = 1u64;
+    let role_account_id = 1u64;
 
-    let storage_provider = working_group::Worker {
+    let storage_provider = working_group::Worker::<Test> {
         member_id: 1,
         role_account_id,
-        reward_relationship: None,
-        role_stake_profile: None,
+        staking_account_id: None,
+        reward_account_id: role_account_id,
+        started_leaving_at: None,
+        job_unstaking_period: 0,
+        reward_per_block: None,
+        missed_reward: None,
+        created_at: 1,
     };
 
     <working_group::WorkerById<Test, StorageWorkingGroupInstance>>::insert(

+ 0 - 0
runtime-modules/working-team/src/tests/mock/staking_handler.rs → runtime-modules/service-discovery/src/mock/staking_handler.rs


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

@@ -1,6 +1,6 @@
 [package]
 name = 'pallet-storage'
-version = '3.1.0'
+version = '4.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 

+ 6 - 4
runtime-modules/storage/src/data_directory.rs

@@ -36,9 +36,11 @@ use serde::{Deserialize, Serialize};
 use common::origin::ActorOriginValidator;
 pub(crate) use common::BlockAndTime;
 
+use working_group::ensure_worker_signed;
+
 use crate::data_object_type_registry;
 use crate::data_object_type_registry::IsActiveDataObjectType;
-use crate::{MemberId, StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::{MemberId, StorageProviderId, StorageWorkingGroupInstance};
 
 /// The _Data directory_ main _Trait_.
 pub trait Trait:
@@ -208,7 +210,7 @@ decl_module! {
             size: u64,
             ipfs_content_id: Vec<u8>
         ) {
-            T::MemberOriginValidator::ensure_actor_origin(
+            <T as Trait>::MemberOriginValidator::ensure_actor_origin(
                 origin,
                 member_id,
             )?;
@@ -248,7 +250,7 @@ decl_module! {
             storage_provider_id: StorageProviderId<T>,
             content_id: T::ContentId
         ) {
-            <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+            ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
             // == MUTATION SAFE ==
 
@@ -267,7 +269,7 @@ decl_module! {
             storage_provider_id: StorageProviderId<T>,
             content_id: T::ContentId
         ) {
-            <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+            ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
             // == MUTATION SAFE ==
 

+ 5 - 3
runtime-modules/storage/src/data_object_storage_registry.rs

@@ -30,7 +30,9 @@ use sp_runtime::traits::{MaybeSerialize, Member};
 use sp_std::vec::Vec;
 
 use crate::data_directory::{self, ContentIdExists};
-use crate::{StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::{StorageProviderId, StorageWorkingGroupInstance};
+
+use working_group::ensure_worker_signed;
 
 const DEFAULT_FIRST_RELATIONSHIP_ID: u8 = 1;
 
@@ -144,7 +146,7 @@ decl_module! {
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_relationship(origin, storage_provider_id: StorageProviderId<T>, cid: T::ContentId) {
             // Origin should match storage provider.
-            <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+            ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
             // Content ID must exist
             ensure!(T::ContentIdExists::has_content(&cid), Error::<T>::CidNotFound);
@@ -209,7 +211,7 @@ impl<T: Trait> Module<T> {
         id: T::DataObjectStorageRelationshipId,
         ready: bool,
     ) -> DispatchResult {
-        <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
+        ensure_worker_signed::<T, StorageWorkingGroupInstance>(origin, &storage_provider_id)?;
 
         // For that, we need to fetch the identified DOSR
         let mut dosr =

+ 7 - 5
runtime-modules/storage/src/data_object_type_registry.rs

@@ -30,7 +30,9 @@ use sp_arithmetic::traits::BaseArithmetic;
 use sp_runtime::traits::{MaybeSerialize, Member};
 use sp_std::vec::Vec;
 
-use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::StorageWorkingGroupInstance;
+
+use working_group::ensure_origin_is_active_leader;
 
 const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
 const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u8 = 1;
@@ -138,7 +140,7 @@ decl_module! {
         /// Registers the new data object type. Requires leader privileges.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn register_data_object_type(origin, data_object_type: DataObjectType) {
-            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure_origin_is_active_leader::<T, StorageWorkingGroupInstance>(origin)?;
 
             let new_do_type_id = Self::next_data_object_type_id();
             let do_type: DataObjectType = DataObjectType {
@@ -159,7 +161,7 @@ decl_module! {
         /// Updates existing data object type. Requires leader privileges.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_data_object_type(origin, id: T::DataObjectTypeId, data_object_type: DataObjectType) {
-            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure_origin_is_active_leader::<T, StorageWorkingGroupInstance>(origin)?;
 
             let mut do_type = Self::ensure_data_object_type(id)?;
 
@@ -178,7 +180,7 @@ decl_module! {
         /// Activates existing data object type. Requires leader privileges.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn activate_data_object_type(origin, id: T::DataObjectTypeId) {
-            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure_origin_is_active_leader::<T, StorageWorkingGroupInstance>(origin)?;
 
             let mut do_type = Self::ensure_data_object_type(id)?;
 
@@ -196,7 +198,7 @@ decl_module! {
         /// Deactivates existing data object type. Requires leader privileges.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn deactivate_data_object_type(origin, id: T::DataObjectTypeId) {
-            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure_origin_is_active_leader::<T, StorageWorkingGroupInstance>(origin)?;
 
             let mut do_type = Self::ensure_data_object_type(id)?;
 

+ 0 - 3
runtime-modules/storage/src/lib.rs

@@ -10,9 +10,6 @@ mod tests;
 // The storage working group instance alias.
 pub type StorageWorkingGroupInstance = working_group::Instance2;
 
-// Alias for storage working group
-pub(crate) type StorageWorkingGroup<T> = working_group::Module<T, StorageWorkingGroupInstance>;
-
 // Alias for the member id.
 pub(crate) type MemberId<T> = <T as membership::Trait>::MemberId;
 

+ 8 - 3
runtime-modules/storage/src/tests/data_object_type_registry.rs

@@ -12,11 +12,16 @@ const DEFAULT_LEADER_WORKER_ID: u32 = 1;
 struct SetLeadFixture;
 impl SetLeadFixture {
     fn set_default_lead() {
-        let worker = working_group::Worker {
+        let worker = working_group::Worker::<Test> {
             member_id: DEFAULT_LEADER_MEMBER_ID,
             role_account_id: DEFAULT_LEADER_ACCOUNT_ID,
-            reward_relationship: None,
-            role_stake_profile: None,
+            staking_account_id: None,
+            reward_account_id: DEFAULT_LEADER_ACCOUNT_ID,
+            started_leaving_at: None,
+            job_unstaking_period: 0,
+            reward_per_block: None,
+            missed_reward: None,
+            created_at: 1,
         };
 
         // Create the worker.

+ 24 - 12
runtime-modules/storage/src/tests/mock.rs → runtime-modules/storage/src/tests/mock/mod.rs

@@ -1,7 +1,7 @@
 #![cfg(test)]
 
 use frame_support::storage::StorageMap;
-use frame_support::traits::{OnFinalize, OnInitialize};
+use frame_support::traits::{LockIdentifier, OnFinalize, OnInitialize};
 use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
 use sp_core::H256;
 use sp_runtime::{
@@ -17,6 +17,8 @@ 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;
@@ -152,11 +154,24 @@ impl GovernanceCurrency for Test {
 
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 3;
+    pub const LockId: LockIdentifier = [2; 8];
 }
 
 impl working_group::Trait<StorageWorkingGroupInstance> for Test {
     type Event = MetaEvent;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler = staking_handler::StakingManager<Self, LockId>;
+    type MemberOriginValidator = ();
+    type MinUnstakingPeriodLimit = ();
+    type RewardPeriod = ();
+}
+
+impl common::origin::ActorOriginValidator<Origin, u64, u64> for () {
+    fn ensure_actor_origin(origin: Origin, _: u64) -> Result<u64, &'static str> {
+        let account_id = frame_system::ensure_signed(origin)?;
+
+        Ok(account_id)
+    }
 }
 
 impl data_object_type_registry::Trait for Test {
@@ -179,14 +194,6 @@ impl crate::data_directory::StorageProviderHelper<Test> for () {
     }
 }
 
-impl common::origin::ActorOriginValidator<Origin, u64, u64> for () {
-    fn ensure_actor_origin(origin: Origin, _account_id: u64) -> Result<u64, &'static str> {
-        let signed_account_id = frame_system::ensure_signed(origin)?;
-
-        Ok(signed_account_id)
-    }
-}
-
 impl data_object_storage_registry::Trait for Test {
     type Event = MetaEvent;
     type DataObjectStorageRelationshipId = u64;
@@ -320,11 +327,16 @@ pub(crate) fn hire_storage_provider() -> (u64, u32) {
     let storage_provider_id = 1;
     let role_account_id = 1;
 
-    let storage_provider = working_group::Worker {
+    let storage_provider = working_group::Worker::<Test> {
         member_id: 1,
         role_account_id,
-        reward_relationship: None,
-        role_stake_profile: None,
+        staking_account_id: None,
+        reward_account_id: role_account_id,
+        started_leaving_at: None,
+        job_unstaking_period: 0,
+        reward_per_block: None,
+        missed_reward: None,
+        created_at: 1,
     };
 
     <working_group::WorkerById<Test, StorageWorkingGroupInstance>>::insert(

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

@@ -0,0 +1,98 @@
+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)
+    }
+}

+ 14 - 19
runtime-modules/working-group/Cargo.toml

@@ -1,44 +1,39 @@
 [package]
-name = 'pallet-working-group'
-version = '3.1.0'
+name = "pallet-working-group"
+version = "4.0.0"
 authors = ['Joystream contributors']
 edition = '2018'
 
 [dependencies]
 serde = { version = "1.0.101", optional = true, features = ["derive"] }
-codec = { package = 'parity-scale-codec', version = '1.3.4', default-features = false, features = ['derive'] }
-sp-std = { package = 'sp-std', 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'}
 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'}
-sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
-membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
-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'}
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 common = { package = 'pallet-common', default-features = false, path = '../common'}
+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}
 
 [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'}
-balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 
 [features]
 default = ['std']
+runtime-benchmarks = ["frame-benchmarking"]
 std = [
 	'serde',
 	'codec/std',
-	'sp-std/std',
+	'sp-runtime/std',
 	'frame-support/std',
 	'frame-system/std',
 	'sp-arithmetic/std',
-	'sp-runtime/std',
-	'membership/std',
-	'stake/std',
-	'hiring/std',
-	'minting/std',
-	'recurringrewards/std',
+	'sp-std/std',
 	'common/std',
-]
+	'membership/std',
+	'balances/std',
+]

+ 91 - 91
runtime-modules/working-team/src/benchmarking.rs → runtime-modules/working-group/src/benchmarking.rs

@@ -12,7 +12,7 @@ use sp_std::prelude::*;
 use system as frame_system;
 
 use crate::types::StakeParameters;
-use crate::Module as WorkingTeam;
+use crate::Module as WorkingGroup;
 use membership::Module as Membership;
 
 const SEED: u32 = 0;
@@ -39,7 +39,7 @@ fn add_opening_helper<T: Trait<I>, I: Instance>(
     id: u32,
     add_opening_origin: &T::Origin,
     staking_role: &StakingRole,
-    job_opening_type: &JobOpeningType,
+    job_opening_type: &OpeningType,
 ) -> T::OpeningId {
     let staking_policy = match staking_role {
         StakingRole::WithStakes => Some(StakePolicy {
@@ -49,7 +49,7 @@ fn add_opening_helper<T: Trait<I>, I: Instance>(
         StakingRole::WithoutStakes => None,
     };
 
-    WorkingTeam::<T, _>::add_opening(
+    WorkingGroup::<T, _>::add_opening(
         add_opening_origin.clone(),
         vec![],
         *job_opening_type,
@@ -89,7 +89,7 @@ fn apply_on_opening_helper<T: Trait<I>, I: Instance>(
         StakingRole::WithoutStakes => None,
     };
 
-    WorkingTeam::<T, _>::apply_on_opening(
+    WorkingGroup::<T, _>::apply_on_opening(
         RawOrigin::Signed(applicant_id.clone()).into(),
         ApplyOnOpeningParameters::<T, I> {
             member_id: *member_id,
@@ -116,7 +116,7 @@ fn add_opening_and_apply_with_multiple_ids<T: Trait<I>, I: Instance>(
     ids: &Vec<u32>,
     add_opening_origin: &T::Origin,
     staking_role: &StakingRole,
-    job_opening_type: &JobOpeningType,
+    job_opening_type: &OpeningType,
 ) -> (T::OpeningId, BTreeSet<T::ApplicationId>, Vec<T::AccountId>) {
     let opening_id =
         add_opening_helper::<T, I>(1, add_opening_origin, &staking_role, job_opening_type);
@@ -147,7 +147,7 @@ fn add_and_apply_opening<T: Trait<I>, I: Instance>(
     staking_role: &StakingRole,
     applicant_id: &T::AccountId,
     member_id: &T::MemberId,
-    job_opening_type: &JobOpeningType,
+    job_opening_type: &OpeningType,
 ) -> (T::OpeningId, T::ApplicationId) {
     let opening_id =
         add_opening_helper::<T, I>(id, add_opening_origin, staking_role, job_opening_type);
@@ -209,22 +209,22 @@ fn force_missed_reward<T: Trait<I>, I: Instance>() {
     let curr_block_number =
         System::<T>::block_number().saturating_add(T::RewardPeriod::get().into());
     System::<T>::set_block_number(curr_block_number);
-    WorkingTeam::<T, _>::set_budget(RawOrigin::Root.into(), Zero::zero()).unwrap();
-    WorkingTeam::<T, _>::on_initialize(curr_block_number);
+    WorkingGroup::<T, _>::set_budget(RawOrigin::Root.into(), Zero::zero()).unwrap();
+    WorkingGroup::<T, _>::on_initialize(curr_block_number);
 }
 
 fn insert_a_worker<T: Trait<I>, I: Instance>(
     staking_role: StakingRole,
-    job_opening_type: JobOpeningType,
+    job_opening_type: OpeningType,
     id: u32,
     lead_id: Option<T::AccountId>,
-) -> (T::AccountId, TeamWorkerId<T>)
+) -> (T::AccountId, WorkerId<T>)
 where
-    WorkingTeam<T, I>: OnInitialize<T::BlockNumber>,
+    WorkingGroup<T, I>: OnInitialize<T::BlockNumber>,
 {
     let add_worker_origin = match job_opening_type {
-        JobOpeningType::Leader => RawOrigin::Root,
-        JobOpeningType::Regular => RawOrigin::Signed(lead_id.clone().unwrap()),
+        OpeningType::Leader => RawOrigin::Root,
+        OpeningType::Regular => RawOrigin::Signed(lead_id.clone().unwrap()),
     };
 
     let (caller_id, member_id) = member_funded_account::<T>("member", id);
@@ -240,7 +240,7 @@ where
 
     let mut successful_application_ids = BTreeSet::<T::ApplicationId>::new();
     successful_application_ids.insert(application_id);
-    WorkingTeam::<T, _>::fill_opening(
+    WorkingGroup::<T, _>::fill_opening(
         add_worker_origin.clone().into(),
         opening_id,
         successful_application_ids,
@@ -251,7 +251,7 @@ where
     // remaining reward
     force_missed_reward::<T, I>();
 
-    let worker_id = TeamWorkerId::<T>::from(id.try_into().unwrap());
+    let worker_id = WorkerId::<T>::from(id.try_into().unwrap());
 
     assert!(WorkerById::<T, I>::contains_key(worker_id));
 
@@ -266,7 +266,7 @@ benchmarks_instance! {
 
         let (lead_id, lead_worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
@@ -276,10 +276,10 @@ benchmarks_instance! {
                 &(1..i).collect(),
                 &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
                 &StakingRole::WithStakes,
-                &JobOpeningType::Regular
+                &OpeningType::Regular
             );
 
-        WorkingTeam::<T, _>::fill_opening(
+        WorkingGroup::<T, _>::fill_opening(
             RawOrigin::Signed(lead_id.clone()).into(),
             opening_id,
             successful_application_ids.clone()
@@ -288,25 +288,25 @@ benchmarks_instance! {
         force_missed_reward::<T,I>();
 
         // Force all workers to leave (Including the lead)
-        // We should have every TeamWorkerId from 0 to i-1
+        // We should have every WorkerId from 0 to i-1
         // Corresponding to each account id
         let mut worker_id = Zero::zero();
         for id in application_account_id {
             worker_id += One::one();
-            WorkingTeam::<T, _>::leave_role(RawOrigin::Signed(id).into(), worker_id).unwrap();
+            WorkingGroup::<T, _>::leave_role(RawOrigin::Signed(id).into(), worker_id).unwrap();
         }
 
         // Worst case scenario one of the leaving workers is the lead
-        WorkingTeam::<T, _>::leave_role(
+        WorkingGroup::<T, _>::leave_role(
             RawOrigin::Signed(lead_id).into(),
             lead_worker_id
         ).unwrap();
 
         for i in 1..successful_application_ids.len() {
-            let worker = TeamWorkerId::<T>::from(i.try_into().unwrap());
+            let worker = WorkerId::<T>::from(i.try_into().unwrap());
             assert!(WorkerById::<T, I>::contains_key(worker), "Not all workers added");
             assert_eq!(
-                WorkingTeam::<T, _>::worker_by_id(worker).started_leaving_at,
+                WorkingGroup::<T, _>::worker_by_id(worker).started_leaving_at,
                 Some(System::<T>::block_number()),
                 "Worker hasn't started leaving"
             );
@@ -319,13 +319,13 @@ benchmarks_instance! {
         let curr_block_number =
             System::<T>::block_number().saturating_add(leaving_unstaking_period.into());
         System::<T>::set_block_number(curr_block_number);
-        WorkingTeam::<T, _>::set_budget(
+        WorkingGroup::<T, _>::set_budget(
             RawOrigin::Root.into(),
             BalanceOfCurrency::<T>::max_value()
         ).unwrap();
 
-        assert_eq!(WorkingTeam::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
-    }: { WorkingTeam::<T, _>::on_initialize(curr_block_number) }
+        assert_eq!(WorkingGroup::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
+    }: { WorkingGroup::<T, _>::on_initialize(curr_block_number) }
     verify {
         WorkerById::<T, I>::iter().for_each(|(worker_id, _)| {
             assert!(!WorkerById::<T, I>::contains_key(worker_id), "Worker hasn't left");
@@ -334,7 +334,7 @@ benchmarks_instance! {
         let reward_per_worker = BalanceOfCurrency::<T>::from(T::RewardPeriod::get());
 
         assert_eq!(
-            WorkingTeam::<T, I>::budget(),
+            WorkingGroup::<T, I>::budget(),
             BalanceOfCurrency::<T>::max_value()
                 .saturating_sub(BalanceOfCurrency::<T>::from(i) * reward_per_worker)
                 .saturating_sub(reward_per_worker),
@@ -348,7 +348,7 @@ benchmarks_instance! {
 
         let (lead_id, _) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
@@ -358,15 +358,15 @@ benchmarks_instance! {
                 &(1..i).collect(),
                 &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
                 &StakingRole::WithStakes,
-                &JobOpeningType::Regular
+                &OpeningType::Regular
             );
 
-        WorkingTeam::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
+        WorkingGroup::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
         successful_application_ids.clone()).unwrap();
 
         for i in 1..successful_application_ids.len() {
             assert!(
-                WorkerById::<T, I>::contains_key(TeamWorkerId::<T>::from(i.try_into().unwrap())),
+                WorkerById::<T, I>::contains_key(WorkerId::<T>::from(i.try_into().unwrap())),
                 "Not all workers added"
             );
         }
@@ -380,13 +380,13 @@ benchmarks_instance! {
         System::<T>::set_block_number(curr_block_number);
 
         // Sets budget so that we can pay it
-        WorkingTeam::<T, _>::set_budget(
+        WorkingGroup::<T, _>::set_budget(
             RawOrigin::Root.into(),
             BalanceOfCurrency::<T>::max_value()
         ).unwrap();
 
-        assert_eq!(WorkingTeam::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
-    }: { WorkingTeam::<T, _>::on_initialize(curr_block_number) }
+        assert_eq!(WorkingGroup::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
+    }: { WorkingGroup::<T, _>::on_initialize(curr_block_number) }
     verify {
         let reward_per_worker = BalanceOfCurrency::<T>::from(T::RewardPeriod::get());
 
@@ -394,7 +394,7 @@ benchmarks_instance! {
             BalanceOfCurrency::<T>::from(i) * reward_per_worker * BalanceOfCurrency::<T>::from(2);
 
         assert_eq!(
-            WorkingTeam::<T, _>::budget(),
+            WorkingGroup::<T, _>::budget(),
             // When creating a worker using `insert_a_worker` it gives the lead a number of block
             // equating to reward period as missed reward(and the reward value is 1) therefore the
             // additional discount of balance
@@ -410,7 +410,7 @@ benchmarks_instance! {
 
         let (lead_id, _) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
@@ -420,15 +420,15 @@ benchmarks_instance! {
                 &(1..i).collect(),
                 &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
                 &StakingRole::WithStakes,
-                &JobOpeningType::Regular
+                &OpeningType::Regular
             );
 
-        WorkingTeam::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
+        WorkingGroup::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
         successful_application_ids.clone()).unwrap();
 
         for i in 1..successful_application_ids.len() {
             assert!(
-                WorkerById::<T, I>::contains_key(TeamWorkerId::<T>::from(i.try_into().unwrap())),
+                WorkerById::<T, I>::contains_key(WorkerId::<T>::from(i.try_into().unwrap())),
                 "Not all workers added"
             );
         }
@@ -440,11 +440,11 @@ benchmarks_instance! {
         System::<T>::set_block_number(curr_block_number);
 
         // Sets budget so that we can't pay it
-        WorkingTeam::<T, _>::set_budget(RawOrigin::Root.into(), Zero::zero()).unwrap();
+        WorkingGroup::<T, _>::set_budget(RawOrigin::Root.into(), Zero::zero()).unwrap();
 
-        assert_eq!(WorkingTeam::<T, _>::budget(), Zero::zero());
+        assert_eq!(WorkingGroup::<T, _>::budget(), Zero::zero());
 
-    }: { WorkingTeam::<T, _>::on_initialize(curr_block_number) }
+    }: { WorkingGroup::<T, _>::on_initialize(curr_block_number) }
     verify {
         WorkerById::<T, I>::iter().for_each(|(_, worker)| {
             let missed_reward = worker.missed_reward.expect("There should be some missed reward");
@@ -461,7 +461,7 @@ benchmarks_instance! {
 
         let (lead_id, _) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
@@ -471,15 +471,15 @@ benchmarks_instance! {
                 &(1..i).collect(),
                 &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
                 &StakingRole::WithStakes,
-                &JobOpeningType::Regular
+                &OpeningType::Regular
             );
 
-        WorkingTeam::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
+        WorkingGroup::<T, _>::fill_opening(RawOrigin::Signed(lead_id.clone()).into(), opening_id,
         successful_application_ids.clone()).unwrap();
 
         for i in 1..successful_application_ids.len() {
             assert!(
-                WorkerById::<T, I>::contains_key(TeamWorkerId::<T>::from(i.try_into().unwrap())),
+                WorkerById::<T, I>::contains_key(WorkerId::<T>::from(i.try_into().unwrap())),
                 "Not all workers added"
             );
         }
@@ -490,17 +490,17 @@ benchmarks_instance! {
         System::<T>::set_block_number(curr_block_number);
 
         // Sets budget so that we can pay it
-        WorkingTeam::<T, _>::set_budget(
+        WorkingGroup::<T, _>::set_budget(
             RawOrigin::Root.into(), BalanceOfCurrency::<T>::max_value()
         ).unwrap();
-        assert_eq!(WorkingTeam::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
+        assert_eq!(WorkingGroup::<T, _>::budget(), BalanceOfCurrency::<T>::max_value());
 
-    }: { WorkingTeam::<T, _>::on_initialize(curr_block_number) }
+    }: { WorkingGroup::<T, _>::on_initialize(curr_block_number) }
     verify {
         let reward_per_worker = BalanceOfCurrency::<T>::from(T::RewardPeriod::get());
         let workers_total_reward = BalanceOfCurrency::<T>::from(i) * reward_per_worker;
         assert_eq!(
-            WorkingTeam::<T, _>::budget(),
+            WorkingGroup::<T, _>::budget(),
             // When creating a worker using `insert_a_worker` it gives the lead a number of block
             // equating to reward period as missed reward(and the reward value is 1) therefore the
             // additional discount of balance
@@ -519,7 +519,7 @@ benchmarks_instance! {
             0,
             &T::Origin::from(RawOrigin::Root),
             &StakingRole::WithStakes,
-            &JobOpeningType::Leader
+            &OpeningType::Leader
         );
 
         let apply_on_opening_params = ApplyOnOpeningParameters::<T, I> {
@@ -558,7 +558,7 @@ benchmarks_instance! {
             &StakingRole::WithoutStakes,
             &lead_account_id,
             &lead_member_id,
-            &JobOpeningType::Leader
+            &OpeningType::Leader
         );
 
         let mut successful_application_ids: BTreeSet<T::ApplicationId> = BTreeSet::new();
@@ -570,7 +570,7 @@ benchmarks_instance! {
         let worker_id = Zero::zero();
 
         assert_eq!(
-            WorkingTeam::<T, I>::current_lead(),
+            WorkingGroup::<T, I>::current_lead(),
             Some(worker_id),
             "Opening for lead not filled"
         );
@@ -587,7 +587,7 @@ benchmarks_instance! {
         let i in 1 .. T::MaxWorkerNumberLimit::get();
         let (lead_id, lead_worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithoutStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
@@ -597,7 +597,7 @@ benchmarks_instance! {
                 &(1..i).collect(),
                 &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
                 &StakingRole::WithoutStakes,
-                &JobOpeningType::Regular
+                &OpeningType::Regular
             );
     }: fill_opening(
             RawOrigin::Signed(lead_id.clone()),
@@ -609,10 +609,10 @@ benchmarks_instance! {
 
         let mut application_id_to_worker_id = BTreeMap::new();
         for (i, application_id) in successful_application_ids.iter().enumerate() {
-            let worker_id = TeamWorkerId::<T>::from((i + 1).try_into().unwrap());
+            let worker_id = WorkerId::<T>::from((i + 1).try_into().unwrap());
             application_id_to_worker_id.insert(*application_id, worker_id);
             assert!(
-                WorkerById::<T, I>::contains_key(TeamWorkerId::<T>::from(i.try_into().unwrap())),
+                WorkerById::<T, I>::contains_key(WorkerId::<T>::from(i.try_into().unwrap())),
                 "Not all workers added"
             );
         }
@@ -625,12 +625,12 @@ benchmarks_instance! {
     update_role_account{
         let i in 0 .. 1;
         let (lead_id, lead_worker_id) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let new_account_id = account::<T::AccountId>("new_lead_account", 1, SEED);
     }: _ (RawOrigin::Signed(lead_id), lead_worker_id, new_account_id.clone())
     verify {
         assert_eq!(
-            WorkingTeam::<T, I>::worker_by_id(lead_worker_id).role_account_id,
+            WorkingGroup::<T, I>::worker_by_id(lead_worker_id).role_account_id,
             new_account_id,
             "Role account notupdated"
         );
@@ -644,12 +644,12 @@ benchmarks_instance! {
         let i in 0 .. 1;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let opening_id = add_opening_helper::<T, I>(
             1,
             &T::Origin::from(RawOrigin::Signed(lead_id.clone())),
             &StakingRole::WithoutStakes,
-            &JobOpeningType::Regular
+            &OpeningType::Regular
         );
 
     }: _ (RawOrigin::Signed(lead_id.clone()), opening_id)
@@ -667,7 +667,7 @@ benchmarks_instance! {
             &StakingRole::WithStakes,
             &caller_id,
             &member_id,
-            &JobOpeningType::Leader
+            &OpeningType::Leader
         );
 
     }: _ (RawOrigin::Signed(caller_id.clone()), application_id)
@@ -682,10 +682,10 @@ benchmarks_instance! {
         let i in 0 .. MAX_BYTES;
 
         let (lead_id, lead_worker_id) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let (caller_id, worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             1,
             Some(lead_id.clone())
         );
@@ -703,16 +703,16 @@ benchmarks_instance! {
         let i in 0 .. MAX_BYTES;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let (caller_id, worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             1,
             Some(lead_id.clone())
         );
         // To be able to pay unpaid reward
         let current_budget = BalanceOfCurrency::<T>::max_value();
-        WorkingTeam::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
+        WorkingGroup::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
         let penalty = Penalty {
             slashing_text: vec![0u8; i.try_into().unwrap()],
             slashing_amount: One::one(),
@@ -727,10 +727,10 @@ benchmarks_instance! {
         let i in 0 .. MAX_BYTES;
 
         let (_, lead_worker_id) =
-            insert_a_worker::<T, I>(StakingRole::WithStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithStakes, OpeningType::Leader, 0, None);
         let current_budget = BalanceOfCurrency::<T>::max_value();
         // To be able to pay unpaid reward
-        WorkingTeam::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
+        WorkingGroup::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
         let penalty = Penalty {
             slashing_text: vec![0u8; i.try_into().unwrap()],
             slashing_amount: One::one(),
@@ -747,16 +747,16 @@ benchmarks_instance! {
         let i in 0 .. 1;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let (caller_id, worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             1,
             Some(lead_id.clone())
         );
 
         let old_stake = One::one();
-        WorkingTeam::<T, _>::decrease_stake(
+        WorkingGroup::<T, _>::decrease_stake(
             RawOrigin::Signed(lead_id.clone()).into(), worker_id.clone(), old_stake).unwrap();
         let new_stake = old_stake + One::one();
     }: _ (RawOrigin::Signed(caller_id.clone()), worker_id.clone(), new_stake)
@@ -770,10 +770,10 @@ benchmarks_instance! {
         let i in 0 .. 1;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let (_, worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             1,
             Some(lead_id.clone())
         );
@@ -790,16 +790,16 @@ benchmarks_instance! {
 
         let (lead_id, _) = insert_a_worker::<T, I>(
             StakingRole::WithoutStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
 
         let current_budget = BalanceOfCurrency::<T>::max_value();
-        WorkingTeam::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
+        WorkingGroup::<T, _>::set_budget(RawOrigin::Root.into(), current_budget).unwrap();
     }: _ (RawOrigin::Signed(lead_id.clone()), lead_id.clone(), current_budget, None)
     verify {
-        assert_eq!(WorkingTeam::<T, I>::budget(), Zero::zero(), "Budget not updated");
+        assert_eq!(WorkingGroup::<T, I>::budget(), Zero::zero(), "Budget not updated");
         assert_last_event::<T, I>(RawEvent::BudgetSpending(lead_id, current_budget).into());
     }
 
@@ -809,10 +809,10 @@ benchmarks_instance! {
         let i in 0 .. 1;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let (_, worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithoutStakes,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             1,
             Some(lead_id.clone())
         );
@@ -821,7 +821,7 @@ benchmarks_instance! {
     }: _ (RawOrigin::Signed(lead_id.clone()), worker_id, new_reward)
     verify {
         assert_eq!(
-            WorkingTeam::<T, I>::worker_by_id(worker_id).reward_per_block,
+            WorkingGroup::<T, I>::worker_by_id(worker_id).reward_per_block,
             new_reward,
             "Reward not updated"
         );
@@ -835,7 +835,7 @@ benchmarks_instance! {
         let i in 0 .. MAX_BYTES;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let status_text = Some(vec![0u8; i.try_into().unwrap()]);
 
     }: _ (RawOrigin::Signed(lead_id), status_text.clone())
@@ -843,7 +843,7 @@ benchmarks_instance! {
         let status_text_hash = T::Hashing::hash(&status_text.unwrap()).as_ref().to_vec();
 
         assert_eq!(
-            WorkingTeam::<T, I>::status_text_hash(),
+            WorkingGroup::<T, I>::status_text_hash(),
             status_text_hash,
             "Status text not updated"
         );
@@ -855,13 +855,13 @@ benchmarks_instance! {
         let i in 0 .. 1;
 
         let (caller_id, worker_id) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
         let new_id = account::<T::AccountId>("new_id", 1, 0);
 
     }: _ (RawOrigin::Signed(caller_id), worker_id, new_id.clone())
     verify {
         assert_eq!(
-            WorkingTeam::<T, I>::worker_by_id(worker_id).reward_account_id,
+            WorkingGroup::<T, I>::worker_by_id(worker_id).reward_account_id,
             new_id,
             "Reward account not updated"
         );
@@ -876,7 +876,7 @@ benchmarks_instance! {
 
     }: _(RawOrigin::Root, new_budget)
     verify {
-        assert_eq!(WorkingTeam::<T, I>::budget(), new_budget, "Budget isn't updated");
+        assert_eq!(WorkingGroup::<T, I>::budget(), new_budget, "Budget isn't updated");
         assert_last_event::<T, I>(RawEvent::BudgetSet(new_budget).into());
     }
 
@@ -886,7 +886,7 @@ benchmarks_instance! {
         let i in 0 .. MAX_BYTES;
 
         let (lead_id, _) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
 
         let stake_policy = StakePolicy {
             stake_amount: BalanceOfCurrency::<T>::max_value(),
@@ -902,7 +902,7 @@ benchmarks_instance! {
     }: _(
             RawOrigin::Signed(lead_id),
             description,
-            JobOpeningType::Regular,
+            OpeningType::Regular,
             Some(stake_policy),
             Some(reward_policy)
         )
@@ -918,10 +918,10 @@ benchmarks_instance! {
         // could separate into new branch to tighten weight
         // Also, workers without stake can leave immediatly
         let (caller_id, lead_worker_id) =
-            insert_a_worker::<T, I>(StakingRole::WithoutStakes, JobOpeningType::Leader, 0, None);
+            insert_a_worker::<T, I>(StakingRole::WithoutStakes, OpeningType::Leader, 0, None);
 
         // To be able to pay unpaid reward
-        WorkingTeam::<T, _>::set_budget(
+        WorkingGroup::<T, _>::set_budget(
             RawOrigin::Root.into(),
             BalanceOfCurrency::<T>::max_value()
         ).unwrap();
@@ -941,14 +941,14 @@ benchmarks_instance! {
         // Workers with stake can't leave immediatly
         let (caller_id, caller_worker_id) = insert_a_worker::<T, I>(
             StakingRole::WithStakes,
-            JobOpeningType::Leader,
+            OpeningType::Leader,
             0,
             None
         );
     }: leave_role(RawOrigin::Signed(caller_id), caller_worker_id)
     verify {
         assert_eq!(
-            WorkingTeam::<T, _>::worker_by_id(caller_worker_id).started_leaving_at,
+            WorkingGroup::<T, _>::worker_by_id(caller_worker_id).started_leaving_at,
             Some(System::<T>::block_number()),
             "Worker hasn't started leaving"
         );

+ 28 - 27
runtime-modules/working-team/src/checks.rs → runtime-modules/working-group/src/checks.rs

@@ -1,6 +1,6 @@
 use crate::{
-    BalanceOf, Instance, JobOpening, JobOpeningType, MemberId, RewardPolicy, StakePolicy,
-    TeamWorker, TeamWorkerId, Trait,
+    ApplicationId, BalanceOf, Instance, MemberId, Opening, OpeningId, OpeningType, RewardPolicy,
+    StakePolicy, Trait, Worker, WorkerId,
 };
 
 use super::Error;
@@ -10,6 +10,7 @@ use frame_support::{ensure, StorageMap, StorageValue};
 use frame_system::{ensure_root, ensure_signed};
 use sp_arithmetic::traits::Zero;
 use sp_std::collections::btree_set::BTreeSet;
+use sp_std::marker::PhantomData;
 use sp_std::vec::Vec;
 
 use crate::types::{ApplicationInfo, StakeParameters};
@@ -17,14 +18,14 @@ use crate::types::{ApplicationInfo, StakeParameters};
 // Check opening: verifies origin and opening type compatibility.
 pub(crate) fn ensure_origin_for_opening_type<T: Trait<I>, I: Instance>(
     origin: T::Origin,
-    opening_type: JobOpeningType,
+    opening_type: OpeningType,
 ) -> DispatchResult {
     match opening_type {
-        JobOpeningType::Regular => {
+        OpeningType::Regular => {
             // Ensure lead is set and is origin signer.
             ensure_origin_is_active_leader::<T, I>(origin)
         }
-        JobOpeningType::Leader => {
+        OpeningType::Leader => {
             // Council proposal.
             ensure_root(origin).map_err(|err| err.into())
         }
@@ -33,8 +34,8 @@ pub(crate) fn ensure_origin_for_opening_type<T: Trait<I>, I: Instance>(
 
 // Check opening: returns the opening by id if it is exists.
 pub(crate) fn ensure_opening_exists<T: Trait<I>, I: Instance>(
-    opening_id: &T::OpeningId,
-) -> Result<JobOpening<T::BlockNumber, BalanceOf<T>>, Error<T, I>> {
+    opening_id: &OpeningId,
+) -> Result<Opening<T::BlockNumber, BalanceOf<T>>, Error<T, I>> {
     ensure!(
         <crate::OpeningById::<T, I>>::contains_key(opening_id),
         Error::<T, I>::OpeningDoesNotExist
@@ -47,7 +48,7 @@ pub(crate) fn ensure_opening_exists<T: Trait<I>, I: Instance>(
 
 // Check application: returns applicationId and application tuple if exists.
 pub(crate) fn ensure_application_exists<T: Trait<I>, I: Instance>(
-    application_id: &T::ApplicationId,
+    application_id: &ApplicationId,
 ) -> Result<ApplicationInfo<T, I>, Error<T, I>> {
     ensure!(
         <crate::ApplicationById::<T, I>>::contains_key(application_id),
@@ -59,12 +60,13 @@ pub(crate) fn ensure_application_exists<T: Trait<I>, I: Instance>(
     Ok(ApplicationInfo {
         application_id: *application_id,
         application,
+        marker: PhantomData,
     })
 }
 
 // Check application: returns applicationId and application tuple if exists.
 pub(crate) fn ensure_succesful_applications_exist<T: Trait<I>, I: Instance>(
-    successful_application_ids: &BTreeSet<T::ApplicationId>,
+    successful_application_ids: &BTreeSet<ApplicationId>,
 ) -> Result<Vec<ApplicationInfo<T, I>>, Error<T, I>> {
     // Check for non-empty set of application ids.
     ensure!(
@@ -96,9 +98,8 @@ pub(crate) fn ensure_succesful_applications_exist<T: Trait<I>, I: Instance>(
     Ok(result_applications_info)
 }
 
-// Check leader: ensures that team leader was hired.
-pub(crate) fn ensure_lead_is_set<T: Trait<I>, I: Instance>() -> Result<TeamWorkerId<T>, Error<T, I>>
-{
+// Check leader: ensures that group leader was hired.
+pub(crate) fn ensure_lead_is_set<T: Trait<I>, I: Instance>() -> Result<WorkerId<T>, Error<T, I>> {
     let leader_worker_id = <crate::CurrentLead<T, I>>::get();
 
     if let Some(leader_worker_id) = leader_worker_id {
@@ -123,8 +124,8 @@ fn ensure_is_lead_account<T: Trait<I>, I: Instance>(
     Ok(())
 }
 
-// Check leader: ensures origin is signed by the leader.
-pub(crate) fn ensure_origin_is_active_leader<T: Trait<I>, I: Instance>(
+/// Check leader: ensures origin is signed by the leader.
+pub fn ensure_origin_is_active_leader<T: Trait<I>, I: Instance>(
     origin: T::Origin,
 ) -> DispatchResult {
     // Ensure is signed
@@ -133,10 +134,10 @@ pub(crate) fn ensure_origin_is_active_leader<T: Trait<I>, I: Instance>(
     ensure_is_lead_account::<T, I>(signer)
 }
 
-// Check worker: ensures the worker was already created.
-pub(crate) fn ensure_worker_exists<T: Trait<I>, I: Instance>(
-    worker_id: &TeamWorkerId<T>,
-) -> Result<TeamWorker<T>, Error<T, I>> {
+/// Check worker: ensures the worker was already created.
+pub fn ensure_worker_exists<T: Trait<I>, I: Instance>(
+    worker_id: &WorkerId<T>,
+) -> Result<Worker<T>, Error<T, I>> {
     ensure!(
         <crate::WorkerById::<T, I>>::contains_key(worker_id),
         Error::<T, I>::WorkerDoesNotExist
@@ -158,11 +159,11 @@ pub(crate) fn ensure_origin_signed_by_member<T: Trait<I>, I: Instance>(
     Ok(())
 }
 
-// Check worker: ensures the origin contains signed account that belongs to existing worker.
-pub(crate) fn ensure_worker_signed<T: Trait<I>, I: Instance>(
+/// Check worker: ensures the origin contains signed account that belongs to existing worker.
+pub fn ensure_worker_signed<T: Trait<I>, I: Instance>(
     origin: T::Origin,
-    worker_id: &TeamWorkerId<T>,
-) -> Result<TeamWorker<T>, DispatchError> {
+    worker_id: &WorkerId<T>,
+) -> Result<Worker<T>, DispatchError> {
     // Ensure that it is signed
     let signer_account = ensure_signed(origin)?;
 
@@ -181,14 +182,14 @@ pub(crate) fn ensure_worker_signed<T: Trait<I>, I: Instance>(
 // Check worker: verifies proper origin for the worker operation. Returns whether the origin is sudo.
 pub(crate) fn ensure_origin_for_worker_operation<T: Trait<I>, I: Instance>(
     origin: T::Origin,
-    worker_id: TeamWorkerId<T>,
+    worker_id: WorkerId<T>,
 ) -> Result<bool, DispatchError> {
     let leader_worker_id = ensure_lead_is_set::<T, I>()?;
 
     let (worker_opening_type, is_sudo) = if leader_worker_id == worker_id {
-        (JobOpeningType::Leader, true)
+        (OpeningType::Leader, true)
     } else {
-        (JobOpeningType::Regular, false)
+        (OpeningType::Regular, false)
     };
 
     ensure_origin_for_opening_type::<T, I>(origin, worker_opening_type)?;
@@ -231,7 +232,7 @@ pub(crate) fn ensure_valid_reward_policy<T: Trait<I>, I: Instance>(
 
 // Check application: verifies that proposed stake is enough for the opening.
 pub(crate) fn ensure_application_stake_match_opening<T: Trait<I>, I: Instance>(
-    opening: &JobOpening<T::BlockNumber, BalanceOf<T>>,
+    opening: &Opening<T::BlockNumber, BalanceOf<T>>,
     stake_parameters: &Option<StakeParameters<T::AccountId, BalanceOf<T>>>,
 ) -> DispatchResult {
     let opening_stake_balance = opening
@@ -251,7 +252,7 @@ pub(crate) fn ensure_application_stake_match_opening<T: Trait<I>, I: Instance>(
 
 // Check worker: verifies that worker has recurring rewards.
 pub(crate) fn ensure_worker_has_recurring_reward<T: Trait<I>, I: Instance>(
-    worker: &TeamWorker<T>,
+    worker: &Worker<T>,
 ) -> DispatchResult {
     worker
         .reward_per_block

+ 45 - 639
runtime-modules/working-group/src/errors.rs

@@ -9,676 +9,82 @@ decl_error! {
         /// Provided stake balance cannot be zero.
         StakeBalanceCannotBeZero,
 
-        /// Cannot get the worker stake profile.
-        NoWorkerStakeProfile,
-
-        /// Current lead is not set.
-        CurrentLeadNotSet,
-
-        /// There is leader already, cannot hire another one.
-        CannotHireLeaderWhenLeaderExists,
-
-        /// Cannot fill opening with multiple applications.
-        CannotHireMultipleLeaders,
-
-        /// Not a lead account.
-        IsNotLeadAccount,
-
-        /// Opening text too short.
-        OpeningTextTooShort,
-
-        /// Opening text too long.
-        OpeningTextTooLong,
-
         /// Opening does not exist.
         OpeningDoesNotExist,
 
-        /// Insufficient balance to apply.
-        InsufficientBalanceToApply,
-
-        /// Unsigned origin.
-        MembershipUnsignedOrigin,
-
-        /// Member id is invalid.
-        MembershipInvalidMemberId,
-
-        /// Signer does not match controller account.
-        ApplyOnWorkerOpeningSignerNotControllerAccount,
-
-        /// Origin must be controller or root account of member.
-        OriginIsNeitherMemberControllerOrRoot,
-
-        /// Member already has an active application on the opening.
-        MemberHasActiveApplicationOnOpening,
-
-        /// Worker application text too long.
-        WorkerApplicationTextTooLong,
-
-        /// Worker application text too short.
-        WorkerApplicationTextTooShort,
-
-        /// Insufficient balance to cover stake.
-        InsufficientBalanceToCoverStake,
-
-        /// Origin is not applicant.
-        OriginIsNotApplicant,
+        /// Cannot fill opening with multiple applications.
+        CannotHireMultipleLeaders,
 
         /// Worker application does not exist.
         WorkerApplicationDoesNotExist,
 
+        /// Working group size limit exceeded.
+        MaxActiveWorkerNumberExceeded,
+
         /// Successful worker application does not exist.
         SuccessfulWorkerApplicationDoesNotExist,
 
-        /// Reward policy has invalid next payment block number.
-        FillOpeningInvalidNextPaymentBlock,
-
-        /// Working group mint does not exist.
-        FillOpeningMintDoesNotExist,
-
-        ///Relationship must exist.
-        RelationshipMustExist,
-
-        /// Worker exit rationale text is too long.
-        WorkerExitRationaleTextTooLong,
-
-        /// Worker exit rationale text is too short.
-        WorkerExitRationaleTextTooShort,
+        /// There is leader already, cannot hire another one.
+        CannotHireLeaderWhenLeaderExists,
 
-        /// Signer is not worker role account.
-        SignerIsNotWorkerRoleAccount,
+        /// Not a lead account.
+        IsNotLeadAccount,
 
-        /// Worker has no recurring reward.
-        WorkerHasNoReward,
+        /// Current lead is not set.
+        CurrentLeadNotSet,
 
         /// Worker does not exist.
         WorkerDoesNotExist,
 
-        /// Opening does not exist.
-        AcceptWorkerApplicationsOpeningDoesNotExist,
-
-        /// Opening Is Not in Waiting to begin.
-        AcceptWorkerApplicationsOpeningIsNotWaitingToBegin,
-
-        /// Opening does not exist.
-        BeginWorkerApplicantReviewOpeningDoesNotExist,
-
-        /// Opening Is Not in Waiting.
-        BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin,
-
-        /// OpeningDoesNotExist.
-        FullWorkerOpeningOpeningDoesNotExist,
-
-        /// Opening not in review period stage.
-        FullWorkerOpeningOpeningNotInReviewPeriodStage,
-
-        /// Application stake unstaking period for successful applicants too short.
-        FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort,
-
-        /// Application stake unstaking period for failed applicants too short.
-        FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort,
-
-        /// Role stake unstaking period for successful applicants too short.
-        FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort,
-
-        /// Role stake unstaking period for failed applicants too short.
-        FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort,
-
-        /// Application stake unstaking period for successful applicants redundant.
-        FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant,
-
-        /// Application stake unstaking period for failed applicants redundant.
-        FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant,
-
-        /// Role stake unstaking period for successful applicants redundant.
-        FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant,
-
-        /// Role stake unstaking period for failed applicants redundant.
-        FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant,
-
-        /// Application does not exist.
-        FullWorkerOpeningApplicationDoesNotExist,
-
-        /// Application not in active stage.
-        FullWorkerOpeningApplicationNotActive,
-
-        /// Applications not for opening.
-        FillWorkerOpeningApplicationForWrongOpening,
-
-        /// Application does not exist.
-        WithdrawWorkerApplicationApplicationDoesNotExist,
-
-        /// Application is not active.
-        WithdrawWorkerApplicationApplicationNotActive,
-
-        /// Opening not accepting applications.
-        WithdrawWorkerApplicationOpeningNotAcceptingApplications,
-
-        /// UnstakingPeriodTooShort .... // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
-        WithdrawWorkerApplicationUnstakingPeriodTooShort,
-
-        /// Redundant unstaking period provided
-        WithdrawWorkerApplicationRedundantUnstakingPeriod,
-
-        /// Opening does not activate in the future.
-        AddWorkerOpeningActivatesInThePast,
-
-        /// Role stake amount less than minimum currency balance.
-        AddWorkerOpeningRoleStakeLessThanMinimum,
-
-        /// Application stake amount less than minimum currency balance.
-        AddWorkerOpeningAppliicationStakeLessThanMinimum,
-
-        /// Opening does not exist.
-        AddWorkerOpeningOpeningDoesNotExist,
-
-        // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
-        /// Stake provided when redundant.
-        AddWorkerOpeningStakeProvidedWhenRedundant,
-
-        // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
-        /// Stake missing when required.
-        AddWorkerOpeningStakeMissingWhenRequired,
-
-        // <== SHOULD REALLY BE TWO SEPARATE, ONE FOR EACH STAKING PURPOSE
-        /// Stake amount too low.
-        AddWorkerOpeningStakeAmountTooLow,
+        /// Invalid origin for a member.
+        InvalidMemberOrigin,
 
-        /// Opening is not in accepting applications stage.
-        AddWorkerOpeningOpeningNotInAcceptingApplicationStage,
-
-        /// New application was crowded out.
-        AddWorkerOpeningNewApplicationWasCrowdedOut,
-
-        /// Application rationing has zero max active applicants.
-        AddWorkerOpeningZeroMaxApplicantCount,
-
-        /// Next payment is not in the future.
-        RecurringRewardsNextPaymentNotInFuture,
-
-        /// Recipient not found.
-        RecurringRewardsRecipientNotFound,
-
-        /// Recipient reward source not found.
-        RecurringRewardsRewardSourceNotFound,
-
-        /// Reward relationship not found.
-        RecurringRewardsRewardRelationshipNotFound,
-
-        /// Stake not found.
-        StakingErrorStakeNotFound,
-
-        /// Unstaking period should be greater than zero.
-        StakingErrorUnstakingPeriodShouldBeGreaterThanZero,
-
-        /// Already unstaking.
-        StakingErrorAlreadyUnstaking,
-
-        /// Not staked.
-        StakingErrorNotStaked,
-
-        /// Cannot unstake while slashes ongoing.
-        StakingErrorCannotUnstakeWhileSlashesOngoing,
-
-        /// Insufficient balance in source account.
-        StakingErrorInsufficientBalanceInSourceAccount,
-
-        /// Cannot change stake by zero.
-        StakingErrorCannotChangeStakeByZero,
-
-        /// Cannot increase stake while unstaking.
-        StakingErrorCannotIncreaseStakeWhileUnstaking,
-
-        /// Cannot decrease stake while slashes ongoing.
-        StakingErrorCannotDecreaseWhileSlashesOngoing,
-
-        /// Insufficient stake to decrease.
-        StakingErrorInsufficientStake,
-
-        /// Slash amount should be greater than zero.
-        StakingErrorSlashAmountShouldBeGreaterThanZero,
-
-        /// Cannot find mint in the minting module.
-        CannotFindMint,
-
-        /// Require root origin in extrinsics.
-        RequireRootOrigin,
-
-        /// Require signed origin in extrinsics.
-        RequireSignedOrigin,
-
-        /// Working group size limit exceeded.
-        MaxActiveWorkerNumberExceeded,
-
-        /// Add worker opening role stake cannot be zero.
-        AddWorkerOpeningRoleStakeCannotBeZero,
-
-        /// Add worker opening application stake cannot be zero.
-        AddWorkerOpeningApplicationStakeCannotBeZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// fill_opening_failed_applicant_application_stake_unstaking_period should be non-zero.
-        FillOpeningFailedApplicantApplicationStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// fill_opening_failed_applicant_role_stake_unstaking_period should be non-zero.
-        FillOpeningFailedApplicantRoleStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// fill_opening_successful_applicant_application_stake_unstaking_period should be non-zero.
-        FillOpeningSuccessfulApplicantApplicationStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// exit_role_stake_unstaking_period should be non-zero.
-        ExitRoleStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// exit_role_application_stake_unstaking_period should be non-zero.
-        ExitRoleApplicationStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// terminate_role_stake_unstaking_period should be non-zero.
-        TerminateRoleStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter:
-        /// terminate_application_stake_unstaking_period should be non-zero.
-        TerminateApplicationStakeUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter (role_staking_policy):
-        /// crowded_out_unstaking_period_length should be non-zero.
-        RoleStakingPolicyCrowdedOutUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter (role_staking_policy):
-        /// review_period_expired_unstaking_period_length should be non-zero.
-        RoleStakingPolicyReviewPeriodUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter (application_staking_policy):
-        /// crowded_out_unstaking_period_length should be non-zero.
-        ApplicationStakingPolicyCrowdedOutUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter (application_staking_policy):
-        /// review_period_expired_unstaking_period_length should be non-zero.
-        ApplicationStakingPolicyReviewPeriodUnstakingPeriodIsZero,
-
-        /// Invalid OpeningPolicyCommitment parameter (application_rationing_policy):
-        /// max_active_applicants should be non-zero.
-        ApplicationRationingPolicyMaxActiveApplicantsIsZero,
-
-        /// Minting error: NextAdjustmentInPast
-        MintingErrorNextAdjustmentInPast,
-    }
-}
+        /// Signer is not worker role account.
+        SignerIsNotWorkerRoleAccount,
 
-/// Error wrapper for external module error conversions.
-pub struct WrappedError<E> {
-    /// Generic error.
-    pub error: E,
-}
+        /// Cannot stake zero.
+        CannotStakeZero,
 
-/// Helps with conversion of other modules errors.
-#[macro_export]
-macro_rules! ensure_on_wrapped_error {
-    ($call:expr) => {{
-        { $call }
-            .map_err(|err| crate::WrappedError { error: err })
-            .map_err(|err| {
-                let e: Error<T, I> = err.into();
+        /// Insufficient balance to cover stake.
+        InsufficientBalanceToCoverStake,
 
-                e
-            })
-    }};
-}
+        /// Application stake is less than required opening stake.
+        ApplicationStakeDoesntMatchOpening,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<hiring::BeginAcceptingApplicationsError>> for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::BeginAcceptingApplicationsError>) -> Self {
-        match wrapper.error {
-            hiring::BeginAcceptingApplicationsError::OpeningDoesNotExist => {
-                Error::AcceptWorkerApplicationsOpeningDoesNotExist
-            }
-            hiring::BeginAcceptingApplicationsError::OpeningIsNotInWaitingToBeginStage => {
-                Error::AcceptWorkerApplicationsOpeningIsNotWaitingToBegin
-            }
-        }
-    }
-}
+        /// Origin is not applicant.
+        OriginIsNotApplicant,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<hiring::AddOpeningError>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::AddOpeningError>) -> Self {
-        match wrapper.error {
-            hiring::AddOpeningError::OpeningMustActivateInTheFuture => {
-                Error::AddWorkerOpeningActivatesInThePast
-            }
-            hiring::AddOpeningError::StakeAmountLessThanMinimumStakeBalance(purpose) => {
-                match purpose {
-                    hiring::StakePurpose::Role => Error::AddWorkerOpeningRoleStakeLessThanMinimum,
-                    hiring::StakePurpose::Application => {
-                        Error::AddWorkerOpeningAppliicationStakeLessThanMinimum
-                    }
-                }
-            }
-            hiring::AddOpeningError::ApplicationRationingZeroMaxApplicants => {
-                Error::AddWorkerOpeningZeroMaxApplicantCount
-            }
-            hiring::AddOpeningError::StakeAmountCannotBeZero(purpose) => match purpose {
-                hiring::StakePurpose::Role => Error::AddWorkerOpeningRoleStakeCannotBeZero,
-                hiring::StakePurpose::Application => {
-                    Error::AddWorkerOpeningApplicationStakeCannotBeZero
-                }
-            },
-        }
-    }
-}
+        /// Invalid operation - worker is leaving.
+        WorkerIsLeaving,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<hiring::BeginReviewError>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::BeginReviewError>) -> Self {
-        match wrapper.error {
-            hiring::BeginReviewError::OpeningDoesNotExist => {
-                Error::BeginWorkerApplicantReviewOpeningDoesNotExist
-            }
-            hiring::BeginReviewError::OpeningNotInAcceptingApplicationsStage => {
-                Error::BeginWorkerApplicantReviewOpeningOpeningIsNotWaitingToBegin
-            }
-        }
-    }
-}
+        /// Reward could not be zero.
+        CannotRewardWithZero,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<hiring::FillOpeningError<T>>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::FillOpeningError<T>>) -> Self {
-        match wrapper.error {
-            hiring::FillOpeningError::<T>::OpeningDoesNotExist => {
-                Error::FullWorkerOpeningOpeningDoesNotExist
-            }
-            hiring::FillOpeningError::<T>::OpeningNotInReviewPeriodStage => {
-                Error::FullWorkerOpeningOpeningNotInReviewPeriodStage
-            }
-            hiring::FillOpeningError::<T>::UnstakingPeriodTooShort(
-                stake_purpose,
-                outcome_in_filled_opening,
-            ) => match stake_purpose {
-                hiring::StakePurpose::Application => match outcome_in_filled_opening {
-                    hiring::ApplicationOutcomeInFilledOpening::Success => {
-                        Error::FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodTooShort
-                    }
-                    hiring::ApplicationOutcomeInFilledOpening::Failure => {
-                        Error::FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodTooShort
-                    }
-                },
-                hiring::StakePurpose::Role => match outcome_in_filled_opening {
-                    hiring::ApplicationOutcomeInFilledOpening::Success => {
-                        Error::FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodTooShort
-                    }
-                    hiring::ApplicationOutcomeInFilledOpening::Failure => {
-                        Error::FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodTooShort
-                    }
-                },
-            },
-            hiring::FillOpeningError::<T>::RedundantUnstakingPeriodProvided(
-                stake_purpose,
-                outcome_in_filled_opening,
-            ) => match stake_purpose {
-                hiring::StakePurpose::Application => match outcome_in_filled_opening {
-                    hiring::ApplicationOutcomeInFilledOpening::Success => {
-                        Error::FullWorkerOpeningSuccessfulApplicationStakeUnstakingPeriodRedundant
-                    }
-                    hiring::ApplicationOutcomeInFilledOpening::Failure => {
-                        Error::FullWorkerOpeningUnsuccessfulApplicationStakeUnstakingPeriodRedundant
-                    }
-                },
-                hiring::StakePurpose::Role => match outcome_in_filled_opening {
-                    hiring::ApplicationOutcomeInFilledOpening::Success => {
-                        Error::FullWorkerOpeningSuccessfulRoleStakeUnstakingPeriodRedundant
-                    }
-                    hiring::ApplicationOutcomeInFilledOpening::Failure => {
-                        Error::FullWorkerOpeningUnsuccessfulRoleStakeUnstakingPeriodRedundant
-                    }
-                },
-            },
-            hiring::FillOpeningError::<T>::ApplicationDoesNotExist(_application_id) => {
-                Error::FullWorkerOpeningApplicationDoesNotExist
-            }
-            hiring::FillOpeningError::<T>::ApplicationNotInActiveStage(_application_id) => {
-                Error::FullWorkerOpeningApplicationNotActive
-            }
-            hiring::FillOpeningError::<T>::ApplicationForWrongOpening(_application_id) => {
-                Error::FillWorkerOpeningApplicationForWrongOpening
-            }
-        }
-    }
-}
+        /// Staking account doesn't belong to a member.
+        InvalidStakingAccountForMember,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<hiring::DeactivateApplicationError>> for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::DeactivateApplicationError>) -> Self {
-        match wrapper.error {
-            hiring::DeactivateApplicationError::ApplicationDoesNotExist => {
-                Error::WithdrawWorkerApplicationApplicationDoesNotExist
-            }
-            hiring::DeactivateApplicationError::ApplicationNotActive => {
-                Error::WithdrawWorkerApplicationApplicationNotActive
-            }
-            hiring::DeactivateApplicationError::OpeningNotAcceptingApplications => {
-                Error::WithdrawWorkerApplicationOpeningNotAcceptingApplications
-            }
-            hiring::DeactivateApplicationError::UnstakingPeriodTooShort(_stake_purpose) => {
-                Error::WithdrawWorkerApplicationUnstakingPeriodTooShort
-            }
-            hiring::DeactivateApplicationError::RedundantUnstakingPeriodProvided(
-                _stake_purpose,
-            ) => Error::WithdrawWorkerApplicationRedundantUnstakingPeriod,
-        }
-    }
-}
+        /// Staking account contains conflicting stakes.
+        ConflictStakesOnAccount,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<hiring::AddApplicationError>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<hiring::AddApplicationError>) -> Self {
-        match wrapper.error {
-            hiring::AddApplicationError::OpeningDoesNotExist => {
-                Error::AddWorkerOpeningOpeningDoesNotExist
-            }
-            hiring::AddApplicationError::StakeProvidedWhenRedundant(_stake_purpose) => {
-                Error::AddWorkerOpeningStakeProvidedWhenRedundant
-            }
-            hiring::AddApplicationError::StakeMissingWhenRequired(_stake_purpose) => {
-                Error::AddWorkerOpeningStakeMissingWhenRequired
-            }
-            hiring::AddApplicationError::StakeAmountTooLow(_stake_purpose) => {
-                Error::AddWorkerOpeningStakeAmountTooLow
-            }
-            hiring::AddApplicationError::OpeningNotInAcceptingApplicationsStage => {
-                Error::AddWorkerOpeningOpeningNotInAcceptingApplicationStage
-            }
-            hiring::AddApplicationError::NewApplicationWasCrowdedOut => {
-                Error::AddWorkerOpeningNewApplicationWasCrowdedOut
-            }
-        }
-    }
-}
+        /// Worker has no recurring reward.
+        WorkerHasNoReward,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<membership::MemberControllerAccountDidNotSign>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<membership::MemberControllerAccountDidNotSign>) -> Self {
-        match wrapper.error {
-            membership::MemberControllerAccountDidNotSign::UnsignedOrigin => {
-                Error::MembershipUnsignedOrigin
-            }
-            membership::MemberControllerAccountDidNotSign::MemberIdInvalid => {
-                Error::MembershipInvalidMemberId
-            }
-            membership::MemberControllerAccountDidNotSign::SignerControllerAccountMismatch => {
-                Error::ApplyOnWorkerOpeningSignerNotControllerAccount
-            }
-        }
-    }
-}
+        /// Specified unstaking period is less then minimum set for the group.
+        UnstakingPeriodLessThanMinimum,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<recurringrewards::RewardsError>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<recurringrewards::RewardsError>) -> Self {
-        match wrapper.error {
-            recurringrewards::RewardsError::NextPaymentNotInFuture => {
-                Error::RecurringRewardsNextPaymentNotInFuture
-            }
-            recurringrewards::RewardsError::RecipientNotFound => {
-                Error::RecurringRewardsRecipientNotFound
-            }
-            recurringrewards::RewardsError::RewardSourceNotFound => {
-                Error::RecurringRewardsRewardSourceNotFound
-            }
-            recurringrewards::RewardsError::RewardRelationshipNotFound => {
-                Error::RecurringRewardsRewardRelationshipNotFound
-            }
-        }
-    }
-}
+        /// Requested operation with stake is impossible because of stake was not defined for the role.
+        CannotChangeStakeWithoutStakingAccount,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<stake::StakeActionError<stake::InitiateUnstakingError>>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<stake::StakeActionError<stake::InitiateUnstakingError>>) -> Self {
-        match wrapper.error {
-            stake::StakeActionError::StakeNotFound => Error::StakingErrorStakeNotFound,
-            stake::StakeActionError::Error(initiate_unstaking_error) => {
-                match initiate_unstaking_error {
-                    stake::InitiateUnstakingError::UnstakingPeriodShouldBeGreaterThanZero => {
-                        Error::StakingErrorUnstakingPeriodShouldBeGreaterThanZero
-                    }
-                    stake::InitiateUnstakingError::UnstakingError(unstaking_error) => {
-                        match unstaking_error {
-                            stake::UnstakingError::AlreadyUnstaking => {
-                                Error::StakingErrorAlreadyUnstaking
-                            }
-                            stake::UnstakingError::NotStaked => Error::StakingErrorNotStaked,
-                            stake::UnstakingError::CannotUnstakeWhileSlashesOngoing => {
-                                Error::StakingErrorCannotUnstakeWhileSlashesOngoing
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
+        /// Invalid spending amount.
+        CannotSpendZero,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<
-        WrappedError<stake::StakeActionError<stake::IncreasingStakeFromAccountError>>,
-    > for Error<T, I>
-{
-    fn from(
-        wrapper: WrappedError<stake::StakeActionError<stake::IncreasingStakeFromAccountError>>,
-    ) -> Self {
-        match wrapper.error {
-            stake::StakeActionError::StakeNotFound => Error::StakingErrorStakeNotFound,
-            stake::StakeActionError::Error(increase_stake_error_from_account) => {
-                match increase_stake_error_from_account {
-                    stake::IncreasingStakeFromAccountError::InsufficientBalanceInSourceAccount => {
-                        Error::StakingErrorInsufficientBalanceInSourceAccount
-                    }
-                    stake::IncreasingStakeFromAccountError::IncreasingStakeError(
-                        increasing_stake_error,
-                    ) => match increasing_stake_error {
-                        stake::IncreasingStakeError::NotStaked => Error::StakingErrorNotStaked,
-                        stake::IncreasingStakeError::CannotChangeStakeByZero => {
-                            Error::StakingErrorCannotChangeStakeByZero
-                        }
-                        stake::IncreasingStakeError::CannotIncreaseStakeWhileUnstaking => {
-                            Error::StakingErrorCannotIncreaseStakeWhileUnstaking
-                        }
-                    },
-                }
-            }
-        }
-    }
-}
+        /// It's not enough budget for this spending.
+        InsufficientBudgetForSpending,
 
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<stake::StakeActionError<stake::IncreasingStakeError>>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<stake::StakeActionError<stake::IncreasingStakeError>>) -> Self {
-        match wrapper.error {
-            stake::StakeActionError::StakeNotFound => Error::StakingErrorStakeNotFound,
-            stake::StakeActionError::Error(increasing_stake_error) => {
-                match increasing_stake_error {
-                    stake::IncreasingStakeError::NotStaked => Error::StakingErrorNotStaked,
-                    stake::IncreasingStakeError::CannotChangeStakeByZero => {
-                        Error::StakingErrorCannotChangeStakeByZero
-                    }
-                    stake::IncreasingStakeError::CannotIncreaseStakeWhileUnstaking => {
-                        Error::StakingErrorCannotIncreaseStakeWhileUnstaking
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<stake::StakeActionError<stake::DecreasingStakeError>>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<stake::StakeActionError<stake::DecreasingStakeError>>) -> Self {
-        match wrapper.error {
-            stake::StakeActionError::StakeNotFound => Error::StakingErrorStakeNotFound,
-            stake::StakeActionError::Error(decreasing_stake_error) => {
-                match decreasing_stake_error {
-                    stake::DecreasingStakeError::NotStaked => Error::StakingErrorNotStaked,
-                    stake::DecreasingStakeError::CannotChangeStakeByZero => {
-                        Error::StakingErrorCannotChangeStakeByZero
-                    }
-                    stake::DecreasingStakeError::CannotDecreaseStakeWhileUnstaking => {
-                        Error::StakingErrorCannotIncreaseStakeWhileUnstaking
-                    }
-                    stake::DecreasingStakeError::CannotDecreaseStakeWhileOngoingSlahes => {
-                        Error::StakingErrorCannotDecreaseWhileSlashesOngoing
-                    }
-                    stake::DecreasingStakeError::InsufficientStake => {
-                        Error::StakingErrorInsufficientStake
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl<T: Trait<I>, I: Instance>
-    sp_std::convert::From<WrappedError<stake::StakeActionError<stake::ImmediateSlashingError>>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<stake::StakeActionError<stake::ImmediateSlashingError>>) -> Self {
-        match wrapper.error {
-            stake::StakeActionError::StakeNotFound => Error::StakingErrorStakeNotFound,
-            stake::StakeActionError::Error(slashing_error) => match slashing_error {
-                stake::ImmediateSlashingError::NotStaked => Error::StakingErrorNotStaked,
-                stake::ImmediateSlashingError::SlashAmountShouldBeGreaterThanZero => {
-                    Error::StakingErrorSlashAmountShouldBeGreaterThanZero
-                }
-            },
-        }
-    }
-}
+        /// Cannot fill opening - no applications provided.
+        NoApplicationsProvided,
 
-impl<T: Trait<I>, I: Instance> sp_std::convert::From<WrappedError<minting::GeneralError>>
-    for Error<T, I>
-{
-    fn from(wrapper: WrappedError<minting::GeneralError>) -> Self {
-        match wrapper.error {
-            minting::GeneralError::MintNotFound => Error::CannotFindMint,
-            minting::GeneralError::NextAdjustmentInPast => Error::MintingErrorNextAdjustmentInPast,
-        }
+        /// Cannot decrease stake - stake delta greater than initial stake.
+        CannotDecreaseStakeDeltaGreaterThanStake,
     }
 }

File diff suppressed because it is too large
+ 427 - 482
runtime-modules/working-group/src/lib.rs


File diff suppressed because it is too large
+ 609 - 347
runtime-modules/working-group/src/tests/fixtures.rs


+ 47 - 67
runtime-modules/working-group/src/tests/hiring_workflow.rs

@@ -2,16 +2,15 @@ use frame_support::dispatch::{DispatchError, DispatchResult};
 use frame_system::RawOrigin;
 
 use crate::tests::fixtures::{
-    create_mint, increase_total_balance_issuance_using_account_id, set_mint_id, setup_members,
-    AddWorkerOpeningFixture, ApplyOnWorkerOpeningFixture, BeginReviewWorkerApplicationsFixture,
-    FillWorkerOpeningFixture, SetLeadFixture,
+    setup_members, AddOpeningFixture, ApplyOnOpeningFixture, FillOpeningFixture, HireLeadFixture,
 };
 use crate::tests::mock::TestWorkingGroup;
-use crate::{OpeningPolicyCommitment, OpeningType, RewardPolicy};
+use crate::types::StakeParameters;
+use crate::{OpeningType, RewardPolicy, StakePolicy};
 
 #[derive(Clone)]
 struct HiringWorkflowApplication {
-    stake: Option<u64>,
+    stake_parameters: Option<StakeParameters<u64, u64>>,
     worker_handle: Vec<u8>,
     origin: RawOrigin<u64>,
     member_id: u64,
@@ -20,87 +19,93 @@ struct HiringWorkflowApplication {
 pub struct HiringWorkflow {
     opening_type: OpeningType,
     expected_result: DispatchResult,
-    role_stake: Option<u64>,
+    stake_policy: Option<StakePolicy<u64, u64>>,
+    reward_policy: Option<RewardPolicy<u64>>,
     applications: Vec<HiringWorkflowApplication>,
     setup_environment: bool,
-    reward_policy: Option<RewardPolicy<u64, u64>>,
 }
 
 impl Default for HiringWorkflow {
     fn default() -> Self {
         Self {
-            opening_type: OpeningType::Worker,
+            opening_type: OpeningType::Regular,
             expected_result: Ok(()),
-            role_stake: None,
+            stake_policy: None,
+            reward_policy: None,
             applications: Vec::new(),
             setup_environment: true,
-            reward_policy: None,
         }
     }
 }
 
 impl HiringWorkflow {
-    pub fn expect(self, result: DispatchResult) -> Self {
+    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
         Self {
-            expected_result: result,
+            stake_policy,
             ..self
         }
     }
 
-    pub fn disable_setup_environment(self) -> Self {
+    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
         Self {
-            setup_environment: false,
+            reward_policy,
             ..self
         }
     }
 
-    pub fn with_setup_environment(self, setup_environment: bool) -> Self {
+    pub fn expect(self, result: DispatchResult) -> Self {
         Self {
-            setup_environment,
+            expected_result: result,
             ..self
         }
     }
 
-    pub fn with_opening_type(self, opening_type: OpeningType) -> Self {
+    pub fn with_setup_environment(self, setup_environment: bool) -> Self {
         Self {
-            opening_type,
+            setup_environment,
             ..self
         }
     }
 
-    pub fn with_role_stake(self, role_stake: Option<u64>) -> Self {
-        Self { role_stake, ..self }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64, u64>>) -> Self {
+    pub fn with_opening_type(self, opening_type: OpeningType) -> Self {
         Self {
-            reward_policy,
+            opening_type,
             ..self
         }
     }
 
     pub fn add_default_application(self) -> Self {
-        let worker_handle = b"default worker handle".to_vec();
+        let worker_handle = b"default".to_vec();
 
         self.add_application(worker_handle)
     }
 
     pub fn add_application(self, worker_handle: Vec<u8>) -> Self {
-        self.add_application_with_origin(worker_handle, RawOrigin::Signed(1), 1)
+        self.add_application_full(worker_handle, RawOrigin::Signed(1), 1, Some(1))
     }
 
-    pub fn add_application_with_origin(
+    pub fn add_application_full(
         self,
         worker_handle: Vec<u8>,
         origin: RawOrigin<u64>,
         member_id: u64,
+        staking_account_id: Option<u64>,
     ) -> Self {
+        let stake_parameters = staking_account_id.map(|staking_account_id| StakeParameters {
+            stake: self
+                .stake_policy
+                .clone()
+                .map(|policy| policy.stake_amount)
+                .unwrap_or_default(),
+            staking_account_id,
+        });
+
         let mut applications = self.applications;
         applications.push(HiringWorkflowApplication {
             worker_handle,
-            stake: self.role_stake.clone(),
             origin,
             member_id,
+            stake_parameters,
         });
 
         Self {
@@ -110,12 +115,11 @@ impl HiringWorkflow {
     }
 
     fn setup_environment(&self) {
-        if matches!(self.opening_type, OpeningType::Worker) {
-            SetLeadFixture::default().set_lead();
+        if matches!(self.opening_type, OpeningType::Regular) {
+            HireLeadFixture::default().hire_lead();
+        } else {
+            setup_members(6);
         }
-        increase_total_balance_issuance_using_account_id(1, 10000);
-        setup_members(4);
-        set_mint_id(create_mint());
     }
 
     pub fn execute(&self) -> Option<u64> {
@@ -135,7 +139,7 @@ impl HiringWorkflow {
     fn fill_worker_position(&self) -> Result<u64, DispatchError> {
         let origin = match self.opening_type {
             OpeningType::Leader => RawOrigin::Root,
-            OpeningType::Worker => {
+            OpeningType::Regular => {
                 let leader_worker_id = TestWorkingGroup::current_lead().unwrap();
                 let leader = TestWorkingGroup::worker_by_id(leader_worker_id);
                 let lead_account_id = leader.role_account_id;
@@ -145,56 +149,32 @@ impl HiringWorkflow {
         };
 
         // create the opening
-        let mut add_worker_opening_fixture = AddWorkerOpeningFixture::default()
+        let add_worker_opening_fixture = AddOpeningFixture::default()
+            .with_stake_policy(self.stake_policy.clone())
+            .with_reward_policy(self.reward_policy.clone())
             .with_opening_type(self.opening_type)
             .with_origin(origin.clone());
 
-        if let Some(stake) = self.role_stake.clone() {
-            add_worker_opening_fixture =
-                add_worker_opening_fixture.with_policy_commitment(OpeningPolicyCommitment {
-                    role_staking_policy: Some(hiring::StakingPolicy {
-                        amount: stake,
-                        amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None,
-                    }),
-                    ..OpeningPolicyCommitment::default()
-                });
-        }
-
         let opening_id = add_worker_opening_fixture.call()?;
 
         // Fill applications.
         let mut application_ids = Vec::new();
         for application in self.applications.clone() {
             let apply_on_worker_opening_fixture =
-                ApplyOnWorkerOpeningFixture::default_for_opening_id(opening_id)
+                ApplyOnOpeningFixture::default_for_opening_id(opening_id)
+                    .with_stake_parameters(application.stake_parameters)
                     .with_text(application.worker_handle)
-                    .with_origin(application.origin, application.member_id)
-                    .with_role_stake(self.role_stake);
+                    .with_origin(application.origin, application.member_id);
 
             let application_id = apply_on_worker_opening_fixture.call()?;
             application_ids.push(application_id);
         }
 
-        // begin application review
-
-        let begin_review_worker_applications_fixture =
-            BeginReviewWorkerApplicationsFixture::default_for_opening_id(opening_id)
-                .with_origin(origin.clone());
-        begin_review_worker_applications_fixture.call_and_assert(Ok(()));
-
         // fill opening
-        let mut fill_worker_opening_fixture =
-            FillWorkerOpeningFixture::default_for_ids(opening_id, application_ids)
-                .with_origin(origin.clone());
-
-        if let Some(reward_policy) = self.reward_policy.clone() {
-            fill_worker_opening_fixture =
-                fill_worker_opening_fixture.with_reward_policy(reward_policy);
-        }
+        let fill_opening_fixture = FillOpeningFixture::default_for_ids(opening_id, application_ids)
+            .with_origin(origin.clone());
 
-        let worker_id = fill_worker_opening_fixture.call()?;
+        let worker_id = fill_opening_fixture.call()?;
 
         Ok(worker_id)
     }

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

@@ -1,237 +0,0 @@
-use frame_support::storage::StorageMap;
-use frame_support::traits::{OnFinalize, OnInitialize};
-use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
-use frame_system;
-use sp_core::H256;
-use sp_runtime::{
-    testing::Header,
-    traits::{BlakeTwo256, IdentityLookup},
-    Perbill,
-};
-use std::marker::PhantomData;
-
-use crate::{BalanceOf, Module, NegativeImbalance, Trait};
-use common::constraints::InputValidationLengthConstraint;
-
-impl_outer_origin! {
-    pub enum Origin for Test {}
-}
-
-mod working_group {
-    pub use super::TestWorkingGroupInstance;
-    pub use crate::Event;
-}
-
-mod membership_mod {
-    pub use membership::Event;
-}
-
-impl_outer_event! {
-    pub enum TestEvent for Test {
-        balances<T>,
-        working_group TestWorkingGroupInstance <T>,
-        membership_mod<T>,
-        frame_system<T>,
-    }
-}
-
-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 = TestEvent;
-    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 = balances::AccountData<u64>;
-    type OnNewAccount = ();
-    type OnKilledAccount = ();
-    type SystemWeightInfo = ();
-}
-
-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 = StakingEventsHandler<Test>;
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
-impl membership::Trait for Test {
-    type Event = TestEvent;
-    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 = ();
-}
-
-impl balances::Trait for Test {
-    type Balance = u64;
-    type DustRemoval = ();
-    type Event = TestEvent;
-    type ExistentialDeposit = ExistentialDeposit;
-    type AccountStore = System;
-    type WeightInfo = ();
-    type MaxLocks = ();
-}
-
-impl recurringrewards::Trait for Test {
-    type PayoutStatusHandler = ();
-    type RecipientId = u64;
-    type RewardRelationshipId = u64;
-}
-
-pub type Balances = balances::Module<Test>;
-pub type System = frame_system::Module<Test>;
-
-parameter_types! {
-    pub const MaxWorkerNumberLimit: u32 = 3;
-}
-
-impl Trait<TestWorkingGroupInstance> for Test {
-    type Event = TestEvent;
-    type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-}
-
-pub type Membership = membership::Module<Test>;
-
-pub type TestWorkingGroupInstance = crate::Instance1;
-pub type TestWorkingGroup = Module<Test, TestWorkingGroupInstance>;
-
-pub(crate) const WORKING_GROUP_MINT_CAPACITY: u64 = 40000;
-pub(crate) const WORKING_GROUP_CONSTRAINT_MIN: u16 = 1;
-pub(crate) const WORKING_GROUP_CONSTRAINT_DIFF: u16 = 40;
-
-pub fn build_test_externalities() -> sp_io::TestExternalities {
-    let mut t = frame_system::GenesisConfig::default()
-        .build_storage::<Test>()
-        .unwrap();
-
-    crate::GenesisConfig::<Test, TestWorkingGroupInstance> {
-        phantom: Default::default(),
-        working_group_mint_capacity: WORKING_GROUP_MINT_CAPACITY,
-        opening_human_readable_text_constraint: InputValidationLengthConstraint::new(
-            WORKING_GROUP_CONSTRAINT_MIN,
-            WORKING_GROUP_CONSTRAINT_DIFF,
-        ),
-        worker_application_human_readable_text_constraint: InputValidationLengthConstraint::new(
-            WORKING_GROUP_CONSTRAINT_MIN,
-            WORKING_GROUP_CONSTRAINT_DIFF,
-        ),
-        worker_exit_rationale_text_constraint: InputValidationLengthConstraint::new(
-            WORKING_GROUP_CONSTRAINT_MIN,
-            WORKING_GROUP_CONSTRAINT_DIFF,
-        ),
-    }
-    .assimilate_storage(&mut t)
-    .unwrap();
-
-    t.into()
-}
-
-pub struct StakingEventsHandler<T> {
-    pub marker: PhantomData<T>,
-}
-
-impl<T: stake::Trait + crate::Trait<TestWorkingGroupInstance>> stake::StakingEventsHandler<T>
-    for StakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if crate::MemberIdByHiringApplicationId::<T, TestWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <crate::Module<T, TestWorkingGroupInstance>>::refund_working_group_stake(
-                *stake_id,
-                remaining_imbalance,
-            );
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for slashing
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
-}
-
-// Recommendation from Parity on testing on_finalize
-// https://substrate.dev/docs/en/next/development/module/tests
-pub fn run_to_block(n: u64) {
-    while System::block_number() < n {
-        <System as OnFinalize<u64>>::on_finalize(System::block_number());
-        <TestWorkingGroup as OnFinalize<u64>>::on_finalize(System::block_number());
-        System::set_block_number(System::block_number() + 1);
-        <System as OnInitialize<u64>>::on_initialize(System::block_number());
-        <TestWorkingGroup as OnInitialize<u64>>::on_initialize(System::block_number());
-    }
-}

+ 4 - 6
runtime-modules/working-team/src/tests/mock/mod.rs → runtime-modules/working-group/src/tests/mock/mod.rs

@@ -16,7 +16,7 @@ impl_outer_origin! {
 
 mod staking_handler;
 
-mod working_team {
+mod working_group {
     pub use crate::Event;
 }
 
@@ -116,8 +116,6 @@ parameter_types! {
 }
 
 impl Trait for Test {
-    type OpeningId = u64;
-    type ApplicationId = u64;
     type Event = TestEvent;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
     type StakingHandler = staking_handler::StakingManager<Self, LockId>;
@@ -140,7 +138,7 @@ impl common::origin::ActorOriginValidator<Origin, u64, u64> for () {
     }
 }
 
-pub type TestWorkingTeam = Module<Test, DefaultInstance>;
+pub type TestWorkingGroup = Module<Test, DefaultInstance>;
 
 pub const STAKING_ACCOUNT_ID_FOR_FAILED_VALIDITY_CHECK: u64 = 111;
 pub const STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES: u64 = 333;
@@ -159,9 +157,9 @@ pub fn build_test_externalities() -> sp_io::TestExternalities {
 pub fn run_to_block(n: u64) {
     while System::block_number() < n {
         <System as OnFinalize<u64>>::on_finalize(System::block_number());
-        <TestWorkingTeam as OnFinalize<u64>>::on_finalize(System::block_number());
+        <TestWorkingGroup as OnFinalize<u64>>::on_finalize(System::block_number());
         System::set_block_number(System::block_number() + 1);
         <System as OnInitialize<u64>>::on_initialize(System::block_number());
-        <TestWorkingTeam as OnInitialize<u64>>::on_initialize(System::block_number());
+        <TestWorkingGroup as OnInitialize<u64>>::on_initialize(System::block_number());
     }
 }

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

@@ -0,0 +1,98 @@
+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)
+    }
+}

File diff suppressed because it is too large
+ 422 - 418
runtime-modules/working-group/src/tests/mod.rs


+ 179 - 159
runtime-modules/working-group/src/types.rs

@@ -1,99 +1,78 @@
 #![warn(missing_docs)]
 
 use codec::{Decode, Encode};
-use sp_std::collections::btree_set::BTreeSet;
+use sp_std::vec::Vec;
 
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
+use sp_std::marker::PhantomData;
 
-/// Terms for slashes 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,
+/// Working group job application type alias.
+pub type Application<T> = JobApplication<<T as frame_system::Trait>::AccountId, MemberId<T>>;
 
-    /// Maximum percentage points of remaining stake which may be slashed in a single slash.
-    pub max_percent_pts_per_time: u16,
-}
+/// Member identifier in membership::member module.
+pub type MemberId<T> = <T as membership::Trait>::MemberId;
 
-/// 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 {
-    /// Cannot be slashed.
-    Unslashable,
+/// Type identifier for a worker role, which must be same as membership actor identifier.
+pub type WorkerId<T> = <T as membership::Trait>::ActorId;
 
-    /// Can be slashed.
-    Slashable(SlashableTerms),
-}
+/// Type for an application id.
+pub type ApplicationId = u64;
 
-/// Must be default constructable 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
-    }
-}
+/// Type for an opening id.
+pub type OpeningId = u64;
 
-/// 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 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: unstaking period for the application stake of failed applicants.
-    pub fill_opening_failed_applicant_application_stake_unstaking_period: Option<BlockNumber>,
-
-    /// When filling an opening: unstaking period for the role stake of failed applicants.
-    pub fill_opening_failed_applicant_role_stake_unstaking_period: Option<BlockNumber>,
+// ApplicationId - Application - helper struct.
+pub(crate) struct ApplicationInfo<T: crate::Trait<I>, I: crate::Instance> {
+    pub application_id: ApplicationId,
+    pub application: Application<T>,
+    pub marker: PhantomData<I>,
+}
 
-    /// When terminating a worker: unstaking period for application stake.
-    pub terminate_application_stake_unstaking_period: Option<BlockNumber>,
+// WorkerId - Worker - helper struct.
+pub(crate) struct WorkerInfo<T: membership::Trait + frame_system::Trait + balances::Trait> {
+    pub worker_id: WorkerId<T>,
+    pub worker: Worker<T>,
+}
 
-    /// When terminating a worke/leadr: unstaking period for role stake.
-    pub terminate_role_stake_unstaking_period: Option<BlockNumber>,
+impl<T: membership::Trait + frame_system::Trait + balances::Trait> From<(WorkerId<T>, Worker<T>)>
+    for WorkerInfo<T>
+{
+    fn from((worker_id, worker): (WorkerId<T>, Worker<T>)) -> Self {
+        WorkerInfo { worker_id, worker }
+    }
+}
 
-    /// When a worker/lead exists: unstaking period for application stake.
-    pub exit_role_application_stake_unstaking_period: Option<BlockNumber>,
+/// Group worker type alias.
+pub type Worker<T> = GroupWorker<
+    <T as frame_system::Trait>::AccountId,
+    MemberId<T>,
+    <T as frame_system::Trait>::BlockNumber,
+    BalanceOf<T>,
+>;
 
-    /// When a worker/lead exists: unstaking period for role stake.
-    pub exit_role_stake_unstaking_period: Option<BlockNumber>,
-}
+/// Balance alias for `balances` module.
+pub type BalanceOf<T> = <T as balances::Trait>::Balance;
 
-/// An opening for a worker or lead role.
+/// Job opening for the normal or leader position.
+/// An opening represents the process of hiring one or more new actors into some available role.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct Opening<OpeningId, BlockNumber, Balance, WorkerApplicationId: core::cmp::Ord> {
-    /// Identifier for underlying opening in the hiring module.
-    pub hiring_opening_id: OpeningId,
+#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, Eq)]
+pub struct Opening<BlockNumber: Ord, Balance> {
+    /// Defines opening type: Leader or worker.
+    pub opening_type: OpeningType,
 
-    /// Set of identifiers for all worker applications ever added.
-    pub applications: BTreeSet<WorkerApplicationId>,
+    /// Block at which opening was added.
+    pub created: BlockNumber,
 
-    /// Commitment to policies in opening.
-    pub policy_commitment: OpeningPolicyCommitment<BlockNumber, Balance>,
+    /// Hash of the opening description.
+    pub description_hash: Vec<u8>,
 
-    /// Defines opening type: Leader or worker.
-    pub opening_type: OpeningType,
+    /// Stake policy for the job opening.
+    pub stake_policy: Option<StakePolicy<BlockNumber, Balance>>,
+
+    /// Reward policy for the job opening.
+    pub reward_policy: Option<RewardPolicy<Balance>>,
 }
 
 /// Defines type of the opening: regular working group fellow or group leader.
@@ -104,148 +83,189 @@ pub enum OpeningType {
     Leader,
 
     /// Regular worker.
-    Worker,
+    Regular,
 }
 
 /// 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 OpeningType {
     fn default() -> Self {
-        Self::Worker
+        Self::Regular
     }
 }
 
-/// An application for the worker/lead role.
+/// An application for the regular worker/lead role opening.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct Application<AccountId, OpeningId, MemberId, ApplicationId> {
+pub struct JobApplication<AccountId, MemberId> {
     /// Account used to authenticate in this role.
     pub role_account_id: AccountId,
 
-    /// Opening on which this application applies.
-    pub opening_id: OpeningId,
+    /// Reward account id.
+    pub reward_account_id: AccountId,
+
+    /// Account used to stake in this role.
+    pub staking_account_id: Option<AccountId>,
 
     /// Member applying.
     pub member_id: MemberId,
 
-    /// Underlying application in hiring module.
-    pub hiring_application_id: ApplicationId,
+    /// Hash of the application description.
+    pub description_hash: Vec<u8>,
 }
 
-impl<AccountId: Clone, OpeningId: Clone, MemberId: Clone, ApplicationId: Clone>
-    Application<AccountId, OpeningId, MemberId, ApplicationId>
-{
-    /// Creates a new worker application using parameters.
+impl<AccountId: Clone, MemberId: Clone> JobApplication<AccountId, MemberId> {
+    /// Creates a new job application using parameters.
     pub fn new(
         role_account_id: &AccountId,
-        opening_id: &OpeningId,
+        reward_account_id: &AccountId,
+        staking_account_id: &Option<AccountId>,
         member_id: &MemberId,
-        application_id: &ApplicationId,
+        description_hash: Vec<u8>,
     ) -> Self {
-        Application {
+        JobApplication {
             role_account_id: role_account_id.clone(),
-            opening_id: opening_id.clone(),
+            reward_account_id: reward_account_id.clone(),
+            staking_account_id: staking_account_id.clone(),
             member_id: member_id.clone(),
-            hiring_application_id: application_id.clone(),
+            description_hash,
         }
     }
 }
 
-/// Role stake information for a worker/lead.
+/// Working group participant: regular worker or lead.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct RoleStakeProfile<StakeId, BlockNumber> {
-    /// Whether participant is staked, and if so, the identifier for this staking in the staking module.
-    pub stake_id: StakeId,
-
-    /// Unstaking period when terminated.
-    pub termination_unstaking_period: Option<BlockNumber>,
-
-    /// Unstaking period when exiting.
-    pub exit_unstaking_period: Option<BlockNumber>,
-}
-
-impl<StakeId: Clone, BlockNumber: Clone> RoleStakeProfile<StakeId, BlockNumber> {
-    /// Creates a new worker/lead role stake profile using stake parameters.
-    pub fn new(
-        stake_id: &StakeId,
-        termination_unstaking_period: &Option<BlockNumber>,
-        exit_unstaking_period: &Option<BlockNumber>,
-    ) -> Self {
-        Self {
-            stake_id: stake_id.clone(),
-            termination_unstaking_period: termination_unstaking_period.clone(),
-            exit_unstaking_period: exit_unstaking_period.clone(),
-        }
-    }
-}
-
-/// Working group participant: worker/lead.
-/// This role can be staked, have reward and be inducted through the hiring module.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct Worker<AccountId, RewardRelationshipId, StakeId, BlockNumber, MemberId> {
+pub struct GroupWorker<AccountId, MemberId, BlockNumber, Balance> {
     /// Member id related to the worker/lead.
     pub member_id: MemberId,
 
     /// Account used to authenticate in this role.
     pub role_account_id: AccountId,
 
-    /// Whether the role has recurring reward, and if so an identifier for this.
-    pub reward_relationship: Option<RewardRelationshipId>,
+    /// Account used to stake in this role.
+    pub staking_account_id: Option<AccountId>,
+
+    /// Reward account id.
+    pub reward_account_id: AccountId,
+
+    /// Specifies the block when the worker chose to leave.
+    pub started_leaving_at: Option<BlockNumber>,
 
-    /// When set, describes role stake of the worker/lead.
-    pub role_stake_profile: Option<RoleStakeProfile<StakeId, BlockNumber>>,
+    /// Unstaking period when the worker chooses to leave the role.
+    /// It is defined by the job opening.
+    pub job_unstaking_period: BlockNumber,
+
+    /// Optional reward setting for the worker.
+    pub reward_per_block: Option<Balance>,
+
+    /// Total missed reward amount.
+    pub missed_reward: Option<Balance>,
+
+    /// Specifies the block when the worker was created.
+    pub created_at: BlockNumber,
 }
 
-impl<
-        AccountId: Clone,
-        RewardRelationshipId: Clone,
-        StakeId: Clone,
-        BlockNumber: Clone,
-        MemberId: Clone,
-    > Worker<AccountId, RewardRelationshipId, StakeId, BlockNumber, MemberId>
+impl<AccountId: Clone, MemberId: Clone, BlockNumber, Balance>
+    GroupWorker<AccountId, MemberId, BlockNumber, Balance>
 {
-    /// Creates a new _Worker_ using parameters.
+    /// Creates a new _GroupWorker_ using parameters.
     pub fn new(
         member_id: &MemberId,
         role_account_id: &AccountId,
-        reward_relationship: &Option<RewardRelationshipId>,
-        role_stake_profile: &Option<RoleStakeProfile<StakeId, BlockNumber>>,
+        reward_account_id: &AccountId,
+        staking_account_id: &Option<AccountId>,
+        job_unstaking_period: BlockNumber,
+        reward_per_block: Option<Balance>,
+        created_at: BlockNumber,
     ) -> Self {
-        Worker {
+        GroupWorker {
             member_id: member_id.clone(),
             role_account_id: role_account_id.clone(),
-            reward_relationship: reward_relationship.clone(),
-            role_stake_profile: role_stake_profile.clone(),
+            reward_account_id: reward_account_id.clone(),
+            staking_account_id: staking_account_id.clone(),
+            started_leaving_at: None,
+            job_unstaking_period,
+            reward_per_block,
+            missed_reward: None,
+            created_at,
         }
     }
+
+    /// Defines whether the worker is leaving the role.
+    pub fn is_leaving(&self) -> bool {
+        self.started_leaving_at.is_some()
+    }
+}
+
+/// Reward policy for the job opening.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
+pub struct RewardPolicy<Balance> {
+    /// Reward per block for the worker.
+    pub reward_per_block: Balance,
 }
 
-/// Origin of exit initiation.
+/// Stake policy for the job opening.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-pub enum ExitInitiationOrigin {
-    /// Lead fires the worker.
-    Lead,
+#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
+pub struct StakePolicy<BlockNumber, Balance> {
+    /// Stake amount for applicants.
+    pub stake_amount: Balance,
+
+    /// Unstaking period for the stake. Zero means no unstaking period.
+    pub leaving_unstaking_period: BlockNumber,
+}
+
+/// Parameters container for the apply_on_opening extrinsic.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
+pub struct ApplyOnOpeningParams<MemberId, OpeningId, AccountId, Balance> {
+    /// Applying member id.
+    pub member_id: MemberId,
+
+    /// Opening id to apply on.
+    pub opening_id: OpeningId,
 
-    /// Worker leaves the position.
-    Worker,
+    /// Role account id.
+    pub role_account_id: AccountId,
+
+    /// Reward account id.
+    pub reward_account_id: AccountId,
+
+    /// Application description.
+    pub description: Vec<u8>,
 
-    /// Council fires the leader.
-    Sudo,
+    /// Stake information for the application.
+    pub stake_parameters: Option<StakeParameters<AccountId, Balance>>,
 }
 
-/// The recurring reward if any to be assigned to an actor when filling in the position.
+/// Contains information for the stakes when applying for opening.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, PartialEq, Debug)]
-pub struct RewardPolicy<Balance, BlockNumber> {
-    /// Balance per payout.
-    pub amount_per_payout: Balance,
+#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
+pub struct StakeParameters<AccountId, Balance> {
+    /// Stake balance.
+    pub stake: Balance,
 
-    /// Next payment time (in blocks).
-    pub next_payment_at_block: BlockNumber,
+    /// Staking account id.
+    pub staking_account_id: AccountId,
+}
+
+/// ApplyOnOpeningParams type alias.
+pub type ApplyOnOpeningParameters<T> = ApplyOnOpeningParams<
+    MemberId<T>,
+    OpeningId,
+    <T as frame_system::Trait>::AccountId,
+    BalanceOf<T>,
+>;
+
+/// Contains information for the slashing.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
+pub struct Penalty<Balance> {
+    /// Slashing rationale
+    pub slashing_text: Vec<u8>,
 
-    /// Optional payout interval.
-    pub payout_interval: Option<BlockNumber>,
+    /// Slashing balance
+    pub slashing_amount: Balance,
 }

+ 0 - 39
runtime-modules/working-team/Cargo.toml

@@ -1,39 +0,0 @@
-[package]
-name = "pallet-working-team"
-version = "1.0.1"
-authors = ['Joystream contributors']
-edition = '2018'
-
-[dependencies]
-serde = { version = "1.0.101", optional = true, features = ["derive"] }
-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'}
-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'}
-sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
-common = { package = 'pallet-common', default-features = false, path = '../common'}
-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}
-
-[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'}
-pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
-
-[features]
-default = ['std']
-runtime-benchmarks = ["frame-benchmarking"]
-std = [
-	'serde',
-	'codec/std',
-	'sp-runtime/std',
-	'frame-support/std',
-	'frame-system/std',
-	'sp-arithmetic/std',
-	'sp-std/std',
-	'common/std',
-	'membership/std',
-	'balances/std',
-]

+ 0 - 90
runtime-modules/working-team/src/errors.rs

@@ -1,90 +0,0 @@
-#![warn(missing_docs)]
-
-use crate::{Instance, Module, Trait};
-use frame_support::decl_error;
-
-decl_error! {
-    /// Discussion module predefined errors
-    pub enum Error for Module<T: Trait<I>, I: Instance>{
-        /// Provided stake balance cannot be zero.
-        StakeBalanceCannotBeZero,
-
-        /// Opening does not exist.
-        OpeningDoesNotExist,
-
-        /// Cannot fill opening with multiple applications.
-        CannotHireMultipleLeaders,
-
-        /// Worker application does not exist.
-        WorkerApplicationDoesNotExist,
-
-        /// Working team size limit exceeded.
-        MaxActiveWorkerNumberExceeded,
-
-        /// Successful worker application does not exist.
-        SuccessfulWorkerApplicationDoesNotExist,
-
-        /// There is leader already, cannot hire another one.
-        CannotHireLeaderWhenLeaderExists,
-
-        /// Not a lead account.
-        IsNotLeadAccount,
-
-        /// Current lead is not set.
-        CurrentLeadNotSet,
-
-        /// Worker does not exist.
-        WorkerDoesNotExist,
-
-        /// Invalid origin for a member.
-        InvalidMemberOrigin,
-
-        /// Signer is not worker role account.
-        SignerIsNotWorkerRoleAccount,
-
-        /// Cannot stake zero.
-        CannotStakeZero,
-
-        /// Insufficient balance to cover stake.
-        InsufficientBalanceToCoverStake,
-
-        /// Application stake is less than required opening stake.
-        ApplicationStakeDoesntMatchOpening,
-
-        /// Origin is not applicant.
-        OriginIsNotApplicant,
-
-        /// Invalid operation - worker is leaving.
-        WorkerIsLeaving,
-
-        /// Reward could not be zero.
-        CannotRewardWithZero,
-
-        /// Staking account doesn't belong to a member.
-        InvalidStakingAccountForMember,
-
-        /// Staking account contains conflicting stakes.
-        ConflictStakesOnAccount,
-
-        /// Worker has no recurring reward.
-        WorkerHasNoReward,
-
-        /// Specified unstaking period is less then minimum set for the team.
-        UnstakingPeriodLessThanMinimum,
-
-        /// Requested operation with stake is impossible because of stake was not defined for the role.
-        CannotChangeStakeWithoutStakingAccount,
-
-        /// Invalid spending amount.
-        CannotSpendZero,
-
-        /// It's not enough budget for this spending.
-        InsufficientBudgetForSpending,
-
-        /// Cannot fill opening - no applications provided.
-        NoApplicationsProvided,
-
-        /// Cannot decrease stake - stake delta greater than initial stake.
-        CannotDecreaseStakeDeltaGreaterThanStake,
-    }
-}

+ 0 - 1124
runtime-modules/working-team/src/lib.rs

@@ -1,1124 +0,0 @@
-//! # Working team pallet
-//! Working team pallet for the Joystream platform.
-//! Contains abstract working team workflow.
-//!
-//! Exact working group (eg.: forum working group) should create an instance of the Working group module.
-//!
-//! ## Supported extrinsics
-//!
-//! - [add_opening](./struct.Module.html#method.add_opening) - Add an opening for a regular worker/lead role.
-//! - [apply_on_opening](./struct.Module.html#method.apply_on_opening) - Apply on a regular worker/lead opening.
-//! - [fill_opening](./struct.Module.html#method.fill_opening) - Fill opening for regular worker/lead role.
-//! - [update_role_account](./struct.Module.html#method.update_role_account) -  Update the role account of the regular worker/lead.
-//! - [leave_role](./struct.Module.html#method.leave_role) - Leave the role by the active regular worker/lead.
-//! - [terminate_role](./struct.Module.html#method.terminate_role) - Terminate the regular worker/lead role.
-//! - [slash_stake](./struct.Module.html#method.slash_stake) - Slashes the regular worker/lead stake.
-//! - [decrease_stake](./struct.Module.html#method.decrease_stake) - Decreases the regular worker/lead stake and returns the remainder to the worker _role_account_.
-//! - [increase_stake](./struct.Module.html#method.increase_stake) - Increases the regular worker/lead stake.
-//! - [cancel_opening](./struct.Module.html#method.cancel_opening) - Cancel opening for a regular worker/lead.
-//! - [withdraw_application](./struct.Module.html#method.withdraw_application) - Withdraw the regular worker/lead application.
-//! - [set_budget](./struct.Module.html#method.set_budget) - Sets the working team budget.
-//! - [update_reward_account](./struct.Module.html#method.update_reward_account) -  Update the reward account of the regular worker/lead.
-//! - [update_reward_amount](./struct.Module.html#method.update_reward_amount) -  Update the reward amount of the regular worker/lead.
-//! - [set_status_text](./struct.Module.html#method.set_status_text) - Sets the working team status.
-//! - [spend_from_budget](./struct.Module.html#method.spend_from_budget) - Spend tokens from the team budget.
-
-// Ensure we're `no_std` when compiling for Wasm.
-#![cfg_attr(not(feature = "std"), no_std)]
-
-// Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
-//#![warn(missing_docs)]
-
-mod benchmarking;
-mod checks;
-mod errors;
-#[cfg(test)]
-mod tests;
-mod types;
-
-use codec::Codec;
-use frame_support::traits::{Currency, Get};
-use frame_support::weights::Weight;
-use frame_support::IterableStorageMap;
-use frame_support::{decl_event, decl_module, decl_storage, ensure, Parameter, StorageValue};
-use frame_system::{ensure_root, ensure_signed};
-use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
-use sp_runtime::traits::{Hash, MaybeSerialize, Member, SaturatedConversion, Saturating};
-use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
-use sp_std::vec::Vec;
-
-pub use errors::Error;
-use types::{ApplicationInfo, BalanceOf, MemberId, TeamWorker, TeamWorkerId, WorkerInfo};
-pub use types::{
-    ApplyOnOpeningParameters, JobApplication, JobOpening, JobOpeningType, Penalty, RewardPolicy,
-    StakePolicy,
-};
-
-use common::origin::ActorOriginValidator;
-use membership::staking_handler::StakingHandler;
-
-/// The _Team_ main _Trait_
-pub trait Trait<I: Instance = DefaultInstance>:
-    frame_system::Trait + membership::Trait + balances::Trait
-{
-    /// OpeningId type
-    type OpeningId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
-    /// ApplicationId type
-    type ApplicationId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
-    /// _Administration_ event type.
-    type Event: From<Event<Self, I>> + Into<<Self as frame_system::Trait>::Event>;
-
-    /// Defines max workers number in the team.
-    type MaxWorkerNumberLimit: Get<u32>;
-
-    /// Stakes and balance locks handler.
-    type StakingHandler: StakingHandler<Self>;
-
-    /// Validates member id and origin combination
-    type MemberOriginValidator: ActorOriginValidator<Self::Origin, MemberId<Self>, Self::AccountId>;
-
-    /// Defines min unstaking period in the team.
-    type MinUnstakingPeriodLimit: Get<Self::BlockNumber>;
-
-    /// Defines the period every worker gets paid in blocks.
-    type RewardPeriod: Get<u32>;
-}
-
-decl_event!(
-    /// _Team_ events
-    pub enum Event<T, I = DefaultInstance>
-    where
-       <T as Trait<I>>::OpeningId,
-       <T as Trait<I>>::ApplicationId,
-       ApplicationIdToWorkerIdMap = BTreeMap<<T as Trait<I>>::ApplicationId, TeamWorkerId<T>>,
-       TeamWorkerId = TeamWorkerId<T>,
-       <T as frame_system::Trait>::AccountId,
-       Balance = BalanceOf<T>,
-    {
-        /// Emits on adding new job opening.
-        /// Params:
-        /// - Opening id
-        OpeningAdded(OpeningId),
-
-        /// Emits on adding the application for the worker opening.
-        /// Params:
-        /// - Opening id
-        /// - Application id
-        AppliedOnOpening(OpeningId, ApplicationId),
-
-        /// Emits on filling the job opening.
-        /// Params:
-        /// - Worker opening id
-        /// - Worker application id to the worker id dictionary
-        OpeningFilled(OpeningId, ApplicationIdToWorkerIdMap),
-
-        /// Emits on setting the team leader.
-        /// Params:
-        /// - Team worker id.
-        LeaderSet(TeamWorkerId),
-
-        /// Emits on updating the role account of the worker.
-        /// Params:
-        /// - Id of the worker.
-        /// - Role account id of the worker.
-        WorkerRoleAccountUpdated(TeamWorkerId, AccountId),
-
-        /// Emits on un-setting the leader.
-        LeaderUnset(),
-
-        /// Emits on exiting the worker.
-        /// Params:
-        /// - worker id.
-        WorkerExited(TeamWorkerId),
-
-        /// Emits on terminating the worker.
-        /// Params:
-        /// - worker id.
-        TerminatedWorker(TeamWorkerId),
-
-        /// Emits on terminating the leader.
-        /// Params:
-        /// - leader worker id.
-        TerminatedLeader(TeamWorkerId),
-
-        /// Emits on slashing the regular worker/lead stake.
-        /// Params:
-        /// - regular worker/lead id.
-        /// - actual slashed balance.
-        StakeSlashed(TeamWorkerId, Balance),
-
-        /// Emits on decreasing the regular worker/lead stake.
-        /// Params:
-        /// - regular worker/lead id.
-        /// - stake delta amount
-        StakeDecreased(TeamWorkerId, Balance),
-
-        /// Emits on increasing the regular worker/lead stake.
-        /// Params:
-        /// - regular worker/lead id.
-        /// - stake delta amount
-        StakeIncreased(TeamWorkerId, Balance),
-
-        /// Emits on withdrawing the application for the regular worker/lead opening.
-        /// Params:
-        /// - Job application id
-        ApplicationWithdrawn(ApplicationId),
-
-        /// Emits on canceling the job opening.
-        /// Params:
-        /// - Opening id
-        OpeningCanceled(OpeningId),
-
-        /// Emits on setting the budget for the working team.
-        /// Params:
-        /// - new budget
-        BudgetSet(Balance),
-
-        /// Emits on updating the reward account of the worker.
-        /// Params:
-        /// - Id of the worker.
-        /// - Reward account id of the worker.
-        WorkerRewardAccountUpdated(TeamWorkerId, AccountId),
-
-        /// Emits on updating the reward amount of the worker.
-        /// Params:
-        /// - Id of the worker.
-        /// - Reward per block
-        WorkerRewardAmountUpdated(TeamWorkerId, Option<Balance>),
-
-        /// Emits on updating the status text of the working team.
-        /// Params:
-        /// - status text hash
-        StatusTextChanged(Vec<u8>),
-
-        /// Emits on updating the status text of the working team.
-        /// Params:
-        /// - status text hash
-        BudgetSpending(AccountId, Balance),
-    }
-);
-
-decl_storage! {
-    trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as WorkingTeam {
-        /// Next identifier value for new job opening.
-        pub NextOpeningId get(fn next_opening_id): T::OpeningId;
-
-        /// Maps identifier to job opening.
-        pub OpeningById get(fn opening_by_id): map hasher(blake2_128_concat)
-            T::OpeningId => JobOpening<T::BlockNumber, BalanceOf<T>>;
-
-        /// Count of active workers.
-        pub ActiveWorkerCount get(fn active_worker_count): u32;
-
-        /// Maps identifier to worker application on opening.
-        pub ApplicationById get(fn application_by_id) : map hasher(blake2_128_concat)
-            T::ApplicationId => JobApplication<T>;
-
-        /// Next identifier value for new worker application.
-        pub NextApplicationId get(fn next_application_id) : T::ApplicationId;
-
-        /// Next identifier for a new worker.
-        pub NextWorkerId get(fn next_worker_id) : TeamWorkerId<T>;
-
-        /// Maps identifier to corresponding worker.
-        pub WorkerById get(fn worker_by_id) : map hasher(blake2_128_concat)
-            TeamWorkerId<T> => TeamWorker<T>;
-
-        /// Current team lead.
-        pub CurrentLead get(fn current_lead) : Option<TeamWorkerId<T>>;
-
-        /// Budget for the working team.
-        pub Budget get(fn budget) : BalanceOf<T>;
-
-        /// Status text hash.
-        pub StatusTextHash get(fn status_text_hash) : Vec<u8>;
-    }
-}
-
-decl_module! {
-    /// _Working group_ substrate module.
-    pub struct Module<T: Trait<I>, I: Instance=DefaultInstance> for enum Call where origin: T::Origin {
-        /// Default deposit_event() handler
-        fn deposit_event() = default;
-
-        /// Predefined errors
-        type Error = Error<T, I>;
-
-        /// Exports const -  max simultaneous active worker number.
-        const MaxWorkerNumberLimit: u32 = T::MaxWorkerNumberLimit::get();
-
-        fn on_initialize() -> Weight {
-            let leaving_workers = Self::get_workers_with_finished_unstaking_period();
-
-            leaving_workers.iter().for_each(|wi| {
-                Self::remove_worker(&wi.worker_id, &wi.worker, RawEvent::WorkerExited(wi.worker_id));
-            });
-
-            if Self::is_reward_block() {
-                WorkerById::<T, I>::iter().for_each(|(worker_id, worker)| {
-                    Self::reward_worker(&worker_id, &worker);
-                });
-            }
-
-            10_000_000 //TODO: adjust weight
-        }
-
-        /// Add a job opening for a regular worker/lead role.
-        /// Require signed leader origin or the root (to add opening for the leader position).
-        #[weight = 10_000_000] // TODO: adjust weight: it should also consider a description length
-        pub fn add_opening(
-            origin,
-            description: Vec<u8>,
-            opening_type: JobOpeningType,
-            stake_policy: Option<StakePolicy<T::BlockNumber, BalanceOf<T>>>,
-            reward_policy: Option<RewardPolicy<BalanceOf<T>>>
-        ){
-            checks::ensure_origin_for_opening_type::<T, I>(origin, opening_type)?;
-
-            checks::ensure_valid_stake_policy::<T, I>(&stake_policy)?;
-
-            checks::ensure_valid_reward_policy::<T, I>(&reward_policy)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let hashed_description = T::Hashing::hash(&description);
-
-            // Create and add worker opening.
-            let new_opening = JobOpening{
-                opening_type,
-                created: Self::current_block(),
-                description_hash: hashed_description.as_ref().to_vec(),
-                stake_policy,
-                reward_policy,
-            };
-
-            let new_opening_id = NextOpeningId::<T, I>::get();
-
-            OpeningById::<T, I>::insert(new_opening_id, new_opening);
-
-            // Update NextOpeningId
-            NextOpeningId::<T, I>::mutate(|id| *id += <T::OpeningId as One>::one());
-
-            Self::deposit_event(RawEvent::OpeningAdded(new_opening_id));
-        }
-
-        /// Apply on a worker opening.
-        #[weight = 10_000_000] // TODO: adjust weight: it should also consider a description length
-        pub fn apply_on_opening(origin, p : ApplyOnOpeningParameters<T, I>) {
-            // Ensure the origin of a member with given id.
-            T::MemberOriginValidator::ensure_actor_origin(origin, p.member_id)?;
-
-            // Ensure job opening exists.
-            let opening = checks::ensure_opening_exists::<T, I>(&p.opening_id)?;
-
-            // Ensure that proposed stake is enough for the opening.
-            checks::ensure_application_stake_match_opening::<T, I>(&opening, &p.stake_parameters)?;
-
-            // Checks external conditions for staking.
-            if let Some(sp) = p.stake_parameters.clone() {
-                ensure!(
-                    T::StakingHandler::is_member_staking_account(&p.member_id, &sp.staking_account_id),
-                    Error::<T, I>::InvalidStakingAccountForMember
-                );
-
-                ensure!(
-                    T::StakingHandler::is_account_free_of_conflicting_stakes(&sp.staking_account_id),
-                    Error::<T, I>::ConflictStakesOnAccount
-                );
-
-                ensure!(
-                    T::StakingHandler::is_enough_balance_for_stake(&sp.staking_account_id, sp.stake),
-                    Error::<T, I>::InsufficientBalanceToCoverStake
-                );
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some(sp) = p.stake_parameters.clone() {
-                T::StakingHandler::lock(&sp.staking_account_id, sp.stake);
-            }
-
-            let hashed_description = T::Hashing::hash(&p.description);
-
-            // Make regular/lead application.
-            let application = JobApplication::<T>::new(
-                &p.role_account_id,
-                &p.reward_account_id,
-                &p.stake_parameters.map(|sp| sp.staking_account_id),
-                &p.member_id,
-                hashed_description.as_ref().to_vec(),
-            );
-
-            // Get id of new worker/lead application
-            let new_application_id = NextApplicationId::<T, I>::get();
-
-            // Store an application.
-            ApplicationById::<T, I>::insert(new_application_id, application);
-
-            // Update the next application identifier value.
-            NextApplicationId::<T, I>::mutate(|id| *id += <T::ApplicationId as One>::one());
-
-            // Trigger the event.
-            Self::deposit_event(RawEvent::AppliedOnOpening(p.opening_id, new_application_id));
-        }
-
-        /// Fill opening for the regular/lead position.
-        /// Require signed leader origin or the root (to fill opening for the leader position).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn fill_opening(
-            origin,
-            opening_id: T::OpeningId,
-            successful_application_ids: BTreeSet<T::ApplicationId>,
-        ) {
-            // Ensure job opening exists.
-            let opening = checks::ensure_opening_exists::<T, I>(&opening_id)?;
-
-            checks::ensure_origin_for_opening_type::<T, I>(origin, opening.opening_type)?;
-
-            // Ensure we're not exceeding the maximum worker number.
-            let potential_worker_number =
-                Self::active_worker_count() + (successful_application_ids.len() as u32);
-            ensure!(
-                potential_worker_number <= T::MaxWorkerNumberLimit::get(),
-                Error::<T, I>::MaxActiveWorkerNumberExceeded
-            );
-
-            // Cannot hire a lead when another leader exists.
-            if matches!(opening.opening_type, JobOpeningType::Leader) {
-                ensure!(!<CurrentLead<T,I>>::exists(), Error::<T, I>::CannotHireLeaderWhenLeaderExists);
-            }
-
-            let checked_applications_info = checks::ensure_succesful_applications_exist::<T, I>(&successful_application_ids)?;
-
-            // Check for a single application for a leader.
-            if matches!(opening.opening_type, JobOpeningType::Leader) {
-                ensure!(successful_application_ids.len() == 1, Error::<T, I>::CannotHireMultipleLeaders);
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Process successful applications
-            let application_id_to_worker_id = Self::fulfill_successful_applications(
-                &opening,
-                checked_applications_info
-            );
-
-            // Remove the opening.
-            <OpeningById::<T, I>>::remove(opening_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::OpeningFilled(opening_id, application_id_to_worker_id));
-        }
-
-        /// Update the associated role account of the active regular worker/lead.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_role_account(
-            origin,
-            worker_id: TeamWorkerId<T>,
-            new_role_account_id: T::AccountId
-        ) {
-            // Ensuring worker actually exists
-            let worker = checks::ensure_worker_exists::<T, I>(&worker_id)?;
-
-            // Ensure that origin is signed by member with given id.
-            checks::ensure_origin_signed_by_member::<T, I>(origin, &worker.member_id)?;
-
-            // Ensure the worker is active.
-            ensure!(!worker.is_leaving(), Error::<T, I>::WorkerIsLeaving);
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Update role account
-            WorkerById::<T, I>::mutate(worker_id, |worker| {
-                worker.role_account_id = new_role_account_id.clone()
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::WorkerRoleAccountUpdated(worker_id, new_role_account_id));
-        }
-
-        /// Leave the role by the active worker.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn leave_role(
-            origin,
-            worker_id: TeamWorkerId<T>,
-        ) {
-            // Ensure there is a signer which matches role account of worker corresponding to provided id.
-            let worker = checks::ensure_worker_signed::<T, I>(origin, &worker_id)?;
-
-            // Ensure the worker is active.
-            ensure!(!worker.is_leaving(), Error::<T, I>::WorkerIsLeaving);
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if Self::can_leave_immediately(&worker){
-                Self::remove_worker(&worker_id, &worker, RawEvent::WorkerExited(worker_id));
-            } else{
-                WorkerById::<T, I>::mutate(worker_id, |worker| {
-                    worker.started_leaving_at = Some(Self::current_block())
-                });
-            }
-        }
-
-        /// Terminate the active worker by the lead.
-        /// Requires signed leader origin or the root (to terminate the leader role).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn terminate_role(
-            origin,
-            worker_id: TeamWorkerId<T>,
-            penalty: Option<Penalty<BalanceOf<T>>>,
-        ) {
-            // Ensure lead is set or it is the council terminating the leader.
-            let is_sudo = checks::ensure_origin_for_worker_operation::<T,I>(origin, worker_id)?;
-
-            // Ensuring worker actually exists.
-            let worker = checks::ensure_worker_exists::<T,I>(&worker_id)?;
-
-            if penalty.is_some() {
-                // Ensure worker has a stake.
-                ensure!(
-                    worker.staking_account_id.is_some(),
-                    Error::<T, I>::CannotChangeStakeWithoutStakingAccount
-                );
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some(penalty) = penalty {
-                if let Some(staking_account_id) = worker.staking_account_id.clone() {
-                    Self::slash(worker_id, &staking_account_id, Some(penalty.slashing_amount));
-                }
-            }
-
-            // Trigger the event
-            let event = if is_sudo {
-                RawEvent::TerminatedLeader(worker_id)
-            } else {
-                RawEvent::TerminatedWorker(worker_id)
-            };
-
-            Self::remove_worker(&worker_id, &worker, event);
-        }
-
-        /// Slashes the regular worker stake, demands a leader origin. No limits, no actions on zero stake.
-        /// If slashing balance greater than the existing stake - stake is slashed to zero.
-        /// Requires signed leader origin or the root (to slash the leader stake).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn slash_stake(origin, worker_id: TeamWorkerId<T>, penalty: Penalty<BalanceOf<T>>) {
-            // Ensure lead is set or it is the council slashing the leader.
-            checks::ensure_origin_for_worker_operation::<T,I>(origin, worker_id)?;
-
-            // Ensuring worker actually exists.
-            let worker = checks::ensure_worker_exists::<T,I>(&worker_id)?;
-
-            // Ensure worker has a stake.
-            ensure!(
-                worker.staking_account_id.is_some(),
-                Error::<T, I>::CannotChangeStakeWithoutStakingAccount
-            );
-
-            ensure!(
-                penalty.slashing_amount != <BalanceOf<T>>::zero(),
-                Error::<T, I>::StakeBalanceCannotBeZero
-            );
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some(staking_account_id) = worker.staking_account_id {
-                Self::slash(worker_id, &staking_account_id, Some(penalty.slashing_amount))
-            }
-        }
-
-        /// Decreases the regular worker/lead stake and returns the remainder to the
-        /// worker staking_account_id. Can be decreased to zero, no actions on zero stake.
-        /// Accepts the stake amount to decrease.
-        /// Requires signed leader origin or the root (to decrease the leader stake).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn decrease_stake(origin, worker_id: TeamWorkerId<T>, stake_balance_delta: BalanceOf<T>) {
-            // Ensure lead is set or it is the council decreasing the leader's stake.
-            checks::ensure_origin_for_worker_operation::<T,I>(origin, worker_id)?;
-
-            let worker = checks::ensure_worker_exists::<T,I>(&worker_id)?;
-
-            // Ensure worker has a stake.
-            ensure!(
-                worker.staking_account_id.is_some(),
-                Error::<T, I>::CannotChangeStakeWithoutStakingAccount
-            );
-
-            // Ensure the worker is active.
-            ensure!(!worker.is_leaving(), Error::<T, I>::WorkerIsLeaving);
-
-            // Ensure non-zero stake delta.
-            ensure!(
-                stake_balance_delta != <BalanceOf<T>>::zero(),
-                Error::<T, I>::StakeBalanceCannotBeZero
-            );
-
-            // Ensure enough stake to decrease.
-            if let Some(staking_account_id) = worker.staking_account_id.clone(){
-                let current_stake = T::StakingHandler::current_stake(&staking_account_id);
-
-                ensure!(
-                    current_stake > stake_balance_delta,
-                    Error::<T, I>::CannotDecreaseStakeDeltaGreaterThanStake
-                );
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-             if let Some(staking_account_id) = worker.staking_account_id{
-                let current_stake = T::StakingHandler::current_stake(&staking_account_id);
-
-                // Cannot possibly overflow because of the already performed check.
-                let new_stake = current_stake.saturating_sub(stake_balance_delta);
-
-                // This external module call both checks and mutates the state.
-                T::StakingHandler::set_stake(&staking_account_id, new_stake)?;
-
-                Self::deposit_event(RawEvent::StakeDecreased(worker_id, stake_balance_delta));
-            }
-        }
-
-        /// Increases the regular worker/lead stake, demands a worker origin.
-        /// Locks tokens from the worker staking_account_id equal to new stake. No limits on the stake.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn increase_stake(origin, worker_id: TeamWorkerId<T>, stake_balance_delta: BalanceOf<T>) {
-            // Checks worker origin and worker existence.
-            let worker = checks::ensure_worker_signed::<T, I>(origin, &worker_id)?;
-
-            // Ensure the worker is active.
-            ensure!(!worker.is_leaving(), Error::<T, I>::WorkerIsLeaving);
-
-            // Ensure worker has a stake.
-            ensure!(
-                worker.staking_account_id.is_some(),
-                Error::<T, I>::CannotChangeStakeWithoutStakingAccount
-            );
-
-            ensure!(
-                stake_balance_delta != <BalanceOf<T>>::zero(),
-                Error::<T, I>::StakeBalanceCannotBeZero
-            );
-
-            if let Some(staking_account_id) = worker.staking_account_id.clone() {
-                ensure!(
-                    T::StakingHandler::is_enough_balance_for_stake(&staking_account_id, stake_balance_delta),
-                    Error::<T, I>::InsufficientBalanceToCoverStake
-                );
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some(staking_account_id) = worker.staking_account_id {
-                let current_stake = T::StakingHandler::current_stake(&staking_account_id);
-
-                let new_stake = current_stake.saturating_add(stake_balance_delta);
-
-                // This external module call both checks and mutates the state.
-                T::StakingHandler::set_stake(&staking_account_id, new_stake)?;
-
-                Self::deposit_event(RawEvent::StakeIncreased(worker_id, stake_balance_delta));
-            }
-        }
-
-        /// Withdraw the worker application. Can be done by the worker only.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn withdraw_application(
-            origin,
-            application_id: T::ApplicationId
-        ) {
-            // Ensuring worker application actually exists
-            let application_info = checks::ensure_application_exists::<T, I>(&application_id)?;
-
-            // Ensure that it is signed
-            let signer_account = ensure_signed(origin)?;
-
-            // Ensure that signer is applicant role account
-            ensure!(
-                signer_account == application_info.application.role_account_id,
-                Error::<T, I>::OriginIsNotApplicant
-            );
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some(staking_account_id) = application_info.application.staking_account_id.clone() {
-                T::StakingHandler::unlock(&staking_account_id);
-            }
-            // Remove an application.
-            <ApplicationById<T, I>>::remove(application_info.application_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::ApplicationWithdrawn(application_id));
-        }
-
-        /// Cancel an opening for the regular worker/lead position.
-        /// Require signed leader origin or the root (to cancel opening for the leader position).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn cancel_opening(
-            origin,
-            opening_id: T::OpeningId,
-        ) {
-            // Ensure job opening exists.
-            let opening = checks::ensure_opening_exists::<T, I>(&opening_id)?;
-
-            checks::ensure_origin_for_opening_type::<T, I>(origin, opening.opening_type)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Remove the opening.
-            <OpeningById::<T, I>>::remove(opening_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::OpeningCanceled(opening_id));
-        }
-
-        /// Sets a new budget for the working team.
-        /// Requires root origin.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn set_budget(
-            origin,
-            new_budget: BalanceOf<T>,
-        ) {
-            ensure_root(origin)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Update the budget.
-            <Budget::<T, I>>::put(new_budget);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::BudgetSet(new_budget));
-        }
-
-        /// Update the reward account associated with a set reward relationship for the active worker.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_reward_account(
-            origin,
-            worker_id: TeamWorkerId<T>,
-            new_reward_account_id: T::AccountId
-        ) {
-            // Ensure there is a signer which matches role account of worker corresponding to provided id.
-            let worker = checks::ensure_worker_signed::<T, I>(origin, &worker_id)?;
-
-            // Ensure the worker actually has a recurring reward.
-            checks::ensure_worker_has_recurring_reward::<T, I>(&worker)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Update worker reward account.
-            WorkerById::<T, I>::mutate(worker_id, |worker| {
-                worker.reward_account_id = new_reward_account_id.clone();
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::WorkerRewardAccountUpdated(worker_id, new_reward_account_id));
-        }
-
-        /// Update the reward per block for the active worker.
-        /// Require signed leader origin or the root (to update leader's reward amount).
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_reward_amount(
-            origin,
-            worker_id: TeamWorkerId<T>,
-            reward_per_block: Option<BalanceOf<T>>
-        ) {
-            // Ensure lead is set or it is the council setting the leader's reward.
-            checks::ensure_origin_for_worker_operation::<T,I>(origin, worker_id)?;
-
-            // Ensuring worker actually exists
-            checks::ensure_worker_exists::<T,I>(&worker_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Update worker reward amount.
-            WorkerById::<T, I>::mutate(worker_id, |worker| {
-                worker.reward_per_block = reward_per_block;
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::WorkerRewardAmountUpdated(worker_id, reward_per_block));
-        }
-
-        /// Sets a new status text for the working team.
-        /// Requires root origin.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn set_status_text(
-            origin,
-            status_text: Option<Vec<u8>>,
-        ) {
-            // Ensure team leader privilege.
-            checks::ensure_origin_is_active_leader::<T,I>(origin)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let status_text_hash = status_text
-                .map(|status_text| {
-                        let hashed = T::Hashing::hash(&status_text);
-
-                        hashed.as_ref().to_vec()
-                    })
-                .unwrap_or_default();
-
-            // Update the status text hash.
-            <StatusTextHash<I>>::put(status_text_hash.clone());
-
-            // Trigger event
-            Self::deposit_event(RawEvent::StatusTextChanged(status_text_hash));
-        }
-
-        /// Transfers specified amount to any account.
-        /// Requires leader origin.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn spend_from_budget(
-            origin,
-            account_id: T::AccountId,
-            amount: BalanceOf<T>,
-            rationale: Option<Vec<u8>>,
-        ) {
-            // Ensure team leader privilege.
-            checks::ensure_origin_is_active_leader::<T,I>(origin)?;
-
-            ensure!(amount > Zero::zero(), Error::<T, I>::CannotSpendZero);
-
-            // Ensures that the budget is sufficient for the spending of specified amount
-            let (_, potential_missed_payment) = Self::calculate_possible_payment(amount);
-            ensure!(
-                potential_missed_payment == Zero::zero(),
-                Error::<T, I>::InsufficientBudgetForSpending
-            );
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            Self::pay_from_budget(&account_id, amount);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::BudgetSpending(account_id, amount));
-        }
-    }
-}
-
-impl<T: Trait<I>, I: Instance> Module<T, I> {
-    // Wrapper-function over frame_system::block_number()
-    fn current_block() -> T::BlockNumber {
-        <frame_system::Module<T>>::block_number()
-    }
-
-    // Increases active worker counter (saturating).
-    fn increase_active_worker_counter() {
-        let next_active_worker_count_value = Self::active_worker_count().saturating_add(1);
-        <ActiveWorkerCount<I>>::put(next_active_worker_count_value);
-    }
-
-    // Decreases active worker counter (saturating).
-    fn decrease_active_worker_counter() {
-        let next_active_worker_count_value = Self::active_worker_count().saturating_sub(1);
-        <ActiveWorkerCount<I>>::put(next_active_worker_count_value);
-    }
-
-    // Processes successful application during the fill_opening().
-    fn fulfill_successful_applications(
-        opening: &JobOpening<T::BlockNumber, BalanceOf<T>>,
-        successful_applications_info: Vec<ApplicationInfo<T, I>>,
-    ) -> BTreeMap<T::ApplicationId, TeamWorkerId<T>> {
-        let mut application_id_to_worker_id = BTreeMap::new();
-
-        successful_applications_info
-            .iter()
-            .for_each(|application_info| {
-                let new_worker_id = Self::create_worker_by_application(&opening, &application_info);
-
-                application_id_to_worker_id.insert(application_info.application_id, new_worker_id);
-
-                // Sets a leader on successful opening when opening is for leader.
-                if matches!(opening.opening_type, JobOpeningType::Leader) {
-                    Self::set_lead(new_worker_id);
-                }
-            });
-
-        application_id_to_worker_id
-    }
-
-    // Creates worker by the application. Deletes application from the storage.
-    fn create_worker_by_application(
-        opening: &JobOpening<T::BlockNumber, BalanceOf<T>>,
-        application_info: &ApplicationInfo<T, I>,
-    ) -> TeamWorkerId<T> {
-        // Get worker id.
-        let new_worker_id = <NextWorkerId<T, I>>::get();
-
-        // Construct a worker.
-        let worker = TeamWorker::<T>::new(
-            &application_info.application.member_id,
-            &application_info.application.role_account_id,
-            &application_info.application.reward_account_id,
-            &application_info.application.staking_account_id,
-            opening
-                .stake_policy
-                .as_ref()
-                .map_or(Zero::zero(), |sp| sp.leaving_unstaking_period),
-            opening.reward_policy.as_ref().map(|rp| rp.reward_per_block),
-            Self::current_block(),
-        );
-
-        // Store a worker.
-        <WorkerById<T, I>>::insert(new_worker_id, worker);
-        Self::increase_active_worker_counter();
-
-        // Update the next worker id.
-        <NextWorkerId<T, I>>::mutate(|id| *id += <TeamWorkerId<T> as One>::one());
-
-        // Remove an application.
-        <ApplicationById<T, I>>::remove(application_info.application_id);
-
-        new_worker_id
-    }
-
-    // Set worker id as a leader id.
-    pub(crate) fn set_lead(worker_id: TeamWorkerId<T>) {
-        // Update current lead
-        <CurrentLead<T, I>>::put(worker_id);
-
-        // Trigger an event
-        Self::deposit_event(RawEvent::LeaderSet(worker_id));
-    }
-
-    // Evict the currently set lead.
-    pub(crate) fn unset_lead() {
-        if checks::ensure_lead_is_set::<T, I>().is_ok() {
-            // Update current lead
-            <CurrentLead<T, I>>::kill();
-
-            Self::deposit_event(RawEvent::LeaderUnset());
-        }
-    }
-
-    // Fires the worker. Unsets the leader if necessary. Decreases active worker counter.
-    // Deposits an event.
-    fn remove_worker(worker_id: &TeamWorkerId<T>, worker: &TeamWorker<T>, event: Event<T, I>) {
-        // Unset lead if the leader is leaving.
-        let leader_worker_id = <CurrentLead<T, I>>::get();
-        if let Some(leader_worker_id) = leader_worker_id {
-            if leader_worker_id == *worker_id {
-                Self::unset_lead();
-            }
-        }
-
-        Self::try_to_pay_missed_reward(worker_id, worker);
-
-        // Remove the worker from the storage.
-        WorkerById::<T, I>::remove(worker_id);
-        Self::decrease_active_worker_counter();
-
-        if let Some(staking_account_id) = worker.staking_account_id.clone() {
-            T::StakingHandler::unlock(&staking_account_id);
-        }
-
-        Self::deposit_event(event);
-    }
-
-    // Slash the stake.
-    fn slash(
-        worker_id: TeamWorkerId<T>,
-        staking_account_id: &T::AccountId,
-        balance: Option<BalanceOf<T>>,
-    ) {
-        let slashed_balance = T::StakingHandler::slash(staking_account_id, balance);
-        Self::deposit_event(RawEvent::StakeSlashed(worker_id, slashed_balance));
-    }
-
-    // Reward a worker using reward presets and working team budget.
-    fn reward_worker(worker_id: &TeamWorkerId<T>, worker: &TeamWorker<T>) {
-        // If reward period is not set.
-        let mut rewarding_period: u32 = T::RewardPeriod::get();
-        if rewarding_period == 0u32 {
-            rewarding_period = One::one();
-        }
-
-        // Modify rewarding period for new workers.
-        let block_from_worker_creation: u128 =
-            (Self::current_block() - worker.created_at).saturated_into();
-        if block_from_worker_creation < rewarding_period.into() {
-            rewarding_period = block_from_worker_creation.saturated_into();
-        }
-
-        if let Some(reward_per_block) = worker.reward_per_block {
-            let reward = reward_per_block * rewarding_period.into();
-
-            let (actual_reward, missed_reward) = Self::calculate_possible_payment(reward);
-
-            // Check whether the budget is not zero.
-            if actual_reward > Zero::zero() {
-                Self::pay_from_budget(&worker.reward_account_id, actual_reward);
-            }
-
-            // Check whether the budget is insufficient.
-            if missed_reward > Zero::zero() {
-                Self::save_missed_reward(worker_id, worker, missed_reward);
-            } else {
-                Self::try_to_pay_missed_reward(worker_id, worker);
-            }
-        }
-    }
-
-    // Transfers the tokens if budget is sufficient. Infallible!
-    // Should be accompanied with previous budget check.
-    fn pay_from_budget(account_id: &T::AccountId, amount: BalanceOf<T>) {
-        let budget = Self::budget();
-
-        let new_budget = budget.saturating_sub(amount);
-        <Budget<T, I>>::put(new_budget);
-
-        let _ = <balances::Module<T>>::deposit_creating(account_id, amount);
-    }
-
-    // Tries to pay missed reward if the reward is enabled for worker and there is enough of team budget.
-    fn try_to_pay_missed_reward(worker_id: &TeamWorkerId<T>, worker: &TeamWorker<T>) {
-        if let Some(missed_reward) = worker.missed_reward {
-            let (could_be_paid_reward, insufficient_amount) =
-                Self::calculate_possible_payment(missed_reward);
-
-            // Checks if the budget allows any payment.
-            if could_be_paid_reward > Zero::zero() {
-                Self::pay_from_budget(&worker.reward_account_id, could_be_paid_reward);
-
-                let new_missed_reward = if insufficient_amount > Zero::zero() {
-                    Some(insufficient_amount)
-                } else {
-                    None
-                };
-
-                // Update worker missed reward.
-                WorkerById::<T, I>::mutate(worker_id, |worker| {
-                    worker.missed_reward = new_missed_reward;
-                });
-            }
-        }
-    }
-
-    // Saves missed reward for a worker.
-    fn save_missed_reward(
-        worker_id: &TeamWorkerId<T>,
-        worker: &TeamWorker<T>,
-        reward: BalanceOf<T>,
-    ) {
-        // Save unpaid reward.
-        let missed_reward_so_far = worker.missed_reward.map_or(Zero::zero(), |val| val);
-
-        let new_missed_reward = missed_reward_so_far + reward;
-
-        // Update worker missed reward.
-        WorkerById::<T, I>::mutate(worker_id, |worker| {
-            worker.missed_reward = Some(new_missed_reward);
-        });
-    }
-
-    // Returns allowed payment by the team budget and possible missed payment
-    fn calculate_possible_payment(amount: BalanceOf<T>) -> (BalanceOf<T>, BalanceOf<T>) {
-        let budget = Self::budget();
-
-        if budget >= amount {
-            (amount, Zero::zero())
-        } else {
-            (budget, amount - budget)
-        }
-    }
-
-    // Returns a collection of workers with finished unstaking period.
-    fn get_workers_with_finished_unstaking_period() -> Vec<WorkerInfo<T>> {
-        WorkerById::<T, I>::iter()
-            .filter_map(|(worker_id, worker)| {
-                if let Some(started_leaving_at) = worker.started_leaving_at {
-                    if started_leaving_at + worker.job_unstaking_period >= Self::current_block() {
-                        return Some((worker_id, worker).into());
-                    }
-                }
-
-                None
-            })
-            .collect::<Vec<_>>()
-    }
-
-    // Defines whether the current block is a reward block.
-    fn is_reward_block() -> bool {
-        let current_block = Self::current_block();
-
-        // Don't reward at genesis.
-        if current_block == Zero::zero() {
-            return false;
-        }
-
-        let reward_period: u32 = T::RewardPeriod::get();
-
-        // Special case for not set reward_period. Treats as reward_period == 1.
-        if reward_period == 0u32 {
-            return true;
-        }
-
-        // Check whether current block is a reward block.
-        current_block % reward_period.into() == Zero::zero()
-    }
-
-    // Defines whether the worker staking parameters allow to leave without unstaking period.
-    fn can_leave_immediately(worker: &TeamWorker<T>) -> bool {
-        if worker.job_unstaking_period == Zero::zero() {
-            return true;
-        }
-
-        if let Some(staking_account_id) = worker.staking_account_id.clone() {
-            if T::StakingHandler::current_stake(&staking_account_id) == Zero::zero() {
-                return true;
-            }
-        }
-
-        false
-    }
-}

+ 0 - 1116
runtime-modules/working-team/src/tests/fixtures.rs

@@ -1,1116 +0,0 @@
-#![cfg(test)]
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::StorageMap;
-use frame_system::{EventRecord, Phase, RawOrigin};
-use sp_runtime::traits::Hash;
-use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
-
-use super::hiring_workflow::HiringWorkflow;
-use super::mock::{Balances, LockId, Membership, System, Test, TestEvent, TestWorkingTeam};
-use crate::types::StakeParameters;
-use crate::{
-    ApplyOnOpeningParameters, DefaultInstance, JobApplication, JobOpening, JobOpeningType, Penalty,
-    RawEvent, RewardPolicy, StakePolicy, TeamWorker,
-};
-
-pub struct EventFixture;
-impl EventFixture {
-    pub fn assert_last_crate_event(
-        expected_raw_event: RawEvent<u64, u64, BTreeMap<u64, u64>, u64, u64, u64, DefaultInstance>,
-    ) {
-        let converted_event = TestEvent::crate_DefaultInstance(expected_raw_event);
-
-        Self::assert_last_global_event(converted_event)
-    }
-
-    pub fn assert_last_global_event(expected_event: TestEvent) {
-        let expected_event = EventRecord {
-            phase: Phase::Initialization,
-            event: expected_event,
-            topics: vec![],
-        };
-
-        assert_eq!(System::events().pop().unwrap(), expected_event);
-    }
-}
-
-pub struct AddOpeningFixture {
-    origin: RawOrigin<u64>,
-    description: Vec<u8>,
-    opening_type: JobOpeningType,
-    starting_block: u64,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-    reward_policy: Option<RewardPolicy<u64>>,
-}
-
-impl Default for AddOpeningFixture {
-    fn default() -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            description: b"human_text".to_vec(),
-            opening_type: JobOpeningType::Regular,
-            starting_block: 0,
-            stake_policy: None,
-            reward_policy: None,
-        }
-    }
-}
-
-impl AddOpeningFixture {
-    pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
-        let saved_opening_next_id = TestWorkingTeam::next_opening_id();
-        let actual_result = self.call().map(|_| ());
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            assert_eq!(
-                TestWorkingTeam::next_opening_id(),
-                saved_opening_next_id + 1
-            );
-            let opening_id = saved_opening_next_id;
-
-            let actual_opening = TestWorkingTeam::opening_by_id(opening_id);
-
-            let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&self.description);
-            let expected_opening = JobOpening {
-                created: self.starting_block,
-                description_hash: expected_hash.as_ref().to_vec(),
-                opening_type: self.opening_type,
-                stake_policy: self.stake_policy.clone(),
-                reward_policy: self.reward_policy.clone(),
-            };
-
-            assert_eq!(actual_opening, expected_opening);
-        }
-
-        saved_opening_next_id
-    }
-
-    pub fn call(&self) -> Result<u64, DispatchError> {
-        let saved_opening_next_id = TestWorkingTeam::next_opening_id();
-        TestWorkingTeam::add_opening(
-            self.origin.clone().into(),
-            self.description.clone(),
-            self.opening_type,
-            self.stake_policy.clone(),
-            self.reward_policy.clone(),
-        )?;
-
-        Ok(saved_opening_next_id)
-    }
-
-    pub fn with_opening_type(self, opening_type: JobOpeningType) -> Self {
-        Self {
-            opening_type,
-            ..self
-        }
-    }
-
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_starting_block(self, starting_block: u64) -> Self {
-        Self {
-            starting_block,
-            ..self
-        }
-    }
-
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
-        Self {
-            reward_policy,
-            ..self
-        }
-    }
-}
-
-pub struct ApplyOnOpeningFixture {
-    origin: RawOrigin<u64>,
-    member_id: u64,
-    opening_id: u64,
-    role_account_id: u64,
-    reward_account_id: u64,
-    description: Vec<u8>,
-    stake_parameters: Option<StakeParameters<u64, u64>>,
-}
-
-impl ApplyOnOpeningFixture {
-    pub fn with_text(self, text: Vec<u8>) -> Self {
-        Self {
-            description: text,
-            ..self
-        }
-    }
-
-    pub fn with_origin(self, origin: RawOrigin<u64>, member_id: u64) -> Self {
-        Self {
-            origin,
-            member_id,
-            ..self
-        }
-    }
-
-    pub fn with_stake_parameters(
-        self,
-        stake_parameters: Option<StakeParameters<u64, u64>>,
-    ) -> Self {
-        Self {
-            stake_parameters,
-            ..self
-        }
-    }
-
-    pub fn default_for_opening_id(opening_id: u64) -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            member_id: 1,
-            opening_id,
-            role_account_id: 1,
-            reward_account_id: 1,
-            description: b"human_text".to_vec(),
-            stake_parameters: None,
-        }
-    }
-
-    pub fn call(&self) -> Result<u64, DispatchError> {
-        let saved_application_next_id = TestWorkingTeam::next_application_id();
-        TestWorkingTeam::apply_on_opening(
-            self.origin.clone().into(),
-            ApplyOnOpeningParameters::<Test, DefaultInstance> {
-                member_id: self.member_id,
-                opening_id: self.opening_id,
-                role_account_id: self.role_account_id,
-                reward_account_id: self.reward_account_id,
-                description: self.description.clone(),
-                stake_parameters: self.stake_parameters.clone(),
-            },
-        )?;
-
-        Ok(saved_application_next_id)
-    }
-    pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
-        let saved_application_next_id = TestWorkingTeam::next_application_id();
-
-        let actual_result = self.call().map(|_| ());
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            assert_eq!(
-                TestWorkingTeam::next_application_id(),
-                saved_application_next_id + 1
-            );
-            let application_id = saved_application_next_id;
-
-            let actual_application = TestWorkingTeam::application_by_id(application_id);
-
-            let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&self.description);
-            let expected_application = JobApplication::<Test> {
-                role_account_id: self.role_account_id,
-                reward_account_id: self.reward_account_id,
-                staking_account_id: self
-                    .stake_parameters
-                    .clone()
-                    .map(|sp| sp.staking_account_id),
-                member_id: self.member_id,
-                description_hash: expected_hash.as_ref().to_vec(),
-            };
-
-            assert_eq!(actual_application, expected_application);
-        }
-
-        saved_application_next_id
-    }
-}
-
-pub fn setup_members(count: u8) {
-    let authority_account_id = 1;
-    Membership::set_screening_authority(RawOrigin::Root.into(), authority_account_id).unwrap();
-
-    for i in 0..count {
-        let account_id: u64 = i as u64;
-        let handle: [u8; 20] = [i; 20];
-        Membership::add_screened_member(
-            RawOrigin::Signed(authority_account_id).into(),
-            account_id,
-            Some(handle.to_vec()),
-            None,
-            None,
-        )
-        .unwrap();
-    }
-}
-
-pub struct FillOpeningFixture {
-    origin: RawOrigin<u64>,
-    opening_id: u64,
-    successful_application_ids: BTreeSet<u64>,
-    role_account_id: u64,
-    reward_account_id: u64,
-    staking_account_id: Option<u64>,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-    reward_policy: Option<RewardPolicy<u64>>,
-    created_at: u64,
-}
-
-impl FillOpeningFixture {
-    pub fn default_for_ids(opening_id: u64, application_ids: Vec<u64>) -> Self {
-        let application_ids: BTreeSet<u64> = application_ids.iter().map(|x| *x).collect();
-
-        Self {
-            origin: RawOrigin::Signed(1),
-            opening_id,
-            successful_application_ids: application_ids,
-            role_account_id: 1,
-            reward_account_id: 1,
-            staking_account_id: None,
-            stake_policy: None,
-            reward_policy: None,
-            created_at: 0,
-        }
-    }
-
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_created_at(self, created_at: u64) -> Self {
-        Self { created_at, ..self }
-    }
-
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn with_staking_account_id(self, staking_account_id: Option<u64>) -> Self {
-        Self {
-            staking_account_id,
-            ..self
-        }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
-        Self {
-            reward_policy,
-            ..self
-        }
-    }
-
-    pub fn call(&self) -> Result<u64, DispatchError> {
-        let saved_worker_next_id = TestWorkingTeam::next_worker_id();
-        TestWorkingTeam::fill_opening(
-            self.origin.clone().into(),
-            self.opening_id,
-            self.successful_application_ids.clone(),
-        )?;
-
-        Ok(saved_worker_next_id)
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) -> u64 {
-        let saved_worker_count = TestWorkingTeam::active_worker_count();
-        let saved_worker_next_id = TestWorkingTeam::next_worker_id();
-        let actual_result = self.call().map(|_| ());
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            assert_eq!(TestWorkingTeam::next_worker_id(), saved_worker_next_id + 1);
-            let worker_id = saved_worker_next_id;
-
-            assert!(!<crate::OpeningById<Test, DefaultInstance>>::contains_key(
-                self.opening_id
-            ));
-
-            for application_id in self.successful_application_ids.iter() {
-                assert!(
-                    !<crate::ApplicationById<Test, DefaultInstance>>::contains_key(application_id)
-                );
-            }
-
-            let expected_worker = TeamWorker::<Test> {
-                member_id: 1,
-                role_account_id: self.role_account_id,
-                reward_account_id: self.reward_account_id,
-                staking_account_id: self.staking_account_id,
-                started_leaving_at: None,
-                job_unstaking_period: self
-                    .stake_policy
-                    .as_ref()
-                    .map_or(0, |sp| sp.leaving_unstaking_period),
-                reward_per_block: self.reward_policy.as_ref().map(|rp| rp.reward_per_block),
-                missed_reward: None,
-                created_at: self.created_at,
-            };
-
-            let actual_worker = TestWorkingTeam::worker_by_id(worker_id);
-
-            assert_eq!(actual_worker, expected_worker);
-
-            let expected_worker_count =
-                saved_worker_count + (self.successful_application_ids.len() as u32);
-
-            assert_eq!(
-                TestWorkingTeam::active_worker_count(),
-                expected_worker_count
-            );
-        }
-
-        saved_worker_next_id
-    }
-}
-
-pub struct HireLeadFixture {
-    setup_environment: bool,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-    reward_policy: Option<RewardPolicy<u64>>,
-}
-
-impl Default for HireLeadFixture {
-    fn default() -> Self {
-        Self {
-            setup_environment: true,
-            stake_policy: None,
-            reward_policy: None,
-        }
-    }
-}
-impl HireLeadFixture {
-    pub fn with_setup_environment(self, setup_environment: bool) -> Self {
-        Self {
-            setup_environment,
-            ..self
-        }
-    }
-
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
-        Self {
-            reward_policy,
-            ..self
-        }
-    }
-
-    pub fn hire_lead(self) -> u64 {
-        HiringWorkflow::default()
-            .with_setup_environment(self.setup_environment)
-            .with_opening_type(JobOpeningType::Leader)
-            .with_stake_policy(self.stake_policy)
-            .with_reward_policy(self.reward_policy)
-            .add_application(b"leader".to_vec())
-            .execute()
-            .unwrap()
-    }
-
-    pub fn expect(self, error: DispatchError) {
-        HiringWorkflow::default()
-            .with_setup_environment(self.setup_environment)
-            .with_opening_type(JobOpeningType::Leader)
-            .with_stake_policy(self.stake_policy)
-            .with_reward_policy(self.reward_policy)
-            .add_application(b"leader".to_vec())
-            .expect(Err(error))
-            .execute();
-    }
-}
-
-pub struct HireRegularWorkerFixture {
-    setup_environment: bool,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-    reward_policy: Option<RewardPolicy<u64>>,
-}
-
-impl Default for HireRegularWorkerFixture {
-    fn default() -> Self {
-        Self {
-            setup_environment: true,
-            stake_policy: None,
-            reward_policy: None,
-        }
-    }
-}
-impl HireRegularWorkerFixture {
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
-        Self {
-            reward_policy,
-            ..self
-        }
-    }
-
-    pub fn hire(self) -> u64 {
-        HiringWorkflow::default()
-            .with_setup_environment(self.setup_environment)
-            .with_opening_type(JobOpeningType::Regular)
-            .with_stake_policy(self.stake_policy)
-            .with_reward_policy(self.reward_policy)
-            .add_application(b"worker".to_vec())
-            .execute()
-            .unwrap()
-    }
-}
-
-pub struct UpdateWorkerRoleAccountFixture {
-    worker_id: u64,
-    new_role_account_id: u64,
-    origin: RawOrigin<u64>,
-}
-
-impl UpdateWorkerRoleAccountFixture {
-    pub fn default_with_ids(worker_id: u64, new_role_account_id: u64) -> Self {
-        Self {
-            worker_id,
-            new_role_account_id,
-            origin: RawOrigin::Signed(1),
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let actual_result = TestWorkingTeam::update_role_account(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.new_role_account_id,
-        );
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            let worker = TestWorkingTeam::worker_by_id(self.worker_id);
-
-            assert_eq!(worker.role_account_id, self.new_role_account_id);
-        }
-    }
-}
-
-pub(crate) struct LeaveWorkerRoleFixture {
-    worker_id: u64,
-    origin: RawOrigin<u64>,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-}
-
-impl LeaveWorkerRoleFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        Self {
-            worker_id,
-            origin: RawOrigin::Signed(1),
-            stake_policy: None,
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let actual_result = TestWorkingTeam::leave_role(self.origin.clone().into(), self.worker_id);
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            if self.stake_policy.is_some() {
-                let worker = TestWorkingTeam::worker_by_id(self.worker_id);
-
-                if worker.job_unstaking_period > 0 {
-                    assert_eq!(
-                        worker.started_leaving_at,
-                        Some(<frame_system::Module<Test>>::block_number())
-                    );
-                    return;
-                }
-            }
-
-            assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
-                self.worker_id
-            ));
-        }
-    }
-}
-
-pub struct TerminateWorkerRoleFixture {
-    worker_id: u64,
-    origin: RawOrigin<u64>,
-    penalty: Option<Penalty<u64>>,
-}
-
-impl TerminateWorkerRoleFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        Self {
-            worker_id,
-            origin: RawOrigin::Signed(1),
-            penalty: None,
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_penalty(self, penalty: Option<Penalty<u64>>) -> Self {
-        Self { penalty, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let actual_result = TestWorkingTeam::terminate_role(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.penalty.clone(),
-        );
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            if actual_result.is_ok() {
-                assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
-                    self.worker_id
-                ));
-            }
-        }
-    }
-}
-
-pub fn increase_total_balance_issuance_using_account_id(account_id: u64, balance: u64) {
-    let _ =
-        <Balances as frame_support::traits::Currency<u64>>::deposit_creating(&account_id, balance);
-}
-
-pub struct SlashWorkerStakeFixture {
-    origin: RawOrigin<u64>,
-    worker_id: u64,
-    account_id: u64,
-    penalty: Penalty<u64>,
-}
-
-impl SlashWorkerStakeFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        let account_id = 1;
-
-        let lead_account_id = get_current_lead_account_id();
-
-        Self {
-            origin: RawOrigin::Signed(lead_account_id),
-            worker_id,
-            penalty: Penalty {
-                slashing_text: Vec::new(),
-                slashing_amount: 10,
-            },
-            account_id,
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_penalty(self, penalty: Penalty<u64>) -> Self {
-        Self { penalty, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_balance = Balances::usable_balance(&self.account_id);
-        let old_stake = get_stake_balance(&self.account_id);
-        let actual_result = TestWorkingTeam::slash_stake(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.penalty.clone(),
-        );
-
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            // stake decreased
-            assert_eq!(
-                old_stake,
-                get_stake_balance(&self.account_id) + self.penalty.slashing_amount
-            );
-
-            let new_balance = Balances::usable_balance(&self.account_id);
-
-            // worker balance unchanged
-            assert_eq!(new_balance, old_balance,);
-        }
-    }
-}
-
-pub(crate) fn get_stake_balance(account_id: &u64) -> u64 {
-    let locks = Balances::locks(account_id);
-
-    let existing_lock = locks.iter().find(|lock| lock.id == LockId::get());
-
-    existing_lock.map_or(0, |lock| lock.amount)
-}
-
-fn get_current_lead_account_id() -> u64 {
-    let leader_worker_id = TestWorkingTeam::current_lead();
-
-    if let Some(leader_worker_id) = leader_worker_id {
-        let leader = TestWorkingTeam::worker_by_id(leader_worker_id);
-        leader.role_account_id
-    } else {
-        0 // return invalid lead_account_id for testing
-    }
-}
-
-pub struct DecreaseWorkerStakeFixture {
-    origin: RawOrigin<u64>,
-    worker_id: u64,
-    balance: u64,
-    account_id: u64,
-}
-
-impl DecreaseWorkerStakeFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        let account_id = 1;
-
-        let lead_account_id = get_current_lead_account_id();
-
-        Self {
-            origin: RawOrigin::Signed(lead_account_id),
-            worker_id,
-            balance: 10,
-            account_id,
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_balance(self, balance: u64) -> Self {
-        Self { balance, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_balance = Balances::usable_balance(&self.account_id);
-        let old_stake = get_stake_balance(&self.account_id);
-        let actual_result = TestWorkingTeam::decrease_stake(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.balance,
-        );
-
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            // new stake was set
-            assert_eq!(self.balance, get_stake_balance(&self.account_id));
-
-            let new_balance = Balances::usable_balance(&self.account_id);
-
-            // worker balance equilibrium
-            assert_eq!(old_balance + old_stake, new_balance + self.balance);
-        }
-    }
-}
-
-pub struct IncreaseWorkerStakeFixture {
-    origin: RawOrigin<u64>,
-    worker_id: u64,
-    balance: u64,
-    account_id: u64,
-}
-
-impl IncreaseWorkerStakeFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        let account_id = 1;
-        Self {
-            origin: RawOrigin::Signed(1),
-            worker_id,
-            balance: 10,
-            account_id,
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_balance(self, balance: u64) -> Self {
-        Self { balance, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_balance = Balances::usable_balance(&self.account_id);
-        let old_stake = get_stake_balance(&self.account_id);
-        let actual_result = TestWorkingTeam::increase_stake(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.balance,
-        );
-
-        assert_eq!(actual_result, expected_result);
-
-        if actual_result.is_ok() {
-            // new stake was set
-            assert_eq!(
-                self.balance + old_stake,
-                get_stake_balance(&self.account_id)
-            );
-
-            let new_balance = Balances::usable_balance(&self.account_id);
-
-            // worker balance equilibrium
-            assert_eq!(
-                old_balance + old_stake,
-                new_balance + self.balance + old_stake
-            );
-        }
-    }
-}
-
-pub struct WithdrawApplicationFixture {
-    origin: RawOrigin<u64>,
-    application_id: u64,
-    stake: bool,
-    account_id: u64,
-}
-
-impl WithdrawApplicationFixture {
-    pub fn with_signer(self, account_id: u64) -> Self {
-        Self {
-            origin: RawOrigin::Signed(account_id),
-            ..self
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_stake(self) -> Self {
-        Self {
-            stake: true,
-            ..self
-        }
-    }
-
-    pub fn default_for_application_id(application_id: u64) -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            application_id,
-            stake: false,
-            account_id: 1,
-        }
-    }
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_balance = Balances::usable_balance(&self.account_id);
-        let old_stake = get_stake_balance(&self.account_id);
-
-        let actual_result =
-            TestWorkingTeam::withdraw_application(self.origin.clone().into(), self.application_id);
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            if self.stake {
-                // the stake was removed
-                assert_eq!(0, get_stake_balance(&self.account_id));
-
-                let new_balance = Balances::usable_balance(&self.account_id);
-
-                // worker balance equilibrium
-                assert_eq!(old_balance + old_stake, new_balance);
-            }
-        }
-    }
-}
-
-pub struct CancelOpeningFixture {
-    origin: RawOrigin<u64>,
-    opening_id: u64,
-}
-
-impl CancelOpeningFixture {
-    pub fn default_for_opening_id(opening_id: u64) -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            opening_id,
-        }
-    }
-
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn call(&self) -> DispatchResult {
-        TestWorkingTeam::cancel_opening(self.origin.clone().into(), self.opening_id)
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        if expected_result.is_ok() {
-            assert!(<crate::OpeningById<Test, DefaultInstance>>::contains_key(
-                self.opening_id
-            ));
-        }
-
-        let actual_result = self.call().map(|_| ());
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            assert!(!<crate::OpeningById<Test, DefaultInstance>>::contains_key(
-                self.opening_id
-            ));
-        }
-    }
-}
-
-pub struct SetBudgetFixture {
-    origin: RawOrigin<u64>,
-    new_budget: u64,
-}
-
-impl Default for SetBudgetFixture {
-    fn default() -> Self {
-        Self {
-            origin: RawOrigin::Root,
-            new_budget: 1000000,
-        }
-    }
-}
-
-impl SetBudgetFixture {
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_budget(self, new_budget: u64) -> Self {
-        Self { new_budget, ..self }
-    }
-
-    pub fn execute(self) {
-        self.call().unwrap();
-    }
-
-    pub fn call(&self) -> DispatchResult {
-        TestWorkingTeam::set_budget(self.origin.clone().into(), self.new_budget)
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_budget = TestWorkingTeam::budget();
-
-        let actual_result = self.call().map(|_| ());
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        let new_budget = TestWorkingTeam::budget();
-
-        if actual_result.is_ok() {
-            assert_eq!(new_budget, self.new_budget);
-        } else {
-            assert_eq!(new_budget, old_budget);
-        }
-    }
-}
-
-pub struct UpdateRewardAccountFixture {
-    worker_id: u64,
-    new_reward_account_id: u64,
-    origin: RawOrigin<u64>,
-}
-
-impl UpdateRewardAccountFixture {
-    pub fn default_with_ids(worker_id: u64, new_reward_account_id: u64) -> Self {
-        Self {
-            worker_id,
-            new_reward_account_id,
-            origin: RawOrigin::Signed(1),
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let actual_result = TestWorkingTeam::update_reward_account(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.new_reward_account_id,
-        );
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            let worker = TestWorkingTeam::worker_by_id(self.worker_id);
-
-            assert_eq!(worker.reward_account_id, self.new_reward_account_id);
-        }
-    }
-}
-
-pub struct UpdateRewardAmountFixture {
-    worker_id: u64,
-    reward_per_block: Option<u64>,
-    origin: RawOrigin<u64>,
-}
-
-impl UpdateRewardAmountFixture {
-    pub fn default_for_worker_id(worker_id: u64) -> Self {
-        let lead_account_id = get_current_lead_account_id();
-
-        Self {
-            worker_id,
-            reward_per_block: None,
-            origin: RawOrigin::Signed(lead_account_id),
-        }
-    }
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_reward_per_block(self, reward_per_block: Option<u64>) -> Self {
-        Self {
-            reward_per_block,
-            ..self
-        }
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let actual_result = TestWorkingTeam::update_reward_amount(
-            self.origin.clone().into(),
-            self.worker_id,
-            self.reward_per_block,
-        );
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        if actual_result.is_ok() {
-            let worker = TestWorkingTeam::worker_by_id(self.worker_id);
-
-            assert_eq!(worker.reward_per_block, self.reward_per_block);
-        }
-    }
-}
-
-pub struct SetStatusTextFixture {
-    origin: RawOrigin<u64>,
-    new_status_text: Option<Vec<u8>>,
-}
-
-impl Default for SetStatusTextFixture {
-    fn default() -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            new_status_text: None,
-        }
-    }
-}
-
-impl SetStatusTextFixture {
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_status_text(self, new_status_text: Option<Vec<u8>>) -> Self {
-        Self {
-            new_status_text,
-            ..self
-        }
-    }
-
-    pub fn call(&self) -> DispatchResult {
-        TestWorkingTeam::set_status_text(self.origin.clone().into(), self.new_status_text.clone())
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_text_hash = TestWorkingTeam::status_text_hash();
-
-        let actual_result = self.call().map(|_| ());
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        let new_text_hash = TestWorkingTeam::status_text_hash();
-
-        if actual_result.is_ok() {
-            let expected_hash = <Test as frame_system::Trait>::Hashing::hash(
-                &self.new_status_text.clone().unwrap(),
-            );
-
-            assert_eq!(new_text_hash, expected_hash.as_ref().to_vec());
-        } else {
-            assert_eq!(new_text_hash, old_text_hash);
-        }
-    }
-}
-
-pub struct SpendFromBudgetFixture {
-    origin: RawOrigin<u64>,
-    account_id: u64,
-    amount: u64,
-    rationale: Option<Vec<u8>>,
-}
-
-impl Default for SpendFromBudgetFixture {
-    fn default() -> Self {
-        Self {
-            origin: RawOrigin::Signed(1),
-            account_id: 1,
-            amount: 100,
-            rationale: None,
-        }
-    }
-}
-
-impl SpendFromBudgetFixture {
-    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
-        Self { origin, ..self }
-    }
-
-    pub fn with_account_id(self, account_id: u64) -> Self {
-        Self { account_id, ..self }
-    }
-
-    pub fn with_amount(self, amount: u64) -> Self {
-        Self { amount, ..self }
-    }
-
-    pub fn call(&self) -> DispatchResult {
-        TestWorkingTeam::spend_from_budget(
-            self.origin.clone().into(),
-            self.account_id,
-            self.amount,
-            self.rationale.clone(),
-        )
-    }
-
-    pub fn call_and_assert(&self, expected_result: DispatchResult) {
-        let old_budget = TestWorkingTeam::budget();
-        let old_balance = Balances::usable_balance(&self.account_id);
-
-        let actual_result = self.call().map(|_| ());
-
-        assert_eq!(actual_result.clone(), expected_result);
-
-        let new_budget = TestWorkingTeam::budget();
-        let new_balance = Balances::usable_balance(&self.account_id);
-
-        if actual_result.is_ok() {
-            assert_eq!(new_budget, old_budget - self.amount);
-            assert_eq!(new_balance, old_balance + self.amount);
-        } else {
-            assert_eq!(old_budget, new_budget);
-            assert_eq!(old_balance, new_balance);
-        }
-    }
-}

+ 0 - 181
runtime-modules/working-team/src/tests/hiring_workflow.rs

@@ -1,181 +0,0 @@
-use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_system::RawOrigin;
-
-use crate::tests::fixtures::{
-    setup_members, AddOpeningFixture, ApplyOnOpeningFixture, FillOpeningFixture, HireLeadFixture,
-};
-use crate::tests::mock::TestWorkingTeam;
-use crate::types::StakeParameters;
-use crate::{JobOpeningType, RewardPolicy, StakePolicy};
-
-#[derive(Clone)]
-struct HiringWorkflowApplication {
-    stake_parameters: Option<StakeParameters<u64, u64>>,
-    worker_handle: Vec<u8>,
-    origin: RawOrigin<u64>,
-    member_id: u64,
-}
-
-pub struct HiringWorkflow {
-    opening_type: JobOpeningType,
-    expected_result: DispatchResult,
-    stake_policy: Option<StakePolicy<u64, u64>>,
-    reward_policy: Option<RewardPolicy<u64>>,
-    applications: Vec<HiringWorkflowApplication>,
-    setup_environment: bool,
-}
-
-impl Default for HiringWorkflow {
-    fn default() -> Self {
-        Self {
-            opening_type: JobOpeningType::Regular,
-            expected_result: Ok(()),
-            stake_policy: None,
-            reward_policy: None,
-            applications: Vec::new(),
-            setup_environment: true,
-        }
-    }
-}
-
-impl HiringWorkflow {
-    pub fn with_stake_policy(self, stake_policy: Option<StakePolicy<u64, u64>>) -> Self {
-        Self {
-            stake_policy,
-            ..self
-        }
-    }
-
-    pub fn with_reward_policy(self, reward_policy: Option<RewardPolicy<u64>>) -> Self {
-        Self {
-            reward_policy,
-            ..self
-        }
-    }
-
-    pub fn expect(self, result: DispatchResult) -> Self {
-        Self {
-            expected_result: result,
-            ..self
-        }
-    }
-
-    pub fn with_setup_environment(self, setup_environment: bool) -> Self {
-        Self {
-            setup_environment,
-            ..self
-        }
-    }
-
-    pub fn with_opening_type(self, opening_type: JobOpeningType) -> Self {
-        Self {
-            opening_type,
-            ..self
-        }
-    }
-
-    pub fn add_default_application(self) -> Self {
-        let worker_handle = b"default".to_vec();
-
-        self.add_application(worker_handle)
-    }
-
-    pub fn add_application(self, worker_handle: Vec<u8>) -> Self {
-        self.add_application_full(worker_handle, RawOrigin::Signed(1), 1, Some(1))
-    }
-
-    pub fn add_application_full(
-        self,
-        worker_handle: Vec<u8>,
-        origin: RawOrigin<u64>,
-        member_id: u64,
-        staking_account_id: Option<u64>,
-    ) -> Self {
-        let stake_parameters = staking_account_id.map(|staking_account_id| StakeParameters {
-            stake: self
-                .stake_policy
-                .clone()
-                .map(|policy| policy.stake_amount)
-                .unwrap_or_default(),
-            staking_account_id,
-        });
-
-        let mut applications = self.applications;
-        applications.push(HiringWorkflowApplication {
-            worker_handle,
-            origin,
-            member_id,
-            stake_parameters,
-        });
-
-        Self {
-            applications,
-            ..self
-        }
-    }
-
-    fn setup_environment(&self) {
-        if matches!(self.opening_type, JobOpeningType::Regular) {
-            HireLeadFixture::default().hire_lead();
-        } else {
-            setup_members(6);
-        }
-    }
-
-    pub fn execute(&self) -> Option<u64> {
-        if self.setup_environment {
-            self.setup_environment()
-        }
-
-        let result = self.fill_worker_position();
-
-        let check_result = result.clone().map(|_| ());
-
-        assert_eq!(check_result, self.expected_result);
-
-        result.ok()
-    }
-
-    fn fill_worker_position(&self) -> Result<u64, DispatchError> {
-        let origin = match self.opening_type {
-            JobOpeningType::Leader => RawOrigin::Root,
-            JobOpeningType::Regular => {
-                let leader_worker_id = TestWorkingTeam::current_lead().unwrap();
-                let leader = TestWorkingTeam::worker_by_id(leader_worker_id);
-                let lead_account_id = leader.role_account_id;
-
-                RawOrigin::Signed(lead_account_id)
-            }
-        };
-
-        // create the opening
-        let add_worker_opening_fixture = AddOpeningFixture::default()
-            .with_stake_policy(self.stake_policy.clone())
-            .with_reward_policy(self.reward_policy.clone())
-            .with_opening_type(self.opening_type)
-            .with_origin(origin.clone());
-
-        let opening_id = add_worker_opening_fixture.call()?;
-
-        // Fill applications.
-        let mut application_ids = Vec::new();
-        for application in self.applications.clone() {
-            let apply_on_worker_opening_fixture =
-                ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-                    .with_stake_parameters(application.stake_parameters)
-                    .with_text(application.worker_handle)
-                    .with_origin(application.origin, application.member_id);
-
-            let application_id = apply_on_worker_opening_fixture.call()?;
-            application_ids.push(application_id);
-        }
-
-        // fill opening
-        let fill_opening_fixture = FillOpeningFixture::default_for_ids(opening_id, application_ids)
-            .with_origin(origin.clone());
-
-        let worker_id = fill_opening_fixture.call()?;
-
-        Ok(worker_id)
-    }
-}

+ 0 - 2406
runtime-modules/working-team/src/tests/mod.rs

@@ -1,2406 +0,0 @@
-mod fixtures;
-mod hiring_workflow;
-mod mock;
-
-pub use mock::{build_test_externalities, Test};
-
-use frame_system::RawOrigin;
-
-use crate::tests::fixtures::{
-    CancelOpeningFixture, DecreaseWorkerStakeFixture, IncreaseWorkerStakeFixture, SetBudgetFixture,
-    SetStatusTextFixture, SlashWorkerStakeFixture, SpendFromBudgetFixture,
-    UpdateRewardAccountFixture, UpdateRewardAmountFixture, WithdrawApplicationFixture,
-};
-use crate::tests::hiring_workflow::HiringWorkflow;
-use crate::tests::mock::{
-    STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES, STAKING_ACCOUNT_ID_FOR_FAILED_VALIDITY_CHECK,
-    STAKING_ACCOUNT_ID_FOR_ZERO_STAKE,
-};
-use crate::types::StakeParameters;
-use crate::{
-    DefaultInstance, Error, JobOpeningType, Penalty, RawEvent, RewardPolicy, StakePolicy,
-    TeamWorker,
-};
-use fixtures::{
-    increase_total_balance_issuance_using_account_id, setup_members, AddOpeningFixture,
-    ApplyOnOpeningFixture, EventFixture, FillOpeningFixture, HireLeadFixture,
-    HireRegularWorkerFixture, LeaveWorkerRoleFixture, TerminateWorkerRoleFixture,
-    UpdateWorkerRoleAccountFixture,
-};
-use frame_support::dispatch::DispatchError;
-use frame_support::StorageMap;
-use mock::{run_to_block, Balances, RewardPeriod, TestWorkingTeam, ACTOR_ORIGIN_ERROR};
-use sp_runtime::traits::Hash;
-use sp_std::collections::btree_map::BTreeMap;
-
-#[test]
-fn add_opening_succeeded() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        let add_opening_fixture = AddOpeningFixture::default()
-            .with_starting_block(starting_block)
-            .with_stake_policy(Some(StakePolicy {
-                stake_amount: 10,
-                leaving_unstaking_period: 100,
-            }))
-            .with_reward_policy(Some(RewardPolicy {
-                reward_per_block: 10,
-            }));
-
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::OpeningAdded(opening_id));
-    });
-}
-
-#[test]
-fn add_opening_fails_with_bad_origin() {
-    build_test_externalities().execute_with(|| {
-        let add_opening_fixture = AddOpeningFixture::default()
-            .with_opening_type(JobOpeningType::Leader)
-            .with_origin(RawOrigin::None);
-
-        add_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn add_opening_fails_with_zero_stake() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: 0,
-                leaving_unstaking_period: 0,
-            }));
-
-        add_opening_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::CannotStakeZero.into()));
-    });
-}
-
-#[test]
-fn add_opening_fails_with_zero_reward() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_reward_policy(Some(RewardPolicy {
-                reward_per_block: 0,
-            }));
-
-        add_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::CannotRewardWithZero.into(),
-        ));
-    });
-}
-
-#[test]
-fn add_opening_fails_with_incorrect_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let invalid_unstaking_period = 3;
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: invalid_unstaking_period,
-            }));
-
-        add_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::UnstakingPeriodLessThanMinimum.into(),
-        ));
-    });
-}
-
-#[test]
-fn add_leader_opening_fails_with_incorrect_origin_for_opening_type() {
-    build_test_externalities().execute_with(|| {
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_opening_type(JobOpeningType::Leader);
-
-        add_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn apply_on_opening_succeeded() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        let add_opening_fixture = AddOpeningFixture::default().with_starting_block(starting_block);
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
-
-        let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::AppliedOnOpening(
-            opening_id,
-            application_id,
-        ));
-    });
-}
-
-#[test]
-fn apply_on_opening_fails_with_invalid_opening_id() {
-    build_test_externalities().execute_with(|| {
-        setup_members(2);
-
-        let invalid_opening_id = 22;
-
-        let apply_on_opening_fixture =
-            ApplyOnOpeningFixture::default_for_opening_id(invalid_opening_id);
-
-        apply_on_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::OpeningDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn apply_on_opening_fails_with_bad_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let member_id = 11;
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_origin(RawOrigin::None, member_id);
-
-        apply_on_opening_fixture.call_and_assert(Err(DispatchError::Other("Bad origin")));
-    });
-}
-
-#[test]
-fn apply_on_opening_fails_with_bad_member_id() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let member_id = 27;
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_origin(RawOrigin::Signed(1), member_id);
-
-        apply_on_opening_fixture
-            .call_and_assert(Err(DispatchError::Other(ACTOR_ORIGIN_ERROR).into()));
-    });
-}
-
-#[test]
-fn fill_opening_succeeded() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        let reward_policy = Some(RewardPolicy {
-            reward_per_block: 10,
-        });
-
-        let add_opening_fixture = AddOpeningFixture::default()
-            .with_starting_block(starting_block)
-            .with_reward_policy(reward_policy.clone());
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
-
-        let application_id = apply_on_opening_fixture.call().unwrap();
-
-        let fill_opening_fixture =
-            FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
-                .with_reward_policy(reward_policy)
-                .with_created_at(starting_block);
-
-        let worker_id = fill_opening_fixture.call_and_assert(Ok(()));
-
-        let mut result_map = BTreeMap::new();
-        result_map.insert(application_id, worker_id);
-
-        EventFixture::assert_last_crate_event(RawEvent::OpeningFilled(opening_id, result_map));
-    });
-}
-
-#[test]
-fn fill_opening_succeeded_with_stake() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: account_id,
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-        let add_opening_fixture = AddOpeningFixture::default()
-            .with_starting_block(starting_block)
-            .with_stake_policy(stake_policy.clone());
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        let application_id = apply_on_opening_fixture.call().unwrap();
-
-        let fill_opening_fixture =
-            FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
-                .with_stake_policy(stake_policy)
-                .with_staking_account_id(Some(account_id))
-                .with_created_at(starting_block);
-
-        let worker_id = fill_opening_fixture.call_and_assert(Ok(()));
-
-        let mut result_map = BTreeMap::new();
-        result_map.insert(application_id, worker_id);
-
-        EventFixture::assert_last_crate_event(RawEvent::OpeningFilled(opening_id, result_map));
-    });
-}
-
-#[test]
-fn fill_opening_fails_with_bad_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
-
-        let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        let fill_opening_fixture =
-            FillOpeningFixture::default_for_ids(opening_id, vec![application_id])
-                .with_origin(RawOrigin::None);
-
-        fill_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn fill_opening_fails_with_invalid_active_worker_number() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let application_id1 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .call()
-            .unwrap();
-        let application_id2 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_origin(RawOrigin::Signed(2), 2)
-            .call()
-            .unwrap();
-        let application_id3 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_origin(RawOrigin::Signed(3), 3)
-            .call()
-            .unwrap();
-        let application_id4 = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_origin(RawOrigin::Signed(4), 4)
-            .call()
-            .unwrap();
-
-        let fill_opening_fixture = FillOpeningFixture::default_for_ids(
-            opening_id,
-            vec![
-                application_id1,
-                application_id2,
-                application_id3,
-                application_id4,
-            ],
-        );
-
-        fill_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::MaxActiveWorkerNumberExceeded.into(),
-        ));
-    });
-}
-
-#[test]
-fn fill_opening_fails_with_invalid_application_id() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let invalid_application_id = 1;
-
-        let fill_opening_fixture =
-            FillOpeningFixture::default_for_ids(opening_id, vec![invalid_application_id]);
-
-        fill_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::SuccessfulWorkerApplicationDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn fill_opening_fails_with_zero_application_ids() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let fill_opening_fixture = FillOpeningFixture::default_for_ids(opening_id, Vec::new());
-
-        fill_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::NoApplicationsProvided.into(),
-        ));
-    });
-}
-
-#[test]
-fn cannot_hire_a_lead_twice() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-        HireLeadFixture::default()
-            .with_setup_environment(false)
-            .expect(Error::<Test, DefaultInstance>::CannotHireLeaderWhenLeaderExists.into());
-    });
-}
-
-#[test]
-fn cannot_hire_muptiple_leaders() {
-    build_test_externalities().execute_with(|| {
-        HiringWorkflow::default()
-            .with_setup_environment(true)
-            .with_opening_type(JobOpeningType::Leader)
-            .add_default_application()
-            .add_application_full(b"leader2".to_vec(), RawOrigin::Signed(2), 2, Some(2))
-            .expect(Err(
-                Error::<Test, DefaultInstance>::CannotHireMultipleLeaders.into(),
-            ))
-            .execute();
-    });
-}
-
-#[test]
-fn update_worker_role_account_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let new_account_id = 10;
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let update_worker_account_fixture =
-            UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
-
-        update_worker_account_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::WorkerRoleAccountUpdated(
-            worker_id,
-            new_account_id,
-        ));
-    });
-}
-
-#[test]
-fn update_worker_role_account_by_leader_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let new_account_id = 10;
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        let old_lead = TestWorkingTeam::worker_by_id(worker_id);
-
-        let update_worker_account_fixture =
-            UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
-
-        update_worker_account_fixture.call_and_assert(Ok(()));
-
-        let new_lead = TestWorkingTeam::worker_by_id(worker_id);
-
-        assert_eq!(
-            new_lead,
-            TeamWorker::<Test> {
-                role_account_id: new_account_id,
-                ..old_lead
-            }
-        );
-    });
-}
-
-#[test]
-fn update_worker_role_fails_with_leaving_worker() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let leaving_unstaking_period = 10;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        let new_account_id = 10;
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        let update_worker_account_fixture =
-            UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, new_account_id);
-
-        update_worker_account_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
-    });
-}
-
-#[test]
-fn update_worker_role_account_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let update_worker_account_fixture =
-            UpdateWorkerRoleAccountFixture::default_with_ids(worker_id, 1)
-                .with_origin(RawOrigin::None);
-
-        update_worker_account_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::InvalidMemberOrigin.into(),
-        ));
-    });
-}
-
-#[test]
-fn leave_worker_role_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::WorkerExited(worker_id));
-    });
-}
-
-#[test]
-fn leave_worker_role_succeeds_with_paying_missed_reward() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-        let block_number = 4;
-
-        run_to_block(block_number);
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        SetBudgetFixture::default().with_budget(1000000).execute();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(
-            Balances::usable_balance(&account_id),
-            block_number * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn leave_worker_role_succeeds_with_partial_payment_of_missed_reward() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-        let block_number = 4;
-
-        run_to_block(block_number);
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        let budget = 30;
-        SetBudgetFixture::default().with_budget(budget).execute();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(Balances::usable_balance(&account_id), budget);
-    });
-}
-
-#[test]
-fn leave_worker_role_by_leader_succeeds() {
-    build_test_externalities().execute_with(|| {
-        // Ensure that lead is default
-        assert_eq!(TestWorkingTeam::current_lead(), None);
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        assert!(TestWorkingTeam::current_lead().is_some());
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(TestWorkingTeam::current_lead(), None);
-    });
-}
-
-#[test]
-fn leave_worker_role_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        let leave_worker_role_fixture =
-            LeaveWorkerRoleFixture::default_for_worker_id(1).with_origin(RawOrigin::None);
-
-        leave_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn leave_worker_role_fails_with_invalid_origin_signed_account() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::Signed(2));
-
-        leave_worker_role_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn leave_worker_role_fails_already_leaving_worker() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-        leave_worker_role_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
-    });
-}
-
-#[test]
-fn leave_worker_role_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        let invalid_worker_id = 10;
-        HireRegularWorkerFixture::default().hire();
-
-        let leave_worker_role_fixture =
-            LeaveWorkerRoleFixture::default_for_worker_id(invalid_worker_id);
-
-        leave_worker_role_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn terminate_worker_role_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        terminate_worker_role_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::TerminatedWorker(worker_id));
-    });
-}
-
-#[test]
-fn terminate_worker_role_succeeds_with_paying_missed_reward() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-        let block_number = 4;
-
-        run_to_block(block_number);
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        SetBudgetFixture::default().with_budget(1000000).execute();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        terminate_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(
-            Balances::usable_balance(&account_id),
-            block_number * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn terminate_leader_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
-                .with_origin(RawOrigin::Root);
-
-        terminate_worker_role_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::TerminatedLeader(worker_id));
-
-        assert_eq!(TestWorkingTeam::current_lead(), None);
-    });
-}
-
-#[test]
-fn terminate_worker_role_fails_with_unset_lead() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        // Remove the leader from the storage.
-        TestWorkingTeam::unset_lead();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        terminate_worker_role_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
-    });
-}
-
-#[test]
-fn terminate_worker_role_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let worker_id = HiringWorkflow::default()
-            .with_setup_environment(false)
-            .add_application_full(b"worker_handle".to_vec(), RawOrigin::Signed(2), 2, Some(2))
-            .execute()
-            .unwrap();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
-                .with_origin(RawOrigin::None);
-
-        terminate_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn terminate_leader_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
-                .with_origin(RawOrigin::None);
-
-        terminate_worker_role_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn unset_lead_event_emitted() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        HireRegularWorkerFixture::default().hire();
-
-        // Remove the leader from the storage.
-        TestWorkingTeam::unset_lead();
-
-        EventFixture::assert_last_crate_event(RawEvent::LeaderUnset());
-    });
-}
-
-#[test]
-fn set_lead_event_emitted() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let worker_id = 10;
-
-        // Add the leader to the storage.
-        TestWorkingTeam::set_lead(worker_id);
-
-        EventFixture::assert_last_crate_event(RawEvent::LeaderSet(worker_id));
-    });
-}
-
-#[test]
-fn apply_on_opening_fails_with_stake_inconsistent_with_opening_stake() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        increase_total_balance_issuance_using_account_id(account_id, 300);
-
-        let stake_parameters = StakeParameters {
-            stake: 100,
-            staking_account_id: account_id,
-        };
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: 200,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        apply_on_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::ApplicationStakeDoesntMatchOpening.into(),
-        ));
-    });
-}
-
-#[test]
-fn apply_on_opening_locks_the_stake() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: account_id,
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance);
-
-        apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-    });
-}
-
-#[test]
-fn apply_on_opening_fails_stake_amount_check() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        let total_balance = 100;
-        let stake = 200;
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: account_id,
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        apply_on_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),
-        ));
-    });
-}
-
-#[ignore] // unlock after implementing members staking accounts
-#[test]
-fn apply_on_opening_fails_invalid_staking_check() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-        increase_total_balance_issuance_using_account_id(
-            STAKING_ACCOUNT_ID_FOR_FAILED_VALIDITY_CHECK,
-            total_balance,
-        );
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: STAKING_ACCOUNT_ID_FOR_FAILED_VALIDITY_CHECK,
-        };
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        apply_on_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::InvalidStakingAccountForMember.into(),
-        ));
-    });
-}
-
-#[ignore] // unlock after implementing conflicting stake
-#[test]
-fn apply_on_opening_fails_with_conflicting_stakes() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES,
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-        increase_total_balance_issuance_using_account_id(
-            STAKING_ACCOUNT_ID_FOR_CONFLICTING_STAKES,
-            total_balance,
-        );
-
-        let add_opening_fixture =
-            AddOpeningFixture::default().with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call().unwrap();
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-
-        apply_on_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::ConflictStakesOnAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn terminate_worker_unlocks_the_stake() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id);
-
-        terminate_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance);
-    });
-}
-
-#[test]
-fn leave_worker_unlocks_the_stake() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let leaving_unstaking_period = 10;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        run_to_block(leaving_unstaking_period);
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance);
-    });
-}
-
-#[test]
-fn leave_worker_unlocks_the_stake_with_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let leaving_unstaking_period = 10;
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        run_to_block(leaving_unstaking_period);
-
-        assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
-            worker_id
-        ));
-        assert_eq!(Balances::usable_balance(&account_id), total_balance);
-
-        EventFixture::assert_last_crate_event(RawEvent::WorkerExited(worker_id));
-    });
-}
-
-#[test]
-fn leave_worker_works_immediately_stake_is_zero() {
-    build_test_externalities().execute_with(|| {
-        let account_id = STAKING_ACCOUNT_ID_FOR_ZERO_STAKE;
-        let total_balance = 300;
-        let stake = 200;
-
-        let leaving_unstaking_period = 10;
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HiringWorkflow::default()
-            .with_setup_environment(true)
-            .with_opening_type(JobOpeningType::Regular)
-            //    .with_stake_policy(stake_policy.clone())
-            .add_application_full(b"worker".to_vec(), RawOrigin::Signed(1), 1, None)
-            .execute()
-            .unwrap();
-
-        //        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
-            worker_id
-        ));
-    });
-}
-
-#[test]
-fn terminate_worker_with_slashing_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let penalty = Penalty {
-            slashing_amount: stake,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
-                .with_penalty(Some(penalty));
-
-        terminate_worker_role_fixture.call_and_assert(Ok(()));
-
-        assert_eq!(Balances::usable_balance(&account_id), total_balance - stake);
-    });
-}
-
-#[test]
-fn terminate_worker_with_slashing_fails_with_no_staking_account() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let penalty = Penalty {
-            slashing_amount: stake,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HiringWorkflow::default()
-            .add_application_full(b"worker".to_vec(), RawOrigin::Signed(1), 1, None)
-            .execute()
-            .unwrap();
-
-        let terminate_worker_role_fixture =
-            TerminateWorkerRoleFixture::default_for_worker_id(worker_id)
-                .with_penalty(Some(penalty));
-
-        terminate_worker_role_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::CannotChangeStakeWithoutStakingAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn slash_worker_stake_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-          Events are not emitted on block 0.
-          So any dispatchable calls made during genesis block formation will have no events emitted.
-          https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let slash_stake = 100;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let penalty = Penalty {
-            slashing_amount: slash_stake,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let slash_stake_fixture =
-            SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_penalty(penalty);
-
-        slash_stake_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::StakeSlashed(worker_id, slash_stake));
-    });
-}
-
-#[test]
-fn slash_worker_stake_fails_with_no_staking_account() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let slash_stake = 100;
-
-        let penalty = Penalty {
-            slashing_amount: slash_stake,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HiringWorkflow::default()
-            .add_application_full(b"worker".to_vec(), RawOrigin::Signed(1), 1, None)
-            .execute()
-            .unwrap();
-
-        let slash_stake_fixture =
-            SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_penalty(penalty);
-
-        slash_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::CannotChangeStakeWithoutStakingAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn slash_leader_stake_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let penalty = Penalty {
-            slashing_amount: stake,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-        let leader_worker_id = HireLeadFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire_lead();
-
-        let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(leader_worker_id)
-            .with_penalty(penalty)
-            .with_origin(RawOrigin::Root);
-
-        slash_stake_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::StakeSlashed(leader_worker_id, stake));
-    });
-}
-
-#[test]
-fn slash_worker_stake_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let invalid_worker_id = 22;
-        let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id)
-            .with_origin(RawOrigin::None);
-
-        slash_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn slash_leader_stake_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        let slash_stake_fixture =
-            SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_origin(RawOrigin::None);
-
-        slash_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn slash_worker_stake_fails_with_zero_balance() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        let penalty = Penalty {
-            slashing_amount: 0,
-            slashing_text: Vec::new(),
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let slash_stake_fixture =
-            SlashWorkerStakeFixture::default_for_worker_id(worker_id).with_penalty(penalty);
-
-        slash_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
-        ));
-    });
-}
-
-#[test]
-fn slash_worker_stake_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-        let invalid_worker_id = 11;
-
-        let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
-
-        slash_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn slash_worker_stake_fails_with_not_set_lead() {
-    build_test_externalities().execute_with(|| {
-        let invalid_worker_id = 11;
-
-        let slash_stake_fixture = SlashWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
-
-        slash_stake_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let new_stake_balance = 100;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(new_stake_balance);
-
-        decrease_stake_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::StakeDecreased(
-            worker_id,
-            new_stake_balance,
-        ));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_no_staking_account() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let new_stake_balance = 100;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HiringWorkflow::default()
-            .add_application_full(b"worker".to_vec(), RawOrigin::Signed(1), 1, None)
-            .execute()
-            .unwrap();
-
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(new_stake_balance);
-
-        decrease_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::CannotChangeStakeWithoutStakingAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_succeeds_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireLeadFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire_lead();
-
-        let new_stake = 100;
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::Root)
-            .with_balance(new_stake);
-
-        decrease_stake_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let worker_id = 22; // random worker id
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::None);
-
-        decrease_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_invalid_origin_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireLeadFixture::default().hire_lead();
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::None);
-
-        decrease_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_zero_balance() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let decrease_stake_fixture =
-            DecreaseWorkerStakeFixture::default_for_worker_id(worker_id).with_balance(0);
-
-        decrease_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
-        ));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-        let invalid_worker_id = 11;
-
-        let decrease_stake_fixture =
-            DecreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
-
-        decrease_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_not_set_lead() {
-    build_test_externalities().execute_with(|| {
-        let invalid_worker_id = 11;
-
-        let decrease_stake_fixture =
-            DecreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
-
-        decrease_stake_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::CurrentLeadNotSet.into()));
-    });
-}
-
-#[test]
-fn increase_worker_stake_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let stake_balance_delta = 100;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(stake_balance_delta);
-
-        increase_stake_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::StakeIncreased(
-            worker_id,
-            stake_balance_delta,
-        ));
-    });
-}
-
-#[test]
-fn increase_worker_stake_succeeds_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 400;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireLeadFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire_lead();
-
-        let increase_stake_fixture =
-            IncreaseWorkerStakeFixture::default_for_worker_id(worker_id).with_balance(stake);
-
-        increase_stake_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let worker_id = 0;
-        let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::None);
-
-        increase_stake_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_with_zero_balance() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let increase_stake_fixture =
-            IncreaseWorkerStakeFixture::default_for_worker_id(worker_id).with_balance(0);
-
-        increase_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::StakeBalanceCannotBeZero.into(),
-        ));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_with_no_staking_account() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HiringWorkflow::default()
-            .add_application_full(b"worker".to_vec(), RawOrigin::Signed(1), 1, None)
-            .execute()
-            .unwrap();
-
-        let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id);
-
-        increase_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::CannotChangeStakeWithoutStakingAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let invalid_worker_id = 11;
-
-        let increase_stake_fixture =
-            IncreaseWorkerStakeFixture::default_for_worker_id(invalid_worker_id);
-
-        increase_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_external_check() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy)
-            .hire();
-
-        let invalid_new_stake = 2000;
-        let decrease_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(invalid_new_stake);
-
-        decrease_stake_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::InsufficientBalanceToCoverStake.into(),
-        ));
-    });
-}
-
-#[test]
-fn withdraw_application_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-
-        let stake_parameters = StakeParameters {
-            stake,
-            staking_account_id: account_id,
-        };
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default()
-            .with_starting_block(starting_block)
-            .with_stake_policy(Some(StakePolicy {
-                stake_amount: stake,
-                leaving_unstaking_period: 10,
-            }));
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id)
-            .with_stake_parameters(Some(stake_parameters));
-        let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        let withdraw_application_fixture =
-            WithdrawApplicationFixture::default_for_application_id(application_id).with_stake();
-        withdraw_application_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::ApplicationWithdrawn(application_id));
-    });
-}
-
-#[test]
-fn withdraw_application_fails_invalid_application_id() {
-    build_test_externalities().execute_with(|| {
-        let invalid_application_id = 6;
-
-        let withdraw_application_fixture =
-            WithdrawApplicationFixture::default_for_application_id(invalid_application_id);
-        withdraw_application_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerApplicationDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn withdraw_application_fails_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
-        let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        let withdraw_application_fixture =
-            WithdrawApplicationFixture::default_for_application_id(application_id)
-                .with_origin(RawOrigin::None);
-        withdraw_application_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn withdraw_worker_application_fails_with_invalid_application_author() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let apply_on_opening_fixture = ApplyOnOpeningFixture::default_for_opening_id(opening_id);
-        let application_id = apply_on_opening_fixture.call_and_assert(Ok(()));
-
-        let invalid_author_account_id = 55;
-        let withdraw_application_fixture =
-            WithdrawApplicationFixture::default_for_application_id(application_id)
-                .with_signer(invalid_author_account_id);
-        withdraw_application_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::OriginIsNotApplicant.into(),
-        ));
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        let starting_block = 1;
-        run_to_block(starting_block);
-
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default().with_starting_block(starting_block);
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening_id(opening_id);
-        cancel_opening_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::OpeningCanceled(opening_id));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let add_opening_fixture = AddOpeningFixture::default();
-        let opening_id = add_opening_fixture.call_and_assert(Ok(()));
-
-        let cancel_opening_fixture =
-            CancelOpeningFixture::default_for_opening_id(opening_id).with_origin(RawOrigin::None);
-        cancel_opening_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_invalid_opening_id() {
-    build_test_externalities().execute_with(|| {
-        let invalid_opening_id = 11;
-
-        let cancel_opening_fixture =
-            CancelOpeningFixture::default_for_opening_id(invalid_opening_id);
-
-        cancel_opening_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::OpeningDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn decrease_worker_stake_fails_with_leaving_worker() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let new_stake_balance = 100;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        let decrease_stake_fixture = DecreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(new_stake_balance);
-
-        decrease_stake_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
-    });
-}
-
-#[test]
-fn increase_worker_stake_fails_with_leaving_worker() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 1;
-        let total_balance = 300;
-        let stake = 200;
-        let new_stake_balance = 100;
-
-        let stake_policy = Some(StakePolicy {
-            stake_amount: stake,
-            leaving_unstaking_period: 10,
-        });
-
-        increase_total_balance_issuance_using_account_id(account_id, total_balance);
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_stake_policy(stake_policy.clone())
-            .hire();
-
-        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id)
-            .with_stake_policy(stake_policy);
-
-        leave_worker_role_fixture.call_and_assert(Ok(()));
-
-        let increase_stake_fixture = IncreaseWorkerStakeFixture::default_for_worker_id(worker_id)
-            .with_balance(new_stake_balance);
-
-        increase_stake_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerIsLeaving.into()));
-    });
-}
-
-#[test]
-fn rewards_payments_are_successful() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        let account_id = worker.role_account_id;
-
-        SetBudgetFixture::default().execute();
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        let block_number = 10;
-        run_to_block(block_number);
-
-        assert_eq!(
-            Balances::usable_balance(&account_id),
-            block_number * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn rewards_payments_with_no_budget() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        let account_id = worker.role_account_id;
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        let block_number = 10;
-        run_to_block(block_number);
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        assert_eq!(
-            worker.missed_reward.unwrap(),
-            block_number * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn rewards_payments_with_insufficient_budget_and_restored_budget() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        let account_id = worker.reward_account_id;
-
-        assert_eq!(Balances::usable_balance(&account_id), 0);
-
-        let paid_blocks = 3;
-
-        let first_budget = paid_blocks * reward_per_block;
-        SetBudgetFixture::default()
-            .with_budget(first_budget)
-            .execute();
-
-        let block_number = 10;
-        run_to_block(block_number);
-
-        assert_eq!(Balances::usable_balance(&account_id), first_budget);
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        let effective_missed_reward: u64 = block_number * reward_per_block - first_budget;
-
-        assert_eq!(worker.missed_reward.unwrap(), effective_missed_reward);
-
-        SetBudgetFixture::default().with_budget(1000000).execute();
-
-        // Checkpoint with restored budget.
-        let block_number2 = 20;
-        run_to_block(block_number2);
-
-        assert_eq!(
-            Balances::usable_balance(&account_id),
-            block_number2 * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn rewards_payments_with_starting_block() {
-    build_test_externalities().execute_with(|| {
-        let starting_block = 3;
-        run_to_block(starting_block);
-
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-        let reward_period: u64 = RewardPeriod::get().into();
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let worker = TestWorkingTeam::worker_by_id(worker_id);
-
-        let account_id = worker.reward_account_id;
-
-        SetBudgetFixture::default().with_budget(100000).execute();
-
-        let block_number = 11;
-        run_to_block(block_number);
-
-        let effective_paid_blocks =
-            (block_number - starting_block) - (block_number % reward_period);
-        assert_eq!(
-            Balances::usable_balance(&account_id),
-            effective_paid_blocks * reward_per_block
-        );
-    });
-}
-
-#[test]
-fn set_budget_succeeded() {
-    build_test_externalities().execute_with(|| {
-        run_to_block(1);
-
-        let new_budget = 10000;
-        SetBudgetFixture::default()
-            .with_budget(new_budget)
-            .call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::BudgetSet(new_budget));
-    });
-}
-
-#[test]
-fn set_budget_fails_with_bad_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-        let leader_account_id = 1;
-
-        SetBudgetFixture::default()
-            .with_origin(RawOrigin::Signed(leader_account_id))
-            .call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn update_reward_account_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let new_reward_account = 22;
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account);
-
-        update_account_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::WorkerRewardAccountUpdated(
-            worker_id,
-            new_reward_account,
-        ));
-    });
-}
-
-#[test]
-fn update_reward_account_succeeds_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireLeadFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire_lead();
-
-        let new_reward_account = 22;
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account);
-
-        update_account_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn update_reward_account_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(1, 1).with_origin(RawOrigin::None);
-
-        update_account_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn update_reward_account_fails_with_invalid_origin_signed_account() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        let worker_id = HireLeadFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire_lead();
-
-        let invalid_role_account = 23333;
-        let new_reward_account = 22;
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account)
-                .with_origin(RawOrigin::Signed(invalid_role_account));
-
-        update_account_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::SignerIsNotWorkerRoleAccount.into(),
-        ));
-    });
-}
-
-#[test]
-fn update_reward_account_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        let reward_per_block = 10;
-        let reward_policy = Some(RewardPolicy { reward_per_block });
-
-        HireRegularWorkerFixture::default()
-            .with_reward_policy(reward_policy)
-            .hire();
-
-        let invalid_worker_id = 11;
-        let new_reward_account = 2;
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(invalid_worker_id, new_reward_account);
-
-        update_account_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn update_reward_account_fails_with_no_recurring_reward() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let new_reward_account = 343;
-
-        let update_account_fixture =
-            UpdateRewardAccountFixture::default_with_ids(worker_id, new_reward_account);
-
-        update_account_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::WorkerHasNoReward.into()));
-    });
-}
-
-#[test]
-fn update_reward_amount_succeeds() {
-    build_test_externalities().execute_with(|| {
-        /*
-           Events are not emitted on block 0.
-           So any dispatchable calls made during genesis block formation will have no events emitted.
-           https://substrate.dev/recipes/2-appetizers/4-events.html
-        */
-        run_to_block(1);
-
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let reward_per_block = Some(120);
-
-        let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
-            .with_reward_per_block(reward_per_block);
-
-        update_amount_fixture.call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::WorkerRewardAmountUpdated(
-            worker_id,
-            reward_per_block,
-        ));
-    });
-}
-
-#[test]
-fn update_reward_amount_succeeds_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireLeadFixture::default()
-            .with_reward_policy(Some(RewardPolicy {
-                reward_per_block: 1000,
-            }))
-            .hire_lead();
-
-        let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::Root);
-
-        update_amount_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn update_reward_amount_fails_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        let worker_id = 22; // random worker id
-
-        let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::None);
-
-        update_amount_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn update_reward_amount_fails_with_invalid_origin_for_leader() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireLeadFixture::default().hire_lead();
-
-        let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::None);
-
-        update_amount_fixture.call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn update_reward_amount_fails_with_invalid_origin_signed_account() {
-    build_test_externalities().execute_with(|| {
-        let worker_id = HireRegularWorkerFixture::default().hire();
-
-        let update_amount_fixture = UpdateRewardAmountFixture::default_for_worker_id(worker_id)
-            .with_origin(RawOrigin::Signed(2));
-
-        update_amount_fixture
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::IsNotLeadAccount.into()));
-    });
-}
-
-#[test]
-fn update_reward_amount_fails_with_invalid_worker_id() {
-    build_test_externalities().execute_with(|| {
-        HireRegularWorkerFixture::default().hire();
-
-        let invalid_worker_id = 12;
-        let update_amount_fixture =
-            UpdateRewardAmountFixture::default_for_worker_id(invalid_worker_id);
-
-        update_amount_fixture.call_and_assert(Err(
-            Error::<Test, DefaultInstance>::WorkerDoesNotExist.into(),
-        ));
-    });
-}
-
-#[test]
-fn set_status_text_succeeded() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-
-        run_to_block(1);
-
-        let status_text = b"some".to_vec();
-        SetStatusTextFixture::default()
-            .with_status_text(Some(status_text.clone()))
-            .call_and_assert(Ok(()));
-
-        let expected_hash = <Test as frame_system::Trait>::Hashing::hash(&status_text);
-        EventFixture::assert_last_crate_event(RawEvent::StatusTextChanged(
-            expected_hash.as_ref().to_vec(),
-        ));
-    });
-}
-
-#[test]
-fn set_status_text_fails_with_bad_origin() {
-    build_test_externalities().execute_with(|| {
-        HireLeadFixture::default().hire_lead();
-        let leader_account_id = 10;
-
-        SetStatusTextFixture::default()
-            .with_origin(RawOrigin::Signed(leader_account_id))
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::IsNotLeadAccount.into()));
-    });
-}
-
-#[test]
-fn spend_from_budget_succeeded() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 2;
-        let amount = 100;
-        HireLeadFixture::default().hire_lead();
-
-        run_to_block(1);
-
-        let set_budget_fixture = SetBudgetFixture::default().with_budget(1000);
-        assert_eq!(set_budget_fixture.call(), Ok(()));
-
-        SpendFromBudgetFixture::default()
-            .with_account_id(account_id)
-            .with_amount(amount)
-            .call_and_assert(Ok(()));
-
-        EventFixture::assert_last_crate_event(RawEvent::BudgetSpending(account_id, amount));
-    });
-}
-
-#[test]
-fn spend_from_budget_failed_with_invalid_origin() {
-    build_test_externalities().execute_with(|| {
-        SpendFromBudgetFixture::default()
-            .with_origin(RawOrigin::None.into())
-            .call_and_assert(Err(DispatchError::BadOrigin));
-    });
-}
-
-#[test]
-fn spend_from_budget_fails_with_empty_budget() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 2;
-        let amount = 100;
-        HireLeadFixture::default().hire_lead();
-
-        SpendFromBudgetFixture::default()
-            .with_account_id(account_id)
-            .with_amount(amount)
-            .call_and_assert(Err(
-                Error::<Test, DefaultInstance>::InsufficientBudgetForSpending.into(),
-            ));
-    });
-}
-
-#[test]
-fn spend_from_budget_fails_with_zero_amount() {
-    build_test_externalities().execute_with(|| {
-        let account_id = 2;
-        let amount = 0;
-        HireLeadFixture::default().hire_lead();
-
-        SpendFromBudgetFixture::default()
-            .with_account_id(account_id)
-            .with_amount(amount)
-            .call_and_assert(Err(Error::<Test, DefaultInstance>::CannotSpendZero.into()));
-    });
-}

+ 0 - 263
runtime-modules/working-team/src/types.rs

@@ -1,263 +0,0 @@
-#![warn(missing_docs)]
-
-use codec::{Decode, Encode};
-use sp_std::vec::Vec;
-
-#[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
-
-/// Team job application type alias.
-pub type JobApplication<T> = Application<<T as frame_system::Trait>::AccountId, MemberId<T>>;
-
-/// Member identifier in membership::member module.
-pub type MemberId<T> = <T as membership::Trait>::MemberId;
-
-/// Type identifier for a worker role, which must be same as membership actor identifier.
-pub type TeamWorkerId<T> = <T as membership::Trait>::ActorId;
-
-// ApplicationId - JobApplication - helper struct.
-pub(crate) struct ApplicationInfo<T: crate::Trait<I>, I: crate::Instance> {
-    pub application_id: T::ApplicationId,
-    pub application: JobApplication<T>,
-}
-
-// WorkerId - TeamWorker - helper struct.
-pub(crate) struct WorkerInfo<T: membership::Trait + frame_system::Trait + balances::Trait> {
-    pub worker_id: TeamWorkerId<T>,
-    pub worker: TeamWorker<T>,
-}
-
-impl<T: membership::Trait + frame_system::Trait + balances::Trait>
-    From<(TeamWorkerId<T>, TeamWorker<T>)> for WorkerInfo<T>
-{
-    fn from((worker_id, worker): (TeamWorkerId<T>, TeamWorker<T>)) -> Self {
-        WorkerInfo { worker_id, worker }
-    }
-}
-
-/// Team worker type alias.
-pub type TeamWorker<T> = Worker<
-    <T as frame_system::Trait>::AccountId,
-    MemberId<T>,
-    <T as frame_system::Trait>::BlockNumber,
-    BalanceOf<T>,
->;
-
-/// Balance alias for `balances` module.
-pub type BalanceOf<T> = <T as balances::Trait>::Balance;
-
-/// Job opening for the normal or leader position.
-/// An opening represents the process of hiring one or more new actors into some available role.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, Eq)]
-pub struct JobOpening<BlockNumber: Ord, Balance> {
-    /// Defines opening type: Leader or worker.
-    pub opening_type: JobOpeningType,
-
-    /// Block at which opening was added.
-    pub created: BlockNumber,
-
-    /// Hash of the opening description.
-    pub description_hash: Vec<u8>,
-
-    /// Stake policy for the job opening.
-    pub stake_policy: Option<StakePolicy<BlockNumber, Balance>>,
-
-    /// Reward policy for the job opening.
-    pub reward_policy: Option<RewardPolicy<Balance>>,
-}
-
-/// Defines type of the opening: regular working group fellow or group leader.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq, Copy)]
-pub enum JobOpeningType {
-    /// Group leader.
-    Leader,
-
-    /// Regular worker.
-    Regular,
-}
-
-/// 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 JobOpeningType {
-    fn default() -> Self {
-        Self::Regular
-    }
-}
-
-/// An application for the regular worker/lead role opening.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct Application<AccountId, MemberId> {
-    /// Account used to authenticate in this role.
-    pub role_account_id: AccountId,
-
-    /// Reward account id.
-    pub reward_account_id: AccountId,
-
-    /// Account used to stake in this role.
-    pub staking_account_id: Option<AccountId>,
-
-    /// Member applying.
-    pub member_id: MemberId,
-
-    /// Hash of the application description.
-    pub description_hash: Vec<u8>,
-}
-
-impl<AccountId: Clone, MemberId: Clone> Application<AccountId, MemberId> {
-    /// Creates a new job application using parameters.
-    pub fn new(
-        role_account_id: &AccountId,
-        reward_account_id: &AccountId,
-        staking_account_id: &Option<AccountId>,
-        member_id: &MemberId,
-        description_hash: Vec<u8>,
-    ) -> Self {
-        Application {
-            role_account_id: role_account_id.clone(),
-            reward_account_id: reward_account_id.clone(),
-            staking_account_id: staking_account_id.clone(),
-            member_id: member_id.clone(),
-            description_hash,
-        }
-    }
-}
-
-/// Working team participant: regular worker or lead.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-pub struct Worker<AccountId, MemberId, BlockNumber, Balance> {
-    /// Member id related to the worker/lead.
-    pub member_id: MemberId,
-
-    /// Account used to authenticate in this role.
-    pub role_account_id: AccountId,
-
-    /// Account used to stake in this role.
-    pub staking_account_id: Option<AccountId>,
-
-    /// Reward account id.
-    pub reward_account_id: AccountId,
-
-    /// Specifies the block when the worker chose to leave.
-    pub started_leaving_at: Option<BlockNumber>,
-
-    /// Unstaking period when the worker chooses to leave the role.
-    /// It is defined by the job opening.
-    pub job_unstaking_period: BlockNumber,
-
-    /// Optional reward setting for the worker.
-    pub reward_per_block: Option<Balance>,
-
-    /// Total missed reward amount.
-    pub missed_reward: Option<Balance>,
-
-    /// Specifies the block when the worker was created.
-    pub created_at: BlockNumber,
-}
-
-impl<AccountId: Clone, MemberId: Clone, BlockNumber, Balance>
-    Worker<AccountId, MemberId, BlockNumber, Balance>
-{
-    /// Creates a new _TeamWorker_ using parameters.
-    pub fn new(
-        member_id: &MemberId,
-        role_account_id: &AccountId,
-        reward_account_id: &AccountId,
-        staking_account_id: &Option<AccountId>,
-        job_unstaking_period: BlockNumber,
-        reward_per_block: Option<Balance>,
-        created_at: BlockNumber,
-    ) -> Self {
-        Worker {
-            member_id: member_id.clone(),
-            role_account_id: role_account_id.clone(),
-            reward_account_id: reward_account_id.clone(),
-            staking_account_id: staking_account_id.clone(),
-            started_leaving_at: None,
-            job_unstaking_period,
-            reward_per_block,
-            missed_reward: None,
-            created_at,
-        }
-    }
-
-    /// Defines whether the worker is leaving the role.
-    pub fn is_leaving(&self) -> bool {
-        self.started_leaving_at.is_some()
-    }
-}
-
-/// Reward policy for the job opening.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct RewardPolicy<Balance> {
-    /// Reward per block for the worker.
-    pub reward_per_block: Balance,
-}
-
-/// Stake policy for the job opening.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct StakePolicy<BlockNumber, Balance> {
-    /// Stake amount for applicants.
-    pub stake_amount: Balance,
-
-    /// Unstaking period for the stake. Zero means no unstaking period.
-    pub leaving_unstaking_period: BlockNumber,
-}
-
-/// Parameters container for the apply_on_opening extrinsic.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct ApplyOnOpeningParams<MemberId, OpeningId, AccountId, Balance> {
-    /// Applying member id.
-    pub member_id: MemberId,
-
-    /// Opening id to apply on.
-    pub opening_id: OpeningId,
-
-    /// Role account id.
-    pub role_account_id: AccountId,
-
-    /// Reward account id.
-    pub reward_account_id: AccountId,
-
-    /// Application description.
-    pub description: Vec<u8>,
-
-    /// Stake information for the application.
-    pub stake_parameters: Option<StakeParameters<AccountId, Balance>>,
-}
-
-/// Contains information for the stakes when applying for opening.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct StakeParameters<AccountId, Balance> {
-    /// Stake balance.
-    pub stake: Balance,
-
-    /// Staking account id.
-    pub staking_account_id: AccountId,
-}
-
-/// ApplyOnOpeningParams type alias.
-pub type ApplyOnOpeningParameters<T, I> = ApplyOnOpeningParams<
-    MemberId<T>,
-    <T as crate::Trait<I>>::OpeningId,
-    <T as frame_system::Trait>::AccountId,
-    BalanceOf<T>,
->;
-
-/// Contains information for the slashing.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Clone, Default, PartialEq, Eq)]
-pub struct Penalty<Balance> {
-    /// Slashing rationale
-    pub slashing_text: Vec<u8>,
-
-    /// Slashing balance
-    pub slashing_amount: Balance,
-}

+ 8 - 4
runtime/src/integration/content_directory.rs

@@ -13,8 +13,10 @@ impl content_directory::ActorAuthenticator for Runtime {
         // get current lead id
         let maybe_current_lead_id = ContentDirectoryWorkingGroup::<Runtime>::current_lead();
         if let Some(ref current_lead_id) = maybe_current_lead_id {
-            if let Ok(worker) =
-                ContentDirectoryWorkingGroup::<Runtime>::ensure_worker_exists(current_lead_id)
+            if let Ok(worker) = working_group::ensure_worker_exists::<
+                Runtime,
+                ContentDirectoryWorkingGroupInstance,
+            >(current_lead_id)
             {
                 *account_id == worker.role_account_id
             } else {
@@ -26,8 +28,10 @@ impl content_directory::ActorAuthenticator for Runtime {
     }
 
     fn is_curator(curator_id: &Self::CuratorId, account_id: &AccountId) -> bool {
-        if let Ok(worker) =
-            ContentDirectoryWorkingGroup::<Runtime>::ensure_worker_exists(curator_id)
+        if let Ok(worker) = working_group::ensure_worker_exists::<
+            Runtime,
+            ContentDirectoryWorkingGroupInstance,
+        >(curator_id)
         {
             *account_id == worker.role_account_id
         } else {

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

@@ -6,4 +6,3 @@ pub mod staking_handler;
 pub mod storage;
 pub mod transactions;
 pub mod versioned_store_permissions;
-pub mod working_group;

+ 22 - 71
runtime/src/integration/proposals/proposal_encoder.rs

@@ -4,7 +4,6 @@ use proposals_codex::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
 use working_group::OpeningType;
 
 use codec::Encode;
-use frame_support::print;
 use sp_std::collections::btree_set::BTreeSet;
 use sp_std::marker::PhantomData;
 use sp_std::vec::Vec;
@@ -35,9 +34,6 @@ impl ProposalEncoder<Runtime> for ExtrinsicProposalEncoder {
             ProposalDetails::Text(text) => {
                 Call::ProposalsCodex(proposals_codex::Call::execute_text_proposal(text))
             }
-            ProposalDetails::SetElectionParameters(election_parameters) => Call::CouncilElection(
-                governance::election::Call::set_election_parameters(election_parameters),
-            ),
             ProposalDetails::Spending(balance, destination) => Call::Council(
                 governance::council::Call::spend_from_council_mint(balance, destination),
             ),
@@ -47,54 +43,20 @@ impl ProposalEncoder<Runtime> for ExtrinsicProposalEncoder {
             ProposalDetails::RuntimeUpgrade(wasm_code) => Call::ProposalsCodex(
                 proposals_codex::Call::execute_runtime_upgrade_proposal(wasm_code),
             ),
-            // ********** Deprecated during the Babylon release.
-            ProposalDetails::DeprecatedSetLead(_) => {
-                print("Error: Calling deprecated SetLead encoding option.");
-                return Vec::new();
-            }
-            // ********** Deprecated during the Babylon release.
-            ProposalDetails::DeprecatedSetContentWorkingGroupMintCapacity(_) => {
-                print(
-                    "Error: Calling deprecated SetContentWorkingGroupMintCapacity encoding option.",
-                );
-                return Vec::new();
-            }
-            // ********** Deprecated during the Nicaea release.
-            // It is kept only for backward compatibility in the Pioneer. **********
-            ProposalDetails::DeprecatedEvictStorageProvider(_) => {
-                print("Error: Calling deprecated EvictStorageProvider encoding option.");
-                return Vec::new();
-            }
-            // ********** Deprecated during the Nicaea release.
-            // It is kept only for backward compatibility in the Pioneer. **********
-            ProposalDetails::DeprecatedSetStorageRoleParameters(_) => {
-                print("Error: Calling deprecated SetStorageRoleParameters encoding option.");
-                return Vec::new();
-            }
             ProposalDetails::AddWorkingGroupLeaderOpening(add_opening_params) => {
                 wrap_working_group_call!(
                     add_opening_params.working_group,
                     Wg::create_add_opening_call(add_opening_params)
                 )
             }
-            ProposalDetails::BeginReviewWorkingGroupLeaderApplications(
-                opening_id,
-                working_group,
-            ) => wrap_working_group_call!(
-                working_group,
-                Wg::create_begin_review_applications_call(opening_id)
-            ),
             ProposalDetails::FillWorkingGroupLeaderOpening(fill_opening_params) => {
                 wrap_working_group_call!(
                     fill_opening_params.working_group,
                     Wg::create_fill_opening_call(fill_opening_params)
                 )
             }
-            ProposalDetails::SetWorkingGroupMintCapacity(mint_balance, working_group) => {
-                wrap_working_group_call!(
-                    working_group,
-                    Wg::create_set_mint_capacity_call(mint_balance)
-                )
+            ProposalDetails::SetWorkingGroupBudgetCapacity(budget, working_group) => {
+                wrap_working_group_call!(working_group, Wg::create_set_budget_capacity_call(budget))
             }
             ProposalDetails::DecreaseWorkingGroupLeaderStake(
                 worker_id,
@@ -143,7 +105,7 @@ struct Wg<T, I> {
 
 impl<T, I> Wg<T, I>
 where
-    T: working_group::Trait<I>,
+    T: working_group::Trait<I> + proposals_codex::Trait,
     I: frame_support::traits::Instance,
 {
     // Generic call constructor for the add working group opening.
@@ -154,28 +116,16 @@ where
         >,
     ) -> working_group::Call<T, I> {
         working_group::Call::<T, I>::add_opening(
-            add_opening_params.activate_at,
-            add_opening_params.commitment,
-            add_opening_params.human_readable_text,
+            add_opening_params.description,
             OpeningType::Leader,
+            add_opening_params.stake_policy,
+            add_opening_params.reward_policy,
         )
     }
 
-    // Generic call constructor for the begin review working group applications.
-    fn create_begin_review_applications_call(
-        opening_id: working_group::OpeningId<T>,
-    ) -> working_group::Call<T, I> {
-        working_group::Call::<T, I>::begin_applicant_review(opening_id)
-    }
-
     // Generic call constructor for the add working group opening.
     fn create_fill_opening_call(
-        fill_opening_params: proposals_codex::FillOpeningParameters<
-            T::BlockNumber,
-            minting::BalanceOf<T>,
-            working_group::OpeningId<T>,
-            working_group::ApplicationId<T>,
-        >,
+        fill_opening_params: proposals_codex::FillOpeningParameters,
     ) -> working_group::Call<T, I> {
         let mut successful_application_ids = BTreeSet::new();
         successful_application_ids.insert(fill_opening_params.successful_application_id);
@@ -183,17 +133,9 @@ where
         working_group::Call::<T, I>::fill_opening(
             fill_opening_params.opening_id,
             successful_application_ids,
-            fill_opening_params.reward_policy,
         )
     }
 
-    // Generic call constructor for the working group 'set mit capacity'.
-    fn create_set_mint_capacity_call(
-        mint_balance: working_group::BalanceOfMint<T>,
-    ) -> working_group::Call<T, I> {
-        working_group::Call::<T, I>::set_mint_capacity(mint_balance)
-    }
-
     // Generic call constructor for the working group 'decrease stake'.
     fn create_decrease_stake_call(
         worker_id: working_group::WorkerId<T>,
@@ -205,27 +147,36 @@ where
     // Generic call constructor for the working group 'slash stake'.
     fn create_slash_stake_call(
         worker_id: working_group::WorkerId<T>,
-        slashing_stake: working_group::BalanceOf<T>,
+        penalty: working_group::Penalty<working_group::BalanceOf<T>>,
     ) -> working_group::Call<T, I> {
-        working_group::Call::<T, I>::slash_stake(worker_id, slashing_stake)
+        working_group::Call::<T, I>::slash_stake(worker_id, penalty)
     }
 
     // Generic call constructor for the working group 'update reward amount'.
     fn create_set_reward_call(
         worker_id: working_group::WorkerId<T>,
-        reward_amount: working_group::BalanceOfMint<T>,
+        reward_amount: Option<working_group::BalanceOf<T>>,
     ) -> working_group::Call<T, I> {
         working_group::Call::<T, I>::update_reward_amount(worker_id, reward_amount)
     }
 
     // Generic call constructor for the working group 'terminate role'.
     fn terminate_role_call(
-        terminate_role_params: proposals_codex::TerminateRoleParameters<working_group::WorkerId<T>>,
+        terminate_role_params: proposals_codex::TerminateRoleParameters<
+            working_group::WorkerId<T>,
+            working_group::BalanceOf<T>,
+        >,
     ) -> working_group::Call<T, I> {
         working_group::Call::<T, I>::terminate_role(
             terminate_role_params.worker_id,
-            terminate_role_params.rationale,
-            terminate_role_params.slash,
+            terminate_role_params.penalty,
         )
     }
+
+    // Generic call constructor for the working group 'set budget'.
+    fn create_set_budget_capacity_call(
+        budget: working_group::BalanceOf<T>,
+    ) -> working_group::Call<T, I> {
+        working_group::Call::<T, I>::set_budget(budget)
+    }
 }

+ 0 - 93
runtime/src/integration/working_group.rs

@@ -1,93 +0,0 @@
-use frame_support::StorageMap;
-use sp_std::marker::PhantomData;
-
-use crate::{ContentDirectoryWorkingGroupInstance, StorageWorkingGroupInstance};
-use stake::{BalanceOf, NegativeImbalance};
-
-pub struct ContentDirectoryWGStakingEventsHandler<T> {
-    pub marker: PhantomData<T>,
-}
-
-impl<T: stake::Trait + working_group::Trait<ContentDirectoryWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for ContentDirectoryWGStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, ContentDirectoryWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, ContentDirectoryWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
-}
-
-pub struct StorageWgStakingEventsHandler<T> {
-    pub marker: PhantomData<T>,
-}
-
-impl<T: stake::Trait + working_group::Trait<StorageWorkingGroupInstance>>
-    stake::StakingEventsHandler<T> for StorageWgStakingEventsHandler<T>
-{
-    /// Unstake remaining sum back to the source_account_id
-    fn unstaked(
-        stake_id: &<T as stake::Trait>::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        // Stake not related to a staked role managed by the hiring module.
-        if !hiring::ApplicationIdByStakingId::<T>::contains_key(*stake_id) {
-            return remaining_imbalance;
-        }
-
-        let hiring_application_id = hiring::ApplicationIdByStakingId::<T>::get(*stake_id);
-
-        if working_group::MemberIdByHiringApplicationId::<T, StorageWorkingGroupInstance>::contains_key(
-            hiring_application_id,
-        ) {
-            return <working_group::Module<T, StorageWorkingGroupInstance>>::refund_working_group_stake(
-				*stake_id,
-				remaining_imbalance,
-			);
-        }
-
-        remaining_imbalance
-    }
-
-    /// Empty handler for the slashing.
-    fn slashed(
-        _: &<T as stake::Trait>::StakeId,
-        _: Option<<T as stake::Trait>::SlashId>,
-        _: BalanceOf<T>,
-        _: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        remaining_imbalance
-    }
-}

+ 20 - 8
runtime/src/lib.rs

@@ -490,10 +490,7 @@ parameter_types! {
 impl stake::Trait for Runtime {
     type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
     type StakePoolId = StakePoolId;
-    type StakingEventsHandler = (
-        crate::integration::working_group::ContentDirectoryWGStakingEventsHandler<Self>,
-        crate::integration::working_group::StorageWgStakingEventsHandler<Self>,
-    );
+    type StakingEventsHandler = ();
     type StakeId = u64;
     type SlashId = u64;
 }
@@ -567,16 +564,31 @@ pub type ContentDirectoryWorkingGroupInstance = working_group::Instance3;
 
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 100;
+    pub const MinUnstakingPeriodLimit: u32 = 43200;
+    pub const StorageWorkingGroupRewardPeriod: u32 = 14400 + 20;
+    pub const ContentWorkingGroupRewardPeriod: u32 = 14400 + 30;
+    pub const StorageWorkingGroupLockId: LockIdentifier = [6; 8];
+    pub const ContentWorkingGroupLockId: LockIdentifier = [7; 8];
 }
 
 impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler =
+        integration::staking_handler::StakingManager<Self, StorageWorkingGroupLockId>;
+    type MemberOriginValidator = MembershipOriginValidator<Self>;
+    type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
+    type RewardPeriod = StorageWorkingGroupRewardPeriod;
 }
 
 impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+    type StakingHandler =
+        integration::staking_handler::StakingManager<Self, ContentWorkingGroupLockId>;
+    type MemberOriginValidator = MembershipOriginValidator<Self>;
+    type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
+    type RewardPeriod = ContentWorkingGroupRewardPeriod;
 }
 
 impl service_discovery::Trait for Runtime {
@@ -645,8 +657,8 @@ impl proposals_codex::Trait for Runtime {
     type BeginReviewWorkingGroupApplicationsProposalParameters =
         BeginReviewWorkingGroupApplicationsProposalParameters;
     type FillWorkingGroupOpeningProposalParameters = FillWorkingGroupOpeningProposalParameters;
-    type SetWorkingGroupMintCapacityProposalParameters =
-        SetWorkingGroupMintCapacityProposalParameters;
+    type SetWorkingGroupBudgetCapacityProposalParameters =
+        SetWorkingGroupBudgetCapacityProposalParameters;
     type DecreaseWorkingGroupLeaderStakeProposalParameters =
         DecreaseWorkingGroupLeaderStakeProposalParameters;
     type SlashWorkingGroupLeaderStakeProposalParameters =
@@ -736,7 +748,7 @@ construct_runtime!(
         ProposalsCodex: proposals_codex::{Module, Call, Storage},
         // --- Working groups
         // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Event<T>},
-        StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
-        ContentDirectoryWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Config<T>, Event<T>},
+        StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Event<T>},
+        ContentDirectoryWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Event<T>},
     }
 );

+ 3 - 3
runtime/src/proposals_configuration/defaults.rs

@@ -100,9 +100,9 @@ pub(crate) fn fill_working_group_opening_proposal() -> ProposalParameters<BlockN
     }
 }
 
-// Proposal parameters for the 'Set working group mint capacity' proposal
-pub(crate) fn set_working_group_mint_capacity_proposal() -> ProposalParameters<BlockNumber, Balance>
-{
+// Proposal parameters for the 'Set working group budget capacity' proposal
+pub(crate) fn set_working_group_budget_capacity_proposal(
+) -> ProposalParameters<BlockNumber, Balance> {
     ProposalParameters {
         voting_period: 43200,
         grace_period: 0,

+ 5 - 5
runtime/src/proposals_configuration/mod.rs

@@ -29,7 +29,7 @@ parameter_types! {
     pub AddWorkingGroupOpeningProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.add_working_group_opening_proposal;
     pub BeginReviewWorkingGroupApplicationsProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.begin_review_working_group_applications_proposal;
     pub FillWorkingGroupOpeningProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.fill_working_group_opening_proposal;
-    pub SetWorkingGroupMintCapacityProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.set_working_group_mint_capacity_proposal;
+    pub SetWorkingGroupBudgetCapacityProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.set_working_group_budget_capacity_proposal;
     pub DecreaseWorkingGroupLeaderStakeProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.decrease_working_group_leader_stake_proposal;
     pub SlashWorkingGroupLeaderStakeProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.slash_working_group_leader_stake_proposal;
     pub SetWorkingGroupLeaderRewardProposalParameters: ProposalParameters<BlockNumber, Balance> = ALL_PROPOSALS_PARAMETERS.set_working_group_leader_reward_proposal;
@@ -47,7 +47,7 @@ struct AllProposalsParameters {
     pub add_working_group_opening_proposal: ProposalParameters<BlockNumber, Balance>,
     pub begin_review_working_group_applications_proposal: ProposalParameters<BlockNumber, Balance>,
     pub fill_working_group_opening_proposal: ProposalParameters<BlockNumber, Balance>,
-    pub set_working_group_mint_capacity_proposal: ProposalParameters<BlockNumber, Balance>,
+    pub set_working_group_budget_capacity_proposal: ProposalParameters<BlockNumber, Balance>,
     pub decrease_working_group_leader_stake_proposal: ProposalParameters<BlockNumber, Balance>,
     pub slash_working_group_leader_stake_proposal: ProposalParameters<BlockNumber, Balance>,
     pub set_working_group_leader_reward_proposal: ProposalParameters<BlockNumber, Balance>,
@@ -119,7 +119,7 @@ fn convert_json_object_to_proposal_parameters(
         init_proposal_parameter_object!(
             params,
             jo.clone(),
-            set_working_group_mint_capacity_proposal
+            set_working_group_budget_capacity_proposal
         );
         init_proposal_parameter_object!(
             params,
@@ -254,8 +254,8 @@ fn default_parameters() -> AllProposalsParameters {
         begin_review_working_group_applications_proposal:
             defaults::begin_review_working_group_applications_proposal(),
         fill_working_group_opening_proposal: defaults::fill_working_group_opening_proposal(),
-        set_working_group_mint_capacity_proposal:
-            defaults::set_working_group_mint_capacity_proposal(),
+        set_working_group_budget_capacity_proposal:
+            defaults::set_working_group_budget_capacity_proposal(),
         decrease_working_group_leader_stake_proposal:
             defaults::decrease_working_group_leader_stake_proposal(),
         slash_working_group_leader_stake_proposal:

+ 1 - 1
runtime/src/proposals_configuration/sample_proposal_parameters.json

@@ -16,7 +16,7 @@
   "add_working_group_opening_proposal": {},
   "begin_review_working_group_applications_proposal": {},
   "fill_working_group_opening_proposal": {},
-  "set_working_group_mint_capacity_proposal": {},
+  "set_working_group_budget_capacity_proposal": {},
   "decrease_working_group_leader_stake_proposal": {},
   "slash_working_group_leader_stake_proposal": {},
   "set_working_group_leader_reward_proposal": {},

+ 20 - 26
runtime/src/runtime_api.rs

@@ -1,5 +1,5 @@
 use frame_support::inherent::{CheckInherentsResult, InherentData};
-use frame_support::traits::{KeyOwnerProofSystem, OnRuntimeUpgrade, Randomness};
+use frame_support::traits::{KeyOwnerProofSystem, Randomness};
 use frame_support::unsigned::{TransactionSource, TransactionValidity};
 use pallet_grandpa::fg_primitives;
 use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
@@ -11,7 +11,6 @@ use sp_runtime::{generic, ApplyExtrinsicResult};
 use sp_std::vec::Vec;
 
 use crate::constants::PRIMARY_PROBABILITY;
-use crate::integration::content_directory::ContentDirectoryWorkingGroup;
 use crate::{
     AccountId, AuthorityDiscoveryId, Balance, BlockNumber, EpochDuration, GrandpaAuthorityList,
     GrandpaId, Hash, Index, RuntimeVersion, Signature, VERSION,
@@ -20,7 +19,6 @@ use crate::{
     AllModules, AuthorityDiscovery, Babe, Call, Grandpa, Historical, InherentDataExt,
     RandomnessCollectiveFlip, Runtime, SessionKeys, System, TransactionPayment,
 };
-use frame_support::weights::Weight;
 
 /// The SignedExtension to the basic transaction logic.
 pub type SignedExtra = (
@@ -54,37 +52,33 @@ pub type BlockId = generic::BlockId<Block>;
 pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<AccountId, Call, Signature, SignedExtra>;
 
 // Default Executive type without the RuntimeUpgrade
-// pub type Executive =
-//     frame_executive::Executive<Runtime, Block, frame_system::ChainContext<Runtime>, Runtime, AllModules>;
-
-/// Custom runtime upgrade handler.
-pub struct CustomOnRuntimeUpgrade;
-impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
-    fn on_runtime_upgrade() -> Weight {
-        let default_text_constraint = crate::working_group::default_text_constraint();
-        let default_content_working_group_mint_capacity = 0;
-
-        ContentDirectoryWorkingGroup::<Runtime>::initialize_working_group(
-            default_text_constraint,
-            default_text_constraint,
-            default_text_constraint,
-            default_content_working_group_mint_capacity,
-        );
-
-        10_000_000 // TODO: adjust weight
-    }
-}
-
-/// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
     Runtime,
     Block,
     frame_system::ChainContext<Runtime>,
     Runtime,
     AllModules,
-    CustomOnRuntimeUpgrade,
 >;
 
+// /// Custom runtime upgrade handler.
+// pub struct CustomOnRuntimeUpgrade;
+// impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
+//     fn on_runtime_upgrade() -> Weight {
+//
+//         10_000_000 // TODO: adjust weight
+//     }
+// }
+//
+// /// Executive: handles dispatch to the various modules with CustomOnRuntimeUpgrade.
+// pub type Executive = frame_executive::Executive<
+//     Runtime,
+//     Block,
+//     frame_system::ChainContext<Runtime>,
+//     Runtime,
+//     AllModules,
+//     CustomOnRuntimeUpgrade,
+// >;
+
 /// Export of the private const generated within the macro.
 pub const EXPORTED_RUNTIME_API_VERSIONS: sp_version::ApisVec = RUNTIME_API_VERSIONS;
 

+ 108 - 364
runtime/src/tests/proposals_integration/working_group_proposals.rs

@@ -6,17 +6,14 @@ use super::*;
 use frame_system::RawOrigin;
 
 use common::working_group::WorkingGroup;
-use hiring::ActivateOpeningAt;
 use proposals_codex::AddOpeningParameters;
-use working_group::{OpeningPolicyCommitment, RewardPolicy};
+use working_group::Penalty;
 
+use crate::primitives::{ActorId, MemberId};
 use crate::{
     Balance, BlockNumber, ContentDirectoryWorkingGroup, ContentDirectoryWorkingGroupInstance,
     StorageWorkingGroup, StorageWorkingGroupInstance,
 };
-use sp_std::collections::btree_set::BTreeSet;
-
-use crate::primitives::{ActorId, MemberId};
 use frame_support::traits;
 use strum::IntoEnumIterator;
 
@@ -27,8 +24,7 @@ type Hiring = hiring::Module<Runtime>;
 fn add_opening(
     member_id: MemberId,
     account_id: [u8; 32],
-    activate_at: hiring::ActivateOpeningAt<BlockNumber>,
-    opening_policy_commitment: Option<OpeningPolicyCommitment<BlockNumber, u128>>,
+    stake_policy: Option<working_group::StakePolicy<BlockNumber, Balance>>,
     sequence_number: u32, // action sequence number to align with other actions
     working_group: WorkingGroup,
 ) -> u64 {
@@ -62,11 +58,9 @@ fn add_opening(
             b"body".to_vec(),
             Some(account_id.into()),
             AddOpeningParameters {
-                activate_at: activate_at.clone(),
-                commitment: opening_policy_commitment
-                    .clone()
-                    .unwrap_or(OpeningPolicyCommitment::default()),
-                human_readable_text: Vec::new(),
+                description: Vec::new(),
+                stake_policy: stake_policy.clone(),
+                reward_policy: None,
                 working_group,
             },
             None,
@@ -80,41 +74,11 @@ fn add_opening(
     opening_id
 }
 
-fn begin_review_applications(
-    member_id: MemberId,
-    account_id: [u8; 32],
-    opening_id: u64,
-    sequence_number: u32, // action sequence number to align with other actions
-    working_group: WorkingGroup,
-) {
-    let expected_proposal_id = sequence_number;
-    let run_to_block = sequence_number * 2;
-
-    let codex_extrinsic_test_fixture = CodexProposalTestFixture::default_for_call(|| {
-        ProposalCodex::create_begin_review_working_group_leader_applications_proposal(
-            RawOrigin::Signed(account_id.into()).into(),
-            member_id,
-            b"title".to_vec(),
-            b"body".to_vec(),
-            Some(account_id.into()),
-            opening_id,
-            working_group,
-            None,
-        )
-    })
-    .disable_setup_enviroment()
-    .with_expected_proposal_id(expected_proposal_id)
-    .with_run_to_block(run_to_block);
-
-    codex_extrinsic_test_fixture.call_extrinsic_and_assert();
-}
-
 fn fill_opening(
     member_id: MemberId,
     account_id: [u8; 32],
     opening_id: u64,
     successful_application_id: u64,
-    reward_policy: Option<RewardPolicy<Balance, BlockNumber>>,
     sequence_number: u32, // action sequence number to align with other actions
     working_group: WorkingGroup,
 ) {
@@ -131,7 +95,6 @@ fn fill_opening(
             proposals_codex::FillOpeningParameters {
                 opening_id,
                 successful_application_id,
-                reward_policy: reward_policy.clone(),
                 working_group,
             },
             None,
@@ -202,7 +165,10 @@ fn slash_stake(
             b"body".to_vec(),
             Some(account_id.into()),
             leader_worker_id,
-            stake_amount,
+            Penalty {
+                slashing_amount: stake_amount,
+                slashing_text: Vec::new(),
+            },
             working_group,
             None,
         )
@@ -233,7 +199,7 @@ fn set_reward(
             b"body".to_vec(),
             Some(account_id.into()),
             leader_worker_id,
-            reward_amount,
+            Some(reward_amount),
             working_group,
             None,
         )
@@ -246,7 +212,7 @@ fn set_reward(
 }
 
 fn set_mint_capacity<
-    T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
+    T: working_group::Trait<I> + frame_system::Trait,
     I: frame_support::traits::Instance,
 >(
     member_id: MemberId,
@@ -255,21 +221,12 @@ fn set_mint_capacity<
     sequence_number: u32, // action sequence number to align with other actions
     setup_environment: bool,
     working_group: WorkingGroup,
-) where
-    <T as minting::Trait>::MintId: From<u64>,
-{
+) {
     let expected_proposal_id = sequence_number;
     let run_to_block = sequence_number * 2;
 
-    let mint_id_result = <minting::Module<Runtime>>::add_mint(0, None);
-
-    if let Ok(mint_id) = mint_id_result {
-        let mint_id: <T as minting::Trait>::MintId = mint_id.into();
-        <working_group::Mint<T, I>>::put(mint_id);
-    }
-
     let codex_extrinsic_test_fixture = CodexProposalTestFixture::default_for_call(|| {
-        ProposalCodex::create_set_working_group_mint_capacity_proposal(
+        ProposalCodex::create_set_working_group_budget_capacity_proposal(
             RawOrigin::Signed(account_id.into()).into(),
             member_id,
             b"title".to_vec(),
@@ -291,7 +248,6 @@ fn terminate_role(
     member_id: MemberId,
     account_id: [u8; 32],
     leader_worker_id: u64,
-    slash: bool,
     sequence_number: u32, // action sequence number to align with other actions
     working_group: WorkingGroup,
 ) {
@@ -307,8 +263,10 @@ fn terminate_role(
             Some(account_id.into()),
             proposals_codex::TerminateRoleParameters {
                 worker_id: leader_worker_id,
-                rationale: Vec::new(),
-                slash,
+                penalty: Some(Penalty {
+                    slashing_amount: 100,
+                    slashing_text: Vec::new(),
+                }),
                 working_group,
             },
             None,
@@ -349,7 +307,6 @@ fn run_create_add_working_group_leader_opening_proposal_execution_succeeds<
     working_group: WorkingGroup,
 ) where
     <T as membership::Trait>::MemberId: From<u64>,
-    <T as hiring::Trait>::OpeningId: From<u64>,
 {
     initial_test_ext().execute_with(|| {
         let member_id: MemberId = 1;
@@ -361,15 +318,8 @@ fn run_create_add_working_group_leader_opening_proposal_execution_succeeds<
             next_opening_id
         ));
 
-        let opening_id: <T as hiring::Trait>::OpeningId = add_opening(
-            member_id,
-            account_id,
-            ActivateOpeningAt::CurrentBlock,
-            None,
-            1,
-            working_group,
-        )
-        .into();
+        let opening_id: working_group::OpeningId =
+            add_opening(member_id, account_id, None, 1, working_group).into();
 
         // Check for expected opening id.
         assert_eq!(opening_id, next_opening_id);
@@ -379,88 +329,6 @@ fn run_create_add_working_group_leader_opening_proposal_execution_succeeds<
     });
 }
 
-#[test]
-fn create_begin_review_working_group_leader_applications_proposal_execution_succeeds() {
-    // This uses strum crate for enum iteration
-    for group in WorkingGroup::iter() {
-        match group {
-            WorkingGroup::Content => {
-                run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
-                Runtime,
-                ContentDirectoryWorkingGroupInstance,
-            >(group);
-            }
-            WorkingGroup::Storage => {
-                run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds::<
-                Runtime,
-                StorageWorkingGroupInstance,
-            >(group);
-            }
-        }
-    }
-}
-
-fn run_create_begin_review_working_group_leader_applications_proposal_execution_succeeds<
-    T: working_group::Trait<I> + frame_system::Trait + stake::Trait,
-    I: frame_support::traits::Instance,
->(
-    working_group: WorkingGroup,
-) where
-    <T as hiring::Trait>::OpeningId: From<u64> + Into<u64>,
-{
-    initial_test_ext().execute_with(|| {
-        let member_id: MemberId = 1;
-        let account_id: [u8; 32] = [member_id as u8; 32];
-
-        let opening_id = add_opening(
-            member_id,
-            account_id,
-            ActivateOpeningAt::CurrentBlock,
-            None,
-            1,
-            working_group,
-        );
-
-        let opening = WorkingGroupInstance::<T, I>::opening_by_id(
-            <T as hiring::Trait>::OpeningId::from(opening_id),
-        );
-
-        let hiring_opening_id: u64 = opening.hiring_opening_id.into();
-        let hiring_opening = Hiring::opening_by_id(hiring_opening_id);
-        assert_eq!(
-            hiring_opening.stage,
-            hiring::OpeningStage::Active {
-                stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: 0
-                },
-                applications_added: BTreeSet::new(),
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0
-            }
-        );
-
-        begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-        let grace_period = 14400;
-        run_to_block(grace_period + 10);
-
-        let hiring_opening = Hiring::opening_by_id(hiring_opening_id);
-        assert_eq!(
-            hiring_opening.stage,
-            hiring::OpeningStage::Active {
-                stage: hiring::ActiveOpeningStage::ReviewPeriod {
-                    started_accepting_applicants_at_block: 0,
-                    started_review_period_at_block: grace_period + 2,
-                },
-                applications_added: BTreeSet::new(),
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0
-            }
-        );
-    });
-}
-
 #[test]
 fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
     // This uses strum crate for enum iteration
@@ -489,54 +357,43 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
         <T as membership::Trait>::MemberId: From<u64>,
-        <T as hiring::Trait>::OpeningId: From<u64>,
+        working_group::MemberId<T>: From<u64>,
     {
         initial_test_ext().execute_with(|| {
-            let member_id: MemberId = 1;
+            let member_id: u64 = 1;
             let account_id: [u8; 32] = [member_id as u8; 32];
 
-            let opening_id = add_opening(
-                member_id,
-                account_id,
-                ActivateOpeningAt::CurrentBlock,
-                None,
-                1,
-                working_group,
-            );
+            let opening_id = add_opening(member_id, account_id, None, 1, working_group);
 
             let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                 RawOrigin::Signed(account_id.into()).into(),
-                member_id.into(),
-                opening_id.into(),
-                account_id.into(),
-                None,
-                None,
-                Vec::new(),
+                working_group::ApplyOnOpeningParameters::<T> {
+                    member_id: member_id.into(),
+                    opening_id,
+                    role_account_id: account_id.into(),
+                    reward_account_id: account_id.into(),
+                    description: Vec::new(),
+                    stake_parameters: None,
+                },
             );
 
             assert_eq!(apply_result, Ok(()));
 
             let expected_application_id = 0;
 
-            begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-
             let lead = WorkingGroupInstance::<T, I>::current_lead();
             assert!(lead.is_none());
 
-            let grace_period_for_begin_application_proposal = 14400;
-            run_to_block(grace_period_for_begin_application_proposal + 20);
-
             fill_opening(
                 member_id,
                 account_id,
                 opening_id,
                 expected_application_id,
-                None,
-                3,
+                2,
                 working_group,
             );
 
-            run_to_block(grace_period_for_begin_application_proposal + 30);
+            run_to_block(30);
 
             let lead = WorkingGroupInstance::<T, I>::current_lead();
             assert!(lead.is_some());
@@ -571,7 +428,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
         working_group: WorkingGroup,
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-        <T as hiring::Trait>::OpeningId: From<u64>,
         <T as membership::Trait>::MemberId: From<u64>,
         <T as membership::Trait>::ActorId: Into<u64>,
         <<T as stake::Trait>::Currency as traits::Currency<
@@ -583,41 +439,29 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             let account_id: [u8; 32] = [member_id as u8; 32];
             let stake_amount: Balance = 100;
 
-            let opening_policy_commitment = OpeningPolicyCommitment {
-                role_staking_policy: Some(hiring::StakingPolicy {
-                    amount: 100,
-                    amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                    crowded_out_unstaking_period_length: None,
-                    review_period_expired_unstaking_period_length: None,
-                }),
-                ..OpeningPolicyCommitment::default()
-            };
+            let stake_policy = Some(working_group::StakePolicy {
+                stake_amount: 100,
+                leaving_unstaking_period: 0,
+            });
 
-            let opening_id = add_opening(
-                member_id,
-                account_id,
-                ActivateOpeningAt::CurrentBlock,
-                Some(opening_policy_commitment),
-                1,
-                working_group,
-            );
+            let opening_id = add_opening(member_id, account_id, stake_policy, 1, working_group);
 
             let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                 RawOrigin::Signed(account_id.into()).into(),
-                member_id.into(),
-                opening_id.into(),
-                account_id.into(),
-                Some(stake_amount.into()),
-                None,
-                Vec::new(),
+                working_group::ApplyOnOpeningParameters::<T> {
+                    member_id: member_id.into(),
+                    opening_id,
+                    role_account_id: account_id.into(),
+                    reward_account_id: account_id.into(),
+                    description: Vec::new(),
+                    stake_parameters: None,
+                },
             );
 
             assert_eq!(apply_result, Ok(()));
 
             let expected_application_id = 0;
 
-            begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-
             let lead = WorkingGroupInstance::<T, I>::current_lead();
             assert!(lead.is_none());
 
@@ -626,7 +470,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                 account_id,
                 opening_id,
                 expected_application_id,
-                None,
                 3,
                 working_group,
             );
@@ -688,7 +531,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
         working_group: WorkingGroup,
     ) where
         <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-        <T as hiring::Trait>::OpeningId: From<u64>,
         <T as membership::Trait>::MemberId: From<u64>,
         <T as membership::Trait>::ActorId: Into<u64>,
         <<T as stake::Trait>::Currency as traits::Currency<
@@ -700,41 +542,29 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             let account_id: [u8; 32] = [member_id as u8; 32];
             let stake_amount: Balance = 100;
 
-            let opening_policy_commitment = OpeningPolicyCommitment {
-                role_staking_policy: Some(hiring::StakingPolicy {
-                    amount: 100,
-                    amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                    crowded_out_unstaking_period_length: None,
-                    review_period_expired_unstaking_period_length: None,
-                }),
-                ..OpeningPolicyCommitment::default()
-            };
+            let stake_policy = Some(working_group::StakePolicy {
+                stake_amount: 100,
+                leaving_unstaking_period: 0,
+            });
 
-            let opening_id = add_opening(
-                member_id,
-                account_id,
-                ActivateOpeningAt::CurrentBlock,
-                Some(opening_policy_commitment),
-                1,
-                working_group,
-            );
+            let opening_id = add_opening(member_id, account_id, stake_policy, 1, working_group);
 
             let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                 RawOrigin::Signed(account_id.into()).into(),
-                member_id.into(),
-                opening_id.into(),
-                account_id.into(),
-                Some(stake_amount.into()),
-                None,
-                Vec::new(),
+                working_group::ApplyOnOpeningParameters::<T> {
+                    member_id: member_id.into(),
+                    opening_id,
+                    role_account_id: account_id.into(),
+                    reward_account_id: account_id.into(),
+                    description: Vec::new(),
+                    stake_parameters: None,
+                },
             );
 
             assert_eq!(apply_result, Ok(()));
 
             let expected_application_id = 0;
 
-            begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-
             let lead = WorkingGroupInstance::<T, I>::current_lead();
 
             assert!(lead.is_none());
@@ -744,7 +574,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                 account_id,
                 opening_id,
                 expected_application_id,
-                None,
                 3,
                 working_group,
             );
@@ -807,16 +636,12 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
             <T as membership::Trait>::MemberId: From<u64>,
             <T as minting::Trait>::MintId: From<u64>,
-            <<T as minting::Trait>::Currency as traits::Currency<
-                <T as frame_system::Trait>::AccountId,
-            >>::Balance: From<u128>,
+            working_group::BalanceOf<T>: From<u128>,
         {
             initial_test_ext().execute_with(|| {
                 let member_id: MemberId = 1;
                 let account_id: [u8; 32] = [member_id as u8; 32];
 
-                assert_eq!(WorkingGroupInstance::<T, I>::mint(), 0.into());
-
                 let mint_capacity = 999999;
                 set_mint_capacity::<T, I>(
                     member_id,
@@ -827,10 +652,10 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     working_group,
                 );
 
-                let mint_id = WorkingGroupInstance::<T, I>::mint();
-                let mint = <minting::Module<T>>::mints(mint_id);
-
-                assert_eq!(mint.capacity(), mint_capacity.into());
+                assert_eq!(
+                    working_group::Module::<T, I>::budget(),
+                    mint_capacity.into()
+                );
             });
         }
 
@@ -865,61 +690,38 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             <T as membership::Trait>::MemberId: From<u64>,
             <T as membership::Trait>::ActorId: Into<u64>,
             <T as minting::Trait>::MintId: From<u64>,
-            <T as hiring::Trait>::OpeningId: From<u64>,
-            <<T as minting::Trait>::Currency as traits::Currency<
-                <T as frame_system::Trait>::AccountId,
-            >>::Balance: From<u128>,
+            working_group::BalanceOf<T>: From<u128>,
         {
             initial_test_ext().execute_with(|| {
                 let member_id: MemberId = 1;
                 let account_id: [u8; 32] = [member_id as u8; 32];
-                let stake_amount = 100;
-
-                let opening_policy_commitment = OpeningPolicyCommitment {
-                    role_staking_policy: Some(hiring::StakingPolicy {
-                        amount: 100,
-                        amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None,
-                    }),
-                    ..OpeningPolicyCommitment::default()
-                };
 
-                let opening_id = add_opening(
-                    member_id,
-                    account_id,
-                    ActivateOpeningAt::CurrentBlock,
-                    Some(opening_policy_commitment),
-                    1,
-                    working_group,
-                );
+                let stake_policy = Some(working_group::StakePolicy {
+                    stake_amount: 100,
+                    leaving_unstaking_period: 0,
+                });
+
+                let opening_id = add_opening(member_id, account_id, stake_policy, 1, working_group);
 
                 let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                     RawOrigin::Signed(account_id.into()).into(),
-                    member_id.into(),
-                    opening_id.into(),
-                    account_id.into(),
-                    Some(stake_amount.into()),
-                    None,
-                    Vec::new(),
+                    working_group::ApplyOnOpeningParameters::<T> {
+                        member_id: member_id.into(),
+                        opening_id,
+                        role_account_id: account_id.into(),
+                        reward_account_id: account_id.into(),
+                        description: Vec::new(),
+                        stake_parameters: None,
+                    },
                 );
 
                 assert_eq!(apply_result, Ok(()));
 
                 let expected_application_id = 0;
 
-                begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-
                 let lead = WorkingGroupInstance::<T, I>::current_lead();
                 assert!(lead.is_none());
 
-                let old_reward_amount = 100;
-                let reward_policy = Some(RewardPolicy {
-                    amount_per_payout: old_reward_amount,
-                    next_payment_at_block: 9999,
-                    payout_interval: None,
-                });
-
                 set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
 
                 fill_opening(
@@ -927,20 +729,12 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     account_id,
                     opening_id,
                     expected_application_id,
-                    reward_policy,
                     4,
                     working_group,
                 );
 
                 let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
 
-                let worker = WorkingGroupInstance::<T, I>::worker_by_id(leader_worker_id);
-                let relationship_id = worker.reward_relationship.unwrap();
-
-                let relationship =
-                    recurring_rewards::RewardRelationships::<T>::get(relationship_id);
-                assert_eq!(relationship.amount_per_payout, old_reward_amount.into());
-
                 let new_reward_amount = 999;
                 set_reward(
                     member_id,
@@ -951,9 +745,9 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     working_group,
                 );
 
-                let relationship =
-                    recurring_rewards::RewardRelationships::<T>::get(relationship_id);
-                assert_eq!(relationship.amount_per_payout, new_reward_amount.into());
+                let worker = WorkingGroupInstance::<T, I>::worker_by_id(leader_worker_id);
+
+                assert_eq!(worker.reward_per_block, Some(new_reward_amount.into()));
             });
         }
 
@@ -986,63 +780,41 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
         ) where
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
             <T as membership::Trait>::MemberId: From<u64>,
+            working_group::MemberId<T>: From<u64>,
             <T as membership::Trait>::ActorId: Into<u64>,
             <T as minting::Trait>::MintId: From<u64>,
-            <T as hiring::Trait>::OpeningId: From<u64>,
-            <<T as stake::Trait>::Currency as traits::Currency<
-                <T as frame_system::Trait>::AccountId,
-            >>::Balance: From<u128>,
         {
             initial_test_ext().execute_with(|| {
                 let member_id: MemberId = 1;
                 let account_id: [u8; 32] = [0; 32];
                 let stake_amount = 100_u128;
 
-                let opening_policy_commitment = OpeningPolicyCommitment {
-                    role_staking_policy: Some(hiring::StakingPolicy {
-                        amount: 100,
-                        amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None,
-                    }),
-                    ..OpeningPolicyCommitment::default()
-                };
+                let stake_policy = Some(working_group::StakePolicy {
+                    stake_amount: 100,
+                    leaving_unstaking_period: 0,
+                });
 
-                let opening_id = add_opening(
-                    member_id.into(),
-                    account_id,
-                    ActivateOpeningAt::CurrentBlock,
-                    Some(opening_policy_commitment),
-                    1,
-                    working_group,
-                );
+                let opening_id = add_opening(member_id, account_id, stake_policy, 1, working_group);
 
                 let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                     RawOrigin::Signed(account_id.into()).into(),
-                    member_id.into(),
-                    opening_id.into(),
-                    account_id.into(),
-                    Some(stake_amount.into()),
-                    None,
-                    Vec::new(),
+                    working_group::ApplyOnOpeningParameters::<T> {
+                        member_id: member_id.into(),
+                        opening_id,
+                        role_account_id: account_id.into(),
+                        reward_account_id: account_id.into(),
+                        description: Vec::new(),
+                        stake_parameters: None,
+                    },
                 );
 
                 assert_eq!(apply_result, Ok(()));
 
                 let expected_application_id = 0;
 
-                begin_review_applications(member_id, account_id, opening_id, 2, working_group);
-
                 let lead = WorkingGroupInstance::<T, I>::current_lead();
                 assert!(lead.is_none());
 
-                let old_reward_amount = 100;
-                let reward_policy = Some(RewardPolicy {
-                    amount_per_payout: old_reward_amount,
-                    next_payment_at_block: 9999,
-                    payout_interval: None,
-                });
-
                 set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
 
                 fill_opening(
@@ -1050,7 +822,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     account_id,
                     opening_id,
                     expected_application_id,
-                    reward_policy,
                     4,
                     working_group,
                 );
@@ -1067,7 +838,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     member_id,
                     account_id,
                     leader_worker_id.into(),
-                    false,
                     5,
                     working_group,
                 );
@@ -1106,68 +876,44 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
             <T as membership::Trait>::MemberId: From<u64>,
             <T as membership::Trait>::ActorId: Into<u64>,
-            <T as minting::Trait>::MintId: From<u64>,
-            <T as hiring::Trait>::OpeningId: From<u64>,
-            <<T as stake::Trait>::Currency as traits::Currency<
-                <T as frame_system::Trait>::AccountId,
-            >>::Balance: From<u128>,
         {
             initial_test_ext().execute_with(|| {
                 let member_id: MemberId = 1;
                 let account_id: [u8; 32] = [0; 32];
                 let stake_amount = 100_u128;
 
-                let opening_policy_commitment = OpeningPolicyCommitment {
-                    role_staking_policy: Some(hiring::StakingPolicy {
-                        amount: 100,
-                        amount_mode: hiring::StakingAmountLimitMode::AtLeast,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None,
-                    }),
-                    ..OpeningPolicyCommitment::default()
+                let staking_policy = working_group::StakePolicy {
+                    stake_amount: 100,
+                    leaving_unstaking_period: 0,
                 };
 
                 let opening_id = add_opening(
                     member_id,
                     account_id,
-                    ActivateOpeningAt::CurrentBlock,
-                    Some(opening_policy_commitment),
+                    Some(staking_policy),
                     1,
                     working_group,
                 );
 
                 let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
                     RawOrigin::Signed(account_id.into()).into(),
-                    member_id.into(),
-                    opening_id.into(),
-                    account_id.into(),
-                    Some(stake_amount.into()),
-                    None,
-                    Vec::new(),
+                    working_group::ApplyOnOpeningParameters::<T> {
+                        member_id: member_id.into(),
+                        opening_id,
+                        role_account_id: account_id.into(),
+                        reward_account_id: account_id.into(),
+                        description: Vec::new(),
+                        stake_parameters: None,
+                    },
                 );
 
                 assert_eq!(apply_result, Ok(()));
 
                 let expected_application_id = 0;
 
-                begin_review_applications(
-                    member_id,
-                    account_id,
-                    opening_id.into(),
-                    2,
-                    working_group,
-                );
-
                 let lead = WorkingGroupInstance::<T, I>::current_lead();
                 assert!(lead.is_none());
 
-                let old_reward_amount = 100;
-                let reward_policy = Some(RewardPolicy {
-                    amount_per_payout: old_reward_amount,
-                    next_payment_at_block: 9999,
-                    payout_interval: None,
-                });
-
                 set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
 
                 fill_opening(
@@ -1175,7 +921,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     account_id,
                     opening_id,
                     expected_application_id,
-                    reward_policy,
                     4,
                     working_group,
                 );
@@ -1192,7 +937,6 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
                     member_id,
                     account_id,
                     leader_worker_id.into(),
-                    true,
                     5,
                     working_group,
                 );

+ 3 - 3
runtime/src/tests/storage_integration.rs

@@ -20,9 +20,9 @@ fn storage_provider_helper_succeeds() {
 		let worker_id2 = 7;
 		let worker_id3 = 19;
 
-		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id1, Worker::default());
-		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id2, Worker::default());
-		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id3, Worker::default());
+		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id1, Worker::<Runtime>::default());
+		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id2, Worker::<Runtime>::default());
+		<working_group::WorkerById<Runtime, Instance2>>::insert(worker_id3, Worker::<Runtime>::default());
 
 		// Still error - not registered in the service discovery.
 		let random_provider_result = <StorageProviderHelper as storage::data_directory::StorageProviderHelper<Runtime>>::get_random_storage_provider();

Some files were not shown because too many files changed in this diff