Browse Source

runtime: storage: Add constant.

- add `MaxNumberOfPendingInvitationsPerDistributionBucket`
Shamil Gadelshin 3 years ago
parent
commit
eb6d409167

+ 18 - 4
runtime-modules/storage/src/lib.rs

@@ -103,7 +103,8 @@
 //! - DefaultChannelDynamicBagCreationPolicy
 //! - MaxDistributionBucketFamilyNumber
 //! - MaxDistributionBucketNumberPerFamily
-//!
+//! - DistributionBucketsPerBagValueConstraint
+//! - MaxNumberOfPendingInvitationsPerDistributionBucket
 
 // Compiler demand.
 #![recursion_limit = "256"]
@@ -142,10 +143,7 @@ use common::working_group::WorkingGroup;
 use distribution_bucket_picker::DistributionBucketPicker;
 use storage_bucket_picker::StorageBucketPicker;
 
-// TODO: constants
-// Max number of pending invitations per distribution bucket.
 // TODO: mut in extrinsics
-// TODO: dynamic bag creation - distributed buckets
 
 // TODO:
 // How to be sure that we don't have already accepted invitation? We need to have it in the bucket
@@ -318,6 +316,9 @@ pub trait Trait: frame_system::Trait + balances::Trait + membership::Trait {
     /// Defines max allowed distribution bucket number per family.
     type MaxDistributionBucketNumberPerFamily: Get<u64>;
 
+    /// Max number of pending invitations per distribution bucket.
+    type MaxNumberOfPendingInvitationsPerDistributionBucket: Get<u64>;
+
     /// Demand the storage working group leader authorization.
     /// TODO: Refactor after merging with the Olympia release.
     fn ensure_storage_working_group_leader_origin(origin: Self::Origin) -> DispatchResult;
@@ -1332,6 +1333,9 @@ decl_error! {
 
         /// Invalid operations: must be a distribution provider operator for a bucket.
         MustBeDistributionProviderOperatorForBucket,
+
+        /// Max number of pending invitations limit for a distribution bucket reached.
+        MaxNumberOfPendingInvitationsLimitForDistributionBucketReached,
     }
 }
 
@@ -1378,6 +1382,10 @@ decl_module! {
         const DistributionBucketsPerBagValueConstraint: StorageBucketsPerBagValueConstraint =
             T::DistributionBucketsPerBagValueConstraint::get();
 
+        /// Exports const - max number of pending invitations per distribution bucket.
+        const MaxNumberOfPendingInvitationsPerDistributionBucket: u64 =
+            T::MaxNumberOfPendingInvitationsPerDistributionBucket::get();
+
         // ===== Storage Lead actions =====
 
         /// Delete storage bucket. Must be empty. Storage operator must be missing.
@@ -3358,6 +3366,12 @@ impl<T: Trait> Module<T> {
             Error::<T>::DistributionProviderOperatorAlreadySet
         );
 
+        ensure!(
+            bucket.pending_invitations.len().saturated_into::<u64>()
+                < T::MaxNumberOfPendingInvitationsPerDistributionBucket::get(),
+            Error::<T>::MaxNumberOfPendingInvitationsLimitForDistributionBucketReached
+        );
+
         Ok(())
     }
 }

+ 3 - 0
runtime-modules/storage/src/tests/mocks.rs

