Browse Source

Merge olympia_dev

iorveth 3 years ago
parent
commit
477237e26c

+ 10 - 2
runtime-modules/bounty/src/lib.rs

@@ -85,7 +85,7 @@ use codec::{Decode, Encode};
 use serde::{Deserialize, Serialize};
 
 use frame_support::dispatch::{DispatchError, DispatchResult};
-use frame_support::traits::{Currency, ExistenceRequirement, Get};
+use frame_support::traits::{Currency, ExistenceRequirement, Get, LockIdentifier};
 use frame_support::weights::Weight;
 use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
 use frame_system::ensure_root;
@@ -128,7 +128,12 @@ pub trait Trait:
     type CouncilBudgetManager: CouncilBudgetManager<BalanceOf<Self>>;
 
     /// Provides stake logic implementation.
-    type StakingHandler: StakingHandler<Self::AccountId, BalanceOf<Self>, MemberId<Self>>;
+    type StakingHandler: StakingHandler<
+        Self::AccountId,
+        BalanceOf<Self>,
+        MemberId<Self>,
+        LockIdentifier,
+    >;
 
     /// Work entry Id type
     type EntryId: From<u32> + Parameter + Default + Copy + Ord + One;
@@ -705,6 +710,9 @@ decl_module! {
         /// Exports const - min work entrant stake for a bounty.
         const MinWorkEntrantStake: BalanceOf<T> = T::MinWorkEntrantStake::get();
 
+        /// Exports const - bounty lock id.
+        const BountyLockId: LockIdentifier = T::StakingHandler::lock_id();
+
         /// Creates a bounty. Metadata stored in the transaction log but discarded after that.
         /// <weight>
         ///

+ 29 - 3
runtime-modules/council/src/lib.rs

@@ -43,7 +43,7 @@
 
 // used dependencies
 use codec::{Decode, Encode};
-use frame_support::traits::{Currency, Get};
+use frame_support::traits::{Currency, Get, LockIdentifier};
 use frame_support::weights::Weight;
 use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, error::BadOrigin};
 
@@ -234,21 +234,35 @@ pub trait Trait:
     /// Minimum number of extra candidates needed for the valid election.
     /// Number of total candidates is equal to council size plus extra candidates.
     type MinNumberOfExtraCandidates: Get<u64>;
+
     /// Council member count
     type CouncilSize: Get<u64>;
+
     /// Minimum stake candidate has to lock
     type MinCandidateStake: Get<Balance<Self>>;
 
     /// Identifier for currency lock used for candidacy staking.
-    type CandidacyLock: StakingHandler<Self::AccountId, Balance<Self>, Self::MemberId>;
+    type CandidacyLock: StakingHandler<
+        Self::AccountId,
+        Balance<Self>,
+        Self::MemberId,
+        LockIdentifier,
+    >;
+
     /// Identifier for currency lock used for candidacy staking.
-    type CouncilorLock: StakingHandler<Self::AccountId, Balance<Self>, Self::MemberId>;
+    type CouncilorLock: StakingHandler<
+        Self::AccountId,
+        Balance<Self>,
+        Self::MemberId,
+        LockIdentifier,
+    >;
 
     /// Validates staking account ownership for a member.
     type StakingAccountValidator: common::StakingAccountValidator<Self>;
 
     /// Duration of annoncing period
     type AnnouncingPeriodDuration: Get<Self::BlockNumber>;
+
     /// Duration of idle period
     type IdlePeriodDuration: Get<Self::BlockNumber>;
 
