Browse Source

Merge pull request #1870 from shamil-gadelshin/drop_obsolete_pallets_fix_tests2

Drop obsolete pallets and fix tests.
Mokhtar Naamani 4 years ago
parent
commit
56209c5049
53 changed files with 659 additions and 10293 deletions
  1. 0 137
      Cargo.lock
  2. 0 2
      Cargo.toml
  3. 0 34
      runtime-modules/hiring/Cargo.toml
  4. 0 163
      runtime-modules/hiring/src/hiring/application.rs
  5. 0 160
      runtime-modules/hiring/src/hiring/mod.rs
  6. 0 402
      runtime-modules/hiring/src/hiring/opening.rs
  7. 0 70
      runtime-modules/hiring/src/hiring/staking_policy.rs
  8. 0 1582
      runtime-modules/hiring/src/lib.rs
  9. 0 188
      runtime-modules/hiring/src/macroes.rs
  10. 0 201
      runtime-modules/hiring/src/mock.rs
  11. 0 28
      runtime-modules/hiring/src/test/mod.rs
  12. 0 441
      runtime-modules/hiring/src/test/public_api/add_application.rs
  13. 0 226
      runtime-modules/hiring/src/test/public_api/add_opening.rs
  14. 0 64
      runtime-modules/hiring/src/test/public_api/begin_accepting_applications.rs
  15. 0 55
      runtime-modules/hiring/src/test/public_api/begin_review.rs
  16. 0 431
      runtime-modules/hiring/src/test/public_api/cancel_opening.rs
  17. 0 382
      runtime-modules/hiring/src/test/public_api/deactivate_application.rs
  18. 0 365
      runtime-modules/hiring/src/test/public_api/ensure_can_add_application.rs
  19. 0 474
      runtime-modules/hiring/src/test/public_api/fill_opening.rs
  20. 0 50
      runtime-modules/hiring/src/test/public_api/mod.rs
  21. 0 177
      runtime-modules/hiring/src/test/public_api/on_finalize.rs
  22. 0 302
      runtime-modules/hiring/src/test/public_api/unstaked.rs
  23. 0 247
      runtime-modules/hiring/src/test/smoke.rs
  24. 0 83
      runtime-modules/hiring/src/test/staking_module/get_opt_stake_amount.rs
  25. 0 72
      runtime-modules/hiring/src/test/staking_module/infallible_stake_initiation_on_application.rs
  26. 0 111
      runtime-modules/hiring/src/test/staking_module/initiate_application_deactivations.rs
  27. 0 8
      runtime-modules/hiring/src/test/staking_module/mod.rs
  28. 0 39
      runtime-modules/hiring/src/test/staking_module/opt_infallible_unstake.rs
  29. 0 391
      runtime-modules/hiring/src/test/staking_module/try_to_initiate_application_deactivation.rs
  30. 0 221
      runtime-modules/hiring/src/test/staking_module/would_application_get_added.rs
  31. 0 4
      runtime-modules/proposals/codex/Cargo.toml
  32. 0 1
      runtime-modules/proposals/codex/src/lib.rs
  33. 0 16
      runtime-modules/proposals/codex/src/tests/mock.rs
  34. 0 1
      runtime-modules/proposals/discussion/src/tests/mock.rs
  35. 0 1
      runtime-modules/proposals/engine/src/tests/mock/mod.rs
  36. 0 2
      runtime-modules/service-discovery/Cargo.toml
  37. 0 16
      runtime-modules/service-discovery/src/mock.rs
  38. 0 30
      runtime-modules/stake/Cargo.toml
  39. 0 164
      runtime-modules/stake/src/errors.rs
  40. 0 1174
      runtime-modules/stake/src/lib.rs
  41. 0 29
      runtime-modules/stake/src/macroes.rs
  42. 0 99
      runtime-modules/stake/src/mock.rs
  43. 0 979
      runtime-modules/stake/src/tests.rs
  44. 0 1
      runtime-modules/staking-handler/src/mock.rs
  45. 0 2
      runtime-modules/storage/Cargo.toml
  46. 0 16
      runtime-modules/storage/src/tests/mock.rs
  47. 1 1
      runtime-modules/working-group/src/lib.rs
  48. 0 1
      runtime-modules/working-group/src/tests/mock.rs
  49. 0 4
      runtime/Cargo.toml
  50. 11 24
      runtime/src/lib.rs
  51. 1 1
      runtime/src/tests/mod.rs
  52. 4 8
      runtime/src/tests/proposals_integration/mod.rs
  53. 642 613
      runtime/src/tests/proposals_integration/working_group_proposals.rs

+ 0 - 137
Cargo.lock

@@ -1042,12 +1042,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-
 [[package]]
 name = "digest"
 version = "0.8.1"
@@ -1097,12 +1091,6 @@ dependencies = [
  "quick-error",
 ]
 
-[[package]]
-name = "downcast"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
-
 [[package]]
 name = "dyn-clonable"
 version = "0.9.0"
@@ -1318,15 +1306,6 @@ dependencies = [
  "miniz_oxide",
 ]
 
-[[package]]
-name = "float-cmp"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
-dependencies = [
- "num-traits",
-]
-
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1351,12 +1330,6 @@ dependencies = [
  "percent-encoding 2.1.0",
 ]
 
-[[package]]
-name = "fragile"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
-
 [[package]]
 name = "frame-benchmarking"
 version = "2.0.0"
@@ -2385,7 +2358,6 @@ dependencies = [
  "pallet-forum",
  "pallet-governance",
  "pallet-grandpa",
- "pallet-hiring",
  "pallet-im-online",
  "pallet-membership",
  "pallet-memo",
@@ -2399,7 +2371,6 @@ dependencies = [
  "pallet-service-discovery",
  "pallet-session",
  "pallet-session-benchmarking",
- "pallet-stake",
  "pallet-staking",
  "pallet-staking-reward-curve",
  "pallet-storage",
@@ -3445,33 +3416,6 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
-[[package]]
-name = "mockall"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01458f8a19b10cb28195290942e3149161c75acf67ebc8fbf714ab67a2b943bc"
-dependencies = [
- "cfg-if 0.1.10",
- "downcast",
- "fragile",
- "lazy_static",
- "mockall_derive",
- "predicates",
- "predicates-tree",
-]
-
-[[package]]
-name = "mockall_derive"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a673cb441f78cd9af4f5919c28576a3cc325fb6b54e42f7047dacce3c718c17b"
-dependencies = [
- "cfg-if 0.1.10",
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "multihash"
 version = "0.11.4"
@@ -3606,12 +3550,6 @@ dependencies = [
  "version_check",
 ]
 
-[[package]]
-name = "normalize-line-endings"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
-
 [[package]]
 name = "num-bigint"
 version = "0.2.6"
@@ -3916,24 +3854,6 @@ dependencies = [
  "sp-std",
 ]
 
-[[package]]
-name = "pallet-hiring"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "mockall",
- "pallet-balances",
- "pallet-stake",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
 [[package]]
 name = "pallet-im-online"
 version = "2.0.0"
@@ -4030,12 +3950,10 @@ dependencies = [
  "pallet-common",
  "pallet-constitution",
  "pallet-governance",
- "pallet-hiring",
  "pallet-membership",
  "pallet-proposals-discussion",
  "pallet-proposals-engine",
  "pallet-recurring-reward",
- "pallet-stake",
  "pallet-staking",
  "pallet-staking-reward-curve",
  "pallet-timestamp",
@@ -4132,10 +4050,8 @@ dependencies = [
  "frame-system",
  "pallet-balances",
  "pallet-common",
- "pallet-hiring",
  "pallet-membership",
  "pallet-recurring-reward",
- "pallet-stake",
  "pallet-timestamp",
  "pallet-token-mint",
  "pallet-working-group",
@@ -4185,22 +4101,6 @@ dependencies = [
  "sp-std",
 ]
 
-[[package]]
-name = "pallet-stake"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-timestamp",
- "parity-scale-codec",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
 [[package]]
 name = "pallet-staking"
 version = "2.0.0"
@@ -4242,10 +4142,8 @@ dependencies = [
  "frame-system",
  "pallet-balances",
  "pallet-common",
- "pallet-hiring",
  "pallet-membership",
  "pallet-recurring-reward",
- "pallet-stake",
  "pallet-timestamp",
  "pallet-token-mint",
  "pallet-working-group",
@@ -4800,35 +4698,6 @@ version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
 
-[[package]]
-name = "predicates"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bfead12e90dccead362d62bb2c90a5f6fc4584963645bc7f71a735e0b0735a"
-dependencies = [
- "difference",
- "float-cmp",
- "normalize-line-endings",
- "predicates-core",
- "regex",
-]
-
-[[package]]
-name = "predicates-core"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
-
-[[package]]
-name = "predicates-tree"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
-dependencies = [
- "predicates-core",
- "treeline",
-]
-
 [[package]]
 name = "primitive-types"
 version = "0.7.3"
@@ -8180,12 +8049,6 @@ dependencies = [
  "tracing-serde",
 ]
 
-[[package]]
-name = "treeline"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
-
 [[package]]
 name = "trie-db"
 version = "0.22.1"

+ 0 - 2
Cargo.toml

@@ -7,12 +7,10 @@ members = [
 	"runtime-modules/common",
 	"runtime-modules/forum",
 	"runtime-modules/governance",
-	"runtime-modules/hiring",
 	"runtime-modules/membership",
 	"runtime-modules/memo",
 	"runtime-modules/recurring-reward",
 	"runtime-modules/service-discovery",
-	"runtime-modules/stake",
 	"runtime-modules/storage",
 	"runtime-modules/token-minting",
 	"runtime-modules/working-group",

+ 0 - 34
runtime-modules/hiring/Cargo.toml

@@ -1,34 +0,0 @@
-[package]
-name = 'pallet-hiring'
-version = '3.1.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'}
-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'}
-stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
-
-[dev-dependencies]
-mockall = "0.7.1"
-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'}
-
-[features]
-default = ['std']
-std = [
-	'serde',
-	'codec/std',
-	'sp-std/std',
-	'frame-support/std',
-	'frame-system/std',
-	'sp-arithmetic/std',
-	'sp-runtime/std',
-	'stake/std',
-]

+ 0 - 163
runtime-modules/hiring/src/hiring/application.rs

@@ -1,163 +0,0 @@
-use codec::{Decode, Encode};
-use sp_std::clone::Clone;
-use sp_std::vec::Vec;
-
-use crate::hiring::StakePurpose;
-
-/// An application for an actor to occupy an opening.
-#[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd, Ord)]
-pub struct Application<OpeningId, BlockNumber, StakeId> {
-    /// Identifier for opening for which this application is for.
-    pub opening_id: OpeningId,
-
-    /// Index of arrival across all applications for given opening,
-    /// which is needed for strictly ordering applications.
-    /// Starts at 0.
-    pub application_index_in_opening: u32,
-
-    /// Block at which this application was added.
-    pub add_to_opening_in_block: BlockNumber,
-
-    // NB: The given staking identifiers have a bloated purpose,
-    // and are mutable, fix this.
-    // https://github.com/Joystream/substrate-hiring-module/issues/11
-    /// Identifier for stake that may possibly be established for role.
-    /// Will be set iff the role staking policy of the corresponding opening
-    /// states so AND application is not inactive.
-    pub active_role_staking_id: Option<StakeId>,
-
-    /// Identifier for stake that may possibly be established for application
-    /// Will be set iff the application staking policy of the corresponding opening
-    /// states so.
-    pub active_application_staking_id: Option<StakeId>,
-
-    /// Status of this application
-    pub stage: ApplicationStage<BlockNumber>,
-
-    /// Application note
-    pub human_readable_text: Vec<u8>,
-}
-
-impl<OpeningId, BlockNumber, StakeId: PartialEq + Clone>
-    Application<OpeningId, BlockNumber, StakeId>
-{
-    /// Compares provided stake_id with internal stake defined by stake_purpose.
-    /// Returns None on equality, Some(stake_id) otherwise.
-    pub fn toggle_stake_id(
-        &self,
-        stake_id: StakeId,
-        stake_purpose: StakePurpose,
-    ) -> Option<StakeId> {
-        let active_staking_id = match stake_purpose {
-            StakePurpose::Application => self.active_application_staking_id.clone(),
-            StakePurpose::Role => self.active_role_staking_id.clone(),
-        };
-
-        match active_staking_id {
-            // If there is a match, toggle.
-            Some(id) => {
-                if id == stake_id {
-                    None
-                } else {
-                    Some(id)
-                }
-            }
-            _ => None,
-        }
-    }
-
-    /// Modifies an application and unstake provided stake_id.
-    /// If last stake unstaked - app stage becomes Inactive
-    pub(crate) fn unstake_application(
-        &mut self,
-        current_block_height: BlockNumber,
-        deactivation_initiated: BlockNumber,
-        cause: ApplicationDeactivationCause,
-        stake_id: StakeId,
-    ) -> bool {
-        // New values for application stakes
-        let new_active_role_staking_id = self.toggle_stake_id(stake_id.clone(), StakePurpose::Role);
-        let new_active_application_staking_id =
-            self.toggle_stake_id(stake_id, StakePurpose::Application);
-
-        // Are we now done unstaking?
-        // Is the case if thereare no application stakes set.
-        let is_now_done_unstaking =
-            new_active_role_staking_id.is_none() && new_active_application_staking_id.is_none();
-
-        self.active_role_staking_id = new_active_role_staking_id;
-        self.active_application_staking_id = new_active_application_staking_id;
-
-        // If we are done unstaking, then we go to the inactive stage
-        if is_now_done_unstaking {
-            self.stage = ApplicationStage::Inactive {
-                deactivation_initiated,
-                deactivated: current_block_height,
-                cause,
-            }
-        };
-
-        is_now_done_unstaking
-    }
-}
-
-/// Possible status of an application
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd, Ord)]
-pub enum ApplicationStage<BlockNumber> {
-    /// Normal active state
-    Active,
-
-    /// Waiting for one or more unstakings, with a non-zero unstaking period, to complete.
-    Unstaking {
-        /// When deactivation was initiated.
-        deactivation_initiated: BlockNumber,
-
-        /// The cause of the deactivation.
-        cause: ApplicationDeactivationCause,
-    },
-
-    ///  No longer active, can't do anything fun now.
-    Inactive {
-        /// When deactivation was initiated.
-        deactivation_initiated: BlockNumber,
-
-        /// When deactivation was completed, and the inactive state was established.
-        deactivated: BlockNumber,
-
-        /// The cause of the deactivation.
-        cause: ApplicationDeactivationCause,
-    },
-}
-
-/// Possible application deactivation causes
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord)]
-pub enum ApplicationDeactivationCause {
-    /// Deactivation initiated from outside
-    External, // Add ID here for simplicity?
-
-    /// Applicant was hired
-    Hired,
-
-    /// Applicant was not hired
-    NotHired,
-
-    /// Application was crowded out by another applicaiton
-    CrowdedOut,
-
-    /// Opening was cancelled
-    OpeningCancelled,
-
-    /// Review period expired
-    ReviewPeriodExpired,
-
-    /// Opening was filled
-    OpeningFilled,
-}
-
-/// OpeningStage 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<BlockNumber> Default for ApplicationStage<BlockNumber> {
-    fn default() -> Self {
-        ApplicationStage::Active
-    }
-}

+ 0 - 160
runtime-modules/hiring/src/hiring/mod.rs

@@ -1,160 +0,0 @@
-mod application;
-mod opening;
-mod staking_policy;
-
-pub use application::*;
-pub use opening::*;
-pub use staking_policy::*;
-
-/// Stake purpose enumeration.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum StakePurpose {
-    /// Stake for a role
-    Role,
-
-    /// Stake for an application
-    Application,
-}
-
-/// Informational result of the unstaked() method. Can be ignored.
-#[derive(Debug, Eq, PartialEq, Clone, Copy)]
-pub enum UnstakedResult {
-    /// Non-existentent stake id provided
-    StakeIdNonExistent,
-
-    /// Application is not in 'Unstaking' state
-    ApplicationIsNotUnstaking,
-
-    /// Fully unstaked
-    Unstaked,
-
-    /// Unstaking in progress
-    UnstakingInProgress,
-}
-
-/// Error of the add_application() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum AddApplicationError {
-    /// Opening does not exist
-    OpeningDoesNotExist,
-
-    /// Provided redundant stake
-    StakeProvidedWhenRedundant(StakePurpose),
-
-    /// Required stake was not provided
-    StakeMissingWhenRequired(StakePurpose),
-
-    /// Provided stake amount is too low
-    StakeAmountTooLow(StakePurpose),
-
-    /// Opening is not in acception application active stage
-    OpeningNotInAcceptingApplicationsStage,
-
-    /// Newly created application was crowded out
-    NewApplicationWasCrowdedOut,
-}
-
-/// Successful result of the add_opening() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub struct ApplicationAdded<ApplicationId> {
-    /// Added application id
-    pub application_id_added: ApplicationId,
-
-    /// Possible id of the crowded out application
-    pub application_id_crowded_out: Option<ApplicationId>,
-}
-
-/// Error of the deactivate_application() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum DeactivateApplicationError {
-    /// Application does not exist
-    ApplicationDoesNotExist,
-
-    /// Application is not in active stage
-    ApplicationNotActive,
-
-    /// Opening is not in accepting application stage
-    OpeningNotAcceptingApplications,
-
-    /// Provided unstaking period is too short
-    UnstakingPeriodTooShort(StakePurpose),
-
-    /// Provided redundant unstaking period
-    RedundantUnstakingPeriodProvided(StakePurpose),
-}
-
-/// Error of the cancel_opening() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum CancelOpeningError {
-    /// Provided unstaking period is too short
-    UnstakingPeriodTooShort(StakePurpose),
-
-    /// Provided redundant unstaking period
-    RedundantUnstakingPeriodProvided(StakePurpose),
-
-    /// Opening does not exist
-    OpeningDoesNotExist,
-
-    /// Opening cannot be cancelled
-    OpeningNotInCancellableStage,
-}
-
-/// NB:
-/// `OpeningCancelled` does not have the ideal form.
-/// https://github.com/Joystream/substrate-hiring-module/issues/10
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub struct OpeningCancelled {
-    /// Number of unstaking application because of canceled opening
-    pub number_of_unstaking_applications: u32,
-
-    /// Number of deactivaed application because of canceled opening
-    pub number_of_deactivated_applications: u32,
-}
-
-/// Error of the begin_review() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum BeginReviewError {
-    /// Opening does not exist
-    OpeningDoesNotExist,
-
-    /// Opening is not in acception application active stage
-    OpeningNotInAcceptingApplicationsStage,
-}
-
-/// Error of the begin_accepting_application() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum BeginAcceptingApplicationsError {
-    /// Opening does not exist
-    OpeningDoesNotExist,
-
-    /// Opening is not in waiting to begin stage
-    OpeningIsNotInWaitingToBeginStage,
-}
-
-/// The possible outcome for an application in an opening which is being filled.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum ApplicationOutcomeInFilledOpening {
-    /// Application is successful
-    Success,
-
-    /// Application failed
-    Failure,
-}
-
-/// Error of the add_opening() API method.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum AddOpeningError {
-    /// Indicates that opening with provided parameters must be activated in the future
-    OpeningMustActivateInTheFuture,
-
-    /// It is not possible to stake less than the minimum balance defined in the
-    /// `Currency` module.
-    StakeAmountLessThanMinimumStakeBalance(StakePurpose),
-
-    /// It is not possible to provide application rationing policy with zero
-    /// 'max_active_applicants' parameter.
-    ApplicationRationingZeroMaxApplicants,
-
-    /// It is not possible to stake zero.
-    StakeAmountCannotBeZero(StakePurpose),
-}

+ 0 - 402
runtime-modules/hiring/src/hiring/opening.rs

@@ -1,402 +0,0 @@
-use sp_std::clone::Clone;
-use sp_std::collections::btree_set::BTreeSet;
-use sp_std::prelude::*;
-use sp_std::vec::Vec;
-
-use codec::{Decode, Encode};
-#[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
-
-use crate::hiring;
-use crate::hiring::*;
-
-/// An opening represents the process of hiring one or more new actors into some available role
-#[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone)]
-pub struct Opening<Balance, BlockNumber, ApplicationId> {
-    /// Block at which opening was added
-    pub created: BlockNumber,
-
-    /// Current stage for this opening
-    pub stage: OpeningStage<BlockNumber, ApplicationId>,
-
-    /// Maximum length of the review stage.
-    pub max_review_period_length: BlockNumber,
-
-    /// Whether, and if so how, to limit the number of active applicants....
-    pub application_rationing_policy: Option<ApplicationRationingPolicy>,
-
-    /// Whether any staking is required just to apply, and if so, how that stake is managed.
-    pub application_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-
-    /// Whether any staking is required for the role, and if so, how that stake is managed.
-    pub role_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-
-    /// Description of opening
-    pub human_readable_text: Vec<u8>,
-}
-
-impl<Balance, BlockNumber, ApplicationId> Opening<Balance, BlockNumber, ApplicationId>
-where
-    Balance: PartialOrd + Clone,
-    BlockNumber: PartialOrd + Clone,
-    ApplicationId: Ord + Clone,
-{
-    ///Creates new instance of Opening
-    pub(crate) fn new(
-        current_block_height: BlockNumber,
-        activate_at: ActivateOpeningAt<BlockNumber>,
-        max_review_period_length: BlockNumber,
-        application_rationing_policy: Option<ApplicationRationingPolicy>,
-        application_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-        role_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-        human_readable_text: Vec<u8>,
-    ) -> Self {
-        // Construct new opening
-        let opening_stage = match activate_at {
-            ActivateOpeningAt::CurrentBlock => hiring::OpeningStage::Active {
-                // We immediately start accepting applications
-                stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: current_block_height.clone(),
-                },
-
-                // Empty set of applicants
-                applications_added: BTreeSet::new(),
-
-                // All counters set to 0
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0,
-            },
-
-            ActivateOpeningAt::ExactBlock(block_number) => hiring::OpeningStage::WaitingToBegin {
-                begins_at_block: block_number,
-            },
-        };
-
-        hiring::Opening {
-            created: current_block_height,
-            stage: opening_stage,
-            max_review_period_length,
-            application_rationing_policy,
-            application_staking_policy,
-            role_staking_policy,
-            human_readable_text,
-        }
-    }
-
-    pub(crate) fn clone_with_new_active_opening_stage(
-        self,
-        active_opening_stage: hiring::ActiveOpeningStage<BlockNumber>,
-    ) -> Self {
-        //TODO: hiring::OpeningStage::Active params should be changed to struct
-        //Copy parameters from previous active stage if any or set defaults
-        let (
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        ) = if let hiring::OpeningStage::Active {
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-            ..
-        } = self.stage
-        {
-            //Active opening stage
-            (
-                applications_added,
-                active_application_count,
-                unstaking_application_count,
-                deactivated_application_count,
-            )
-        } else {
-            //Not active opening stage
-            (BTreeSet::new(), 0, 0, 0)
-        };
-
-        hiring::Opening {
-            stage: hiring::OpeningStage::Active {
-                stage: active_opening_stage,
-                applications_added,
-                active_application_count,
-                unstaking_application_count,
-                deactivated_application_count,
-            },
-            ..self
-        }
-    }
-
-    pub(crate) fn change_opening_stage_after_application_unstaked(&mut self) {
-        if let OpeningStage::Active {
-            ref stage,
-            ref applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        } = self.stage
-        {
-            self.stage = hiring::OpeningStage::Active {
-                stage: stage.clone(),
-                applications_added: applications_added.clone(),
-                active_application_count,
-                unstaking_application_count: unstaking_application_count - 1,
-                deactivated_application_count: deactivated_application_count + 1,
-            };
-        } else {
-            panic!("stage MUST be active")
-        }
-    }
-}
-
-/// The stage at which an `Opening` may be at.
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone)]
-pub enum OpeningStage<BlockNumber, ApplicationId> {
-    /// Opening is not active yet. Will be activated at 'begins_at_block' block number
-    WaitingToBegin {
-        /// Becomes active at block number
-        begins_at_block: BlockNumber,
-    },
-
-    /// Active opening stage
-    Active {
-        /// Active stage
-        stage: hiring::ActiveOpeningStage<BlockNumber>,
-
-        /// Set of identifiers for all applications which have been added, but not removed, for this opening.
-        /// Is required for timely on-chain lookup of all applications associated with an opening.
-        applications_added: BTreeSet<ApplicationId>, //BTreeMap<ApplicationId, ()>, //Vec<T::ApplicationId>,
-
-        // TODO: Drop these counters
-        // https://github.com/Joystream/substrate-hiring-module/issues/9
-        //
-        // Counters over all possible application states.
-        // Are needed to set `application_index_in_opening` in new applications
-        // Are very useful for light clients.
-        //
-        // NB: Remember that _all_ state transitions in applications will require updating these variables,
-        // its easy to forget!
-        //
-        // NB: The sum of
-        // - `active_application_count`
-        // - `unstaking_application_count`
-        // - `deactivated_application_count`
-        //
-        // equals the total number of applications ever added to the opening via `add_application`.
-        /// Active NOW
-        active_application_count: u32,
-
-        /// Unstaking NOW
-        unstaking_application_count: u32,
-
-        /// Deactivated at any time for any cause.
-        deactivated_application_count: u32,
-    },
-}
-
-impl<BlockNumber: Clone, ApplicationId: Ord + Clone> OpeningStage<BlockNumber, ApplicationId> {
-    /// The number of applications ever added to the opening via
-    /// `add_opening` extrinsic.
-    pub fn number_of_applications_ever_added(&self) -> u32 {
-        match self {
-            OpeningStage::WaitingToBegin { .. } => 0,
-
-            OpeningStage::Active {
-                active_application_count,
-                unstaking_application_count,
-                deactivated_application_count,
-                ..
-            } => {
-                active_application_count
-                    + unstaking_application_count
-                    + deactivated_application_count
-            }
-        }
-    }
-
-    /// Ensures that an opening is waiting to begin.
-    pub(crate) fn ensure_opening_stage_is_waiting_to_begin<Err>(
-        &self,
-        error: Err,
-    ) -> Result<BlockNumber, Err> {
-        if let OpeningStage::WaitingToBegin { begins_at_block } = self {
-            return Ok(begins_at_block.clone());
-        }
-
-        Err(error)
-    }
-
-    // Clones current stage. Panics if not Active.
-    // Adds application_id to applications_added collection.
-    // Increments 'active_application_count' counter.
-    pub(crate) fn clone_with_added_active_application(
-        self,
-        new_application_id: ApplicationId,
-    ) -> Self {
-        if let hiring::OpeningStage::Active {
-            stage,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-            mut applications_added,
-        } = self
-        {
-            applications_added.insert(new_application_id);
-
-            hiring::OpeningStage::Active {
-                stage,
-                applications_added,
-                active_application_count: active_application_count + 1,
-                unstaking_application_count,
-                deactivated_application_count,
-            }
-        } else {
-            panic!("updated opening should be in active stage");
-        }
-    }
-}
-
-/// OpeningStage 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<BlockNumber: Default, ApplicationId> Default for OpeningStage<BlockNumber, ApplicationId> {
-    fn default() -> Self {
-        OpeningStage::WaitingToBegin {
-            begins_at_block: BlockNumber::default(),
-        }
-    }
-}
-
-/// Substages of an active opening stage
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone)]
-pub enum ActiveOpeningStage<BlockNumber> {
-    /// Active opening accepts application
-    AcceptingApplications {
-        ///Start accepting applications at block number
-        started_accepting_applicants_at_block: BlockNumber,
-    },
-
-    /// Active opening is in review period
-    ReviewPeriod {
-        /// Start accepting applications at block number
-        started_accepting_applicants_at_block: BlockNumber,
-        /// Start review application at block number
-        started_review_period_at_block: BlockNumber,
-    },
-
-    /// Active opening was deactivated
-    Deactivated {
-        /// Deactivation cause
-        cause: OpeningDeactivationCause,
-
-        /// Deactivated at block number
-        deactivated_at_block: BlockNumber,
-
-        /// Start accepting applications at block number
-        started_accepting_applicants_at_block: BlockNumber,
-
-        /// Whether the review period had ever been started, and if so, at what block.
-        /// Deactivation can also occur directly from the AcceptingApplications stage.
-        started_review_period_at_block: Option<BlockNumber>,
-    },
-}
-
-impl<BlockNumber: Clone> ActiveOpeningStage<BlockNumber> {
-    // Ensures that active opening stage is accepting applications.
-    pub(crate) fn ensure_active_opening_is_accepting_applications<Err>(
-        &self,
-        error: Err,
-    ) -> Result<BlockNumber, Err> {
-        if let ActiveOpeningStage::AcceptingApplications {
-            started_accepting_applicants_at_block,
-        } = self
-        {
-            return Ok(started_accepting_applicants_at_block.clone());
-        }
-
-        Err(error)
-    }
-
-    // Ensures that active opening stage is in review period.
-    pub(crate) fn ensure_active_opening_is_in_review_period<Err>(
-        &self,
-        error: Err,
-    ) -> Result<(BlockNumber, BlockNumber), Err> {
-        match self {
-            ActiveOpeningStage::ReviewPeriod {
-                started_accepting_applicants_at_block,
-                started_review_period_at_block,
-            } => Ok((
-                started_accepting_applicants_at_block.clone(),
-                started_review_period_at_block.clone(),
-            )), // <= need proper type here in the future, not param
-            _ => Err(error),
-        }
-    }
-
-    // Creates new active opening stage on cancel opening
-    pub(crate) fn new_stage_on_cancelling(
-        self,
-        current_block_height: BlockNumber,
-    ) -> Result<ActiveOpeningStage<BlockNumber>, CancelOpeningError> {
-        match self {
-            ActiveOpeningStage::AcceptingApplications {
-                started_accepting_applicants_at_block,
-            } => Ok(ActiveOpeningStage::Deactivated {
-                cause: OpeningDeactivationCause::CancelledAcceptingApplications,
-                deactivated_at_block: current_block_height,
-                started_accepting_applicants_at_block,
-                started_review_period_at_block: None,
-            }),
-            ActiveOpeningStage::ReviewPeriod {
-                started_accepting_applicants_at_block,
-                started_review_period_at_block,
-            } => Ok(ActiveOpeningStage::Deactivated {
-                cause: OpeningDeactivationCause::CancelledInReviewPeriod,
-                deactivated_at_block: current_block_height,
-                started_accepting_applicants_at_block,
-                started_review_period_at_block: Some(started_review_period_at_block),
-            }),
-            ActiveOpeningStage::Deactivated { .. } => {
-                Err(CancelOpeningError::OpeningNotInCancellableStage)
-            }
-        }
-    }
-}
-
-/// Opening deactivation cause
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone)]
-pub enum OpeningDeactivationCause {
-    /// Opening was cancelled before activation
-    CancelledBeforeActivation,
-
-    /// Opening was cancelled during accepting application stage
-    CancelledAcceptingApplications,
-
-    /// Opening was cancelled during accepting application stage
-    CancelledInReviewPeriod,
-
-    /// Opening was cancelled after review period expired.
-    ReviewPeriodExpired,
-
-    /// Opening was filled.
-    Filled,
-}
-
-/// Defines the moment of the opening activation.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
-pub enum ActivateOpeningAt<BlockNumber> {
-    /// Activate opening now (current block).
-    CurrentBlock,
-
-    /// Activate opening at block number.
-    ExactBlock(BlockNumber),
-}
-
-/// How to limit the number of eligible applicants
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone)]
-pub struct ApplicationRationingPolicy {
-    /// The maximum number of applications that can be on the list at any time.
-    pub max_active_applicants: u32,
-}

+ 0 - 70
runtime-modules/hiring/src/hiring/staking_policy.rs

@@ -1,70 +0,0 @@
-use codec::{Decode, Encode};
-
-#[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
-
-/// Policy for staking
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, Default)]
-pub struct StakingPolicy<Balance, BlockNumber> {
-    /// Staking amount
-    pub amount: Balance,
-
-    /// How to interpret the amount requirement
-    pub amount_mode: StakingAmountLimitMode,
-
-    /// The unstaking period length, if any, deactivation causes that are autonomous,
-    /// that is they are triggered internally to this module.
-    pub crowded_out_unstaking_period_length: Option<BlockNumber>,
-
-    /// The review period length
-    pub review_period_expired_unstaking_period_length: Option<BlockNumber>,
-}
-
-impl<Balance: PartialOrd + Clone, BlockNumber: Clone> StakingPolicy<Balance, BlockNumber> {
-    pub(crate) fn accepts_amount(&self, test_amount: &Balance) -> bool {
-        match self.amount_mode {
-            StakingAmountLimitMode::AtLeast => *test_amount >= self.amount,
-            StakingAmountLimitMode::Exact => *test_amount == self.amount,
-        }
-    }
-
-    pub(crate) fn opt_staking_policy_to_review_period_expired_unstaking_period(
-        opt_staking_policy: &Option<StakingPolicy<Balance, BlockNumber>>,
-    ) -> Option<BlockNumber> {
-        if let Some(ref staking_policy) = opt_staking_policy {
-            staking_policy
-                .review_period_expired_unstaking_period_length
-                .clone()
-        } else {
-            None
-        }
-    }
-
-    pub(crate) fn opt_staking_policy_to_crowded_out_unstaking_period(
-        opt_staking_policy: &Option<StakingPolicy<Balance, BlockNumber>>,
-    ) -> Option<BlockNumber> {
-        if let Some(ref staking_policy) = opt_staking_policy {
-            staking_policy.crowded_out_unstaking_period_length.clone()
-        } else {
-            None
-        }
-    }
-}
-
-/// Constraints around staking amount
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Debug, Eq, PartialEq, Clone)]
-pub enum StakingAmountLimitMode {
-    /// Stake should be equal or greater than provided value
-    AtLeast,
-
-    /// Stake should be equal to provided value
-    Exact,
-}
-
-impl Default for StakingAmountLimitMode {
-    fn default() -> Self {
-        StakingAmountLimitMode::Exact
-    }
-}

+ 0 - 1582
runtime-modules/hiring/src/lib.rs

