Browse Source

runtime: Upgrade the ‘storage’ pallet.

Shamil Gadelshin 4 years ago
parent
commit
1b734fb8e3

+ 24 - 0
Cargo.lock

@@ -1142,6 +1142,30 @@ dependencies = [
  "sp-std",
 ]
 
+[[package]]
+name = "pallet-storage"
+version = "3.0.0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "pallet-balances",
+ "pallet-common",
+ "pallet-hiring",
+ "pallet-membership",
+ "pallet-recurring-reward",
+ "pallet-stake",
+ "pallet-timestamp",
+ "pallet-token-mint",
+ "pallet-working-group",
+ "parity-scale-codec",
+ "serde",
+ "sp-arithmetic",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
 [[package]]
 name = "pallet-timestamp"
 version = "2.0.0-rc4"

+ 1 - 1
Cargo.toml

@@ -14,7 +14,7 @@ members = [
 	"runtime-modules/recurring-reward",
 #	"runtime-modules/service-discovery",
 	"runtime-modules/stake",
-#	"runtime-modules/storage",
+	"runtime-modules/storage",
 	"runtime-modules/token-minting",
 	"runtime-modules/versioned-store",
 	"runtime-modules/versioned-store-permissions",

+ 32 - 105
runtime-modules/storage/Cargo.toml

@@ -1,116 +1,43 @@
 [package]
-name = 'substrate-storage-module'
-version = '2.0.0'
+name = 'pallet-storage'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+rstd = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+working-group = { package = 'pallet-working-group', default-features = false, path = '../working-group'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
+hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
+recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'rstd/std',
-	'codec/std',
-	'timestamp/std',
 	'serde',
-	'primitives/std',
-	'common/std',
+	'codec/std',
+	'rstd/std',
+	'frame-support/std',
+	'system/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
 	'membership/std',
+	'timestamp/std',
 	'working-group/std',
+	'common/std',
 ]
-
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../membership'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dependencies.working-group]
-default_features = false
-package = 'substrate-working-group-module'
-path = '../working-group'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.recurringrewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../recurring-reward'
-
-[dev-dependencies.hiring]
-default_features = false
-package = 'substrate-hiring-module'
-path = '../hiring'
-
-[dev-dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../stake'
-
-[dev-dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'

+ 26 - 36
runtime-modules/storage/src/data_directory.rs

@@ -22,11 +22,11 @@
 //#![warn(missing_docs)]
 
 use codec::{Decode, Encode};
+use frame_support::dispatch::DispatchResult;
+use frame_support::traits::Get;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
 use rstd::collections::btree_map::BTreeMap;
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member};
-use srml_support::traits::Get;
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_runtime::traits::{MaybeSerialize, Member};
 use system::{self, ensure_root};
 
 use common::origin::ActorOriginValidator;
@@ -64,7 +64,7 @@ pub trait Trait:
 
 decl_error! {
     /// _Data object storage registry_ module predefined errors.
-    pub enum Error {
+    pub enum Error for Module<T: Trait>{
         /// Content with this ID not found.
         CidNotFound,
 
@@ -85,25 +85,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// The decision of the storage provider when it acts as liaison.
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub enum LiaisonJudgement {
@@ -163,11 +144,11 @@ pub type DataObjectsMap<T> = BTreeMap<<T as Trait>::ContentId, DataObject<T>>;
 decl_storage! {
     trait Store for Module<T: Trait> as DataDirectory {
         /// List of ids known to the system.
-        pub KnownContentIds get(known_content_ids): Vec<T::ContentId> = Vec::new();
+        pub KnownContentIds get(fn known_content_ids): Vec<T::ContentId> = Vec::new();
 
         /// Maps data objects by their content id.
-        pub DataObjectByContentId get(data_object_by_content_id):
-            map T::ContentId => Option<DataObject<T>>;
+        pub DataObjectByContentId get(fn data_object_by_content_id):
+            map hasher(blake2_128_concat) T::ContentId => Option<DataObject<T>>;
     }
 }
 
@@ -205,13 +186,14 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors.
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Maximum objects allowed per inject_data_objects() transaction
         const MaxObjectsPerInjection: u32 = T::MaxObjectsPerInjection::get();
 
         /// 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(
             origin,
             member_id: MemberId<T>,
@@ -226,10 +208,10 @@ decl_module! {
             )?;
 
             ensure!(T::IsActiveDataObjectType::is_active_data_object_type(&type_id),
-                Error::DataObjectTypeMustBeActive);
+                Error::<T>::DataObjectTypeMustBeActive);
 
-            ensure!(!<DataObjectByContentId<T>>::exists(content_id),
-                Error::DataObjectAlreadyAdded);
+            ensure!(!<DataObjectByContentId<T>>::contains_key(content_id),
+                Error::<T>::DataObjectAlreadyAdded);
 
             let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
 
@@ -254,6 +236,7 @@ decl_module! {
 
         /// Storage provider accepts a content. Requires signed storage provider account and its id.
         /// The LiaisonJudgement can be updated, but only by the liaison.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn accept_content(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -272,6 +255,7 @@ decl_module! {
 
         /// Storage provider rejects a content. Requires signed storage provider account and its id.
         /// The LiaisonJudgement can be updated, but only by the liaison.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn reject_content(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -288,6 +272,7 @@ decl_module! {
         // Sudo methods
 
         /// Removes the content id from the list of known content ids. Requires root privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         fn remove_known_content_id(origin, content_id: T::ContentId) {
             ensure_root(origin)?;
 
@@ -305,11 +290,12 @@ decl_module! {
         /// The number of objects that can be added per call is limited to prevent the dispatch
         /// from causing the block production to fail if it takes too much time to process.
         /// Existing data objects will be overwritten.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn inject_data_objects(origin, objects: DataObjectsMap<T>) {
             ensure_root(origin)?;
 
             // Must provide something to inject
-            ensure!(objects.len() <= T::MaxObjectsPerInjection::get() as usize, Error::DataObjectsInjectionExceededLimit);
+            ensure!(objects.len() <= T::MaxObjectsPerInjection::get() as usize, Error::<T>::DataObjectsInjectionExceededLimit);
 
             for (id, object) in objects.into_iter() {
                 // append to known content ids
@@ -332,11 +318,15 @@ impl<T: Trait> Module<T> {
         storage_provider_id: &StorageProviderId<T>,
         content_id: T::ContentId,
         judgement: LiaisonJudgement,
-    ) -> Result<(), Error> {
-        let mut data = Self::data_object_by_content_id(&content_id).ok_or(Error::CidNotFound)?;
+    ) -> DispatchResult {
+        let mut data =
+            Self::data_object_by_content_id(&content_id).ok_or(Error::<T>::CidNotFound)?;
 
         // Make sure the liaison matches
-        ensure!(data.liaison == *storage_provider_id, Error::LiaisonRequired);
+        ensure!(
+            data.liaison == *storage_provider_id,
+            Error::<T>::LiaisonRequired
+        );
 
         data.liaison_judgement = judgement;
         <DataObjectByContentId<T>>::insert(content_id, data);
@@ -368,7 +358,7 @@ impl<T: Trait> ContentIdExists<T> for Module<T> {
     fn get_data_object(content_id: &T::ContentId) -> Result<DataObject<T>, &'static str> {
         match Self::data_object_by_content_id(*content_id) {
             Some(data) => Ok(data),
-            None => Err(Error::LiaisonRequired.into()),
+            None => Err(Error::<T>::LiaisonRequired.into()),
         }
     }
 }

+ 21 - 34
runtime-modules/storage/src/data_object_storage_registry.rs

@@ -23,14 +23,15 @@
 //#![warn(missing_docs)]
 
 use codec::{Codec, Decode, Encode};
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use frame_support::dispatch::DispatchResult;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_runtime::traits::{MaybeSerialize, Member};
 
 use crate::data_directory::{self, ContentIdExists};
 use crate::{StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
 
-const DEFAULT_FIRST_RELATIONSHIP_ID: u32 = 1;
+const DEFAULT_FIRST_RELATIONSHIP_ID: u8 = 1;
 
 /// The _Data object storage registry_ main _Trait_.
 pub trait Trait:
@@ -45,7 +46,7 @@ pub trait Trait:
     /// Type for data object storage relationship id
     type DataObjectStorageRelationshipId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -58,7 +59,7 @@ pub trait Trait:
 
 decl_error! {
     /// _Data object storage registry_ module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait>{
         /// Content with this ID not found.
         CidNotFound,
 
@@ -73,25 +74,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// Defines a relationship between the content and the storage provider
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectStorageRelationship<T: Trait> {
@@ -109,17 +91,19 @@ decl_storage! {
     trait Store for Module<T: Trait> as DataObjectStorageRegistry {
 
         /// Defines first relationship id.
-        pub FirstRelationshipId get(first_relationship_id) config(first_relationship_id):
+        pub FirstRelationshipId get(fn first_relationship_id) config(first_relationship_id):
             T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
 
         /// Defines next relationship id.
-        pub NextRelationshipId get(next_relationship_id) build(|config: &GenesisConfig<T>| config.first_relationship_id): T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
+        pub NextRelationshipId get(fn next_relationship_id) build(|config: &GenesisConfig<T>| config.first_relationship_id): T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
 
         /// Mapping of Data object types
-        pub Relationships get(relationships): map T::DataObjectStorageRelationshipId => Option<DataObjectStorageRelationship<T>>;
+        pub Relationships get(fn relationships): map hasher(blake2_128_concat)
+            T::DataObjectStorageRelationshipId => Option<DataObjectStorageRelationship<T>>;
 
         /// Keeps a list of storage relationships per content id.
-        pub RelationshipsByContentId get(relationships_by_content_id): map T::ContentId => Vec<T::DataObjectStorageRelationshipId>;
+        pub RelationshipsByContentId get(fn relationships_by_content_id): map hasher(blake2_128_concat)
+            T::ContentId => Vec<T::DataObjectStorageRelationshipId>;
     }
 }
 
@@ -152,16 +136,17 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors.
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Add storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_relationship(origin, storage_provider_id: StorageProviderId<T>, cid: T::ContentId) {
             // Origin should match storage provider.
             <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
             // Content ID must exist
-            ensure!(T::ContentIdExists::has_content(&cid), Error::CidNotFound);
+            ensure!(T::ContentIdExists::has_content(&cid), Error::<T>::CidNotFound);
 
             // Create new ID, data.
             let new_id = Self::next_relationship_id();
@@ -194,6 +179,7 @@ decl_module! {
 
         /// Activates storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group. A storage provider may flip their own ready state, but nobody else.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_relationship_ready(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -204,6 +190,7 @@ decl_module! {
 
         /// Deactivates storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group. A storage provider may flip their own ready state, but nobody else.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn unset_relationship_ready(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -220,16 +207,16 @@ impl<T: Trait> Module<T> {
         storage_provider_id: StorageProviderId<T>,
         id: T::DataObjectStorageRelationshipId,
         ready: bool,
-    ) -> Result<(), Error> {
+    ) -> DispatchResult {
         <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
         // For that, we need to fetch the identified DOSR
         let mut dosr =
-            Self::relationships(id).ok_or(Error::DataObjectStorageRelationshipNotFound)?;
+            Self::relationships(id).ok_or(Error::<T>::DataObjectStorageRelationshipNotFound)?;
 
         ensure!(
             dosr.storage_provider_id == storage_provider_id,
-            Error::OnlyStorageProviderMayClaimReady
+            Error::<T>::OnlyStorageProviderMayClaimReady
         );
 
         // Flip to ready

+ 25 - 34
runtime-modules/storage/src/data_object_type_registry.rs

@@ -22,14 +22,17 @@
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
 //#![warn(missing_docs)]
 
-use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
 use codec::{Codec, Decode, Encode};
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
+use frame_support::dispatch::DispatchError;
+use frame_support::weights::Weight;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_runtime::traits::{MaybeSerialize, Member};
+
+use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
 
 const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
-const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u32 = 1;
+const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u8 = 1;
 
 /// The _Data object type registry_ main _Trait_.
 pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstance> {
@@ -39,7 +42,7 @@ pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstanc
     /// _Data object type id_ type
     type DataObjectTypeId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -49,7 +52,7 @@ pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstanc
 
 decl_error! {
     /// _Data object type registry_ module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait> {
         /// Data Object Type with the given ID not found.
         DataObjectTypeNotFound,
 
@@ -58,25 +61,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// Contains description and constrains for the data object.
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectType {
@@ -99,15 +83,16 @@ impl Default for DataObjectType {
 decl_storage! {
     trait Store for Module<T: Trait> as DataObjectTypeRegistry {
         /// Data object type ids should start at this value.
-        pub FirstDataObjectTypeId get(first_data_object_type_id) config(first_data_object_type_id):
+        pub FirstDataObjectTypeId get(fn first_data_object_type_id) config(first_data_object_type_id):
             T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Provides id counter for the data object types.
-        pub NextDataObjectTypeId get(next_data_object_type_id) build(|config: &GenesisConfig<T>|
+        pub NextDataObjectTypeId get(fn next_data_object_type_id) build(|config: &GenesisConfig<T>|
             config.first_data_object_type_id): T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Mapping of Data object types.
-        pub DataObjectTypes get(data_object_types): map T::DataObjectTypeId => Option<DataObjectType>;
+        pub DataObjectTypes get(fn data_object_types): map hasher(blake2_128_concat)
+            T::DataObjectTypeId => Option<DataObjectType>;
     }
 }
 
@@ -134,20 +119,23 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors
-        type Error = Error;
+        type Error = Error<T>;
 
-        fn on_initialize() {
+        fn on_initialize() -> Weight{
             // Create a default data object type if it was not created yet.
-            if !<DataObjectTypes<T>>::exists(Self::first_data_object_type_id()) {
+            if !<DataObjectTypes<T>>::contains_key(Self::first_data_object_type_id()) {
                 let do_type: DataObjectType = DataObjectType::default();
                 let new_type_id = Self::next_data_object_type_id();
 
                 <DataObjectTypes<T>>::insert(new_type_id, do_type);
                 <NextDataObjectTypeId<T>>::mutate(|n| { *n += T::DataObjectTypeId::from(1); });
             }
+
+            10_000_000 //TODO: adjust weight
         }
 
         /// Registers the new data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn register_data_object_type(origin, data_object_type: DataObjectType) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -168,6 +156,7 @@ decl_module! {
         }
 
         /// Updates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_data_object_type(origin, id: T::DataObjectTypeId, data_object_type: DataObjectType) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -186,6 +175,7 @@ decl_module! {
         }
 
         /// Activates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn activate_data_object_type(origin, id: T::DataObjectTypeId) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -203,6 +193,7 @@ decl_module! {
         }
 
         /// Deactivates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn deactivate_data_object_type(origin, id: T::DataObjectTypeId) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -222,8 +213,8 @@ decl_module! {
 }
 
 impl<T: Trait> Module<T> {
-    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, Error> {
-        Self::data_object_types(&id).ok_or(Error::DataObjectTypeNotFound)
+    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, DispatchError> {
+        Self::data_object_types(&id).ok_or_else(|| Error::<T>::DataObjectTypeNotFound.into())
     }
 }
 

+ 29 - 7
runtime-modules/storage/src/tests/data_directory.rs

@@ -1,10 +1,11 @@
 #![cfg(test)]
 
-use super::mock::*;
-use crate::data_directory::Error;
+use frame_support::dispatch::DispatchError;
 use rstd::collections::btree_map::BTreeMap;
 use system::RawOrigin;
 
+use super::mock::*;
+
 #[test]
 fn succeed_adding_content() {
     with_default_mock_builder(|| {
@@ -36,13 +37,20 @@ fn add_content_fails_with_invalid_origin() {
             0,
             vec![1, 3, 3, 7],
         );
-        assert_eq!(res, Err(Error::Other("RequireSignedOrigin")));
+        assert_eq!(res, Err(DispatchError::Other("Bad origin")));
     });
 }
 
 #[test]
 fn accept_and_reject_content_fail_with_invalid_storage_provider() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -72,20 +80,27 @@ fn accept_and_reject_content_fail_with_invalid_storage_provider() {
             storage_provider_id,
             content_id,
         );
-        assert_eq!(res, Err(Error::Other("WorkerDoesNotExist")));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
 
         let res = TestDataDirectory::reject_content(
             Origin::signed(storage_provider_account_id),
             storage_provider_id,
             content_id,
         );
-        assert_eq!(res, Err(Error::Other("WorkerDoesNotExist")));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
 #[test]
 fn accept_content_as_liaison() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -130,6 +145,13 @@ fn accept_content_as_liaison() {
 #[test]
 fn reject_content_as_liaison() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -199,7 +221,7 @@ fn data_object_injection_works() {
         let content_id_2 = 2;
         objects.insert(content_id_2, object.clone());
 
-        let res = TestDataDirectory::inject_data_objects(Origin::ROOT, objects);
+        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
         assert!(res.is_ok());
 
         assert_eq!(
@@ -279,7 +301,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
         objects.insert(content_id_1, object1.clone());
         objects.insert(content_id_2, object2.clone());
 
-        let res = TestDataDirectory::inject_data_objects(Origin::ROOT, objects);
+        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
         assert!(res.is_ok());
 
         assert_eq!(

+ 10 - 3
runtime-modules/storage/src/tests/data_object_storage_registry.rs

@@ -22,7 +22,7 @@ fn add_relationship_fails_with_invalid_authorization() {
             storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -44,7 +44,7 @@ fn set_relationship_ready_fails_with_invalid_authorization() {
             invalid_storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -66,7 +66,7 @@ fn unset_relationship_ready_fails_with_invalid_authorization() {
             invalid_storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -100,6 +100,13 @@ fn test_fail_adding_relationship_with_bad_content() {
 #[test]
 fn test_toggle_ready() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let (account_id, storage_provider_id) = hire_storage_provider();
         // Create a DOSR
         let res = TestDataObjectStorageRegistry::add_relationship(

+ 71 - 15
runtime-modules/storage/src/tests/data_object_type_registry.rs

@@ -1,9 +1,10 @@
 #![cfg(test)]
 
-use super::mock::*;
-use srml_support::{StorageLinkedMap, StorageValue};
+use frame_support::{StorageMap, StorageValue};
 use system::{self, EventRecord, Phase, RawOrigin};
 
+use super::mock::*;
+
 const DEFAULT_LEADER_ACCOUNT_ID: u64 = 1;
 const DEFAULT_LEADER_MEMBER_ID: u64 = 1;
 const DEFAULT_LEADER_WORKER_ID: u32 = 1;
@@ -73,6 +74,13 @@ fn succeed_register() {
 #[test]
 fn activate_data_object_type_fails_with_invalid_lead() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         SetLeadFixture::set_default_lead();
 
         // First register a type
@@ -93,13 +101,26 @@ fn activate_data_object_type_fails_with_invalid_lead() {
             RawOrigin::Signed(invalid_leader_account_id).into(),
             dot_id,
         );
-        assert_eq!(res, Err(working_group::Error::IsNotLeadAccount.into()));
+        assert_eq!(
+            res,
+            Err(
+                working_group::Error::<Test, crate::StorageWorkingGroupInstance>::IsNotLeadAccount
+                    .into()
+            )
+        );
     });
 }
 
 #[test]
 fn deactivate_data_object_type_fails_with_invalid_lead() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         SetLeadFixture::set_default_lead();
 
         // First register a type
@@ -120,13 +141,26 @@ fn deactivate_data_object_type_fails_with_invalid_lead() {
             RawOrigin::Signed(invalid_leader_account_id).into(),
             dot_id,
         );
-        assert_eq!(res, Err(working_group::Error::IsNotLeadAccount.into()));
+        assert_eq!(
+            res,
+            Err(
+                working_group::Error::<Test, crate::StorageWorkingGroupInstance>::IsNotLeadAccount
+                    .into()
+            )
+        );
     });
 }
 
 #[test]
 fn update_data_object_type_fails_with_invalid_lead() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         SetLeadFixture::set_default_lead();
 
         // First register a type
@@ -152,13 +186,26 @@ fn update_data_object_type_fails_with_invalid_lead() {
             dot_id,
             updated1,
         );
-        assert_eq!(res, Err(working_group::Error::IsNotLeadAccount.into()));
+        assert_eq!(
+            res,
+            Err(
+                working_group::Error::<Test, crate::StorageWorkingGroupInstance>::IsNotLeadAccount
+                    .into()
+            )
+        );
     });
 }
 
 #[test]
 fn update_existing() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         SetLeadFixture::set_default_lead();
 
         // First register a type
@@ -201,7 +248,7 @@ fn update_existing() {
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
                     data_object_type_registry::RawEvent::DataObjectTypeUpdated(dot_id)
                 ),
@@ -230,6 +277,15 @@ fn register_data_object_type_failed_with_no_lead() {
 #[test]
 fn activate_existing() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
+        let expected_data_object_type_id = TEST_FIRST_DATA_OBJECT_TYPE_ID + 1; // on_initialize() increments the default value.
+
         SetLeadFixture::set_default_lead();
 
         // First register a type
@@ -245,10 +301,10 @@ fn activate_existing() {
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
                     data_object_type_registry::RawEvent::DataObjectTypeRegistered(
-                        TEST_FIRST_DATA_OBJECT_TYPE_ID
+                        expected_data_object_type_id
                     )
                 ),
                 topics: vec![],
@@ -256,23 +312,23 @@ fn activate_existing() {
         );
 
         // Retrieve, and ensure it's not active.
-        let data = TestDataObjectTypeRegistry::data_object_types(TEST_FIRST_DATA_OBJECT_TYPE_ID);
+        let data = TestDataObjectTypeRegistry::data_object_types(expected_data_object_type_id);
         assert!(data.is_some());
         assert!(!data.unwrap().active);
 
         // Now activate the data object type
         let res = TestDataObjectTypeRegistry::activate_data_object_type(
             RawOrigin::Signed(DEFAULT_LEADER_ACCOUNT_ID).into(),
-            TEST_FIRST_DATA_OBJECT_TYPE_ID,
+            expected_data_object_type_id,
         );
         assert!(res.is_ok());
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
                     data_object_type_registry::RawEvent::DataObjectTypeUpdated(
-                        TEST_FIRST_DATA_OBJECT_TYPE_ID
+                        expected_data_object_type_id
                     )
                 ),
                 topics: vec![],
@@ -280,17 +336,17 @@ fn activate_existing() {
         );
 
         // Ensure that the item is actually activated.
-        let data = TestDataObjectTypeRegistry::data_object_types(TEST_FIRST_DATA_OBJECT_TYPE_ID);
+        let data = TestDataObjectTypeRegistry::data_object_types(expected_data_object_type_id);
         assert!(data.is_some());
         assert!(data.unwrap().active);
 
         // Deactivate again.
         let res = TestDataObjectTypeRegistry::deactivate_data_object_type(
             RawOrigin::Signed(DEFAULT_LEADER_ACCOUNT_ID).into(),
-            TEST_FIRST_DATA_OBJECT_TYPE_ID,
+            expected_data_object_type_id,
         );
         assert!(res.is_ok());
-        let data = TestDataObjectTypeRegistry::data_object_types(TEST_FIRST_DATA_OBJECT_TYPE_ID);
+        let data = TestDataObjectTypeRegistry::data_object_types(expected_data_object_type_id);
         assert!(data.is_some());
         assert!(!data.unwrap().active);
     });

+ 43 - 30
runtime-modules/storage/src/tests/mock.rs

@@ -1,22 +1,21 @@
 #![cfg(test)]
 
-pub use crate::{data_directory, data_object_storage_registry, data_object_type_registry};
-pub use common::currency::GovernanceCurrency;
-use membership;
-pub use system;
-
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, Perbill,
+use frame_support::storage::StorageMap;
+use frame_support::traits::{OnFinalize, OnInitialize};
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
 
 use crate::data_directory::ContentIdExists;
 use crate::data_object_type_registry::IsActiveDataObjectType;
 pub use crate::StorageWorkingGroupInstance;
-use srml_support::{impl_outer_event, impl_outer_origin, parameter_types, StorageLinkedMap};
+pub use crate::{data_directory, data_object_storage_registry, data_object_type_registry};
+use common::currency::GovernanceCurrency;
+use membership;
 
 mod working_group_mod {
     pub use super::StorageWorkingGroupInstance;
@@ -39,6 +38,7 @@ impl_outer_event! {
         balances<T>,
         members<T>,
         working_group_mod StorageWorkingGroupInstance <T>,
+        system<T>,
     }
 }
 
@@ -97,10 +97,11 @@ parameter_types! {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -109,9 +110,17 @@ impl system::Trait for Test {
     type Event = MetaEvent;
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
 impl timestamp::Trait for Test {
@@ -122,28 +131,15 @@ impl timestamp::Trait for Test {
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
     pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = MetaEvent;
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = MetaEvent;
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl GovernanceCurrency for Test {
@@ -262,7 +258,7 @@ impl ExtBuilder {
         self.first_metadata_id = first_metadata_id;
         self
     }
-    pub fn build(self) -> runtime_io::TestExternalities {
+    pub fn build(self) -> sp_io::TestExternalities {
         let mut t = system::GenesisConfig::default()
             .build_storage::<Test>()
             .unwrap();
@@ -290,10 +286,11 @@ impl ExtBuilder {
     }
 }
 
+pub type TestDataObjectType = data_object_type_registry::DataObjectType;
+
 pub type Balances = balances::Module<Test>;
 pub type System = system::Module<Test>;
 pub type TestDataObjectTypeRegistry = data_object_type_registry::Module<Test>;
-pub type TestDataObjectType = data_object_type_registry::DataObjectType;
 pub type TestDataDirectory = data_directory::Module<Test>;
 pub type TestDataObjectStorageRegistry = data_object_storage_registry::Module<Test>;
 
@@ -325,3 +322,19 @@ pub(crate) fn hire_storage_provider() -> (u64, u32) {
 
     (role_account_id, storage_provider_id)
 }
+
+// Recommendation from Parity on testing on_finalize
+// https://substrate.dev/docs/en/next/development/module/tests
+pub fn run_to_block(n: u64) {
+    while System::block_number() < n {
+        <System as OnFinalize<u64>>::on_finalize(System::block_number());
+        <TestDataObjectTypeRegistry as OnFinalize<u64>>::on_finalize(System::block_number());
+        <TestDataDirectory as OnFinalize<u64>>::on_finalize(System::block_number());
+        <TestDataObjectStorageRegistry as OnFinalize<u64>>::on_finalize(System::block_number());
+        System::set_block_number(System::block_number() + 1);
+        <System as OnInitialize<u64>>::on_initialize(System::block_number());
+        <TestDataObjectTypeRegistry as OnInitialize<u64>>::on_initialize(System::block_number());
+        <TestDataDirectory as OnInitialize<u64>>::on_initialize(System::block_number());
+        <TestDataObjectStorageRegistry as OnInitialize<u64>>::on_initialize(System::block_number());
+    }
+}