Browse Source

working_group: introduce length constraint for the working group roles storage field

iorveth 4 years ago
parent
commit
f93b965c5d

+ 4 - 0
node/src/chain_spec/mod.rs

@@ -311,6 +311,7 @@ pub fn testnet_genesis(
             opening_human_readable_text_constraint: default_text_constraint,
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_text_constraint: default_text_constraint,
         }),
         working_group_Instance3: Some(ContentDirectoryWorkingGroupConfig {
             phantom: Default::default(),
@@ -318,6 +319,7 @@ pub fn testnet_genesis(
             opening_human_readable_text_constraint: default_text_constraint,
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_text_constraint: default_text_constraint,
         }),
         working_group_Instance4: Some(BuilderWorkingGroupConfig {
             phantom: Default::default(),
@@ -325,6 +327,7 @@ pub fn testnet_genesis(
             opening_human_readable_text_constraint: default_text_constraint,
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_text_constraint: default_text_constraint,
         }),
         working_group_Instance5: Some(GatewayWorkingGroupConfig {
             phantom: Default::default(),
@@ -332,6 +335,7 @@ pub fn testnet_genesis(
             opening_human_readable_text_constraint: default_text_constraint,
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
+            worker_storage_text_constraint: default_text_constraint,
         }),
         content: Some({
             ContentConfig {

+ 6 - 0
runtime-modules/working-group/src/errors.rs

@@ -84,6 +84,12 @@ decl_error! {
         /// Worker exit rationale text is too short.
         WorkerExitRationaleTextTooShort,
 
+        /// Worker storage text is too long.
+        WorkerStorageTextTooLong,
+
+        /// Worker storage text is too short.
+        WorkerStorageTextTooShort,
+
         /// Signer is not worker role account.
         SignerIsNotWorkerRoleAccount,
 

+ 20 - 1
runtime-modules/working-group/src/lib.rs

@@ -327,6 +327,9 @@ decl_storage! {
         /// Worker exit rationale text length limits.
         pub WorkerExitRationaleText get(fn worker_exit_rationale_text) : InputValidationLengthConstraint;
 
+        /// Worker storage text length limits.
+        pub WorkerStorageText get(fn worker_storage_text) : InputValidationLengthConstraint;
+
         /// Map member id by hiring application id.
         /// Required by StakingEventsHandler callback call to refund the balance on unstaking.
         pub MemberIdByHiringApplicationId get(fn member_id_by_hiring_application_id):
@@ -338,11 +341,13 @@ decl_storage! {
         config(opening_human_readable_text_constraint): InputValidationLengthConstraint;
         config(worker_application_human_readable_text_constraint): InputValidationLengthConstraint;
         config(worker_exit_rationale_text_constraint): InputValidationLengthConstraint;
+        config(worker_storage_text_constraint): InputValidationLengthConstraint;
         build(|config: &GenesisConfig<T, I>| {
             Module::<T, I>::initialize_working_group(
                 config.opening_human_readable_text_constraint,
                 config.worker_application_human_readable_text_constraint,
                 config.worker_exit_rationale_text_constraint,
+                config.worker_storage_text_constraint,
                 config.working_group_mint_capacity)
         });
     }
@@ -401,6 +406,8 @@ decl_module! {
             // Ensure there is a signer which matches role account of worker corresponding to provided id.
             let mut worker = Self::ensure_worker_signed(origin, &worker_id)?;
 
+            Self::ensure_worker_role_storage_text_is_valid(&storage)?;
+
             //
             // == MUTATION SAFE ==
             //
@@ -1358,11 +1365,21 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
             )
             .map_err(|e| DispatchError::Other(e))
     }
+
+    fn ensure_worker_role_storage_text_is_valid(text: &[u8]) -> DispatchResult {
+        Self::worker_storage_text()
+            .ensure_valid(
+                text.len(),
+                Error::<T, I>::WorkerStorageTextTooShort.into(),
+                Error::<T, I>::WorkerStorageTextTooLong.into(),
+            )
+            .map_err(|e| DispatchError::Other(e))
+    }
 }
 
 /// Creates default text constraint.
 pub fn default_text_constraint() -> InputValidationLengthConstraint {
-    InputValidationLengthConstraint::new(1, 1024)
+    InputValidationLengthConstraint::new(1, 2048)
 }
 
 impl<T: Trait<I>, I: Instance> Module<T, I> {
@@ -1517,6 +1534,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         opening_human_readable_text_constraint: InputValidationLengthConstraint,
         worker_application_human_readable_text_constraint: InputValidationLengthConstraint,
         worker_exit_rationale_text_constraint: InputValidationLengthConstraint,
+        worker_storage_text_constraint: InputValidationLengthConstraint,
         working_group_mint_capacity: minting::BalanceOf<T>,
     ) {
         // Create a mint.
@@ -1534,6 +1552,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
             worker_application_human_readable_text_constraint,
         );
         <WorkerExitRationaleText<I>>::put(worker_exit_rationale_text_constraint);
+        <WorkerStorageText<I>>::put(worker_storage_text_constraint);
     }
 
     // Set worker id as a leader id.

+ 4 - 0
runtime-modules/working-group/src/tests/mock.rs

@@ -169,6 +169,10 @@ pub fn build_test_externalities() -> sp_io::TestExternalities {
             WORKING_GROUP_CONSTRAINT_MIN,
             WORKING_GROUP_CONSTRAINT_DIFF,
         ),
+        worker_storage_text_constraint: InputValidationLengthConstraint::new(
+            WORKING_GROUP_CONSTRAINT_MIN,
+            WORKING_GROUP_CONSTRAINT_DIFF,
+        ),
     }
     .assimilate_storage(&mut t)
     .unwrap();

+ 42 - 6
runtime-modules/working-group/src/tests/mod.rs

@@ -7,6 +7,7 @@ use frame_support::storage::{StorageMap, StorageValue};
 use std::collections::BTreeMap;
 use system::RawOrigin;
 
+use crate::default_text_constraint;
 use crate::tests::hiring_workflow::HiringWorkflow;
 use crate::types::{OpeningPolicyCommitment, OpeningType, RewardPolicy};
 use crate::{Error, RawEvent, Worker};
@@ -1232,7 +1233,7 @@ fn update_worker_storage_fails_with_invalid_origin_signed_account() {
             UpdateWorkerStorageFixture::default_with_storage_field(worker_id, storage_field)
                 .with_origin(RawOrigin::Signed(2));
 
-                update_storage_fixture.call_and_assert(Err(
+        update_storage_fixture.call_and_assert(Err(
             Error::<Test, TestWorkingGroupInstance>::SignerIsNotWorkerRoleAccount.into(),
         ));
     });
@@ -1241,20 +1242,55 @@ fn update_worker_storage_fails_with_invalid_origin_signed_account() {
 #[test]
 fn update_worker_storage_fails_with_invalid_worker_id() {
     build_test_externalities().execute_with(|| {
-        let invalid_worker_id = 1;
+        let storage_field = vec![0u8].repeat(10);
+
         fill_default_worker_position();
 
-        let storage_field = vec![0u8].repeat(10);
+        let invalid_worker_id = 1;
 
-        let update_storage_fixture =
-            UpdateWorkerStorageFixture::default_with_storage_field(invalid_worker_id, storage_field);
+        let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
+            invalid_worker_id,
+            storage_field.clone(),
+        );
 
-            update_storage_fixture.call_and_assert(Err(
+        update_storage_fixture.call_and_assert(Err(
             Error::<Test, TestWorkingGroupInstance>::WorkerDoesNotExist.into(),
         ));
     });
 }
 
+#[test]
+fn update_worker_storage_fails_with_too_long_text() {
+    build_test_externalities().execute_with(|| {
+        let storage_field = vec![0u8].repeat(default_text_constraint().max() as usize + 1);
+
+        let worker_id = fill_default_worker_position();
+
+        let update_storage_fixture = UpdateWorkerStorageFixture::default_with_storage_field(
+            worker_id,
+            storage_field.clone(),
+        );
+
+        update_storage_fixture
+            .call_and_assert(Err(DispatchError::Other("WorkerStorageTextTooLong")));
+    });
+}
+
+#[test]
+fn update_worker_storage_fails_with_too_short_text() {
+    build_test_externalities().execute_with(|| {
+        let worker_id = fill_default_worker_position();
+
+        let storage_field = vec![0u8].repeat(default_text_constraint().min as usize - 1);
+
+        let update_storage_fixture =
+            UpdateWorkerStorageFixture::default_with_storage_field(worker_id, storage_field);
+
+        update_storage_fixture
+            .call_and_assert(Err(DispatchError::Other("WorkerStorageTextTooShort")));
+    });
+}
+
 #[test]
 fn update_worker_reward_account_succeeds() {
     build_test_externalities().execute_with(|| {

+ 1 - 0
runtime-modules/working-group/src/types.rs

@@ -2,6 +2,7 @@
 
 use codec::{Decode, Encode};
 use sp_std::collections::btree_set::BTreeSet;
+use sp_std::prelude::Vec;
 
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};

+ 2 - 0
runtime/src/runtime_api.rs

@@ -77,6 +77,7 @@ impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
             default_text_constraint,
             default_text_constraint,
             default_text_constraint,
+            default_text_constraint,
             default_content_working_group_mint_capacity,
         );
 
@@ -84,6 +85,7 @@ impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
             default_text_constraint,
             default_text_constraint,
             default_text_constraint,
+            default_text_constraint,
             default_content_working_group_mint_capacity,
         );