@@ -1,1582 +0,0 @@
-//! Hiring substrate module for the Joystream platform
-//!
-//! Public APIs:
-//! - add_opening
-//! - ensure_can_add_application
-//! - add_application
-//! - deactivate_application
-//! - cancel_opening
-//! - fill_opening
-//! - begin_review
-//! - begin_acception_application
-//! - unstaked
-//!
-//! Dependency: Joystream stake module
-
-// 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)]
-
-// Test dependencies
-#[cfg(all(test, not(target_arch = "wasm32")))]
-use mockall::predicate::*;
-#[cfg(all(test, not(target_arch = "wasm32")))]
-use mockall::*;
-
-use codec::Codec;
-use frame_support::storage::IterableStorageMap;
-use frame_support::traits::{Currency, Imbalance};
-use frame_support::{decl_module, decl_storage, ensure, Parameter};
-use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
-use sp_runtime::traits::{MaybeSerialize, Member};
-use sp_std::cell::RefCell;
-use sp_std::collections::btree_map::BTreeMap;
-use sp_std::collections::btree_set::BTreeSet;
-use sp_std::iter::Iterator;
-use sp_std::rc::Rc;
-use sp_std::vec::Vec;
-
-use stake::{InitiateUnstakingError, Stake, StakeActionError, StakingError, Trait as StakeTrait};
-
-mod hiring;
-#[macro_use]
-mod macroes;
-mod mock;
-mod test;
-
-pub use hiring::*;
-
-/// Main trait of hiring substrate module
-pub trait Trait: frame_system::Trait + stake::Trait + Sized {
-    /// OpeningId type
-    type OpeningId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
-    /// ApplicationId type
-    type ApplicationId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
-    /// Type that will handle various staking events
-    type ApplicationDeactivatedHandler: ApplicationDeactivatedHandler<Self>;
-
-    /// Marker type for Stake module handler. Indicates that hiring module uses stake module mock.
-    type StakeHandlerProvider: StakeHandlerProvider<Self>;
-}
-
-decl_storage! {
-    trait Store for Module<T: Trait> as Hiring {
-        /// Openings.
-        pub OpeningById get(fn opening_by_id): map hasher(blake2_128_concat)
-            T::OpeningId => Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>;
-
-        /// Identifier for next opening to be added.
-        pub NextOpeningId get(fn next_opening_id): T::OpeningId;
-
-        /// Applications
-        pub ApplicationById get(fn application_by_id): map hasher(blake2_128_concat)
-            T::ApplicationId => Application<T::OpeningId, T::BlockNumber, T::StakeId>;
-
-        /// Identifier for next application to be added.
-        pub NextApplicationId get(fn next_application_id): T::ApplicationId;
-
-        /// Internal purpose of given stake, i.e. fro what application, and whether for the role or for the application.
-        pub ApplicationIdByStakingId get(fn stake_purpose_by_staking_id): map hasher(blake2_128_concat)
-            T::StakeId => T::ApplicationId;
-    }
-}
-
-decl_module! {
-    /// Main hiring module definition
-    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-
-        fn on_finalize(now: T::BlockNumber) {
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Change opening from WaitingToBegin stage to Active::AcceptingApplications stage
-            for (opening_id, opening) in Self::openings_waiting_to_begin_iterator(now) {
-                let opening_accepting_applications = opening.clone_with_new_active_opening_stage(
-                    hiring::ActiveOpeningStage::AcceptingApplications {
-                        started_accepting_applicants_at_block: now
-                });
-
-                <OpeningById<T>>::insert(opening_id, opening_accepting_applications);
-            }
-
-            // Deactivate opening
-            for (opening_id,
-                opening,
-                (
-                    applications_added,
-                    started_accepting_applicants_at_block,
-                    started_review_period_at_block
-                )) in Self::openings_expired_review_period_iterator(now) {
-
-                //
-                // Deactivate all applications that are part of this opening
-                //
-
-                // Get unstaking periods
-                let application_stake_unstaking_period = StakingPolicy::opt_staking_policy_to_review_period_expired_unstaking_period(&opening.application_staking_policy);
-                let role_stake_unstaking_period = StakingPolicy::opt_staking_policy_to_review_period_expired_unstaking_period(&opening.role_staking_policy);
-
-                // Get applications
-                let applications_map = Self::application_id_iter_to_map(applications_added.iter());
-
-                // Deactivate applications
-                Self::initiate_application_deactivations(
-                    &applications_map,
-                    application_stake_unstaking_period,
-                    role_stake_unstaking_period,
-                    hiring::ApplicationDeactivationCause::ReviewPeriodExpired
-                );
-
-                let deactivated_opening =
-                    opening.clone_with_new_active_opening_stage(
-                        hiring::ActiveOpeningStage::Deactivated {
-                            cause: hiring::OpeningDeactivationCause::ReviewPeriodExpired,
-                            deactivated_at_block: now,
-                            started_accepting_applicants_at_block,
-                            started_review_period_at_block: Some(started_review_period_at_block),
-                    });
-
-                <OpeningById<T>>::insert(opening_id, deactivated_opening);
-            }
-        }
-    }
-}
-
-/*
- *  ======== Main API implementation ========
- */
-
-// Public API implementation
-impl<T: Trait> Module<T> {
-    /// Add new opening based on given inputs policies.
-    /// The new Opening instance has stage WaitingToBegin, and is added to openingsById,
-    /// and has identifier equal to nextOpeningId.
-    /// The latter is incremented. The used identifier is returned.
-    pub fn add_opening(
-        activate_at: ActivateOpeningAt<T::BlockNumber>,
-        max_review_period_length: T::BlockNumber,
-        application_rationing_policy: Option<ApplicationRationingPolicy>,
-        application_staking_policy: Option<StakingPolicy<BalanceOf<T>, T::BlockNumber>>,
-        role_staking_policy: Option<StakingPolicy<BalanceOf<T>, T::BlockNumber>>,
-        human_readable_text: Vec<u8>,
-    ) -> Result<T::OpeningId, AddOpeningError> {
-        let current_block_height = <frame_system::Module<T>>::block_number();
-
-        Self::ensure_can_add_opening(
-            current_block_height,
-            activate_at.clone(),
-            T::Currency::minimum_balance(),
-            application_rationing_policy.clone(),
-            application_staking_policy.clone(),
-            role_staking_policy.clone(),
-        )?;
-
-        // == MUTATION SAFE ==
-
-        let new_opening = hiring::Opening::new(
-            current_block_height,
-            activate_at,
-            max_review_period_length,
-            application_rationing_policy,
-            application_staking_policy,
-            role_staking_policy,
-            human_readable_text,
-        );
-
-        // Get Id for new opening
-        let new_opening_id = <NextOpeningId<T>>::get();
-
-        // Insert opening in storage
-        <OpeningById<T>>::insert(new_opening_id, new_opening);
-
-        // Update NextOpeningId counter
-        <NextOpeningId<T>>::mutate(|id| *id += T::OpeningId::one());
-
-        // Return
-        Ok(new_opening_id)
-    }
-
-    /// Cancels opening with given identifier, using provided unstaking periods for
-    /// application and role, as necesary.
-    pub fn cancel_opening(
-        opening_id: T::OpeningId,
-        application_stake_unstaking_period: Option<T::BlockNumber>,
-        role_stake_unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<OpeningCancelled, CancelOpeningError> {
-        // Ensure that the opening exists
-        let opening =
-            ensure_opening_exists!(T, opening_id, CancelOpeningError::OpeningDoesNotExist)?;
-
-        // Opening is in stage Active.{AcceptingApplications or ReviewPeriod}
-
-        let (
-            active_stage,
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        ) = ensure_opening_is_active!(
-            opening.stage,
-            CancelOpeningError::OpeningNotInCancellableStage
-        )?;
-
-        //
-        let current_block_height = <frame_system::Module<T>>::block_number(); // move later!
-        let new_active_stage = active_stage.new_stage_on_cancelling(current_block_height)?;
-
-        // Ensure unstaking periods are OK.
-        ensure_opt_unstaking_period_is_ok!(
-            application_stake_unstaking_period,
-            opening.application_staking_policy,
-            CancelOpeningError::UnstakingPeriodTooShort(StakePurpose::Application),
-            CancelOpeningError::RedundantUnstakingPeriodProvided(StakePurpose::Application)
-        )?;
-
-        ensure_opt_unstaking_period_is_ok!(
-            role_stake_unstaking_period,
-            opening.role_staking_policy,
-            CancelOpeningError::UnstakingPeriodTooShort(StakePurpose::Role),
-            CancelOpeningError::RedundantUnstakingPeriodProvided(StakePurpose::Role)
-        )?;
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        // Create and store new cancelled opening
-        let new_opening = Opening {
-            stage: hiring::OpeningStage::Active {
-                stage: new_active_stage,
-                applications_added: applications_added.clone(),
-                active_application_count,
-                unstaking_application_count,
-                deactivated_application_count,
-            },
-            ..opening
-        };
-
-        OpeningById::<T>::insert(opening_id, new_opening);
-
-        // Map with applications
-        let applications_map = Self::application_id_iter_to_map(applications_added.iter());
-
-        // Initiate deactivation of all active applications
-        let net_result = Self::initiate_application_deactivations(
-            &applications_map,
-            application_stake_unstaking_period,
-            role_stake_unstaking_period,
-            hiring::ApplicationDeactivationCause::OpeningCancelled,
-        );
-
-        // Return
-        Ok(OpeningCancelled {
-            number_of_unstaking_applications: net_result.number_of_unstaking_applications,
-            number_of_deactivated_applications: net_result.number_of_deactivated_applications,
-        })
-    }
-
-    /// Transit opening to the accepting application stage.
-    /// Applies when given opening is in WaitingToBegin stage.
-    /// The stage is updated to Active stage with AcceptingApplications substage
-    pub fn begin_accepting_applications(
-        opening_id: T::OpeningId,
-    ) -> Result<(), BeginAcceptingApplicationsError> {
-        // Ensure that the opening exists
-        let opening = ensure_opening_exists!(
-            T,
-            opening_id,
-            BeginAcceptingApplicationsError::OpeningDoesNotExist
-        )?;
-
-        // Ensure that it is the waiting to begin stage
-        opening.stage.ensure_opening_stage_is_waiting_to_begin(
-            BeginAcceptingApplicationsError::OpeningIsNotInWaitingToBeginStage,
-        )?;
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        let current_block_height = <frame_system::Module<T>>::block_number();
-
-        // Update state of opening
-        let new_opening = opening.clone_with_new_active_opening_stage(
-            hiring::ActiveOpeningStage::AcceptingApplications {
-                started_accepting_applicants_at_block: current_block_height,
-            },
-        );
-
-        // Write back opening
-        <OpeningById<T>>::insert(opening_id, new_opening);
-
-        // DONE
-        Ok(())
-    }
-
-    /// Transit opening to the begin review period stage.
-    /// Applies when given opening is in Active stage and AcceptingApplications substage.
-    /// The stage is updated to Active stage and ReviewPeriod substage
-    pub fn begin_review(opening_id: T::OpeningId) -> Result<(), BeginReviewError> {
-        // Ensure that the opening exists
-        let opening = ensure_opening_exists!(T, opening_id, BeginReviewError::OpeningDoesNotExist)?;
-
-        // Opening is accepting applications
-        let (active_stage, _, _, _, _) = ensure_opening_is_active!(
-            opening.stage,
-            BeginReviewError::OpeningNotInAcceptingApplicationsStage
-        )?;
-
-        let started_accepting_applicants_at_block = ensure_active_opening_is_accepting_applications!(
-            active_stage,
-            BeginReviewError::OpeningNotInAcceptingApplicationsStage
-        )?;
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        let current_block_height = <frame_system::Module<T>>::block_number();
-
-        let new_opening =
-            opening.clone_with_new_active_opening_stage(hiring::ActiveOpeningStage::ReviewPeriod {
-                started_accepting_applicants_at_block,
-                started_review_period_at_block: current_block_height,
-            });
-
-        // Update to new opening
-        <OpeningById<T>>::insert(opening_id, new_opening);
-
-        Ok(())
-    }
-
-    /// Fill an opening, identified with `opening_id`, currently in the review period.
-    /// Applies when given opening is in ReviewPeriod stage.
-    /// Given list of applications are deactivated to under the Hired,
-    /// all other active applicants are NotHired.
-    /// Separately for each group,
-    /// unstaking periods for any applicable application and/or role stake must be provided.
-    pub fn fill_opening(
-        opening_id: T::OpeningId,
-        successful_applications: BTreeSet<T::ApplicationId>,
-        opt_successful_applicant_application_stake_unstaking_period: Option<T::BlockNumber>,
-        opt_failed_applicant_application_stake_unstaking_period: Option<T::BlockNumber>,
-        /* this parameter does not make sense? opt_successful_applicant_role_stake_unstaking_period: Option<T::BlockNumber>, */
-        opt_failed_applicant_role_stake_unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), FillOpeningError<T>> {
-        // Ensure that the opening exists
-        let opening = ensure_opening_exists!(T, opening_id, FillOpeningError::OpeningDoesNotExist)?;
-
-        let (active_stage, applications_added, _, _, _) = ensure_opening_is_active!(
-            opening.stage,
-            FillOpeningError::OpeningNotInReviewPeriodStage
-        )?;
-
-        // Ensure opening is in review period
-        let (started_accepting_applicants_at_block, started_review_period_at_block) = active_stage
-            .ensure_active_opening_is_in_review_period(
-                FillOpeningError::OpeningNotInReviewPeriodStage,
-            )?;
-
-        //
-        // Ensure that all unstaking periods are neither too short (0) nor redundant.
-        //
-
-        ensure_opt_unstaking_period_is_ok!(
-            opt_successful_applicant_application_stake_unstaking_period,
-            opening.application_staking_policy,
-            FillOpeningError::UnstakingPeriodTooShort(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Success
-            ),
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Success
-            )
-        )?;
-
-        ensure_opt_unstaking_period_is_ok!(
-            opt_failed_applicant_application_stake_unstaking_period,
-            opening.application_staking_policy,
-            FillOpeningError::UnstakingPeriodTooShort(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Failure
-            ),
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Failure
-            )
-        )?;
-
-        ensure_opt_unstaking_period_is_ok!(
-            opt_failed_applicant_role_stake_unstaking_period,
-            opening.role_staking_policy,
-            FillOpeningError::UnstakingPeriodTooShort(
-                StakePurpose::Role,
-                ApplicationOutcomeInFilledOpening::Failure
-            ),
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Role,
-                ApplicationOutcomeInFilledOpening::Failure
-            )
-        )?;
-
-        // Ensure that all successful applications actually exist
-        for application_id in &successful_applications {
-            ensure_application_exists!(
-                T,
-                *application_id,
-                FillOpeningError::ApplicationDoesNotExist(*application_id)
-            )?;
-        }
-
-        let successful_applications_map =
-            Self::application_id_iter_to_map(successful_applications.iter());
-
-        // Ensure that all successful applications are actually active and associated with the opening
-        for (application_id, application) in &successful_applications_map {
-            ensure_eq!(
-                application.stage,
-                hiring::ApplicationStage::Active,
-                FillOpeningError::ApplicationNotInActiveStage(*application_id,)
-            );
-
-            ensure_eq!(
-                application.opening_id,
-                opening_id,
-                FillOpeningError::ApplicationForWrongOpening(*application_id)
-            );
-        }
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        // Deactivate all successful applications, with cause being hired
-        Self::initiate_application_deactivations(
-            &successful_applications_map,
-            opt_successful_applicant_application_stake_unstaking_period,
-            None,
-            hiring::ApplicationDeactivationCause::Hired,
-        );
-
-        // Deactivate all unsuccessful applications, with cause being not being hired.
-
-        // First get all failed applications by their id.
-        let failed_applications_map = Self::application_id_iter_to_map(
-            applications_added.difference(&successful_applications),
-        );
-
-        // Deactivate all successful applications, with cause being not hired
-        Self::initiate_application_deactivations(
-            &failed_applications_map,
-            opt_failed_applicant_application_stake_unstaking_period,
-            opt_failed_applicant_role_stake_unstaking_period,
-            hiring::ApplicationDeactivationCause::NotHired,
-        );
-
-        // Grab current block height
-        let current_block_height = <frame_system::Module<T>>::block_number();
-        // Get opening with updated counters
-        let opening_needed_for_data = <OpeningById<T>>::get(opening_id);
-
-        // Deactivate opening
-        let new_opening = opening_needed_for_data.clone_with_new_active_opening_stage(
-            hiring::ActiveOpeningStage::Deactivated {
-                cause: OpeningDeactivationCause::Filled,
-                deactivated_at_block: current_block_height,
-                started_accepting_applicants_at_block,
-                started_review_period_at_block: Some(started_review_period_at_block),
-            },
-        );
-
-        // Write back new opening
-        <OpeningById<T>>::insert(opening_id, new_opening);
-
-        // DONE
-        Ok(())
-    }
-
-    /// Adds a new application on the given opening, and begins staking for
-    /// the role, the application or both possibly.
-    pub fn ensure_can_add_application(
-        opening_id: T::OpeningId,
-        opt_role_stake_balance: Option<BalanceOf<T>>,
-        opt_application_stake_balance: Option<BalanceOf<T>>,
-    ) -> Result<DestructuredApplicationCanBeAddedEvaluation<T>, AddApplicationError> {
-        // Ensure that the opening exists
-        let opening =
-            ensure_opening_exists!(T, opening_id, AddApplicationError::OpeningDoesNotExist)?;
-
-        // Ensure that proposed stakes match the policy of the opening.
-        let opt_role_stake_balance = ensure_stake_balance_matches_staking_policy!(
-            &opt_role_stake_balance,
-            &opening.role_staking_policy,
-            AddApplicationError::StakeMissingWhenRequired(StakePurpose::Role),
-            AddApplicationError::StakeProvidedWhenRedundant(StakePurpose::Role),
-            AddApplicationError::StakeAmountTooLow(StakePurpose::Role)
-        )?;
-
-        let opt_application_stake_balance = ensure_stake_balance_matches_staking_policy!(
-            &opt_application_stake_balance,
-            &opening.application_staking_policy,
-            AddApplicationError::StakeMissingWhenRequired(StakePurpose::Application),
-            AddApplicationError::StakeProvidedWhenRedundant(StakePurpose::Application),
-            AddApplicationError::StakeAmountTooLow(StakePurpose::Application)
-        )?;
-
-        // Opening is accepting applications
-
-        let (
-            active_stage,
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        ) = ensure_opening_is_active!(
-            opening.stage,
-            AddApplicationError::OpeningNotInAcceptingApplicationsStage
-        )?;
-
-        active_stage.ensure_active_opening_is_accepting_applications(
-            AddApplicationError::OpeningNotInAcceptingApplicationsStage,
-        )?;
-
-        // Ensure that the new application would actually make it
-        let would_get_added_success = ensure_application_would_get_added!(
-            &opening.application_rationing_policy,
-            &applications_added,
-            &opt_role_stake_balance,
-            &opt_application_stake_balance,
-            AddApplicationError::NewApplicationWasCrowdedOut
-        )?;
-
-        Ok(DestructuredApplicationCanBeAddedEvaluation {
-            opening,
-            active_stage,
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-            would_get_added_success,
-        })
-    }
-
-    /// Adds a new application on the given opening, and begins staking for
-    /// the role, the application or both possibly.
-    pub fn add_application(
-        opening_id: T::OpeningId,
-        opt_role_stake_imbalance: Option<NegativeImbalance<T>>,
-        opt_application_stake_imbalance: Option<NegativeImbalance<T>>,
-        human_readable_text: Vec<u8>,
-    ) -> Result<ApplicationAdded<T::ApplicationId>, AddApplicationError> {
-        let opt_role_stake_balance = Self::create_stake_balance(&opt_role_stake_imbalance);
-        let opt_application_stake_balance =
-            Self::create_stake_balance(&opt_application_stake_imbalance);
-
-        let can_be_added_destructured = Self::ensure_can_add_application(
-            opening_id,
-            opt_role_stake_balance,
-            opt_application_stake_balance,
-        )?;
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        // If required, deactive another application that was crowded out.
-        if let ApplicationAddedSuccess::CrowdsOutExistingApplication(
-            id_of_croweded_out_application,
-        ) = can_be_added_destructured.would_get_added_success
-        {
-            // Get relevant unstaking periods
-            let opt_application_stake_unstaking_period =
-                hiring::StakingPolicy::opt_staking_policy_to_crowded_out_unstaking_period(
-                    &can_be_added_destructured.opening.application_staking_policy,
-                );
-            let opt_role_stake_unstaking_period =
-                hiring::StakingPolicy::opt_staking_policy_to_crowded_out_unstaking_period(
-                    &can_be_added_destructured.opening.role_staking_policy,
-                );
-
-            // Fetch application
-            let crowded_out_application = <ApplicationById<T>>::get(id_of_croweded_out_application);
-
-            // Initiate actual deactivation
-            //
-            // MUST not have been ignored, is runtime invariant, false means code is broken.
-            // But should we do panic in runtime? Is there safer way?
-            let deactivation_result = Self::try_to_initiate_application_deactivation(
-                &crowded_out_application,
-                id_of_croweded_out_application,
-                opt_application_stake_unstaking_period,
-                opt_role_stake_unstaking_period,
-                hiring::ApplicationDeactivationCause::CrowdedOut,
-            );
-
-            assert_ne!(
-                deactivation_result,
-                ApplicationDeactivationInitiationResult::Ignored
-            );
-        }
-
-        // Get Id for this new application
-        let new_application_id = <NextApplicationId<T>>::get();
-
-        // Possibly initiate staking
-        let active_role_staking_id =
-            Self::infallible_opt_stake_initiation(opt_role_stake_imbalance, &new_application_id);
-        let active_application_staking_id = Self::infallible_opt_stake_initiation(
-            opt_application_stake_imbalance,
-            &new_application_id,
-        );
-
-        // Grab current block height
-        let current_block_height = <frame_system::Module<T>>::block_number();
-
-        // Compute index for this new application
-        let application_index_in_opening =
-            can_be_added_destructured.calculate_total_application_count();
-
-        // Create a new application
-        let new_application = hiring::Application {
-            opening_id,
-            application_index_in_opening,
-            add_to_opening_in_block: current_block_height,
-            active_role_staking_id,
-            active_application_staking_id,
-            // Stage of new application
-            stage: hiring::ApplicationStage::Active,
-            human_readable_text,
-        };
-
-        // Insert into main application map
-        <ApplicationById<T>>::insert(new_application_id, new_application);
-
-        // Update next application id
-        <NextApplicationId<T>>::mutate(|id| *id += One::one());
-
-        // Update counter on opening
-        // Should reload after possible deactivation in try_to_initiate_application_deactivation
-        let opening_needed_for_data = <OpeningById<T>>::get(opening_id);
-        let new_active_stage = opening_needed_for_data
-            .stage
-            .clone_with_added_active_application(new_application_id);
-
-        <OpeningById<T>>::mutate(opening_id, |opening| {
-            opening.stage = new_active_stage;
-        });
-
-        let application_id_crowded_out = can_be_added_destructured
-            .would_get_added_success
-            .crowded_out_application_id();
-
-        // DONE
-        Ok(ApplicationAdded {
-            application_id_added: new_application_id,
-            application_id_crowded_out,
-        })
-    }
-
-    /// Deactive an active application.
-    /// Does currently not support slashing
-    pub fn deactive_application(
-        application_id: T::ApplicationId,
-        application_stake_unstaking_period: Option<T::BlockNumber>,
-        role_stake_unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), DeactivateApplicationError> {
-        // Check that application id is valid, and if so,
-        // grab corresponding application and opening.
-        let (application, opening) = ensure_application_exists!(
-            T,
-            application_id,
-            DeactivateApplicationError::ApplicationDoesNotExist,
-            auto_fetch_opening
-        )?;
-
-        // Application is active
-        ensure_eq!(
-            application.stage,
-            hiring::ApplicationStage::Active,
-            DeactivateApplicationError::ApplicationNotActive
-        );
-
-        // Opening is accepting applications
-        let (active_stage, ..) = ensure_opening_is_active!(
-            opening.stage,
-            DeactivateApplicationError::OpeningNotAcceptingApplications
-        )?;
-
-        active_stage.ensure_active_opening_is_accepting_applications(
-            DeactivateApplicationError::OpeningNotAcceptingApplications,
-        )?;
-
-        // Ensure unstaking periods are OK.
-        ensure_opt_unstaking_period_is_ok!(
-            application_stake_unstaking_period,
-            opening.application_staking_policy,
-            DeactivateApplicationError::UnstakingPeriodTooShort(StakePurpose::Application),
-            DeactivateApplicationError::RedundantUnstakingPeriodProvided(StakePurpose::Application)
-        )?;
-
-        ensure_opt_unstaking_period_is_ok!(
-            role_stake_unstaking_period,
-            opening.role_staking_policy,
-            DeactivateApplicationError::UnstakingPeriodTooShort(StakePurpose::Role),
-            DeactivateApplicationError::RedundantUnstakingPeriodProvided(StakePurpose::Role)
-        )?;
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        // Deactive application
-        let result = Self::try_to_initiate_application_deactivation(
-            &application,
-            application_id,
-            application_stake_unstaking_period,
-            role_stake_unstaking_period,
-            hiring::ApplicationDeactivationCause::External,
-        );
-
-        assert_ne!(result, ApplicationDeactivationInitiationResult::Ignored);
-
-        // DONE
-        Ok(())
-    }
-
-    /// The stake, with the given id, was unstaked.
-    pub fn unstaked(stake_id: T::StakeId) -> UnstakedResult {
-        // Ignore unstaked
-        if !<ApplicationIdByStakingId<T>>::contains_key(stake_id) {
-            return UnstakedResult::StakeIdNonExistent;
-        }
-
-        // Get application
-        let application_id = <ApplicationIdByStakingId<T>>::get(stake_id);
-
-        assert!(<ApplicationById<T>>::contains_key(application_id));
-
-        let application = <ApplicationById<T>>::get(application_id);
-
-        // Make sure that we are actually unstaking, ignore otherwise.
-        let (deactivation_initiated, cause) = if let ApplicationStage::Unstaking {
-            deactivation_initiated,
-            cause,
-        } = application.stage
-        {
-            (deactivation_initiated, cause)
-        } else {
-            return UnstakedResult::ApplicationIsNotUnstaking;
-        };
-
-        //
-        // == MUTATION SAFE ==
-        //
-
-        // Drop stake from stake to application map
-        <ApplicationIdByStakingId<T>>::remove(stake_id);
-        let current_block_height = <frame_system::Module<T>>::block_number();
-
-        // New application computed
-        let mut new_application = application.clone();
-        let is_now_done_unstaking = new_application.unstake_application(
-            current_block_height,
-            deactivation_initiated,
-            cause,
-            stake_id,
-        );
-
-        // Update to new application
-        <ApplicationById<T>>::insert(&application_id, new_application);
-
-        // If the application is now finished compeleting any pending unstaking process,
-        // then we need to update the opening counters, and make the deactivation callback.
-        if is_now_done_unstaking {
-            // Update Opening
-            // We know the stage MUST be active, hence mutate is certain.
-            <OpeningById<T>>::mutate(application.opening_id, |opening| {
-                opening.change_opening_stage_after_application_unstaked();
-            });
-
-            // Call handler
-            T::ApplicationDeactivatedHandler::deactivated(&application_id, cause);
-            return UnstakedResult::Unstaked;
-        }
-
-        UnstakedResult::UnstakingInProgress
-    }
-}
-
-/*
- *  === Application Deactivated Handler  ======
- */
-
-/// Handles application deactivation with a cause
-pub trait ApplicationDeactivatedHandler<T: Trait> {
-    /// An application, with the given id, was fully deactivated, with the
-    /// given cause, and was put in the inactive state.
-    fn deactivated(application_id: &T::ApplicationId, cause: hiring::ApplicationDeactivationCause);
-}
-
-/// Helper implementation so we can provide multiple handlers by grouping handlers in tuple pairs.
-/// For example for three handlers, A, B and C we can set the StakingEventHandler type on the trait to:
-/// type StakingEventHandler = ((A, B), C)
-impl<T: Trait> ApplicationDeactivatedHandler<T> for () {
-    fn deactivated(
-        _application_id: &T::ApplicationId,
-        _cause: hiring::ApplicationDeactivationCause,
-    ) {
-    }
-}
-
-/*
- *  ======== API types bound to the Trait ========
- */
-
-/// Error due to attempting to fill an opening.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum FillOpeningError<T: Trait> {
-    /// Opening does not exist
-    OpeningDoesNotExist,
-
-    /// Opening is not in review period
-    OpeningNotInReviewPeriodStage,
-
-    /// Provided unstaking period is too short
-    UnstakingPeriodTooShort(StakePurpose, ApplicationOutcomeInFilledOpening),
-
-    /// Provided redundant unstaking period
-    RedundantUnstakingPeriodProvided(StakePurpose, ApplicationOutcomeInFilledOpening),
-
-    /// Application does not exist
-    ApplicationDoesNotExist(T::ApplicationId),
-
-    /// Application is not in active stage
-    ApplicationNotInActiveStage(T::ApplicationId),
-
-    /// Application is not for the opening
-    ApplicationForWrongOpening(T::ApplicationId),
-}
-
-/// Product of ensure_can_add_application()
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub struct DestructuredApplicationCanBeAddedEvaluation<T: Trait> {
-    /// Opening object
-    pub opening: Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>,
-
-    /// Active opening stage
-    pub active_stage: ActiveOpeningStage<T::BlockNumber>,
-
-    /// Collection of added applicaiton ids
-    pub applications_added: BTreeSet<T::ApplicationId>,
-
-    /// Active applications counter
-    pub active_application_count: u32,
-
-    /// Unstaking applications counter
-    pub unstaking_application_count: u32,
-
-    /// Deactivated applications counter
-    pub deactivated_application_count: u32,
-
-    /// Prospects of application adding
-    pub would_get_added_success: ApplicationAddedSuccess<T>,
-}
-
-impl<T: Trait> DestructuredApplicationCanBeAddedEvaluation<T> {
-    pub(crate) fn calculate_total_application_count(&self) -> u32 {
-        // TODO: fix so that `number_of_appliations_ever_added` can be invoked.
-        // cant do this due to bad design of stage => opening.stage.number_of_appliations_ever_added();
-        self.active_application_count
-            + self.unstaking_application_count
-            + self.deactivated_application_count
-    }
-}
-
-/// Adding application result
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum ApplicationAddedSuccess<T: Trait> {
-    /// Application was added without side-effects
-    Unconditionally,
-
-    /// Application has crowded out existing application
-    CrowdsOutExistingApplication(T::ApplicationId),
-}
-
-impl<T: Trait> ApplicationAddedSuccess<T> {
-    pub(crate) fn crowded_out_application_id(&self) -> Option<T::ApplicationId> {
-        if let ApplicationAddedSuccess::CrowdsOutExistingApplication(id) = self {
-            Some(*id)
-        } else {
-            None
-        }
-    }
-}
-
-/// Prospects of application. Whether it would be added to the opening.
-#[derive(Eq, PartialEq, Clone, Debug)]
-pub enum ApplicationWouldGetAddedEvaluation<T: Trait> {
-    /// Negative prospects
-    No,
-
-    /// Positive prospects
-    Yes(ApplicationAddedSuccess<T>),
-}
-
-/// Balance alias
-pub type BalanceOf<T> =
-    <<T as stake::Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
-
-/// Balance alias for staking
-pub type NegativeImbalance<T> = <<T as stake::Trait>::Currency as Currency<
-    <T as frame_system::Trait>::AccountId,
->>::NegativeImbalance;
-
-/*
- *  ======== ======== ======== ======== =======
- *  ======== PRIVATE TYPES AND METHODS ========
- *  ======== ======== ======== ======== =======
- */
-
-#[derive(PartialEq, Debug, Clone)]
-struct ApplicationsDeactivationsInitiationResult {
-    number_of_unstaking_applications: u32,
-    number_of_deactivated_applications: u32,
-}
-
-type ApplicationBTreeMap<T> = BTreeMap<
-    <T as Trait>::ApplicationId,
-    hiring::Application<
-        <T as Trait>::OpeningId,
-        <T as frame_system::Trait>::BlockNumber,
-        <T as stake::Trait>::StakeId,
-    >,
->;
-
-#[derive(PartialEq, Debug, Clone)]
-enum ApplicationDeactivationInitiationResult {
-    Ignored, // <= is there a case for kicking this out, making sure that initiation cannot happen when it may fail?
-    Unstaking,
-    Deactivated,
-}
-
-// Opening and application iterators
-impl<T: Trait> Module<T> {
-    // Iterate through ApplicationById map
-    fn application_id_iter_to_map<'a>(
-        application_id_iter: impl Iterator<Item = &'a T::ApplicationId>,
-    ) -> ApplicationBTreeMap<T> {
-        application_id_iter
-            .map(|application_id| {
-                let application = <ApplicationById<T>>::get(application_id);
-
-                (*application_id, application)
-            })
-            .collect::<BTreeMap<_, _>>()
-    }
-
-    // Compute iterator of openings waiting to begin
-    fn openings_waiting_to_begin_iterator(
-        now: T::BlockNumber,
-    ) -> impl Iterator<
-        Item = (
-            T::OpeningId,
-            Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>,
-        ),
-    > {
-        <OpeningById<T>>::iter().filter_map(move |(opening_id, opening)| {
-            if let hiring::OpeningStage::WaitingToBegin { begins_at_block } = opening.stage {
-                if begins_at_block == now {
-                    Some((opening_id, opening))
-                } else {
-                    None
-                }
-            } else {
-                None
-            }
-        })
-    }
-
-    // Compute iterator of openings in expired review period
-    fn openings_expired_review_period_iterator(
-        now: T::BlockNumber,
-    ) -> impl Iterator<
-        Item = (
-            T::OpeningId,
-            Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>,
-            (BTreeSet<T::ApplicationId>, T::BlockNumber, T::BlockNumber),
-        ),
-    > {
-        <OpeningById<T>>::iter().filter_map(move |(opening_id, opening)| {
-            if let hiring::OpeningStage::Active {
-                ref stage,
-                ref applications_added,
-                ..
-            } = opening.stage
-            {
-                if let hiring::ActiveOpeningStage::ReviewPeriod {
-                    ref started_accepting_applicants_at_block,
-                    ref started_review_period_at_block,
-                } = stage
-                {
-                    if now == opening.max_review_period_length + *started_review_period_at_block {
-                        Some((
-                            opening_id,
-                            opening.clone(),
-                            (
-                                applications_added.clone(),
-                                *started_accepting_applicants_at_block,
-                                *started_review_period_at_block,
-                            ),
-                        ))
-                    } else {
-                        None
-                    }
-                } else {
-                    None
-                }
-            } else {
-                None
-            }
-        })
-    }
-}
-
-// Application deactivation logic methods.
-impl<T: Trait> Module<T> {
-    fn initiate_application_deactivations(
-        applications: &ApplicationBTreeMap<T>,
-        application_stake_unstaking_period: Option<T::BlockNumber>,
-        role_stake_unstaking_period: Option<T::BlockNumber>,
-        cause: ApplicationDeactivationCause,
-    ) -> ApplicationsDeactivationsInitiationResult {
-        // Update stage on active applications, and collect result
-
-        applications
-            .iter()
-            .map(
-                |(application_id, application)| -> ApplicationDeactivationInitiationResult {
-                    // Initiate deactivations!
-                    Self::try_to_initiate_application_deactivation(
-                        application,
-                        *application_id,
-                        application_stake_unstaking_period,
-                        role_stake_unstaking_period,
-                        cause,
-                    )
-                },
-            )
-            .fold(
-                // Initiatial reducer value
-                ApplicationsDeactivationsInitiationResult {
-                    number_of_unstaking_applications: 0,
-                    number_of_deactivated_applications: 0,
-                },
-                |acc, deactivation_result| {
-                    // Update accumulator counters based on what actually happened
-                    match deactivation_result {
-                        ApplicationDeactivationInitiationResult::Ignored => acc,
-
-                        ApplicationDeactivationInitiationResult::Unstaking => {
-                            ApplicationsDeactivationsInitiationResult {
-                                number_of_unstaking_applications: 1 + acc
-                                    .number_of_unstaking_applications,
-                                number_of_deactivated_applications: acc
-                                    .number_of_deactivated_applications,
-                            }
-                        }
-
-                        ApplicationDeactivationInitiationResult::Deactivated => {
-                            ApplicationsDeactivationsInitiationResult {
-                                number_of_unstaking_applications: acc
-                                    .number_of_unstaking_applications,
-                                number_of_deactivated_applications: 1 + acc
-                                    .number_of_deactivated_applications,
-                            }
-                        }
-                    }
-                },
-            )
-    }
-
-    /// Initiates
-    fn try_to_initiate_application_deactivation(
-        application: &Application<T::OpeningId, T::BlockNumber, T::StakeId>,
-        application_id: T::ApplicationId,
-        application_stake_unstaking_period: Option<T::BlockNumber>,
-        role_stake_unstaking_period: Option<T::BlockNumber>,
-        cause: hiring::ApplicationDeactivationCause,
-    ) -> ApplicationDeactivationInitiationResult {
-        match application.stage {
-            ApplicationStage::Active => {
-                // Initiate unstaking of any active application stake
-                let application_was_unstaked = Self::opt_infallible_unstake(
-                    application.active_application_staking_id,
-                    application_stake_unstaking_period,
-                );
-
-                // Only unstake role stake for a non successful result ie. not Hired
-                let role_was_unstaked = cause != hiring::ApplicationDeactivationCause::Hired
-                    && Self::opt_infallible_unstake(
-                        application.active_role_staking_id,
-                        role_stake_unstaking_period,
-                    );
-
-                // Capture if any unstaking occured at all
-                let was_unstaked = application_was_unstaked || role_was_unstaked;
-
-                // Grab current block height
-                let current_block_height = <frame_system::Module<T>>::block_number();
-
-                /*
-                 * TODO:
-                 * There should be a single transformation based on
-                 * was_unstaked which renders a new value for `application.stage`
-                 * and `opening.stage`, which guarantees to only produces new values
-                 * for given variant values, but the state machine types are currently
-                 * not well organised to support this.
-                 *
-                 * Likewise the construction of hiring::OpeningStage::Active below
-                 * is a wreck because of this.
-                 *
-                 * Issue: https://github.com/Joystream/joystream/issues/36#issuecomment-539567407
-                 */
-
-                // Figure out new stage for the application
-                let new_application_stage = if was_unstaked {
-                    ApplicationStage::Unstaking {
-                        deactivation_initiated: current_block_height,
-                        cause,
-                    }
-                } else {
-                    ApplicationStage::Inactive {
-                        deactivation_initiated: current_block_height,
-                        deactivated: current_block_height,
-                        cause,
-                    }
-                };
-
-                // Update the application stage
-                <ApplicationById<T>>::mutate(application_id, |application| {
-                    application.stage = new_application_stage;
-                });
-
-                // Update counters on opening
-                <OpeningById<T>>::mutate(application.opening_id, |opening| {
-                    // NB: This ugly byref destructuring is same issue as pointed out multiple times now.
-                    if let hiring::OpeningStage::Active {
-                        ref stage,
-                        ref applications_added,
-                        ref active_application_count,
-                        ref unstaking_application_count,
-                        ref deactivated_application_count,
-                    } = opening.stage
-                    {
-                        assert!(*active_application_count > 0);
-
-                        let new_active_application_count = active_application_count - 1;
-
-                        let new_unstaking_application_count =
-                            unstaking_application_count + if was_unstaked { 1 } else { 0 };
-
-                        let new_deactivated_application_count =
-                            deactivated_application_count + if was_unstaked { 0 } else { 1 };
-
-                        opening.stage = hiring::OpeningStage::Active {
-                            stage: stage.clone(),
-                            applications_added: applications_added.clone(),
-                            active_application_count: new_active_application_count,
-                            unstaking_application_count: new_unstaking_application_count,
-                            deactivated_application_count: new_deactivated_application_count,
-                        };
-                    } else {
-                        panic!("opening stage must be 'Active'");
-                    }
-                });
-
-                // Call handler(s)
-                if was_unstaked {
-                    T::ApplicationDeactivatedHandler::deactivated(&application_id, cause);
-                }
-
-                // Return conclusion
-                if was_unstaked {
-                    ApplicationDeactivationInitiationResult::Unstaking
-                } else {
-                    ApplicationDeactivationInitiationResult::Deactivated
-                }
-            }
-            _ => ApplicationDeactivationInitiationResult::Ignored,
-        }
-    }
-
-    /// Tries to unstake, based on a stake id which, if set, MUST
-    /// be ready to be unstaked, with an optional unstaking period.
-    ///
-    /// Returns whether unstaking was actually initiated.
-    fn opt_infallible_unstake(
-        opt_stake_id: Option<T::StakeId>,
-        opt_unstaking_period: Option<T::BlockNumber>,
-    ) -> bool {
-        if let Some(stake_id) = opt_stake_id {
-            // `initiate_unstaking` MUST hold, is runtime invariant, false means code is broken.
-            // But should we do panic in runtime? Is there safer way?
-
-            assert!(T::StakeHandlerProvider::staking()
-                .initiate_unstaking(&stake_id, opt_unstaking_period)
-                .is_ok());
-        }
-
-        opt_stake_id.is_some()
-    }
-}
-
-// Stake initiation
-impl<T: Trait> Module<T> {
-    fn infallible_opt_stake_initiation(
-        opt_imbalance: Option<NegativeImbalance<T>>,
-        application_id: &T::ApplicationId,
-    ) -> Option<T::StakeId> {
-        if let Some(imbalance) = opt_imbalance {
-            Some(Self::infallible_stake_initiation_on_application(
-                imbalance,
-                application_id,
-            ))
-        } else {
-            None
-        }
-    }
-
-    fn infallible_stake_initiation_on_application(
-        imbalance: NegativeImbalance<T>,
-        application_id: &T::ApplicationId,
-    ) -> T::StakeId {
-        // Create stake
-        let new_stake_id = T::StakeHandlerProvider::staking().create_stake();
-
-        // Keep track of this stake id to process unstaking callbacks that may
-        // be invoked later.
-        // NB: We purposefully update state to reflect mapping _before_ initiating staking below
-        // in order to be safe from race conditions arising out of third party code executing in callback of staking module.
-
-        // MUST never already be a key for new stake, false means code is broken.
-        // But should we do panic in runtime? Is there safer way?
-        assert!(!<ApplicationIdByStakingId<T>>::contains_key(new_stake_id));
-
-        <ApplicationIdByStakingId<T>>::insert(new_stake_id, application_id);
-
-        // Initiate staking
-        //
-        // MUST work, is runtime invariant, false means code is broken.
-        // But should we do panic in runtime? Is there safer way?
-        assert_eq!(
-            T::StakeHandlerProvider::staking().stake(&new_stake_id, imbalance),
-            Ok(())
-        );
-
-        new_stake_id
-    }
-}
-
-// Conditions for adding application
-impl<T: Trait> Module<T> {
-    /// Evaluates prospects for a new application
-    ///
-    pub(crate) fn would_application_get_added(
-        possible_opening_application_rationing_policy: &Option<ApplicationRationingPolicy>,
-        opening_applicants: &BTreeSet<T::ApplicationId>,
-        opt_role_stake_balance: &Option<BalanceOf<T>>,
-        opt_application_stake_balance: &Option<BalanceOf<T>>,
-    ) -> ApplicationWouldGetAddedEvaluation<T> {
-        // Check whether any rationing policy is set at all, if not
-        // then there is no rationing, and any application can get added.
-        let application_rationing_policy = if let Some(application_rationing_policy) =
-            possible_opening_application_rationing_policy
-        {
-            application_rationing_policy
-        } else {
-            return ApplicationWouldGetAddedEvaluation::Yes(
-                ApplicationAddedSuccess::Unconditionally,
-            );
-        };
-
-        // Map with applications
-        let applications_map = Self::application_id_iter_to_map(opening_applicants.iter());
-
-        let active_applications_with_stake_iter =
-            applications_map
-                .iter()
-                .filter_map(|(application_id, application)| {
-                    if application.stage == hiring::ApplicationStage::Active {
-                        let total_stake =
-                            Self::get_opt_stake_amount(application.active_role_staking_id)
-                                + Self::get_opt_stake_amount(
-                                    application.active_application_staking_id,
-                                );
-
-                        Some((application_id, application, total_stake))
-                    } else {
-                        None
-                    }
-                });
-
-        // Compute number of active applications
-        let number_of_active_applications = active_applications_with_stake_iter.clone().count();
-
-        // Check whether the current number of _active_ applicants is either at or above the maximum
-        // limit, if not, then we can add at least one additional application,
-        // otherwise we must evaluate whether this new application would specifically get added.
-        if (number_of_active_applications as u32)
-            < application_rationing_policy.max_active_applicants
-        {
-            return ApplicationWouldGetAddedEvaluation::Yes(
-                ApplicationAddedSuccess::Unconditionally,
-            );
-        }
-
-        // Here we try to figure out if the new application
-        // has sufficient stake to crowd out one of the already
-        // active applicants.
-
-        // The total stake of new application
-        let total_stake_of_new_application = opt_role_stake_balance.unwrap_or_default()
-            + opt_application_stake_balance.unwrap_or_default();
-
-        // The total stake of all current active applications
-        let opt_min_item = active_applications_with_stake_iter
-            .clone()
-            .min_by_key(|(_, _, total_stake)| *total_stake);
-
-        if let Some((application_id, _, lowest_active_total_stake)) = opt_min_item {
-            // Finally we compare the two and come up with a final evaluation
-            if total_stake_of_new_application <= lowest_active_total_stake {
-                ApplicationWouldGetAddedEvaluation::No // stake too low!
-            } else {
-                ApplicationWouldGetAddedEvaluation::Yes(
-                    ApplicationAddedSuccess::CrowdsOutExistingApplication(*application_id),
-                )
-            }
-        } else {
-            panic!("`number_of_active_applications` (length of `active_applications_iter`) == 0")
-        }
-    }
-
-    fn get_opt_stake_amount(stake_id: Option<T::StakeId>) -> BalanceOf<T> {
-        stake_id.map_or(<BalanceOf<T> as Zero>::zero(), |stake_id| {
-            // INVARIANT: stake MUST exist in the staking module
-            assert!(T::StakeHandlerProvider::staking().stake_exists(stake_id));
-
-            let stake = T::StakeHandlerProvider::staking().get_stake(stake_id);
-
-            match stake.staking_status {
-                // INVARIANT: stake MUST be in the staked state.
-                stake::StakingStatus::Staked(staked_state) => staked_state.staked_amount,
-                _ => panic!("stake MUST be in the staked state."),
-            }
-        })
-    }
-
-    pub(crate) fn create_stake_balance(
-        opt_stake_imbalance: &Option<NegativeImbalance<T>>,
-    ) -> Option<BalanceOf<T>> {
-        if let Some(ref imbalance) = opt_stake_imbalance {
-            Some(imbalance.peek())
-        } else {
-            None
-        }
-    }
-
-    /// Performs all necessary check before adding an opening
-    pub(crate) fn ensure_can_add_opening(
-        current_block_height: T::BlockNumber,
-        activate_at: ActivateOpeningAt<T::BlockNumber>,
-        minimum_stake_balance: BalanceOf<T>,
-        application_rationing_policy: Option<ApplicationRationingPolicy>,
-        application_staking_policy: Option<StakingPolicy<BalanceOf<T>, T::BlockNumber>>,
-        role_staking_policy: Option<StakingPolicy<BalanceOf<T>, T::BlockNumber>>,
-    ) -> Result<(), AddOpeningError> {
-        // Check that exact activation is actually in the future
-        ensure!(
-            match activate_at {
-                ActivateOpeningAt::ExactBlock(block_number) => block_number > current_block_height,
-                _ => true,
-            },
-            AddOpeningError::OpeningMustActivateInTheFuture
-        );
-
-        if let Some(app_rationing_policy) = application_rationing_policy {
-            ensure!(
-                app_rationing_policy.max_active_applicants > 0,
-                AddOpeningError::ApplicationRationingZeroMaxApplicants
-            );
-        }
-
-        // Check that staking amounts clear minimum balance required.
-        Self::ensure_amount_valid_in_opt_staking_policy(
-            application_staking_policy,
-            minimum_stake_balance,
-            StakePurpose::Application,
-        )?;
-
-        // Check that staking amounts clear minimum balance required.
-        Self::ensure_amount_valid_in_opt_staking_policy(
-            role_staking_policy,
-            minimum_stake_balance,
-            StakePurpose::Role,
-        )?;
-
-        Ok(())
-    }
-
-    /// Ensures that optional staking policy prescribes value that clears minimum balance requirement
-    pub(crate) fn ensure_amount_valid_in_opt_staking_policy(
-        opt_staking_policy: Option<StakingPolicy<BalanceOf<T>, T::BlockNumber>>,
-        minimum_stake_balance: BalanceOf<T>,
-        stake_purpose: StakePurpose,
-    ) -> Result<(), AddOpeningError> {
-        if let Some(ref staking_policy) = opt_staking_policy {
-            ensure!(
-                staking_policy.amount > Zero::zero(),
-                AddOpeningError::StakeAmountCannotBeZero(stake_purpose)
-            );
-
-            ensure!(
-                staking_policy.amount >= minimum_stake_balance,
-                AddOpeningError::StakeAmountLessThanMinimumStakeBalance(stake_purpose)
-            );
-        }
-
-        Ok(())
-    }
-}
-
-/*
- *  === Stake module wrappers  ======
- */
-
-/// Defines stake module interface
-#[cfg_attr(all(test, not(target_arch = "wasm32")), automock)]
-pub trait StakeHandler<T: StakeTrait> {
-    /// Adds a new Stake which is NotStaked, created at given block, into stakes map.
-    fn create_stake(&self) -> T::StakeId;
-
-    /// to the module's account, and the corresponding staked_balance is set to this amount in the new Staked state.
-    /// On error, as the negative imbalance is not returned to the caller, it is the caller's responsibility to return the funds
-    /// back to the source (by creating a new positive imbalance)
-    fn stake(
-        &self,
-        new_stake_id: &T::StakeId,
-        imbalance: NegativeImbalance<T>,
-    ) -> Result<(), StakeActionError<stake::StakingError>>;
-
-    /// Checks whether stake exists by its id
-    fn stake_exists(&self, stake_id: T::StakeId) -> bool;
-
-    /// Acquires stake by id
-    fn get_stake(&self, stake_id: T::StakeId) -> Stake<T::BlockNumber, BalanceOf<T>, T::SlashId>;
-
-    /// Initiate unstaking of a Staked stake.
-    fn initiate_unstaking(
-        &self,
-        stake_id: &T::StakeId,
-        unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), StakeActionError<InitiateUnstakingError>>;
-}
-
-/// Allows to provide different StakeHandler implementation. Useful for mocks.
-pub trait StakeHandlerProvider<T: Trait> {
-    /// Returns StakeHandler. Mock entry point for stake module.
-    fn staking() -> Rc<RefCell<dyn StakeHandler<T>>>;
-}
-
-impl<T: Trait> StakeHandlerProvider<T> for Module<T> {
-    /// Returns StakeHandler. Mock entry point for stake module.
-    fn staking() -> Rc<RefCell<dyn StakeHandler<T>>> {
-        Rc::new(RefCell::new(HiringStakeHandler {}))
-    }
-}
-
-/// Default stake module logic implementation
-pub struct HiringStakeHandler;
-impl<T: Trait> StakeHandler<T> for HiringStakeHandler {
-    fn create_stake(&self) -> T::StakeId {
-        <stake::Module<T>>::create_stake()
-    }
-
-    fn stake(
-        &self,
-        new_stake_id: &T::StakeId,
-        imbalance: NegativeImbalance<T>,
-    ) -> Result<(), StakeActionError<StakingError>> {
-        <stake::Module<T>>::stake(new_stake_id, imbalance)
-    }
-
-    fn stake_exists(&self, stake_id: T::StakeId) -> bool {
-        <stake::Stakes<T>>::contains_key(stake_id)
-    }
-
-    fn get_stake(&self, stake_id: T::StakeId) -> Stake<T::BlockNumber, BalanceOf<T>, T::SlashId> {
-        <stake::Stakes<T>>::get(stake_id)
-    }
-
-    fn initiate_unstaking(
-        &self,
-        stake_id: &T::StakeId,
-        unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), StakeActionError<InitiateUnstakingError>> {
-        <stake::Module<T>>::initiate_unstaking(&stake_id, unstaking_period)
-    }
-}
-
-// Proxy implementation of StakeHandler trait to simplify calls via staking() method
-// Allows to get rid of borrow() calls,
-// eg.: T::StakeHandlerProvider::staking().get_stake(stake_id);
-// instead of T::StakeHandlerProvider::staking().borrow().get_stake(stake_id);
-impl<T: Trait> StakeHandler<T> for Rc<RefCell<dyn StakeHandler<T>>> {
-    fn create_stake(&self) -> T::StakeId {
-        self.borrow().create_stake()
-    }
-
-    fn stake(
-        &self,
-        new_stake_id: &T::StakeId,
-        imbalance: NegativeImbalance<T>,
-    ) -> Result<(), StakeActionError<StakingError>> {
-        self.borrow().stake(new_stake_id, imbalance)
-    }
-
-    fn stake_exists(&self, stake_id: T::StakeId) -> bool {
-        self.borrow().stake_exists(stake_id)
-    }
-
-    fn get_stake(&self, stake_id: T::StakeId) -> Stake<T::BlockNumber, BalanceOf<T>, T::SlashId> {
-        self.borrow().get_stake(stake_id)
-    }
-
-    fn initiate_unstaking(
-        &self,
-        stake_id: &T::StakeId,
-        unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), StakeActionError<InitiateUnstakingError>> {
-        self.borrow().initiate_unstaking(stake_id, unstaking_period)
-    }
-}