@@ -56,6 +56,7 @@ parameter_types! {
     pub const DataObjectDeletionPrize: u64 = 10;
     pub const StorageModuleId: ModuleId = ModuleId(*b"mstorage"); // module storage
     pub const BlacklistSizeLimit: u64 = 1;
+    pub const MaxNumberOfPendingInvitationsPerDistributionBucket: u64 = 1;
     pub const StorageBucketsPerBagValueConstraint: crate::StorageBucketsPerBagValueConstraint =
         crate::StorageBucketsPerBagValueConstraint {min: 3, max_min_diff: 7};
     pub const InitialStorageBucketsNumberForDynamicBag: u64 = 3;
@@ -98,6 +99,8 @@ impl crate::Trait for Test {
     type MaxDistributionBucketFamilyNumber = MaxDistributionBucketFamilyNumber;
     type MaxDistributionBucketNumberPerFamily = MaxDistributionBucketNumberPerFamily;
     type DistributionBucketsPerBagValueConstraint = DistributionBucketsPerBagValueConstraint;
+    type MaxNumberOfPendingInvitationsPerDistributionBucket =
+        MaxNumberOfPendingInvitationsPerDistributionBucket;
 
     fn ensure_storage_working_group_leader_origin(origin: Self::Origin) -> DispatchResult {
         let account_id = ensure_signed(origin)?;

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

@@ -26,13 +26,13 @@ use mocks::{
     DefaultChannelDynamicBagNumberOfStorageBuckets, DefaultMemberDynamicBagNumberOfStorageBuckets,
     InitialStorageBucketsNumberForDynamicBag, MaxDistributionBucketFamilyNumber,
     MaxDistributionBucketNumberPerFamily, MaxNumberOfDataObjectsPerBag, MaxRandomIterationNumber,
-    MaxStorageBucketNumber, Storage, Test, ANOTHER_STORAGE_PROVIDER_ID,
+    MaxStorageBucketNumber, Storage, Test, ANOTHER_DISTRIBUTION_PROVIDER_ID,
+    ANOTHER_STORAGE_PROVIDER_ID, DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID,
     DEFAULT_DISTRIBUTION_PROVIDER_ID, DEFAULT_MEMBER_ACCOUNT_ID, DEFAULT_MEMBER_ID,
     DEFAULT_STORAGE_PROVIDER_ACCOUNT_ID, DEFAULT_STORAGE_PROVIDER_ID,
     DISTRIBUTION_WG_LEADER_ACCOUNT_ID, STORAGE_WG_LEADER_ACCOUNT_ID,
 };
 
-use crate::tests::mocks::DEFAULT_DISTRIBUTION_PROVIDER_ACCOUNT_ID;
 use fixtures::*;
 
 #[test]
@@ -4278,6 +4278,42 @@ fn invite_distribution_bucket_operator_fails_with_non_missing_invitation() {
     });
 }
 
+#[test]
+fn invite_distribution_bucket_operator_fails_with_exceeding_the_limit_of_pending_invitations() {
+    build_test_externalities().execute_with(|| {
+        let invited_worker_id = DEFAULT_DISTRIBUTION_PROVIDER_ID;
+        let another_worker_id = ANOTHER_DISTRIBUTION_PROVIDER_ID;
+
+        let family_id = CreateDistributionBucketFamilyFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+
+        let bucket_id = CreateDistributionBucketFixture::default()
+            .with_family_id(family_id)
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .call_and_assert(Ok(()))
+            .unwrap();
+
+        InviteDistributionBucketOperatorFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .with_bucket_id(bucket_id)
+            .with_family_id(family_id)
+            .with_operator_worker_id(invited_worker_id)
+            .call_and_assert(Ok(()));
+
+        InviteDistributionBucketOperatorFixture::default()
+            .with_origin(RawOrigin::Signed(DISTRIBUTION_WG_LEADER_ACCOUNT_ID))
+            .with_bucket_id(bucket_id)
+            .with_family_id(family_id)
+            .with_operator_worker_id(another_worker_id)
+            .call_and_assert(Err(
+                Error::<Test>::MaxNumberOfPendingInvitationsLimitForDistributionBucketReached
+                    .into(),
+            ));
+    });
+}
+
 #[test]
 fn invite_distribution_bucket_operator_fails_with_invalid_distribution_provider_id() {
     build_test_externalities().execute_with(|| {

+ 3 - 0
runtime/src/lib.rs

@@ -658,6 +658,7 @@ parameter_types! {
     pub const DataObjectDeletionPrize: Balance = 10; //TODO: adjust value
     pub const BlacklistSizeLimit: u64 = 10000; //TODO: adjust value
     pub const MaxRandomIterationNumber: u64 = 30; //TODO: adjust value
+    pub const MaxNumberOfPendingInvitationsPerDistributionBucket: u64 = 30; //TODO: adjust value
     pub const StorageModuleId: ModuleId = ModuleId(*b"mstorage"); // module storage
     pub const StorageBucketsPerBagValueConstraint: storage::StorageBucketsPerBagValueConstraint =
         storage::StorageBucketsPerBagValueConstraint {min: 3, max_min_diff: 7}; //TODO: adjust value
@@ -690,6 +691,8 @@ impl storage::Trait for Runtime {
     type MaxDistributionBucketNumberPerFamily = MaxDistributionBucketNumberPerFamily;
     type DistributionBucketsPerBagValueConstraint = DistributionBucketsPerBagValueConstraint;
     type DistributionBucketOperatorId = DistributionBucketOperatorId;
+    type MaxNumberOfPendingInvitationsPerDistributionBucket =
+        MaxNumberOfPendingInvitationsPerDistributionBucket;
 
     fn ensure_storage_working_group_leader_origin(origin: Self::Origin) -> DispatchResult {
         StorageWorkingGroup::ensure_origin_is_active_leader(origin)