@@ -479,19 +493,31 @@ decl_module! {
         /// Minimum number of extra candidates needed for the valid election.
         /// Number of total candidates is equal to council size plus extra candidates.
         const MinNumberOfExtraCandidates: u64 = T::MinNumberOfExtraCandidates::get();
+
         /// Council member count
         const CouncilSize: u64 = T::CouncilSize::get();
+
         /// Minimum stake candidate has to lock
         const MinCandidateStake: Balance<T> = T::MinCandidateStake::get();
+
         /// Duration of annoncing period
         const AnnouncingPeriodDuration: T::BlockNumber = T::AnnouncingPeriodDuration::get();
+
         /// Duration of idle period
         const IdlePeriodDuration: T::BlockNumber = T::IdlePeriodDuration::get();
+
         /// Interval for automatic reward payments.
         const ElectedMemberRewardPeriod: T::BlockNumber = T::ElectedMemberRewardPeriod::get();
+
         /// Interval between automatic budget refills.
         const BudgetRefillPeriod: T::BlockNumber = T::BudgetRefillPeriod::get();
 
+        /// Exports const - candidacy lock id.
+        const CandidacyLockId: LockIdentifier = T::CandidacyLock::lock_id();
+
+        /// Exports const - councilor lock id.
+        const CouncilorLockId: LockIdentifier = T::CouncilorLock::lock_id();
+
         /////////////////// Lifetime ///////////////////////////////////////////
 
         // No origin so this is a priviledged call

+ 55 - 69
runtime-modules/forum/src/benchmarking.rs

@@ -53,7 +53,7 @@ const MAX_POSTS: u32 = 500;
 const MAX_THREADS: u32 = 500;
 
 fn get_byte(num: u32, byte_number: u8) -> u8 {
-    ((num & (0xff << (8 * byte_number))) >> 8 * byte_number) as u8
+    ((num & (0xff << (8 * byte_number))) >> (8 * byte_number)) as u8
 }
 
 fn assert_last_event<T: Trait>(generic_event: <T as Trait>::Event) {
@@ -90,12 +90,12 @@ where
     let member_id = T::MemberId::from(id.try_into().unwrap());
     Membership::<T>::add_staking_account_candidate(
         RawOrigin::Signed(account_id.clone()).into(),
-        member_id.clone(),
+        member_id,
     )
     .unwrap();
     Membership::<T>::confirm_staking_account(
         RawOrigin::Signed(account_id.clone()).into(),
-        member_id.clone(),
+        member_id,
         account_id.clone(),
     )
     .unwrap();
@@ -178,12 +178,8 @@ where
 
     let mut successful_application_ids = BTreeSet::<ApplicationId>::new();
     successful_application_ids.insert(application_id);
-    ForumGroup::<T>::fill_opening(
-        leader_origin.clone().into(),
-        opening_id,
-        successful_application_ids,
-    )
-    .unwrap();
+    ForumGroup::<T>::fill_opening(leader_origin.into(), opening_id, successful_application_ids)
+        .unwrap();
 
     let actor_id =
         <T as common::membership::MembershipTypes>::ActorId::from(id.try_into().unwrap());
@@ -294,7 +290,7 @@ fn create_new_thread<T: Trait>(
     category_id: T::CategoryId,
     title: Vec<u8>,
     text: Vec<u8>,
-    poll: Option<Poll<T::Moment, T::Hash>>,
+    poll: Option<PollInput<T::Moment>>,
 ) -> T::ThreadId {
     Module::<T>::create_thread(
         RawOrigin::Signed(account_id).into(),
@@ -327,30 +323,26 @@ fn add_thread_post<T: Trait>(
     Module::<T>::next_post_id() - T::PostId::one()
 }
 
-pub fn good_poll_alternative_text() -> Vec<u8> {
+fn good_poll_alternative_text() -> Vec<u8> {
     b"poll alternative".to_vec()
 }
 
-pub fn good_poll_description() -> Vec<u8> {
+fn good_poll_description() -> Vec<u8> {
     b"poll description".to_vec()
 }
 
-pub fn generate_poll<T: Trait>(
+/// Generates poll input
+pub fn generate_poll_input<T: Trait>(
     expiration_diff: T::Moment,
     alternatives_number: u32,
-) -> Poll<T::Moment, T::Hash> {
-    Poll {
-        description_hash: T::calculate_hash(good_poll_description().as_slice()),
+) -> PollInput<T::Moment> {
+    PollInput {
+        description: good_poll_description(),
         end_time: pallet_timestamp::Module::<T>::now() + expiration_diff,
         poll_alternatives: {
             let mut alternatives = vec![];
             for _ in 0..alternatives_number {
-                alternatives.push(PollAlternative {
-                    alternative_text_hash: T::calculate_hash(
-                        good_poll_alternative_text().as_slice(),
-                    ),
-                    vote_count: 0,
-                });
+                alternatives.push(good_poll_alternative_text());
             }
             alternatives
         },
@@ -382,19 +374,16 @@ pub fn generate_categories_tree<T: Trait>(
             text.clone(),
         );
 
-        match moderator_id {
-            Some(moderator_id) => {
-                // Set up category membership of moderator.
-                Module::<T>::update_category_membership_of_moderator(
-                    RawOrigin::Signed(caller_id.clone()).into(),
-                    moderator_id,
-                    category_id,
-                    true,
-                )
-                .unwrap();
-            }
-            _ => (),
-        };
+        if let Some(moderator_id) = moderator_id {
+            // Set up category membership of moderator.
+            Module::<T>::update_category_membership_of_moderator(
+                RawOrigin::Signed(caller_id.clone()).into(),
+                moderator_id,
+                category_id,
+                true,
+            )
+            .unwrap();
+        }
     }
 
     assert_eq!(
@@ -434,11 +423,7 @@ benchmarks! {
         // Generate categories tree
         let (_, parent_category_id) = generate_categories_tree::<T>(caller_id.clone(), i, None);
 
-        let parent_category = if let Some(parent_category_id) = parent_category_id {
-            Some(Module::<T>::category_by_id(parent_category_id))
-        } else {
-            None
-        };
+        let parent_category = parent_category_id.map(Module::<T>::category_by_id);
 
         let category_counter = <Module<T>>::category_counter();
 
@@ -941,18 +926,18 @@ benchmarks! {
 
         let expiration_diff = 1010u32.into();
 
-        let poll = if z == 1 {
+        let poll_input = if z == 1 {
             None
         } else {
             // min number of poll alternatives is set to 2
-            Some(generate_poll::<T>(expiration_diff, z))
+            Some(generate_poll_input::<T>(expiration_diff, z))
         };
 
         let next_thread_id = Module::<T>::next_thread_id();
         let next_post_id = Module::<T>::next_post_id();
         let initial_balance = Balances::<T>::usable_balance(&caller_id);
 
-    }: _ (RawOrigin::Signed(caller_id.clone()), forum_user_id.saturated_into(), category_id, title.clone(), text.clone(), poll.clone())
+    }: _ (RawOrigin::Signed(caller_id.clone()), forum_user_id.saturated_into(), category_id, title.clone(), text.clone(), poll_input.clone())
     verify {
 
         assert_eq!(
@@ -978,7 +963,7 @@ benchmarks! {
             category_id,
             title_hash: T::calculate_hash(&title),
             author_id: forum_user_id.saturated_into(),
-            poll: poll.clone(),
+            poll: poll_input.clone().map(<Module<T>>::from_poll_input),
             cleanup_pay_off: T::ThreadDeposit::get(),
             number_of_posts: 1,
         };
@@ -996,12 +981,13 @@ benchmarks! {
 
         assert_last_event::<T>(
             RawEvent::ThreadCreated(
+                category_id,
                 next_thread_id,
+                next_post_id,
                 forum_user_id.saturated_into(),
-                category_id,
                 title,
                 text,
-                poll,
+                poll_input,
             ).into()
         );
     }
@@ -1057,13 +1043,13 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
         let thread_id = create_new_thread::<T>(
             caller_id.clone(), forum_user_id.saturated_into(), category_id,
-            text.clone(), text.clone(), poll
+            text.clone(), text, poll
         );
 
         // Add poll voting.
@@ -1152,7 +1138,7 @@ benchmarks! {
         };
 
         // Create thread
-        let thread_id = create_new_thread::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, text.clone(), text.clone(), None);
+        let thread_id = create_new_thread::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, text.clone(), text, None);
         let thread = Module::<T>::thread_by_id(category_id, thread_id);
 
         let mut category = Module::<T>::category_by_id(category_id);
@@ -1214,7 +1200,7 @@ benchmarks! {
         };
 
         // Create thread
-        let thread_id = create_new_thread::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, text.clone(), text.clone(), None);
+        let thread_id = create_new_thread::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, text.clone(), text, None);
         let thread = Module::<T>::thread_by_id(category_id, thread_id);
 
         let moderator_id = ModeratorId::<T>::from(forum_user_id.try_into().unwrap());
@@ -1269,12 +1255,12 @@ benchmarks! {
 
         // Create thread
         let expiration_diff = 10u32.into();
-        let poll = Some(generate_poll::<T>(expiration_diff, j));
+        let poll_input = Some(generate_poll_input::<T>(expiration_diff, j));
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
         let thread_id = create_new_thread::<T>(
             caller_id.clone(), forum_user_id.saturated_into(), category_id,
-            text.clone(), text.clone(), poll
+            text.clone(), text, poll_input
         );
 
         let mut thread = Module::<T>::thread_by_id(category_id, thread_id);
@@ -1327,13 +1313,13 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
 
         let text = vec![1u8].repeat(MAX_BYTES as usize);
         let thread_id = create_new_thread::<T>(
             caller_id.clone(), (lead_id as u64).saturated_into(), category_id,
-            text.clone(), text.clone(), poll
+            text.clone(), text, poll
         );
 
         let mut category = Module::<T>::category_by_id(category_id);
@@ -1383,13 +1369,13 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
 
         let text = vec![1u8].repeat(MAX_BYTES as usize);
         let thread_id = create_new_thread::<T>(
             caller_id.clone(), (lead_id as u64).saturated_into(), category_id,
-            text.clone(), text.clone(), poll
+            text.clone(), text, poll
         );
 
         let moderator_id = ModeratorId::<T>::from(lead_id.try_into().unwrap());
@@ -1466,7 +1452,7 @@ benchmarks! {
         let new_post = Post {
             text_hash: T::calculate_hash(&text),
             author_id: forum_user_id.saturated_into(),
-            thread_id: thread_id,
+            thread_id,
             last_edited: System::<T>::block_number(),
             cleanup_pay_off: T::PostDeposit::get(),
         };
@@ -1501,7 +1487,7 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1510,7 +1496,7 @@ benchmarks! {
             text.clone(), text.clone(), poll
         );
 
-        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text.clone());
+        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text);
 
         let react = T::PostReactionId::one();
 
@@ -1542,7 +1528,7 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1551,7 +1537,7 @@ benchmarks! {
             text.clone(), text.clone(), poll
         );
 
-        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text.clone());
+        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text);
 
         let mut post = Module::<T>::post_by_id(thread_id, post_id);
 
@@ -1596,7 +1582,7 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1604,7 +1590,7 @@ benchmarks! {
             caller_id.clone(), forum_user_id.saturated_into(), category_id,
             text.clone(), text.clone(), poll
         );
-        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text.clone());
+        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text);
 
         let mut thread = Module::<T>::thread_by_id(category_id, thread_id);
 
@@ -1643,7 +1629,7 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1651,7 +1637,7 @@ benchmarks! {
             caller_id.clone(), forum_user_id.saturated_into(), category_id,
             text.clone(), text.clone(), poll
         );
-        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text.clone());
+        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text);
 
         let mut thread = Module::<T>::thread_by_id(category_id, thread_id);
 
@@ -1699,7 +1685,7 @@ benchmarks! {
         // Create thread
         let expiration_diff = 10u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1726,7 +1712,7 @@ benchmarks! {
             );
         }
 
-        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text.clone());
+        let post_id = add_thread_post::<T>(caller_id.clone(), forum_user_id.saturated_into(), category_id, thread_id, text);
 
         let mut thread = Module::<T>::thread_by_id(category_id, thread_id);
 
@@ -1777,7 +1763,7 @@ benchmarks! {
         // Create threads
         let expiration_diff = 1010u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 
@@ -1820,7 +1806,7 @@ benchmarks! {
         // Create threads
         let expiration_diff = 1010u32.into();
         let poll = Some(
-            generate_poll::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
+            generate_poll_input::<T>(expiration_diff, (<<<T as Trait>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>::get() - 1) as u32)
         );
         let text = vec![1u8].repeat(MAX_BYTES as usize);
 

+ 58 - 16
runtime-modules/forum/src/lib.rs

@@ -187,7 +187,7 @@ pub trait Trait:
 }
 
 /// Upper bounds for storage maps and double maps. Needed to prevent potential block exhaustion during deletion, etc.
-/// MaxSubcategories, MaxThreadsInCategory, and MaxPostsInThread should be reasonably small because when the category is deleted
+/// MaxSubcategories, and MaxCategories should be reasonably small because when the category is deleted
 /// all of it's subcategories with their threads and posts will be iterated over and deleted.
 pub trait StorageLimits {
     /// Maximum direct subcategories in a category
@@ -203,7 +203,7 @@ pub trait StorageLimits {
     type MaxPollAlternativesNumber: Get<u64>;
 }
 
-/// Represents all poll alternatives and vote count for each one
+/// Represents all poll alternative text hashes and vote count for each one
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
 pub struct PollAlternative<Hash> {
@@ -214,6 +214,20 @@ pub struct PollAlternative<Hash> {
     pub vote_count: u32,
 }
 
+/// Represents a poll input
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub struct PollInput<Timestamp> {
+    /// description
+    pub description: Vec<u8>,
+
+    /// timestamp of poll end
+    pub end_time: Timestamp,
+
+    /// Alternative polls description
+    pub poll_alternatives: Vec<Vec<u8>>,
+}
+
 /// Represents a poll
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
@@ -221,7 +235,7 @@ pub struct Poll<Timestamp, Hash> {
     /// hash of description
     pub description_hash: Hash,
 
-    /// pallet_timestamp of poll end
+    /// timestamp of poll end
     pub end_time: Timestamp,
 
     /// Alternative description and count
@@ -494,8 +508,8 @@ decl_event!(
         ForumUserId = ForumUserId<T>,
         <T as Trait>::PostReactionId,
         PrivilegedActor = PrivilegedActor<T>,
-        Poll = Poll<<T as pallet_timestamp::Trait>::Moment, <T as frame_system::Trait>::Hash>,
         ExtendedPostId = ExtendedPostId<T>,
+        PollInput = PollInput<<T as pallet_timestamp::Trait>::Moment>,
     {
         /// A category was introduced
         CategoryCreated(CategoryId, Option<CategoryId>, Vec<u8>, Vec<u8>),
@@ -516,7 +530,8 @@ decl_event!(
         CategoryDeleted(CategoryId, PrivilegedActor),
 
         /// A thread with given id was created.
-        ThreadCreated(ThreadId, ForumUserId, CategoryId, Vec<u8>, Vec<u8>, Option<Poll>),
+        /// A third argument reflects the initial post id of the thread.
+        ThreadCreated(CategoryId, ThreadId, PostId, ForumUserId, Vec<u8>, Vec<u8>, Option<PollInput>),
 
         /// A thread with given id was moderated.
         ThreadModerated(ThreadId, Vec<u8>, PrivilegedActor, CategoryId),
@@ -569,6 +584,14 @@ decl_module! {
 
         fn deposit_event() = default;
 
+        /// Exports const
+
+        /// Deposit needed to create a post
+        const PostDeposit: BalanceOf<T> = T::PostDeposit::get();
+
+        /// Deposit needed to create a thread
+        const ThreadDeposit: BalanceOf<T> = T::ThreadDeposit::get();
+
         /// Enable a moderator can moderate a category and its sub categories.
         ///
         /// <weight>
@@ -889,7 +912,7 @@ decl_module! {
             category_id: T::CategoryId,
             title: Vec<u8>,
             text: Vec<u8>,
-            poll: Option<Poll<T::Moment, T::Hash>>,
+            poll_input: Option<PollInput<T::Moment>>,
         ) -> DispatchResult {
             // Ensure data migration is done
             Self::ensure_data_migration_done()?;
@@ -899,12 +922,12 @@ decl_module! {
             Self::ensure_can_create_thread(&account_id, &forum_user_id, &category_id)?;
 
             // Ensure poll is valid
-            if let Some(ref data) = poll {
+            if let Some(ref data) = poll_input {
                 // Check all poll alternatives
                 Self::ensure_poll_alternatives_length_is_valid(&data.poll_alternatives)?;
 
                 // Check poll self information
-                Self::ensure_poll_is_valid(data)?;
+                Self::ensure_poll_input_is_valid(data)?;
             }
 
             //
@@ -922,12 +945,15 @@ decl_module! {
                 &account_id
             )?;
 
+            // Hash poll description and poll alternatives description
+            let poll = poll_input.clone().map(Self::from_poll_input);
+
             // Build a new thread
             let new_thread = Thread {
                 category_id,
                 title_hash: T::calculate_hash(&title),
                 author_id: forum_user_id,
-                poll: poll.clone(),
+                poll,
                 cleanup_pay_off: T::ThreadDeposit::get(),
                 number_of_posts: 0,
             };
@@ -938,7 +964,7 @@ decl_module! {
             });
 
             // Add inital post to thread
-            let _ = Self::add_new_post(
+            let initial_post_id = Self::add_new_post(
                 new_thread_id,
                 category_id,
                 &text,
@@ -955,12 +981,13 @@ decl_module! {
             // Generate event
             Self::deposit_event(
                 RawEvent::ThreadCreated(
+                    category_id,
                     new_thread_id,
+                    initial_post_id,
                     forum_user_id,
-                    category_id,
                     title,
                     text,
-                    poll,
+                    poll_input,
                 )
             );
 
@@ -1548,6 +1575,22 @@ decl_module! {
 }
 
 impl<T: Trait> Module<T> {
+    /// Hash poll description and poll alternatives descriptions, coverting `PollInput` into `Poll`
+    fn from_poll_input(poll_input: PollInput<T::Moment>) -> Poll<T::Moment, T::Hash> {
+        Poll {
+            description_hash: T::calculate_hash(poll_input.description.as_slice()),
+            poll_alternatives: poll_input
+                .poll_alternatives
+                .into_iter()
+                .map(|poll_alternative| PollAlternative {
+                    alternative_text_hash: T::calculate_hash(poll_alternative.as_slice()),
+                    vote_count: 0,
+                })
+                .collect(),
+            end_time: poll_input.end_time,
+        }
+    }
+
     fn slash_thread_account(thread_id: T::ThreadId, amount: BalanceOf<T>) {
         let thread_account_id = T::ModuleId::get().into_sub_account(thread_id);
         let _ = Balances::<T>::slash(&thread_account_id, amount);
@@ -1581,6 +1624,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
+    /// Add new posts & increase thread counter
     pub fn add_new_post(
         thread_id: T::ThreadId,
         category_id: T::CategoryId,
@@ -1638,7 +1682,7 @@ impl<T: Trait> Module<T> {
     }
 
     // Ensure poll is valid
-    fn ensure_poll_is_valid(poll: &Poll<T::Moment, T::Hash>) -> Result<(), Error<T>> {
+    fn ensure_poll_input_is_valid(poll: &PollInput<T::Moment>) -> Result<(), Error<T>> {
         // Poll end time must larger than now
         if poll.end_time < <pallet_timestamp::Module<T>>::now() {
             return Err(Error::<T>::PollTimeSetting);
@@ -1648,9 +1692,7 @@ impl<T: Trait> Module<T> {
     }
 
     // Ensure poll alternative size is valid
-    fn ensure_poll_alternatives_length_is_valid(
-        alternatives: &[PollAlternative<T::Hash>],
-    ) -> Result<(), Error<T>> {
+    fn ensure_poll_alternatives_length_is_valid<K>(alternatives: &[K]) -> Result<(), Error<T>> {
         Self::ensure_map_limits::<<<T>::MapLimits as StorageLimits>::MaxPollAlternativesNumber>(
             alternatives.len() as u64,
         )?;

+ 52 - 21
runtime-modules/forum/src/mock.rs

@@ -555,83 +555,93 @@ pub const FORUM_MODERATOR_2_ORIGIN: OriginType = OriginType::Signed(FORUM_MODERA
 const EXTRA_MODERATOR_COUNT: usize = 5;
 pub const EXTRA_MODERATORS: [u128; EXTRA_MODERATOR_COUNT] = [125, 126, 127, 128, 129];
 
+/// Get a good category title
 pub fn good_category_title() -> Vec<u8> {
     b"Great new category".to_vec()
 }
 
+/// Get a new good category title
 pub fn good_category_title_new() -> Vec<u8> {
     b"Great new category title".to_vec()
 }
 
+/// Get a good category description
 pub fn good_category_description() -> Vec<u8> {
     b"This is a great new category for the forum".to_vec()
 }
 
+/// Get a good new category description
 pub fn good_category_description_new() -> Vec<u8> {
     b"This is a great new category description for the forum".to_vec()
 }
 
+/// Get a new good thread title
 pub fn good_thread_title() -> Vec<u8> {
     b"Great new thread".to_vec()
 }
 
+/// Get a new good thread text
 pub fn good_thread_text() -> Vec<u8> {
     b"The first post in this thread".to_vec()
 }
 
+/// Get a new title ofr the  good  thread
 pub fn good_thread_new_title() -> Vec<u8> {
     b"Brand new thread title".to_vec()
 }
 
+/// Get a good post text
 pub fn good_post_text() -> Vec<u8> {
     b"A response in the thread".to_vec()
 }
 
+/// Get a good new post text
 pub fn good_post_new_text() -> Vec<u8> {
     b"Changed post's text".to_vec()
 }
 
+/// Get a good moderation rationale
 pub fn good_moderation_rationale() -> Vec<u8> {
     b"Moderation rationale".to_vec()
 }
 
+/// Get a good poll description
 pub fn good_poll_description() -> Vec<u8> {
     b"poll description".to_vec()
 }
 
+/// Get a good poll alternative text
 pub fn good_poll_alternative_text() -> Vec<u8> {
     b"poll alternative".to_vec()
 }
 
-pub fn generate_poll(
+/// Generate a valid poll input
+pub fn generate_poll_input(
     expiration_diff: u64,
-) -> Poll<<Runtime as pallet_timestamp::Trait>::Moment, <Runtime as frame_system::Trait>::Hash> {
-    Poll {
-        description_hash: Runtime::calculate_hash(good_poll_description().as_slice()),
+) -> PollInput<<Runtime as pallet_timestamp::Trait>::Moment> {
+    PollInput {
+        description: good_poll_description(),
         end_time: Timestamp::now() + expiration_diff,
         poll_alternatives: {
             let mut alternatives = vec![];
             for _ in 0..5 {
-                alternatives.push(PollAlternative {
-                    alternative_text_hash: Runtime::calculate_hash(
-                        good_poll_alternative_text().as_slice(),
-                    ),
-                    vote_count: 0,
-                });
+                alternatives.push(good_poll_alternative_text());
             }
             alternatives
         },
     }
 }
 
-pub fn generate_poll_timestamp_cases(
+/// Generate poll input for different timestamp cases
+pub fn generate_poll_input_timestamp_cases(
     index: usize,
     expiration_diff: u64,
-) -> Poll<<Runtime as pallet_timestamp::Trait>::Moment, <Runtime as frame_system::Trait>::Hash> {
-    let test_cases = vec![generate_poll(expiration_diff), generate_poll(1)];
+) -> PollInput<<Runtime as pallet_timestamp::Trait>::Moment> {
+    let test_cases = vec![generate_poll_input(expiration_diff), generate_poll_input(1)];
     test_cases[index].clone()
 }
 
+/// Create category mock
 pub fn create_category_mock(
     origin: OriginType,
     parent: Option<<Runtime as Trait>::CategoryId>,
@@ -664,6 +674,7 @@ pub fn create_category_mock(
     category_id
 }
 
+/// Create thread mock
 pub fn create_thread_mock(
     origin: OriginType,
     account_id: <Runtime as frame_system::Trait>::AccountId,
@@ -671,9 +682,7 @@ pub fn create_thread_mock(
     category_id: <Runtime as Trait>::CategoryId,
     title: Vec<u8>,
     text: Vec<u8>,
-    poll_data: Option<
-        Poll<<Runtime as pallet_timestamp::Trait>::Moment, <Runtime as frame_system::Trait>::Hash>,
-    >,
+    poll_input_data: Option<PollInput<<Runtime as pallet_timestamp::Trait>::Moment>>,
     result: DispatchResult,
 ) -> <Runtime as Trait>::ThreadId {
     let thread_id = TestForumModule::next_thread_id();
@@ -686,7 +695,7 @@ pub fn create_thread_mock(
             category_id,
             title.clone(),
             text.clone(),
-            poll_data.clone(),
+            poll_input_data.clone(),
         ),
         result
     );
@@ -695,12 +704,13 @@ pub fn create_thread_mock(
         assert_eq!(
             System::events().last().unwrap().event,
             TestEvent::forum_mod(RawEvent::ThreadCreated(
+                category_id,
                 thread_id,
+                TestForumModule::next_thread_id() - 1,
                 forum_user_id,
-                category_id,
                 title.clone(),
                 text.clone(),
-                poll_data.clone()
+                poll_input_data.clone()
             ))
         );
 
@@ -719,6 +729,7 @@ pub fn create_thread_mock(
     thread_id
 }
 
+/// Create edit thread title mock
 pub fn edit_thread_title_mock(
     origin: OriginType,
     forum_user_id: ForumUserId<Runtime>,
@@ -755,6 +766,7 @@ pub fn edit_thread_title_mock(
     thread_id
 }
 
+/// Create delete thread mock
 pub fn delete_thread_mock(
     origin: OriginType,
     account_id: <Runtime as frame_system::Trait>::AccountId,
@@ -809,6 +821,7 @@ pub fn delete_thread_mock(
     }
 }
 
+/// Create delete post mock
 pub fn delete_post_mock(
     origin: OriginType,
     account_id: <Runtime as frame_system::Trait>::AccountId,
@@ -869,6 +882,7 @@ pub fn delete_post_mock(
     }
 }
 
+/// Create move thread mock
 pub fn move_thread_mock(
     origin: OriginType,
     moderator_id: ModeratorId<Runtime>,
@@ -904,6 +918,7 @@ pub fn move_thread_mock(
     }
 }
 
+/// Made a create post mock
 pub fn create_post_mock(
     origin: OriginType,
     account_id: <Runtime as frame_system::Trait>::AccountId,
@@ -966,6 +981,7 @@ pub fn create_post_mock(
     post_id
 }
 
+/// Create edit post text mock
 pub fn edit_post_text_mock(
     origin: OriginType,
     forum_user_id: ForumUserId<Runtime>,
@@ -1004,10 +1020,12 @@ pub fn edit_post_text_mock(
     post_id
 }
 
+/// Change current timestamp
 pub fn change_current_time(diff: u64) -> () {
     Timestamp::set_timestamp(Timestamp::now() + diff);
 }
 
+/// Create update category membership of moderator mock
 pub fn update_category_membership_of_moderator_mock(
     origin: OriginType,
     moderator_id: ModeratorId<Runtime>,
@@ -1042,6 +1060,7 @@ pub fn update_category_membership_of_moderator_mock(
     category_id
 }
 
+/// Create vote on poll mock
 pub fn vote_on_poll_mock(
     origin: OriginType,
     forum_user_id: ForumUserId<Runtime>,
@@ -1087,6 +1106,7 @@ pub fn vote_on_poll_mock(
     thread_id
 }
 
+/// Create update category archival status mock
 pub fn update_category_archival_status_mock(
     origin: OriginType,
     actor: PrivilegedActor<Runtime>,
@@ -1115,6 +1135,7 @@ pub fn update_category_archival_status_mock(
     }
 }
 
+/// Create update category title mock
 pub fn update_category_title_mock(
     origin: OriginType,
     actor: PrivilegedActor<Runtime>,
@@ -1144,6 +1165,7 @@ pub fn update_category_title_mock(
     }
 }
 
+/// Create update category description mock
 pub fn update_category_description_mock(
     origin: OriginType,
     actor: PrivilegedActor<Runtime>,
@@ -1173,6 +1195,7 @@ pub fn update_category_description_mock(
     }
 }
 
+/// Create delete category mock
 pub fn delete_category_mock(
     origin: OriginType,
     moderator_id: PrivilegedActor<Runtime>,
@@ -1192,6 +1215,7 @@ pub fn delete_category_mock(
     }
 }
 
+/// Create moderate thread mock
 pub fn moderate_thread_mock(
     origin: OriginType,
     moderator_id: ModeratorId<Runtime>,
@@ -1233,6 +1257,7 @@ pub fn moderate_thread_mock(
     thread_id
 }
 
+/// Create moderate post mock
 pub fn moderate_post_mock(
     origin: OriginType,
     moderator_id: ModeratorId<Runtime>,
@@ -1281,6 +1306,7 @@ pub fn moderate_post_mock(
     post_id
 }
 
+/// Create set stickied threads mock
 pub fn set_stickied_threads_mock(
     origin: OriginType,
     moderator_id: ModeratorId<Runtime>,
@@ -1314,6 +1340,7 @@ pub fn set_stickied_threads_mock(
     category_id
 }
 
+/// Create react post mock
 pub fn react_post_mock(
     origin: OriginType,
     forum_user_id: ForumUserId<Runtime>,
@@ -1348,14 +1375,17 @@ pub fn react_post_mock(
     };
 }
 
+/// Create default genesis config
 pub fn default_genesis_config() -> GenesisConfig<Runtime> {
     create_genesis_config(true)
 }
 
+/// Create config without data migration
 pub fn migration_not_done_config() -> GenesisConfig<Runtime> {
     create_genesis_config(false)
 }
 
+/// Create genesis config
 pub fn create_genesis_config(data_migration_done: bool) -> GenesisConfig<Runtime> {
     GenesisConfig::<Runtime> {
         category_by_id: vec![],
@@ -1386,6 +1416,7 @@ pub fn build_test_externalities(config: GenesisConfig<Runtime>) -> sp_io::TestEx
     t.into()
 }
 
+/// Generate enviroment with test externalities
 pub fn with_test_externalities<R, F: FnOnce() -> R>(f: F) -> R {
     let default_genesis_config = default_genesis_config();
     /*
@@ -1413,11 +1444,11 @@ pub fn run_to_block(n: u64) {
     }
 }
 
-// pub type System = system::Module<Runtime>;
+/// System module on a test runtime
 pub type System = frame_system::Module<Runtime>;
 
+/// Timestamp module on a test runtime
 pub type Timestamp = pallet_timestamp::Module<Runtime>;
-// pub type System = frame_system::Module<Runtime>;
 
 /// Export forum module on a test runtime
 pub type TestForumModule = Module<Runtime>;

+ 5 - 5
runtime-modules/forum/src/tests.rs

@@ -963,7 +963,7 @@ fn create_thread_poll_timestamp() {
             balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
 
             change_current_time(1);
-            let poll = generate_poll_timestamp_cases(index, expiration_diff);
+            let poll = generate_poll_input_timestamp_cases(index, expiration_diff);
             change_current_time(index as u64 * expiration_diff + 1);
 
             let category_id = create_category_mock(
@@ -1088,7 +1088,7 @@ fn delete_thread() {
             category_id,
             good_thread_title(),
             good_thread_text(),
-            Some(generate_poll(10)),
+            Some(generate_poll_input(10)),
             Ok(()),
         );
 
@@ -1434,7 +1434,7 @@ fn vote_on_poll_origin() {
                 category_id,
                 good_thread_title(),
                 good_thread_text(),
-                Some(generate_poll(expiration_diff)),
+                Some(generate_poll_input(expiration_diff)),
                 Ok(()),
             );
 
@@ -1473,7 +1473,7 @@ fn vote_on_poll_fails_on_double_voting() {
             category_id,
             good_thread_title(),
             good_thread_text(),
-            Some(generate_poll(expiration_diff)),
+            Some(generate_poll_input(expiration_diff)),
             Ok(()),
         );
 
@@ -1558,7 +1558,7 @@ fn vote_on_poll_expired() {
             category_id,
             good_thread_title(),
             good_thread_text(),
-            Some(generate_poll(expiration_diff)),
+            Some(generate_poll_input(expiration_diff)),
             Ok(()),
         );
         change_current_time(expiration_diff + 1);

+ 12 - 1
runtime-modules/membership/src/lib.rs

@@ -51,7 +51,7 @@ mod tests;
 
 use codec::{Decode, Encode};
 use frame_support::dispatch::DispatchError;
-use frame_support::traits::{Currency, Get, WithdrawReason, WithdrawReasons};
+use frame_support::traits::{Currency, Get, LockIdentifier, WithdrawReason, WithdrawReasons};
 pub use frame_support::weights::Weight;
 use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure};
 use frame_system::{ensure_root, ensure_signed};
@@ -123,6 +123,7 @@ pub trait Trait:
         Self::AccountId,
         BalanceOf<Self>,
         Self::MemberId,
+        LockIdentifier,
     >;
 
     /// Staking handler used for staking candidate.
@@ -130,6 +131,7 @@ pub trait Trait:
         Self::AccountId,
         BalanceOf<Self>,
         Self::MemberId,
+        LockIdentifier,
     >;
 
     /// Weight information for extrinsics in this pallet.
@@ -389,6 +391,15 @@ decl_module! {
         const DefaultInitialInvitationBalance: BalanceOf<T> =
             T::DefaultInitialInvitationBalance::get();
 
+        /// Exports const - Stake needed to candidate as staking account.
+        const CandidateStake: BalanceOf<T> = T::CandidateStake::get();
+
+        /// Exports const - invited member lock id.
+        const InvitedMemberLockId: LockIdentifier = T::InvitedMemberStakingHandler::lock_id();
+
+        /// Exports const - staking candidate lock id.
+        const StakingCandidateLockId: LockIdentifier = T::StakingCandidateStakingHandler::lock_id();
+
         /// Non-members can buy membership.
         ///
         /// <weight>

+ 3 - 1
runtime-modules/proposals/codex/src/benchmarking.rs

@@ -159,7 +159,9 @@ fn create_proposal_verify<T: Trait>(
         "Active proposal count not updated"
     );
 
-    assert_last_event::<T>(RawEvent::ProposalCreated(proposal_parameters, proposal_details).into());
+    assert_last_event::<T>(
+        RawEvent::ProposalCreated(proposal_id, proposal_parameters, proposal_details).into(),
+    );
 
     assert!(
         ThreadIdByProposalId::<T>::contains_key(proposal_id),

+ 4 - 2
runtime-modules/proposals/codex/src/lib.rs

@@ -259,12 +259,14 @@ decl_event! {
     pub enum Event<T> where
         GeneralProposalParameters = GeneralProposalParameters<T>,
         ProposalDetailsOf = ProposalDetailsOf<T>,
+        <T as proposals_engine::Trait>::ProposalId,
     {
         /// A proposal was created
         /// Params:
+        /// - Id of a newly created proposal after it was saved in storage.
         /// - General proposal parameter. Parameters shared by all proposals
         /// - Proposal Details. Parameter of proposal with a variant for each kind of proposal
-        ProposalCreated(GeneralProposalParameters, ProposalDetailsOf),
+        ProposalCreated(ProposalId, GeneralProposalParameters, ProposalDetailsOf),
     }
 }
 
@@ -513,7 +515,7 @@ decl_module! {
 
             <ThreadIdByProposalId<T>>::insert(proposal_id, discussion_thread_id);
 
-            Self::deposit_event(RawEvent::ProposalCreated(general_proposal_parameters, proposal_details));
+            Self::deposit_event(RawEvent::ProposalCreated(proposal_id, general_proposal_parameters, proposal_details));
         }
     }
 }

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

@@ -123,6 +123,7 @@ where
         assert_eq!(proposal.parameters, self.proposal_parameters);
         assert_last_event(
             RawEvent::ProposalCreated(
+                proposal_id,
                 self.general_proposal_parameters.clone(),
                 self.proposal_details.clone(),
             )

+ 10 - 12
runtime-modules/proposals/engine/src/lib.rs

@@ -143,7 +143,7 @@ mod tests;
 use codec::Decode;
 use frame_support::dispatch::{DispatchError, DispatchResult, UnfilteredDispatchable};
 use frame_support::storage::IterableStorageMap;
-use frame_support::traits::Get;
+use frame_support::traits::{Get, LockIdentifier};
 use frame_support::weights::{GetDispatchInfo, Weight};
 use frame_support::{
     decl_error, decl_event, decl_module, decl_storage, ensure, Parameter, StorageDoubleMap,
@@ -204,7 +204,12 @@ pub trait Trait:
     type ProposalId: From<u32> + Parameter + Default + Copy;
 
     /// Provides stake logic implementation.
-    type StakingHandler: StakingHandler<Self::AccountId, BalanceOf<Self>, MemberId<Self>>;
+    type StakingHandler: StakingHandler<
+        Self::AccountId,
+        BalanceOf<Self>,
+        MemberId<Self>,
+        LockIdentifier,
+    >;
 
     /// The fee is applied when cancel the proposal. A fee would be slashed (burned).
     type CancellationFee: Get<BalanceOf<Self>>;
@@ -259,11 +264,6 @@ decl_event!(
         MemberId = MemberId<T>,
         <T as frame_system::Trait>::BlockNumber,
     {
-        /// Emits on proposal creation.
-        /// Params:
-        /// - Member id of a proposer.
-        /// - Id of a newly created proposal after it was saved in storage.
-        ProposalCreated(MemberId, ProposalId),
 
         /// Emits on proposal creation.
         /// Params:
@@ -415,6 +415,9 @@ decl_module! {
         /// Exports const -  max simultaneous active proposals number.
         const MaxActiveProposalLimit: u32 = T::MaxActiveProposalLimit::get();
 
+        /// Exports const - staking handler lock id.
+        const StakingHandlerLockId: LockIdentifier = T::StakingHandler::lock_id();
+
         /// Block Initialization. Perform voting period check, vote result tally, approved proposals
         /// grace period checks, and proposal execution.
         /// # <weight>
@@ -604,11 +607,6 @@ impl<T: Trait> Module<T> {
         ProposalCount::put(next_proposal_count_value);
         Self::increase_active_proposal_counter();
 
-        Self::deposit_event(RawEvent::ProposalCreated(
-            creation_params.proposer_id,
-            proposal_id,
-        ));
-
         Ok(proposal_id)
     }
 

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

@@ -406,7 +406,6 @@ fn proposal_execution_succeeds() {
         run_to_block(2);
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Approve, Vec::new()),
@@ -458,7 +457,6 @@ fn proposal_execution_failed() {
         assert!(!<crate::Proposals<Test>>::contains_key(proposal_id));
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Approve, Vec::new()),
@@ -509,7 +507,6 @@ fn voting_results_calculation_succeeds() {
         run_to_block(block_number);
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Reject, Vec::new()),
@@ -871,15 +868,13 @@ fn veto_proposal_fails_with_insufficient_rights() {
 }
 
 #[test]
-fn create_proposal_event_emitted() {
+fn create_proposal() {
     initial_test_ext().execute_with(|| {
         // Events start only from 1 first block. No events on block zero.
         run_to_block_and_finalize(1);
 
         let dummy_proposal = DummyProposalFixture::default();
         dummy_proposal.create_proposal_and_assert(Ok(1));
-
-        EventFixture::assert_events(vec![RawEvent::ProposalCreated(1, 1)]);
     });
 }
 
@@ -896,7 +891,6 @@ fn veto_proposal_event_emitted() {
         veto_proposal.veto_and_assert(Ok(()));
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::ProposalDecisionMade(proposal_id, ProposalDecision::Vetoed),
         ]);
     });
@@ -918,7 +912,6 @@ fn cancel_proposal_event_emitted() {
         cancel_proposal.cancel_and_assert(Ok(()));
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::ProposalDecisionMade(proposal_id, ProposalDecision::Canceled),
             RawEvent::ProposalCancelled(dummy_proposal.account_id, proposal_id),
         ]);
@@ -938,7 +931,6 @@ fn vote_proposal_event_emitted() {
         vote_generator.vote_and_assert_ok(VoteKind::Approve);
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, 1),
             RawEvent::Voted(1, 1, VoteKind::Approve, Vec::new()),
         ]);
     });
@@ -961,13 +953,11 @@ fn create_proposal_and_expire_it() {
         run_to_block_and_finalize(expected_expriration_block - 1);
 
         assert!(<crate::Proposals<Test>>::contains_key(proposal_id));
-        EventFixture::assert_last_crate_event(RawEvent::ProposalCreated(1, proposal_id));
 
         run_to_block_and_finalize(expected_expriration_block);
 
         assert!(!<crate::Proposals<Test>>::contains_key(proposal_id));
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::ProposalDecisionMade(proposal_id, ProposalDecision::Expired),
         ]);
     });
@@ -1091,8 +1081,6 @@ fn cancel_active_and_pending_execution_proposal_by_runtime() {
         ProposalsEngine::cancel_active_and_pending_proposals();
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, pending_execution_proposal_id),
-            RawEvent::ProposalCreated(1, active_proposal_id),
             RawEvent::Voted(
                 1,
                 pending_execution_proposal_id,
@@ -1186,7 +1174,6 @@ fn cancel_pending_constitutionality_proposal_by_runtime() {
         ProposalsEngine::cancel_active_and_pending_proposals();
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Approve, Vec::new()),
@@ -1849,7 +1836,6 @@ fn proposal_with_pending_constitutionality_succeeds() {
         run_to_block_and_finalize(2);
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Approve, Vec::new()),
@@ -1912,7 +1898,6 @@ fn proposal_with_pending_constitutionality_reactivation_succeeds() {
         run_to_block_and_finalize(2);
 
         EventFixture::assert_events(vec![
-            RawEvent::ProposalCreated(1, proposal_id),
             RawEvent::Voted(1, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(2, proposal_id, VoteKind::Approve, Vec::new()),
             RawEvent::Voted(3, proposal_id, VoteKind::Approve, Vec::new()),
@@ -2010,7 +1995,6 @@ fn proposal_with_pending_constitutionality_execution_succeeds() {
         EventFixture::assert_global_events(vec![
             TestEvent::frame_system(frame_system::RawEvent::NewAccount(1)), // because of token transfer
             TestEvent::balances(balances::RawEvent::Endowed(1, total_balance)), // because of token transfer
-            TestEvent::engine(RawEvent::ProposalCreated(1, proposal_id)),
             TestEvent::engine(RawEvent::Voted(
                 1,
                 proposal_id,
@@ -2109,7 +2093,6 @@ fn proposal_with_pending_constitutionality_execution_succeeds() {
             // first chain of event from the creation to the approval
             TestEvent::frame_system(frame_system::RawEvent::NewAccount(1)), // because of token transfer
             TestEvent::balances(balances::RawEvent::Endowed(1, total_balance)), // because of token transfer
-            TestEvent::engine(RawEvent::ProposalCreated(1, proposal_id)),
             TestEvent::engine(RawEvent::Voted(
                 1,
                 proposal_id,

+ 13 - 2
runtime-modules/referendum/src/lib.rs

@@ -33,7 +33,7 @@
 // used dependencies
 use codec::{Codec, Decode, Encode};
 use core::marker::PhantomData;
-use frame_support::traits::{EnsureOrigin, Get};
+use frame_support::traits::{EnsureOrigin, Get, LockIdentifier};
 use frame_support::weights::Weight;
 use frame_support::{
     decl_error, decl_event, decl_module, decl_storage, ensure, error::BadOrigin, Parameter,
@@ -222,7 +222,12 @@ pub trait Trait<I: Instance = DefaultInstance>:
     type MaxSaltLength: Get<u64>;
 
     /// Stakes and balance locks handler.
-    type StakingHandler: StakingHandler<Self::AccountId, BalanceOf<Self>, Self::MemberId>;
+    type StakingHandler: StakingHandler<
+        Self::AccountId,
+        BalanceOf<Self>,
+        Self::MemberId,
+        LockIdentifier,
+    >;
 
     /// Origin from which the referendum can be started.
     type ManagerOrigin: EnsureOrigin<Self::Origin>;
@@ -395,13 +400,19 @@ decl_module! {
         /// Maximum length of vote commitment salt. Use length that ensures uniqueness for hashing
         /// e.g. std::u64::MAX.
         const MaxSaltLength: u64 = T::MaxSaltLength::get();
+
         /// Duration of voting stage (number of blocks)
         const VoteStageDuration: T::BlockNumber = T::VoteStageDuration::get();
+
         /// Duration of revealing stage (number of blocks)
         const RevealStageDuration: T::BlockNumber = T::RevealStageDuration::get();
+
         /// Minimum stake needed for voting
         const MinimumStake: BalanceOf<T> = T::MinimumStake::get();
 
+        /// Exports const - staking handler lock id.
+        const StakingHandlerLockId: LockIdentifier = T::StakingHandler::lock_id();
+
         /////////////////// Lifetime ///////////////////////////////////////////
 
         // No origin so this is a priviledged call

+ 9 - 1
runtime-modules/staking-handler/src/lib.rs

@@ -26,7 +26,7 @@ pub trait LockComparator<Balance> {
 /// Defines abstract staking handler to manage user stakes for different activities
 /// like adding a proposal. Implementation should use built-in LockableCurrency
 /// and LockIdentifier to lock balance consistently with pallet_staking.
-pub trait StakingHandler<AccountId, Balance, MemberId> {
+pub trait StakingHandler<AccountId, Balance, MemberId, LockIdentifier> {
     /// Locks the specified balance on the account using specific lock identifier.
     /// It locks for all withdraw reasons.
     fn lock(account_id: &AccountId, amount: Balance);
@@ -54,6 +54,9 @@ pub trait StakingHandler<AccountId, Balance, MemberId> {
     /// is 'already locked funds' + 'usable funds'.
     fn is_enough_balance_for_stake(account_id: &AccountId, amount: Balance) -> bool;
 
+    /// Returns lock identifier
+    fn lock_id() -> LockIdentifier;
+
     /// Returns the current stake on the account.
     fn current_stake(account_id: &AccountId) -> Balance;
 }
@@ -81,6 +84,7 @@ impl<
         <T as frame_system::Trait>::AccountId,
         <T as pallet_balances::Trait>::Balance,
         <T as common::membership::MembershipTypes>::MemberId,
+        LockIdentifier,
     > for StakingManager<T, LockId>
 {
     fn lock(
@@ -174,6 +178,10 @@ impl<
         <pallet_balances::Module<T>>::usable_balance(account_id) >= amount
     }
 
+    fn lock_id() -> LockIdentifier {
+        LockId::get()
+    }
+
     fn current_stake(
         account_id: &<T as frame_system::Trait>::AccountId,
     ) -> <T as pallet_balances::Trait>::Balance {

+ 27 - 5
runtime-modules/working-group/src/lib.rs

@@ -42,7 +42,7 @@ mod errors;
 mod tests;
 mod types;
 
-use frame_support::traits::{Currency, Get};
+use frame_support::traits::{Currency, Get, LockIdentifier};
 use frame_support::weights::Weight;
 use frame_support::IterableStorageMap;
 use frame_support::{decl_event, decl_module, decl_storage, ensure, StorageValue};
@@ -104,12 +104,17 @@ pub trait Trait<I: Instance = DefaultInstance>:
     type MaxWorkerNumberLimit: Get<u32>;
 
     /// Stakes and balance locks handler.
-    type StakingHandler: StakingHandler<Self::AccountId, BalanceOf<Self>, MemberId<Self>>;
+    type StakingHandler: StakingHandler<
+        Self::AccountId,
+        BalanceOf<Self>,
+        MemberId<Self>,
+        LockIdentifier,
+    >;
 
     /// Validates staking account ownership for a member.
     type StakingAccountValidator: common::StakingAccountValidator<Self>;
 
-    /// Validates member id and origin combination
+    /// Validates member id and origin combination.
     type MemberOriginValidator: MemberOriginValidator<Self::Origin, MemberId<Self>, Self::AccountId>;
 
     /// Defines min unstaking period in the group.
@@ -121,7 +126,7 @@ pub trait Trait<I: Instance = DefaultInstance>:
     /// Weight information for extrinsics in this pallet.
     type WeightInfo: WeightInfo;
 
-    /// Minimum stake required for applying into an opening
+    /// Minimum stake required for applying into an opening.
     type MinimumApplicationStake: Get<Self::Balance>;
 
     /// Stake needed to create an opening
@@ -339,9 +344,26 @@ decl_module! {
         /// Predefined errors
         type Error = Error<T, I>;
 
-        /// Exports const -  max simultaneous active worker number.
+        /// Exports const
+
+        /// Max simultaneous active worker number.
         const MaxWorkerNumberLimit: u32 = T::MaxWorkerNumberLimit::get();
 
+        /// Defines min unstaking period in the group.
+        const MinUnstakingPeriodLimit: T::BlockNumber = T::MinUnstakingPeriodLimit::get();
+
+        /// Minimum stake required for applying into an opening.
+        const MinimumApplicationStake: T::Balance = T::MinimumApplicationStake::get();
+
+        /// Stake needed to create an opening.
+        const LeaderOpeningStake: T::Balance = T::LeaderOpeningStake::get();
+
+        /// Defines the period every worker gets paid in blocks.
+        const RewardPeriod: u32 = T::RewardPeriod::get();
+
+        /// Staking handler lock id.
+        const StakingHandlerLockId: LockIdentifier = T::StakingHandler::lock_id();
+
         /// # <weight>
         ///
         /// ## Weight

+ 5 - 0
runtime/src/tests/proposals_integration/working_group_proposals.rs

@@ -5,6 +5,7 @@ use super::*;
 
 use common::working_group::WorkingGroup;
 use common::BalanceKind;
+use frame_support::traits::LockIdentifier;
 use frame_system::RawOrigin;
 use proposals_codex::CreateOpeningParameters;
 use sp_runtime::SaturatedConversion;
@@ -646,6 +647,7 @@ fn run_create_decrease_group_leader_stake_proposal_execution_succeeds<
         <T as frame_system::Trait>::AccountId,
         <T as pallet_balances::Trait>::Balance,
         <T as common::membership::MembershipTypes>::MemberId,
+        LockIdentifier,
     >,
 >(
     working_group: WorkingGroup,
@@ -806,6 +808,7 @@ fn run_create_slash_group_leader_stake_proposal_execution_succeeds<
         <T as frame_system::Trait>::AccountId,
         <T as pallet_balances::Trait>::Balance,
         <T as common::membership::MembershipTypes>::MemberId,
+        LockIdentifier,
     >,
 >(
     working_group: WorkingGroup,
@@ -1323,6 +1326,7 @@ fn run_create_terminate_group_leader_role_proposal_execution_succeeds<
         <T as frame_system::Trait>::AccountId,
         <T as pallet_balances::Trait>::Balance,
         <T as common::membership::MembershipTypes>::MemberId,
+        LockIdentifier,
     >,
 >(
     working_group: WorkingGroup,
@@ -1479,6 +1483,7 @@ fn run_create_terminate_group_leader_role_proposal_with_slashing_execution_succe
         <T as frame_system::Trait>::AccountId,
         <T as pallet_balances::Trait>::Balance,
         <T as common::membership::MembershipTypes>::MemberId,
+        LockIdentifier,
     >,
 >(
     working_group: WorkingGroup,