+ 0 - 188
runtime-modules/hiring/src/macroes.rs

@@ -1,188 +0,0 @@
-/// TODO: Move into Substrate-utility library
-/// Ensure that two expressions are equal.
-macro_rules! ensure_eq {
-    ($left:expr, $right:expr, $error:expr) => {
-        ensure!(($left) == ($right), $error)
-    };
-}
-
-/// TODO: Move into Substrate-utility library
-/// Ensure that a storage map, with a given name, has mapping for the given key value.
-macro_rules! ensure_map_key {
-    ($map_variable_name:ident , $runtime_trait:tt, $key:expr, $error:expr) => {{
-        if <$map_variable_name<$runtime_trait>>::contains_key($key) {
-            let value = <$map_variable_name<$runtime_trait>>::get($key);
-
-            Ok(value)
-        } else {
-            Err($error)
-        }
-    }};
-}
-
-/// Ensure that an opening exists in `OpeningnById`, and if so, return it.
-///
-/// Returns
-/// - `Ok(opening)` where `opening` is the opening, if it exists.
-/// - `Err($error)` otherwise
-macro_rules! ensure_opening_exists {
-    ($runtime_trait:tt, $opening_id:expr, $error:expr) => {{
-        ensure_map_key!(OpeningById, $runtime_trait, $opening_id, $error)
-    }};
-}
-
-/// Ensure that an applications exists in `ApplicationById` , and if so, return it along with the
-/// corresponding opening.
-macro_rules! ensure_application_exists {
-    ($runtime_trait:tt, $application_id:expr, $error:expr) => {{
-        ensure_map_key!(ApplicationById, $runtime_trait, $application_id, $error)
-    }};
-
-    ($runtime_trait:tt, $application_id:expr, $error:expr, auto_fetch_opening) => {{
-        ensure_application_exists!($runtime_trait, $application_id, $error).and_then(
-            |application| {
-                // Grab corresponding opening, which MUST exist.
-                let opening = <OpeningById<$runtime_trait>>::get(application.opening_id);
-
-                // Return both
-                Ok((application, opening))
-            },
-        )
-    }};
-}
-
-/// Ensures that an opening is active.
-macro_rules! ensure_opening_is_active {
-    ($stage:expr, $error:expr) => {{
-        match $stage {
-            hiring::OpeningStage::Active {
-                // <= need proper type here in the future, not param
-                ref stage,
-                ref applications_added,
-                ref active_application_count,
-                ref unstaking_application_count,
-                ref deactivated_application_count,
-            } => Ok((
-                stage.clone(),
-                applications_added.clone(),
-                active_application_count.clone(),
-                unstaking_application_count.clone(),
-                deactivated_application_count.clone(),
-            )),
-            _ => Err($error),
-        }
-    }};
-}
-
-/// Ensures that active opening stage is accepting applications.
-macro_rules! ensure_active_opening_is_accepting_applications {
-
-    ($stage:expr, $error:expr) => {{
-
-        match $stage {
-            hiring::ActiveOpeningStage::AcceptingApplications {
-                started_accepting_applicants_at_block
-            } => Ok(started_accepting_applicants_at_block), // <= need proper type here in the future, not param
-            _ => Err($error),
-        }
-    }}
-}
-
-/// Ensures that optional imbalance matches requirements of optional staking policy
-macro_rules! ensure_stake_balance_matches_staking_policy {
-    (
-        $opt_balance:expr,
-        $opt_policy: expr,
-        $stake_missing_when_required_error:expr,
-        $stake_provided_when_redundant_error:expr,
-        $stake_amount_too_low_error:expr
-
-    ) => {{
-        if let Some(ref balance) = $opt_balance {
-            if let Some(ref policy) = $opt_policy {
-                if !policy.accepts_amount(balance) {
-                    Err($stake_amount_too_low_error)
-                } else {
-                    Ok(Some(balance.clone()))
-                }
-            } else {
-                Err($stake_provided_when_redundant_error)
-            }
-        } else if $opt_policy.is_some() {
-            Err($stake_missing_when_required_error)
-        } else {
-            Ok(None)
-        }
-    }};
-}
-
-/// Ensures that an optional unstaking period is at least one block whens set.
-macro_rules! _ensure_opt_unstaking_period_not_zero {
-    ($opt_period:expr, $error:expr) => {{
-        if let Some(ref length) = $opt_period {
-            let lower_bound = One::one();
-
-            if *length < lower_bound {
-                Err($error)
-            } else {
-                Ok(())
-            }
-        } else {
-            Ok(())
-        }
-    }};
-}
-
-/// Ensures that provided unstaking period is not redundant
-macro_rules! _ensure_opt_unstaking_period_not_redundant {
-    (
-        $opt_policy:expr,
-        $opt_staking_period:expr,
-        $error:expr
-    ) => {{
-        if $opt_policy.is_some() || $opt_staking_period.is_none() {
-            Ok(())
-        } else {
-            Err($error)
-        }
-    }};
-}
-
-/// Ensures that provided unstaking period is valid
-macro_rules! ensure_opt_unstaking_period_is_ok {
-    (
-        $opt_staking_period:expr,
-        $opt_staking_policy:expr,
-        $period_zero_error:expr,
-        $period_redundant_error:expr
-    ) => {{
-        _ensure_opt_unstaking_period_not_zero!($opt_staking_period, $period_zero_error).and(
-            _ensure_opt_unstaking_period_not_redundant!(
-                $opt_staking_policy,
-                $opt_staking_period,
-                $period_redundant_error
-            ),
-        )
-    }};
-}
-
-/// Ensures that a new application would make it into a given opening
-macro_rules! ensure_application_would_get_added {
-    (
-        $opt_staking_policy:expr,
-        $applicants:expr,
-        $opt_role_stake_balance:expr,
-        $opt_application_stake_balance:expr,
-        $error:expr) => {{
-        match Self::would_application_get_added(
-            $opt_staking_policy,
-            $applicants,
-            $opt_role_stake_balance,
-            $opt_application_stake_balance,
-        ) {
-            // Would get added indeed!
-            ApplicationWouldGetAddedEvaluation::Yes(success) => Ok(success),
-            _ => Err($error),
-        }
-    }};
-}

+ 0 - 201
runtime-modules/hiring/src/mock.rs

@@ -1,201 +0,0 @@
-#![cfg(test)]
-
-use frame_support::{impl_outer_origin, parameter_types};
-use sp_core::H256;
-use sp_runtime::{
-    testing::Header,
-    traits::{BlakeTwo256, IdentityLookup},
-    Perbill,
-};
-use sp_std::cell::{Cell, RefCell};
-use sp_std::rc::Rc;
-use std::panic;
-
-use crate::hiring::ApplicationDeactivationCause;
-use crate::{Module, Trait};
-use balances;
-use stake;
-
-impl_outer_origin! {
-    pub enum Origin for Test {}
-}
-
-parameter_types! {
-    pub const BlockHashCount: u64 = 250;
-    pub const MaximumBlockWeight: u32 = 1024;
-    pub const MaximumBlockLength: u32 = 2 * 1024;
-    pub const AvailableBlockRatio: Perbill = Perbill::one();
-}
-
-// 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 = ();
-    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 = ();
-}
-
-parameter_types! {
-    pub const ExistentialDeposit: u32 = 100;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
-}
-
-impl balances::Trait for Test {
-    type Balance = u64;
-    type DustRemoval = ();
-    type Event = ();
-    type ExistentialDeposit = ExistentialDeposit;
-    type AccountStore = System;
-    type WeightInfo = ();
-    type MaxLocks = ();
-}
-
-impl Trait for Test {
-    type OpeningId = u64;
-    type ApplicationId = u64;
-    type ApplicationDeactivatedHandler = TestApplicationDeactivatedHandler;
-    type StakeHandlerProvider = TestStakeHandlerProvider;
-}
-
-impl stake::Trait for Test {
-    type Currency = Balances;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
-pub type Balances = balances::Module<Test>;
-pub type System = frame_system::Module<Test>;
-pub type Hiring = Module<Test>;
-
-// Intercepts panic method
-// Returns: whether panic occurred
-fn panics<F: std::panic::RefUnwindSafe + Fn()>(could_panic_func: F) -> bool {
-    {
-        let default_hook = panic::take_hook();
-        panic::set_hook(Box::new(|info| {
-            println!("{}", info);
-        }));
-
-        // intercept panic
-        let result = panic::catch_unwind(|| could_panic_func());
-
-        //restore default behaviour
-        panic::set_hook(default_hook);
-
-        result.is_err()
-    }
-}
-
-pub struct TestStakeHandlerProvider;
-impl crate::StakeHandlerProvider<Test> for TestStakeHandlerProvider {
-    /// Returns StakeHandler. Mock entry point for stake module.
-    fn staking() -> Rc<RefCell<dyn crate::StakeHandler<Test>>> {
-        THREAD_LOCAL_STAKE_HANDLER.with(|f| f.borrow().clone())
-    }
-}
-
-// 1. RefCell - thread_local! mutation pattern
-// 2. Rc - ability to have multiple references
-// 3. Refcell - interior mutability to provide extra-mock capabilities (like mockall checkpoint).
-thread_local! {
-    pub static THREAD_LOCAL_STAKE_HANDLER:
-      RefCell<Rc<RefCell<dyn crate::StakeHandler<Test>>>> = RefCell::new(Rc::new(RefCell::new(crate::HiringStakeHandler {})));
-}
-
-// Sets stake handler implementation in hiring module. Mockall frameworks integration
-pub(crate) fn set_stake_handler_impl(
-    mock: Rc<sp_std::cell::RefCell<dyn crate::StakeHandler<Test>>>,
-) {
-    // Hiring::staking.mock_safe(move || MockResult::Return(mock.clone()));
-    THREAD_LOCAL_STAKE_HANDLER.with(|f| {
-        *f.borrow_mut() = mock.clone();
-    });
-}
-
-// Tests mock expectation and restores default behaviour
-pub(crate) fn test_expectation_and_clear_mock() {
-    set_stake_handler_impl(Rc::new(RefCell::new(crate::HiringStakeHandler {})));
-}
-
-pub fn build_test_externalities() -> sp_io::TestExternalities {
-    let t = frame_system::GenesisConfig::default()
-        .build_storage::<Test>()
-        .unwrap();
-
-    t.into()
-}
-
-// Intercepts panic in provided function, test mock expectation and restores default behaviour
-pub(crate) fn handle_mock<F: std::panic::RefUnwindSafe + Fn()>(func: F) {
-    let panicked = panics(func);
-
-    test_expectation_and_clear_mock();
-
-    assert!(!panicked);
-}
-
-//
-// ******* ApplicationDeactivatedHandler mocks ********************
-//
-thread_local! {
-    pub static LAST_DEACTIVATED_APPLICATION:
-        Cell<Option<(<Test as Trait>::ApplicationId, ApplicationDeactivationCause)>> = Cell::new(None);
-}
-
-pub struct TestApplicationDeactivatedHandler;
-impl crate::ApplicationDeactivatedHandler<Test> for TestApplicationDeactivatedHandler {
-    fn deactivated(
-        application_id: &<Test as Trait>::ApplicationId,
-        cause: ApplicationDeactivationCause,
-    ) {
-        LAST_DEACTIVATED_APPLICATION.with(|f| {
-            f.replace(Some((*application_id, cause)));
-        });
-    }
-}
-
-impl TestApplicationDeactivatedHandler {
-    pub(crate) fn assert_deactivated_application(
-        expected_application_id: <Test as Trait>::ApplicationId,
-        expected_cause: ApplicationDeactivationCause,
-    ) {
-        let mut actual_deactivated_application = None;
-        LAST_DEACTIVATED_APPLICATION.with(|f| {
-            actual_deactivated_application = f.replace(None);
-        });
-
-        assert_eq!(
-            Some((expected_application_id, expected_cause)),
-            actual_deactivated_application
-        );
-    }
-}
-
-// Test fixtures starting block.
-pub(crate) static FIRST_BLOCK_HEIGHT: <Test as frame_system::Trait>::BlockNumber = 0;

+ 0 - 28
runtime-modules/hiring/src/test/mod.rs

@@ -1,28 +0,0 @@
-#![cfg(test)]
-
-mod public_api;
-mod smoke;
-mod staking_module;
-use public_api::*;
-
-use crate::mock::Test;
-use crate::*;
-
-use sp_std::cell::RefCell;
-use sp_std::rc::Rc;
-
-use std::panic;
-
-pub(crate) type OpeningId = <Test as Trait>::OpeningId;
-pub(crate) type ApplicationId = <Test as Trait>::ApplicationId;
-pub(crate) type BlockNumber = <Test as frame_system::Trait>::BlockNumber;
-pub(crate) type StakeId = <Test as stake::Trait>::StakeId;
-pub(crate) type Balance = <<Test as stake::Trait>::Currency as Currency<
-    <Test as frame_system::Trait>::AccountId,
->>::Balance;
-
-// Debug test object content. Recurring temporary usage - do not delete.
-#[allow(dead_code)]
-pub fn debug_print<T: sp_std::fmt::Debug>(obj: T) {
-    println!("{:?}", obj);
-}

+ 0 - 441
runtime-modules/hiring/src/test/public_api/add_application.rs

@@ -1,441 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-use sp_std::collections::btree_map::BTreeMap;
-use stake::NegativeImbalance;
-
-use crate::test::public_api::*;
-
-/*
-Most 'ensures' (add_application() fail reasons) covered in ensure_can_add_application_* tests.
-*/
-
-pub struct AddApplicationFixture {
-    pub opening_id: OpeningId,
-    pub opt_role_stake_imbalance: Option<NegativeImbalance<Test>>,
-    pub opt_application_stake_imbalance: Option<NegativeImbalance<Test>>,
-    pub human_readable_text: Vec<u8>,
-}
-
-impl AddApplicationFixture {
-    pub(crate) fn default_for_opening(opening_id: OpeningId) -> Self {
-        AddApplicationFixture {
-            opening_id,
-            opt_role_stake_imbalance: None,
-            opt_application_stake_imbalance: None,
-            human_readable_text: HUMAN_READABLE_TEXT.to_vec(),
-        }
-    }
-
-    pub(crate) fn add_application(
-        &self,
-    ) -> Result<ApplicationAdded<ApplicationId>, AddApplicationError> {
-        let mut opt_role_stake_imbalance = None;
-        if let Some(ref imbalance) = self.opt_role_stake_imbalance {
-            opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(imbalance.peek()));
-        }
-
-        let mut opt_application_stake_imbalance = None;
-        if let Some(ref imbalance) = self.opt_application_stake_imbalance {
-            opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(imbalance.peek()));
-        }
-
-        Hiring::add_application(
-            self.opening_id,
-            opt_role_stake_imbalance,
-            opt_application_stake_imbalance,
-            self.human_readable_text.clone(),
-        )
-    }
-
-    fn call_and_assert(
-        &self,
-        expected_result: Result<ApplicationAdded<ApplicationId>, AddApplicationError>,
-    ) {
-        let expected_application_id = Hiring::next_application_id();
-        // save opening state (can be invalid if invalid opening_id provided)
-        let old_opening_state = <OpeningById<Test>>::get(self.opening_id);
-
-        let add_application_result = self.add_application();
-
-        // Check expected result
-        assert_eq!(add_application_result, expected_result);
-
-        if add_application_result.is_ok() {
-            // Check next application id has been updated
-            assert_eq!(Hiring::next_application_id(), expected_application_id + 1);
-            // Check application exists
-            assert!(<ApplicationById<Test>>::contains_key(
-                expected_application_id
-            ));
-        } else {
-            // Check next application id has not been updated
-            assert_eq!(Hiring::next_application_id(), expected_application_id);
-            // Check application does not exist
-            assert!(!<ApplicationById<Test>>::contains_key(
-                expected_application_id
-            ));
-        };
-
-        //Check application content
-        self.assert_application_content(add_application_result.clone(), expected_application_id);
-
-        //Check opening state after add_application() call
-        self.assert_opening_content(
-            old_opening_state,
-            add_application_result,
-            expected_application_id,
-        );
-    }
-
-    fn assert_application_content(
-        &self,
-        add_application_result: Result<ApplicationAdded<ApplicationId>, AddApplicationError>,
-        expected_application_id: ApplicationId,
-    ) {
-        if add_application_result.is_ok() {
-            let opening = <OpeningById<Test>>::get(self.opening_id);
-            let total_applications_count;
-            if let OpeningStage::Active {
-                applications_added, ..
-            } = opening.stage
-            {
-                total_applications_count = applications_added.len();
-            } else {
-                panic!("Opening should be in active stage");
-            }
-
-            let found_application = <ApplicationById<Test>>::get(expected_application_id);
-            let expected_application_index_in_opening = total_applications_count as u32 - 1;
-
-            // Skip this check due external stake module dependency
-            let expected_active_role_staking_id = found_application.active_role_staking_id;
-
-            // Skip this check due external stake module dependency
-            let expected_active_application_staking_id =
-                found_application.active_application_staking_id;
-
-            let expected_application = Application {
-                opening_id: self.opening_id,
-                application_index_in_opening: expected_application_index_in_opening,
-                add_to_opening_in_block: 0,
-                active_role_staking_id: expected_active_role_staking_id,
-                active_application_staking_id: expected_active_application_staking_id,
-                stage: ApplicationStage::Active,
-                human_readable_text: HUMAN_READABLE_TEXT.to_vec(),
-            };
-
-            assert_eq!(found_application, expected_application);
-        }
-    }
-
-    fn assert_opening_content(
-        &self,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        add_application_result: Result<ApplicationAdded<ApplicationId>, AddApplicationError>,
-        expected_application_id: ApplicationId,
-    ) {
-        let new_opening_state = <OpeningById<Test>>::get(self.opening_id);
-
-        let mut expected_added_apps_in_opening;
-        let mut expected_active_application_count;
-        let mut expected_unstaking_application_count;
-        let expected_deactivated_application_count;
-        if let OpeningStage::Active {
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-            ..
-        } = old_opening.stage
-        {
-            expected_added_apps_in_opening = applications_added.clone();
-            expected_active_application_count = active_application_count;
-            expected_deactivated_application_count = deactivated_application_count;
-            expected_unstaking_application_count = unstaking_application_count;
-
-            if let Ok(add_app_data) = add_application_result {
-                expected_added_apps_in_opening.insert(expected_application_id);
-                if add_app_data.application_id_crowded_out.is_some() {
-                    expected_unstaking_application_count += 1;
-                } else {
-                    expected_active_application_count += 1;
-                }
-            }
-        } else {
-            panic!("Opening should be in active stage");
-        }
-
-        let expected_opening = Opening {
-            stage: OpeningStage::Active {
-                stage: ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                },
-                applications_added: expected_added_apps_in_opening,
-                active_application_count: expected_active_application_count,
-                unstaking_application_count: expected_unstaking_application_count,
-                deactivated_application_count: expected_deactivated_application_count,
-            },
-            ..old_opening
-        };
-        assert_eq!(new_opening_state, expected_opening);
-    }
-}
-
-#[test]
-fn add_application_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.call_and_assert(Ok(ApplicationAdded {
-            application_id_added: 0,
-            application_id_crowded_out: None,
-        }));
-    });
-}
-
-#[test]
-fn add_application_succeeds_with_crowding_out() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let add_appplication_result = application_fixture.add_application();
-        let application_id = add_appplication_result.unwrap().application_id_added;
-
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-
-        application_fixture.call_and_assert(Ok(ApplicationAdded {
-            application_id_added: 1,
-            application_id_crowded_out: Some(0),
-        }));
-
-        TestApplicationDeactivatedHandler::assert_deactivated_application(
-            application_id,
-            ApplicationDeactivationCause::CrowdedOut,
-        );
-    });
-}
-
-#[test]
-fn add_application_fails() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(50));
-
-        application_fixture.call_and_assert(Err(AddApplicationError::StakeAmountTooLow(
-            StakePurpose::Application,
-        )));
-    });
-}
-
-#[test]
-fn add_application_succeeds_with_created_application_stake() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let application = <ApplicationById<Test>>::get(application_id);
-        let application_stake_id = application.active_application_staking_id.unwrap();
-
-        let stake = Hiring::staking().get_stake(application_stake_id);
-        let expected_stake = stake::Stake {
-            created: FIRST_BLOCK_HEIGHT,
-            staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                staked_amount: 100,
-                staked_status: stake::StakedStatus::Normal,
-                next_slash_id: 0,
-                ongoing_slashes: BTreeMap::new(),
-            }),
-        };
-
-        assert_eq!(stake, expected_stake);
-    });
-}
-
-#[test]
-fn add_application_succeeds_with_crowding_out_with_staking_mocks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_rationing_policy =
-                Some(hiring::ApplicationRationingPolicy {
-                    max_active_applicants: 1,
-                });
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            assert!(application_fixture.add_application().is_ok());
-            mock.borrow_mut().checkpoint();
-
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(101));
-
-            let mock2 = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_stake_exists().returning(|_| true);
-
-                mock.expect_stake().times(1).returning(|_, _| Ok(()));
-
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-
-                mock.expect_create_stake().times(1).returning(|| 1);
-
-                mock.expect_get_stake().returning(|_| stake::Stake {
-                    created: 1,
-                    staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                        staked_amount: 100,
-                        staked_status: stake::StakedStatus::Normal,
-                        next_slash_id: 0,
-                        ongoing_slashes: BTreeMap::new(),
-                    }),
-                });
-
-                Rc::new(RefCell::new(mock))
-            };
-
-            set_stake_handler_impl(mock2.clone());
-
-            assert!(application_fixture.add_application().is_ok());
-        });
-    });
-}
-
-#[test]
-fn add_application_succeeds_with_crowding_out_with_role_staking_mocks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_rationing_policy =
-                Some(hiring::ApplicationRationingPolicy {
-                    max_active_applicants: 1,
-                });
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let add_appplication_result = application_fixture.add_application();
-            let application_id = add_appplication_result.unwrap().application_id_added;
-            mock.borrow_mut().checkpoint();
-
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(101));
-
-            let mock2 = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_stake_exists().returning(|_| true);
-
-                mock.expect_stake().times(1).returning(|_, _| Ok(()));
-
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-
-                mock.expect_create_stake().times(1).returning(|| 1);
-
-                mock.expect_get_stake().returning(|_| stake::Stake {
-                    created: 1,
-                    staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                        staked_amount: 100,
-                        staked_status: stake::StakedStatus::Normal,
-                        next_slash_id: 0,
-                        ongoing_slashes: BTreeMap::new(),
-                    }),
-                });
-
-                Rc::new(RefCell::new(mock))
-            };
-
-            set_stake_handler_impl(mock2.clone());
-
-            assert!(application_fixture.add_application().is_ok());
-
-            TestApplicationDeactivatedHandler::assert_deactivated_application(
-                application_id,
-                ApplicationDeactivationCause::CrowdedOut,
-            );
-        });
-    });
-}

+ 0 - 226
runtime-modules/hiring/src/test/public_api/add_opening.rs

@@ -1,226 +0,0 @@
-use crate::mock::{build_test_externalities, Hiring, Test, FIRST_BLOCK_HEIGHT};
-use crate::test::{BlockNumber, OpeningId};
-use crate::StakingAmountLimitMode::Exact;
-use crate::*;
-use crate::{
-    ActivateOpeningAt, ActiveOpeningStage, AddOpeningError, ApplicationRationingPolicy, Opening,
-    OpeningStage, StakePurpose, StakingPolicy,
-};
-use sp_std::collections::btree_set::BTreeSet;
-
-pub static HUMAN_READABLE_TEXT: &[u8] = b"HUMAN_READABLE_TEXT!!!!";
-
-pub struct AddOpeningFixture<Balance> {
-    pub activate_at: ActivateOpeningAt<BlockNumber>,
-    pub max_review_period_length: BlockNumber,
-    pub application_rationing_policy: Option<ApplicationRationingPolicy>,
-    pub application_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-    pub role_staking_policy: Option<StakingPolicy<Balance, BlockNumber>>,
-    pub human_readable_text: Vec<u8>,
-}
-
-impl<Balance> Default for AddOpeningFixture<Balance> {
-    fn default() -> Self {
-        AddOpeningFixture {
-            activate_at: ActivateOpeningAt::CurrentBlock,
-            max_review_period_length: 672,
-            application_rationing_policy: None,
-            application_staking_policy: None,
-            role_staking_policy: None,
-            human_readable_text: HUMAN_READABLE_TEXT.to_vec(),
-        }
-    }
-}
-
-impl AddOpeningFixture<OpeningId> {
-    fn call_and_assert(&self, expected_result: Result<OpeningId, AddOpeningError>) {
-        let expected_opening_id = Hiring::next_opening_id();
-
-        let add_opening_result = self.add_opening();
-        assert_eq!(add_opening_result, expected_result);
-
-        if add_opening_result.is_ok() {
-            // Check next opening id has been updated
-            assert_eq!(Hiring::next_opening_id(), expected_opening_id + 1);
-            // Check opening exists
-            assert!(<OpeningById<Test>>::contains_key(expected_opening_id));
-        } else {
-            // Check next opening id has not been updated
-            assert_eq!(Hiring::next_opening_id(), expected_opening_id);
-            // Check opening does not exist
-            assert!(!<OpeningById<Test>>::contains_key(expected_opening_id));
-        };
-
-        //Check opening content
-        if add_opening_result.is_ok() {
-            self.assert_opening_content(expected_opening_id);
-        }
-    }
-
-    fn assert_opening_content(&self, expected_opening_id: OpeningId) {
-        let expected_opening_stage = match self.activate_at {
-            ActivateOpeningAt::CurrentBlock => OpeningStage::Active {
-                stage: ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                },
-                applications_added: BTreeSet::new(),
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0,
-            },
-            ActivateOpeningAt::ExactBlock(block_number) => OpeningStage::WaitingToBegin {
-                begins_at_block: block_number,
-            },
-        };
-
-        let expected_opening = Opening {
-            created: mock::FIRST_BLOCK_HEIGHT,
-            stage: expected_opening_stage,
-            max_review_period_length: self.max_review_period_length,
-            application_rationing_policy: self.application_rationing_policy.clone(),
-            application_staking_policy: self.application_staking_policy.clone(),
-            role_staking_policy: self.role_staking_policy.clone(),
-            human_readable_text: HUMAN_READABLE_TEXT.to_vec(),
-        };
-
-        let found_opening = Hiring::opening_by_id(expected_opening_id);
-        assert_eq!(found_opening, expected_opening);
-    }
-
-    pub(crate) fn add_opening(&self) -> Result<OpeningId, AddOpeningError> {
-        Hiring::add_opening(
-            self.activate_at.clone(),
-            self.max_review_period_length,
-            self.application_rationing_policy.clone(),
-            self.application_staking_policy.clone(),
-            self.role_staking_policy.clone(),
-            self.human_readable_text.clone(),
-        )
-    }
-}
-
-#[test]
-fn add_opening_succeeds_with_exact_block() {
-    build_test_externalities().execute_with(|| {
-        let opening_data = AddOpeningFixture::default();
-
-        let expected_opening_id = 0;
-
-        // Add an opening, check that the returned value is Zero
-        opening_data.call_and_assert(Ok(expected_opening_id));
-    });
-}
-
-#[test]
-fn add_opening_succeeds_with_waiting_to_begin() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_data = AddOpeningFixture::default();
-        opening_data.activate_at = ActivateOpeningAt::ExactBlock(22);
-        let expected_opening_id = 0;
-
-        // Add an opening, check that the returned value is Zero
-        opening_data.call_and_assert(Ok(expected_opening_id));
-    });
-}
-
-#[test]
-fn add_opening_fails_due_to_activation_in_the_past() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_data = AddOpeningFixture::default();
-        opening_data.activate_at = ActivateOpeningAt::ExactBlock(0);
-
-        opening_data.call_and_assert(Err(AddOpeningError::OpeningMustActivateInTheFuture));
-    });
-}
-
-#[test]
-fn add_opening_succeeds_or_fails_due_to_application_staking_policy() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_data = AddOpeningFixture::default();
-        //Valid stake amount
-        opening_data.application_staking_policy = Some(StakingPolicy {
-            amount: 300,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Ok(0));
-
-        //Zero stake amount
-        opening_data.application_staking_policy = Some(StakingPolicy {
-            amount: 0,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Err(AddOpeningError::StakeAmountCannotBeZero(
-            StakePurpose::Application,
-        )));
-
-        //Invalid stake amount
-        opening_data.application_staking_policy = Some(StakingPolicy {
-            amount: 1,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Err(
-            AddOpeningError::StakeAmountLessThanMinimumStakeBalance(StakePurpose::Application),
-        ));
-    });
-}
-
-#[test]
-fn add_opening_succeeds_or_fails_due_to_role_staking_policy() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_data = AddOpeningFixture::default();
-        //Valid stake amount
-        opening_data.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Ok(0));
-
-        //Zero stake amount
-        opening_data.role_staking_policy = Some(StakingPolicy {
-            amount: 0,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Err(AddOpeningError::StakeAmountCannotBeZero(
-            StakePurpose::Role,
-        )));
-
-        //Invalid stake amount
-        opening_data.role_staking_policy = Some(StakingPolicy {
-            amount: 1,
-            amount_mode: Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        opening_data.call_and_assert(Err(
-            AddOpeningError::StakeAmountLessThanMinimumStakeBalance(StakePurpose::Role),
-        ));
-    });
-}
-
-#[test]
-fn add_opening_succeeds_or_fails_due_to_invalid_application_rationing_policy() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_data = AddOpeningFixture::default();
-        opening_data.application_rationing_policy = Some(ApplicationRationingPolicy {
-            max_active_applicants: 0,
-        });
-
-        opening_data.call_and_assert(Err(AddOpeningError::ApplicationRationingZeroMaxApplicants));
-    });
-}

