Browse Source

runtime: storage: Add extrinsic.

- add `update_distribution_bucket_status` extrinsic
Shamil Gadelshin 3 years ago
parent
commit
a3c6d72712

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

@@ -58,6 +58,8 @@
 //! deletes distribution bucket family.
 //! - [create_distribution_bucket](./struct.Module.html#method.create_distribution_bucket) -
 //! creates distribution bucket.
+//! - [update_distribution_bucket_status](./struct.Module.html#method.update_distribution_bucket_status) -
+//! updates distribution bucket status (accepting new bags).
 //!
 //! #### Public methods
 //! Public integration methods are exposed via the [DataObjectStorage](./trait.DataObjectStorage.html)
@@ -1005,6 +1007,13 @@ decl_event! {
         /// - accepting new bags
         /// - distribution bucket ID
         DistributionBucketCreated(DistributionBucketFamilyId, bool, DistributionBucketId),
+
+        /// Emits on storage bucket status update.
+        /// Params
+        /// - distribution bucket family ID
+        /// - distribution bucket ID
+        /// - new status (accepting new bags)
+        DistributionBucketStatusUpdated(DistributionBucketFamilyId, DistributionBucketId, bool),
     }
 }
 
@@ -1130,6 +1139,9 @@ decl_error! {
 
         /// Max distribution bucket number per family limit exceeded.
         MaxDistributionBucketNumberPerFamilyLimitExceeded,
+
+        /// Distribution bucket doesn't exist.
+        DistributionBucketDoesntExist,
     }
 }
 
@@ -1651,7 +1663,7 @@ decl_module! {
             );
         }
 
-        /// Update whether new bags are being accepted for storage.
+        /// Update whether a bucket accepts new bags for storage.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_storage_bucket_status(
             origin,
@@ -1756,6 +1768,7 @@ decl_module! {
             origin,
             family_id: T::DistributionBucketFamilyId,
             accepting_new_bags: bool,
+            // TODO: invited ?
         ) {
             T::ensure_distribution_working_group_leader_origin(origin)?;
 
@@ -1787,6 +1800,45 @@ decl_module! {
                 RawEvent::DistributionBucketCreated(family_id, accepting_new_bags, bucket_id)
             );
         }
+
+        /// Update whether a bucket accepts new bags for distribution.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_distribution_bucket_status(
+            origin,
+            family_id: T::DistributionBucketFamilyId,
+            distribution_bucket_id: T::DistributionBucketId,
+            accepting_new_bags: bool
+        ) {
+            T::ensure_distribution_working_group_leader_origin(origin)?;
+
+            let mut family = Self::ensure_distribution_bucket_family_exists(&family_id)?;
+            let mut bucket = Self::ensure_distribution_bucket_exists(
+                &family,
+                &distribution_bucket_id
+            )?;
+
+            //TODO: Self::ensure_bucket_invitation_accepted(&bucket, worker_id)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            bucket.accepting_new_bags = accepting_new_bags;
+            family.distribution_buckets.insert(distribution_bucket_id, bucket);
+
+            <DistributionBucketFamilyById<T>>::insert(family_id, family);
+
+            Self::deposit_event(
+                RawEvent::DistributionBucketStatusUpdated(
+                    family_id,
+                    distribution_bucket_id,
+                    accepting_new_bags
+                )
+            );
+        }
+
+        // ===== Distribution Operator actions =====
+
     }
 }
 
@@ -2613,4 +2665,17 @@ impl<T: Trait> Module<T> {
 
         Ok(Self::distribution_bucket_family_by_id(family_id))
     }
+
+    // Ensures the existence of the distribution bucket.
+    // Returns the DistributionBucket object or error.
+    fn ensure_distribution_bucket_exists(
+        family: &DistributionBucketFamily<T::DistributionBucketId>,
+        distribution_bucket_id: &T::DistributionBucketId,
+    ) -> Result<DistributionBucket, Error<T>> {
+        family
+            .distribution_buckets
+            .get(distribution_bucket_id)
+            .cloned()
+            .ok_or(Error::<T>::DistributionBucketDoesntExist)
+    }
 }

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

@@ -1330,3 +1330,40 @@ impl CreateDistributionBucketFixture {
         }
     }
 }
