Browse Source

Merge pull request #1273 from iorveth/runtime_integration

Content directory runtime integration
Bedeho Mender 4 years ago
parent
commit
531abfa089

+ 3 - 2
Cargo.lock

@@ -2040,6 +2040,7 @@ dependencies = [
  "pallet-balances",
  "pallet-collective",
  "pallet-common",
+ "pallet-content-directory",
  "pallet-content-working-group",
  "pallet-finality-tracker",
  "pallet-forum",
@@ -3948,9 +3949,9 @@ dependencies = [
 
 [[package]]
 name = "parity-scale-codec-derive"
-version = "1.2.0"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245"
+checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14"
 dependencies = [
  "proc-macro-crate",
  "proc-macro2",

+ 21 - 5
node/src/chain_spec.rs

@@ -30,11 +30,12 @@ use sp_runtime::Perbill;
 
 use node_runtime::{
     versioned_store::InputValidationLengthConstraint as VsInputValidation,
-    AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentWorkingGroupConfig,
-    CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
-    DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, MembersConfig,
-    ProposalsCodexConfig, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
-    StorageWorkingGroupConfig, SudoConfig, SystemConfig, VersionedStoreConfig, DAYS, WASM_BINARY,
+    AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentDirectoryConfig,
+    ContentDirectoryWorkingGroupConfig, ContentWorkingGroupConfig, CouncilConfig,
+    CouncilElectionConfig, DataObjectStorageRegistryConfig, DataObjectTypeRegistryConfig,
+    ElectionParameters, GrandpaConfig, ImOnlineConfig, MembersConfig, ProposalsCodexConfig,
+    SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig,
+    SudoConfig, SystemConfig, VersionedStoreConfig, DAYS, WASM_BINARY,
 };
 
 pub use node_runtime::{AccountId, GenesisConfig};
@@ -292,6 +293,13 @@ pub fn testnet_genesis(
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
         }),
+        working_group_Instance3: Some(ContentDirectoryWorkingGroupConfig {
+            phantom: Default::default(),
+            storage_working_group_mint_capacity: 0,
+            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,
+        }),
         versioned_store: Some(VersionedStoreConfig {
             class_by_id: vec![],
             entity_by_id: vec![],
@@ -326,6 +334,14 @@ pub fn testnet_genesis(
             channel_banner_constraint: InputValidationLengthConstraint::new(5, 1024),
             channel_title_constraint: InputValidationLengthConstraint::new(5, 1024),
         }),
+        content_directory: Some({
+            ContentDirectoryConfig {
+                curator_group_by_id: vec![],
+                next_class_id: 1,
+                next_entity_id: 1,
+                next_curator_group_id: 1,
+            }
+        }),
         proposals_codex: Some(ProposalsCodexConfig {
             set_validator_count_proposal_voting_period: cpcp
                 .set_validator_count_proposal_voting_period,

+ 1 - 1
runtime-modules/content-directory/src/helpers.rs

@@ -185,7 +185,7 @@ pub struct InputValidationLengthConstraint {
 
 impl InputValidationLengthConstraint {
     /// Create new `InputValidationLengthConstraint` constraint
-    pub fn new(min: u16, max_min_diff: u16) -> Self {
+    pub const fn new(min: u16, max_min_diff: u16) -> Self {
         Self { min, max_min_diff }
     }
 

+ 7 - 13
runtime-modules/content-directory/src/lib.rs

@@ -135,7 +135,6 @@ pub use operations::*;
 pub use permissions::*;
 pub use schema::*;
 
-use core::fmt::Debug;
 use core::hash::Hash;
 use core::ops::AddAssign;
 
@@ -145,21 +144,22 @@ use frame_support::storage::IterableStorageMap;
 use frame_support::{
     decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure, traits::Get, Parameter,
 };
+#[cfg(feature = "std")]
+pub use serde::{Deserialize, Serialize};
 use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
 use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
+use sp_std::borrow::ToOwned;
 use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
+use sp_std::vec;
 use sp_std::vec::Vec;
 use system::ensure_signed;
 
-#[cfg(feature = "std")]
-pub use serde::{Deserialize, Serialize};
-
 pub use errors::Error;
 
 use core::debug_assert;
 
 /// Type, used in diffrent numeric constraints representations
-type MaxNumber = u32;
+pub type MaxNumber = u32;
 
 /// Module configuration trait for this Substrate module.
 pub trait Trait: system::Trait + ActorAuthenticator + Clone {
@@ -174,8 +174,6 @@ pub trait Trait: system::Trait + ActorAuthenticator + Clone {
         + Default
         + Copy
         + Clone
-        + One
-        + Zero
         + MaybeSerializeDeserialize
         + Eq
         + PartialEq
@@ -190,9 +188,7 @@ pub trait Trait: system::Trait + ActorAuthenticator + Clone {
         + Default
         + Copy
         + Clone
-        + One
         + Hash
-        + Zero
         + MaybeSerializeDeserialize
         + Eq
         + PartialEq
@@ -207,8 +203,6 @@ pub trait Trait: system::Trait + ActorAuthenticator + Clone {
         + Copy
         + Clone
         + Hash
-        + One
-        + Zero
         + MaybeSerializeDeserialize
         + Eq
         + PartialEq
@@ -266,10 +260,10 @@ decl_storage! {
     trait Store for Module<T: Trait> as ContentDirectory {
 
         /// Map, representing ClassId -> Class relation
-        pub ClassById get(fn class_by_id) config(): map hasher(blake2_128_concat) T::ClassId => Class<T>;
+        pub ClassById get(fn class_by_id): map hasher(blake2_128_concat) T::ClassId => Class<T>;
 
         /// Map, representing EntityId -> Entity relation
-        pub EntityById get(fn entity_by_id) config(): map hasher(blake2_128_concat) T::EntityId => Entity<T>;
+        pub EntityById get(fn entity_by_id): map hasher(blake2_128_concat) T::EntityId => Entity<T>;
 
         /// Map, representing  CuratorGroupId -> CuratorGroup relation
         pub CuratorGroupById get(fn curator_group_by_id) config(): map hasher(blake2_128_concat) T::CuratorGroupId => CuratorGroup<T>;

+ 0 - 31
runtime-modules/content-directory/src/mock.rs

@@ -89,21 +89,16 @@ thread_local! {
     static PROPERTY_DESCRIPTION_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
     static CLASS_NAME_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
     static CLASS_DESCRIPTION_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
-
     static MAX_NUMBER_OF_CLASSES: RefCell<MaxNumber> = RefCell::new(0);
     static MAX_NUMBER_OF_MAINTAINERS_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
     static MAX_NUMBER_OF_SCHEMAS_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
     static MAX_NUMBER_OF_PROPERTIES_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
     static MAX_NUMBER_OF_ENTITIES_PER_CLASS: RefCell<EntityId> = RefCell::new(0);
-
     static MAX_NUMBER_OF_CURATORS_PER_GROUP: RefCell<MaxNumber> = RefCell::new(0);
-
     static MAX_NUMBER_OF_OPERATIONS_DURING_ATOMIC_BATCHING: RefCell<MaxNumber> = RefCell::new(0);
-
     static VEC_MAX_LENGTH_CONSTRAINT: RefCell<VecMaxLength> = RefCell::new(0);
     static TEXT_MAX_LENGTH_CONSTRAINT: RefCell<TextMaxLength> = RefCell::new(0);
     static HASHED_TEXT_MAX_LENGTH_CONSTRAINT: RefCell<HashedTextMaxLength> = RefCell::new(Some(0));
-
     static INDIVIDUAL_ENTITIES_CREATION_LIMIT: RefCell<EntityId> = RefCell::new(0);
 }
 
@@ -252,31 +247,23 @@ impl_outer_event! {
 
 impl Trait for Runtime {
     type Event = TestEvent;
-
     type Nonce = u64;
-
     type ClassId = u64;
     type EntityId = u64;
-
     type PropertyNameLengthConstraint = PropertyNameLengthConstraint;
     type PropertyDescriptionLengthConstraint = PropertyDescriptionLengthConstraint;
     type ClassNameLengthConstraint = ClassNameLengthConstraint;
     type ClassDescriptionLengthConstraint = ClassDescriptionLengthConstraint;
-
     type MaxNumberOfClasses = MaxNumberOfClasses;
     type MaxNumberOfMaintainersPerClass = MaxNumberOfMaintainersPerClass;
     type MaxNumberOfSchemasPerClass = MaxNumberOfSchemasPerClass;
     type MaxNumberOfPropertiesPerSchema = MaxNumberOfPropertiesPerSchema;
     type MaxNumberOfEntitiesPerClass = MaxNumberOfEntitiesPerClass;
-
     type MaxNumberOfCuratorsPerGroup = MaxNumberOfCuratorsPerGroup;
-
     type MaxNumberOfOperationsDuringAtomicBatching = MaxNumberOfOperationsDuringAtomicBatching;
-
     type VecMaxLengthConstraint = VecMaxLengthConstraint;
     type TextMaxLengthConstraint = TextMaxLengthConstraint;
     type HashedTextMaxLengthConstraint = HashedTextMaxLengthConstraint;
-
     type IndividualEntitiesCreationLimit = IndividualEntitiesCreationLimit;
 }
 
@@ -311,21 +298,16 @@ pub struct ExtBuilder {
     property_description_constraint: InputValidationLengthConstraint,
     class_name_constraint: InputValidationLengthConstraint,
     class_description_constraint: InputValidationLengthConstraint,
-
     max_number_of_classes: MaxNumber,
     max_number_of_maintainers_per_class: MaxNumber,
     max_number_of_schemas_per_class: MaxNumber,
     max_number_of_properties_per_class: MaxNumber,
     max_number_of_entities_per_class: EntityId,
-
     max_number_of_curators_per_group: MaxNumber,
-
     max_number_of_operations_during_atomic_batching: MaxNumber,
-
     vec_max_length_constraint: VecMaxLength,
     text_max_length_constraint: TextMaxLength,
     hashed_text_max_length_constraint: HashedTextMaxLength,
-
     individual_entities_creation_limit: EntityId,
 }
 
@@ -336,21 +318,16 @@ impl Default for ExtBuilder {
             property_description_constraint: InputValidationLengthConstraint::new(1, 500),
             class_name_constraint: InputValidationLengthConstraint::new(1, 49),
             class_description_constraint: InputValidationLengthConstraint::new(1, 500),
-
             max_number_of_classes: 100,
             max_number_of_maintainers_per_class: 10,
             max_number_of_schemas_per_class: 20,
             max_number_of_properties_per_class: 40,
             max_number_of_entities_per_class: 400,
-
             max_number_of_curators_per_group: 50,
-
             max_number_of_operations_during_atomic_batching: 500,
-
             vec_max_length_constraint: 200,
             text_max_length_constraint: 5000,
             hashed_text_max_length_constraint: Some(25000),
-
             individual_entities_creation_limit: 50,
         }
     }
@@ -363,7 +340,6 @@ impl ExtBuilder {
             .with(|v| *v.borrow_mut() = self.property_description_constraint);
         CLASS_NAME_CONSTRAINT.with(|v| *v.borrow_mut() = self.class_name_constraint);
         CLASS_DESCRIPTION_CONSTRAINT.with(|v| *v.borrow_mut() = self.class_description_constraint);
-
         MAX_NUMBER_OF_CLASSES.with(|v| *v.borrow_mut() = self.max_number_of_classes);
         MAX_NUMBER_OF_MAINTAINERS_PER_CLASS
             .with(|v| *v.borrow_mut() = self.max_number_of_maintainers_per_class);
@@ -373,19 +349,14 @@ impl ExtBuilder {
             .with(|v| *v.borrow_mut() = self.max_number_of_properties_per_class);
         MAX_NUMBER_OF_ENTITIES_PER_CLASS
             .with(|v| *v.borrow_mut() = self.max_number_of_entities_per_class);
-
         MAX_NUMBER_OF_CURATORS_PER_GROUP
             .with(|v| *v.borrow_mut() = self.max_number_of_curators_per_group);
-
         MAX_NUMBER_OF_OPERATIONS_DURING_ATOMIC_BATCHING
             .with(|v| *v.borrow_mut() = self.max_number_of_operations_during_atomic_batching);
-
         VEC_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow_mut() = self.vec_max_length_constraint);
         TEXT_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow_mut() = self.text_max_length_constraint);
-
         HASHED_TEXT_MAX_LENGTH_CONSTRAINT
             .with(|v| *v.borrow_mut() = self.hashed_text_max_length_constraint);
-
         INDIVIDUAL_ENTITIES_CREATION_LIMIT
             .with(|v| *v.borrow_mut() = self.individual_entities_creation_limit);
     }
@@ -405,8 +376,6 @@ impl ExtBuilder {
 
 fn default_content_directory_genesis_config() -> GenesisConfig<Runtime> {
     GenesisConfig {
-        class_by_id: vec![],
-        entity_by_id: vec![],
         curator_group_by_id: vec![],
         next_class_id: 1,
         next_entity_id: 1,

+ 0 - 1
runtime-modules/content-directory/src/operations.rs

@@ -69,7 +69,6 @@ pub enum OperationType<T: Trait> {
 }
 
 impl<T: Trait> core::fmt::Debug for OperationType<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "OperationType {:?}", self)
     }

+ 0 - 2
runtime-modules/content-directory/src/permissions.rs

@@ -51,7 +51,6 @@ pub trait ActorAuthenticator: system::Trait {
         + Member
         + BaseArithmetic
         + Codec
-        + One
         + Default
         + Copy
         + Clone
@@ -122,7 +121,6 @@ impl<T: Trait> Default for Actor<T> {
 }
 
 impl<T: Trait> core::fmt::Debug for Actor<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "Actor {:?}", self)
     }

+ 0 - 1
runtime-modules/content-directory/src/permissions/class.rs

@@ -24,7 +24,6 @@ pub struct ClassPermissions<T: Trait> {
 }
 
 impl<T: Trait> core::fmt::Debug for ClassPermissions<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "ClassPermissions {:?}", self)
     }

+ 0 - 1
runtime-modules/content-directory/src/permissions/entity.rs

@@ -27,7 +27,6 @@ impl<T: Trait> Default for EntityController<T> {
 }
 
 impl<T: Trait> core::fmt::Debug for EntityController<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "EntityController {:?}", self)
     }

+ 0 - 1
runtime-modules/content-directory/src/schema.rs

@@ -287,7 +287,6 @@ impl<T: Trait> Default for Property<T> {
 }
 
 impl<T: Trait> core::fmt::Debug for Property<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "Property {:?}", self)
     }

+ 1 - 3
runtime-modules/content-directory/src/schema/input.rs

@@ -9,7 +9,6 @@ pub enum InputPropertyValue<T: Trait> {
 }
 
 impl<T: Trait> core::fmt::Debug for InputPropertyValue<T> {
-    #[cfg(feature = "std")]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         write!(formatter, "InputPropertyValue {:?}", self)
     }
@@ -81,8 +80,7 @@ pub enum InputValue<T: Trait> {
 }
 
 impl<T: Trait> core::fmt::Debug for InputValue<T> {
-    #[cfg(feature = "std")]
-    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> sp_std::fmt::Result {
         write!(formatter, "InputValue {:?}", self)
     }
 }

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

@@ -1298,7 +1298,8 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         Ok(worker)
     }
 
-    fn ensure_worker_exists(worker_id: &WorkerId<T>) -> Result<WorkerOf<T>, Error<T, I>> {
+    /// Ensures worker under given id already exists
+    pub fn ensure_worker_exists(worker_id: &WorkerId<T>) -> Result<WorkerOf<T>, Error<T, I>> {
         ensure!(
             WorkerById::<T, I>::contains_key(worker_id),
             Error::<T, I>::WorkerDoesNotExist

+ 2 - 0
runtime/Cargo.toml

@@ -77,6 +77,7 @@ service-discovery = { package = 'pallet-service-discovery', default-features = f
 proposals-engine = { package = 'pallet-proposals-engine', default-features = false, path = '../runtime-modules/proposals/engine'}
 proposals-discussion = { package = 'pallet-proposals-discussion', default-features = false, path = '../runtime-modules/proposals/discussion'}
 proposals-codex = { package = 'pallet-proposals-codex', default-features = false, path = '../runtime-modules/proposals/codex'}
+content-directory = { package = 'pallet-content-directory', default-features = false, path = '../runtime-modules/content-directory' }
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
@@ -152,6 +153,7 @@ std = [
     'proposals-engine/std',
     'proposals-discussion/std',
     'proposals-codex/std',
+    'content-directory/std',
 ]
 runtime-benchmarks = [
     "system/runtime-benchmarks",

+ 44 - 0
runtime/src/integration/content_directory.rs

@@ -0,0 +1,44 @@
+use crate::{AccountId, ContentDirectoryWorkingGroupInstance, MemberId, Runtime};
+
+// Alias for content directory working group
+pub(crate) type ContentDirectoryWorkingGroup<T> =
+    working_group::Module<T, ContentDirectoryWorkingGroupInstance>;
+
+impl content_directory::ActorAuthenticator for Runtime {
+    type CuratorId = u64;
+    type MemberId = MemberId;
+    type CuratorGroupId = u64;
+
+    fn is_lead(account_id: &AccountId) -> bool {
+        // get current lead id
+        let maybe_current_lead_id = ContentDirectoryWorkingGroup::<Runtime>::current_lead();
+        if let Some(ref current_lead_id) = maybe_current_lead_id {
+            if let Ok(worker) =
+                ContentDirectoryWorkingGroup::<Runtime>::ensure_worker_exists(current_lead_id)
+            {
+                *account_id == worker.role_account_id
+            } else {
+                false
+            }
+        } else {
+            false
+        }
+    }
+
+    fn is_curator(curator_id: &Self::CuratorId, account_id: &AccountId) -> bool {
+        if let Ok(worker) =
+            ContentDirectoryWorkingGroup::<Runtime>::ensure_worker_exists(curator_id)
+        {
+            *account_id == worker.role_account_id
+        } else {
+            false
+        }
+    }
+
+    fn is_member(member_id: &Self::MemberId, account_id: &AccountId) -> bool {
+        membership::Module::<Runtime>::ensure_is_controller_account_for_member(
+            member_id, account_id,
+        )
+        .is_ok()
+    }
+}

+ 1 - 0
runtime/src/integration/mod.rs

@@ -1,3 +1,4 @@
+pub mod content_directory;
 pub mod content_working_group;
 pub mod forum;
 pub mod proposals;

+ 60 - 1
runtime/src/lib.rs

@@ -62,6 +62,11 @@ pub use proposals_codex::ProposalsConfigParameters;
 pub use versioned_store;
 pub use working_group;
 
+pub use content_directory;
+pub use content_directory::{
+    HashedTextMaxLength, InputValidationLengthConstraint, MaxNumber, TextMaxLength, VecMaxLength,
+};
+
 /// This runtime version.
 pub const VERSION: RuntimeVersion = RuntimeVersion {
     spec_name: create_runtime_str!("joystream-node"),
@@ -372,6 +377,48 @@ impl versioned_store_permissions::Trait for Runtime {
         integration::versioned_store_permissions::ContentLeadOrSudoKeyCanCreateClasses;
 }
 
+type EntityId = <Runtime as content_directory::Trait>::EntityId;
+
+parameter_types! {
+    pub const PropertyNameLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 49);
+    pub const PropertyDescriptionLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 500);
+    pub const ClassNameLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 49);
+    pub const ClassDescriptionLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 500);
+    pub const MaxNumberOfClasses: MaxNumber = 100;
+    pub const MaxNumberOfMaintainersPerClass: MaxNumber = 10;
+    pub const MaxNumberOfSchemasPerClass: MaxNumber = 20;
+    pub const MaxNumberOfPropertiesPerSchema: MaxNumber = 40;
+    pub const MaxNumberOfEntitiesPerClass: MaxNumber = 400;
+    pub const MaxNumberOfCuratorsPerGroup: MaxNumber = 50;
+    pub const MaxNumberOfOperationsDuringAtomicBatching: MaxNumber = 500;
+    pub const VecMaxLengthConstraint: VecMaxLength = 200;
+    pub const TextMaxLengthConstraint: TextMaxLength = 5000;
+    pub const HashedTextMaxLengthConstraint: HashedTextMaxLength = Some(25000);
+    pub const IndividualEntitiesCreationLimit: EntityId = 50;
+}
+
+impl content_directory::Trait for Runtime {
+    type Event = Event;
+    type Nonce = u64;
+    type ClassId = u64;
+    type EntityId = u64;
+    type PropertyNameLengthConstraint = PropertyNameLengthConstraint;
+    type PropertyDescriptionLengthConstraint = PropertyDescriptionLengthConstraint;
+    type ClassNameLengthConstraint = ClassNameLengthConstraint;
+    type ClassDescriptionLengthConstraint = ClassDescriptionLengthConstraint;
+    type MaxNumberOfClasses = MaxNumberOfClasses;
+    type MaxNumberOfMaintainersPerClass = MaxNumberOfMaintainersPerClass;
+    type MaxNumberOfSchemasPerClass = MaxNumberOfSchemasPerClass;
+    type MaxNumberOfPropertiesPerSchema = MaxNumberOfPropertiesPerSchema;
+    type MaxNumberOfEntitiesPerClass = MaxNumberOfEntitiesPerClass;
+    type MaxNumberOfCuratorsPerGroup = MaxNumberOfCuratorsPerGroup;
+    type MaxNumberOfOperationsDuringAtomicBatching = MaxNumberOfOperationsDuringAtomicBatching;
+    type VecMaxLengthConstraint = VecMaxLengthConstraint;
+    type TextMaxLengthConstraint = TextMaxLengthConstraint;
+    type HashedTextMaxLengthConstraint = HashedTextMaxLengthConstraint;
+    type IndividualEntitiesCreationLimit = IndividualEntitiesCreationLimit;
+}
+
 impl hiring::Trait for Runtime {
     type OpeningId = u64;
     type ApplicationId = u64;
@@ -454,9 +501,11 @@ impl storage::data_object_storage_registry::Trait for Runtime {
     type ContentIdExists = DataDirectory;
 }
 
+pub type MemberId = u64;
+
 impl membership::Trait for Runtime {
     type Event = Event;
-    type MemberId = u64;
+    type MemberId = MemberId;
     type PaidTermId = u64;
     type SubscriptionId = u64;
     type ActorId = ActorId;
@@ -472,6 +521,9 @@ impl forum::Trait for Runtime {
 // The storage working group instance alias.
 pub type StorageWorkingGroupInstance = working_group::Instance2;
 
+// The content directory working group instance alias.
+pub type ContentDirectoryWorkingGroupInstance = working_group::Instance3;
+
 parameter_types! {
     pub const MaxWorkerNumberLimit: u32 = 100;
 }
@@ -481,6 +533,11 @@ impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
 }
 
+impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Runtime {
+    type Event = Event;
+    type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
+}
+
 impl service_discovery::Trait for Runtime {
     type Event = Event;
 }
@@ -603,6 +660,7 @@ construct_runtime!(
         RecurringRewards: recurring_rewards::{Module, Call, Storage},
         Hiring: hiring::{Module, Call, Storage},
         ContentWorkingGroup: content_wg::{Module, Call, Storage, Event<T>, Config<T>},
+        ContentDirectory: content_directory::{Module, Call, Storage, Event<T>, Config<T>},
         // --- Storage
         DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event<T>, Config<T>},
         DataDirectory: data_directory::{Module, Call, Storage, Event<T>},
@@ -615,5 +673,6 @@ construct_runtime!(
         // --- Working groups
         // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Event<T>},
         StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
+        ContentDirectoryWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Config<T>, Event<T>},
     }
 );