+ 0 - 64
runtime-modules/hiring/src/test/public_api/begin_accepting_applications.rs

@@ -1,64 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-use sp_std::collections::btree_set::BTreeSet;
-
-#[test]
-fn begin_accepting_applications_fails_with_no_opening() {
-    build_test_externalities().execute_with(|| {
-        assert_eq!(
-            Hiring::begin_accepting_applications(2),
-            Err(BeginAcceptingApplicationsError::OpeningDoesNotExist)
-        );
-    });
-}
-
-#[test]
-fn begin_accepting_applications_fails_with_not_in_waiting_for_begin() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::begin_accepting_applications(opening_id),
-            Err(BeginAcceptingApplicationsError::OpeningIsNotInWaitingToBeginStage)
-        );
-    });
-}
-
-#[test]
-fn begin_accepting_applications_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        // set future activation
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(22);
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(Hiring::begin_accepting_applications(opening_id), Ok(()));
-
-        let updated_opening = <OpeningById<Test>>::get(opening_id);
-
-        let expected_opening_state = Opening {
-            created: FIRST_BLOCK_HEIGHT,
-            stage: OpeningStage::Active {
-                stage: ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                },
-                applications_added: BTreeSet::new(),
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0,
-            },
-            max_review_period_length: 672,
-            application_rationing_policy: None,
-            application_staking_policy: None,
-            role_staking_policy: None,
-            human_readable_text: HUMAN_READABLE_TEXT.to_vec(),
-        };
-
-        assert_eq!(updated_opening, expected_opening_state);
-    });
-}

+ 0 - 55
runtime-modules/hiring/src/test/public_api/begin_review.rs

@@ -1,55 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-
-#[test]
-fn begin_review_fails_with_no_opening() {
-    build_test_externalities().execute_with(|| {
-        assert_eq!(
-            Hiring::begin_review(2),
-            Err(BeginReviewError::OpeningDoesNotExist)
-        );
-    });
-}
-
-#[test]
-fn begin_review_fails_with_not_in_accepting_application_stage() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        // set future activation
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(22);
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::begin_review(opening_id),
-            Err(BeginReviewError::OpeningNotInAcceptingApplicationsStage)
-        );
-    });
-}
-
-#[test]
-fn begin_review_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        assert!(application_fixture.add_application().is_ok());
-
-        let old_opening = <OpeningById<Test>>::get(opening_id);
-
-        assert_eq!(Hiring::begin_review(opening_id), Ok(()));
-
-        let updated_opening = <OpeningById<Test>>::get(opening_id);
-
-        let expected_opening_state =
-            old_opening.clone_with_new_active_opening_stage(ActiveOpeningStage::ReviewPeriod {
-                started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                started_review_period_at_block: FIRST_BLOCK_HEIGHT,
-            });
-
-        assert_eq!(updated_opening, expected_opening_state);
-    });
-}

+ 0 - 431
runtime-modules/hiring/src/test/public_api/cancel_opening.rs

@@ -1,431 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-
-use crate::test::public_api::*;
-use sp_std::collections::btree_map::BTreeMap;
-
-/*
-Not covered:
-- Application content check
-*/
-
-pub struct CancelOpeningFixture {
-    pub opening_id: OpeningId,
-    pub application_stake_unstaking_period: Option<BlockNumber>,
-    pub role_stake_unstaking_period: Option<BlockNumber>,
-}
-
-impl CancelOpeningFixture {
-    pub(crate) fn default_for_opening(opening_id: OpeningId) -> Self {
-        CancelOpeningFixture {
-            opening_id,
-            application_stake_unstaking_period: None,
-            role_stake_unstaking_period: None,
-        }
-    }
-
-    fn call_and_assert(&self, expected_result: Result<OpeningCancelled, CancelOpeningError>) {
-        let old_opening = <OpeningById<Test>>::get(self.opening_id);
-        let old_applications = self.extract_applications();
-
-        let cancel_opening_result = self.cancel_opening();
-
-        assert_eq!(cancel_opening_result, expected_result);
-
-        self.assert_opening_content(old_opening, cancel_opening_result.clone());
-
-        if !cancel_opening_result.is_ok() {
-            self.assert_same_applications(old_applications);
-        }
-    }
-
-    fn assert_same_applications(
-        &self,
-        old_applications: BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>>,
-    ) {
-        for (app_id, application) in old_applications {
-            let test_application = <ApplicationById<Test>>::get(app_id);
-            assert_eq!(application, test_application)
-        }
-    }
-
-    fn extract_applications(
-        &self,
-    ) -> BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>> {
-        let opening = <OpeningById<Test>>::get(self.opening_id);
-
-        if let OpeningStage::Active {
-            applications_added, ..
-        } = opening.stage
-        {
-            applications_added
-                .iter()
-                .map(|app_id| (*app_id, <ApplicationById<Test>>::get(app_id)))
-                .collect::<BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>>>()
-        } else {
-            BTreeMap::new()
-        }
-    }
-
-    pub(crate) fn cancel_opening(&self) -> Result<OpeningCancelled, CancelOpeningError> {
-        Hiring::cancel_opening(
-            self.opening_id,
-            self.application_stake_unstaking_period,
-            self.role_stake_unstaking_period,
-        )
-    }
-
-    fn assert_opening_content(
-        &self,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        cancel_opening_result: Result<OpeningCancelled, CancelOpeningError>,
-    ) {
-        let new_opening = <OpeningById<Test>>::get(self.opening_id);
-        let mut expected_opening = old_opening.clone();
-
-        if cancel_opening_result.is_ok() {
-            if let hiring::OpeningStage::Active {
-                stage,
-                applications_added,
-                ..
-            } = old_opening.stage
-            {
-                // compose expected stage
-                let expected_active_stage = match stage {
-                    ActiveOpeningStage::AcceptingApplications {
-                        started_accepting_applicants_at_block,
-                    } => ActiveOpeningStage::Deactivated {
-                        cause: OpeningDeactivationCause::CancelledAcceptingApplications,
-                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
-                        started_accepting_applicants_at_block,
-                        started_review_period_at_block: None,
-                    },
-                    ActiveOpeningStage::ReviewPeriod {
-                        started_accepting_applicants_at_block,
-                        started_review_period_at_block,
-                    } => ActiveOpeningStage::Deactivated {
-                        cause: OpeningDeactivationCause::CancelledInReviewPeriod,
-                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
-                        started_accepting_applicants_at_block,
-                        started_review_period_at_block: Some(started_review_period_at_block),
-                    },
-                    ActiveOpeningStage::Deactivated { .. } => {
-                        panic!("OpeningNotInCancellableStage")
-                    }
-                };
-
-                // calculate application counters
-                let mut deactivated_app_count = 0;
-                let mut unstaking_app_count = 0;
-                for app_id in applications_added.clone() {
-                    let application = <ApplicationById<Test>>::get(app_id);
-
-                    match application.stage {
-                        ApplicationStage::Active => panic!("Cannot be in active stage"),
-                        ApplicationStage::Inactive { .. } => {
-                            deactivated_app_count += 1;
-                        }
-                        ApplicationStage::Unstaking { .. } => {
-                            unstaking_app_count += 1;
-                        }
-                    }
-                }
-
-                expected_opening.stage = hiring::OpeningStage::Active {
-                    stage: expected_active_stage,
-                    applications_added,
-                    active_application_count: 0,
-                    unstaking_application_count: unstaking_app_count,
-                    deactivated_application_count: deactivated_app_count,
-                };
-            } else {
-                panic!("old opening stage MUST be active")
-            }
-        };
-
-        assert_eq!(expected_opening, new_opening);
-    }
-}
-
-#[test]
-fn cancel_opening_fails_due_to_opening_not_existing() {
-    build_test_externalities().execute_with(|| {
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(0);
-        cancel_opening_fixture.call_and_assert(Err(CancelOpeningError::OpeningDoesNotExist));
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds_with_single_crowded_out_application() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-        application_fixture.opt_role_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-        application_fixture.opt_role_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.call_and_assert(Ok(OpeningCancelled {
-            number_of_unstaking_applications: 1,
-            number_of_deactivated_applications: 0,
-        }));
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds_with_single_unstaking_application() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.call_and_assert(Ok(OpeningCancelled {
-            number_of_unstaking_applications: 1,
-            number_of_deactivated_applications: 0,
-        }));
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds_with_single_deactivated_application() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.call_and_assert(Ok(OpeningCancelled {
-            number_of_unstaking_applications: 0,
-            number_of_deactivated_applications: 1,
-        }));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_opening_is_not_active() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(5);
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture
-            .call_and_assert(Err(CancelOpeningError::OpeningNotInCancellableStage));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_opening_not_in_cancellable_stage() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-
-        let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        assert!(cancel_opening_fixture.cancel_opening().is_ok());
-        cancel_opening_fixture
-            .call_and_assert(Err(CancelOpeningError::OpeningNotInCancellableStage));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_redundant_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.application_stake_unstaking_period = Some(0);
-        cancel_opening_fixture.call_and_assert(Err(CancelOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Application,
-        )));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_redundant_role_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.role_stake_unstaking_period = Some(50);
-        cancel_opening_fixture.call_and_assert(Err(
-            CancelOpeningError::RedundantUnstakingPeriodProvided(StakePurpose::Role),
-        ));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_too_short_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.application_stake_unstaking_period = Some(0);
-        cancel_opening_fixture.call_and_assert(Err(CancelOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Application,
-        )));
-    });
-}
-
-#[test]
-fn cancel_opening_fails_due_to_too_short_role_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-        cancel_opening_fixture.role_stake_unstaking_period = Some(0);
-        cancel_opening_fixture.call_and_assert(Err(CancelOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Role,
-        )));
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds_with_single_unstaking_application_with_application_stake_checks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let mock2 = default_mock_for_unstaking();
-            set_stake_handler_impl(mock2.clone());
-
-            let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-            cancel_opening_fixture.call_and_assert(Ok(OpeningCancelled {
-                number_of_unstaking_applications: 1,
-                number_of_deactivated_applications: 0,
-            }));
-
-            TestApplicationDeactivatedHandler::assert_deactivated_application(
-                application_id,
-                ApplicationDeactivationCause::OpeningCancelled,
-            );
-        })
-    });
-}
-
-#[test]
-fn cancel_opening_succeeds_with_single_unstaking_application_with_role_stake_checks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let app_application_result = application_fixture.add_application();
-            assert!(app_application_result.is_ok());
-
-            let mock2 = default_mock_for_unstaking();
-            set_stake_handler_impl(mock2.clone());
-
-            let cancel_opening_fixture = CancelOpeningFixture::default_for_opening(opening_id);
-            cancel_opening_fixture.call_and_assert(Ok(OpeningCancelled {
-                number_of_unstaking_applications: 1,
-                number_of_deactivated_applications: 0,
-            }));
-        })
-    });
-}

+ 0 - 382
runtime-modules/hiring/src/test/public_api/deactivate_application.rs

@@ -1,382 +0,0 @@
-use crate::mock::*;
-use crate::test::public_api::*;
-use crate::test::*;
-use crate::ApplicationDeactivationCause;
-
-/*
-Not covered:
-- application content checks: deactivation in future blocks
-*/
-
-pub struct DeactivateApplicationFixture {
-    pub application_id: ApplicationId,
-    pub application_stake_unstaking_period: Option<BlockNumber>,
-    pub role_stake_unstaking_period: Option<BlockNumber>,
-}
-
-impl DeactivateApplicationFixture {
-    pub(crate) fn default_for_application_id(application_id: ApplicationId) -> Self {
-        DeactivateApplicationFixture {
-            application_id,
-            application_stake_unstaking_period: None,
-            role_stake_unstaking_period: None,
-        }
-    }
-
-    pub(crate) fn deactivate_application(&self) -> Result<(), DeactivateApplicationError> {
-        Hiring::deactive_application(
-            self.application_id,
-            self.application_stake_unstaking_period,
-            self.role_stake_unstaking_period,
-        )
-    }
-
-    fn call_and_assert(&self, expected_result: Result<(), DeactivateApplicationError>) {
-        // save opening state (can be invalid if invalid opening_id provided)
-        let old_application = <ApplicationById<Test>>::get(self.application_id);
-        let old_opening_state = <OpeningById<Test>>::get(old_application.opening_id);
-
-        let deactivate_application_result = self.deactivate_application();
-
-        assert_eq!(deactivate_application_result, expected_result);
-
-        self.assert_application_content(
-            old_application.clone(),
-            deactivate_application_result.clone(),
-        );
-
-        self.assert_opening_content(
-            old_application.opening_id,
-            old_opening_state,
-            deactivate_application_result,
-        );
-    }
-
-    fn assert_application_content(
-        &self,
-        old_application_state: Application<OpeningId, BlockNumber, StakeId>,
-        deactivate_application_result: Result<(), DeactivateApplicationError>,
-    ) {
-        let actual_application_state = <ApplicationById<Test>>::get(self.application_id);
-
-        let expected_application_state = if deactivate_application_result.is_ok() {
-            if old_application_state
-                .active_application_staking_id
-                .is_some()
-                || old_application_state.active_role_staking_id.is_some()
-            {
-                Application {
-                    stage: ApplicationStage::Unstaking {
-                        deactivation_initiated: FIRST_BLOCK_HEIGHT,
-                        cause: ApplicationDeactivationCause::External,
-                    },
-                    ..old_application_state
-                }
-            } else {
-                Application {
-                    stage: ApplicationStage::Inactive {
-                        deactivation_initiated: FIRST_BLOCK_HEIGHT,
-                        deactivated: FIRST_BLOCK_HEIGHT,
-                        cause: ApplicationDeactivationCause::External,
-                    },
-                    ..old_application_state
-                }
-            }
-        } else {
-            old_application_state
-        };
-
-        assert_eq!(expected_application_state, actual_application_state);
-    }
-
-    fn assert_opening_content(
-        &self,
-        opening_id: OpeningId,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        actual_result: Result<(), DeactivateApplicationError>,
-    ) {
-        // invalid opening stages are not supported
-
-        // check for opening existence
-        if !<OpeningById<Test>>::contains_key(opening_id) {
-            return;
-        }
-
-        // check only for active opening
-        if let OpeningStage::Active {
-            stage,
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        } = old_opening.stage
-        {
-            // check only for accepting application stage
-            if let ActiveOpeningStage::AcceptingApplications { .. } = stage {
-                let mut expected_active_application_count = active_application_count;
-                let mut expected_deactivated_application_count = deactivated_application_count;
-                let mut expected_unstaking_application_count = unstaking_application_count;
-
-                if actual_result.is_ok() {
-                    expected_active_application_count -= 1;
-
-                    if old_opening.application_staking_policy.is_some()
-                        || old_opening.role_staking_policy.is_some()
-                    {
-                        expected_unstaking_application_count += 1;
-                    } else {
-                        expected_deactivated_application_count += 1;
-                    }
-                }
-                let expected_opening = Opening {
-                    stage: OpeningStage::Active {
-                        stage: ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                        },
-                        applications_added,
-                        active_application_count: expected_active_application_count,
-                        unstaking_application_count: expected_unstaking_application_count,
-                        deactivated_application_count: expected_deactivated_application_count,
-                    },
-                    ..old_opening
-                };
-
-                let new_opening_state = <OpeningById<Test>>::get(opening_id);
-                assert_eq!(new_opening_state, expected_opening);
-            }
-        }
-    }
-}
-
-#[test]
-fn deactivate_application_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-
-        deactivate_application_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn deactivate_application_fails_with_no_application() {
-    build_test_externalities().execute_with(|| {
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(0);
-
-        deactivate_application_fixture
-            .call_and_assert(Err(DeactivateApplicationError::ApplicationDoesNotExist));
-    });
-}
-
-#[test]
-fn deactivate_application_fails_with_redundant_application_staking_period_provided() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-        deactivate_application_fixture.application_stake_unstaking_period = Some(3);
-
-        deactivate_application_fixture.call_and_assert(Err(
-            DeactivateApplicationError::RedundantUnstakingPeriodProvided(StakePurpose::Application),
-        ))
-    });
-}
-
-#[test]
-fn deactivate_application_fails_with_redundant_role_staking_period_provided() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-        deactivate_application_fixture.role_stake_unstaking_period = Some(3);
-
-        deactivate_application_fixture.call_and_assert(Err(
-            DeactivateApplicationError::RedundantUnstakingPeriodProvided(StakePurpose::Role),
-        ))
-    });
-}
-
-#[test]
-fn deactivate_application_fails_for_already_deactivated_application() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-
-        // deactivate first
-        assert!(deactivate_application_fixture
-            .deactivate_application()
-            .is_ok());
-
-        // try again to deactivate
-        deactivate_application_fixture
-            .call_and_assert(Err(DeactivateApplicationError::ApplicationNotActive))
-    });
-}
-
-#[test]
-fn deactivate_application_for_opening_not_accepting_applications() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-
-        deactivate_application_fixture.call_and_assert(Err(
-            DeactivateApplicationError::OpeningNotAcceptingApplications,
-        ))
-    });
-}
-
-#[test]
-fn deactivate_application_fails_with_too_short_application_unstaking_period_provided() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-        deactivate_application_fixture.application_stake_unstaking_period = Some(0);
-
-        deactivate_application_fixture.call_and_assert(Err(
-            DeactivateApplicationError::UnstakingPeriodTooShort(StakePurpose::Application),
-        ))
-    });
-}
-
-#[test]
-fn deactivate_application_fails_with_too_short_role_unstaking_period_provided() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-        deactivate_application_fixture.role_stake_unstaking_period = Some(0);
-
-        deactivate_application_fixture.call_and_assert(Err(
-            DeactivateApplicationError::UnstakingPeriodTooShort(StakePurpose::Role),
-        ))
-    });
-}
-
-#[test]
-fn deactivate_application_succeeds_with_application_stake_checks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let deactivate_application_fixture =
-                DeactivateApplicationFixture::default_for_application_id(application_id);
-
-            let mock2 = default_mock_for_unstaking();
-            set_stake_handler_impl(mock2.clone());
-
-            deactivate_application_fixture.call_and_assert(Ok(()));
-
-            TestApplicationDeactivatedHandler::assert_deactivated_application(
-                application_id,
-                ApplicationDeactivationCause::External,
-            );
-        });
-    });
-}
-
-#[test]
-fn deactivate_application_succeeds_with_role_stake_checks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let deactivate_application_fixture =
-                DeactivateApplicationFixture::default_for_application_id(application_id);
-
-            let mock2 = default_mock_for_unstaking();
-            set_stake_handler_impl(mock2.clone());
-
-            deactivate_application_fixture.call_and_assert(Ok(()))
-        });
-    });
-}

+ 0 - 365
runtime-modules/hiring/src/test/public_api/ensure_can_add_application.rs

@@ -1,365 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-
-use crate::hiring::*;
-use sp_std::collections::btree_set::BTreeSet;
-
-#[test]
-fn ensure_can_add_application_fails_with_no_opening() {
-    build_test_externalities().execute_with(|| {
-        assert_eq!(
-            Hiring::ensure_can_add_application(2, None, None),
-            Err(AddApplicationError::OpeningDoesNotExist)
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_redundant_role_stake() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, Some(200), None),
-            Err(AddApplicationError::StakeProvidedWhenRedundant(
-                StakePurpose::Role
-            ))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_too_low_role_stake_amout() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, Some(200), None),
-            Err(AddApplicationError::StakeAmountTooLow(StakePurpose::Role))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_missing_role_stake_when_required() {
-    build_test_externalities().execute_with(|| {
-        //**** stake provided when redundant
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, None),
-            Err(AddApplicationError::StakeMissingWhenRequired(
-                StakePurpose::Role
-            ))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_redundant_application_stake() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, Some(200),),
-            Err(AddApplicationError::StakeProvidedWhenRedundant(
-                StakePurpose::Application
-            ))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_too_low_application_stake_amout() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, Some(200),),
-            Err(AddApplicationError::StakeAmountTooLow(
-                StakePurpose::Application
-            ))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_missing_application_stake_when_required() {
-    build_test_externalities().execute_with(|| {
-        //**** stake provided when redundant
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, None),
-            Err(AddApplicationError::StakeMissingWhenRequired(
-                StakePurpose::Application
-            ))
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_non_active_opening() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(22);
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, None),
-            Err(AddApplicationError::OpeningNotInAcceptingApplicationsStage)
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_non_accepting_application_stage() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert_eq!(Hiring::begin_review(opening_id), Ok(()));
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, None),
-            Err(AddApplicationError::OpeningNotInAcceptingApplicationsStage)
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_succeeds_with_application_rationing_policy() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert!(Hiring::ensure_can_add_application(opening_id, None, None).is_ok(),);
-    });
-}
-
-#[test]
-fn ensure_can_add_application_fails_with_application_rationing_policy() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, Some(100)),
-            Err(AddApplicationError::NewApplicationWasCrowdedOut)
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let ensure_can_add_application_result =
-            Hiring::ensure_can_add_application(opening_id, Some(100), Some(100));
-
-        assert_eq!(
-            ensure_can_add_application_result,
-            Ok(DestructuredApplicationCanBeAddedEvaluation {
-                opening: Opening {
-                    created: FIRST_BLOCK_HEIGHT,
-                    stage: hiring::OpeningStage::Active {
-                        stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT
-                        },
-                        applications_added: BTreeSet::new(),
-                        active_application_count: 0,
-                        unstaking_application_count: 0,
-                        deactivated_application_count: 0
-                    },
-                    max_review_period_length: 672,
-                    application_rationing_policy: None,
-                    application_staking_policy: Some(StakingPolicy {
-                        amount: 100,
-                        amount_mode: StakingAmountLimitMode::Exact,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None
-                    }),
-                    role_staking_policy: Some(StakingPolicy {
-                        amount: 100,
-                        amount_mode: StakingAmountLimitMode::Exact,
-                        crowded_out_unstaking_period_length: None,
-                        review_period_expired_unstaking_period_length: None
-                    }),
-                    human_readable_text: HUMAN_READABLE_TEXT.to_vec()
-                },
-                active_stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT
-                },
-                applications_added: BTreeSet::new(),
-                active_application_count: 0,
-                unstaking_application_count: 0,
-                deactivated_application_count: 0,
-                would_get_added_success: ApplicationAddedSuccess::Unconditionally
-            })
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_new_application_should_be_crowded_out_with_exact_stake() {
-    ensure_can_add_application_new_application_should_be_crowded_out_with_staking_policy(
-        StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::Exact,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        },
-    );
-}
-
-#[test]
-fn ensure_can_add_application_new_application_should_be_crowded_out_with_atleast_stake() {
-    ensure_can_add_application_new_application_should_be_crowded_out_with_staking_policy(
-        StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        },
-    );
-}
-
-fn ensure_can_add_application_new_application_should_be_crowded_out_with_staking_policy(
-    staking_policy: StakingPolicy<Balance, BlockNumber>,
-) {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(staking_policy);
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        assert_eq!(
-            Hiring::ensure_can_add_application(opening_id, None, Some(100)),
-            Err(AddApplicationError::NewApplicationWasCrowdedOut)
-        );
-    });
-}
-
-#[test]
-fn ensure_can_add_application_should_crowd_out_application() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let destructered_app_result = Hiring::ensure_can_add_application(opening_id, None, Some(101));
-        assert!(destructered_app_result.is_ok());
-
-        let destructered_app = destructered_app_result.unwrap();
-
-        if let ApplicationAddedSuccess::CrowdsOutExistingApplication(application_id) = destructered_app.would_get_added_success {
-            assert_eq!(0, application_id);
-        } else {
-            panic!("Expected ApplicationAddedSuccess::CrowdsOutExistingApplication(application_id == 0)")
-        }
-    });
-}

+ 0 - 474
runtime-modules/hiring/src/test/public_api/fill_opening.rs

@@ -1,474 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-
-use crate::test::public_api::*;
-use sp_std::collections::btree_set::BTreeSet;
-use sp_std::result::Result;
-
-/*
-Not covered:
-- Application content check
-*/
-
-pub struct FillOpeningFixture {
-    pub opening_id: OpeningId,
-    pub successful_applications: BTreeSet<<mock::Test as Trait>::ApplicationId>,
-    pub opt_successful_applicant_application_stake_unstaking_period: Option<BlockNumber>,
-    pub opt_failed_applicant_application_stake_unstaking_period: Option<BlockNumber>,
-    pub opt_failed_applicant_role_stake_unstaking_period: Option<BlockNumber>,
-}
-
-impl FillOpeningFixture {
-    pub(crate) fn default_for_opening(opening_id: OpeningId) -> Self {
-        FillOpeningFixture {
-            opening_id,
-            successful_applications: BTreeSet::new(),
-            opt_successful_applicant_application_stake_unstaking_period: None,
-            opt_failed_applicant_application_stake_unstaking_period: None,
-            opt_failed_applicant_role_stake_unstaking_period: None,
-        }
-    }
-
-    fn call_and_assert(&self, expected_result: Result<(), FillOpeningError<mock::Test>>) {
-        let old_opening = <OpeningById<Test>>::get(self.opening_id);
-        let old_applications = self.extract_successful_applications();
-
-        let fill_opening_result = self.fill_opening();
-
-        assert_eq!(fill_opening_result, expected_result);
-
-        self.assert_opening_content(old_opening, fill_opening_result.clone());
-
-        if !fill_opening_result.is_ok() {
-            self.assert_same_applications(old_applications);
-        }
-    }
-
-    fn assert_same_applications(
-        &self,
-        old_applications: BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>>,
-    ) {
-        for (app_id, application) in old_applications {
-            let test_application = <ApplicationById<Test>>::get(app_id);
-            assert_eq!(application, test_application)
-        }
-    }
-
-    fn extract_successful_applications(
-        &self,
-    ) -> BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>> {
-        self.successful_applications
-            .iter()
-            .map(|app_id| (*app_id, <ApplicationById<Test>>::get(app_id)))
-            .collect::<BTreeMap<ApplicationId, Application<OpeningId, BlockNumber, StakeId>>>()
-    }
-
-    pub(crate) fn fill_opening(&self) -> Result<(), FillOpeningError<mock::Test>> {
-        Hiring::fill_opening(
-            self.opening_id,
-            self.successful_applications.clone(),
-            self.opt_successful_applicant_application_stake_unstaking_period,
-            self.opt_failed_applicant_application_stake_unstaking_period,
-            self.opt_failed_applicant_role_stake_unstaking_period,
-        )
-    }
-
-    fn assert_opening_content(
-        &self,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        fill_opening_result: Result<(), FillOpeningError<mock::Test>>,
-    ) {
-        let new_opening = <OpeningById<Test>>::get(self.opening_id);
-        let mut expected_opening = old_opening.clone();
-
-        if fill_opening_result.is_ok() {
-            if let hiring::OpeningStage::Active {
-                applications_added, ..
-            } = old_opening.stage
-            {
-                // compose expected stage
-                let expected_active_stage = ActiveOpeningStage::Deactivated {
-                    cause: OpeningDeactivationCause::Filled,
-                    deactivated_at_block: FIRST_BLOCK_HEIGHT,
-                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                    started_review_period_at_block: Some(FIRST_BLOCK_HEIGHT),
-                };
-
-                // calculate application counters
-                let mut deactivated_app_count = 0;
-                let mut unstaking_app_count = 0;
-                for app_id in applications_added.clone() {
-                    let application = <ApplicationById<Test>>::get(app_id);
-
-                    match application.stage {
-                        ApplicationStage::Active => panic!("Cannot be in active stage"),
-                        ApplicationStage::Inactive { .. } => {
-                            deactivated_app_count += 1;
-                        }
-                        ApplicationStage::Unstaking { .. } => {
-                            unstaking_app_count += 1;
-                        }
-                    }
-                }
-
-                expected_opening.stage = hiring::OpeningStage::Active {
-                    stage: expected_active_stage,
-                    applications_added,
-                    active_application_count: 0,
-                    unstaking_application_count: unstaking_app_count,
-                    deactivated_application_count: deactivated_app_count,
-                };
-            } else {
-                panic!("old opening stage MUST be active")
-            }
-        };
-        assert_eq!(expected_opening, new_opening);
-    }
-}
-
-#[test]
-fn fill_opening_fails_due_to_opening_not_existing() {
-    build_test_externalities().execute_with(|| {
-        let fill_opening_fixture = FillOpeningFixture::default_for_opening(0);
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::OpeningDoesNotExist));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_to_opening_is_not_active() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(5);
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::OpeningNotInReviewPeriodStage));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_to_redundant_successful_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_successful_applicant_application_stake_unstaking_period = Some(50);
-        fill_opening_fixture.call_and_assert(Err(
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Success,
-            ),
-        ));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_too_short_successful_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_successful_applicant_application_stake_unstaking_period = Some(0);
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Application,
-            ApplicationOutcomeInFilledOpening::Success,
-        )));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_to_redundant_failed_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_failed_applicant_application_stake_unstaking_period = Some(50);
-        fill_opening_fixture.call_and_assert(Err(
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Application,
-                ApplicationOutcomeInFilledOpening::Failure,
-            ),
-        ));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_too_short_failed_application_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_failed_applicant_application_stake_unstaking_period = Some(0);
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Application,
-            ApplicationOutcomeInFilledOpening::Failure,
-        )));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_to_redundant_failed_role_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_failed_applicant_role_stake_unstaking_period = Some(50);
-        fill_opening_fixture.call_and_assert(Err(
-            FillOpeningError::RedundantUnstakingPeriodProvided(
-                StakePurpose::Role,
-                ApplicationOutcomeInFilledOpening::Failure,
-            ),
-        ));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_too_short_failed_role_unstaking_period() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        fill_opening_fixture.opt_failed_applicant_role_stake_unstaking_period = Some(0);
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::UnstakingPeriodTooShort(
-            StakePurpose::Role,
-            ApplicationOutcomeInFilledOpening::Failure,
-        )));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_not_existing_application() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        let mut apps = BTreeSet::new();
-        let invalid_app_id = 10;
-        apps.insert(invalid_app_id);
-        fill_opening_fixture.successful_applications = apps;
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::ApplicationDoesNotExist(
-            invalid_app_id,
-        )));
-    });
-}
-
-#[test]
-fn fill_opening_fails_due_not_active_application() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-
-        assert!(deactivate_application_fixture
-            .deactivate_application()
-            .is_ok());
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        let mut apps = BTreeSet::new();
-        apps.insert(application_id);
-
-        fill_opening_fixture.successful_applications = apps;
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::ApplicationNotInActiveStage(
-            application_id,
-        )));
-    });
-}
-
-#[test]
-fn fill_opening_succeeds() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let to_deactivate_app_result = application_fixture.add_application();
-        let to_deactivate_app_id = to_deactivate_app_result.unwrap().application_id_added;
-
-        assert!(Hiring::deactive_application(to_deactivate_app_id, None, None).is_ok());
-
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        let mut apps = BTreeSet::new();
-        apps.insert(application_id);
-
-        fill_opening_fixture.successful_applications = apps;
-        fill_opening_fixture.call_and_assert(Ok(()));
-    });
-}
-
-#[test]
-fn fill_opening_succeeds_with_application_stake_checks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_result = application_fixture.add_application();
-            let application_id = app_result.unwrap().application_id_added;
-
-            assert!(Hiring::begin_review(opening_id).is_ok());
-
-            let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-            let mut apps = BTreeSet::new();
-            apps.insert(application_id);
-
-            fill_opening_fixture.successful_applications = apps;
-
-            let mock2 = default_mock_for_unstaking();
-            set_stake_handler_impl(mock2.clone());
-
-            fill_opening_fixture.call_and_assert(Ok(()));
-
-            TestApplicationDeactivatedHandler::assert_deactivated_application(
-                application_id,
-                ApplicationDeactivationCause::Hired,
-            );
-        });
-    });
-}
-
-#[test]
-fn fill_opening_succeeds_with_not_role_stake_unstaked() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = default_mock_for_creating_stake();
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_result = application_fixture.add_application();
-            let application_id = app_result.unwrap().application_id_added;
-
-            assert!(Hiring::begin_review(opening_id).is_ok());
-
-            let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-            let mut apps = BTreeSet::new();
-            apps.insert(application_id);
-
-            fill_opening_fixture.successful_applications = apps;
-
-            let mock2 = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_stake_exists().returning(|_| true);
-
-                mock.expect_get_stake().returning(|_| stake::Stake {
-                    created: 1,
-                    staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                        staked_amount: 100,
-                        staked_status: stake::StakedStatus::Normal,
-                        next_slash_id: 0,
-                        ongoing_slashes: BTreeMap::new(),
-                    }),
-                });
-
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock2.clone());
-
-            fill_opening_fixture.call_and_assert(Ok(()));
-        });
-    });
-}
-
-#[test]
-fn fill_opening_fails_with_application_to_wrong_opening() {
-    build_test_externalities().execute_with(|| {
-        // opening 1
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-        // opening 2
-        let opening_fixture2 = AddOpeningFixture::default();
-        let add_opening_result2 = opening_fixture2.add_opening();
-        let opening_id2 = add_opening_result2.unwrap();
-
-        // application to opening 2
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id2);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        // opening 1 being review
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        // fill opening 1 with application made to opening 2 (which should fail)
-        let mut fill_opening_fixture = FillOpeningFixture::default_for_opening(opening_id);
-        let mut apps = BTreeSet::new();
-        apps.insert(application_id);
-
-        fill_opening_fixture.successful_applications = apps;
-        fill_opening_fixture.call_and_assert(Err(FillOpeningError::ApplicationForWrongOpening(
-            application_id,
-        )));
-    });
-}

+ 0 - 50
runtime-modules/hiring/src/test/public_api/mod.rs

@@ -1,50 +0,0 @@
-mod add_application;
-mod add_opening;
-mod deactivate_application;
-
-mod begin_accepting_applications;
-mod begin_review;
-mod cancel_opening;
-mod ensure_can_add_application;
-mod fill_opening;
-mod on_finalize;
-mod unstaked;
-
-pub use add_application::AddApplicationFixture;
-pub use add_opening::{AddOpeningFixture, HUMAN_READABLE_TEXT};
-pub use deactivate_application::DeactivateApplicationFixture;
-
-use crate::mock::Test;
-use sp_std::cell::RefCell;
-use sp_std::collections::btree_map::BTreeMap;
-use sp_std::rc::Rc;
-
-fn default_mock_for_creating_stake() -> Rc<RefCell<crate::MockStakeHandler<Test>>> {
-    let mut mock = crate::MockStakeHandler::<Test>::new();
-
-    mock.expect_stake().times(1).returning(|_, _| Ok(()));
-    mock.expect_create_stake().times(1).returning(|| 0);
-
-    Rc::new(sp_std::cell::RefCell::new(mock))
-}
-
-fn default_mock_for_unstaking() -> Rc<RefCell<crate::MockStakeHandler<Test>>> {
-    let mut mock = crate::MockStakeHandler::<Test>::new();
-    mock.expect_stake_exists().returning(|_| true);
-
-    mock.expect_initiate_unstaking()
-        .times(1)
-        .returning(|_, _| Ok(()));
-
-    mock.expect_get_stake().returning(|_| stake::Stake {
-        created: 1,
-        staking_status: stake::StakingStatus::Staked(stake::StakedState {
-            staked_amount: 100,
-            staked_status: stake::StakedStatus::Normal,
-            next_slash_id: 0,
-            ongoing_slashes: BTreeMap::new(),
-        }),
-    });
-
-    Rc::new(RefCell::new(mock))
-}

+ 0 - 177
runtime-modules/hiring/src/test/public_api/on_finalize.rs

