Sfoglia il codice sorgente

Merge pull request #2099 from iorveth/storage_for_all

Storage for all
Bedeho Mender 4 anni fa
parent
commit
b6a0c69f4a

+ 91 - 6
runtime-modules/storage/src/data_directory.rs

@@ -40,6 +40,12 @@ use crate::data_object_type_registry;
 use crate::data_object_type_registry::IsActiveDataObjectType;
 use crate::{MemberId, StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
 
+// Temporary representation.
+type ChannelId = u64;
+
+// Temporary representation.
+type DAOId = u64;
+
 /// The _Data directory_ main _Trait_.
 pub trait Trait:
     pallet_timestamp::Trait
@@ -89,6 +95,31 @@ decl_error! {
     }
 }
 
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
+pub enum WorkinGroupType {
+    ContentDirectory,
+    Builders,
+    StorageProviders,
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
+pub enum AbstractStorageObjectOwner<ChannelId, DAOId> {
+    Channel(ChannelId), // acts through content directory module, where again DAOs can own channels for example
+    DAO(DAOId),         // acts through upcoming `content_finance` module
+    Council,            // acts through proposal system
+    WorkingGroup(WorkinGroupType), // acts through new extrinsic in working group
+}
+
+// New owner type for storage object struct
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
+pub enum StorageObjectOwner<MemberId, ChannelId, DAOId> {
+    Member(MemberId),
+    AbstractStorageObjectOwner(AbstractStorageObjectOwner<ChannelId, DAOId>),
+}
+
 /// The decision of the storage provider when it acts as liaison.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
@@ -112,6 +143,8 @@ impl Default for LiaisonJudgement {
 /// Alias for DataObjectInternal
 pub type DataObject<T> = DataObjectInternal<
     MemberId<T>,
+    ChannelId,
+    DAOId,
     <T as system::Trait>::BlockNumber,
     <T as pallet_timestamp::Trait>::Moment,
     <T as data_object_type_registry::Trait>::DataObjectTypeId,
@@ -121,9 +154,17 @@ pub type DataObject<T> = DataObjectInternal<
 /// Manages content ids, type and storage provider decision about it.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
-pub struct DataObjectInternal<MemberId, BlockNumber, Moment, DataObjectTypeId, StorageProviderId> {
+pub struct DataObjectInternal<
+    MemberId,
+    ChannelId,
+    DAOId,
+    BlockNumber,
+    Moment,
+    DataObjectTypeId,
+    StorageProviderId,
+> {
     /// Content owner.
-    pub owner: MemberId,
+    pub owner: StorageObjectOwner<MemberId, ChannelId, DAOId>,
 
     /// Content added at.
     pub added_at: BlockAndTime<BlockNumber, Moment>,
@@ -162,14 +203,14 @@ decl_event! {
     /// _Data directory_ events
     pub enum Event<T> where
         <T as Trait>::ContentId,
-        MemberId = MemberId<T>,
+        StorageObjectOwner = StorageObjectOwner<MemberId<T>, ChannelId, DAOId>,
         StorageProviderId = StorageProviderId<T>
     {
         /// Emits on adding of the content.
         /// Params:
         /// - Id of the relationship.
         /// - Id of the member.
-        ContentAdded(ContentId, MemberId),
+        ContentAdded(ContentId, StorageObjectOwner),
 
         /// Emits when the storage provider accepts a content.
         /// Params:
@@ -201,6 +242,48 @@ decl_module! {
         /// awaits liaison to accept or reject it.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_content(
+            origin,
+            abstract_owner: AbstractStorageObjectOwner<ChannelId, DAOId>,
+            content_id: T::ContentId,
+            type_id: <T as data_object_type_registry::Trait>::DataObjectTypeId,
+            size: u64,
+            ipfs_content_id: Vec<u8>
+        ) {
+            ensure_root(origin)?;
+
+            ensure!(T::IsActiveDataObjectType::is_active_data_object_type(&type_id),
+                Error::<T>::DataObjectTypeMustBeActive);
+
+            ensure!(!<DataObjectByContentId<T>>::contains_key(content_id),
+                Error::<T>::DataObjectAlreadyAdded);
+
+            let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
+
+            let owner = StorageObjectOwner::AbstractStorageObjectOwner(abstract_owner);
+
+            // Let's create the entry then
+            let data: DataObject<T> = DataObjectInternal {
+                type_id,
+                size,
+                added_at: common::current_block_time::<T>(),
+                owner: owner.clone(),
+                liaison,
+                liaison_judgement: LiaisonJudgement::Pending,
+                ipfs_content_id,
+            };
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            <DataObjectByContentId<T>>::insert(&content_id, data);
+            Self::deposit_event(RawEvent::ContentAdded(content_id, owner));
+        }
+
+        /// Adds the content to the system. Member id should match its origin. The created DataObject
+        /// awaits liaison to accept or reject it.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn add_content_as_member(
             origin,
             member_id: MemberId<T>,
             content_id: T::ContentId,
@@ -221,12 +304,14 @@ decl_module! {
 
             let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
 
+            let owner = StorageObjectOwner::Member(member_id);
+
             // Let's create the entry then
             let data: DataObject<T> = DataObjectInternal {
                 type_id,
                 size,
                 added_at: common::current_block_time::<T>(),
-                owner: member_id,
+                owner: owner.clone(),
                 liaison,
                 liaison_judgement: LiaisonJudgement::Pending,
                 ipfs_content_id,
@@ -237,7 +322,7 @@ decl_module! {
             //
 
             <DataObjectByContentId<T>>::insert(&content_id, data);
-            Self::deposit_event(RawEvent::ContentAdded(content_id, member_id));
+            Self::deposit_event(RawEvent::ContentAdded(content_id, owner));
         }
 
         /// Storage provider accepts a content. Requires signed storage provider account and its id.

+ 25 - 26
runtime-modules/storage/src/tests/data_directory.rs

@@ -12,7 +12,7 @@ fn succeed_adding_content() {
         let sender = 1u64;
         let member_id = 1u64;
         // Register a content with 1234 bytes of type 1, which should be recognized.
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             1,
@@ -29,7 +29,7 @@ fn add_content_fails_with_invalid_origin() {
     with_default_mock_builder(|| {
         let member_id = 1u64;
         // Register a content with 1234 bytes of type 1, which should be recognized.
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             RawOrigin::Root.into(),
             member_id,
             1,
@@ -54,7 +54,7 @@ fn accept_and_reject_content_fail_with_invalid_storage_provider() {
         let sender = 1u64;
         let member_id = 1u64;
 
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             1,
@@ -64,12 +64,11 @@ fn accept_and_reject_content_fail_with_invalid_storage_provider() {
         );
         assert!(res.is_ok());
 
-        let (content_id, _) = match System::events().last().unwrap().event {
-            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
-                content_id,
-                creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+        let content_id = match System::events().last().unwrap().event {
+            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(content_id, _)) => {
+                content_id
+            }
+            _ => 0u64,
         };
 
         //  invalid data
@@ -104,7 +103,7 @@ fn accept_content_as_liaison() {
         let sender = 1u64;
         let member_id = 1u64;
 
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             1,
@@ -115,15 +114,15 @@ fn accept_content_as_liaison() {
         assert!(res.is_ok());
 
         // An appropriate event should have been fired.
-        let (content_id, creator) = match System::events().last().unwrap().event {
+        let (content_id, creator) = match &System::events().last().unwrap().event {
             MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
                 content_id,
                 creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+            )) => (*content_id, creator.clone()),
+            _ => (0u64, StorageObjectOwner::Member(0xdeadbeefu64)), // invalid value, unlikely to match
         };
-        assert_ne!(creator, 0xdeadbeefu64);
-        assert_eq!(creator, sender);
+        assert_ne!(creator, StorageObjectOwner::Member(0xdeadbeefu64));
+        assert_eq!(creator, StorageObjectOwner::Member(sender));
 
         let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
 
@@ -155,7 +154,7 @@ fn reject_content_as_liaison() {
         let sender = 1u64;
         let member_id = 1u64;
 
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             1,
@@ -166,15 +165,15 @@ fn reject_content_as_liaison() {
         assert!(res.is_ok());
 
         // An appropriate event should have been fired.
-        let (content_id, creator) = match System::events().last().unwrap().event {
+        let (content_id, creator) = match &System::events().last().unwrap().event {
             MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
                 content_id,
                 creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+            )) => (*content_id, creator.clone()),
+            _ => (0u64, StorageObjectOwner::Member(0xdeadbeefu64)), // invalid value, unlikely to match
         };
-        assert_ne!(creator, 0xdeadbeefu64);
-        assert_eq!(creator, sender);
+        assert_ne!(creator, StorageObjectOwner::Member(0xdeadbeefu64));
+        assert_eq!(creator, StorageObjectOwner::Member(sender));
 
         let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
 
@@ -209,7 +208,7 @@ fn data_object_injection_works() {
                 block: 10,
                 time: 1024,
             },
-            owner: 1,
+            owner: StorageObjectOwner::Member(1),
             liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
             liaison_judgement: data_directory::LiaisonJudgement::Pending,
             ipfs_content_id: vec![],
@@ -251,7 +250,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
 
         // Start with some existing objects in directory which will be
         // overwritten
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             content_id_1,
@@ -260,7 +259,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
             vec![8, 8, 8, 8],
         );
         assert!(res.is_ok());
-        let res = TestDataDirectory::add_content(
+        let res = TestDataDirectory::add_content_as_member(
             Origin::signed(sender),
             member_id,
             content_id_2,
@@ -279,7 +278,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
                 block: 10,
                 time: 1000,
             },
-            owner: 5,
+            owner: StorageObjectOwner::Member(5),
             liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
             liaison_judgement: data_directory::LiaisonJudgement::Pending,
             ipfs_content_id: vec![5, 6, 7],
@@ -292,7 +291,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
                 block: 20,
                 time: 2000,
             },
-            owner: 6,
+            owner: StorageObjectOwner::Member(6),
             liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
             liaison_judgement: data_directory::LiaisonJudgement::Pending,
             ipfs_content_id: vec![5, 6, 7],

+ 2 - 1
runtime-modules/storage/src/tests/mock.rs

@@ -11,6 +11,7 @@ use sp_runtime::{
 };
 
 use crate::data_directory::ContentIdExists;
+pub use crate::data_directory::StorageObjectOwner;
 use crate::data_object_type_registry::IsActiveDataObjectType;
 pub use crate::StorageWorkingGroupInstance;
 pub use crate::{data_directory, data_object_storage_registry, data_object_type_registry};
@@ -74,7 +75,7 @@ impl ContentIdExists<Test> for MockContent {
                     block: 10,
                     time: 1024,
                 },
-                owner: 1,
+                owner: StorageObjectOwner::Member(1),
                 liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
                 liaison_judgement: data_directory::LiaisonJudgement::Pending,
                 ipfs_content_id: vec![],