Browse Source

Migrate storage module to substrate errors

Modules affected:
- data object type registry
- data object storage registry
Shamil Gadelshin 4 years ago
parent
commit
c6c22b1223

+ 51 - 14
runtime-modules/storage/src/data_object_storage_registry.rs

@@ -1,6 +1,6 @@
-// Clippy linter requirement
-// disable it because of the substrate lib design
-// example:  pub NextRelationshipId get(next_relationship_id) build(|config: &GenesisConfig<T>|
+// Clippy linter requirement.
+// Disable it because of the substrate lib design. Example:
+//  pub NextRelationshipId get(next_relationship_id) build(|config: &GenesisConfig<T>|
 #![allow(clippy::redundant_closure_call)]
 
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
@@ -10,11 +10,13 @@ use codec::{Codec, Decode, Encode};
 use roles::traits::Roles;
 use rstd::prelude::*;
 use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_event, decl_module, decl_storage, ensure, Parameter};
+use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
 
 use crate::data_directory::{self, ContentIdExists};
 use crate::StorageBureaucracy;
 
+const DEFAULT_FIRST_RELATIONSHIP_ID: u32 = 1;
+
 /// Storage provider is a worker from the bureuacracy module.
 pub type StorageProviderId<T> = bureaucracy::WorkerId<T>;
 
@@ -40,13 +42,41 @@ pub trait Trait:
     type ContentIdExists: data_directory::ContentIdExists<Self>;
 }
 
-// TODO: migrate to the Substrate error style
-static MSG_CID_NOT_FOUND: &str = "Content with this ID not found.";
-static MSG_DOSR_NOT_FOUND: &str = "No data object storage relationship found for this ID.";
-static MSG_ONLY_STORAGE_PROVIDER_MAY_CLAIM_READY: &str =
-    "Only the storage provider in a DOSR can decide whether they're ready.";
+decl_error! {
+    /// _Data object storage registry_ module predefined errors
+    pub enum Error {
+        /// Content with this ID not found.
+        CidNotFound,
 
-const DEFAULT_FIRST_RELATIONSHIP_ID: u32 = 1;
+        /// No data object storage relationship found for this ID.
+        DataObjectStorageRelationshipNotFound,
+
+        /// Only the storage provider in a DOSR can decide whether they're ready.
+        OnlyStorageProviderMayClaimReady,
+
+        /// Require root origin in extrinsics
+        RequireRootOrigin,
+    }
+}
+
+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<bureaucracy::Error> for Error {
+    fn from(error: bureaucracy::Error) -> Self {
+        match error {
+            bureaucracy::Error::Other(msg) => Error::Other(msg),
+            _ => Error::Other(error.into()),
+        }
+    }
+}
 
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectStorageRelationship<T: Trait> {
@@ -94,15 +124,20 @@ decl_event! {
 }
 
 decl_module! {
+    /// _Data object storage registry_ substrate module.
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+        /// Default deposit_event() handler
         fn deposit_event() = default;
 
+        /// Predefined errors
+        type Error = Error;
+
         pub fn add_relationship(origin, storage_provider_id: StorageProviderId<T>, cid: T::ContentId) {
             // Origin should match storage provider.
             <StorageBureaucracy<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
             // Content ID must exist
-            ensure!(T::ContentIdExists::has_content(&cid), MSG_CID_NOT_FOUND);
+            ensure!(T::ContentIdExists::has_content(&cid), Error::CidNotFound);
 
             // Create new ID, data.
             let new_id = Self::next_relationship_id();
@@ -154,14 +189,16 @@ impl<T: Trait> Module<T> {
         storage_provider_id: StorageProviderId<T>,
         id: T::DataObjectStorageRelationshipId,
         ready: bool,
-    ) -> Result<(), &'static str> {
+    ) -> Result<(), Error> {
         <StorageBureaucracy<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(MSG_DOSR_NOT_FOUND)?;
+        let mut dosr =
+            Self::relationships(id).ok_or(Error::DataObjectStorageRelationshipNotFound)?;
+
         ensure!(
             dosr.storage_provider_id == storage_provider_id,
-            MSG_ONLY_STORAGE_PROVIDER_MAY_CLAIM_READY
+            Error::OnlyStorageProviderMayClaimReady
         );
 
         // Flip to ready

+ 40 - 10
runtime-modules/storage/src/data_object_type_registry.rs

@@ -15,9 +15,9 @@
 //! - [deactivate_data_object_type](./struct.Module.html#method.deactivate_data_object_type) -  Deactivates existing data object type.
 //!
 
-// Clippy linter requirement
-// disable it because of the substrate lib design
-// example:   NextDataObjectTypeId get(next_data_object_type_id) build(|config: &GenesisConfig<T>|
+// Clippy linter requirement.
+// Disable it because of the substrate lib design. Example:
+//   NextDataObjectTypeId get(next_data_object_type_id) build(|config: &GenesisConfig<T>|
 #![allow(clippy::redundant_closure_call)]
 
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
@@ -27,7 +27,10 @@ use crate::StorageBureaucracy;
 use codec::{Codec, Decode, Encode};
 use rstd::prelude::*;
 use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_event, decl_module, decl_storage, Parameter};
+use srml_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
+
+const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
+const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u32 = 1;
 
 /// The _Data object type registry_ main _Trait_
 pub trait Trait: system::Trait + bureaucracy::Trait<bureaucracy::Instance2> {
@@ -45,11 +48,35 @@ pub trait Trait: system::Trait + bureaucracy::Trait<bureaucracy::Instance2> {
         + PartialEq;
 }
 
-// TODO: migrate to the Substrate error style
-const MSG_DO_TYPE_NOT_FOUND: &str = "Data Object Type with the given ID not found.";
-const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
+decl_error! {
+    /// _Data object type registry_ module predefined errors
+    pub enum Error {
+        /// Data Object Type with the given ID not found.
+        DataObjectTypeNotFound,
 
-const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u32 = 1;
+        /// Require root origin in extrinsics
+        RequireRootOrigin,
+    }
+}
+
+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<bureaucracy::Error> for Error {
+    fn from(error: bureaucracy::Error) -> Self {
+        match error {
+            bureaucracy::Error::Other(msg) => Error::Other(msg),
+            _ => Error::Other(error.into()),
+        }
+    }
+}
 
 /// Contains description and constrains for the data object.
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
@@ -114,6 +141,9 @@ decl_module! {
         /// Default deposit_event() handler
         fn deposit_event() = default;
 
+        /// Predefined errors
+        type Error = Error;
+
         fn on_initialize() {
             // Create a default data object type if it was not created yet.
             if !<DataObjectTypes<T>>::exists(Self::first_data_object_type_id()) {
@@ -184,8 +214,8 @@ decl_module! {
 }
 
 impl<T: Trait> Module<T> {
-    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, &'static str> {
-        Self::data_object_types(&id).ok_or(MSG_DO_TYPE_NOT_FOUND)
+    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, Error> {
+        Self::data_object_types(&id).ok_or(Error::DataObjectTypeNotFound)
     }
 }