@@ -1,177 +0,0 @@
-use crate::mock::*;
-use crate::test::*;
-
-use frame_support::traits::{OnFinalize, OnInitialize};
-
-// Recommendation from Parity on testing on_finalize
-// https://substrate.dev/docs/en/next/development/module/tests
-fn run_to_block(n: u64) {
-    while System::block_number() < n {
-        <System as OnFinalize<u64>>::on_finalize(System::block_number());
-        <Hiring 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());
-        <Hiring as OnInitialize<u64>>::on_initialize(System::block_number());
-    }
-}
-
-fn run_to_block_and_finalize(n: u64) {
-    run_to_block(n);
-    <Hiring as OnFinalize<u64>>::on_finalize(n);
-}
-
-#[test]
-fn on_finalize_should_work_on_empty_data() {
-    build_test_externalities().execute_with(|| {
-        run_to_block_and_finalize(42);
-    });
-}
-
-#[test]
-fn on_finalize_should_not_change_opening_prematurely() {
-    build_test_externalities().execute_with(|| {
-        let opening_activation_block = 2;
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(opening_activation_block);
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let old_opening = <OpeningById<Test>>::get(opening_id);
-
-        let block_to_finalize = opening_activation_block - 1;
-        run_to_block_and_finalize(block_to_finalize);
-
-        let new_opening = <OpeningById<Test>>::get(opening_id);
-
-        assert_eq!(old_opening, new_opening);
-    });
-}
-
-#[test]
-fn on_finalize_should_change_waiting_to_begin_opening_stage_to_active_and_acception_application() {
-    build_test_externalities().execute_with(|| {
-        let opening_activation_block = 2;
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.activate_at = ActivateOpeningAt::ExactBlock(opening_activation_block);
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let old_opening = <OpeningById<Test>>::get(opening_id);
-        // ensure preparation are valid
-        if let OpeningStage::WaitingToBegin { .. } = old_opening.stage {
-            // expected
-        } else {
-            panic!("planned to be WaitingToBegin")
-        }
-
-        let block_to_finalize = opening_activation_block;
-        run_to_block_and_finalize(block_to_finalize);
-
-        // ensure on_finalize worked
-        let new_opening = <OpeningById<Test>>::get(opening_id);
-        if let OpeningStage::Active { stage, .. } = new_opening.stage {
-            if let ActiveOpeningStage::AcceptingApplications { .. } = stage {
-                // expected
-            } else {
-                panic!("should be AcceptingApplications")
-            }
-        } else {
-            panic!("should be Active")
-        }
-    });
-}
-
-#[test]
-fn on_finalize_should_not_change_opening_to_begin_review_stage_prematurely() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.max_review_period_length = 2;
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let old_opening = <OpeningById<Test>>::get(opening_id);
-
-        let block_to_finalize = opening_fixture.max_review_period_length - 1;
-        run_to_block_and_finalize(block_to_finalize);
-
-        let new_opening = <OpeningById<Test>>::get(opening_id);
-
-        assert_eq!(old_opening, new_opening);
-    });
-}
-
-#[test]
-fn on_finalize_should_deactivate_opening_on_begin_review_stage() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.max_review_period_length = 2;
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let old_opening = <OpeningById<Test>>::get(opening_id);
-        if let OpeningStage::Active { stage, .. } = old_opening.stage {
-            if let ActiveOpeningStage::ReviewPeriod { .. } = stage {
-                // expected
-            } else {
-                panic!("should be BeginReview")
-            }
-        } else {
-            panic!("should be Active")
-        }
-
-        let block_to_finalize = opening_fixture.max_review_period_length + 1;
-        run_to_block_and_finalize(block_to_finalize);
-
-        let new_opening = <OpeningById<Test>>::get(opening_id);
-        if let OpeningStage::Active { stage, .. } = new_opening.stage {
-            if let ActiveOpeningStage::Deactivated { .. } = stage {
-                // expected
-            } else {
-                panic!("should be Deactivated")
-            }
-        } else {
-            panic!("should be Active")
-        }
-    });
-}
-
-#[test]
-fn on_finalize_should_deactivate_application_with_review_period_expired_cause() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.max_review_period_length = 2;
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        assert!(Hiring::begin_review(opening_id).is_ok());
-
-        let old_application = <ApplicationById<Test>>::get(application_id);
-        if let ApplicationStage::Active = old_application.stage {
-            // expected
-        } else {
-            panic!("should be Active")
-        }
-
-        let block_to_finalize = opening_fixture.max_review_period_length + 1;
-        run_to_block_and_finalize(block_to_finalize);
-
-        let new_application = <ApplicationById<Test>>::get(application_id);
-        if let ApplicationStage::Inactive { cause, .. } = new_application.stage {
-            if let ApplicationDeactivationCause::ReviewPeriodExpired = cause {
-                // expected
-            } else {
-                panic!("should be ReviewPeriodExpired")
-            }
-        } else {
-            panic!("should be Active")
-        }
-    });
-}

+ 0 - 302
runtime-modules/hiring/src/test/public_api/unstaked.rs

@@ -1,302 +0,0 @@
-use crate::mock::*;
-use crate::test::public_api::*;
-use crate::test::*;
-
-pub struct UnstakedFixture {
-    pub opening_id: OpeningId,
-    pub application_id: ApplicationId,
-    pub stake_id: StakeId,
-}
-
-impl UnstakedFixture {
-    fn call_and_assert(&self, expected_result: UnstakedResult) {
-        let old_opening = <OpeningById<Test>>::get(self.opening_id);
-        let old_application = <ApplicationById<Test>>::get(self.application_id);
-
-        let unstaked_result = self.unstaked();
-
-        assert_eq!(unstaked_result, expected_result);
-
-        self.assert_application_content(old_application.clone(), unstaked_result);
-
-        self.assert_opening_content(old_opening, unstaked_result);
-    }
-
-    pub(crate) fn unstaked(&self) -> UnstakedResult {
-        Hiring::unstaked(self.stake_id)
-    }
-
-    fn assert_application_content(
-        &self,
-        old_application: Application<OpeningId, BlockNumber, StakeId>,
-        unstaked_result: UnstakedResult,
-    ) {
-        let new_application = <ApplicationById<Test>>::get(self.application_id);
-
-        match unstaked_result {
-            UnstakedResult::StakeIdNonExistent | UnstakedResult::ApplicationIsNotUnstaking => {
-                assert_eq!(old_application, new_application);
-            }
-            UnstakedResult::UnstakingInProgress => {
-                let expected_active_role_staking_id =
-                    old_application.toggle_stake_id(self.stake_id, StakePurpose::Role);
-                let expected_active_application_staking_id =
-                    old_application.toggle_stake_id(self.stake_id, StakePurpose::Application);
-                let expected_application = hiring::Application {
-                    active_role_staking_id: expected_active_role_staking_id,
-                    active_application_staking_id: expected_active_application_staking_id,
-                    ..old_application
-                };
-                assert_eq!(expected_application, new_application);
-            }
-            UnstakedResult::Unstaked => {
-                let expected_active_role_staking_id =
-                    old_application.toggle_stake_id(self.stake_id, StakePurpose::Role);
-                let expected_active_application_staking_id =
-                    old_application.toggle_stake_id(self.stake_id, StakePurpose::Application);
-
-                if let ApplicationStage::Unstaking {
-                    deactivation_initiated,
-                    cause,
-                } = old_application.stage
-                {
-                    let expected_application_stage = ApplicationStage::Inactive {
-                        deactivation_initiated,
-                        deactivated: FIRST_BLOCK_HEIGHT,
-                        cause,
-                    };
-
-                    let expected_application = hiring::Application {
-                        active_role_staking_id: expected_active_role_staking_id,
-                        active_application_staking_id: expected_active_application_staking_id,
-                        stage: expected_application_stage,
-                        ..old_application
-                    };
-                    assert_eq!(expected_application, new_application);
-                } else {
-                    panic!("old application should be in Unstaking stage")
-                }
-            }
-        };
-    }
-
-    fn assert_opening_content(
-        &self,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        unstaked_result: UnstakedResult,
-    ) {
-        let new_opening = <OpeningById<Test>>::get(self.opening_id);
-        let mut expected_opening = old_opening.clone();
-
-        if let UnstakedResult::Unstaked = unstaked_result {
-            if let hiring::OpeningStage::Active {
-                stage,
-                applications_added,
-                active_application_count,
-                unstaking_application_count,
-                deactivated_application_count,
-            } = old_opening.stage
-            {
-                expected_opening.stage = hiring::OpeningStage::Active {
-                    stage,
-                    applications_added,
-                    active_application_count,
-                    unstaking_application_count: unstaking_application_count - 1,
-                    deactivated_application_count: deactivated_application_count + 1,
-                };
-            } else {
-                panic!("old opening stage MUST be active")
-            }
-        };
-
-        assert_eq!(expected_opening, new_opening);
-    }
-}
-
-#[test]
-fn unstaked_returns_non_existent_stake_id() {
-    build_test_externalities().execute_with(|| {
-        let unstaked_fixture = UnstakedFixture {
-            opening_id: 0,
-            application_id: 0,
-            stake_id: 0,
-        };
-
-        unstaked_fixture.call_and_assert(UnstakedResult::StakeIdNonExistent);
-    });
-}
-
-#[test]
-fn unstaked_returns_application_is_not_unstaking() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-        let application = <ApplicationById<Test>>::get(application_id);
-        let stake_id = application.active_application_staking_id.unwrap();
-
-        let unstaked_fixture = UnstakedFixture {
-            opening_id,
-            application_id,
-            stake_id,
-        };
-
-        unstaked_fixture.call_and_assert(UnstakedResult::ApplicationIsNotUnstaking);
-    });
-}
-
-#[test]
-fn unstaked_returns_unstaking_in_progress() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-        opening_fixture.role_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-        application_fixture.opt_role_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-        let first_application_id = app_application_result.unwrap().application_id_added;
-
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-        application_fixture.opt_role_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let application = <ApplicationById<Test>>::get(first_application_id);
-        let stake_id = application.active_application_staking_id.unwrap();
-
-        let unstaked_fixture = UnstakedFixture {
-            opening_id,
-            application_id: first_application_id,
-            stake_id,
-        };
-
-        unstaked_fixture.call_and_assert(UnstakedResult::UnstakingInProgress);
-    });
-}
-
-#[test]
-fn unstaked_returns_unstaked() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-        let first_application_id = app_application_result.unwrap().application_id_added;
-
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let application = <ApplicationById<Test>>::get(first_application_id);
-        let stake_id = application.active_application_staking_id.unwrap();
-
-        let unstaked_fixture = UnstakedFixture {
-            opening_id,
-            application_id: first_application_id,
-            stake_id,
-        };
-
-        unstaked_fixture.call_and_assert(UnstakedResult::Unstaked);
-
-        TestApplicationDeactivatedHandler::assert_deactivated_application(
-            first_application_id,
-            ApplicationDeactivationCause::CrowdedOut,
-        );
-    });
-}
-
-#[test]
-fn unstaked_returns_unstaked_with_stake_checks() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        assert!(app_application_result.is_ok());
-        let first_application_id = app_application_result.unwrap().application_id_added;
-
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(101));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let application = <ApplicationById<Test>>::get(first_application_id);
-        let stake_id = application.active_application_staking_id.unwrap();
-
-        let unstaked_fixture = UnstakedFixture {
-            opening_id,
-            application_id: first_application_id,
-            stake_id,
-        };
-
-        unstaked_fixture.call_and_assert(UnstakedResult::Unstaked);
-    });
-}

+ 0 - 247
runtime-modules/hiring/src/test/smoke.rs

@@ -1,247 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-use sp_std::collections::btree_set::BTreeSet;
-
-/**
-Main hiring workflow:
-1. add_opening
-1.1 (optional) ensure_can_add_application
-2. add_application
-3. begin_review
-4. fill_opening
-Not covered:
-- begin_accepting_applications
-- unstaked
-- cancel_opening
-- deactive_application
-
-Smoke-test concept:
-https://en.wikipedia.org/wiki/Smoke_testing_(software)
-**/
-#[test]
-fn full_hiring_workflow_successful_path() {
-    build_test_externalities().execute_with(|| {
-        // 1. Add opening
-        let expected_opening_id = 0;
-
-        let activation_at = ActivateOpeningAt::CurrentBlock;
-        let max_review_period_length = 672;
-        let application_rationing_policy = None;
-        let application_staking_policy = None;
-        let role_staking_policy = None;
-        let human_readable_text = "human_readable_text!!!".as_bytes().to_vec();
-        let application_readable_text = "hrt!!".as_bytes().to_vec();
-
-        // Add an opening, check that the returned value is Zero
-        assert_eq!(
-            Hiring::add_opening(
-                activation_at,
-                max_review_period_length,
-                application_rationing_policy,
-                application_staking_policy,
-                role_staking_policy,
-                human_readable_text.clone()
-            ),
-            Ok(expected_opening_id)
-        );
-
-        // Check that next opening id has been updated
-        assert_eq!(Hiring::next_opening_id(), expected_opening_id + 1);
-
-        // Check that our opening actually was added
-        assert!(<OpeningById<Test>>::contains_key(expected_opening_id));
-
-        let found_opening = Hiring::opening_by_id(expected_opening_id);
-
-        // Check opening content
-        assert_eq!(
-            found_opening,
-            Opening {
-                created: FIRST_BLOCK_HEIGHT,
-                stage: OpeningStage::Active {
-                    stage: ActiveOpeningStage::AcceptingApplications {
-                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT
-                    },
-                    applications_added: BTreeSet::new(),
-                    active_application_count: 0,
-                    unstaking_application_count: 0,
-                    deactivated_application_count: 0
-                },
-                max_review_period_length,
-                application_rationing_policy: None,
-                application_staking_policy: None,
-                role_staking_policy: None,
-                human_readable_text: human_readable_text.clone()
-            }
-        );
-        let current_opening_id = expected_opening_id;
-
-        // 1.1 (optional) ensure_can_add_application
-        let ensure_can_add_application_result =
-            Hiring::ensure_can_add_application(current_opening_id, None, None);
-
-        // Check ensure_can_add_application result
-        assert!(ensure_can_add_application_result.is_ok());
-
-        // Check returned content
-        let destructured_app_data = ensure_can_add_application_result.unwrap();
-        let expected = DestructuredApplicationCanBeAddedEvaluation {
-            opening: Opening {
-                created: FIRST_BLOCK_HEIGHT,
-                stage: OpeningStage::Active {
-                    stage: ActiveOpeningStage::AcceptingApplications {
-                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                    },
-                    applications_added: BTreeSet::new(),
-                    active_application_count: 0,
-                    unstaking_application_count: 0,
-                    deactivated_application_count: 0,
-                },
-                max_review_period_length: 672,
-                application_rationing_policy: None,
-                application_staking_policy: None,
-                role_staking_policy: None,
-                human_readable_text: human_readable_text.clone(),
-            },
-            active_stage: ActiveOpeningStage::AcceptingApplications {
-                started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-            },
-            applications_added: BTreeSet::new(),
-            active_application_count: 0,
-            unstaking_application_count: 0,
-            deactivated_application_count: 0,
-            would_get_added_success: ApplicationAddedSuccess::Unconditionally,
-        };
-
-        assert_eq!(destructured_app_data, expected);
-
-        // 2. add_application
-        let add_application_result = Hiring::add_application(
-            current_opening_id,
-            None,
-            None,
-            application_readable_text.clone(),
-        );
-
-        // Check add_application result
-        assert!(add_application_result.is_ok());
-
-        // Check that application wasn't crowded_out
-        let app_added = add_application_result.unwrap();
-        assert_eq!(app_added.application_id_crowded_out, None);
-
-        let new_application_id = app_added.application_id_added;
-
-        // Check that our application actually was added
-        assert!(<ApplicationById<Test>>::contains_key(new_application_id));
-
-        let new_application = Hiring::application_by_id(new_application_id);
-
-        // Check application content
-        assert_eq!(
-            new_application,
-            Application {
-                opening_id: 0,
-                application_index_in_opening: 0,
-                add_to_opening_in_block: FIRST_BLOCK_HEIGHT,
-                active_role_staking_id: None,
-                active_application_staking_id: None,
-                stage: ApplicationStage::Active,
-                human_readable_text: application_readable_text.clone()
-            }
-        );
-
-        // 3. begin_review
-        let begin_review_result = Hiring::begin_review(current_opening_id);
-
-        // Check begin_review result
-        assert!(begin_review_result.is_ok());
-
-        let updated_opening_after_begin_review = Hiring::opening_by_id(current_opening_id);
-
-        let mut expected_added_apps_in_opening = BTreeSet::new();
-        expected_added_apps_in_opening.insert(0);
-
-        // Check updated opening content
-        assert_eq!(
-            updated_opening_after_begin_review,
-            Opening {
-                created: FIRST_BLOCK_HEIGHT,
-                stage: OpeningStage::Active {
-                    stage: ActiveOpeningStage::ReviewPeriod {
-                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                        started_review_period_at_block: FIRST_BLOCK_HEIGHT
-                    },
-                    applications_added: expected_added_apps_in_opening.clone(),
-                    active_application_count: 1,
-                    unstaking_application_count: 0,
-                    deactivated_application_count: 0
-                },
-                max_review_period_length,
-                application_rationing_policy: None,
-                application_staking_policy: None,
-                role_staking_policy: None,
-                human_readable_text: human_readable_text.clone()
-            }
-        );
-        // 4. fill_opening
-        let applications = [new_application_id]
-            .iter()
-            .map(|&x| x)
-            .collect::<BTreeSet<_>>();
-        let fill_opening_result =
-            Hiring::fill_opening(current_opening_id, applications, None, None, None);
-
-        // Check fill_opening result
-        assert!(fill_opening_result.is_ok());
-
-        let updated_opening_fill_opening = Hiring::opening_by_id(current_opening_id);
-
-        // Check updated opening content
-        assert_eq!(
-            updated_opening_fill_opening,
-            Opening {
-                created: FIRST_BLOCK_HEIGHT,
-                stage: OpeningStage::Active {
-                    stage: ActiveOpeningStage::Deactivated {
-                        cause: OpeningDeactivationCause::Filled,
-                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
-                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                        started_review_period_at_block: Some(FIRST_BLOCK_HEIGHT)
-                    },
-                    applications_added: expected_added_apps_in_opening,
-                    active_application_count: 0,
-                    unstaking_application_count: 0,
-                    deactivated_application_count: 1
-                },
-                max_review_period_length,
-                application_rationing_policy: None,
-                application_staking_policy: None,
-                role_staking_policy: None,
-                human_readable_text: human_readable_text.clone()
-            }
-        );
-
-        let current_application_id = new_application_id;
-        let application_after_fill_opening = Hiring::application_by_id(current_application_id);
-
-        // Check updated application content
-        assert_eq!(
-            application_after_fill_opening,
-            Application {
-                opening_id: 0,
-                application_index_in_opening: 0,
-                add_to_opening_in_block: FIRST_BLOCK_HEIGHT,
-                active_role_staking_id: None,
-                active_application_staking_id: None,
-                stage: ApplicationStage::Inactive {
-                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
-                    deactivated: FIRST_BLOCK_HEIGHT,
-                    cause: ApplicationDeactivationCause::Hired
-                },
-                human_readable_text: application_readable_text.clone()
-            }
-        );
-    });
-}

+ 0 - 83
runtime-modules/hiring/src/test/staking_module/get_opt_stake_amount.rs

@@ -1,83 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-use mockall::predicate::*;
-
-#[test]
-fn get_opt_stake_amount_succeeds_with_empty_stake_id() {
-    build_test_externalities().execute_with(|| {
-        let no_stake = Hiring::get_opt_stake_amount(None);
-
-        assert_eq!(no_stake, 0)
-    })
-}
-
-#[test]
-#[should_panic]
-fn get_opt_stake_amount_panics_with_non_existing_stake() {
-    build_test_externalities().execute_with(|| {
-        Hiring::get_opt_stake_amount(Some(0));
-    });
-}
-
-#[test]
-#[should_panic]
-fn get_opt_stake_amount_panics_with_incorrect_stake_status() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_stake_exists()
-                    .with(eq(0))
-                    .times(1)
-                    .returning(|_| true);
-
-                mock.expect_get_stake()
-                    .with(eq(0))
-                    .times(1)
-                    .returning(|_| stake::Stake {
-                        created: 1,
-                        staking_status: stake::StakingStatus::NotStaked,
-                    });
-
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            Hiring::get_opt_stake_amount(Some(0));
-        })
-    })
-}
-
-#[test]
-fn get_opt_stake_amount_succeeds_with_existing_stake() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_stake_exists()
-                    .with(eq(0))
-                    .times(1)
-                    .returning(|_| true);
-
-                mock.expect_get_stake()
-                    .with(eq(0))
-                    .times(1)
-                    .returning(|_| stake::Stake {
-                        created: 1,
-                        staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                            staked_amount: 100,
-                            staked_status: stake::StakedStatus::Normal,
-                            next_slash_id: 0,
-                            ongoing_slashes: BTreeMap::new(),
-                        }),
-                    });
-
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock.clone());
-
-            assert_eq!(Hiring::get_opt_stake_amount(Some(0)), 100);
-        })
-    });
-}

+ 0 - 72
runtime-modules/hiring/src/test/staking_module/infallible_stake_initiation_on_application.rs

@@ -1,72 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-#[test]
-#[should_panic]
-fn infallible_stake_initiation_on_application_panics_on_existed_stake() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_create_stake().times(1).returning(|| 10);
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            let application_id = 10;
-            <ApplicationIdByStakingId<Test>>::insert(10, application_id);
-
-            Hiring::infallible_stake_initiation_on_application(
-                stake::NegativeImbalance::<Test>::new(100),
-                &application_id,
-            );
-        });
-    });
-}
-
-#[test]
-#[should_panic]
-fn infallible_stake_initiation_on_application_panics_on_unsuccessful_staking() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_create_stake().times(1).returning(|| 10);
-                mock.expect_stake()
-                    .times(1)
-                    .returning(|_, _| Err(StakeActionError::StakeNotFound));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            let application_id = 10;
-            Hiring::infallible_stake_initiation_on_application(
-                stake::NegativeImbalance::<Test>::new(100),
-                &application_id,
-            );
-        });
-    });
-}
-
-#[test]
-fn infallible_stake_initiation_on_application_succeeds() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_create_stake().times(1).returning(|| 10);
-                mock.expect_stake().times(1).returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            let application_id = 10;
-            let staking_result = Hiring::infallible_stake_initiation_on_application(
-                stake::NegativeImbalance::<Test>::new(100),
-                &application_id,
-            );
-
-            assert_eq!(staking_result, 10);
-        });
-    });
-}

+ 0 - 111
runtime-modules/hiring/src/test/staking_module/initiate_application_deactivations.rs

@@ -1,111 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-type ApplicationMap = BTreeMap<ApplicationId, hiring::Application<OpeningId, BlockNumber, StakeId>>;
-
-struct InitiateApplicationDeactivationsFixture {
-    pub applications: ApplicationMap,
-    pub application_stake_unstaking_period: Option<BlockNumber>,
-    pub role_stake_unstaking_period: Option<BlockNumber>,
-    pub cause: ApplicationDeactivationCause,
-}
-
-impl InitiateApplicationDeactivationsFixture {
-    fn default_for_applications(
-        applications: ApplicationMap,
-    ) -> InitiateApplicationDeactivationsFixture {
-        InitiateApplicationDeactivationsFixture {
-            applications,
-            application_stake_unstaking_period: None,
-            role_stake_unstaking_period: None,
-            cause: ApplicationDeactivationCause::External,
-        }
-    }
-
-    fn initiate_application_deactivations(&self) -> ApplicationsDeactivationsInitiationResult {
-        Hiring::initiate_application_deactivations(
-            &self.applications,
-            self.application_stake_unstaking_period,
-            self.role_stake_unstaking_period,
-            self.cause,
-        )
-    }
-
-    fn call_and_assert(&self, expected_result: ApplicationsDeactivationsInitiationResult) {
-        let actual_result = self.initiate_application_deactivations();
-
-        assert_eq!(expected_result, actual_result);
-    }
-}
-
-#[test]
-fn initiate_application_deactivations_succeeds_with_deactivated_result() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let application = <ApplicationById<Test>>::get(application_id);
-
-        let mut applications = ApplicationMap::new();
-        applications.insert(application_id, application);
-
-        let iad_fixture =
-            InitiateApplicationDeactivationsFixture::default_for_applications(applications);
-
-        iad_fixture.call_and_assert(ApplicationsDeactivationsInitiationResult {
-            number_of_deactivated_applications: 1,
-            number_of_unstaking_applications: 0,
-        });
-    });
-}
-
-#[test]
-fn initiate_application_deactivations_succeeds_with_unstaking_result() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let application = <ApplicationById<Test>>::get(application_id);
-
-            let mut applications = ApplicationMap::new();
-            applications.insert(application_id, application);
-
-            let iad_fixture =
-                InitiateApplicationDeactivationsFixture::default_for_applications(applications);
-
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            iad_fixture.call_and_assert(ApplicationsDeactivationsInitiationResult {
-                number_of_deactivated_applications: 0,
-                number_of_unstaking_applications: 1,
-            });
-        });
-    });
-}

+ 0 - 8
runtime-modules/hiring/src/test/staking_module/mod.rs

@@ -1,8 +0,0 @@
-mod get_opt_stake_amount;
-mod infallible_stake_initiation_on_application;
-mod initiate_application_deactivations;
-mod opt_infallible_unstake;
-mod try_to_initiate_application_deactivation;
-mod would_application_get_added;
-
-use super::*;

+ 0 - 39
runtime-modules/hiring/src/test/staking_module/opt_infallible_unstake.rs

@@ -1,39 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-#[test]
-fn opt_infallible_unstake_succeeds_with_empty_stake() {
-    build_test_externalities().execute_with(|| {
-        let unstake_result = Hiring::opt_infallible_unstake(None, None);
-
-        assert_eq!(unstake_result, false);
-    });
-}
-
-#[test]
-#[should_panic]
-fn opt_infallible_unstake_panics_with_invalid_stake() {
-    build_test_externalities().execute_with(|| {
-        Hiring::opt_infallible_unstake(Some(10), None);
-    });
-}
-
-#[test]
-fn opt_infallible_unstake_succeeds() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            let unstake_result = Hiring::opt_infallible_unstake(Some(10), Some(10));
-
-            assert_eq!(unstake_result, true);
-        });
-    });
-}

+ 0 - 391
runtime-modules/hiring/src/test/staking_module/try_to_initiate_application_deactivation.rs

@@ -1,391 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-struct TryToInitiateApplicationDeactivationFixture<'a> {
-    pub application: &'a Application<OpeningId, BlockNumber, StakeId>,
-    pub application_id: ApplicationId,
-    pub application_stake_unstaking_period: Option<BlockNumber>,
-    pub role_stake_unstaking_period: Option<BlockNumber>,
-    pub cause: hiring::ApplicationDeactivationCause,
-}
-
-impl<'a> TryToInitiateApplicationDeactivationFixture<'a> {
-    pub fn default_for_application(
-        application_id: ApplicationId,
-        application: &'a Application<OpeningId, BlockNumber, StakeId>,
-    ) -> TryToInitiateApplicationDeactivationFixture<'a> {
-        TryToInitiateApplicationDeactivationFixture {
-            application,
-            application_id,
-            application_stake_unstaking_period: None,
-            role_stake_unstaking_period: None,
-            cause: ApplicationDeactivationCause::NotHired,
-        }
-    }
-
-    fn call_and_assert(&self, expected_result: ApplicationDeactivationInitiationResult) {
-        let old_application = <ApplicationById<Test>>::get(self.application_id);
-        let old_opening_state = <OpeningById<Test>>::get(old_application.opening_id);
-
-        let actual_result = self.try_to_initiate_application_deactivation();
-
-        assert_eq!(expected_result, actual_result);
-
-        self.assert_application_content(old_application.clone(), actual_result.clone());
-
-        self.assert_opening_content(old_application.opening_id, old_opening_state, actual_result);
-    }
-
-    fn try_to_initiate_application_deactivation(&self) -> ApplicationDeactivationInitiationResult {
-        Hiring::try_to_initiate_application_deactivation(
-            self.application,
-            self.application_id,
-            self.application_stake_unstaking_period,
-            self.role_stake_unstaking_period,
-            self.cause,
-        )
-    }
-
-    fn assert_application_content(
-        &self,
-        old_application_state: Application<OpeningId, BlockNumber, StakeId>,
-        result: ApplicationDeactivationInitiationResult,
-    ) {
-        let actual_application_state = <ApplicationById<Test>>::get(self.application_id);
-
-        let expected_application_state = match result {
-            ApplicationDeactivationInitiationResult::Deactivated => Application {
-                stage: ApplicationStage::Inactive {
-                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
-                    deactivated: FIRST_BLOCK_HEIGHT,
-                    cause: self.cause,
-                },
-                ..old_application_state
-            },
-            ApplicationDeactivationInitiationResult::Unstaking => Application {
-                stage: ApplicationStage::Unstaking {
-                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
-                    cause: self.cause,
-                },
-                ..old_application_state
-            },
-            ApplicationDeactivationInitiationResult::Ignored => old_application_state,
-        };
-
-        assert_eq!(expected_application_state, actual_application_state);
-    }
-
-    fn assert_opening_content(
-        &self,
-        opening_id: OpeningId,
-        old_opening: Opening<Balance, BlockNumber, ApplicationId>,
-        result: ApplicationDeactivationInitiationResult,
-    ) {
-        // invalid opening stages are not supported
-
-        // check for opening existence
-        if !<OpeningById<Test>>::contains_key(opening_id) {
-            return;
-        }
-
-        // check only for active opening
-        if let OpeningStage::Active {
-            stage,
-            applications_added,
-            active_application_count,
-            unstaking_application_count,
-            deactivated_application_count,
-        } = old_opening.stage
-        {
-            // check only for accepting application stage
-            if let ActiveOpeningStage::AcceptingApplications { .. } = stage {
-                let mut expected_active_application_count = active_application_count;
-                let mut expected_deactivated_application_count = deactivated_application_count;
-                let mut expected_unstaking_application_count = unstaking_application_count;
-
-                match result {
-                    ApplicationDeactivationInitiationResult::Deactivated => {
-                        expected_active_application_count -= 1;
-                        expected_deactivated_application_count += 1;
-                    }
-                    ApplicationDeactivationInitiationResult::Unstaking => {
-                        expected_active_application_count -= 1;
-                        expected_unstaking_application_count += 1;
-                    }
-                    ApplicationDeactivationInitiationResult::Ignored => {}
-                }
-
-                let expected_opening = Opening {
-                    stage: OpeningStage::Active {
-                        stage: ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
-                        },
-                        applications_added,
-                        active_application_count: expected_active_application_count,
-                        unstaking_application_count: expected_unstaking_application_count,
-                        deactivated_application_count: expected_deactivated_application_count,
-                    },
-                    ..old_opening
-                };
-
-                let new_opening_state = <OpeningById<Test>>::get(opening_id);
-                assert_eq!(new_opening_state, expected_opening);
-            }
-        }
-    }
-}
-
-#[test]
-fn try_to_initiate_application_deactivation_succeeds_with_ignored_result() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let deactivate_application_fixture =
-            DeactivateApplicationFixture::default_for_application_id(application_id);
-
-        assert!(deactivate_application_fixture
-            .deactivate_application()
-            .is_ok());
-
-        let application = <ApplicationById<Test>>::get(application_id);
-        let ttiad_fixture = TryToInitiateApplicationDeactivationFixture::default_for_application(
-            application_id,
-            &application,
-        );
-
-        ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Ignored);
-    });
-}
-
-#[test]
-#[should_panic]
-fn try_to_initiate_application_deactivation_panics_because_of_not_active_opening() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let application = <ApplicationById<Test>>::get(application_id);
-
-        // provide incorrect opening (invalid stage)
-        let mut opening = <OpeningById<Test>>::get(opening_id);
-        opening.stage = OpeningStage::WaitingToBegin { begins_at_block: 0 };
-        <OpeningById<Test>>::insert(opening_id, opening);
-
-        let ttiad_fixture = TryToInitiateApplicationDeactivationFixture::default_for_application(
-            application_id,
-            &application,
-        );
-
-        ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Ignored);
-    });
-}
-
-#[test]
-#[should_panic]
-fn try_to_initiate_application_deactivation_panics_because_of_opening_with_no_applications() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let application = <ApplicationById<Test>>::get(application_id);
-
-        // provide incorrect opening (no applications)
-        let add_opening_result = opening_fixture.add_opening();
-        let new_opening_id = add_opening_result.unwrap();
-        let new_opening = <OpeningById<Test>>::get(new_opening_id);
-        <OpeningById<Test>>::insert(opening_id, new_opening);
-
-        let ttiad_fixture = TryToInitiateApplicationDeactivationFixture::default_for_application(
-            application_id,
-            &application,
-        );
-
-        ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Ignored);
-    });
-}
-
-#[test]
-fn try_to_initiate_application_deactivation_succeeds_with_deactivated_result() {
-    build_test_externalities().execute_with(|| {
-        let opening_fixture = AddOpeningFixture::default();
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let application = <ApplicationById<Test>>::get(application_id);
-
-        let ttiad_fixture = TryToInitiateApplicationDeactivationFixture::default_for_application(
-            application_id,
-            &application,
-        );
-
-        ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Deactivated);
-    });
-}
-
-#[test]
-fn try_to_initiate_application_deactivation_succeeds_with_single_application_unstaking() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let application = <ApplicationById<Test>>::get(application_id);
-
-            let ttiad_fixture =
-                TryToInitiateApplicationDeactivationFixture::default_for_application(
-                    application_id,
-                    &application,
-                );
-
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Unstaking);
-        });
-    });
-}
-
-#[test]
-fn try_to_initiate_application_deactivation_succeeds_with_application_and_role_unstaking() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let application = <ApplicationById<Test>>::get(application_id);
-
-            let ttiad_fixture =
-                TryToInitiateApplicationDeactivationFixture::default_for_application(
-                    application_id,
-                    &application,
-                );
-
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_initiate_unstaking()
-                    .times(2)
-                    .returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Unstaking);
-        });
-    });
-}
-
-#[test]
-fn try_to_initiate_application_deactivation_succeeds_hired_cause_and_application_only_unstaking() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-            opening_fixture.role_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-            application_fixture.opt_role_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let application = <ApplicationById<Test>>::get(application_id);
-
-            let mut ttiad_fixture =
-                TryToInitiateApplicationDeactivationFixture::default_for_application(
-                    application_id,
-                    &application,
-                );
-            ttiad_fixture.cause = ApplicationDeactivationCause::Hired;
-
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-                mock.expect_initiate_unstaking()
-                    .times(1)
-                    .returning(|_, _| Ok(()));
-                Rc::new(RefCell::new(mock))
-            };
-            set_stake_handler_impl(mock);
-
-            ttiad_fixture.call_and_assert(ApplicationDeactivationInitiationResult::Unstaking);
-        });
-    });
-}

+ 0 - 221
runtime-modules/hiring/src/test/staking_module/would_application_get_added.rs

@@ -1,221 +0,0 @@
-use super::*;
-use crate::mock::*;
-
-#[derive(Default)]
-struct WouldApplicationGetAddedFixture {
-    possible_opening_application_rationing_policy: Option<ApplicationRationingPolicy>,
-    opening_applicants: BTreeSet<ApplicationId>,
-    opt_role_stake_balance: Option<Balance>,
-    opt_application_stake_balance: Option<Balance>,
-}
-
-impl WouldApplicationGetAddedFixture {
-    fn call_and_assert(&self, expected_result: ApplicationWouldGetAddedEvaluation<Test>) {
-        let wagaf_result = self.would_application_get_added();
-
-        assert_eq!(wagaf_result, expected_result);
-    }
-
-    fn would_application_get_added(&self) -> ApplicationWouldGetAddedEvaluation<Test> {
-        Hiring::would_application_get_added(
-            &self.possible_opening_application_rationing_policy,
-            &self.opening_applicants,
-            &self.opt_role_stake_balance,
-            &self.opt_application_stake_balance,
-        )
-    }
-}
-
-#[test]
-fn would_application_get_added_with_no_rationing_policy() {
-    build_test_externalities().execute_with(|| {
-        let wagaf = WouldApplicationGetAddedFixture::default();
-
-        wagaf.call_and_assert(ApplicationWouldGetAddedEvaluation::Yes(
-            ApplicationAddedSuccess::Unconditionally,
-        ));
-    });
-}
-
-#[test]
-fn would_application_get_added_with_zero_opening_applicants() {
-    build_test_externalities().execute_with(|| {
-        let mut wagaf = WouldApplicationGetAddedFixture::default();
-        wagaf.possible_opening_application_rationing_policy =
-            Some(hiring::ApplicationRationingPolicy {
-                max_active_applicants: 1,
-            });
-
-        wagaf.call_and_assert(ApplicationWouldGetAddedEvaluation::Yes(
-            ApplicationAddedSuccess::Unconditionally,
-        ));
-    });
-}
-
-#[test]
-fn would_application_get_added_with_too_low_stake() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut wagaf = WouldApplicationGetAddedFixture::default();
-        wagaf.possible_opening_application_rationing_policy =
-            Some(hiring::ApplicationRationingPolicy {
-                max_active_applicants: 1,
-            });
-        wagaf.opening_applicants.insert(application_id);
-        wagaf.opt_application_stake_balance = Some(99);
-
-        wagaf.call_and_assert(ApplicationWouldGetAddedEvaluation::No);
-    });
-}
-
-#[test]
-fn would_application_get_added_with_too_low_stake_with_mocks() {
-    handle_mock(|| {
-        build_test_externalities().execute_with(|| {
-            let mock = {
-                let mut mock = crate::MockStakeHandler::<Test>::new();
-
-                mock.expect_stake().times(1).returning(|_, _| Ok(()));
-                mock.expect_stake_exists().times(2).returning(|_| true);
-                mock.expect_create_stake().times(1).returning(|| 0);
-                mock.expect_get_stake().returning(|_| stake::Stake {
-                    created: 1,
-                    staking_status: stake::StakingStatus::Staked(stake::StakedState {
-                        staked_amount: 101,
-                        staked_status: stake::StakedStatus::Normal,
-                        next_slash_id: 0,
-                        ongoing_slashes: BTreeMap::new(),
-                    }),
-                });
-
-                Rc::new(sp_std::cell::RefCell::new(mock))
-            };
-
-            set_stake_handler_impl(mock.clone());
-
-            let mut opening_fixture = AddOpeningFixture::default();
-            opening_fixture.application_rationing_policy =
-                Some(hiring::ApplicationRationingPolicy {
-                    max_active_applicants: 1,
-                });
-            opening_fixture.application_staking_policy = Some(StakingPolicy {
-                amount: 100,
-                amount_mode: StakingAmountLimitMode::AtLeast,
-                crowded_out_unstaking_period_length: None,
-                review_period_expired_unstaking_period_length: None,
-            });
-
-            let add_opening_result = opening_fixture.add_opening();
-            let opening_id = add_opening_result.unwrap();
-
-            let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-            application_fixture.opt_application_stake_imbalance =
-                Some(stake::NegativeImbalance::<Test>::new(100));
-
-            let app_application_result = application_fixture.add_application();
-            let application_id = app_application_result.unwrap().application_id_added;
-
-            let mut wagaf = WouldApplicationGetAddedFixture::default();
-            wagaf.possible_opening_application_rationing_policy =
-                Some(hiring::ApplicationRationingPolicy {
-                    max_active_applicants: 1,
-                });
-            wagaf.opening_applicants.insert(application_id);
-            wagaf.opt_application_stake_balance = Some(99);
-
-            wagaf.call_and_assert(ApplicationWouldGetAddedEvaluation::No);
-        });
-    });
-}
-
-#[test]
-fn would_application_get_added_with_crowding_out() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        let app_application_result = application_fixture.add_application();
-        let application_id = app_application_result.unwrap().application_id_added;
-
-        let mut wagaf = WouldApplicationGetAddedFixture::default();
-        wagaf.possible_opening_application_rationing_policy =
-            Some(hiring::ApplicationRationingPolicy {
-                max_active_applicants: 1,
-            });
-        wagaf.opening_applicants.insert(application_id);
-        wagaf.opt_application_stake_balance = Some(101);
-
-        wagaf.call_and_assert(ApplicationWouldGetAddedEvaluation::Yes(
-            ApplicationAddedSuccess::CrowdsOutExistingApplication(application_id),
-        ));
-    });
-}
-#[test]
-#[should_panic]
-fn would_application_get_added_panics_with_bad_params() {
-    build_test_externalities().execute_with(|| {
-        let mut opening_fixture = AddOpeningFixture::default();
-        opening_fixture.application_rationing_policy = Some(hiring::ApplicationRationingPolicy {
-            max_active_applicants: 1,
-        });
-        opening_fixture.application_staking_policy = Some(StakingPolicy {
-            amount: 100,
-            amount_mode: StakingAmountLimitMode::AtLeast,
-            crowded_out_unstaking_period_length: None,
-            review_period_expired_unstaking_period_length: None,
-        });
-
-        let add_opening_result = opening_fixture.add_opening();
-        let opening_id = add_opening_result.unwrap();
-
-        let mut application_fixture = AddApplicationFixture::default_for_opening(opening_id);
-        application_fixture.opt_application_stake_imbalance =
-            Some(stake::NegativeImbalance::<Test>::new(100));
-
-        assert!(application_fixture.add_application().is_ok());
-
-        let mut wagaf = WouldApplicationGetAddedFixture::default();
-        wagaf.possible_opening_application_rationing_policy =
-            Some(hiring::ApplicationRationingPolicy {
-                max_active_applicants: 0,
-            });
-        wagaf.opt_application_stake_balance = Some(100);
-
-        wagaf.would_application_get_added();
-    });
-}

