Browse Source

addressed bug when dealing with bags during deletion

ignazio-bovo 3 years ago
parent
commit
12e5b5fcae

+ 24 - 21
runtime-modules/content/src/lib.rs

@@ -747,28 +747,31 @@ decl_module! {
             let dyn_bag = DynamicBagIdType::<T::MemberId, T::ChannelId>::Channel(channel_id);
             let bag_id = storage::BagIdType::from(dyn_bag.clone());
 
-            // ensure that bag size provided is valid
-            ensure!(
-                storage::Bags::<T>::get(&bag_id).objects_number == num_objects_to_delete,
-                Error::<T>::InvalidBagSizeSpecified
-            );
-
-            // construct collection of assets to be removed
-            let assets_to_remove: BTreeSet<DataObjectId<T>> =
-                storage::DataObjectsById::<T>::iter_prefix(&bag_id).map(|x| x.0).collect();
-
-            // remove specified assets from storage
-            Self::remove_assets_from_storage(
-                &assets_to_remove,
-                &channel_id,
-                &channel.deletion_prize_source_account_id
-            )?;
+            // channel has a dynamic bag associated to it -> remove assets from storage
+            if let Ok(bag) = Storage::<T>::ensure_bag_exists(&bag_id) {
+                // ensure that bag size provided is valid
+                ensure!(
+                    bag.objects_number == num_objects_to_delete,
+                    Error::<T>::InvalidBagSizeSpecified
+                );
+
+                // construct collection of assets to be removed
+                let assets_to_remove: BTreeSet<DataObjectId<T>> =
+                    storage::DataObjectsById::<T>::iter_prefix(&bag_id).map(|x| x.0).collect();
+
+                // remove specified assets from storage
+                Self::remove_assets_from_storage(
+                    &assets_to_remove,
+                    &channel_id,
+                    &channel.deletion_prize_source_account_id
+                )?;
 
-            // delete channel dynamic bag
-            Storage::<T>::delete_dynamic_bag(
-                channel.deletion_prize_source_account_id,
-                dyn_bag
-            )?;
+                // delete channel dynamic bag
+                Storage::<T>::delete_dynamic_bag(
+                    channel.deletion_prize_source_account_id,
+                    dyn_bag
+                )?;
+            }
 
             //
             // == MUTATION SAFE ==

+ 20 - 0
runtime-modules/content/src/tests/channels.rs

@@ -68,6 +68,26 @@ fn successful_channel_deletion() {
             3u64,
             Ok(()),
         );
+
+        // create a channel with no assets:
+        let empty_channel_id = Content::next_channel_id();
+        create_channel_mock(
+            FIRST_MEMBER_ORIGIN,
+            ContentActor::Member(FIRST_MEMBER_ID),
+            ChannelCreationParametersRecord {
+                assets: None,
+                meta: None,
+                reward_account: None,
+            },
+            Ok(()),
+        );
+        delete_channel_mock(
+            FIRST_MEMBER_ORIGIN,
+            ContentActor::Member(FIRST_MEMBER_ID),
+            empty_channel_id,
+            43u64, // this param will be discarded if channel has no assets
+            Ok(()),
+        );
     })
 }
 

+ 1 - 1
runtime-modules/storage/src/lib.rs

@@ -3419,7 +3419,7 @@ impl<T: Trait> Module<T> {
     }
 
     // Check the dynamic bag existence. Static bags always exist.
-    fn ensure_bag_exists(bag_id: &BagId<T>) -> Result<Bag<T>, DispatchError> {
+    pub fn ensure_bag_exists(bag_id: &BagId<T>) -> Result<Bag<T>, DispatchError> {
         if let BagId::<T>::Dynamic(_) = &bag_id {
             ensure!(
                 <Bags<T>>::contains_key(&bag_id),