+
+pub struct UpdateDistributionBucketStatusFixture {
+    origin: RawOrigin<u64>,
+    family_id: u64,
+    distribution_bucket_id: u64,
+    new_status: bool,
+}
+
+impl UpdateDistributionBucketStatusFixture {
+    pub fn default(family_id: u64, bucket_id: u64) -> Self {
+        Self {
+            origin: RawOrigin::Signed(DEFAULT_MEMBER_ACCOUNT_ID),
+            family_id,
+            distribution_bucket_id: bucket_id,
+            new_status: false,
+        }
+    }
+
+    pub fn with_origin(self, origin: RawOrigin<u64>) -> Self {
+        Self { origin, ..self }
+    }
+
+    pub fn with_new_status(self, new_status: bool) -> Self {
+        Self { new_status, ..self }
+    }
+
+    pub fn call_and_assert(&self, expected_result: DispatchResult) {
+        let actual_result = Storage::update_distribution_bucket_status(
+            self.origin.clone().into(),
+            self.family_id,
+            self.distribution_bucket_id,
+            self.new_status,
+        );
+
+        assert_eq!(actual_result, expected_result);
+    }
+}

+ 70 - 2
runtime-modules/storage/src/tests/mod.rs

@@ -25,10 +25,9 @@ use mocks::{
     InitialStorageBucketsNumberForDynamicBag, MaxNumberOfDataObjectsPerBag,
     MaxRandomIterationNumber, MaxStorageBucketNumber, Storage, Test, ANOTHER_STORAGE_PROVIDER_ID,
     DEFAULT_MEMBER_ACCOUNT_ID, DEFAULT_MEMBER_ID, DEFAULT_STORAGE_PROVIDER_ACCOUNT_ID,
-    DEFAULT_STORAGE_PROVIDER_ID, STORAGE_WG_LEADER_ACCOUNT_ID,
+    DEFAULT_STORAGE_PROVIDER_ID, DISTRIBUTION_WG_LEADER_ACCOUNT_ID, STORAGE_WG_LEADER_ACCOUNT_ID,
 };
 
-use crate::tests::mocks::DISTRIBUTION_WG_LEADER_ACCOUNT_ID;
 use fixtures::*;
 
 #[test]
@@ -3638,3 +3637,72 @@ fn create_distribution_bucket_fails_with_exceeding_max_bucket_number() {
             ));
     });
 }
+
+#[test]
+fn update_distribution_bucket_status_succeeded() {
+    build_test_externalities().execute_with(|| {
+        let starting_block = 1;
+        run_to_block(starting_block);
+
+        let family_id = CreateDistributionBucketFamilyFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+
+        let bucket_id = CreateDistributionBucketFixture::default(family_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+
+        let new_status = true;
+        UpdateDistributionBucketStatusFixture::default(family_id, bucket_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .with_new_status(new_status)
+            .call_and_assert(Ok(()));
+
+        EventFixture::assert_last_crate_event(RawEvent::DistributionBucketStatusUpdated(
+            family_id, bucket_id, new_status,
+        ));
+    });
+}
+
+#[test]
+fn update_distribution_bucket_status_fails_with_invalid_origin() {
+    build_test_externalities().execute_with(|| {
+        let invalid_family_id = 111;
+        let invalid_bucket_id = 111;
+
+        UpdateDistributionBucketStatusFixture::default(invalid_family_id, invalid_bucket_id)
+            .with_origin(RawOrigin::Root)
+            .call_and_assert(Err(DispatchError::BadOrigin));
+    });
+}
+
+#[test]
+fn update_distribution_bucket_status_fails_with_invalid_distribution_bucket() {
+    build_test_externalities().execute_with(|| {
+        let family_id = CreateDistributionBucketFamilyFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+        let invalid_bucket_id = 111;
+
+        UpdateDistributionBucketStatusFixture::default(family_id, invalid_bucket_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Err(Error::<Test>::DistributionBucketDoesntExist.into()));
+    });
+}
+
+#[test]
+fn update_distribution_bucket_status_fails_with_invalid_distribution_bucket_family() {
+    build_test_externalities().execute_with(|| {
+        let invalid_family_id = 111;
+        let invalid_bucket_id = 111;
+
+        UpdateDistributionBucketStatusFixture::default(invalid_family_id, invalid_bucket_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Err(
+                Error::<Test>::DistributionBucketFamilyDoesntExist.into()
+            ));
+    });
+}