+ 0 - 4
runtime-modules/proposals/codex/Cargo.toml

@@ -16,9 +16,7 @@ staking = { package = 'pallet-staking', default-features = false, git = 'https:/
 pallet-timestamp = { package = 'pallet-timestamp', 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'}
 membership = { package = 'pallet-membership', default-features = false, path = '../../membership'}
-stake = { package = 'pallet-stake', default-features = false, path = '../../stake'}
 governance = { package = 'pallet-governance', default-features = false, path = '../../governance'}
-hiring = { package = 'pallet-hiring', default-features = false, path = '../../hiring'}
 minting = { package = 'pallet-token-mint', default-features = false, path = '../../token-minting'}
 working-group = { package = 'pallet-working-group', default-features = false, path = '../../working-group'}
 common = { package = 'pallet-common', default-features = false, path = '../../common'}
@@ -49,9 +47,7 @@ std = [
     'pallet-timestamp/std',
     'balances/std',
     'membership/std',
-    'stake/std',
     'governance/std',
-    'hiring/std',
     'minting/std',
     'working-group/std',
     'common/std',

+ 0 - 1
runtime-modules/proposals/codex/src/lib.rs

@@ -106,7 +106,6 @@ pub trait Trait:
     + proposals_discussion::Trait
     + membership::Trait
     + governance::election::Trait
-    + hiring::Trait
     + staking::Trait
 {
     /// Defines max allowed text proposal length.

+ 0 - 16
runtime-modules/proposals/codex/src/tests/mock.rs

@@ -29,7 +29,6 @@ parameter_types! {
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl_outer_dispatch! {
@@ -67,14 +66,6 @@ impl balances::Trait for Test {
     type MaxLocks = ();
 }
 
-impl stake::Trait for Test {
-    type Currency = Balances;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
 parameter_types! {
     pub const CancellationFee: u64 = 5;
     pub const RejectionFee: u64 = 3;
@@ -246,13 +237,6 @@ impl recurring_rewards::Trait for Test {
     type RewardRelationshipId = u64;
 }
 
-impl hiring::Trait for Test {
-    type OpeningId = u64;
-    type ApplicationId = u64;
-    type ApplicationDeactivatedHandler = ();
-    type StakeHandlerProvider = hiring::Module<Self>;
-}
-
 pallet_staking_reward_curve::build! {
     const I_NPOS: PiecewiseLinear<'static> = curve!(
         min_inflation: 0_025_000,

+ 0 - 1
runtime-modules/proposals/discussion/src/tests/mock.rs

@@ -27,7 +27,6 @@ parameter_types! {
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 parameter_types! {

+ 0 - 1
runtime-modules/proposals/engine/src/tests/mock/mod.rs

@@ -171,7 +171,6 @@ parameter_types! {
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl frame_system::Trait for Test {

+ 0 - 2
runtime-modules/service-discovery/Cargo.toml

@@ -20,8 +20,6 @@ sp-core = { package = 'sp-core', default-features = false, git = 'https://github
 pallet-timestamp = { package = 'pallet-timestamp', 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'}
 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'}
 common = { package = 'pallet-common', default-features = false, path = '../common'}

+ 0 - 16
runtime-modules/service-discovery/src/mock.rs

@@ -50,7 +50,6 @@ parameter_types! {
     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;
     pub const MembershipFee: u64 = 100;
 }
@@ -87,26 +86,11 @@ impl Trait for Test {
     type Event = MetaEvent;
 }
 
-impl hiring::Trait for Test {
-    type OpeningId = u64;
-    type ApplicationId = u64;
-    type ApplicationDeactivatedHandler = ();
-    type StakeHandlerProvider = hiring::Module<Self>;
-}
-
 impl minting::Trait for Test {
     type Currency = Balances;
     type MintId = u64;
 }
 
-impl stake::Trait for Test {
-    type Currency = Balances;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
 impl membership::Trait for Test {
     type Event = MetaEvent;
     type MemberId = u64;

+ 0 - 30
runtime-modules/stake/Cargo.toml

@@ -1,30 +0,0 @@
-[package]
-name = 'pallet-stake'
-version = '3.1.0'
-authors = ['Joystream contributors']
-edition = '2018'
-
-[dependencies]
-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'}
-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'}
-
-[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'}
-balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
-
-[features]
-default = ['std']
-std = [
-	'codec/std',
-	'sp-std/std',
-	'frame-support/std',
-	'frame-system/std',
-	'sp-arithmetic/std',
-	'sp-runtime/std',
-]

+ 0 - 164
runtime-modules/stake/src/errors.rs

@@ -1,164 +0,0 @@
-#[derive(Debug, Eq, PartialEq)]
-pub enum StakeActionError<ErrorType> {
-    StakeNotFound,
-    Error(ErrorType),
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum TransferFromAccountError {
-    InsufficientBalance,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum StakingError {
-    CannotStakeZero,
-    CannotStakeLessThanMinimumBalance,
-    AlreadyStaked,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum StakingFromAccountError {
-    StakingError(StakingError),
-    InsufficientBalanceInSourceAccount,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum IncreasingStakeError {
-    NotStaked,
-    CannotChangeStakeByZero,
-    CannotIncreaseStakeWhileUnstaking,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum IncreasingStakeFromAccountError {
-    IncreasingStakeError(IncreasingStakeError),
-    InsufficientBalanceInSourceAccount,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum DecreasingStakeError {
-    NotStaked,
-    CannotChangeStakeByZero,
-    CannotDecreaseStakeWhileOngoingSlahes,
-    InsufficientStake,
-    CannotDecreaseStakeWhileUnstaking,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum ImmediateSlashingError {
-    NotStaked,
-    SlashAmountShouldBeGreaterThanZero,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum InitiateSlashingError {
-    NotStaked,
-    SlashPeriodShouldBeGreaterThanZero,
-    SlashAmountShouldBeGreaterThanZero,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum PauseSlashingError {
-    SlashNotFound,
-    NotStaked,
-    AlreadyPaused,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum ResumeSlashingError {
-    SlashNotFound,
-    NotStaked,
-    NotPaused,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum CancelSlashingError {
-    SlashNotFound,
-    NotStaked,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum UnstakingError {
-    NotStaked,
-    AlreadyUnstaking,
-    CannotUnstakeWhileSlashesOngoing,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum InitiateUnstakingError {
-    UnstakingError(UnstakingError),
-    UnstakingPeriodShouldBeGreaterThanZero,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum PauseUnstakingError {
-    NotStaked,
-    NotUnstaking,
-    AlreadyPaused,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum ResumeUnstakingError {
-    NotStaked,
-    NotUnstaking,
-    NotPaused,
-}
-
-impl<ErrorType> From<ErrorType> for StakeActionError<ErrorType> {
-    fn from(e: ErrorType) -> StakeActionError<ErrorType> {
-        StakeActionError::Error(e)
-    }
-}
-
-impl From<StakingError> for StakeActionError<StakingFromAccountError> {
-    fn from(e: StakingError) -> StakeActionError<StakingFromAccountError> {
-        StakeActionError::Error(StakingFromAccountError::StakingError(e))
-    }
-}
-
-impl From<TransferFromAccountError> for StakeActionError<StakingFromAccountError> {
-    fn from(e: TransferFromAccountError) -> StakeActionError<StakingFromAccountError> {
-        match e {
-            TransferFromAccountError::InsufficientBalance => {
-                StakeActionError::Error(StakingFromAccountError::InsufficientBalanceInSourceAccount)
-            }
-        }
-    }
-}
-
-impl From<IncreasingStakeError> for StakeActionError<IncreasingStakeFromAccountError> {
-    fn from(e: IncreasingStakeError) -> StakeActionError<IncreasingStakeFromAccountError> {
-        StakeActionError::Error(IncreasingStakeFromAccountError::IncreasingStakeError(e))
-    }
-}
-
-impl From<TransferFromAccountError> for StakeActionError<IncreasingStakeFromAccountError> {
-    fn from(e: TransferFromAccountError) -> StakeActionError<IncreasingStakeFromAccountError> {
-        match e {
-            TransferFromAccountError::InsufficientBalance => StakeActionError::Error(
-                IncreasingStakeFromAccountError::InsufficientBalanceInSourceAccount,
-            ),
-        }
-    }
-}
-
-impl From<StakeActionError<IncreasingStakeError>>
-    for StakeActionError<IncreasingStakeFromAccountError>
-{
-    fn from(
-        e: StakeActionError<IncreasingStakeError>,
-    ) -> StakeActionError<IncreasingStakeFromAccountError> {
-        match e {
-            StakeActionError::StakeNotFound => StakeActionError::StakeNotFound,
-            StakeActionError::Error(increasing_stake_error) => StakeActionError::Error(
-                IncreasingStakeFromAccountError::IncreasingStakeError(increasing_stake_error),
-            ),
-        }
-    }
-}
-
-impl From<UnstakingError> for StakeActionError<InitiateUnstakingError> {
-    fn from(e: UnstakingError) -> StakeActionError<InitiateUnstakingError> {
-        StakeActionError::Error(InitiateUnstakingError::UnstakingError(e))
-    }
-}

+ 0 - 1174
runtime-modules/stake/src/lib.rs

@@ -1,1174 +0,0 @@
-// Ensure we're `no_std` when compiling for Wasm.
-#![cfg_attr(not(feature = "std"), no_std)]
-
-use codec::{Codec, Decode, Encode};
-use frame_support::storage::IterableStorageMap;
-use frame_support::traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons};
-use frame_support::{decl_module, decl_storage, ensure, Parameter};
-use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
-use sp_runtime::traits::{AccountIdConversion, MaybeSerialize, Member};
-use sp_runtime::ModuleId;
-use sp_std::collections::btree_map::BTreeMap;
-use sp_std::prelude::*;
-
-mod errors;
-pub use errors::*;
-mod macroes;
-mod mock;
-mod tests;
-
-pub type BalanceOf<T> =
-    <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
-
-pub type NegativeImbalance<T> =
-    <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
-
-pub trait Trait: frame_system::Trait + Sized {
-    /// The currency that is managed by the module
-    type Currency: Currency<Self::AccountId>;
-
-    /// ModuleId for computing deterministic AccountId for the module
-    type StakePoolId: Get<[u8; 8]>;
-
-    /// Type that will handle various staking events
-    type StakingEventsHandler: StakingEventsHandler<Self>;
-
-    /// The type used as a stake identifier.
-    type StakeId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
-
-    /// The type used as slash identifier.
-    type SlashId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq
-        + Ord; //required to be a key in BTreeMap
-}
-
-pub trait StakingEventsHandler<T: Trait> {
-    /// Handler for unstaking event.
-    /// The handler is informed of the amount that was unstaked, and the value removed from stake is passed as a negative imbalance.
-    /// The handler is responsible to consume part or all of the value (for example by moving it into an account). The remainder
-    /// of the value that is not consumed should be returned as a negative imbalance.
-    fn unstaked(
-        id: &T::StakeId,
-        unstaked_amount: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T>;
-
-    /// Handler for slashing event.
-    /// NB: actually_slashed can be less than amount of the slash itself if the
-    /// claim amount on the stake cannot cover it fully.
-    /// The SlashId is optional, as slashing may not be associated with a slashing that was initiated, but was an immediate slashing.
-    /// For Immediate slashes, the stake may have transitioned to NotStaked so handler should not assume the state
-    /// is still in staked status.
-    fn slashed(
-        id: &T::StakeId,
-        slash_id: Option<T::SlashId>,
-        slashed_amount: BalanceOf<T>,
-        remaining_stake: BalanceOf<T>,
-        remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T>;
-}
-
-/// Default implementation just destroys the unstaked or slashed value
-impl<T: Trait> StakingEventsHandler<T> for () {
-    fn unstaked(
-        _id: &T::StakeId,
-        _unstaked_amount: BalanceOf<T>,
-        _remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        NegativeImbalance::<T>::zero()
-    }
-
-    fn slashed(
-        _id: &T::StakeId,
-        _slash_id: Option<T::SlashId>,
-        _slahed_amount: BalanceOf<T>,
-        _remaining_stake: BalanceOf<T>,
-        _remaining_imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        NegativeImbalance::<T>::zero()
-    }
-}
-
-/// Helper implementation so we can chain multiple handlers by grouping handlers in tuple pairs.
-/// For example for three handlers, A, B and C we can set the StakingEventHandler type on the trait to:
-/// type StakingEventHandler = ((A, B), C)
-/// Individual handlers are expected consume in full or in part the negative imbalance and return any unconsumed value.
-/// The unconsumed value is then passed to the next handler in the chain.
-impl<T: Trait, X: StakingEventsHandler<T>, Y: StakingEventsHandler<T>> StakingEventsHandler<T>
-    for (X, Y)
-{
-    fn unstaked(
-        id: &T::StakeId,
-        unstaked_amount: BalanceOf<T>,
-        imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        let unused_imbalance = X::unstaked(id, unstaked_amount, imbalance);
-        Y::unstaked(id, unstaked_amount, unused_imbalance)
-    }
-
-    fn slashed(
-        id: &T::StakeId,
-        slash_id: Option<T::SlashId>,
-        slashed_amount: BalanceOf<T>,
-        remaining_stake: BalanceOf<T>,
-        imbalance: NegativeImbalance<T>,
-    ) -> NegativeImbalance<T> {
-        let unused_imbalance = X::slashed(id, slash_id, slashed_amount, remaining_stake, imbalance);
-        Y::slashed(
-            id,
-            slash_id,
-            slashed_amount,
-            remaining_stake,
-            unused_imbalance,
-        )
-    }
-}
-
-#[derive(Encode, Decode, Copy, Clone, Debug, Default, Eq, PartialEq)]
-pub struct Slash<BlockNumber, Balance> {
-    /// The block where slashing was initiated.
-    pub started_at_block: BlockNumber,
-
-    /// Whether slashing is in active, or conversley paused state.
-    /// Blocks are only counted towards slashing execution delay when active.
-    pub is_active: bool,
-
-    /// The number blocks which must be finalised while in the active period before the slashing can be executed
-    pub blocks_remaining_in_active_period_for_slashing: BlockNumber,
-
-    /// Amount to slash
-    pub slash_amount: Balance,
-}
-
-#[derive(Encode, Decode, Debug, Default, Eq, PartialEq)]
-pub struct UnstakingState<BlockNumber> {
-    /// The block where the unstaking was initiated
-    pub started_at_block: BlockNumber,
-
-    /// Whether unstaking is in active, or conversely paused state.
-    /// Blocks are only counted towards unstaking period when active.
-    pub is_active: bool,
-
-    /// The number blocks which must be finalised while in the active period before the unstaking is finished
-    pub blocks_remaining_in_active_period_for_unstaking: BlockNumber,
-}
-
-#[derive(Encode, Decode, Debug, Eq, PartialEq)]
-pub enum StakedStatus<BlockNumber> {
-    /// Baseline staking status, nothing is happening.
-    Normal,
-
-    /// Unstaking is under way.
-    Unstaking(UnstakingState<BlockNumber>),
-}
-
-impl<BlockNumber> Default for StakedStatus<BlockNumber> {
-    fn default() -> Self {
-        StakedStatus::Normal
-    }
-}
-
-#[derive(Encode, Decode, Debug, Default, Eq, PartialEq)]
-pub struct StakedState<BlockNumber, Balance, SlashId: Ord> {
-    /// Total amount of funds at stake.
-    pub staked_amount: Balance,
-
-    /// Status of the staking.
-    pub staked_status: StakedStatus<BlockNumber>,
-
-    /// SlashId to use for next Slash that is initiated.
-    /// Will be incremented by one after adding a new Slash.
-    pub next_slash_id: SlashId,
-
-    /// All ongoing slashing.
-    pub ongoing_slashes: BTreeMap<SlashId, Slash<BlockNumber, Balance>>,
-}
-
-impl<BlockNumber, Balance, SlashId> StakedState<BlockNumber, Balance, SlashId>
-where
-    BlockNumber: BaseArithmetic + Copy,
-    Balance: BaseArithmetic + Copy,
-    SlashId: Ord + Copy,
-{
-    /// Iterates over all ongoing slashes and decrements blocks_remaining_in_active_period_for_slashing of active slashes (advancing the timer).
-    /// Returns true if there was at least one slashe that was active and had its timer advanced.
-    fn advance_slashing_timer(&mut self) -> bool {
-        let mut did_advance_timers = false;
-
-        for (_slash_id, slash) in self.ongoing_slashes.iter_mut() {
-            if slash.is_active
-                && slash.blocks_remaining_in_active_period_for_slashing > Zero::zero()
-            {
-                slash.blocks_remaining_in_active_period_for_slashing -= One::one();
-                did_advance_timers = true;
-            }
-        }
-
-        did_advance_timers
-    }
-
-    /// Returns pair of slash_id and slashes that should be executed
-    fn get_slashes_to_finalize(&mut self) -> Vec<(SlashId, Slash<BlockNumber, Balance>)> {
-        let slashes_to_finalize = self
-            .ongoing_slashes
-            .iter()
-            .filter(|(_, slash)| {
-                slash.blocks_remaining_in_active_period_for_slashing == Zero::zero()
-            })
-            .map(|(slash_id, _)| *slash_id)
-            .collect::<Vec<_>>();
-
-        // remove and return the slashes
-        slashes_to_finalize
-            .iter()
-            .map(|slash_id| {
-                // assert!(self.ongoing_slashes.contains_key(slash_id))
-                (*slash_id, self.ongoing_slashes.remove(slash_id).unwrap())
-            })
-            .collect()
-    }
-
-    /// Executes a Slash. If remaining at stake drops below the minimum_balance, it will slash the entire staked amount.
-    /// Returns the actual slashed amount.
-    fn apply_slash(&mut self, slash_amount: Balance, minimum_balance: Balance) -> Balance {
-        // calculate how much to slash
-        let mut slash_amount = if slash_amount > self.staked_amount {
-            self.staked_amount
-        } else {
-            slash_amount
-        };
-
-        // apply the slashing
-        self.staked_amount -= slash_amount;
-
-        // don't leave less than minimum_balance at stake
-        if self.staked_amount < minimum_balance {
-            slash_amount += self.staked_amount;
-            self.staked_amount = Zero::zero();
-        }
-
-        slash_amount
-    }
-
-    /// For all slahes that should be executed, will apply the Slash to the staked amount, and drop it from the ongoing slashes map.
-    /// Returns a vector of the executed slashes outcome: (SlashId, Slashed Amount, Remaining Staked Amount)
-    fn finalize_slashes(&mut self, minimum_balance: Balance) -> Vec<(SlashId, Balance, Balance)> {
-        let mut finalized_slashes: Vec<(SlashId, Balance, Balance)> = Vec::new();
-
-        for (slash_id, slash) in self.get_slashes_to_finalize().iter() {
-            // apply the slashing and get back actual amount slashed
-            let slashed_amount = self.apply_slash(slash.slash_amount, minimum_balance);
-
-            finalized_slashes.push((*slash_id, slashed_amount, self.staked_amount));
-        }
-
-        finalized_slashes
-    }
-}
-
-#[derive(Encode, Decode, Debug, Eq, PartialEq)]
-pub enum StakingStatus<BlockNumber, Balance, SlashId: Ord> {
-    NotStaked,
-
-    Staked(StakedState<BlockNumber, Balance, SlashId>),
-}
-
-impl<BlockNumber, Balance, SlashId: Ord> Default for StakingStatus<BlockNumber, Balance, SlashId> {
-    fn default() -> Self {
-        StakingStatus::NotStaked
-    }
-}
-
-#[derive(Encode, Decode, Default, Debug, Eq, PartialEq)]
-pub struct Stake<BlockNumber, Balance, SlashId: Ord> {
-    /// When role was created
-    pub created: BlockNumber,
-
-    /// Status of any possible ongoing staking
-    pub staking_status: StakingStatus<BlockNumber, Balance, SlashId>,
-}
-
-impl<BlockNumber, Balance, SlashId> Stake<BlockNumber, Balance, SlashId>
-where
-    BlockNumber: Copy + BaseArithmetic + Zero,
-    Balance: Copy + BaseArithmetic,
-    SlashId: Copy + Ord + Zero + One,
-{
-    fn new(created_at: BlockNumber) -> Self {
-        Self {
-            created: created_at,
-            staking_status: StakingStatus::NotStaked,
-        }
-    }
-
-    fn is_not_staked(&self) -> bool {
-        self.staking_status == StakingStatus::NotStaked
-    }
-
-    /// If staking status is Staked and not currently Unstaking it will increase the staked amount by value.
-    /// On success returns new total staked value.
-    /// Increasing stake by zero is an error.
-    fn increase_stake(&mut self, value: Balance) -> Result<Balance, IncreasingStakeError> {
-        ensure!(
-            value > Zero::zero(),
-            IncreasingStakeError::CannotChangeStakeByZero
-        );
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => match staked_state.staked_status {
-                StakedStatus::Normal => {
-                    staked_state.staked_amount += value;
-                    Ok(staked_state.staked_amount)
-                }
-                _ => Err(IncreasingStakeError::CannotIncreaseStakeWhileUnstaking),
-            },
-            _ => Err(IncreasingStakeError::NotStaked),
-        }
-    }
-
-    /// If staking status is Staked and not currently Unstaking, and no ongoing slashes exist, it will decrease the amount at stake
-    /// by provided value. If remaining at stake drops below the minimum_balance it will decrease the stake to zero.
-    /// On success returns (the actual amount of stake decreased, the remaining amount at stake).
-    /// Decreasing stake by zero is an error.
-    fn decrease_stake(
-        &mut self,
-        value: Balance,
-        minimum_balance: Balance,
-    ) -> Result<(Balance, Balance), DecreasingStakeError> {
-        // maybe StakeDecrease
-        ensure!(
-            value > Zero::zero(),
-            DecreasingStakeError::CannotChangeStakeByZero
-        );
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => match staked_state.staked_status {
-                StakedStatus::Normal => {
-                    // prevent decreasing stake if there are any ongoing slashes (irrespective if active or not)
-                    if !staked_state.ongoing_slashes.is_empty() {
-                        return Err(DecreasingStakeError::CannotDecreaseStakeWhileOngoingSlahes);
-                    }
-
-                    if value > staked_state.staked_amount {
-                        return Err(DecreasingStakeError::InsufficientStake);
-                    }
-
-                    let stake_to_reduce = if staked_state.staked_amount - value < minimum_balance {
-                        // If staked amount would drop below minimum balance, deduct the entire stake
-                        staked_state.staked_amount
-                    } else {
-                        value
-                    };
-
-                    staked_state.staked_amount -= stake_to_reduce;
-
-                    Ok((stake_to_reduce, staked_state.staked_amount))
-                }
-                _ => Err(DecreasingStakeError::CannotDecreaseStakeWhileUnstaking),
-            },
-            _ => Err(DecreasingStakeError::NotStaked),
-        }
-    }
-
-    fn start_staking(
-        &mut self,
-        value: Balance,
-        minimum_balance: Balance,
-    ) -> Result<(), StakingError> {
-        ensure!(value > Zero::zero(), StakingError::CannotStakeZero);
-        ensure!(
-            value >= minimum_balance,
-            StakingError::CannotStakeLessThanMinimumBalance
-        );
-        if self.is_not_staked() {
-            self.staking_status = StakingStatus::Staked(StakedState {
-                staked_amount: value,
-                next_slash_id: Zero::zero(),
-                ongoing_slashes: BTreeMap::new(),
-                staked_status: StakedStatus::Normal,
-            });
-            Ok(())
-        } else {
-            Err(StakingError::AlreadyStaked)
-        }
-    }
-
-    fn slash_immediate(
-        &mut self,
-        slash_amount: Balance,
-        minimum_balance: Balance,
-    ) -> Result<(Balance, Balance), ImmediateSlashingError> {
-        ensure!(
-            slash_amount > Zero::zero(),
-            ImmediateSlashingError::SlashAmountShouldBeGreaterThanZero
-        );
-
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                // irrespective of wether we are unstaking or not, slash!
-
-                let actually_slashed = staked_state.apply_slash(slash_amount, minimum_balance);
-
-                let remaining_stake = staked_state.staked_amount;
-
-                Ok((actually_slashed, remaining_stake))
-            }
-            // can't slash if not staked
-            _ => Err(ImmediateSlashingError::NotStaked),
-        }
-    }
-
-    fn initiate_slashing(
-        &mut self,
-        slash_amount: Balance,
-        slash_period: BlockNumber,
-        now: BlockNumber,
-    ) -> Result<SlashId, InitiateSlashingError> {
-        ensure!(
-            slash_period > Zero::zero(),
-            InitiateSlashingError::SlashPeriodShouldBeGreaterThanZero
-        );
-        ensure!(
-            slash_amount > Zero::zero(),
-            InitiateSlashingError::SlashAmountShouldBeGreaterThanZero
-        );
-
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                let slash_id = staked_state.next_slash_id;
-                staked_state.next_slash_id = slash_id + One::one();
-
-                staked_state.ongoing_slashes.insert(
-                    slash_id,
-                    Slash {
-                        is_active: true,
-                        blocks_remaining_in_active_period_for_slashing: slash_period,
-                        slash_amount,
-                        started_at_block: now,
-                    },
-                );
-
-                // pause Unstaking if unstaking is active
-                if let StakedStatus::Unstaking(ref mut unstaking_state) = staked_state.staked_status
-                {
-                    unstaking_state.is_active = false;
-                }
-
-                Ok(slash_id)
-            }
-            _ => Err(InitiateSlashingError::NotStaked),
-        }
-    }
-
-    fn pause_slashing(&mut self, slash_id: &SlashId) -> Result<(), PauseSlashingError> {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                match staked_state.ongoing_slashes.get_mut(slash_id) {
-                    Some(ref mut slash) => {
-                        if slash.is_active {
-                            slash.is_active = false;
-                            Ok(())
-                        } else {
-                            Err(PauseSlashingError::AlreadyPaused)
-                        }
-                    }
-                    _ => Err(PauseSlashingError::SlashNotFound),
-                }
-            }
-            _ => Err(PauseSlashingError::NotStaked),
-        }
-    }
-
-    fn resume_slashing(&mut self, slash_id: &SlashId) -> Result<(), ResumeSlashingError> {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                match staked_state.ongoing_slashes.get_mut(slash_id) {
-                    Some(ref mut slash) => {
-                        if slash.is_active {
-                            Err(ResumeSlashingError::NotPaused)
-                        } else {
-                            slash.is_active = true;
-                            Ok(())
-                        }
-                    }
-                    _ => Err(ResumeSlashingError::SlashNotFound),
-                }
-            }
-            _ => Err(ResumeSlashingError::NotStaked),
-        }
-    }
-
-    fn cancel_slashing(&mut self, slash_id: &SlashId) -> Result<(), CancelSlashingError> {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                if staked_state.ongoing_slashes.remove(slash_id).is_none() {
-                    return Err(CancelSlashingError::SlashNotFound);
-                }
-
-                // unpause unstaking on last ongoing slash cancelled
-                if staked_state.ongoing_slashes.is_empty() {
-                    if let StakedStatus::Unstaking(ref mut unstaking_state) =
-                        staked_state.staked_status
-                    {
-                        unstaking_state.is_active = true;
-                    }
-                }
-
-                Ok(())
-            }
-            _ => Err(CancelSlashingError::NotStaked),
-        }
-    }
-
-    fn unstake(&mut self) -> Result<Balance, UnstakingError> {
-        let staked_amount = match self.staking_status {
-            StakingStatus::Staked(ref staked_state) => {
-                // prevent unstaking if there are any ongonig slashes (irrespective if active or not)
-                if !staked_state.ongoing_slashes.is_empty() {
-                    return Err(UnstakingError::CannotUnstakeWhileSlashesOngoing);
-                }
-                if StakedStatus::Normal != staked_state.staked_status {
-                    return Err(UnstakingError::AlreadyUnstaking);
-                }
-                Ok(staked_state.staked_amount)
-            }
-            _ => Err(UnstakingError::NotStaked),
-        }?;
-
-        self.staking_status = StakingStatus::NotStaked;
-        Ok(staked_amount)
-    }
-
-    fn initiate_unstaking(
-        &mut self,
-        unstaking_period: BlockNumber,
-        now: BlockNumber,
-    ) -> Result<(), InitiateUnstakingError> {
-        ensure!(
-            unstaking_period > Zero::zero(),
-            InitiateUnstakingError::UnstakingPeriodShouldBeGreaterThanZero
-        );
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                // prevent unstaking if there are any ongonig slashes (irrespective if active or not)
-                if !staked_state.ongoing_slashes.is_empty() {
-                    return Err(InitiateUnstakingError::UnstakingError(
-                        UnstakingError::CannotUnstakeWhileSlashesOngoing,
-                    ));
-                }
-
-                if StakedStatus::Normal != staked_state.staked_status {
-                    return Err(InitiateUnstakingError::UnstakingError(
-                        UnstakingError::AlreadyUnstaking,
-                    ));
-                }
-
-                staked_state.staked_status = StakedStatus::Unstaking(UnstakingState {
-                    started_at_block: now,
-                    is_active: true,
-                    blocks_remaining_in_active_period_for_unstaking: unstaking_period,
-                });
-
-                Ok(())
-            }
-            _ => Err(InitiateUnstakingError::UnstakingError(
-                UnstakingError::NotStaked,
-            )),
-        }
-    }
-
-    fn pause_unstaking(&mut self) -> Result<(), PauseUnstakingError> {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => match staked_state.staked_status {
-                StakedStatus::Unstaking(ref mut unstaking_state) => {
-                    if unstaking_state.is_active {
-                        unstaking_state.is_active = false;
-                        Ok(())
-                    } else {
-                        Err(PauseUnstakingError::AlreadyPaused)
-                    }
-                }
-                _ => Err(PauseUnstakingError::NotUnstaking),
-            },
-            _ => Err(PauseUnstakingError::NotStaked),
-        }
-    }
-
-    fn resume_unstaking(&mut self) -> Result<(), ResumeUnstakingError> {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => match staked_state.staked_status {
-                StakedStatus::Unstaking(ref mut unstaking_state) => {
-                    if !unstaking_state.is_active {
-                        unstaking_state.is_active = true;
-                        Ok(())
-                    } else {
-                        Err(ResumeUnstakingError::NotPaused)
-                    }
-                }
-                _ => Err(ResumeUnstakingError::NotUnstaking),
-            },
-            _ => Err(ResumeUnstakingError::NotStaked),
-        }
-    }
-
-    fn finalize_slashing(
-        &mut self,
-        minimum_balance: Balance,
-    ) -> (bool, Vec<(SlashId, Balance, Balance)>) {
-        match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => {
-                // tick the slashing timer
-                let did_update = staked_state.advance_slashing_timer();
-
-                // finalize and apply slashes
-                let slashed = staked_state.finalize_slashes(minimum_balance);
-
-                (did_update, slashed)
-            }
-            _ => (false, Vec::new()),
-        }
-    }
-
-    fn finalize_unstaking(&mut self) -> (bool, Option<Balance>) {
-        let (did_update, unstaked) = match self.staking_status {
-            StakingStatus::Staked(ref mut staked_state) => match staked_state.staked_status {
-                StakedStatus::Unstaking(ref mut unstaking_state) => {
-                    // if all slashes were processed and there are no more active slashes
-                    // resume unstaking
-                    if staked_state.ongoing_slashes.is_empty() {
-                        unstaking_state.is_active = true;
-                    }
-
-                    // tick the unstaking timer
-                    if unstaking_state.is_active
-                        && unstaking_state.blocks_remaining_in_active_period_for_unstaking
-                            > Zero::zero()
-                    {
-                        // tick the unstaking timer
-                        unstaking_state.blocks_remaining_in_active_period_for_unstaking -=
-                            One::one();
-                    }
-
-                    // finalize unstaking
-                    if unstaking_state.blocks_remaining_in_active_period_for_unstaking
-                        == Zero::zero()
-                    {
-                        (true, Some(staked_state.staked_amount))
-                    } else {
-                        (unstaking_state.is_active, None)
-                    }
-                }
-                _ => (false, None),
-            },
-            _ => (false, None),
-        };
-
-        // if unstaking was finalized transition to NotStaked state
-        if unstaked.is_some() {
-            self.staking_status = StakingStatus::NotStaked;
-        }
-
-        (did_update, unstaked)
-    }
-
-    fn finalize_slashing_and_unstaking(
-        &mut self,
-        minimum_balance: Balance,
-    ) -> (bool, Vec<(SlashId, Balance, Balance)>, Option<Balance>) {
-        let (did_update_slashing_timers, slashed) = self.finalize_slashing(minimum_balance);
-
-        let (did_update_unstaking_timer, unstaked) = self.finalize_unstaking();
-
-        (
-            did_update_slashing_timers || did_update_unstaking_timer,
-            slashed,
-            unstaked,
-        )
-    }
-}
-
-#[derive(Debug, Eq, PartialEq)]
-pub struct SlashImmediateOutcome<Balance, NegativeImbalance> {
-    pub caused_unstake: bool,
-    pub actually_slashed: Balance,
-    pub remaining_stake: Balance,
-    pub remaining_imbalance: NegativeImbalance,
-}
-
-decl_storage! {
-    trait Store for Module<T: Trait> as StakePool {
-        /// Maps identifiers to a stake.
-        pub Stakes get(fn stakes): map hasher(blake2_128_concat)
-            T::StakeId => Stake<T::BlockNumber, BalanceOf<T>, T::SlashId>;
-
-        /// Identifier value for next stake, and count of total stakes created (not necessarily the number of current
-        /// stakes in the Stakes map as stakes can be removed.)
-        pub StakesCreated get(fn stakes_created): T::StakeId;
-    }
-}
-
-decl_module! {
-    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-        fn on_finalize(_now: T::BlockNumber) {
-            Self::finalize_slashing_and_unstaking();
-        }
-    }
-}
-
-impl<T: Trait> Module<T> {
-    /// The account ID of theis module which holds all the staked balance. (referred to as the stake pool)
-    ///
-    /// This actually does computation. If you need to keep using it, then make sure you cache the
-    /// value and only call this once. Is it deterministic?
-    pub fn stake_pool_account_id() -> T::AccountId {
-        ModuleId(T::StakePoolId::get()).into_account()
-    }
-
-    pub fn stake_pool_balance() -> BalanceOf<T> {
-        T::Currency::free_balance(&Self::stake_pool_account_id())
-    }
-
-    /// Adds a new Stake which is NotStaked, created at given block, into stakes map.
-    pub fn create_stake() -> T::StakeId {
-        let stake_id = Self::stakes_created();
-        <StakesCreated<T>>::put(stake_id + One::one());
-
-        <Stakes<T>>::insert(
-            &stake_id,
-            Stake::new(<frame_system::Module<T>>::block_number()),
-        );
-
-        stake_id
-    }
-
-    /// Given that stake with id exists in stakes and is NotStaked, remove from stakes.
-    pub fn remove_stake(stake_id: &T::StakeId) -> Result<(), StakeActionError<StakingError>> {
-        let stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        ensure!(
-            stake.is_not_staked(),
-            StakeActionError::Error(StakingError::AlreadyStaked)
-        );
-
-        <Stakes<T>>::remove(stake_id);
-
-        Ok(())
-    }
-
-    /// Dry run to see if staking can be initiated for the specified stake id. This should
-    /// be called before stake() to make sure staking is possible before withdrawing funds.
-    pub fn ensure_can_stake(
-        stake_id: &T::StakeId,
-        value: BalanceOf<T>,
-    ) -> Result<(), StakeActionError<StakingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake
-            .start_staking(value, T::Currency::minimum_balance())
-            .err()
-            .map_or(Ok(()), |err| Err(StakeActionError::Error(err)))
-    }
-
-    /// Provided the stake exists and is in state NotStaked the value is transferred
-    /// to the module's account, and the corresponding staked_balance is set to this amount in the new Staked state.
-    /// On error, as the negative imbalance is not returned to the caller, it is the caller's responsibility to return the funds
-    /// back to the source (by creating a new positive imbalance)
-    pub fn stake(
-        stake_id: &T::StakeId,
-        imbalance: NegativeImbalance<T>,
-    ) -> Result<(), StakeActionError<StakingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        let value = imbalance.peek();
-
-        stake.start_staking(value, T::Currency::minimum_balance())?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Self::deposit_funds_into_stake_pool(imbalance);
-
-        Ok(())
-    }
-
-    pub fn stake_from_account(
-        stake_id: &T::StakeId,
-        source_account_id: &T::AccountId,
-        value: BalanceOf<T>,
-    ) -> Result<(), StakeActionError<StakingFromAccountError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.start_staking(value, T::Currency::minimum_balance())?;
-
-        // Its important to only do the transfer as the last step to ensure starting staking was possible.
-        Self::transfer_funds_from_account_into_stake_pool(source_account_id, value)?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(())
-    }
-
-    /// Moves funds from specified account into the module's account
-    fn transfer_funds_from_account_into_stake_pool(
-        source: &T::AccountId,
-        value: BalanceOf<T>,
-    ) -> Result<(), TransferFromAccountError> {
-        // We don't use T::Currency::transfer() to prevent fees being incurred.
-        let negative_imbalance = T::Currency::withdraw(
-            source,
-            value,
-            WithdrawReasons::all(),
-            ExistenceRequirement::AllowDeath,
-        )
-        .map_err(|_err| TransferFromAccountError::InsufficientBalance)?;
-
-        Self::deposit_funds_into_stake_pool(negative_imbalance);
-        Ok(())
-    }
-
-    fn deposit_funds_into_stake_pool(imbalance: NegativeImbalance<T>) {
-        // move the negative imbalance into the stake pool
-        T::Currency::resolve_creating(&Self::stake_pool_account_id(), imbalance);
-    }
-
-    /// Moves funds from the module's account into specified account. Should never fail if used internally.
-    /// Will panic! if value exceeds balance in the pool.
-    fn transfer_funds_from_pool_into_account(destination: &T::AccountId, value: BalanceOf<T>) {
-        let imbalance = Self::withdraw_funds_from_stake_pool(value);
-        T::Currency::resolve_creating(destination, imbalance);
-    }
-
-    /// Withdraws value from the pool and returns a NegativeImbalance.
-    /// As long as it is only called internally when executing slashes and unstaking, it
-    /// should never fail as the pool balance is always in sync with total amount at stake.
-    fn withdraw_funds_from_stake_pool(value: BalanceOf<T>) -> NegativeImbalance<T> {
-        // We don't use T::Currency::transfer() to prevent fees being incurred.
-        T::Currency::withdraw(
-            &Self::stake_pool_account_id(),
-            value,
-            WithdrawReasons::all(),
-            ExistenceRequirement::AllowDeath,
-        )
-        .expect("pool had less than expected funds!")
-    }
-
-    /// Dry run to see if the state of stake allows for increasing stake. This should be called
-    /// to make sure increasing stake is possible before withdrawing funds.
-    pub fn ensure_can_increase_stake(
-        stake_id: &T::StakeId,
-        value: BalanceOf<T>,
-    ) -> Result<(), StakeActionError<IncreasingStakeError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake
-            .increase_stake(value)
-            .err()
-            .map_or(Ok(()), |err| Err(StakeActionError::Error(err)))
-    }
-
-    /// Provided the stake exists and is in state Staked.Normal, then the amount is transferred to the module's account,
-    /// and the corresponding staked_amount is increased by the value. New value of staked_amount is returned.
-    /// Caller should call check ensure_can_increase_stake() prior to avoid getting back an error. On error, as the negative imbalance
-    /// is not returned to the caller, it is the caller's responsibility to return the funds back to the source (by creating a new positive imbalance)
-    pub fn increase_stake(
-        stake_id: &T::StakeId,
-        imbalance: NegativeImbalance<T>,
-    ) -> Result<BalanceOf<T>, StakeActionError<IncreasingStakeError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        let total_staked_amount = stake.increase_stake(imbalance.peek())?;
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Self::deposit_funds_into_stake_pool(imbalance);
-
-        Ok(total_staked_amount)
-    }
-
-    /// Provided the stake exists and is in state Staked.Normal, and the given source account covers the amount,
-    /// then the amount is transferred to the module's account, and the corresponding staked_amount is increased
-    /// by the amount. New value of staked_amount is returned.
-    pub fn increase_stake_from_account(
-        stake_id: &T::StakeId,
-        source_account_id: &T::AccountId,
-        value: BalanceOf<T>,
-    ) -> Result<BalanceOf<T>, StakeActionError<IncreasingStakeFromAccountError>> {
-        let mut stake = ensure_stake_exists!(
-            T,
-            stake_id,
-            <StakeActionError<IncreasingStakeFromAccountError>>::StakeNotFound
-        )?;
-
-        let total_staked_amount = stake.increase_stake(value)?;
-
-        Self::transfer_funds_from_account_into_stake_pool(&source_account_id, value)?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(total_staked_amount)
-    }
-
-    pub fn ensure_can_decrease_stake(
-        stake_id: &T::StakeId,
-        value: BalanceOf<T>,
-    ) -> Result<(), StakeActionError<DecreasingStakeError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake
-            .decrease_stake(value, T::Currency::minimum_balance())
-            .err()
-            .map_or(Ok(()), |err| Err(StakeActionError::Error(err)))
-    }
-
-    pub fn decrease_stake(
-        stake_id: &T::StakeId,
-        value: BalanceOf<T>,
-    ) -> Result<(BalanceOf<T>, NegativeImbalance<T>), StakeActionError<DecreasingStakeError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        let (deduct_from_pool, staked_amount) =
-            stake.decrease_stake(value, T::Currency::minimum_balance())?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        let imbalance = Self::withdraw_funds_from_stake_pool(deduct_from_pool);
-
-        Ok((staked_amount, imbalance))
-    }
-
-    /// Provided the stake exists and is in state Staked.Normal, and the given stake holds at least the value,
-    /// then the value is transferred from the module's account to the destination_account, and the corresponding
-    /// staked_amount is decreased by the value. New value of staked_amount is returned.
-    pub fn decrease_stake_to_account(
-        stake_id: &T::StakeId,
-        destination_account_id: &T::AccountId,
-        value: BalanceOf<T>,
-    ) -> Result<BalanceOf<T>, StakeActionError<DecreasingStakeError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        let (deduct_from_pool, staked_amount) =
-            stake.decrease_stake(value, T::Currency::minimum_balance())?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Self::transfer_funds_from_pool_into_account(&destination_account_id, deduct_from_pool);
-
-        Ok(staked_amount)
-    }
-
-    /// Slashes a stake with immediate effect, returns the outcome of the slashing.
-    /// Can optionally specify if slashing can result in immediate unstaking if staked amount
-    /// after slashing goes to zero.
-    pub fn slash_immediate(
-        stake_id: &T::StakeId,
-        slash_amount: BalanceOf<T>,
-        unstake_on_zero_staked: bool,
-    ) -> Result<
-        SlashImmediateOutcome<BalanceOf<T>, NegativeImbalance<T>>,
-        StakeActionError<ImmediateSlashingError>,
-    > {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        // Get amount at stake before slashing to be used in unstaked event trigger
-        let staked_amount_before_slash = ensure_staked_amount!(
-            stake,
-            StakeActionError::Error(ImmediateSlashingError::NotStaked)
-        )?;
-
-        let (actually_slashed, remaining_stake) =
-            stake.slash_immediate(slash_amount, T::Currency::minimum_balance())?;
-
-        let caused_unstake = unstake_on_zero_staked && remaining_stake == BalanceOf::<T>::zero();
-
-        if caused_unstake {
-            stake.staking_status = StakingStatus::NotStaked;
-        }
-
-        // Update state before calling handlers!
-        <Stakes<T>>::insert(stake_id, stake);
-
-        // Remove the slashed amount from the pool
-        let slashed_imbalance = Self::withdraw_funds_from_stake_pool(actually_slashed);
-
-        // Notify slashing event handler before unstaked handler.
-        let remaining_imbalance_after_slash_handler = T::StakingEventsHandler::slashed(
-            stake_id,
-            None,
-            actually_slashed,
-            remaining_stake,
-            slashed_imbalance,
-        );
-
-        let remaining_imbalance = if caused_unstake {
-            // Notify unstaked handler with any remaining unused imbalance
-            // from the slashing event handler
-            T::StakingEventsHandler::unstaked(
-                &stake_id,
-                staked_amount_before_slash,
-                remaining_imbalance_after_slash_handler,
-            )
-        } else {
-            remaining_imbalance_after_slash_handler
-        };
-
-        Ok(SlashImmediateOutcome {
-            caused_unstake,
-            actually_slashed,
-            remaining_stake,
-            remaining_imbalance,
-        })
-    }
-
-    /// Initiate a new slashing of a staked stake. Slashing begins at next block.
-    pub fn initiate_slashing(
-        stake_id: &T::StakeId,
-        slash_amount: BalanceOf<T>,
-        slash_period: T::BlockNumber,
-    ) -> Result<T::SlashId, StakeActionError<InitiateSlashingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        let slash_id = stake.initiate_slashing(
-            slash_amount,
-            slash_period,
-            <frame_system::Module<T>>::block_number(),
-        )?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-        Ok(slash_id)
-    }
-
-    /// Pause an ongoing slashing
-    pub fn pause_slashing(
-        stake_id: &T::StakeId,
-        slash_id: &T::SlashId,
-    ) -> Result<(), StakeActionError<PauseSlashingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.pause_slashing(slash_id)?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(())
-    }
-
-    /// Resume a currently paused ongoing slashing.
-    pub fn resume_slashing(
-        stake_id: &T::StakeId,
-        slash_id: &T::SlashId,
-    ) -> Result<(), StakeActionError<ResumeSlashingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.resume_slashing(slash_id)?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-        Ok(())
-    }
-
-    /// Cancel an ongoing slashing (regardless of whether its active or paused).
-    pub fn cancel_slashing(
-        stake_id: &T::StakeId,
-        slash_id: &T::SlashId,
-    ) -> Result<(), StakeActionError<CancelSlashingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.cancel_slashing(slash_id)?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(())
-    }
-
-    /// Initiate unstaking of a Staked stake.
-    pub fn initiate_unstaking(
-        stake_id: &T::StakeId,
-        unstaking_period: Option<T::BlockNumber>,
-    ) -> Result<(), StakeActionError<InitiateUnstakingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        if let Some(unstaking_period) = unstaking_period {
-            stake
-                .initiate_unstaking(unstaking_period, <frame_system::Module<T>>::block_number())?;
-            <Stakes<T>>::insert(stake_id, stake);
-        } else {
-            let staked_amount = stake.unstake()?;
-            <Stakes<T>>::insert(stake_id, stake);
-
-            let imbalance = Self::withdraw_funds_from_stake_pool(staked_amount);
-            let _ = T::StakingEventsHandler::unstaked(stake_id, staked_amount, imbalance);
-        }
-
-        Ok(())
-    }
-
-    /// Pause an ongoing Unstaking.
-    pub fn pause_unstaking(
-        stake_id: &T::StakeId,
-    ) -> Result<(), StakeActionError<PauseUnstakingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.pause_unstaking()?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(())
-    }
-
-    /// Resume a currently paused ongoing unstaking.
-    pub fn resume_unstaking(
-        stake_id: &T::StakeId,
-    ) -> Result<(), StakeActionError<ResumeUnstakingError>> {
-        let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-
-        stake.resume_unstaking()?;
-
-        <Stakes<T>>::insert(stake_id, stake);
-
-        Ok(())
-    }
-
-    /// Handle timers for finalizing unstaking and slashing.
-    /// Finalised unstaking results in the staked_balance in the given stake to removed from the pool, the corresponding
-    /// imbalance is provided to the unstaked() hook in the StakingEventsHandler.
-    /// Finalised slashing results in the staked_balance in the given stake being correspondingly reduced, and the imbalance
-    /// is provided to the slashed() hook in the StakingEventsHandler.
-    fn finalize_slashing_and_unstaking() {
-        for (stake_id, ref mut stake) in <Stakes<T>>::iter() {
-            let (updated, slashed, unstaked) =
-                stake.finalize_slashing_and_unstaking(T::Currency::minimum_balance());
-
-            // update the state before making external calls to StakingEventsHandler
-            if updated {
-                <Stakes<T>>::insert(stake_id, stake)
-            }
-
-            for (slash_id, slashed_amount, staked_amount) in slashed.into_iter() {
-                // remove the slashed amount from the pool
-                let imbalance = Self::withdraw_funds_from_stake_pool(slashed_amount);
-
-                let _ = T::StakingEventsHandler::slashed(
-                    &stake_id,
-                    Some(slash_id),
-                    slashed_amount,
-                    staked_amount,
-                    imbalance,
-                );
-            }
-
-            if let Some(staked_amount) = unstaked {
-                // remove the unstaked amount from the pool
-                let imbalance = Self::withdraw_funds_from_stake_pool(staked_amount);
-
-                let _ = T::StakingEventsHandler::unstaked(&stake_id, staked_amount, imbalance);
-            }
-        }
-    }
-}

+ 0 - 29
runtime-modules/stake/src/macroes.rs

@@ -1,29 +0,0 @@
-#[macro_export]
-macro_rules! ensure_map_has_mapping_with_key {
-    ($map_variable_name:ident , $runtime_trait:tt, $key:expr, $error:expr) => {{
-        if <$map_variable_name<$runtime_trait>>::contains_key($key) {
-            let value = <$map_variable_name<$runtime_trait>>::get($key);
-
-            Ok(value)
-        } else {
-            Err($error)
-        }
-    }};
-}
-
-#[macro_export]
-macro_rules! ensure_stake_exists {
-    ($runtime_trait:tt, $stake_id:expr, $error:expr) => {{
-        ensure_map_has_mapping_with_key!(Stakes, $runtime_trait, $stake_id, $error)
-    }};
-}
-
-#[macro_export]
-macro_rules! ensure_staked_amount {
-    ($stake:expr, $error:expr) => {{
-        match $stake.staking_status {
-            StakingStatus::Staked(ref staked_state) => Ok(staked_state.staked_amount),
-            _ => Err($error),
-        }
-    }};
-}

+ 0 - 99
runtime-modules/stake/src/mock.rs

@@ -1,99 +0,0 @@
-#![cfg(test)]
-
-use crate::*;
-use crate::{Module, Trait};
-use balances;
-use frame_support::{impl_outer_origin, parameter_types};
-use sp_core::H256;
-use sp_runtime::{
-    testing::Header,
-    traits::{BlakeTwo256, IdentityLookup},
-    Perbill,
-};
-
-impl_outer_origin! {
-    pub enum Origin for Test {}
-}
-
-// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct Test;
-parameter_types! {
-    pub const BlockHashCount: u64 = 250;
-    pub const MaximumBlockWeight: u32 = 1024;
-    pub const MaximumBlockLength: u32 = 2 * 1024;
-    pub const AvailableBlockRatio: Perbill = Perbill::one();
-}
-
-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 = ();
-    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 = ();
-}
-
-parameter_types! {
-    pub const ExistentialDeposit: u32 = 500;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
-    pub const MaxLocks: u32 = 50;
-}
-
-impl balances::Trait for Test {
-    type Balance = u64;
-    type DustRemoval = ();
-    type Event = ();
-    type ExistentialDeposit = ExistentialDeposit;
-    type AccountStore = System;
-    type WeightInfo = ();
-    type MaxLocks = MaxLocks;
-}
-
-impl Trait for Test {
-    type Currency = Balances;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
-pub fn build_test_externalities() -> sp_io::TestExternalities {
-    let t = frame_system::GenesisConfig::default()
-        .build_storage::<Test>()
-        .unwrap();
-
-    t.into()
-}
-
-pub type System = frame_system::Module<Test>;
-pub type Balances = balances::Module<Test>;
-pub type StakePool = Module<Test>;
-
-// Some helper methods for creating Stake states
-pub mod fixtures {
-    use super::*;
-    pub type OngoingSlashes = BTreeMap<
-        <Test as Trait>::SlashId,
-        Slash<<Test as frame_system::Trait>::BlockNumber, BalanceOf<Test>>,
-    >;
-}

+ 0 - 979
runtime-modules/stake/src/tests.rs

@@ -1,979 +0,0 @@
-#![cfg(test)]
-
-use super::*;
-use crate::mock::*;
-use frame_support::traits::OnFinalize;
-use frame_support::{assert_err, assert_ok};
-
-#[test]
-fn stake_pool_works() {
-    build_test_externalities().execute_with(|| {
-        // using deposit_creating
-        assert_eq!(Balances::total_issuance(), 0);
-        assert_eq!(StakePool::stake_pool_balance(), 0);
-
-        // minimum balance (existential deposit) feature applies to stake pool
-        if Balances::minimum_balance() > 0 {
-            let pos_imbalance = Balances::deposit_creating(
-                &StakePool::stake_pool_account_id(),
-                Balances::minimum_balance() - 1,
-            );
-            assert_eq!(pos_imbalance.peek(), 0);
-            assert_eq!(Balances::total_issuance(), 0);
-            assert_eq!(StakePool::stake_pool_balance(), 0);
-        }
-
-        let starting_pool_balance = Balances::minimum_balance() + 1000;
-        let _ =
-            Balances::deposit_creating(&StakePool::stake_pool_account_id(), starting_pool_balance);
-        assert_eq!(Balances::total_issuance(), starting_pool_balance);
-        assert_eq!(StakePool::stake_pool_balance(), starting_pool_balance);
-
-        let staker_starting_balance = Balances::minimum_balance() + 1000;
-        // using transfer_funds_from_account_into_pool()
-        let _ = Balances::deposit_creating(&1, staker_starting_balance);
-        assert_eq!(
-            Balances::total_issuance(),
-            starting_pool_balance + staker_starting_balance
-        );
-
-        let funds = 100;
-
-        assert_ok!(StakePool::transfer_funds_from_account_into_stake_pool(
-            &1, funds
-        ));
-
-        // total issuance unchanged after movement of funds
-        assert_eq!(
-            Balances::total_issuance(),
-            starting_pool_balance + staker_starting_balance
-        );
-
-        // funds moved into stake pool
-        assert_eq!(
-            StakePool::stake_pool_balance(),
-            starting_pool_balance + funds
-        );
-
-        // no fees were deducted
-        assert_eq!(Balances::free_balance(&1), staker_starting_balance - funds);
-
-        StakePool::transfer_funds_from_pool_into_account(&1, funds);
-
-        assert_eq!(Balances::free_balance(&1), staker_starting_balance);
-        assert_eq!(StakePool::stake_pool_balance(), starting_pool_balance);
-    });
-}
-
-#[test]
-fn create_stake() {
-    build_test_externalities().execute_with(|| {
-        let stake_id = StakePool::create_stake();
-        assert_eq!(stake_id, 0);
-        assert!(<Stakes<Test>>::contains_key(&stake_id));
-
-        assert_eq!(StakePool::stakes_created(), stake_id + 1);
-
-        // Should be NotStaked
-        let stake = StakePool::stakes(&stake_id);
-        assert_eq!(stake.staking_status, StakingStatus::NotStaked);
-    });
-}
-
-#[test]
-fn remove_stake_in_not_staked_state() {
-    build_test_externalities().execute_with(|| {
-        <Stakes<Test>>::insert(
-            &100,
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::NotStaked,
-            },
-        );
-        assert_ok!(StakePool::remove_stake(&100));
-        assert!(!<Stakes<Test>>::contains_key(&100));
-
-        // when status is Staked, removing should fail
-        <Stakes<Test>>::insert(
-            &200,
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::Staked(Default::default()),
-            },
-        );
-
-        assert_err!(
-            StakePool::remove_stake(&200),
-            StakeActionError::Error(StakingError::AlreadyStaked)
-        );
-        assert!(<Stakes<Test>>::contains_key(&200));
-    });
-}
-
-#[test]
-fn enter_staked_state() {
-    build_test_externalities().execute_with(|| {
-        <Stakes<Test>>::insert(
-            &100,
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::NotStaked,
-            },
-        );
-
-        let starting_balance: u64 = Balances::minimum_balance();
-        let staker_account: u64 = 1;
-        let stake_value: u64 = Balances::minimum_balance() + 100;
-
-        let _ = Balances::deposit_creating(&staker_account, starting_balance);
-
-        // can't stake zero
-        assert_err!(
-            StakePool::stake_from_account(&100, &staker_account, 0),
-            StakeActionError::Error(StakingFromAccountError::StakingError(
-                StakingError::CannotStakeZero
-            ))
-        );
-
-        // must stake at least the minimum balance
-        if Balances::minimum_balance() > 0 {
-            assert_err!(
-                StakePool::stake_from_account(
-                    &100,
-                    &staker_account,
-                    Balances::minimum_balance() - 1
-                ),
-                StakeActionError::Error(StakingFromAccountError::StakingError(
-                    StakingError::CannotStakeLessThanMinimumBalance
-                ))
-            );
-        }
-
-        // cannot stake with insufficient funds
-        assert_err!(
-            StakePool::stake_from_account(&100, &staker_account, stake_value),
-            StakeActionError::Error(StakingFromAccountError::InsufficientBalanceInSourceAccount)
-        );
-
-        // deposit exact amount to stake
-        let _ = Balances::deposit_creating(&staker_account, stake_value);
-
-        assert_ok!(StakePool::stake_from_account(
-            &100,
-            &staker_account,
-            stake_value
-        ));
-
-        assert_eq!(Balances::free_balance(&staker_account), starting_balance);
-
-        assert_eq!(StakePool::stake_pool_balance(), stake_value);
-    });
-}
-
-#[test]
-fn increasing_stake() {
-    build_test_externalities().execute_with(|| {
-        let starting_pool_stake = Balances::minimum_balance() + 5000;
-        let _ =
-            Balances::deposit_creating(&StakePool::stake_pool_account_id(), starting_pool_stake);
-
-        let starting_stake = Balances::minimum_balance() + 100;
-        <Stakes<Test>>::insert(
-            &100,
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: starting_stake,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                }),
-            },
-        );
-
-        let additional_stake: u64 = 500;
-        let starting_balance: u64 = Balances::minimum_balance() + additional_stake;
-        let staker_account: u64 = 1;
-
-        let _ = Balances::deposit_creating(&staker_account, starting_balance);
-
-        assert_err!(
-            StakePool::increase_stake_from_account(&100, &staker_account, 0),
-            StakeActionError::Error(IncreasingStakeFromAccountError::IncreasingStakeError(
-                IncreasingStakeError::CannotChangeStakeByZero
-            ))
-        );
-
-        let total_staked =
-            StakePool::increase_stake_from_account(&100, &staker_account, additional_stake)
-                .ok()
-                .unwrap();
-        assert_eq!(total_staked, starting_stake + additional_stake);
-
-        assert_eq!(
-            Balances::free_balance(&staker_account),
-            starting_balance - additional_stake
-        );
-
-        assert_eq!(
-            StakePool::stake_pool_balance(),
-            starting_pool_stake + additional_stake
-        );
-
-        assert_eq!(
-            StakePool::stakes(&100),
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: starting_stake + additional_stake,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                })
-            }
-        );
-
-        // cannot increase stake if insufficent balance
-        assert!(StakePool::increase_stake_from_account(
-            &100,
-            &staker_account,
-            Balances::free_balance(&staker_account) + 1
-        )
-        .is_err());
-    });
-}
-
-#[test]
-fn decreasing_stake() {
-    build_test_externalities().execute_with(|| {
-        let starting_pool_stake = 5000;
-        let _ =
-            Balances::deposit_creating(&StakePool::stake_pool_account_id(), starting_pool_stake);
-
-        let starting_stake = Balances::minimum_balance() + 2000;
-        <Stakes<Test>>::insert(
-            &100,
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: starting_stake,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                }),
-            },
-        );
-
-        let starting_balance: u64 = Balances::minimum_balance();
-        let staker_account: u64 = 1;
-        let decrease_stake_by: u64 = 200;
-
-        let _ = Balances::deposit_creating(&staker_account, starting_balance);
-
-        assert_err!(
-            StakePool::decrease_stake_to_account(&100, &staker_account, 0),
-            StakeActionError::Error(DecreasingStakeError::CannotChangeStakeByZero)
-        );
-
-        let total_staked =
-            StakePool::decrease_stake_to_account(&100, &staker_account, decrease_stake_by)
-                .ok()
-                .unwrap();
-        assert_eq!(total_staked, starting_stake - decrease_stake_by);
-
-        assert_eq!(
-            Balances::free_balance(&staker_account),
-            starting_balance + decrease_stake_by
-        );
-
-        assert_eq!(
-            StakePool::stake_pool_balance(),
-            starting_pool_stake - decrease_stake_by
-        );
-
-        assert_eq!(
-            StakePool::stakes(&100),
-            Stake {
-                created: 0,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: starting_stake - decrease_stake_by,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                })
-            }
-        );
-
-        // cannot unstake more than total at stake
-        assert_err!(
-            StakePool::decrease_stake_to_account(&100, &staker_account, total_staked + 1),
-            StakeActionError::Error(DecreasingStakeError::InsufficientStake)
-        );
-
-        // decreasing stake to value less than minimum_balance should reduce entire stake
-        if Balances::minimum_balance() > 0 {
-            let over_minimum = 50;
-            let staked_amount = Balances::minimum_balance() + over_minimum;
-
-            let _ = Balances::deposit_creating(&StakePool::stake_pool_account_id(), staked_amount);
-            <Stakes<Test>>::insert(
-                &200,
-                Stake {
-                    created: 0,
-                    staking_status: StakingStatus::Staked(StakedState {
-                        staked_amount,
-                        ongoing_slashes: BTreeMap::new(),
-                        next_slash_id: 0,
-                        staked_status: StakedStatus::Normal,
-                    }),
-                },
-            );
-
-            assert_eq!(Balances::free_balance(&2), 0);
-            let starting_pool_balance = StakePool::stake_pool_balance();
-            let remaining_stake = StakePool::decrease_stake_to_account(&200, &2, over_minimum + 1)
-                .ok()
-                .unwrap();
-            assert_eq!(remaining_stake, 0);
-            assert_eq!(Balances::free_balance(&2), staked_amount);
-            assert_eq!(
-                StakePool::stake_pool_balance(),
-                starting_pool_balance - staked_amount
-            );
-        }
-    });
-}
-
-#[test]
-fn initiating_pausing_resuming_cancelling_slashes() {
-    build_test_externalities().execute_with(|| {
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let _ = Balances::deposit_creating(&StakePool::stake_pool_account_id(), staked_amount);
-
-        assert_err!(
-            StakePool::initiate_slashing(&100, 5000, 0),
-            StakeActionError::StakeNotFound
-        );
-
-        let stake_id = StakePool::create_stake();
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::NotStaked,
-            },
-        );
-
-        assert_err!(
-            StakePool::initiate_slashing(&stake_id, 5000, 0),
-            StakeActionError::Error(InitiateSlashingError::SlashPeriodShouldBeGreaterThanZero)
-        );
-
-        assert_err!(
-            StakePool::initiate_slashing(&stake_id, 5000, 1),
-            StakeActionError::Error(InitiateSlashingError::NotStaked)
-        );
-
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: true,
-                    }),
-                }),
-            },
-        );
-
-        // assert_err!(StakePool::initiate_slashing(&stake_id, 0, 0), StakingError::ZeroSlashing);
-
-        let mut slash_id = 0;
-        assert!(StakePool::initiate_slashing(&stake_id, 5000, 10).is_ok());
-
-        let mut expected_ongoing_slashes: fixtures::OngoingSlashes = BTreeMap::new();
-
-        expected_ongoing_slashes.insert(
-            slash_id,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: true,
-                blocks_remaining_in_active_period_for_slashing: 10,
-                slash_amount: 5000,
-            },
-        );
-
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: expected_ongoing_slashes.clone(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: false,
-                    }),
-                })
-            }
-        );
-
-        assert_err!(
-            StakePool::pause_slashing(&stake_id, &999),
-            StakeActionError::Error(PauseSlashingError::SlashNotFound)
-        );
-        assert_err!(
-            StakePool::pause_slashing(&999, &slash_id),
-            StakeActionError::StakeNotFound
-        );
-
-        assert_ok!(StakePool::pause_slashing(&stake_id, &slash_id));
-        expected_ongoing_slashes.insert(
-            slash_id,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: false,
-                blocks_remaining_in_active_period_for_slashing: 10,
-                slash_amount: 5000,
-            },
-        );
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: expected_ongoing_slashes.clone(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: false,
-                    }),
-                })
-            }
-        );
-
-        assert_err!(
-            StakePool::resume_slashing(&stake_id, &999),
-            StakeActionError::Error(ResumeSlashingError::SlashNotFound)
-        );
-        assert_err!(
-            StakePool::resume_slashing(&999, &slash_id),
-            StakeActionError::StakeNotFound
-        );
-
-        assert_ok!(StakePool::resume_slashing(&stake_id, &slash_id));
-        expected_ongoing_slashes.insert(
-            slash_id,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: true,
-                blocks_remaining_in_active_period_for_slashing: 10,
-                slash_amount: 5000,
-            },
-        );
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: expected_ongoing_slashes.clone(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: false,
-                    }),
-                })
-            }
-        );
-
-        assert_err!(
-            StakePool::cancel_slashing(&stake_id, &999),
-            StakeActionError::Error(CancelSlashingError::SlashNotFound)
-        );
-        assert_err!(
-            StakePool::cancel_slashing(&999, &slash_id),
-            StakeActionError::StakeNotFound
-        );
-
-        assert_ok!(StakePool::cancel_slashing(&stake_id, &slash_id));
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: true,
-                    }),
-                })
-            }
-        );
-
-        expected_ongoing_slashes = BTreeMap::new();
-        let slashing_amount = 5000;
-        slash_id += 1;
-        assert!(StakePool::initiate_slashing(&stake_id, slashing_amount, 2).is_ok());
-
-        StakePool::on_finalize(System::block_number());
-
-        expected_ongoing_slashes.insert(
-            slash_id,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: true,
-                blocks_remaining_in_active_period_for_slashing: 1,
-                slash_amount: slashing_amount,
-            },
-        );
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: expected_ongoing_slashes.clone(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: false,
-                    }),
-                })
-            }
-        );
-
-        StakePool::on_finalize(System::block_number());
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: staked_amount - slashing_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: slash_id + 1,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 99,
-                        is_active: true
-                    })
-                })
-            }
-        );
-
-        assert_eq!(
-            StakePool::stake_pool_balance(),
-            staked_amount - slashing_amount
-        );
-    });
-}
-
-#[test]
-fn initiating_pausing_resuming_unstaking() {
-    build_test_externalities().execute_with(|| {
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let starting_stake_fund_balance = Balances::minimum_balance() + 3333;
-
-        let _ = Balances::deposit_creating(
-            &StakePool::stake_pool_account_id(),
-            starting_stake_fund_balance + staked_amount,
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&100, Some(1)),
-            StakeActionError::StakeNotFound
-        );
-
-        let stake_id = StakePool::create_stake();
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::NotStaked,
-            },
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, Some(0)),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingPeriodShouldBeGreaterThanZero)
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, Some(1)),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingError(
-                UnstakingError::NotStaked
-            ))
-        );
-
-        let mut ongoing_slashes = BTreeMap::new();
-        ongoing_slashes.insert(
-            1,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: true,
-                blocks_remaining_in_active_period_for_slashing: 100,
-                slash_amount: 100,
-            },
-        );
-
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes,
-                    next_slash_id: 2,
-                    staked_status: StakedStatus::Normal,
-                }),
-            },
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, Some(1)),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingError(
-                UnstakingError::CannotUnstakeWhileSlashesOngoing
-            ))
-        );
-
-        assert_ok!(StakePool::cancel_slashing(&stake_id, &1));
-
-        assert_ok!(StakePool::initiate_unstaking(&stake_id, Some(2)));
-
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 2,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: System::block_number(),
-                        blocks_remaining_in_active_period_for_unstaking: 2,
-                        is_active: true
-                    })
-                })
-            }
-        );
-
-        StakePool::on_finalize(System::block_number());
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 2,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: System::block_number(),
-                        blocks_remaining_in_active_period_for_unstaking: 1,
-                        is_active: true
-                    })
-                })
-            }
-        );
-
-        StakePool::finalize_slashing_and_unstaking();
-        assert_eq!(
-            StakePool::stakes(&stake_id),
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::NotStaked
-            }
-        );
-
-        assert_eq!(StakePool::stake_pool_balance(), starting_stake_fund_balance);
-
-        // unstaked amount is destroyed by StakingEventsHandler
-        assert_eq!(Balances::total_issuance(), starting_stake_fund_balance);
-    });
-}
-
-#[test]
-fn unstake() {
-    build_test_externalities().execute_with(|| {
-        assert_err!(
-            StakePool::initiate_unstaking(&0, None),
-            StakeActionError::StakeNotFound
-        );
-
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let starting_stake_fund_balance = Balances::minimum_balance() + 3333;
-
-        let _ = Balances::deposit_creating(
-            &StakePool::stake_pool_account_id(),
-            starting_stake_fund_balance + staked_amount,
-        );
-
-        let stake_id = StakePool::create_stake();
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, None),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingError(
-                UnstakingError::NotStaked
-            ))
-        );
-
-        let mut ongoing_slashes = BTreeMap::new();
-        ongoing_slashes.insert(
-            1,
-            Slash {
-                started_at_block: System::block_number(),
-                is_active: true,
-                blocks_remaining_in_active_period_for_slashing: 100,
-                slash_amount: 100,
-            },
-        );
-
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes,
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                }),
-            },
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, None),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingError(
-                UnstakingError::CannotUnstakeWhileSlashesOngoing
-            ))
-        );
-
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Unstaking(UnstakingState {
-                        started_at_block: 0,
-                        blocks_remaining_in_active_period_for_unstaking: 100,
-                        is_active: true,
-                    }),
-                }),
-            },
-        );
-
-        assert_err!(
-            StakePool::initiate_unstaking(&stake_id, None),
-            StakeActionError::Error(InitiateUnstakingError::UnstakingError(
-                UnstakingError::AlreadyUnstaking
-            ))
-        );
-
-        <Stakes<Test>>::insert(
-            &stake_id,
-            Stake {
-                created: System::block_number(),
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount,
-                    ongoing_slashes: BTreeMap::new(),
-                    next_slash_id: 0,
-                    staked_status: StakedStatus::Normal,
-                }),
-            },
-        );
-
-        assert_ok!(StakePool::initiate_unstaking(&stake_id, None));
-        assert_eq!(StakePool::stake_pool_balance(), starting_stake_fund_balance);
-    });
-}
-
-#[test]
-fn immediate_slashing_cannot_slash_non_existent_stake() {
-    build_test_externalities().execute_with(|| {
-        let outcome = StakePool::slash_immediate(&100, 5000, false);
-        assert!(outcome.is_err());
-        let error = outcome.err().unwrap();
-        assert_eq!(error, StakeActionError::StakeNotFound);
-    });
-}
-
-#[test]
-fn immediate_slashing_without_unstaking() {
-    build_test_externalities().execute_with(|| {
-        const UNSTAKE_POLICY: bool = false;
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let _ = Balances::deposit_creating(&StakePool::stake_pool_account_id(), staked_amount);
-
-        let stake_id = StakePool::create_stake();
-        let created_at = System::block_number();
-        let initial_stake_state = Stake {
-            created: created_at,
-            staking_status: StakingStatus::Staked(StakedState {
-                staked_amount,
-                staked_status: StakedStatus::Normal,
-                next_slash_id: 0,
-                ongoing_slashes: BTreeMap::new(),
-            }),
-        };
-        <Stakes<Test>>::insert(&stake_id, initial_stake_state);
-
-        let slash_amount = 5000;
-
-        let outcome = StakePool::slash_immediate(&stake_id, slash_amount, UNSTAKE_POLICY);
-        assert!(outcome.is_ok());
-        let outcome = outcome.ok().unwrap();
-
-        assert_eq!(outcome.caused_unstake, false);
-        assert_eq!(outcome.actually_slashed, slash_amount);
-        assert_eq!(outcome.remaining_stake, staked_amount - slash_amount);
-        // Default handler destroys imbalance
-        assert_eq!(outcome.remaining_imbalance.peek(), 0);
-
-        assert_eq!(
-            <Stakes<Test>>::get(stake_id),
-            Stake {
-                created: created_at,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: outcome.remaining_stake,
-                    staked_status: StakedStatus::Normal,
-                    next_slash_id: 0,
-                    ongoing_slashes: BTreeMap::new()
-                }),
-            }
-        );
-
-        // slash to zero but without asking to unstake
-        // Slash and unstake by making slash go to zero
-        let slash_amount = outcome.remaining_stake;
-        let outcome = StakePool::slash_immediate(&stake_id, slash_amount, UNSTAKE_POLICY)
-            .ok()
-            .unwrap();
-        assert_eq!(outcome.caused_unstake, false);
-        assert_eq!(outcome.actually_slashed, slash_amount);
-        assert_eq!(outcome.remaining_stake, 0);
-        // Default handler destroys imbalance
-        assert_eq!(outcome.remaining_imbalance.peek(), 0);
-
-        // Should still be staked, even if staked amount = 0
-        assert_eq!(
-            <Stakes<Test>>::get(stake_id),
-            Stake {
-                created: created_at,
-                staking_status: StakingStatus::Staked(StakedState {
-                    staked_amount: 0,
-                    staked_status: StakedStatus::Normal,
-                    next_slash_id: 0,
-                    ongoing_slashes: BTreeMap::new()
-                }),
-            }
-        );
-    });
-}
-
-#[test]
-fn immediate_slashing_with_unstaking() {
-    build_test_externalities().execute_with(|| {
-        const UNSTAKE_POLICY: bool = true;
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let _ = Balances::deposit_creating(&StakePool::stake_pool_account_id(), staked_amount);
-
-        let stake_id = StakePool::create_stake();
-        let created_at = System::block_number();
-        let initial_stake_state = Stake {
-            created: created_at,
-            staking_status: StakingStatus::Staked(StakedState {
-                staked_amount,
-                staked_status: StakedStatus::Normal,
-                next_slash_id: 0,
-                ongoing_slashes: BTreeMap::new(),
-            }),
-        };
-        <Stakes<Test>>::insert(&stake_id, initial_stake_state);
-
-        // Slash whole amount unstake by making slash go to zero
-        let slash_amount = staked_amount;
-        let outcome = StakePool::slash_immediate(&stake_id, slash_amount, UNSTAKE_POLICY)
-            .ok()
-            .unwrap();
-        assert_eq!(outcome.caused_unstake, true);
-        assert_eq!(outcome.actually_slashed, slash_amount);
-        assert_eq!(outcome.remaining_stake, 0);
-        // Default handler destroys imbalance
-        assert_eq!(outcome.remaining_imbalance.peek(), 0);
-        // Should now be unstaked
-        assert_eq!(
-            <Stakes<Test>>::get(stake_id),
-            Stake {
-                created: created_at,
-                staking_status: StakingStatus::NotStaked
-            }
-        );
-    });
-}
-
-#[test]
-fn immediate_slashing_cannot_slash_if_not_staked() {
-    build_test_externalities().execute_with(|| {
-        let stake_id = StakePool::create_stake();
-        let created_at = System::block_number();
-        let initial_stake_state = Stake {
-            created: created_at,
-            staking_status: StakingStatus::NotStaked,
-        };
-        <Stakes<Test>>::insert(&stake_id, initial_stake_state);
-
-        let outcome = StakePool::slash_immediate(&stake_id, 1, false);
-        let outcome_err = outcome.err().unwrap();
-        assert_eq!(
-            outcome_err,
-            StakeActionError::Error(ImmediateSlashingError::NotStaked)
-        );
-    });
-}
-
-#[test]
-fn immediate_slashing_cannot_slash_zero() {
-    build_test_externalities().execute_with(|| {
-        let staked_amount = Balances::minimum_balance() + 10000;
-        let _ = Balances::deposit_creating(&StakePool::stake_pool_account_id(), staked_amount);
-
-        let stake_id = StakePool::create_stake();
-        let created_at = System::block_number();
-        let initial_stake_state = Stake {
-            created: created_at,
-            staking_status: StakingStatus::Staked(StakedState {
-                staked_amount,
-                staked_status: StakedStatus::Normal,
-                next_slash_id: 0,
-                ongoing_slashes: BTreeMap::new(),
-            }),
-        };
-        <Stakes<Test>>::insert(&stake_id, initial_stake_state);
-
-        const ZERO_SLASH_AMOUNT: u64 = 0;
-
-        let outcome_err = StakePool::slash_immediate(&stake_id, ZERO_SLASH_AMOUNT, true)
-            .err()
-            .unwrap();
-        assert_eq!(
-            outcome_err,
-            StakeActionError::Error(ImmediateSlashingError::SlashAmountShouldBeGreaterThanZero)
-        );
-    });
-}

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

