From a4c152f9533ac20fc1fff6179d72cdd68483c81f Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 10:43:10 +0100 Subject: [PATCH 01/17] For #7, implment simple Data Object Type registry --- src/lib.rs | 13 ++++- src/storage/mod.rs | 3 + src/storage/types.rs | 135 +++++++++++++++++++++++++++++++++++++++++++ src/traits.rs | 11 ++++ 4 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/storage/mod.rs create mode 100644 src/storage/types.rs create mode 100644 src/traits.rs diff --git a/src/lib.rs b/src/lib.rs index 77adf189ae..c728fb6734 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,10 @@ extern crate parity_codec_derive; pub mod governance; use governance::{election, council, proposals}; +pub mod storage; +use storage::{types}; mod memo; +mod traits; use rstd::prelude::*; #[cfg(feature = "std")] @@ -24,7 +27,7 @@ use primitives::bytes; use primitives::{Ed25519AuthorityId, OpaqueMetadata}; use runtime_primitives::{ ApplyResult, transaction_validity::TransactionValidity, Ed25519Signature, generic, - traits::{self, Convert, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str + traits::{self as runtime_traits, Convert, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str }; use client::{ block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, @@ -67,7 +70,7 @@ pub mod opaque { #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - impl traits::Extrinsic for UncheckedExtrinsic { + impl runtime_traits::Extrinsic for UncheckedExtrinsic { fn is_signed(&self) -> Option { None } @@ -224,6 +227,11 @@ impl memo::Trait for Runtime { type Event = Event; } +impl storage::types::Trait for Runtime { + type Event = Event; + type DataObjectTypeID = u64; +} + construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem) where Block = Block, @@ -244,6 +252,7 @@ construct_runtime!( CouncilElection: election::{Module, Call, Storage, Event, Config}, Council: council::{Module, Call, Storage, Event, Config}, Memo: memo::{Module, Call, Storage, Event}, + DataObjectType: types::{Module, Call, Storage, Event, Config}, } ); diff --git a/src/storage/mod.rs b/src/storage/mod.rs new file mode 100644 index 0000000000..3d799e20b0 --- /dev/null +++ b/src/storage/mod.rs @@ -0,0 +1,3 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod types; diff --git a/src/storage/types.rs b/src/storage/types.rs new file mode 100644 index 0000000000..44dbec0c4e --- /dev/null +++ b/src/storage/types.rs @@ -0,0 +1,135 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use parity_codec::Codec; +use parity_codec_derive::{Encode, Decode}; +use srml_support::{StorageMap, StorageValue, decl_module, decl_storage, decl_event, ensure, Parameter}; +use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeSerializeDebug}; +use system::{self}; +use crate::governance::GovernanceCurrency; +use crate::traits; + +pub trait Trait: system::Trait + GovernanceCurrency +{ + type Event: From> + Into<::Event>; + + type DataObjectTypeID: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + + As + As + MaybeSerializeDebug + PartialEq; +} + +static MSG_REQUIRE_NEW_DOT: &str = "New Data Object Type required; the provided one seems to be in use already!"; +static MSG_DOT_NOT_FOUND: &str = "Data Object Type with the given ID not found!"; +static MSG_REQUIRE_DOT_ID: &str = "Can only update Data Object Types that are already registered (with an ID)!"; +static MSG_REQUIRE_EXISTING_DOT: &str = "Can only update Data Object Types that are already registered!"; + +const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u64 = 1; + +#[derive(Encode, Decode, Clone, PartialEq)] +pub struct ObjectType +{ + // If the OT is registered, an ID must exist, otherwise it's a new OT. + pub id: Option, + pub description: Vec, + pub active: bool, + + // TODO in future releases + // - replication factor + // - storage trances (empty is ok) +} + +decl_storage! { + trait Store for Module as DataObjectTypeRegistry + { + // Start at this value + pub FirstDataObjectTypeID get(first_data_object_type_id) config(first_data_object_type_id): T::DataObjectTypeID = T::DataObjectTypeID::sa(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID); + + // Increment + pub NextDataObjectTypeID get(next_data_object_type_id) build(|config: &GenesisConfig| config.first_data_object_type_id): T::DataObjectTypeID = T::DataObjectTypeID::sa(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID); + + // Mapping of Data object types + pub DataObjectType get(data_object_type): map T::DataObjectTypeID => Option>; + } +} + +decl_event! { + pub enum Event where + ::DataObjectTypeID + { + DataObjectTypeAdded(DataObjectTypeID), + DataObjectTypeUpdated(DataObjectTypeID), + } +} + + + +impl traits::IsActiveDataObjectType for Module +{ + fn is_active_data_object_type(which: &T::DataObjectTypeID) -> bool + { + match Self::ensure_data_object_type(*which) + { + Ok(dot) => dot.active, + Err(err) => false + } + } +} + + +decl_module! { + pub struct Module for enum Call where origin: T::Origin + { + fn deposit_event() = default; + + fn register_data_object_type(data_object_type: ObjectType) + { + ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); + + let new_dot_id = Self::next_data_object_type_id(); + let dot: ObjectType = ObjectType { + id: Some(new_dot_id), + description: data_object_type.description.clone(), + active: data_object_type.active, + }; + + >::insert(new_dot_id, dot); + >::mutate(|n| { *n += T::DataObjectTypeID::sa(1); }); + + Self::deposit_event(RawEvent::DataObjectTypeAdded(new_dot_id)); + } + + fn update_data_object_type(data_object_type: ObjectType) + { + ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); + + let id = data_object_type.id.unwrap(); + let mut dot = Self::ensure_data_object_type(id)?; + + dot.description = data_object_type.description.clone(); + dot.active = data_object_type.active; + + >::insert(id, dot); + + Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); + } + + fn activate_data_object_type(id: T::DataObjectTypeID, active: bool) + { + let mut dot = Self::ensure_data_object_type(id)?; + + dot.active = active; + + >::insert(id, dot); + + Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); + } + } +} + +impl Module +{ + fn ensure_data_object_type(id: T::DataObjectTypeID) -> Result, &'static str> + { + let dot = Self::data_object_type(&id).ok_or(MSG_DOT_NOT_FOUND)?; + Ok(dot) + } +} diff --git a/src/traits.rs b/src/traits.rs new file mode 100644 index 0000000000..d5533c70e3 --- /dev/null +++ b/src/traits.rs @@ -0,0 +1,11 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use crate::storage::types; + +pub trait IsActiveDataObjectType +{ + fn is_active_data_object_type(which: &T::DataObjectTypeID) -> bool + { + false + } +} From 8668f1b1c8625c7320724def05eb11fff8f25e99 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 10:45:46 +0100 Subject: [PATCH 02/17] Fix comment typo --- src/storage/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/types.rs b/src/storage/types.rs index 44dbec0c4e..8b7a7bbc09 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -34,7 +34,7 @@ pub struct ObjectType // TODO in future releases // - replication factor - // - storage trances (empty is ok) + // - storage tranches (empty is ok) } decl_storage! { From 8d66c1204c58517388d273a3aa1b54ac2a77c80d Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 14:48:19 +0100 Subject: [PATCH 03/17] These extrinsics should be public --- src/storage/types.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storage/types.rs b/src/storage/types.rs index 8b7a7bbc09..b0da249d28 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -80,7 +80,7 @@ decl_module! { { fn deposit_event() = default; - fn register_data_object_type(data_object_type: ObjectType) + pub fn register_data_object_type(data_object_type: ObjectType) { ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); @@ -97,7 +97,7 @@ decl_module! { Self::deposit_event(RawEvent::DataObjectTypeAdded(new_dot_id)); } - fn update_data_object_type(data_object_type: ObjectType) + pub fn update_data_object_type(data_object_type: ObjectType) { ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); @@ -112,7 +112,7 @@ decl_module! { Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } - fn activate_data_object_type(id: T::DataObjectTypeID, active: bool) + pub fn activate_data_object_type(id: T::DataObjectTypeID, active: bool) { let mut dot = Self::ensure_data_object_type(id)?; From ff33136d05551d3f64327cad95a94e42d6e3a33b Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 14:54:43 +0100 Subject: [PATCH 04/17] Be explicit about requiring root. IMHO this is better style. --- src/storage/types.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/storage/types.rs b/src/storage/types.rs index b0da249d28..989824f2ad 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -5,7 +5,7 @@ use parity_codec::Codec; use parity_codec_derive::{Encode, Decode}; use srml_support::{StorageMap, StorageValue, decl_module, decl_storage, decl_event, ensure, Parameter}; use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeSerializeDebug}; -use system::{self}; +use system::{self, ensure_root}; use crate::governance::GovernanceCurrency; use crate::traits; @@ -80,8 +80,9 @@ decl_module! { { fn deposit_event() = default; - pub fn register_data_object_type(data_object_type: ObjectType) + pub fn register_data_object_type(origin, data_object_type: ObjectType) { + ensure_root(origin); ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); let new_dot_id = Self::next_data_object_type_id(); @@ -97,8 +98,9 @@ decl_module! { Self::deposit_event(RawEvent::DataObjectTypeAdded(new_dot_id)); } - pub fn update_data_object_type(data_object_type: ObjectType) + pub fn update_data_object_type(origin, data_object_type: ObjectType) { + ensure_root(origin); ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); let id = data_object_type.id.unwrap(); @@ -112,8 +114,9 @@ decl_module! { Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } - pub fn activate_data_object_type(id: T::DataObjectTypeID, active: bool) + pub fn activate_data_object_type(origin, id: T::DataObjectTypeID, active: bool) { + ensure_root(origin); let mut dot = Self::ensure_data_object_type(id)?; dot.active = active; From ba3413d61ace8dda349797f02afebdfda87e9b1f Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 16:57:32 +0100 Subject: [PATCH 05/17] Unit test setup for storage module --- src/storage/mock.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++ src/storage/mod.rs | 2 ++ src/storage/tests.rs | 24 ++++++++++++++++++++ src/storage/types.rs | 8 +++---- 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/storage/mock.rs create mode 100644 src/storage/tests.rs diff --git a/src/storage/mock.rs b/src/storage/mock.rs new file mode 100644 index 0000000000..799d36129b --- /dev/null +++ b/src/storage/mock.rs @@ -0,0 +1,53 @@ +#![cfg(test)] + +use rstd::prelude::*; +pub use super::{types}; +pub use system; + +pub use primitives::{H256, Blake2Hasher}; +pub use runtime_primitives::{ + BuildStorage, + traits::{BlakeTwo256, OnFinalise, IdentityLookup}, + testing::{Digest, DigestItem, Header, UintAuthorityId} +}; + +use srml_support::impl_outer_origin; + +impl_outer_origin! { + pub enum Origin for Test {} +} + +// For testing the module, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of modules we want to use. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct Test; +impl system::Trait for Test +{ + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type Digest = Digest; + type AccountId = u64; + type Header = Header; + type Event = (); + type Log = DigestItem; + type Lookup = IdentityLookup; +} +impl types::Trait for Test +{ + type Event = (); + type DataObjectTypeID = u64; +} + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn initial_test_ext() -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + + runtime_io::TestExternalities::new(t) +} + +pub type Types = types::Module; diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 3d799e20b0..84d813f0ad 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,3 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod types; + +mod mock; diff --git a/src/storage/tests.rs b/src/storage/tests.rs new file mode 100644 index 0000000000..d5323dad9a --- /dev/null +++ b/src/storage/tests.rs @@ -0,0 +1,24 @@ +#![cfg(test)] + +use super::*; +use super::mock::*; + +use parity_codec::Encode; +use runtime_io::with_externalities; +use srml_support::*; + +#[test] +fn initial_state() +{ + const DEFAULT_FIRST_ID: u32 = 1000; + + with_externalities(&mut ExtBuilder::default() + .first_data_object_id(DEFAULT_FIRST_ID).build(), || + { + assert_eq!(DataObjectType::first_data_object_id(), DEFAULT_FIRST_ID); + + // TODO + + assert_ok!(false); + }); +} diff --git a/src/storage/types.rs b/src/storage/types.rs index 989824f2ad..bd6de688dd 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -6,10 +6,10 @@ use parity_codec_derive::{Encode, Decode}; use srml_support::{StorageMap, StorageValue, decl_module, decl_storage, decl_event, ensure, Parameter}; use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeSerializeDebug}; use system::{self, ensure_root}; -use crate::governance::GovernanceCurrency; +use std::fmt; use crate::traits; -pub trait Trait: system::Trait + GovernanceCurrency +pub trait Trait: system::Trait + fmt::Debug { type Event: From> + Into<::Event>; @@ -17,14 +17,14 @@ pub trait Trait: system::Trait + GovernanceCurrency + As + As + MaybeSerializeDebug + PartialEq; } + static MSG_REQUIRE_NEW_DOT: &str = "New Data Object Type required; the provided one seems to be in use already!"; static MSG_DOT_NOT_FOUND: &str = "Data Object Type with the given ID not found!"; static MSG_REQUIRE_DOT_ID: &str = "Can only update Data Object Types that are already registered (with an ID)!"; -static MSG_REQUIRE_EXISTING_DOT: &str = "Can only update Data Object Types that are already registered!"; const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u64 = 1; -#[derive(Encode, Decode, Clone, PartialEq)] +#[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct ObjectType { // If the OT is registered, an ID must exist, otherwise it's a new OT. From 913538b40a8d1db45706c0741e75b86bd96b3810 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 17:12:41 +0100 Subject: [PATCH 06/17] Get unit tests to run --- src/storage/mock.rs | 37 ++++++++++++++++++++++++++++++++----- src/storage/mod.rs | 1 + src/storage/tests.rs | 8 ++++---- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/storage/mock.rs b/src/storage/mock.rs index 799d36129b..e30b4d1a34 100644 --- a/src/storage/mock.rs +++ b/src/storage/mock.rs @@ -42,12 +42,39 @@ impl types::Trait for Test type DataObjectTypeID = u64; } -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. -pub fn initial_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; +pub struct ExtBuilder +{ + first_data_object_type_id: u64, +} - runtime_io::TestExternalities::new(t) +impl Default for ExtBuilder +{ + fn default() -> Self + { + Self { + first_data_object_type_id: 1, + } + } } +impl ExtBuilder +{ + pub fn first_data_object_type_id(mut self, first_data_object_type_id: u64) -> Self + { + self.first_data_object_type_id = first_data_object_type_id; + self + } + pub fn build(self) -> runtime_io::TestExternalities + { + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + + t.extend(types::GenesisConfig::{ + first_data_object_type_id: self.first_data_object_type_id, + }.build_storage().unwrap().0); + + t.into() + } +} + + pub type Types = types::Module; diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 84d813f0ad..f50e2661c0 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -3,3 +3,4 @@ pub mod types; mod mock; +mod tests; diff --git a/src/storage/tests.rs b/src/storage/tests.rs index d5323dad9a..5cd08bdcd3 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -10,15 +10,15 @@ use srml_support::*; #[test] fn initial_state() { - const DEFAULT_FIRST_ID: u32 = 1000; + const DEFAULT_FIRST_ID: u64 = 1000; with_externalities(&mut ExtBuilder::default() - .first_data_object_id(DEFAULT_FIRST_ID).build(), || + .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || { - assert_eq!(DataObjectType::first_data_object_id(), DEFAULT_FIRST_ID); + assert_eq!(Types::first_data_object_type_id(), DEFAULT_FIRST_ID); // TODO - assert_ok!(false); + assert_ok!(Err(123)); }); } From 6c14ac713e878eb507ad26df0972d3a1564e3cd9 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 17:46:05 +0100 Subject: [PATCH 07/17] Make unit tests work, but still allow building wasm runtime. --- src/storage/tests.rs | 1 - src/storage/types.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/storage/tests.rs b/src/storage/tests.rs index 5cd08bdcd3..fbec019da7 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -3,7 +3,6 @@ use super::*; use super::mock::*; -use parity_codec::Encode; use runtime_io::with_externalities; use srml_support::*; diff --git a/src/storage/types.rs b/src/storage/types.rs index bd6de688dd..802b9f3e92 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -4,12 +4,11 @@ use rstd::prelude::*; use parity_codec::Codec; use parity_codec_derive::{Encode, Decode}; use srml_support::{StorageMap, StorageValue, decl_module, decl_storage, decl_event, ensure, Parameter}; -use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeSerializeDebug}; +use runtime_primitives::traits::{SimpleArithmetic, As, Member, MaybeSerializeDebug, MaybeDebug}; use system::{self, ensure_root}; -use std::fmt; use crate::traits; -pub trait Trait: system::Trait + fmt::Debug +pub trait Trait: system::Trait + MaybeDebug { type Event: From> + Into<::Event>; @@ -24,7 +23,8 @@ static MSG_REQUIRE_DOT_ID: &str = "Can only update Data Object Types that are al const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u64 = 1; -#[derive(Clone, Debug, Encode, Decode, PartialEq)] +#[derive(Clone, Encode, Decode, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] pub struct ObjectType { // If the OT is registered, an ID must exist, otherwise it's a new OT. From c928b8866df478757736919fe7cbc18784cacb54 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 17:48:43 +0100 Subject: [PATCH 08/17] Silence warning --- src/storage/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/types.rs b/src/storage/types.rs index 802b9f3e92..ee633a7311 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -69,7 +69,7 @@ impl traits::IsActiveDataObjectType for Module match Self::ensure_data_object_type(*which) { Ok(dot) => dot.active, - Err(err) => false + Err(_err) => false } } } From 854378a46f21e875784c4dc72fd53a7f4437c639 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 18:41:17 +0100 Subject: [PATCH 09/17] Cover extrinsics with unit tests --- src/storage/mock.rs | 15 ++++- src/storage/tests.rs | 143 ++++++++++++++++++++++++++++++++++++++++++- src/storage/types.rs | 6 +- 3 files changed, 156 insertions(+), 8 deletions(-) diff --git a/src/storage/mock.rs b/src/storage/mock.rs index e30b4d1a34..b30135d8f9 100644 --- a/src/storage/mock.rs +++ b/src/storage/mock.rs @@ -11,12 +11,19 @@ pub use runtime_primitives::{ testing::{Digest, DigestItem, Header, UintAuthorityId} }; -use srml_support::impl_outer_origin; +use srml_support::{impl_outer_origin, impl_outer_event}; impl_outer_origin! { pub enum Origin for Test {} } +impl_outer_event! { + pub enum MetaEvent for Test + { + types, + } +} + // For testing the module, we construct most of a mock runtime. This means // first constructing a configuration type (`Test`) which `impl`s each of the // configuration traits of modules we want to use. @@ -32,13 +39,13 @@ impl system::Trait for Test type Digest = Digest; type AccountId = u64; type Header = Header; - type Event = (); + type Event = MetaEvent; type Log = DigestItem; type Lookup = IdentityLookup; } impl types::Trait for Test { - type Event = (); + type Event = MetaEvent; type DataObjectTypeID = u64; } @@ -77,4 +84,6 @@ impl ExtBuilder } +pub type System = system::Module; pub type Types = types::Module; +pub type TestDataObjectType = types::ObjectType; diff --git a/src/storage/tests.rs b/src/storage/tests.rs index fbec019da7..2f9df21172 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -5,6 +5,7 @@ use super::mock::*; use runtime_io::with_externalities; use srml_support::*; +use system::{self, Phase, EventRecord}; #[test] fn initial_state() @@ -15,9 +16,147 @@ fn initial_state() .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || { assert_eq!(Types::first_data_object_type_id(), DEFAULT_FIRST_ID); + }); +} + +#[test] +fn fail_register_without_root() +{ + const DEFAULT_FIRST_ID: u64 = 1000; + + with_externalities(&mut ExtBuilder::default() + .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || + { + let data: TestDataObjectType = TestDataObjectType { + id: None, + description: "foo".as_bytes().to_vec(), + active: false, + }; + let res = Types::register_data_object_type(Origin::signed(1), data); + assert!(res.is_err()); + }); +} + +#[test] +fn succeed_register_as_root() +{ + const DEFAULT_FIRST_ID: u64 = 1000; + + with_externalities(&mut ExtBuilder::default() + .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || + { + let data: TestDataObjectType = TestDataObjectType { + id: None, + description: "foo".as_bytes().to_vec(), + active: false, + }; + let res = Types::register_data_object_type(Origin::ROOT, data); + assert!(res.is_ok()); + }); +} + +#[test] +fn update_existing() +{ + const DEFAULT_FIRST_ID: u64 = 1000; + + with_externalities(&mut ExtBuilder::default() + .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || + { + // First register a type + let data: TestDataObjectType = TestDataObjectType { + id: None, + description: "foo".as_bytes().to_vec(), + active: false, + }; + let id_res = Types::register_data_object_type(Origin::ROOT, data); + assert!(id_res.is_ok()); + assert_eq!(*System::events().last().unwrap(), + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + } + ); + + + // Now update it with new data - we need the ID to be the same as in + // returned by the previous call. First, though, try and fail without + let updated1: TestDataObjectType = TestDataObjectType { + id: None, + description: "bar".as_bytes().to_vec(), + active: false, + }; + let res = Types::update_data_object_type(Origin::ROOT, updated1); + assert!(res.is_err()); + + // Now try with a bad ID + let updated2: TestDataObjectType = TestDataObjectType { + id: Some(DEFAULT_FIRST_ID + 1), + description: "bar".as_bytes().to_vec(), + active: false, + }; + let res = Types::update_data_object_type(Origin::ROOT, updated2); + assert!(res.is_err()); + + // Finally with an existing ID, it should work. + let updated3: TestDataObjectType = TestDataObjectType { + id: Some(DEFAULT_FIRST_ID), + description: "bar".as_bytes().to_vec(), + active: false, + }; + let res = Types::update_data_object_type(Origin::ROOT, updated3); + assert!(res.is_ok()); + assert_eq!(*System::events().last().unwrap(), + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + } + ); + }); +} + + +#[test] +fn activate_existing() +{ + const DEFAULT_FIRST_ID: u64 = 1000; + + with_externalities(&mut ExtBuilder::default() + .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || + { + // First register a type + let data: TestDataObjectType = TestDataObjectType { + id: None, + description: "foo".as_bytes().to_vec(), + active: false, + }; + let id_res = Types::register_data_object_type(Origin::ROOT, data); + assert!(id_res.is_ok()); + assert_eq!(*System::events().last().unwrap(), + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + } + ); + + // Retrieve, and ensure it's not active. + let data = Types::data_object_type(DEFAULT_FIRST_ID); + assert!(data.is_some()); + assert!(!data.unwrap().active); - // TODO + // Now activate the data object type + let res = Types::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); + assert!(res.is_ok()); + assert_eq!(*System::events().last().unwrap(), + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + } + ); - assert_ok!(Err(123)); + // Ensure that the item is actually activated. + let data = Types::data_object_type(DEFAULT_FIRST_ID); + assert!(data.is_some()); + assert!(data.unwrap().active); }); } diff --git a/src/storage/types.rs b/src/storage/types.rs index ee633a7311..41c9dfd79f 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -82,7 +82,7 @@ decl_module! { pub fn register_data_object_type(origin, data_object_type: ObjectType) { - ensure_root(origin); + ensure_root(origin)?; ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); let new_dot_id = Self::next_data_object_type_id(); @@ -100,7 +100,7 @@ decl_module! { pub fn update_data_object_type(origin, data_object_type: ObjectType) { - ensure_root(origin); + ensure_root(origin)?; ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); let id = data_object_type.id.unwrap(); @@ -116,7 +116,7 @@ decl_module! { pub fn activate_data_object_type(origin, id: T::DataObjectTypeID, active: bool) { - ensure_root(origin); + ensure_root(origin)?; let mut dot = Self::ensure_data_object_type(id)?; dot.active = active; From 0286059dc984e095c627a223ae4a10054f722a5c Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Mon, 25 Mar 2019 18:47:31 +0100 Subject: [PATCH 10/17] Improve naming --- src/storage/mock.rs | 2 +- src/storage/types.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/storage/mock.rs b/src/storage/mock.rs index b30135d8f9..c9b5b8ab84 100644 --- a/src/storage/mock.rs +++ b/src/storage/mock.rs @@ -86,4 +86,4 @@ impl ExtBuilder pub type System = system::Module; pub type Types = types::Module; -pub type TestDataObjectType = types::ObjectType; +pub type TestDataObjectType = types::DataObjectType; diff --git a/src/storage/types.rs b/src/storage/types.rs index 41c9dfd79f..90855a3c54 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -25,7 +25,7 @@ const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u64 = 1; #[derive(Clone, Encode, Decode, PartialEq)] #[cfg_attr(feature = "std", derive(Debug))] -pub struct ObjectType +pub struct DataObjectType { // If the OT is registered, an ID must exist, otherwise it's a new OT. pub id: Option, @@ -47,7 +47,7 @@ decl_storage! { pub NextDataObjectTypeID get(next_data_object_type_id) build(|config: &GenesisConfig| config.first_data_object_type_id): T::DataObjectTypeID = T::DataObjectTypeID::sa(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID); // Mapping of Data object types - pub DataObjectType get(data_object_type): map T::DataObjectTypeID => Option>; + pub DataObjectTypeMap get(data_object_type): map T::DataObjectTypeID => Option>; } } @@ -80,25 +80,25 @@ decl_module! { { fn deposit_event() = default; - pub fn register_data_object_type(origin, data_object_type: ObjectType) + pub fn register_data_object_type(origin, data_object_type: DataObjectType) { ensure_root(origin)?; ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); let new_dot_id = Self::next_data_object_type_id(); - let dot: ObjectType = ObjectType { + let dot: DataObjectType = DataObjectType { id: Some(new_dot_id), description: data_object_type.description.clone(), active: data_object_type.active, }; - >::insert(new_dot_id, dot); + >::insert(new_dot_id, dot); >::mutate(|n| { *n += T::DataObjectTypeID::sa(1); }); Self::deposit_event(RawEvent::DataObjectTypeAdded(new_dot_id)); } - pub fn update_data_object_type(origin, data_object_type: ObjectType) + pub fn update_data_object_type(origin, data_object_type: DataObjectType) { ensure_root(origin)?; ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); @@ -109,7 +109,7 @@ decl_module! { dot.description = data_object_type.description.clone(); dot.active = data_object_type.active; - >::insert(id, dot); + >::insert(id, dot); Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } @@ -121,7 +121,7 @@ decl_module! { dot.active = active; - >::insert(id, dot); + >::insert(id, dot); Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } @@ -130,7 +130,7 @@ decl_module! { impl Module { - fn ensure_data_object_type(id: T::DataObjectTypeID) -> Result, &'static str> + fn ensure_data_object_type(id: T::DataObjectTypeID) -> Result, &'static str> { let dot = Self::data_object_type(&id).ok_or(MSG_DOT_NOT_FOUND)?; Ok(dot) From 61dfc3ca442a48833cb04d93637b30f47744f7e5 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 14:11:26 +0100 Subject: [PATCH 11/17] Fixes #14 --- src/storage/types.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/storage/types.rs b/src/storage/types.rs index 90855a3c54..316b221fb4 100644 --- a/src/storage/types.rs +++ b/src/storage/types.rs @@ -17,9 +17,9 @@ pub trait Trait: system::Trait + MaybeDebug } -static MSG_REQUIRE_NEW_DOT: &str = "New Data Object Type required; the provided one seems to be in use already!"; -static MSG_DOT_NOT_FOUND: &str = "Data Object Type with the given ID not found!"; -static MSG_REQUIRE_DOT_ID: &str = "Can only update Data Object Types that are already registered (with an ID)!"; +static MSG_REQUIRE_NEW_DO_TYPE: &str = "New Data Object Type required; the provided one seems to be in use already!"; +static MSG_DO_TYPE_NOT_FOUND: &str = "Data Object Type with the given ID not found!"; +static MSG_REQUIRE_DO_TYPE_ID: &str = "Can only update Data Object Types that are already registered (with an ID)!"; const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u64 = 1; @@ -68,7 +68,7 @@ impl traits::IsActiveDataObjectType for Module { match Self::ensure_data_object_type(*which) { - Ok(dot) => dot.active, + Ok(do_type) => do_type.active, Err(_err) => false } } @@ -83,33 +83,33 @@ decl_module! { pub fn register_data_object_type(origin, data_object_type: DataObjectType) { ensure_root(origin)?; - ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DOT); + ensure!(data_object_type.id.is_none(), MSG_REQUIRE_NEW_DO_TYPE); - let new_dot_id = Self::next_data_object_type_id(); - let dot: DataObjectType = DataObjectType { - id: Some(new_dot_id), + let new_do_type_id = Self::next_data_object_type_id(); + let do_type: DataObjectType = DataObjectType { + id: Some(new_do_type_id), description: data_object_type.description.clone(), active: data_object_type.active, }; - >::insert(new_dot_id, dot); + >::insert(new_do_type_id, do_type); >::mutate(|n| { *n += T::DataObjectTypeID::sa(1); }); - Self::deposit_event(RawEvent::DataObjectTypeAdded(new_dot_id)); + Self::deposit_event(RawEvent::DataObjectTypeAdded(new_do_type_id)); } pub fn update_data_object_type(origin, data_object_type: DataObjectType) { ensure_root(origin)?; - ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DOT_ID); + ensure!(data_object_type.id.is_some(), MSG_REQUIRE_DO_TYPE_ID); let id = data_object_type.id.unwrap(); - let mut dot = Self::ensure_data_object_type(id)?; + let mut do_type = Self::ensure_data_object_type(id)?; - dot.description = data_object_type.description.clone(); - dot.active = data_object_type.active; + do_type.description = data_object_type.description.clone(); + do_type.active = data_object_type.active; - >::insert(id, dot); + >::insert(id, do_type); Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } @@ -117,11 +117,11 @@ decl_module! { pub fn activate_data_object_type(origin, id: T::DataObjectTypeID, active: bool) { ensure_root(origin)?; - let mut dot = Self::ensure_data_object_type(id)?; + let mut do_type = Self::ensure_data_object_type(id)?; - dot.active = active; + do_type.active = active; - >::insert(id, dot); + >::insert(id, do_type); Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } @@ -132,7 +132,7 @@ impl Module { fn ensure_data_object_type(id: T::DataObjectTypeID) -> Result, &'static str> { - let dot = Self::data_object_type(&id).ok_or(MSG_DOT_NOT_FOUND)?; - Ok(dot) + let do_type = Self::data_object_type(&id).ok_or(MSG_DO_TYPE_NOT_FOUND)?; + Ok(do_type) } } From a695dd27fcc09be0babcbe183b2f0eb578a9ad2b Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 14:15:28 +0100 Subject: [PATCH 12/17] Respond to comment about consistent naming. I think the best compromise is to call the module file `type_registry`, and the use the full `DataObjectTypeRegistry` name for the Module. --- src/lib.rs | 6 ++--- src/storage/mock.rs | 12 ++++----- src/storage/mod.rs | 2 +- src/storage/tests.rs | 30 +++++++++++----------- src/storage/{types.rs => type_registry.rs} | 0 src/traits.rs | 4 +-- 6 files changed, 27 insertions(+), 27 deletions(-) rename src/storage/{types.rs => type_registry.rs} (100%) diff --git a/src/lib.rs b/src/lib.rs index c728fb6734..82f3e2f638 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ extern crate parity_codec_derive; pub mod governance; use governance::{election, council, proposals}; pub mod storage; -use storage::{types}; +use storage::{type_registry}; mod memo; mod traits; @@ -227,7 +227,7 @@ impl memo::Trait for Runtime { type Event = Event; } -impl storage::types::Trait for Runtime { +impl storage::type_registry::Trait for Runtime { type Event = Event; type DataObjectTypeID = u64; } @@ -252,7 +252,7 @@ construct_runtime!( CouncilElection: election::{Module, Call, Storage, Event, Config}, Council: council::{Module, Call, Storage, Event, Config}, Memo: memo::{Module, Call, Storage, Event}, - DataObjectType: types::{Module, Call, Storage, Event, Config}, + DataObjectTypeRegistry: type_registry::{Module, Call, Storage, Event, Config}, } ); diff --git a/src/storage/mock.rs b/src/storage/mock.rs index c9b5b8ab84..1c4b6d8521 100644 --- a/src/storage/mock.rs +++ b/src/storage/mock.rs @@ -1,7 +1,7 @@ #![cfg(test)] use rstd::prelude::*; -pub use super::{types}; +pub use super::{type_registry}; pub use system; pub use primitives::{H256, Blake2Hasher}; @@ -20,7 +20,7 @@ impl_outer_origin! { impl_outer_event! { pub enum MetaEvent for Test { - types, + type_registry, } } @@ -43,7 +43,7 @@ impl system::Trait for Test type Log = DigestItem; type Lookup = IdentityLookup; } -impl types::Trait for Test +impl type_registry::Trait for Test { type Event = MetaEvent; type DataObjectTypeID = u64; @@ -75,7 +75,7 @@ impl ExtBuilder { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(types::GenesisConfig::{ + t.extend(type_registry::GenesisConfig::{ first_data_object_type_id: self.first_data_object_type_id, }.build_storage().unwrap().0); @@ -85,5 +85,5 @@ impl ExtBuilder pub type System = system::Module; -pub type Types = types::Module; -pub type TestDataObjectType = types::DataObjectType; +pub type TestDataObjectTypeRegistry = type_registry::Module; +pub type TestDataObjectType = type_registry::DataObjectType; diff --git a/src/storage/mod.rs b/src/storage/mod.rs index f50e2661c0..ac6f28c54d 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub mod types; +pub mod type_registry; mod mock; mod tests; diff --git a/src/storage/tests.rs b/src/storage/tests.rs index 2f9df21172..50e474fa5e 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -15,7 +15,7 @@ fn initial_state() with_externalities(&mut ExtBuilder::default() .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || { - assert_eq!(Types::first_data_object_type_id(), DEFAULT_FIRST_ID); + assert_eq!(DataObjectTypeRegistry::first_data_object_type_id(), DEFAULT_FIRST_ID); }); } @@ -32,7 +32,7 @@ fn fail_register_without_root() description: "foo".as_bytes().to_vec(), active: false, }; - let res = Types::register_data_object_type(Origin::signed(1), data); + let res = DataObjectTypeRegistry::register_data_object_type(Origin::signed(1), data); assert!(res.is_err()); }); } @@ -50,7 +50,7 @@ fn succeed_register_as_root() description: "foo".as_bytes().to_vec(), active: false, }; - let res = Types::register_data_object_type(Origin::ROOT, data); + let res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(res.is_ok()); }); } @@ -69,12 +69,12 @@ fn update_existing() description: "foo".as_bytes().to_vec(), active: false, }; - let id_res = Types::register_data_object_type(Origin::ROOT, data); + let id_res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(id_res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), } ); @@ -86,7 +86,7 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = Types::update_data_object_type(Origin::ROOT, updated1); + let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated1); assert!(res.is_err()); // Now try with a bad ID @@ -95,7 +95,7 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = Types::update_data_object_type(Origin::ROOT, updated2); + let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated2); assert!(res.is_err()); // Finally with an existing ID, it should work. @@ -104,12 +104,12 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = Types::update_data_object_type(Origin::ROOT, updated3); + let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated3); assert!(res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), } ); }); @@ -130,32 +130,32 @@ fn activate_existing() description: "foo".as_bytes().to_vec(), active: false, }; - let id_res = Types::register_data_object_type(Origin::ROOT, data); + let id_res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(id_res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(types::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), } ); // Retrieve, and ensure it's not active. - let data = Types::data_object_type(DEFAULT_FIRST_ID); + let data = DataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); assert!(data.is_some()); assert!(!data.unwrap().active); // Now activate the data object type - let res = Types::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); + let res = DataObjectTypeRegistry::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); assert!(res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(types::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), } ); // Ensure that the item is actually activated. - let data = Types::data_object_type(DEFAULT_FIRST_ID); + let data = DataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); assert!(data.is_some()); assert!(data.unwrap().active); }); diff --git a/src/storage/types.rs b/src/storage/type_registry.rs similarity index 100% rename from src/storage/types.rs rename to src/storage/type_registry.rs diff --git a/src/traits.rs b/src/traits.rs index d5533c70e3..a4cb028663 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,8 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std)] -use crate::storage::types; +use crate::storage::type_registry; -pub trait IsActiveDataObjectType +pub trait IsActiveDataObjectType { fn is_active_data_object_type(which: &T::DataObjectTypeID) -> bool { From 701e2b075a9a89f1004568517c181a5a68a7244f Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 15:07:41 +0100 Subject: [PATCH 13/17] More renaming (debated in rocket chat); works for WASM build, but not yet for unit tests. --- src/lib.rs | 6 +++--- .../{type_registry.rs => data_object_type_registry.rs} | 0 src/storage/mod.rs | 2 +- src/traits.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/storage/{type_registry.rs => data_object_type_registry.rs} (100%) diff --git a/src/lib.rs b/src/lib.rs index 82f3e2f638..53c03f2d5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ extern crate parity_codec_derive; pub mod governance; use governance::{election, council, proposals}; pub mod storage; -use storage::{type_registry}; +use storage::{data_object_type_registry}; mod memo; mod traits; @@ -227,7 +227,7 @@ impl memo::Trait for Runtime { type Event = Event; } -impl storage::type_registry::Trait for Runtime { +impl storage::data_object_type_registry::Trait for Runtime { type Event = Event; type DataObjectTypeID = u64; } @@ -252,7 +252,7 @@ construct_runtime!( CouncilElection: election::{Module, Call, Storage, Event, Config}, Council: council::{Module, Call, Storage, Event, Config}, Memo: memo::{Module, Call, Storage, Event}, - DataObjectTypeRegistry: type_registry::{Module, Call, Storage, Event, Config}, + DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event, Config}, } ); diff --git a/src/storage/type_registry.rs b/src/storage/data_object_type_registry.rs similarity index 100% rename from src/storage/type_registry.rs rename to src/storage/data_object_type_registry.rs diff --git a/src/storage/mod.rs b/src/storage/mod.rs index ac6f28c54d..c2255437b7 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub mod type_registry; +pub mod data_object_type_registry; mod mock; mod tests; diff --git a/src/traits.rs b/src/traits.rs index a4cb028663..e146692de7 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,8 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std)] -use crate::storage::type_registry; +use crate::storage::data_object_type_registry; -pub trait IsActiveDataObjectType +pub trait IsActiveDataObjectType { fn is_active_data_object_type(which: &T::DataObjectTypeID) -> bool { From 32b659a819050eb65495acdc29c0dc5ba8b86974 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 15:13:42 +0100 Subject: [PATCH 14/17] Adjust renaming to unit tests --- src/storage/mock.rs | 12 ++++++------ src/storage/tests.rs | 30 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/storage/mock.rs b/src/storage/mock.rs index 1c4b6d8521..96191c1610 100644 --- a/src/storage/mock.rs +++ b/src/storage/mock.rs @@ -1,7 +1,7 @@ #![cfg(test)] use rstd::prelude::*; -pub use super::{type_registry}; +pub use super::{data_object_type_registry}; pub use system; pub use primitives::{H256, Blake2Hasher}; @@ -20,7 +20,7 @@ impl_outer_origin! { impl_outer_event! { pub enum MetaEvent for Test { - type_registry, + data_object_type_registry, } } @@ -43,7 +43,7 @@ impl system::Trait for Test type Log = DigestItem; type Lookup = IdentityLookup; } -impl type_registry::Trait for Test +impl data_object_type_registry::Trait for Test { type Event = MetaEvent; type DataObjectTypeID = u64; @@ -75,7 +75,7 @@ impl ExtBuilder { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(type_registry::GenesisConfig::{ + t.extend(data_object_type_registry::GenesisConfig::{ first_data_object_type_id: self.first_data_object_type_id, }.build_storage().unwrap().0); @@ -85,5 +85,5 @@ impl ExtBuilder pub type System = system::Module; -pub type TestDataObjectTypeRegistry = type_registry::Module; -pub type TestDataObjectType = type_registry::DataObjectType; +pub type TestDataObjectTypeRegistry = data_object_type_registry::Module; +pub type TestDataObjectType = data_object_type_registry::DataObjectType; diff --git a/src/storage/tests.rs b/src/storage/tests.rs index 50e474fa5e..8ffd2771f5 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -15,7 +15,7 @@ fn initial_state() with_externalities(&mut ExtBuilder::default() .first_data_object_type_id(DEFAULT_FIRST_ID).build(), || { - assert_eq!(DataObjectTypeRegistry::first_data_object_type_id(), DEFAULT_FIRST_ID); + assert_eq!(TestDataObjectTypeRegistry::first_data_object_type_id(), DEFAULT_FIRST_ID); }); } @@ -32,7 +32,7 @@ fn fail_register_without_root() description: "foo".as_bytes().to_vec(), active: false, }; - let res = DataObjectTypeRegistry::register_data_object_type(Origin::signed(1), data); + let res = TestDataObjectTypeRegistry::register_data_object_type(Origin::signed(1), data); assert!(res.is_err()); }); } @@ -50,7 +50,7 @@ fn succeed_register_as_root() description: "foo".as_bytes().to_vec(), active: false, }; - let res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); + let res = TestDataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(res.is_ok()); }); } @@ -69,12 +69,12 @@ fn update_existing() description: "foo".as_bytes().to_vec(), active: false, }; - let id_res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); + let id_res = TestDataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(id_res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + event: MetaEvent::data_object_type_registry(data_object_type_registry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), } ); @@ -86,7 +86,7 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated1); + let res = TestDataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated1); assert!(res.is_err()); // Now try with a bad ID @@ -95,7 +95,7 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated2); + let res = TestDataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated2); assert!(res.is_err()); // Finally with an existing ID, it should work. @@ -104,12 +104,12 @@ fn update_existing() description: "bar".as_bytes().to_vec(), active: false, }; - let res = DataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated3); + let res = TestDataObjectTypeRegistry::update_data_object_type(Origin::ROOT, updated3); assert!(res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + event: MetaEvent::data_object_type_registry(data_object_type_registry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), } ); }); @@ -130,32 +130,32 @@ fn activate_existing() description: "foo".as_bytes().to_vec(), active: false, }; - let id_res = DataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); + let id_res = TestDataObjectTypeRegistry::register_data_object_type(Origin::ROOT, data); assert!(id_res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), + event: MetaEvent::data_object_type_registry(data_object_type_registry::RawEvent::DataObjectTypeAdded(DEFAULT_FIRST_ID)), } ); // Retrieve, and ensure it's not active. - let data = DataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); + let data = TestDataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); assert!(data.is_some()); assert!(!data.unwrap().active); // Now activate the data object type - let res = DataObjectTypeRegistry::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); + let res = TestDataObjectTypeRegistry::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); assert!(res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::types(DataObjectTypeRegistry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), + event: MetaEvent::data_object_type_registry(data_object_type_registry::RawEvent::DataObjectTypeUpdated(DEFAULT_FIRST_ID)), } ); // Ensure that the item is actually activated. - let data = DataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); + let data = TestDataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); assert!(data.is_some()); assert!(data.unwrap().active); }); From cb73509a4295e8d451840863f6639f2c332ba316 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 15:17:06 +0100 Subject: [PATCH 15/17] Simplify ensure_data_object_type() --- src/storage/data_object_type_registry.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/storage/data_object_type_registry.rs b/src/storage/data_object_type_registry.rs index 316b221fb4..cfc6e8227a 100644 --- a/src/storage/data_object_type_registry.rs +++ b/src/storage/data_object_type_registry.rs @@ -132,7 +132,6 @@ impl Module { fn ensure_data_object_type(id: T::DataObjectTypeID) -> Result, &'static str> { - let do_type = Self::data_object_type(&id).ok_or(MSG_DO_TYPE_NOT_FOUND)?; - Ok(do_type) + return Self::data_object_type(&id).ok_or(MSG_DO_TYPE_NOT_FOUND); } } From f7440326863fc9b95675b5c5a41da2ce4025a822 Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 15:20:04 +0100 Subject: [PATCH 16/17] Separate activate and deactivate functions for DO types --- src/storage/data_object_type_registry.rs | 20 ++++++++++++++++++-- src/storage/tests.rs | 9 ++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/storage/data_object_type_registry.rs b/src/storage/data_object_type_registry.rs index cfc6e8227a..8e09c8ec2d 100644 --- a/src/storage/data_object_type_registry.rs +++ b/src/storage/data_object_type_registry.rs @@ -114,17 +114,33 @@ decl_module! { Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } - pub fn activate_data_object_type(origin, id: T::DataObjectTypeID, active: bool) + // Activate and deactivate functions as separate functions, because + // toggling DO types is likely a more common operation than updating + // other aspects. + pub fn activate_data_object_type(origin, id: T::DataObjectTypeID) { ensure_root(origin)?; let mut do_type = Self::ensure_data_object_type(id)?; - do_type.active = active; + do_type.active = true; >::insert(id, do_type); Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); } + + pub fn deactivate_data_object_type(origin, id: T::DataObjectTypeID) + { + ensure_root(origin)?; + let mut do_type = Self::ensure_data_object_type(id)?; + + do_type.active = false; + + >::insert(id, do_type); + + Self::deposit_event(RawEvent::DataObjectTypeUpdated(id)); + } + } } diff --git a/src/storage/tests.rs b/src/storage/tests.rs index 8ffd2771f5..dbacde2ee3 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -145,7 +145,7 @@ fn activate_existing() assert!(!data.unwrap().active); // Now activate the data object type - let res = TestDataObjectTypeRegistry::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID, true); + let res = TestDataObjectTypeRegistry::activate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID); assert!(res.is_ok()); assert_eq!(*System::events().last().unwrap(), EventRecord { @@ -158,5 +158,12 @@ fn activate_existing() let data = TestDataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); assert!(data.is_some()); assert!(data.unwrap().active); + + // Deactivate again. + let res = TestDataObjectTypeRegistry::deactivate_data_object_type(Origin::ROOT, DEFAULT_FIRST_ID); + assert!(res.is_ok()); + let data = TestDataObjectTypeRegistry::data_object_type(DEFAULT_FIRST_ID); + assert!(data.is_some()); + assert!(!data.unwrap().active); }); } From b3e5ff2c7be2b7c755b108d8ce26f8d9527cff7f Mon Sep 17 00:00:00 2001 From: Jens Finkhaeuser Date: Tue, 26 Mar 2019 15:21:45 +0100 Subject: [PATCH 17/17] Add comment about future field in DO types --- src/storage/data_object_type_registry.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storage/data_object_type_registry.rs b/src/storage/data_object_type_registry.rs index 8e09c8ec2d..7b87d219e4 100644 --- a/src/storage/data_object_type_registry.rs +++ b/src/storage/data_object_type_registry.rs @@ -33,6 +33,7 @@ pub struct DataObjectType pub active: bool, // TODO in future releases + // - maximum size // - replication factor // - storage tranches (empty is ok) }