Browse Source

runtime: storage: Add extrinsic.

- delete_distribution_bucket_family
Shamil Gadelshin 3 years ago
parent
commit
3641b1b99a

+ 45 - 3
runtime-modules/storage/src/lib.rs

@@ -54,6 +54,8 @@
 //! #### Distribution working group leader extrinsics
 //! - [create_distribution_bucket_family](./struct.Module.html#method.create_distribution_bucket_family) -
 //! creates distribution bucket family.
+//! - [delete_distribution_bucket_family](./struct.Module.html#method.delete_distribution_bucket_family) -
+//! deletes distribution bucket family.
 //!
 //! #### Public methods
 //! Public integration methods are exposed via the [DataObjectStorage](./trait.DataObjectStorage.html)
@@ -978,11 +980,15 @@ decl_event! {
         /// - new number of storage buckets
         NumberOfStorageBucketsInDynamicBagCreationPolicyUpdated(DynamicBagType, u64),
 
-        /// Emits on updating the number of storage buckets in dynamic bag creation policy.
+        /// Emits on creating distribution bucket family.
         /// Params
-        /// - dynamic bag type
-        /// - new number of storage buckets
+        /// - distribution family bucket ID
         DistributionBucketFamilyCreated(DistributionBucketFamilyId),
+
+        /// Emits on deleting distribution bucket family.
+        /// Params
+        /// - distribution family bucket ID
+        DistributionBucketFamilyDeleted(DistributionBucketFamilyId),
     }
 }
 
@@ -1102,6 +1108,9 @@ decl_error! {
 
         /// Max distribution bucket family number limit exceeded.
         MaxDistributionBucketFamilyNumberLimitExceeded,
+
+        /// Distribution bucket family doesn't exist.
+        DistributionBucketFamilyDoesntExist,
     }
 }
 
@@ -1697,6 +1706,26 @@ decl_module! {
 
             Self::deposit_event(RawEvent::DistributionBucketFamilyCreated(family_id));
         }
+
+        /// Deletes a distribution family.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_distribution_bucket_family(origin, family_id: T::DistributionBucketFamilyId) {
+            T::ensure_distribution_working_group_leader_origin(origin)?;
+
+            Self::ensure_distribution_bucket_family_exists(&family_id)?;
+
+            // TODO: check for emptiness
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            Self::decrement_distribution_family_number();
+
+            <DistributionBucketFamilyById<T>>::remove(family_id);
+
+            Self::deposit_event(RawEvent::DistributionBucketFamilyDeleted(family_id));
+        }
     }
 }
 
@@ -2510,4 +2539,17 @@ impl<T: Trait> Module<T> {
 
         Ok(())
     }
+
+    // Ensures the existence of the distribution bucket family.
+    // Returns the DistributionBucketFamily object or error.
+    fn ensure_distribution_bucket_family_exists(
+        family_id: &T::DistributionBucketFamilyId,
+    ) -> Result<DistributionBucketFamily<T::DistributionBucketId>, Error<T>> {
+        ensure!(
+            <DistributionBucketFamilyById<T>>::contains_key(family_id),
+            Error::<T>::DistributionBucketFamilyDoesntExist
+        );
+
+        Ok(Self::distribution_bucket_family_by_id(family_id))
+    }
 }

+ 38 - 0
runtime-modules/storage/src/tests/fixtures.rs

@@ -1228,3 +1228,41 @@ impl CreateDistributionBucketBucketFamilyFixture {
         }
     }
 }
+
+pub struct DeleteDistributionBucketBucketFamilyFixture {
+    origin: RawOrigin<u64>,
+    family_id: u64,
+}
+
+impl DeleteDistributionBucketBucketFamilyFixture {
+    pub fn default(family_id: u64) -> Self {
+        Self {
+            origin: RawOrigin::Signed(DEFAULT_ACCOUNT_ID),
+            family_id,
+        }
+    }
+
+    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
+        Self { origin, ..self }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let family_number = Storage::distribution_bucket_family_number();
+        let actual_result =
+            Storage::delete_distribution_bucket_family(self.origin.clone().into(), self.family_id);
+
+        assert_eq!(actual_result, expected_result);
+
+        if actual_result.is_ok() {
+            assert_eq!(
+                family_number - 1,
+                Storage::distribution_bucket_family_number()
+            );
+            assert!(!<crate::DistributionBucketFamilyById<Test>>::contains_key(
+                self.family_id
+            ));
+        } else {
+            assert_eq!(family_number, Storage::distribution_bucket_family_number());
+        }
+    }
+}

+ 41 - 0
runtime-modules/storage/src/tests/mod.rs

@@ -3528,3 +3528,44 @@ fn create_distribution_bucket_family_fails_with_exceeding_family_number_limit()
             ));
     });
 }
+
+#[test]
+fn delete_distribution_bucket_family_succeeded() {
+    build_test_externalities().execute_with(|| {
+        let starting_block = 1;
+        run_to_block(starting_block);
+
+        let family_id = CreateDistributionBucketBucketFamilyFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+
+        DeleteDistributionBucketBucketFamilyFixture::default(family_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()));
+
+        EventFixture::assert_last_crate_event(RawEvent::DistributionBucketFamilyDeleted(family_id));
+    });
+}
+
+#[test]
+fn delete_distribution_bucket_family_fails_with_non_signed_origin() {
+    build_test_externalities().execute_with(|| {
+        let invalid_family_id = 100;
+        DeleteDistributionBucketBucketFamilyFixture::default(invalid_family_id)
+            .with_origin(RawOrigin::None)
+            .call_and_assert(Err(DispatchError::BadOrigin));
+    });
+}
+
+#[test]
+fn delete_distribution_bucket_family_fails_with_non_existing_family() {
+    build_test_externalities().execute_with(|| {
+        let invalid_family_id = 100;
+        DeleteDistributionBucketBucketFamilyFixture::default(invalid_family_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Err(
+                Error::<Test>::DistributionBucketFamilyDoesntExist.into()
+            ));
+    });
+}