@@ -21,7 +21,6 @@ parameter_types! {
     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;
     pub const MembershipFee: u64 = 100;
 }

+ 0 - 2
runtime-modules/storage/Cargo.toml

@@ -21,8 +21,6 @@ common = { package = 'pallet-common', default-features = false, path = '../commo
 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'}
-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'}
 staking-handler = { package = 'staking-handler', default-features = false, path = '../staking-handler'}

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

@@ -133,7 +133,6 @@ impl pallet_timestamp::Trait for Test {
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl balances::Trait for Test {
@@ -206,14 +205,6 @@ impl membership::Trait for Test {
     type MembershipFee = MembershipFee;
 }
 
-impl stake::Trait for Test {
-    type Currency = Balances;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
 impl minting::Trait for Test {
     type Currency = Balances;
     type MintId = u64;
@@ -225,13 +216,6 @@ impl recurringrewards::Trait for Test {
     type RewardRelationshipId = u64;
 }
 
-impl hiring::Trait for Test {
-    type OpeningId = u64;
-    type ApplicationId = u64;
-    type ApplicationDeactivatedHandler = ();
-    type StakeHandlerProvider = hiring::Module<Self>;
-}
-
 pub struct ExtBuilder {
     first_data_object_type_id: u64,
     first_content_id: u64,

+ 1 - 1
runtime-modules/working-group/src/lib.rs

@@ -49,7 +49,7 @@ use sp_std::vec::Vec;
 pub use errors::Error;
 pub use types::{
     Application, ApplicationId, ApplyOnOpeningParameters, BalanceOf, MemberId, Opening, OpeningId,
-    OpeningType, Penalty, RewardPolicy, StakePolicy, Worker, WorkerId,
+    OpeningType, Penalty, RewardPolicy, StakeParameters, StakePolicy, Worker, WorkerId,
 };
 use types::{ApplicationInfo, WorkerInfo};
 

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

@@ -37,7 +37,6 @@ parameter_types! {
     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;
     pub const MembershipFee: u64 = 0;
 }

+ 0 - 4
runtime/Cargo.toml

@@ -66,9 +66,7 @@ common = { package = 'pallet-common', default-features = false, path = '../runti
 memo = { package = 'pallet-memo', default-features = false, path = '../runtime-modules/memo'}
 forum = { package = 'pallet-forum', default-features = false, path = '../runtime-modules/forum'}
 membership = { package = 'pallet-membership', default-features = false, path = '../runtime-modules/membership'}
-stake = { package = 'pallet-stake', default-features = false, path = '../runtime-modules/stake'}
 governance = { package = 'pallet-governance', default-features = false, path = '../runtime-modules/governance'}
-hiring = { package = 'pallet-hiring', default-features = false, path = '../runtime-modules/hiring'}
 minting = { package = 'pallet-token-mint', default-features = false, path = '../runtime-modules/token-minting'}
 recurring-rewards = { package = 'pallet-recurring-reward', default-features = false, path = '../runtime-modules/recurring-reward'}
 working-group = { package = 'pallet-working-group', default-features = false, path = '../runtime-modules/working-group'}
@@ -142,9 +140,7 @@ std = [
     'memo/std',
     'forum/std',
     'membership/std',
-    'stake/std',
     'governance/std',
-    'hiring/std',
     'minting/std',
     'recurring-rewards/std',
     'working-group/std',

+ 11 - 24
runtime/src/lib.rs

@@ -447,13 +447,6 @@ impl content_directory::Trait for Runtime {
     type IndividualEntitiesCreationLimit = IndividualEntitiesCreationLimit;
 }
 
-impl hiring::Trait for Runtime {
-    type OpeningId = u64;
-    type ApplicationId = u64;
-    type ApplicationDeactivatedHandler = (); // TODO - what needs to happen?
-    type StakeHandlerProvider = hiring::Module<Self>;
-}
-
 impl minting::Trait for Runtime {
     type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
     type MintId = u64;
@@ -465,18 +458,6 @@ impl recurring_rewards::Trait for Runtime {
     type RewardRelationshipId = u64;
 }
 
-parameter_types! {
-    pub const StakePoolId: [u8; 8] = *b"joystake";
-}
-
-impl stake::Trait for Runtime {
-    type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
-    type StakePoolId = StakePoolId;
-    type StakingEventsHandler = ();
-    type StakeId = u64;
-    type SlashId = u64;
-}
-
 impl common::currency::GovernanceCurrency for Runtime {
     type Currency = pallet_balances::Module<Self>;
 }
@@ -625,10 +606,18 @@ parameter_types! {
     pub const ForumGroupLockId: LockIdentifier = [8; 8];
 }
 
+// Staking managers type aliases.
+pub type ForumWorkingGroupStakingManager =
+    staking_handler::StakingManager<Runtime, ForumGroupLockId>;
+pub type ContentDirectoryWorkingGroupStakingManager =
+    staking_handler::StakingManager<Runtime, ContentWorkingGroupLockId>;
+pub type StorageWorkingGroupStakingManager =
+    staking_handler::StakingManager<Runtime, StorageWorkingGroupLockId>;
+
 impl working_group::Trait<ForumWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-    type StakingHandler = staking_handler::StakingManager<Self, ForumGroupLockId>;
+    type StakingHandler = ForumWorkingGroupStakingManager;
     type MemberOriginValidator = MembershipOriginValidator<Self>;
     type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
     type RewardPeriod = ForumWorkingGroupRewardPeriod;
@@ -637,7 +626,7 @@ impl working_group::Trait<ForumWorkingGroupInstance> for Runtime {
 impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-    type StakingHandler = staking_handler::StakingManager<Self, StorageWorkingGroupLockId>;
+    type StakingHandler = StorageWorkingGroupStakingManager;
     type MemberOriginValidator = MembershipOriginValidator<Self>;
     type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
     type RewardPeriod = StorageWorkingGroupRewardPeriod;
@@ -646,7 +635,7 @@ impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
 impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Runtime {
     type Event = Event;
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
-    type StakingHandler = staking_handler::StakingManager<Self, ContentWorkingGroupLockId>;
+    type StakingHandler = ContentDirectoryWorkingGroupStakingManager;
     type MemberOriginValidator = MembershipOriginValidator<Self>;
     type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
     type RewardPeriod = ContentWorkingGroupRewardPeriod;
@@ -797,10 +786,8 @@ construct_runtime!(
         Memo: memo::{Module, Call, Storage, Event<T>},
         Members: membership::{Module, Call, Storage, Event<T>, Config<T>},
         Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
-        Stake: stake::{Module, Call, Storage},
         Minting: minting::{Module, Call, Storage},
         RecurringRewards: recurring_rewards::{Module, Call, Storage},
-        Hiring: hiring::{Module, Call, Storage},
         ContentDirectory: content_directory::{Module, Call, Storage, Event<T>, Config<T>},
         Constitution: pallet_constitution::{Module, Call, Storage, Event},
         // --- Storage

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

@@ -50,7 +50,7 @@ pub(crate) fn increase_total_balance_issuance_using_account_id(
     type Balances = pallet_balances::Module<Runtime>;
     let initial_balance = Balances::total_issuance();
     {
-        let _ = <Runtime as stake::Trait>::Currency::deposit_creating(&account_id, balance);
+        let _ = Balances::deposit_creating(&account_id, balance);
     }
     assert_eq!(Balances::total_issuance(), initial_balance + balance);
 }

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

@@ -282,17 +282,13 @@ fn proposal_cancellation_with_slashes_with_balance_checks_succeeds() {
             .with_proposer(member_id);
 
         let account_balance = 500000;
-        let _imbalance =
-            <Runtime as stake::Trait>::Currency::deposit_creating(&account_id, account_balance);
+        let _imbalance = Balances::deposit_creating(&account_id, account_balance);
 
-        assert_eq!(
-            <Runtime as stake::Trait>::Currency::usable_balance(&account_id),
-            account_balance
-        );
+        assert_eq!(Balances::usable_balance(&account_id), account_balance);
 
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
         assert_eq!(
-            <Runtime as stake::Trait>::Currency::usable_balance(&account_id),
+            Balances::usable_balance(&account_id),
             account_balance - stake_amount
         );
 
@@ -318,7 +314,7 @@ fn proposal_cancellation_with_slashes_with_balance_checks_succeeds() {
 
         let cancellation_fee = ProposalCancellationFee::get() as u128;
         assert_eq!(
-            <Runtime as stake::Trait>::Currency::usable_balance(&account_id),
+            Balances::usable_balance(&account_id),
             account_balance - cancellation_fee
         );
     });

+ 642 - 613
runtime/src/tests/proposals_integration/working_group_proposals.rs

@@ -3,24 +3,22 @@
 
 use super::*;
 
-use frame_system::RawOrigin;
-
 use common::working_group::WorkingGroup;
+use frame_system::RawOrigin;
 use proposals_codex::AddOpeningParameters;
-use working_group::Penalty;
+use strum::IntoEnumIterator;
+use working_group::{Penalty, StakeParameters};
 
 use crate::primitives::{ActorId, MemberId};
 use crate::{
     Balance, BlockNumber, ContentDirectoryWorkingGroup, ContentDirectoryWorkingGroupInstance,
-    ForumWorkingGroup, ForumWorkingGroupInstance, StorageWorkingGroup, StorageWorkingGroupInstance,
+    ContentDirectoryWorkingGroupStakingManager, ForumWorkingGroup, ForumWorkingGroupInstance,
+    ForumWorkingGroupStakingManager, StorageWorkingGroup, StorageWorkingGroupInstance,
+    StorageWorkingGroupStakingManager,
 };
-use frame_support::traits;
-use strum::IntoEnumIterator;
 
 type WorkingGroupInstance<T, I> = working_group::Module<T, I>;
 
-type Hiring = hiring::Module<Runtime>;
-
 fn add_opening(
     member_id: MemberId,
     account_id: [u8; 32],
@@ -115,14 +113,6 @@ fn fill_opening(
     codex_extrinsic_test_fixture.call_extrinsic_and_assert();
 }
 
-fn get_stake_balance(stake: stake::Stake<BlockNumber, Balance, u64>) -> Balance {
-    if let stake::StakingStatus::Staked(stake) = stake.staking_status {
-        return stake.staked_amount;
-    }
-
-    panic!("Not staked.");
-}
-
 fn decrease_stake(
     member_id: u64,
     account_id: [u8; 32],
@@ -256,6 +246,7 @@ fn terminate_role(
     member_id: MemberId,
     account_id: [u8; 32],
     leader_worker_id: u64,
+    penalty: Option<Penalty<Balance>>,
     sequence_number: u32, // action sequence number to align with other actions
     working_group: WorkingGroup,
 ) {
@@ -271,10 +262,7 @@ fn terminate_role(
             Some(account_id.into()),
             proposals_codex::TerminateRoleParameters {
                 worker_id: leader_worker_id,
-                penalty: Some(Penalty {
-                    slashing_amount: 100,
-                    slashing_text: Vec::new(),
-                }),
+                penalty: penalty.clone(),
                 working_group,
             },
             None,
@@ -315,7 +303,7 @@ fn create_add_working_group_leader_opening_proposal_execution_succeeds() {
 }
 
 fn run_create_add_working_group_leader_opening_proposal_execution_succeeds<
-    T: working_group::Trait<I> + frame_system::Trait + stake::Trait,
+    T: working_group::Trait<I> + frame_system::Trait,
     I: frame_support::traits::Instance,
 >(
     working_group: WorkingGroup,
@@ -368,640 +356,681 @@ fn create_fill_working_group_leader_opening_proposal_execution_succeeds() {
             }
         }
     }
+}
+
+fn run_create_fill_working_group_leader_opening_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait,
+    I: frame_support::traits::Instance,
+>(
+    working_group: WorkingGroup,
+) where
+    <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
+    <T as membership::Trait>::MemberId: From<u64>,
+    working_group::MemberId<T>: From<u64>,
+{
+    initial_test_ext().execute_with(|| {
+        let member_id: u64 = 1;
+        let account_id: [u8; 32] = [member_id as u8; 32];
 
-    fn run_create_fill_working_group_leader_opening_proposal_execution_succeeds<
-        T: working_group::Trait<I> + frame_system::Trait + stake::Trait,
-        I: frame_support::traits::Instance,
-    >(
-        working_group: WorkingGroup,
-    ) where
-        <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-        <T as membership::Trait>::MemberId: From<u64>,
-        working_group::MemberId<T>: From<u64>,
-    {
-        initial_test_ext().execute_with(|| {
-            let member_id: u64 = 1;
-            let account_id: [u8; 32] = [member_id as u8; 32];
-
-            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(),
-                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;
-
-            let lead = WorkingGroupInstance::<T, I>::current_lead();
-            assert!(lead.is_none());
-
-            fill_opening(
-                member_id,
-                account_id,
+        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(),
+            working_group::ApplyOnOpeningParameters::<T> {
+                member_id: member_id.into(),
                 opening_id,
-                expected_application_id,
-                2,
-                working_group,
-            );
+                role_account_id: account_id.into(),
+                reward_account_id: account_id.into(),
+                description: Vec::new(),
+                stake_parameters: None,
+            },
+        );
 
-            run_to_block(30);
+        assert_eq!(apply_result, Ok(()));
 
-            let lead = WorkingGroupInstance::<T, I>::current_lead();
-            assert!(lead.is_some());
-        });
-    }
+        let expected_application_id = 0;
+
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_none());
+
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            2,
+            working_group,
+        );
 
-    #[test]
-    fn create_decrease_group_leader_stake_proposal_execution_succeeds() {
-        // This uses strum crate for enum iteration
-        for group in WorkingGroup::iter() {
-            match group {
-                WorkingGroup::Content => {
-                    run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        ContentDirectoryWorkingGroupInstance,
-                    >(group);
-                }
-                WorkingGroup::Storage => {
-                    run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        StorageWorkingGroupInstance,
-                    >(group);
-                }
-                WorkingGroup::Forum => {
-                    run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        ForumWorkingGroupInstance,
-                    >(group);
-                }
+        run_to_block(30);
+
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_some());
+    });
+}
+
+#[test]
+fn create_decrease_group_leader_stake_proposal_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                    ContentDirectoryWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Storage => {
+                run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                    StorageWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Forum => {
+                run_create_decrease_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                    ForumWorkingGroupStakingManager,
+                >(group);
             }
         }
     }
+}
+
+fn run_create_decrease_group_leader_stake_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait + membership::Trait + pallet_balances::Trait,
+    I: frame_support::traits::Instance,
+    SM: staking_handler::StakingHandler<T>,
+>(
+    working_group: WorkingGroup,
+) where
+    <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 pallet_balances::Trait>::Balance: 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: Balance = 100;
 
-    fn run_create_decrease_group_leader_stake_proposal_execution_succeeds<
-        T: working_group::Trait<I> + frame_system::Trait + stake::Trait,
-        I: frame_support::traits::Instance,
-    >(
-        working_group: WorkingGroup,
-    ) where
-        <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 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] = [member_id as u8; 32];
-            let stake_amount: Balance = 100;
-
-            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(),
-                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;
-
-            let lead = WorkingGroupInstance::<T, I>::current_lead();
-            assert!(lead.is_none());
-
-            fill_opening(
-                member_id,
-                account_id,
+        let stake_policy = Some(working_group::StakePolicy {
+            stake_amount,
+            leaving_unstaking_period: 45000, // more than min value
+        });
+
+        let stake_parameters = Some(
+            StakeParameters::<T::AccountId, working_group::BalanceOf<T>> {
+                stake: stake_amount.into(),
+                staking_account_id: account_id.into(),
+            },
+        );
+
+        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(),
+            working_group::ApplyOnOpeningParameters::<T> {
+                member_id: member_id.into(),
                 opening_id,
-                expected_application_id,
-                3,
-                working_group,
-            );
+                role_account_id: account_id.into(),
+                reward_account_id: account_id.into(),
+                description: Vec::new(),
+                stake_parameters,
+            },
+        );
 
-            let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
+        assert_eq!(apply_result, Ok(()));
 
-            let stake_id = 1;
-            let old_balance = Balances::free_balance(&account_id.into());
-            let old_stake = <stake::Module<Runtime>>::stakes(stake_id);
+        let expected_application_id = 0;
 
-            assert_eq!(get_stake_balance(old_stake), stake_amount);
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_none());
 
-            let decreasing_stake_amount = 30;
-            decrease_stake(
-                member_id,
-                account_id,
-                leader_worker_id.into(),
-                decreasing_stake_amount,
-                4,
-                working_group,
-            );
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            2,
+            working_group,
+        );
 
-            let new_balance = Balances::free_balance(&account_id.into());
-            let new_stake = <stake::Module<Runtime>>::stakes(stake_id);
+        let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
 
-            assert_eq!(
-                get_stake_balance(new_stake),
-                stake_amount - decreasing_stake_amount
-            );
-            assert_eq!(new_balance, old_balance + decreasing_stake_amount);
-        });
-    }
+        let old_balance = Balances::usable_balance(&account_id.into());
+        let old_stake = SM::current_stake(&account_id.into());
+
+        assert_eq!(old_stake, stake_amount.into());
+
+        let decreasing_stake_amount = 30;
+        decrease_stake(
+            member_id,
+            account_id,
+            leader_worker_id.into(),
+            decreasing_stake_amount,
+            3,
+            working_group,
+        );
+
+        let new_balance = Balances::usable_balance(&account_id.into());
+        let new_stake: working_group::BalanceOf<T> = SM::current_stake(&account_id.into()).into();
+        let converted_stake_amount: working_group::BalanceOf<T> = stake_amount.into();
+
+        assert_eq!(
+            new_stake,
+            converted_stake_amount - decreasing_stake_amount.into()
+        );
+        assert_eq!(new_balance, old_balance + decreasing_stake_amount);
+    });
+}
 
-    #[test]
-    fn create_slash_group_leader_stake_proposal_execution_succeeds() {
-        // This uses strum crate for enum iteration
-        for group in WorkingGroup::iter() {
-            match group {
-                WorkingGroup::Content => {
-                    run_create_slash_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        ContentDirectoryWorkingGroupInstance,
-                    >(group)
-                }
-                WorkingGroup::Storage => {
-                    run_create_slash_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        StorageWorkingGroupInstance,
-                    >(group)
-                }
-                WorkingGroup::Forum => {
-                    run_create_slash_group_leader_stake_proposal_execution_succeeds::<
-                        Runtime,
-                        ForumWorkingGroupInstance,
-                    >(group)
-                }
+#[test]
+fn create_slash_group_leader_stake_proposal_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_slash_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                    ContentDirectoryWorkingGroupStakingManager,
+                >(group)
+            }
+            WorkingGroup::Storage => {
+                run_create_slash_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                    StorageWorkingGroupStakingManager,
+                >(group)
+            }
+            WorkingGroup::Forum => {
+                run_create_slash_group_leader_stake_proposal_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                    ForumWorkingGroupStakingManager,
+                >(group)
             }
         }
     }
+}
+
+fn run_create_slash_group_leader_stake_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait,
+    I: frame_support::traits::Instance,
+    SM: staking_handler::StakingHandler<T>,
+>(
+    working_group: WorkingGroup,
+) where
+    <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 pallet_balances::Trait>::Balance: 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: Balance = 100;
+
+        let stake_policy = Some(working_group::StakePolicy {
+            stake_amount,
+            leaving_unstaking_period: 45000, // more than min value
+        });
+
+        let stake_parameters = Some(
+            StakeParameters::<T::AccountId, working_group::BalanceOf<T>> {
+                stake: stake_amount.into(),
+                staking_account_id: account_id.into(),
+            },
+        );
+
+        let opening_id = add_opening(member_id, account_id, stake_policy, 1, working_group);
 
