Pārlūkot izejas kodu

Merge branch 'olympia' into olympia-types

Leszek Wiesner 3 gadi atpakaļ
vecāks
revīzija
1eae241ef2

+ 58 - 3
analyses/fee-analysis/README.md

@@ -6,7 +6,7 @@ This directory has a CLI to output the analysis of weights into a `CSV` and a mo
 
 ## Requirements
 
-* python3
+* python >= 3.9
 * (virtualenv)[https://pypi.org/project/virtualenv/]
 
 ## Steps to run
@@ -17,15 +17,70 @@ This directory has a CLI to output the analysis of weights into a `CSV` and a mo
 * a browser tab should launch with the files in this directory
 
 ## To run the CLI
+This CLI will output a CSV with the weights of the extrinsics given a file or directory with files that are output by
+the FRAME benchmarks.
+Furthermore, given the parameters in a configuration file it will calculate the token fees for the given
+weights.
+
+Moreover, it can optionally try to estimate the price in fiat currency of the extrinsics given the total issuance of tokens in
+the system and the market cap.
+
 * `python analysis_cli --help` will output the help
 
 You will need to provide a path to a directory containing the weight files or the path to a single
 weight file.
 
+By default the output will be in `output.csv` where the cli is run, to change this use the `-o` option.
+
 For the CSV to include an analysis pass the parameter `-p` (Meaning the calculated price in tokens and prices)
 
-The `config.json` file in the `analysis_cli` there is configuration for said analysis. Such as specializing the
-parametrs and length for a given extrinsics, the coefficients, issuance and marke caps.
+The parameter configurations is found in `config.json` in the `analysis_cli` directory, you can change the file using
+the `-c` option.
+
+The config file has the following form:
+
+```json
+{
+    "weight_coefficient": Number,
+    "issuance": Number,
+    "length_coefficient": Number,
+    "min_market_cap": Number,
+    "max_market_cap": Number,
+    "lengths": {
+        "<extrinsic_name>": Number
+    },
+    "params": {
+        "<extrinsic_name>": {
+            "i": Number,
+            "j": Number,
+            "k": Number,
+            ...
+        }
+    }
+}
+```
+
+Where:
+* `weight_coefficient`: is the coefficient for converting a weight to a token fee, this can be found in
+  `runtime/src/constants.rs` as part of the `WeightToFeePolynomial` implementation by `WeightToFee`.
+* `issuance`: The total number of tokens available in the system, this is found in `runtime/src/constants.rs` as `JOYS`.
+* `length_coefficient`: This is how much a byte of an extrinsic cost in number of tokens, this is found in
+  `runtime/src/constants.rs` as `TransactionByteFee`.
+* `min_market_cap`: This is the estimated minimum market cap of the token. This is only used when the dollar price of a
+  extrinsics is calculated.
+* `max_market_cap`: This is the estimated maximum market cap of the token. This is only used when the dollar price of a
+  extrinsics is calculated.
+* `lengths`: This is a dictionary containing `<extrinsic_name>`. This entries maps to a length in bytes for a given
+  extrinsic. When calculating the token fee of an extrinsic this will be added over its weight fee using
+  `length_coefficient` for the convertion. (It's specially important to set a length for `runtime_upgrade` since this
+  extrinsic can easily take up to 3MB in size which will make a considerable part of its cost.
+* `params`: This is a dictionary of dictionaries, each entry on the first level represent a different extrinsic with
+  `<extrinsic_name>`. Each of these entries are a dictionary with `<parameter>` that represent a value of a parameter
+  that will be used when calculating the weight of the extrinsic with its corresponding function.
+
+Note that the `<extrinsic_name>` need its fully qualified path, e.g. `proposals_discussion::add_post`.
+
+Currently the `weight_coefficient` and the `length_coefficient` is set to the same as the runtime.
 
 **Note:** The output csv file already sums the `EXTRINSIC_BASE_WEIGHT` to the weight column
 

+ 0 - 92
runtime-modules/forum/src/benchmarking.rs

@@ -794,7 +794,6 @@ benchmarks! {
             category_id,
             title_hash: T::calculate_hash(&title),
             author_id: forum_user_id.saturated_into(),
-            archived: false,
             poll: poll.clone(),
             cleanup_pay_off: T::ThreadDeposit::get(),
             number_of_posts: 1,
@@ -860,81 +859,6 @@ benchmarks! {
         );
     }
 
-    update_thread_archival_status_lead {
-        let i in 1 .. (T::MaxCategoryDepth::get() + 1) as u32;
-
-        let forum_user_id = 0;
-        let caller_id =
-            insert_a_leader::<T>(forum_user_id);
-        let text = vec![1u8].repeat(MAX_BYTES as usize);
-
-        // Generate categories tree
-        let (category_id, _) = generate_categories_tree::<T>(caller_id.clone(), i, None);
-
-        // 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 mut thread = Module::<T>::thread_by_id(category_id, thread_id);
-        let new_archival_status = true;
-
-    }: update_thread_archival_status(RawOrigin::Signed(caller_id), PrivilegedActor::Lead, category_id, thread_id, new_archival_status)
-    verify {
-        thread.archived = new_archival_status;
-
-        assert_eq!(Module::<T>::thread_by_id(category_id, thread_id), thread);
-
-        assert_last_event::<T>(
-            RawEvent::ThreadUpdated(
-                thread_id,
-                new_archival_status,
-                PrivilegedActor::Lead,
-                category_id
-            ).into()
-        );
-    }
-
-    update_thread_archival_status_moderator {
-        let i in 1 .. (T::MaxCategoryDepth::get() + 1) as u32;
-
-        let forum_user_id = 0;
-        let caller_id =
-            insert_a_leader::<T>(forum_user_id);
-        let text = vec![1u8].repeat(MAX_BYTES as usize);
-
-        // Generate categories tree
-        let (category_id, _) = generate_categories_tree::<T>(caller_id.clone(), i, None);
-
-        // 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 mut thread = Module::<T>::thread_by_id(category_id, thread_id);
-        let new_archival_status = true;
-
-        let moderator_id = ModeratorId::<T>::from(forum_user_id.try_into().unwrap());
-
-        // 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();
-
-    }: update_thread_archival_status(RawOrigin::Signed(caller_id), PrivilegedActor::Moderator(moderator_id), category_id, thread_id, new_archival_status)
-    verify {
-        thread.archived = new_archival_status;
-
-        assert_eq!(Module::<T>::thread_by_id(category_id, thread_id), thread);
-
-        assert_last_event::<T>(
-            RawEvent::ThreadUpdated(
-                thread_id,
-                new_archival_status,
-                PrivilegedActor::Moderator(moderator_id),
-                category_id
-            ).into()
-        );
-    }
-
     delete_thread {
         let i in 1 .. (T::MaxCategoryDepth::get() + 1) as u32;
         let hide = false;
@@ -1818,22 +1742,6 @@ mod tests {
         });
     }
 
-    #[test]
-    fn test_update_thread_archival_status_lead() {
-        with_test_externalities(|| {
-            assert_ok!(test_benchmark_update_thread_archival_status_lead::<Runtime>());
-        });
-    }
-
-    #[test]
-    fn test_update_thread_archival_status_moderator() {
-        with_test_externalities(|| {
-            assert_ok!(test_benchmark_update_thread_archival_status_moderator::<
-                Runtime,
-            >());
-        });
-    }
-
     #[test]
     fn test_delete_thread() {
         with_test_externalities(|| {

+ 1 - 79
runtime-modules/forum/src/lib.rs

@@ -65,14 +65,12 @@ pub trait WeightInfo {
     fn delete_category_moderator(i: u32) -> Weight;
     fn create_thread(j: u32, k: u32, i: u32) -> Weight;
     fn edit_thread_title(i: u32, j: u32) -> Weight;
-    fn update_thread_archival_status_lead(i: u32) -> Weight;
-    fn update_thread_archival_status_moderator(i: u32) -> Weight;
     fn delete_thread(i: u32) -> Weight;
     fn move_thread_to_category_lead(i: u32) -> Weight;
     fn move_thread_to_category_moderator(i: u32) -> Weight;
     fn vote_on_poll(i: u32, j: u32) -> Weight;
     fn moderate_thread_lead(i: u32, k: u32) -> Weight;
-    fn moderate_thread_moderator(i: u32, j: u32, k: u32) -> Weight;
+    fn moderate_thread_moderator(i: u32, k: u32) -> Weight;
     fn add_post(i: u32, j: u32) -> Weight;
     fn react_post(i: u32) -> Weight;
     fn edit_post_text(i: u32, j: u32) -> Weight;
@@ -242,9 +240,6 @@ pub struct Thread<ForumUserId, CategoryId, Moment, Hash, Balance> {
     /// Author of post.
     pub author_id: ForumUserId,
 
-    /// Whether thread is archived.
-    pub archived: bool,
-
     /// poll description.
     pub poll: Option<Poll<Moment, Hash>>,
 
@@ -340,9 +335,6 @@ decl_error! {
         /// Thread not being updated.
         ThreadNotBeingUpdated,
 
-        /// Thread is immutable, i.e. archived.
-        ThreadImmutable,
-
         /// Not enough balance to create thread
         InsufficientBalanceForThreadCreation,
 
@@ -805,7 +797,6 @@ decl_module! {
                 category_id,
                 title_hash: T::calculate_hash(&title),
                 author_id: forum_user_id,
-                archived: false,
                 poll: poll.clone(),
                 cleanup_pay_off: T::ThreadDeposit::get(),
                 number_of_posts: 0,
@@ -890,53 +881,6 @@ decl_module! {
             Ok(())
         }
 
-        /// Update thread archival status
-        ///
-        /// <weight>
-        ///
-        /// ## Weight
-        /// `O (W)` where:
-        /// - `W` is the category depth
-        /// - DB:
-        ///    - O(W)
-        /// # </weight>
-        #[weight = WeightInfoForum::<T>::update_thread_archival_status_lead(
-            T::MaxCategoryDepth::get() as u32,
-        ).max(WeightInfoForum::<T>::update_thread_archival_status_moderator(
-            T::MaxCategoryDepth::get() as u32,
-        ))]
-        fn update_thread_archival_status(origin, actor: PrivilegedActor<T>, category_id: T::CategoryId, thread_id: T::ThreadId, new_archival_status: bool) -> DispatchResult {
-            // Ensure data migration is done
-            Self::ensure_data_migration_done()?;
-
-            let account_id = ensure_signed(origin)?;
-
-            // Ensure actor can update category
-            let (_, thread) = Self::ensure_can_update_thread_archival_status(account_id, &actor, &category_id, &thread_id)?;
-
-            // No change, invalid transaction
-            if new_archival_status == thread.archived {
-                return Err(Error::<T>::ThreadNotBeingUpdated.into());
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Mutate thread, and set possible new change parameters
-            <ThreadById<T>>::mutate(thread.category_id, thread_id, |c| c.archived = new_archival_status);
-
-            // Generate event
-            Self::deposit_event(RawEvent::ThreadUpdated(
-                    thread_id,
-                    new_archival_status,
-                    actor,
-                    category_id
-                ));
-
-            Ok(())
-        }
-
         /// Delete thread
         ///
         /// <weight>
@@ -1121,7 +1065,6 @@ decl_module! {
         ).max(
             WeightInfoForum::<T>::moderate_thread_moderator(
                 T::MaxCategoryDepth::get() as u32,
-                0,
                 rationale.len().saturated_into(),
             )
         )]
@@ -1692,33 +1635,12 @@ impl<T: Trait> Module<T> {
         // Make sure thread exists
         let thread = Self::ensure_thread_exists(category_id, thread_id)?;
 
-        if thread.archived {
-            return Err(Error::<T>::ThreadImmutable);
-        }
-
         // and corresponding category is mutable
         let category = Self::ensure_category_is_mutable(category_id)?;
 
         Ok((category, thread))
     }
 
-    fn ensure_can_update_thread_archival_status(
-        account_id: T::AccountId,
-        actor: &PrivilegedActor<T>,
-        category_id: &T::CategoryId,
-        thread_id: &T::ThreadId,
-    ) -> Result<(Category<T::CategoryId, T::ThreadId, T::Hash>, ThreadOf<T>), Error<T>> {
-        // Check actor's role
-        Self::ensure_actor_role(&account_id, actor)?;
-
-        let (category, thread) = Self::ensure_thread_is_mutable(category_id, thread_id)?;
-
-        // Ensure actor can delete category
-        Self::ensure_can_moderate_category_path(actor, category_id)?;
-
-        Ok((category, thread))
-    }
-
     fn ensure_thread_exists(
         category_id: &T::CategoryId,
         thread_id: &T::ThreadId,

+ 1 - 38
runtime-modules/forum/src/mock.rs

@@ -447,12 +447,6 @@ impl WeightInfo for () {
     fn edit_thread_title(_: u32, _: u32) -> Weight {
         0
     }
-    fn update_thread_archival_status_lead(_: u32) -> Weight {
-        0
-    }
-    fn update_thread_archival_status_moderator(_: u32) -> Weight {
-        0
-    }
     fn delete_thread(_: u32) -> Weight {
         0
     }
@@ -468,7 +462,7 @@ impl WeightInfo for () {
     fn moderate_thread_lead(_: u32, _: u32) -> Weight {
         0
     }
-    fn moderate_thread_moderator(_: u32, _: u32, _: u32) -> Weight {
+    fn moderate_thread_moderator(_: u32, _: u32) -> Weight {
         0
     }
     fn add_post(_: u32, _: u32) -> Weight {
@@ -876,37 +870,6 @@ pub fn move_thread_mock(
     }
 }
 
-pub fn update_thread_archival_status_mock(
-    origin: OriginType,
-    actor: PrivilegedActor<Runtime>,
-    category_id: <Runtime as Trait>::CategoryId,
-    thread_id: <Runtime as Trait>::ThreadId,
-    new_archival_status: bool,
-    result: DispatchResult,
-) {
-    assert_eq!(
-        TestForumModule::update_thread_archival_status(
-            mock_origin(origin),
-            actor.clone(),
-            category_id,
-            thread_id,
-            new_archival_status
-        ),
-        result
-    );
-    if result.is_ok() {
-        assert_eq!(
-            System::events().last().unwrap().event,
-            TestEvent::forum_mod(RawEvent::ThreadUpdated(
-                thread_id,
-                new_archival_status,
-                actor,
-                category_id
-            ))
-        );
-    }
-}
-
 pub fn create_post_mock(
     origin: OriginType,
     account_id: <Runtime as frame_system::Trait>::AccountId,

+ 0 - 268
runtime-modules/forum/src/tests.rs

@@ -798,274 +798,6 @@ fn edit_thread_title() {
 /*
  ** update_category
  */
-#[test]
-// test if category updator is forum lead
-fn update_thread_archival_status_origin() {
-    let origins = [FORUM_LEAD_ORIGIN, NOT_FORUM_LEAD_ORIGIN];
-    let results = vec![Ok(()), Err(Error::<Runtime>::OriginNotForumLead.into())];
-
-    for index in 0..origins.len() {
-        let forum_lead = FORUM_LEAD_ORIGIN_ID;
-        let origin = OriginType::Signed(forum_lead);
-        let initial_balance = 10_000_000;
-        with_test_externalities(|| {
-            balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
-
-            let category_id = create_category_mock(
-                origin,
-                None,
-                good_category_title(),
-                good_category_description(),
-                Ok(()),
-            );
-
-            let thread_id = create_thread_mock(
-                origins[0].clone(),
-                forum_lead,
-                forum_lead,
-                category_id,
-                good_thread_title(),
-                good_thread_text(),
-                None,
-                Ok(()),
-            );
-            update_thread_archival_status_mock(
-                origins[index].clone(),
-                PrivilegedActor::Lead,
-                category_id,
-                thread_id,
-                true,
-                results[index],
-            );
-        });
-    }
-}
-
-#[test]
-// test case for new setting actually not update thread status
-fn update_thread_archival_status_no_change() {
-    let forum_lead = FORUM_LEAD_ORIGIN_ID;
-    let origin = OriginType::Signed(forum_lead);
-    let initial_balance = 10_000_000;
-    with_test_externalities(|| {
-        balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
-
-        let category_id = create_category_mock(
-            origin.clone(),
-            None,
-            good_category_title(),
-            good_category_description(),
-            Ok(()),
-        );
-        let thread_id = create_thread_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            good_thread_title(),
-            good_thread_text(),
-            None,
-            Ok(()),
-        );
-        update_thread_archival_status_mock(
-            origin,
-            PrivilegedActor::Lead,
-            category_id,
-            thread_id,
-            false,
-            Err(Error::<Runtime>::ThreadNotBeingUpdated.into()),
-        );
-    });
-}
-
-#[test]
-// test case for editing nonexistent thread
-fn update_thread_archival_status_thread_exists() {
-    let forum_lead = FORUM_LEAD_ORIGIN_ID;
-    let origin = OriginType::Signed(forum_lead);
-    let initial_balance = 10_000_000;
-    with_test_externalities(|| {
-        balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
-
-        let category_id = create_category_mock(
-            origin.clone(),
-            None,
-            good_category_title(),
-            good_category_description(),
-            Ok(()),
-        );
-        let thread_id = create_thread_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            good_thread_title(),
-            good_thread_text(),
-            None,
-            Ok(()),
-        );
-        update_thread_archival_status_mock(
-            origin.clone(),
-            PrivilegedActor::Lead,
-            category_id,
-            thread_id,
-            true,
-            Ok(()),
-        );
-        update_thread_archival_status_mock(
-            origin.clone(),
-            PrivilegedActor::Lead,
-            category_id,
-            thread_id + 1,
-            true,
-            Err(Error::<Runtime>::ThreadDoesNotExist.into()),
-        );
-    });
-}
-
-#[test]
-// test if moderator can archive thread
-fn update_thread_archival_status_moderator() {
-    let moderators = [FORUM_MODERATOR_ORIGIN_ID];
-    let origins = [FORUM_MODERATOR_ORIGIN];
-
-    let forum_lead = FORUM_LEAD_ORIGIN_ID;
-    let origin = OriginType::Signed(forum_lead);
-    let initial_balance = 10_000_000;
-    with_test_externalities(|| {
-        balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
-
-        let category_id = create_category_mock(
-            origin.clone(),
-            None,
-            good_category_title(),
-            good_category_description(),
-            Ok(()),
-        );
-        let thread_id = create_thread_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            good_thread_title(),
-            good_thread_text(),
-            None,
-            Ok(()),
-        );
-
-        // unprivileged moderator will fail to update category
-        update_thread_archival_status_mock(
-            origins[0].clone(),
-            PrivilegedActor::Moderator(moderators[0]),
-            category_id,
-            thread_id,
-            true,
-            Err(Error::<Runtime>::ModeratorCantUpdateCategory.into()),
-        );
-
-        // give permision to moderate category itself
-        update_category_membership_of_moderator_mock(
-            origin.clone(),
-            moderators[0],
-            category_id,
-            true,
-            Ok(()),
-        );
-
-        // moderator associated with category will succeed
-        update_thread_archival_status_mock(
-            origins[0].clone(),
-            PrivilegedActor::Moderator(moderators[0]),
-            category_id,
-            thread_id,
-            true,
-            Ok(()),
-        );
-    });
-}
-
-#[test]
-// test if moderator can archive thread
-fn update_thread_archival_status_lock_works() {
-    let forum_lead = FORUM_LEAD_ORIGIN_ID;
-    let origin = OriginType::Signed(forum_lead);
-    let initial_balance = 10_000_000;
-    with_test_externalities(|| {
-        balances::Module::<Runtime>::make_free_balance_be(&forum_lead, initial_balance);
-
-        let category_id = create_category_mock(
-            origin.clone(),
-            None,
-            good_category_title(),
-            good_category_description(),
-            Ok(()),
-        );
-
-        let thread_id = create_thread_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            good_thread_title(),
-            good_thread_text(),
-            None,
-            Ok(()),
-        );
-
-        let post_id = create_post_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            thread_id,
-            good_post_text(),
-            true,
-            Ok(()),
-        );
-
-        update_thread_archival_status_mock(
-            origin.clone(),
-            PrivilegedActor::Lead,
-            category_id,
-            thread_id,
-            true,
-            Ok(()),
-        );
-
-        // can't add more posts to thread inside category
-        create_post_mock(
-            origin.clone(),
-            forum_lead,
-            forum_lead,
-            category_id,
-            thread_id,
-            good_post_text(),
-            true,
-            Err(Error::<Runtime>::ThreadImmutable.into()),
-        );
-
-        // can't update post
-        edit_post_text_mock(
-            origin.clone(),
-            forum_lead,
-            category_id,
-            thread_id,
-            post_id,
-            good_post_new_text(),
-            Err(Error::<Runtime>::ThreadImmutable.into()),
-        );
-
-        // can't update thread
-        edit_thread_title_mock(
-            origin.clone(),
-            forum_lead,
-            category_id,
-            thread_id,
-            good_thread_new_title(),
-            Err(Error::<Runtime>::ThreadImmutable.into()),
-        );
-    });
-}
 
 #[test]
 // test if thread creator can delete thread

+ 71 - 15
runtime-modules/working-group/src/lib.rs

@@ -52,7 +52,7 @@ pub use types::{
     Application, ApplicationId, ApplyOnOpeningParameters, BalanceOf, Opening, OpeningId,
     OpeningType, StakeParameters, StakePolicy, Worker, WorkerId,
 };
-use types::{ApplicationInfo, WorkerInfo};
+use types::{ApplicationInfo, RewardPaymentType, WorkerInfo};
 
 pub use checks::{ensure_worker_exists, ensure_worker_signed};
 
@@ -181,11 +181,11 @@ decl_event!(
         /// - Rationale.
         WorkerExited(WorkerId),
 
-        /// Emits when worker is leaving immediatly after extrinsic is called
+        /// Emits when worker started leaving their role.
         /// Params:
         /// - Worker id.
         /// - Rationale.
-        WorkerLeft(WorkerId, Option<Vec<u8>>),
+        WorkerStartedLeaving(WorkerId, Option<Vec<u8>>),
 
         /// Emits on terminating the worker.
         /// Params:
@@ -256,10 +256,28 @@ decl_event!(
 
         /// Emits on budget from the working group being spent
         /// Params:
-        /// - Reciever Account Id.
+        /// - Receiver Account Id.
         /// - Balance spent.
         /// - Rationale.
         BudgetSpending(AccountId, Balance, Option<Vec<u8>>),
+
+        /// Emits on paying the reward.
+        /// Params:
+        /// - Receiver Account Id.
+        /// - Reward
+        RewardPaid(AccountId, Balance),
+
+        /// Emits on paying the missed reward.
+        /// Params:
+        /// - Receiver Account Id.
+        /// - Missed reward
+        MissedRewardPaid(AccountId, Balance),
+
+        /// Emits on reaching new missed reward.
+        /// Params:
+        /// - Worker ID.
+        /// - Missed reward (optional). None means 'no missed reward'.
+        NewMissedRewardLevelReached(WorkerId, Option<Balance>),
     }
 );
 
@@ -653,6 +671,9 @@ decl_module! {
             WorkerById::<T, I>::mutate(worker_id, |worker| {
                 worker.started_leaving_at = Some(Self::current_block())
             });
+
+            // Trigger event
+            Self::deposit_event(RawEvent::WorkerStartedLeaving(worker_id, rationale));
         }
 
         /// Terminate the active worker by the lead.
@@ -1300,7 +1321,11 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
 
             // Check whether the budget is not zero.
             if actual_reward > Zero::zero() {
-                Self::pay_from_budget(&worker.reward_account_id, actual_reward);
+                Self::pay_reward(
+                    &worker.reward_account_id,
+                    actual_reward,
+                    RewardPaymentType::RegularReward,
+                );
             }
 
             // Check whether the budget is insufficient.
@@ -1323,6 +1348,24 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         let _ = <balances::Module<T>>::deposit_creating(account_id, amount);
     }
 
+    // Helper-function joining the reward payment with the event.
+    fn pay_reward(
+        account_id: &T::AccountId,
+        amount: BalanceOf<T>,
+        reward_payment_type: RewardPaymentType,
+    ) {
+        Self::pay_from_budget(account_id, amount);
+
+        let event = match reward_payment_type {
+            RewardPaymentType::MissedReward => {
+                RawEvent::MissedRewardPaid(account_id.clone(), amount)
+            }
+            RewardPaymentType::RegularReward => RawEvent::RewardPaid(account_id.clone(), amount),
+        };
+
+        Self::deposit_event(event);
+    }
+
     // Tries to pay missed reward if the reward is enabled for worker and there is enough of group budget.
     fn try_to_pay_missed_reward(worker_id: &WorkerId<T>, worker: &Worker<T>) {
         if let Some(missed_reward) = worker.missed_reward {
@@ -1331,7 +1374,11 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
 
             // Checks if the budget allows any payment.
             if could_be_paid_reward > Zero::zero() {
-                Self::pay_from_budget(&worker.reward_account_id, could_be_paid_reward);
+                Self::pay_reward(
+                    &worker.reward_account_id,
+                    could_be_paid_reward,
+                    RewardPaymentType::MissedReward,
+                );
 
                 let new_missed_reward = if insufficient_amount > Zero::zero() {
                     Some(insufficient_amount)
@@ -1339,14 +1386,26 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
                     None
                 };
 
-                // Update worker missed reward.
-                WorkerById::<T, I>::mutate(worker_id, |worker| {
-                    worker.missed_reward = new_missed_reward;
-                });
+                Self::update_worker_missed_reward(worker_id, new_missed_reward);
             }
         }
     }
 
+    // Update worker missed reward.
+    fn update_worker_missed_reward(
+        worker_id: &WorkerId<T>,
+        new_missed_reward: Option<BalanceOf<T>>,
+    ) {
+        WorkerById::<T, I>::mutate(worker_id, |worker| {
+            worker.missed_reward = new_missed_reward;
+        });
+
+        Self::deposit_event(RawEvent::NewMissedRewardLevelReached(
+            *worker_id,
+            new_missed_reward,
+        ));
+    }
+
     // Saves missed reward for a worker.
     fn save_missed_reward(worker_id: &WorkerId<T>, worker: &Worker<T>, reward: BalanceOf<T>) {
         // Save unpaid reward.
@@ -1354,10 +1413,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
 
         let new_missed_reward = missed_reward_so_far + reward;
 
-        // Update worker missed reward.
-        WorkerById::<T, I>::mutate(worker_id, |worker| {
-            worker.missed_reward = Some(new_missed_reward);
-        });
+        Self::update_worker_missed_reward(worker_id, Some(new_missed_reward));
     }
 
     // Returns allowed payment by the group budget and possible missed payment
@@ -1376,7 +1432,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         WorkerById::<T, I>::iter()
             .filter_map(|(worker_id, worker)| {
                 if let Some(started_leaving_at) = worker.started_leaving_at {
-                    if started_leaving_at + worker.job_unstaking_period >= Self::current_block() {
+                    if started_leaving_at + worker.job_unstaking_period <= Self::current_block() {
                         return Some((worker_id, worker).into());
                     }
                 }

+ 29 - 0
runtime-modules/working-group/src/tests/fixtures.rs

@@ -44,6 +44,35 @@ impl EventFixture {
 
         assert_eq!(System::events().pop().unwrap(), expected_event);
     }
+
+    pub fn contains_crate_event(
+        expected_raw_event: RawEvent<
+            u64,
+            u64,
+            BTreeMap<u64, u64>,
+            u64,
+            u64,
+            u64,
+            OpeningType,
+            StakePolicy<u64, u64>,
+            ApplyOnOpeningParameters<Test>,
+            DefaultInstance,
+        >,
+    ) {
+        let converted_event = TestEvent::crate_DefaultInstance(expected_raw_event);
+
+        Self::contains_global_event(converted_event)
+    }
+
+    fn contains_global_event(expected_event: TestEvent) {
+        let expected_event = EventRecord {
+            phase: Phase::Initialization,
+            event: expected_event,
+            topics: vec![],
+        };
+
+        assert!(System::events().iter().any(|ev| *ev == expected_event));
+    }
 }
 
 pub struct AddOpeningFixture {

+ 64 - 4
runtime-modules/working-group/src/tests/mod.rs

@@ -592,6 +592,8 @@ fn leave_worker_role_succeeds() {
 
         leave_worker_role_fixture.call_and_assert(Ok(()));
 
+        EventFixture::assert_last_crate_event(RawEvent::WorkerStartedLeaving(worker_id, None));
+
         let worker = TestWorkingGroup::worker_by_id(worker_id);
         run_to_block(1 + worker.job_unstaking_period);
 
@@ -608,9 +610,11 @@ fn leave_worker_role_succeeds_with_paying_missed_reward() {
         let worker_id = HireRegularWorkerFixture::default()
             .with_reward_per_block(Some(reward_per_block))
             .hire();
-        let block_number = 4;
 
-        run_to_block(block_number);
+        let reward_period: u64 = <Test as Trait>::RewardPeriod::get().into();
+        let missed_reward_block_number = reward_period * 2;
+
+        run_to_block(missed_reward_block_number);
 
         assert_eq!(Balances::usable_balance(&account_id), 0);
 
@@ -620,15 +624,65 @@ fn leave_worker_role_succeeds_with_paying_missed_reward() {
         leave_worker_role_fixture.call_and_assert(Ok(()));
 
         let worker = TestWorkingGroup::worker_by_id(worker_id);
-        run_to_block(block_number + worker.job_unstaking_period);
+        let leaving_block = missed_reward_block_number + worker.job_unstaking_period;
+        run_to_block(leaving_block);
 
+        let missed_reward = missed_reward_block_number * reward_per_block;
+        EventFixture::contains_crate_event(RawEvent::NewMissedRewardLevelReached(
+            worker_id,
+            Some(missed_reward),
+        ));
+        EventFixture::contains_crate_event(RawEvent::MissedRewardPaid(account_id, missed_reward));
+
+        // Didn't get the last reward period: leaving earlier than rewarding.
+        let reward_block_count = leaving_block - reward_period;
         assert_eq!(
             Balances::usable_balance(&account_id),
-            block_number * reward_per_block + <Test as Trait>::MinimumApplicationStake::get()
+            reward_block_count * reward_per_block + <Test as Trait>::MinimumApplicationStake::get()
         );
     });
 }
 
+#[test]
+fn leave_worker_role_succeeds_with_correct_unstaking_period() {
+    build_test_externalities().execute_with(|| {
+        let starting_block = 10;
+        run_to_block(starting_block);
+
+        let worker_id = HireRegularWorkerFixture::default().hire();
+
+        // Assert initial worker existence
+        assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
+            worker_id
+        ));
+
+        let default_unstaking_period =
+            TestWorkingGroup::worker_by_id(worker_id).job_unstaking_period;
+
+        let leave_worker_role_fixture = LeaveWorkerRoleFixture::default_for_worker_id(worker_id);
+        leave_worker_role_fixture.call_and_assert(Ok(()));
+
+        // Assert worker existence after leave_role
+        assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
+            worker_id
+        ));
+
+        run_to_block(starting_block + default_unstaking_period - 1);
+
+        // Assert worker existence one block before the end of the unstaking period.
+        assert!(<crate::WorkerById<Test, DefaultInstance>>::contains_key(
+            worker_id
+        ));
+
+        run_to_block(starting_block + default_unstaking_period);
+
+        // Assert worker removal after the unstaking period.
+        assert!(!<crate::WorkerById<Test, DefaultInstance>>::contains_key(
+            worker_id
+        ));
+    });
+}
+
 #[test]
 fn leave_worker_role_succeeds_with_partial_payment_of_missed_reward() {
     build_test_externalities().execute_with(|| {
@@ -1866,6 +1920,12 @@ fn rewards_payments_are_successful() {
             Balances::usable_balance(&account_id),
             block_number * reward_per_block
         );
+
+        let reward_period: u64 = <Test as Trait>::RewardPeriod::get().into();
+        EventFixture::assert_last_crate_event(RawEvent::RewardPaid(
+            account_id,
+            reward_per_block * reward_period,
+        ));
     });
 }
 

+ 9 - 0
runtime-modules/working-group/src/types.rs

@@ -258,3 +258,12 @@ pub type ApplyOnOpeningParameters<T> = ApplyOnOpeningParams<
     <T as frame_system::Trait>::AccountId,
     BalanceOf<T>,
 >;
+
+// Reward payment type enum.
+pub(crate) enum RewardPaymentType {
+    // The reward was missed.
+    MissedReward,
+
+    // The reward was paid in time.
+    RegularReward,
+}

+ 61 - 77
runtime/src/weights/forum.rs

@@ -9,172 +9,156 @@ pub struct WeightInfo;
 impl forum::WeightInfo for WeightInfo {
     fn create_category(i: u32, j: u32, k: u32) -> Weight {
         (0 as Weight)
-            .saturating_add((214_529_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((98_000 as Weight).saturating_mul(j as Weight))
-            .saturating_add((134_000 as Weight).saturating_mul(k as Weight))
+            .saturating_add((244_424_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((108_000 as Weight).saturating_mul(j as Weight))
+            .saturating_add((149_000 as Weight).saturating_mul(k as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn update_category_membership_of_moderator_new() -> Weight {
-        (297_135_000 as Weight)
+        (318_667_000 as Weight)
             .saturating_add(DbWeight::get().reads(4 as Weight))
             .saturating_add(DbWeight::get().writes(2 as Weight))
     }
     fn update_category_membership_of_moderator_old() -> Weight {
-        (315_520_000 as Weight)
+        (340_448_000 as Weight)
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().writes(2 as Weight))
     }
     fn update_category_archival_status_lead(i: u32) -> Weight {
-        (177_097_000 as Weight)
-            .saturating_add((57_774_000 as Weight).saturating_mul(i as Weight))
+        (191_321_000 as Weight)
+            .saturating_add((62_117_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn update_category_archival_status_moderator(i: u32) -> Weight {
-        (195_602_000 as Weight)
-            .saturating_add((57_023_000 as Weight).saturating_mul(i as Weight))
+        (213_940_000 as Weight)
+            .saturating_add((58_413_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn delete_category_lead(i: u32) -> Weight {
-        (142_929_000 as Weight)
-            .saturating_add((68_133_000 as Weight).saturating_mul(i as Weight))
+        (152_811_000 as Weight)
+            .saturating_add((70_445_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(4 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(2 as Weight))
     }
     fn delete_category_moderator(i: u32) -> Weight {
-        (184_678_000 as Weight)
-            .saturating_add((63_220_000 as Weight).saturating_mul(i as Weight))
+        (168_140_000 as Weight)
+            .saturating_add((72_252_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     // WARNING! Some components were not used: ["z"]
     fn create_thread(j: u32, k: u32, i: u32) -> Weight {
-        (1_763_250_000 as Weight)
-            .saturating_add((122_000 as Weight).saturating_mul(j as Weight))
-            .saturating_add((171_000 as Weight).saturating_mul(k as Weight))
+        (1_988_301_000 as Weight)
+            .saturating_add((144_000 as Weight).saturating_mul(j as Weight))
+            .saturating_add((190_000 as Weight).saturating_mul(k as Weight))
             .saturating_add(DbWeight::get().reads(7 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(7 as Weight))
     }
     fn edit_thread_title(i: u32, j: u32) -> Weight {
-        (161_572_000 as Weight)
-            .saturating_add((72_014_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((127_000 as Weight).saturating_mul(j as Weight))
+        (249_076_000 as Weight)
+            .saturating_add((65_112_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((145_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
-    fn update_thread_archival_status_lead(i: u32) -> Weight {
-        (212_838_000 as Weight)
-            .saturating_add((116_257_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add(DbWeight::get().reads(4 as Weight))
-            .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
-            .saturating_add(DbWeight::get().writes(1 as Weight))
-    }
-    fn update_thread_archival_status_moderator(i: u32) -> Weight {
-        (237_385_000 as Weight)
-            .saturating_add((114_127_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add(DbWeight::get().reads(4 as Weight))
-            .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
-            .saturating_add(DbWeight::get().writes(1 as Weight))
-    }
     fn delete_thread(i: u32) -> Weight {
-        (592_486_000 as Weight)
-            .saturating_add((57_770_000 as Weight).saturating_mul(i as Weight))
+        (745_492_000 as Weight)
+            .saturating_add((61_494_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
-            .saturating_add(DbWeight::get().writes(4 as Weight))
+            .saturating_add(DbWeight::get().writes(102 as Weight))
     }
     fn move_thread_to_category_lead(i: u32) -> Weight {
-        (365_000_000 as Weight)
-            .saturating_add((100_941_000 as Weight).saturating_mul(i as Weight))
+        (392_377_000 as Weight)
+            .saturating_add((107_424_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(4 as Weight))
     }
     fn move_thread_to_category_moderator(i: u32) -> Weight {
-        (400_012_000 as Weight)
-            .saturating_add((101_980_000 as Weight).saturating_mul(i as Weight))
+        (429_980_000 as Weight)
+            .saturating_add((107_333_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(6 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(4 as Weight))
     }
     fn vote_on_poll(i: u32, j: u32) -> Weight {
-        (311_689_000 as Weight)
-            .saturating_add((57_977_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((18_453_000 as Weight).saturating_mul(j as Weight))
-            .saturating_add(DbWeight::get().reads(4 as Weight))
+        (331_092_000 as Weight)
+            .saturating_add((64_865_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((20_909_000 as Weight).saturating_mul(j as Weight))
+            .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
-            .saturating_add(DbWeight::get().writes(1 as Weight))
+            .saturating_add(DbWeight::get().writes(2 as Weight))
     }
-    // WARNING! Some components were not used: ["j"]
     fn moderate_thread_lead(i: u32, k: u32) -> Weight {
-        (533_448_000 as Weight)
-            .saturating_add((57_859_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((129_000 as Weight).saturating_mul(k as Weight))
+        (570_691_000 as Weight)
+            .saturating_add((63_690_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((142_000 as Weight).saturating_mul(k as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
-    fn moderate_thread_moderator(i: u32, j: u32, k: u32) -> Weight {
-        (343_909_000 as Weight)
-            .saturating_add((63_466_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((6_334_000 as Weight).saturating_mul(j as Weight))
-            .saturating_add((131_000 as Weight).saturating_mul(k as Weight))
+    fn moderate_thread_moderator(i: u32, k: u32) -> Weight {
+        (555_260_000 as Weight)
+            .saturating_add((65_443_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((143_000 as Weight).saturating_mul(k as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn add_post(i: u32, j: u32) -> Weight {
-        (584_267_000 as Weight)
-            .saturating_add((54_076_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((128_000 as Weight).saturating_mul(j as Weight))
+        (628_419_000 as Weight)
+            .saturating_add((59_569_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((145_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(6 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(5 as Weight))
     }
     fn react_post(i: u32) -> Weight {
-        (299_480_000 as Weight)
-            .saturating_add((57_223_000 as Weight).saturating_mul(i as Weight))
+        (330_603_000 as Weight)
+            .saturating_add((61_553_000 as Weight).saturating_mul(i as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
     }
     fn edit_post_text(i: u32, j: u32) -> Weight {
-        (387_494_000 as Weight)
-            .saturating_add((70_340_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((126_000 as Weight).saturating_mul(j as Weight))
+        (477_603_000 as Weight)
+            .saturating_add((63_656_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((145_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(4 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn moderate_post_lead(i: u32, j: u32) -> Weight {
-        (1_094_423_000 as Weight)
-            .saturating_add((103_781_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((121_000 as Weight).saturating_mul(j as Weight))
+        (1_061_737_000 as Weight)
+            .saturating_add((125_999_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((142_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(6 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn moderate_post_moderator(i: u32, j: u32) -> Weight {
-        (863_056_000 as Weight)
-            .saturating_add((134_282_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((126_000 as Weight).saturating_mul(j as Weight))
+        (992_903_000 as Weight)
+            .saturating_add((134_194_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((145_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(6 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn delete_posts(i: u32, j: u32, k: u32) -> Weight {
         (0 as Weight)
-            .saturating_add((1_007_340_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((113_000 as Weight).saturating_mul(j as Weight))
-            .saturating_add((1_418_940_000 as Weight).saturating_mul(k as Weight))
+            .saturating_add((30_679_118_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((27_000 as Weight).saturating_mul(j as Weight))
+            .saturating_add((1_545_369_000 as Weight).saturating_mul(k as Weight))
             .saturating_add(DbWeight::get().reads(5 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight)))
@@ -182,18 +166,18 @@ impl forum::WeightInfo for WeightInfo {
             .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight)))
     }
     fn set_stickied_threads_lead(i: u32, j: u32) -> Weight {
-        (219_049_000 as Weight)
-            .saturating_add((59_817_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((204_099_000 as Weight).saturating_mul(j as Weight))
+        (0 as Weight)
+            .saturating_add((103_175_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((232_740_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(j as Weight)))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn set_stickied_threads_moderator(i: u32, j: u32) -> Weight {
-        (281_825_000 as Weight)
-            .saturating_add((47_851_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add((203_487_000 as Weight).saturating_mul(j as Weight))
+        (20_591_000 as Weight)
+            .saturating_add((72_609_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add((233_007_000 as Weight).saturating_mul(j as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(i as Weight)))
             .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(j as Weight)))