Browse Source

runtime: blog: update benchmarking and fail fast for delete replies

conectado 3 years ago
parent
commit
415dd43a63

+ 13 - 13
runtime-modules/blog/src/benchmarking.rs

@@ -94,14 +94,14 @@ fn handle_from_id<T: membership::Trait>(id: u32) -> Vec<u8> {
     handle
 }
 
-fn generate_post<T: Trait<I>, I: Instance>() -> PostId {
-    assert_eq!(Blog::<T, I>::post_count(), 0);
+fn generate_post<T: Trait<I>, I: Instance>(seq_num: u64) -> PostId {
+    assert_eq!(Blog::<T, I>::post_count(), seq_num);
 
     Blog::<T, I>::create_post(RawOrigin::Root.into(), vec![0u8], vec![0u8]).unwrap();
 
-    let post_id = 0;
+    let post_id = seq_num;
 
-    assert_eq!(Blog::<T, I>::post_count(), 1);
+    assert_eq!(Blog::<T, I>::post_count(), seq_num + 1);
 
     assert_eq!(
         Blog::<T, I>::post_by_id(post_id),
@@ -170,7 +170,7 @@ benchmarks_instance! {
     }
 
     lock_post {
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
     }: _(RawOrigin::Root, post_id)
     verify {
         assert!(Blog::<T, I>::post_by_id(post_id).is_locked());
@@ -178,7 +178,7 @@ benchmarks_instance! {
     }
 
     unlock_post {
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
         Blog::<T, I>::lock_post(RawOrigin::Root.into(), post_id).unwrap();
         assert!(Blog::<T, I>::post_by_id(post_id).is_locked());
     }: _(RawOrigin::Root, post_id)
@@ -191,7 +191,7 @@ benchmarks_instance! {
         let t in 0 .. MAX_BYTES;
         let b in 0 .. MAX_BYTES;
 
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
         let title = Some(vec![1u8; t.try_into().unwrap()]);
         let body = Some(vec![1u8; b.try_into().unwrap()]);
     }: _(RawOrigin::Root, post_id, title.clone(), body.clone())
@@ -206,7 +206,7 @@ benchmarks_instance! {
     create_reply_to_post {
         let t in 0 .. MAX_BYTES;
 
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
         let (account_id, participant_id) = member_funded_account::<T, I>("caller", 0);
         let origin = RawOrigin::Signed(account_id);
         let text = vec![0u8; t.try_into().unwrap()];
@@ -239,7 +239,7 @@ benchmarks_instance! {
     create_reply_to_reply {
         let t in 0 .. MAX_BYTES;
 
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
         let (account_id, participant_id) = member_funded_account::<T, I>("caller", 0);
         let reply_id = generate_reply::<T, I>(account_id.clone(), participant_id, post_id.clone());
         let origin = RawOrigin::Signed(account_id);
@@ -276,7 +276,7 @@ benchmarks_instance! {
     edit_reply {
         let t in 0 .. MAX_BYTES;
 
-        let post_id = generate_post::<T, I>();
+        let post_id = generate_post::<T, I>(0);
         let (account_id, participant_id) = member_funded_account::<T, I>("caller", 0);
         let reply_id = generate_reply::<T, I>(account_id.clone(), participant_id, post_id.clone());
         let origin = RawOrigin::Signed(account_id);
@@ -306,13 +306,13 @@ benchmarks_instance! {
     }
 
     delete_replies {
-        let i in 0 .. 100;
-        let post_id = generate_post::<T, I>();
+        let i in 1 .. T::PostsMaxNumber::get().try_into().unwrap();
         let (account_id, participant_id) = member_funded_account::<T, I>("caller", 0);
         let mut replies = Vec::new();
         let hide = false;
 
-        for _ in 0..=i {
+        for seq_num in 0..i {
+            let post_id = generate_post::<T, I>(seq_num.into());
             let reply_id =
                 generate_reply::<T, I>(account_id.clone(), participant_id, post_id.clone());
             replies.push(ReplyToDelete {post_id, reply_id, hide});

+ 5 - 1
runtime-modules/blog/src/errors.rs

@@ -29,6 +29,10 @@ decl_error! {
         InvalidReactionIndex,
 
         /// Insuficient balance for reply creation
-        InsufficientBalanceForReply
+        InsufficientBalanceForReply,
+
+        /// This error represent the invalid state where there is not enough funds in a post
+        /// account to pay off its delete
+        InsufficientBalanceInPostAccount,
     }
 }

+ 20 - 5
runtime-modules/blog/src/lib.rs

@@ -50,6 +50,7 @@ use sp_runtime::{
     traits::{AccountIdConversion, Hash, MaybeSerialize, Member, Saturating},
     ModuleId,
 };
+use sp_std::collections::btree_map::BTreeMap;
 use sp_std::prelude::*;
 
 mod benchmarking;
@@ -656,7 +657,7 @@ decl_module! {
         /// `O (R)` where
         /// - R is the number of replies to be deleted
         /// - DB:
-        ///    - O(1) doesn't depend on the state or parameters
+        ///    - O(R)
         /// # </weight>
         #[weight = BlogWeightInfo::<T, I>::delete_replies(replies.len().saturated_into())]
         pub fn delete_replies(
@@ -667,6 +668,7 @@ decl_module! {
             let account_id = Self::ensure_valid_participant(origin, participant_id)?;
 
             let mut erase_replies = Vec::new();
+            let mut pay_off_map = BTreeMap::new();
             for ReplyToDelete { post_id, reply_id, hide } in replies {
                 // Ensure post with given id exists
                 let post = Self::ensure_post_exists(post_id)?;
@@ -688,9 +690,20 @@ decl_module! {
                     ensure!(!hide, Error::<T, I>::ReplyOwnershipError);
                 }
 
+                *pay_off_map.entry(post_id).or_default() += reply.cleanup_pay_off;
                 erase_replies.push((post_id, reply_id, reply.cleanup_pay_off, hide));
             }
 
+            for (post_id, post_deposit) in pay_off_map.into_iter() {
+                ensure!(
+                    Balances::<T>::usable_balance(
+                        &Self::get_treasury_account(post_id)
+                    ) >= post_deposit,
+                    Error::<T, I>::InsufficientBalanceInPostAccount
+
+                );
+            }
+
             //
             // == MUTATION SAFE ==
             //
@@ -711,10 +724,13 @@ decl_module! {
 }
 
 impl<T: Trait<I>, I: Instance> Module<T, I> {
+    fn get_treasury_account(post_id: PostId) -> T::AccountId {
+        T::ModuleId::get().into_sub_account(post_id)
+    }
+
     fn pay_off(post_id: PostId, amount: BalanceOf<T>, account_id: &T::AccountId) -> DispatchResult {
-        let state_cleanup_treasury_account = T::ModuleId::get().into_sub_account(post_id);
         <Balances<T> as Currency<T::AccountId>>::transfer(
-            &state_cleanup_treasury_account,
+            &Self::get_treasury_account(post_id),
             account_id,
             amount,
             ExistenceRequirement::AllowDeath,
@@ -726,10 +742,9 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         post_id: PostId,
         account_id: &T::AccountId,
     ) -> DispatchResult {
-        let state_cleanup_treasury_account = T::ModuleId::get().into_sub_account(post_id);
         <Balances<T> as Currency<T::AccountId>>::transfer(
             account_id,
-            &state_cleanup_treasury_account,
+            &Self::get_treasury_account(post_id),
             amount,
             ExistenceRequirement::AllowDeath,
         )

+ 19 - 18
runtime/src/weights/blog.rs

@@ -8,51 +8,52 @@ use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight};
 pub struct WeightInfo;
 impl blog::WeightInfo for WeightInfo {
     fn create_post(t: u32, b: u32) -> Weight {
-        (317_873_000 as Weight)
-            .saturating_add((92_000 as Weight).saturating_mul(t as Weight))
-            .saturating_add((129_000 as Weight).saturating_mul(b as Weight))
+        (496_105_000 as Weight)
+            .saturating_add((88_000 as Weight).saturating_mul(t as Weight))
+            .saturating_add((150_000 as Weight).saturating_mul(b as Weight))
             .saturating_add(DbWeight::get().reads(1 as Weight))
             .saturating_add(DbWeight::get().writes(2 as Weight))
     }
     fn lock_post() -> Weight {
-        (160_756_000 as Weight)
+        (169_763_000 as Weight)
             .saturating_add(DbWeight::get().reads(1 as Weight))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn unlock_post() -> Weight {
-        (158_932_000 as Weight)
+        (169_042_000 as Weight)
             .saturating_add(DbWeight::get().reads(1 as Weight))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn edit_post(t: u32, b: u32) -> Weight {
-        (384_273_000 as Weight)
-            .saturating_add((95_000 as Weight).saturating_mul(t as Weight))
-            .saturating_add((131_000 as Weight).saturating_mul(b as Weight))
+        (561_965_000 as Weight)
+            .saturating_add((94_000 as Weight).saturating_mul(t as Weight))
+            .saturating_add((134_000 as Weight).saturating_mul(b as Weight))
             .saturating_add(DbWeight::get().reads(1 as Weight))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn create_reply_to_post(t: u32) -> Weight {
-        (591_784_000 as Weight)
-            .saturating_add((161_000 as Weight).saturating_mul(t as Weight))
+        (581_402_000 as Weight)
+            .saturating_add((189_000 as Weight).saturating_mul(t as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn create_reply_to_reply(t: u32) -> Weight {
-        (508_330_000 as Weight)
-            .saturating_add((160_000 as Weight).saturating_mul(t as Weight))
+        (532_869_000 as Weight)
+            .saturating_add((187_000 as Weight).saturating_mul(t as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().writes(3 as Weight))
     }
     fn edit_reply(t: u32) -> Weight {
-        (281_077_000 as Weight)
-            .saturating_add((160_000 as Weight).saturating_mul(t as Weight))
+        (327_078_000 as Weight)
+            .saturating_add((192_000 as Weight).saturating_mul(t as Weight))
             .saturating_add(DbWeight::get().reads(3 as Weight))
             .saturating_add(DbWeight::get().writes(1 as Weight))
     }
     fn delete_replies(i: u32) -> Weight {
-        (492_001_000 as Weight)
-            .saturating_add((352_154_000 as Weight).saturating_mul(i as Weight))
-            .saturating_add(DbWeight::get().reads(4 as Weight))
-            .saturating_add(DbWeight::get().writes(2 as Weight))
+        (93_653_000 as Weight)
+            .saturating_add((446_908_000 as Weight).saturating_mul(i as Weight))
+            .saturating_add(DbWeight::get().reads(1 as Weight))
+            .saturating_add(DbWeight::get().reads((3 as Weight).saturating_mul(i as Weight)))
+            .saturating_add(DbWeight::get().writes((2 as Weight).saturating_mul(i as Weight)))
     }
 }