-    fn run_create_slash_group_leader_stake_proposal_execution_succeeds<
-        T: working_group::Trait<I> + frame_system::Trait + stake::Trait,
-        I: frame_support::traits::Instance,
-    >(
-        working_group: WorkingGroup,
-    ) where
-        <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 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] = [member_id as u8; 32];
-            let stake_amount: Balance = 100;
-
-            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(),
-                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;
-
-            let lead = WorkingGroupInstance::<T, I>::current_lead();
-
-            assert!(lead.is_none());
-
-            fill_opening(
-                member_id,
-                account_id,
+        let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
+            RawOrigin::Signed(account_id.into()).into(),
+            working_group::ApplyOnOpeningParameters::<T> {
+                member_id: member_id.into(),
                 opening_id,
-                expected_application_id,
-                3,
-                working_group,
-            );
+                role_account_id: account_id.into(),
+                reward_account_id: account_id.into(),
+                description: Vec::new(),
+                stake_parameters,
+            },
+        );
 
-            let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
+        assert_eq!(apply_result, Ok(()));
 
-            let stake_id = 1;
-            let old_balance = Balances::free_balance(&account_id.into());
-            let old_stake = <stake::Module<Runtime>>::stakes(stake_id);
+        let expected_application_id = 0;
 
-            assert_eq!(get_stake_balance(old_stake), stake_amount);
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
 
-            let slashing_stake_amount = 30;
-            slash_stake(
-                member_id,
-                account_id,
-                leader_worker_id.into(),
-                slashing_stake_amount,
-                4,
-                working_group,
-            );
+        assert!(lead.is_none());
 
-            let new_balance = Balances::free_balance(&account_id.into());
-            let new_stake = <stake::Module<Runtime>>::stakes(stake_id);
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            2,
+            working_group,
+        );
 
-            assert_eq!(
-                get_stake_balance(new_stake),
-                stake_amount as u128 - slashing_stake_amount
-            );
-            assert_eq!(new_balance, old_balance);
-        });
-    }
+        let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
 
-    #[test]
-    fn create_set_working_group_mint_capacity_proposal_execution_succeeds() {
-        // This uses strum crate for enum iteration
-        for group in WorkingGroup::iter() {
-            match group {
-                WorkingGroup::Content => {
-                    run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                        Runtime,
-                        ContentDirectoryWorkingGroupInstance,
-                    >(group);
-                }
-                WorkingGroup::Storage => {
-                    run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                        Runtime,
-                        StorageWorkingGroupInstance,
-                    >(group);
-                }
-                WorkingGroup::Forum => {
-                    run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                        Runtime,
-                        ForumWorkingGroupInstance,
-                    >(group);
-                }
-            }
-        }
+        let old_balance = Balances::usable_balance(&account_id.into());
+        let old_stake = SM::current_stake(&account_id.into());
 
-        fn run_create_set_working_group_mint_capacity_proposal_execution_succeeds<
-            T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
-            I: frame_support::traits::Instance,
-        >(
-            working_group: WorkingGroup,
-        ) where
-            <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
-            <T as minting::Trait>::MintId: From<u64>,
-            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 mint_capacity = 999999;
-                set_mint_capacity::<T, I>(
-                    member_id,
-                    account_id,
-                    mint_capacity,
-                    1,
-                    true,
-                    working_group,
-                );
-
-                assert_eq!(
-                    working_group::Module::<T, I>::budget(),
-                    mint_capacity.into()
-                );
-            });
-        }
+        assert_eq!(old_stake, stake_amount.into());
+
+        let slashing_stake_amount = 30;
+        slash_stake(
+            member_id,
+            account_id,
+            leader_worker_id.into(),
+            slashing_stake_amount,
+            3,
+            working_group,
+        );
 
-        #[test]
-        fn create_set_group_leader_reward_proposal_execution_succeeds() {
-            // This uses strum crate for enum iteration
-            for group in WorkingGroup::iter() {
-                match group {
-                    WorkingGroup::Content => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                            Runtime,
-                            ContentDirectoryWorkingGroupInstance,
-                        >(group);
-                    }
-                    WorkingGroup::Storage => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                            Runtime,
-                            StorageWorkingGroupInstance,
-                        >(group);
-                    }
-                    WorkingGroup::Forum => {
-                        run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
-                            Runtime,
-                            ForumWorkingGroupInstance,
-                        >(group);
-                    }
-                }
+        let new_balance = Balances::usable_balance(&account_id.into());
+        let new_stake: working_group::BalanceOf<T> = SM::current_stake(&account_id.into()).into();
+        let converted_stake_amount: working_group::BalanceOf<T> = stake_amount.into();
+
+        assert_eq!(
+            new_stake,
+            converted_stake_amount - slashing_stake_amount.into()
+        );
+        assert_eq!(new_balance, old_balance);
+    });
+}
+
+#[test]
+fn create_set_working_group_mint_capacity_proposal_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                >(group);
+            }
+            WorkingGroup::Storage => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                >(group);
+            }
+            WorkingGroup::Forum => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                >(group);
             }
         }
+    }
+}
 
-        fn run_create_set_group_leader_reward_proposal_execution_succeeds<
-            T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
-            I: frame_support::traits::Instance,
-        >(
-            working_group: WorkingGroup,
-        ) where
-            <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>,
-            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_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(),
-                    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;
-
-                let lead = WorkingGroupInstance::<T, I>::current_lead();
-                assert!(lead.is_none());
-
-                set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
-
-                fill_opening(
-                    member_id,
-                    account_id,
-                    opening_id,
-                    expected_application_id,
-                    4,
-                    working_group,
-                );
-
-                let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
-
-                let new_reward_amount = 999;
-                set_reward(
-                    member_id,
-                    account_id,
-                    leader_worker_id.into(),
-                    new_reward_amount,
-                    5,
-                    working_group,
-                );
-
-                let worker = WorkingGroupInstance::<T, I>::worker_by_id(leader_worker_id);
-
-                assert_eq!(worker.reward_per_block, Some(new_reward_amount.into()));
-            });
-        }
+fn run_create_set_working_group_mint_capacity_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
+    I: frame_support::traits::Instance,
+>(
+    working_group: WorkingGroup,
+) where
+    <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
+    <T as membership::Trait>::MemberId: From<u64>,
+    <T as minting::Trait>::MintId: From<u64>,
+    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 mint_capacity = 999999;
+        set_mint_capacity::<T, I>(member_id, account_id, mint_capacity, 1, true, working_group);
 
-        #[test]
-        fn create_terminate_group_leader_role_proposal_execution_succeeds() {
-            // This uses strum crate for enum iteration
-            for group in WorkingGroup::iter() {
-                match group {
-                    WorkingGroup::Content => {
-                        run_create_terminate_group_leader_role_proposal_execution_succeeds::<
-                            Runtime,
-                            ContentDirectoryWorkingGroupInstance,
-                        >(group);
-                    }
-                    WorkingGroup::Storage => {
-                        run_create_terminate_group_leader_role_proposal_execution_succeeds::<
-                            Runtime,
-                            StorageWorkingGroupInstance,
-                        >(group);
-                    }
-                    WorkingGroup::Forum => {
-                        run_create_terminate_group_leader_role_proposal_execution_succeeds::<
-                            Runtime,
-                            ForumWorkingGroupInstance,
-                        >(group);
-                    }
-                }
+        assert_eq!(
+            working_group::Module::<T, I>::budget(),
+            mint_capacity.into()
+        );
+    });
+}
+
+#[test]
+fn create_set_group_leader_reward_proposal_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                >(group);
+            }
+            WorkingGroup::Storage => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                >(group);
+            }
+            WorkingGroup::Forum => {
+                run_create_set_working_group_mint_capacity_proposal_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                >(group);
             }
         }
+    }
+}
 
-        fn run_create_terminate_group_leader_role_proposal_execution_succeeds<
-            T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
-            I: frame_support::traits::Instance,
-        >(
-            working_group: WorkingGroup,
-        ) 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>,
-        {
-            initial_test_ext().execute_with(|| {
-                let member_id: MemberId = 1;
-                let account_id: [u8; 32] = [0; 32];
-                let stake_amount = 100_u128;
-
-                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(),
-                    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;
-
-                let lead = WorkingGroupInstance::<T, I>::current_lead();
-                assert!(lead.is_none());
-
-                set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
-
-                fill_opening(
-                    member_id,
-                    account_id,
-                    opening_id,
-                    expected_application_id,
-                    4,
-                    working_group,
-                );
-
-                let stake_id = 1;
-                let old_balance = Balances::free_balance(&account_id.into());
-                let old_stake = <stake::Module<Runtime>>::stakes(stake_id);
-
-                assert_eq!(get_stake_balance(old_stake), stake_amount);
-
-                let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
-
-                terminate_role(
-                    member_id,
-                    account_id,
-                    leader_worker_id.into(),
-                    5,
-                    working_group,
-                );
-
-                assert!(WorkingGroupInstance::<T, I>::current_lead().is_none());
-
-                let new_balance = Balances::free_balance(&account_id.into());
-                let new_stake = <stake::Module<Runtime>>::stakes(stake_id);
-
-                assert_eq!(new_stake.staking_status, stake::StakingStatus::NotStaked);
-                assert_eq!(new_balance, old_balance + stake_amount);
-            });
-        }
+fn run_create_set_group_leader_reward_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
+    I: frame_support::traits::Instance,
+>(
+    working_group: WorkingGroup,
+) where
+    <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>,
+    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_policy = Some(working_group::StakePolicy {
+            stake_amount: 100,
+            leaving_unstaking_period: 0,
+        });
 
-        #[test]
-        fn create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds() {
-            // This uses strum crate for enum iteration
-            for group in WorkingGroup::iter() {
-                match group {
-                    WorkingGroup::Content => {
-                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, ContentDirectoryWorkingGroupInstance>(group);
-                    }
-                    WorkingGroup::Storage => {
-                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, StorageWorkingGroupInstance>(group);
-                    }
-                    WorkingGroup::Forum => {
-                        run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<Runtime, ForumWorkingGroupInstance>(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(),
+            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;
+
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_none());
+
+        set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
+
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            4,
+            working_group,
+        );
+
+        let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
+
+        let new_reward_amount = 999;
+        set_reward(
+            member_id,
+            account_id,
+            leader_worker_id.into(),
+            new_reward_amount,
+            5,
+            working_group,
+        );
+
+        let worker = WorkingGroupInstance::<T, I>::worker_by_id(leader_worker_id);
+
+        assert_eq!(worker.reward_per_block, Some(new_reward_amount.into()));
+    });
+}
+
+#[test]
+fn create_terminate_group_leader_role_proposal_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_terminate_group_leader_role_proposal_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                    ContentDirectoryWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Storage => {
+                run_create_terminate_group_leader_role_proposal_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                    StorageWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Forum => {
+                run_create_terminate_group_leader_role_proposal_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                    ForumWorkingGroupStakingManager,
+                >(group);
             }
         }
+    }
+}
+
+fn run_create_terminate_group_leader_role_proposal_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
+    I: frame_support::traits::Instance,
+    SM: staking_handler::StakingHandler<T>,
+>(
+    working_group: WorkingGroup,
+) 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 pallet_balances::Trait>::Balance: 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_u128;
+
+        let stake_policy = Some(working_group::StakePolicy {
+            stake_amount,
+            leaving_unstaking_period: 45000, // more than min value
+        });
 
-        fn run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds<
-            T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
-            I: frame_support::traits::Instance,
-        >(
-            working_group: WorkingGroup,
-        ) where
-            <T as frame_system::Trait>::AccountId: From<[u8; 32]>,
-            <T as membership::Trait>::MemberId: From<u64>,
-            <T as membership::Trait>::ActorId: Into<u64>,
-        {
-            initial_test_ext().execute_with(|| {
-                let member_id: MemberId = 1;
-                let account_id: [u8; 32] = [0; 32];
-                let stake_amount = 100_u128;
-
-                let staking_policy = working_group::StakePolicy {
-                    stake_amount: 100,
-                    leaving_unstaking_period: 0,
-                };
-
-                let opening_id = add_opening(
-                    member_id,
-                    account_id,
-                    Some(staking_policy),
-                    1,
-                    working_group,
-                );
-
-                let apply_result = WorkingGroupInstance::<T, I>::apply_on_opening(
-                    RawOrigin::Signed(account_id.into()).into(),
-                    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;
-
-                let lead = WorkingGroupInstance::<T, I>::current_lead();
-                assert!(lead.is_none());
-
-                set_mint_capacity::<T, I>(member_id, account_id, 999999, 3, false, working_group);
-
-                fill_opening(
-                    member_id,
-                    account_id,
-                    opening_id,
-                    expected_application_id,
-                    4,
-                    working_group,
-                );
-
-                let stake_id = 1;
-                let old_balance = Balances::free_balance(&account_id.into());
-                let old_stake = <stake::Module<Runtime>>::stakes(stake_id);
-
-                assert_eq!(get_stake_balance(old_stake), stake_amount);
-
-                let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
-
-                terminate_role(
-                    member_id,
-                    account_id,
-                    leader_worker_id.into(),
-                    5,
-                    working_group,
-                );
-
-                assert!(WorkingGroupInstance::<T, I>::current_lead().is_none());
-
-                let new_balance = Balances::free_balance(&account_id.into());
-                let new_stake = <stake::Module<Runtime>>::stakes(stake_id);
-
-                assert_eq!(new_stake.staking_status, stake::StakingStatus::NotStaked);
-                assert_eq!(new_balance, old_balance);
-            });
+        let stake_parameters = Some(
+            StakeParameters::<T::AccountId, working_group::BalanceOf<T>> {
+                stake: stake_amount.into(),
+                staking_account_id: account_id.into(),
+            },
+        );
+
+        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(),
+            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,
+            },
+        );
+
+        assert_eq!(apply_result, Ok(()));
+
+        let expected_application_id = 0;
+
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_none());
+
+        set_mint_capacity::<T, I>(member_id, account_id, 999999, 2, false, working_group);
+
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            3,
+            working_group,
+        );
+
+        let old_balance = Balances::usable_balance(&account_id.into());
+        let old_stake = SM::current_stake(&account_id.into());
+
+        assert_eq!(old_stake, stake_amount.into());
+
+        let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
+
+        terminate_role(
+            member_id,
+            account_id,
+            leader_worker_id.into(),
+            None,
+            4,
+            working_group,
+        );
+
+        assert!(WorkingGroupInstance::<T, I>::current_lead().is_none());
+
+        let new_balance = Balances::usable_balance(&account_id.into());
+        let new_stake: working_group::BalanceOf<T> = SM::current_stake(&account_id.into()).into();
+
+        assert_eq!(new_stake, 0.into());
+        assert_eq!(new_balance, old_balance + stake_amount);
+    });
+}
+
+#[test]
+fn create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds() {
+    // This uses strum crate for enum iteration
+    for group in WorkingGroup::iter() {
+        match group {
+            WorkingGroup::Content => {
+                run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<
+                    Runtime,
+                    ContentDirectoryWorkingGroupInstance,
+                    ContentDirectoryWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Storage => {
+                run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<
+                    Runtime,
+                    StorageWorkingGroupInstance,
+                    StorageWorkingGroupStakingManager,
+                >(group);
+            }
+            WorkingGroup::Forum => {
+                run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds::<
+                    Runtime,
+                    ForumWorkingGroupInstance,
+                    ForumWorkingGroupStakingManager,
+                >(group);
+            }
         }
     }
 }
+
+fn run_create_terminate_group_leader_role_proposal_with_slashing_execution_succeeds<
+    T: working_group::Trait<I> + frame_system::Trait + minting::Trait,
+    I: frame_support::traits::Instance,
+    SM: staking_handler::StakingHandler<T>,
+>(
+    working_group: WorkingGroup,
+) where
+    <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 pallet_balances::Trait>::Balance: 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_u128;
+
+        let stake_policy = Some(working_group::StakePolicy {
+            stake_amount,
+            leaving_unstaking_period: 45000, // more than min value
+        });
+
+        let stake_parameters = Some(
+            StakeParameters::<T::AccountId, working_group::BalanceOf<T>> {
+                stake: stake_amount.into(),
+                staking_account_id: account_id.into(),
+            },
+        );
+
+        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(),
+            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,
+            },
+        );
+
+        assert_eq!(apply_result, Ok(()));
+
+        let expected_application_id = 0;
+
+        let lead = WorkingGroupInstance::<T, I>::current_lead();
+        assert!(lead.is_none());
+
+        set_mint_capacity::<T, I>(member_id, account_id, 999999, 2, false, working_group);
+
+        fill_opening(
+            member_id,
+            account_id,
+            opening_id,
+            expected_application_id,
+            3,
+            working_group,
+        );
+
+        let old_balance = Balances::usable_balance(&account_id.into());
+        let old_stake = SM::current_stake(&account_id.into());
+
+        assert_eq!(old_stake, stake_amount.into());
+
+        let leader_worker_id = WorkingGroupInstance::<T, I>::current_lead().unwrap();
+
+        terminate_role(
+            member_id,
+            account_id,
+            leader_worker_id.into(),
+            Some(Penalty {
+                slashing_amount: stake_amount.into(),
+                slashing_text: Vec::new(),
+            }),
+            4,
+            working_group,
+        );
+
+        assert!(WorkingGroupInstance::<T, I>::current_lead().is_none());
+
+        let new_balance = Balances::usable_balance(&account_id.into());
+        let new_stake: working_group::BalanceOf<T> = SM::current_stake(&account_id.into()).into();
+
+        assert_eq!(new_stake, 0.into());
+        assert_eq!(new_balance, old_balance);
+    });
+}