Просмотр исходного кода

Remove forum lead sudo depedencies

- remove old code from the forum
- remove forum sudo from the genesis config
- prepare forum mocks for tests changes
- clean up bureaucracy module
Shamil Gadelshin 4 лет назад
Родитель
Сommit
17fc1257a2

+ 6 - 0
Cargo.lock

@@ -1645,6 +1645,7 @@ dependencies = [
  "srml-timestamp",
  "srml-transaction-payment",
  "substrate-authority-discovery-primitives",
+ "substrate-bureaucracy-module",
  "substrate-client",
  "substrate-common-module",
  "substrate-consensus-babe-primitives",
@@ -4840,7 +4841,12 @@ dependencies = [
  "srml-support-procedural",
  "srml-system",
  "srml-timestamp",
+ "substrate-bureaucracy-module",
+ "substrate-common-module",
+ "substrate-membership-module",
  "substrate-primitives",
+ "substrate-recurring-reward-module",
+ "substrate-token-mint-module",
 ]
 
 [[package]]

+ 2 - 2
node/src/forum_config/from_serialized.rs

@@ -18,7 +18,8 @@ fn parse_forum_json() -> Result<ForumData> {
     serde_json::from_str(data)
 }
 
-pub fn create(forum_sudo: AccountId) -> ForumConfig {
+//TODO: should we set the forum_sudo account in the bureaucracy module?
+pub fn create(_forum_sudo: AccountId) -> ForumConfig {
     let forum_data = parse_forum_json().expect("failed loading forum data");
 
     let next_category_id: CategoryId = forum_data
@@ -35,7 +36,6 @@ pub fn create(forum_sudo: AccountId) -> ForumConfig {
         next_category_id,
         next_thread_id,
         next_post_id,
-        forum_sudo,
         category_title_constraint: new_validation(10, 90),
         category_description_constraint: new_validation(10, 490),
         thread_title_constraint: new_validation(10, 90),

+ 24 - 45
runtime-modules/bureaucracy/src/lib.rs

@@ -6,16 +6,16 @@ mod types;
 use sr_primitives::traits::One;
 use srml_support::traits::Currency;
 use srml_support::{decl_module, decl_storage, dispatch, ensure};
-use system::{self, ensure_signed};
+use system::ensure_root;
 
 use membership::role_types::{ActorInRole, Role};
 use types::{Lead, LeadRoleState};
 
-pub static MSG_CHANNEL_DESCRIPTION_TOO_SHORT: &str = "Channel description too short";
-pub static MSG_CHANNEL_DESCRIPTION_TOO_LONG: &str = "Channel description too long";
+//TODO: convert messages to the decl_error! entries
 pub static MSG_ORIGIN_IS_NOT_LEAD: &str = "Origin is not lead";
 pub static MSG_CURRENT_LEAD_NOT_SET: &str = "Current lead is not set";
 pub static MSG_CURRENT_LEAD_ALREADY_SET: &str = "Current lead is already set";
+pub static MSG_IS_NOT_LEAD_ACCOUNT: &str = "Not a lead account";
 
 /// Type identifier for lead role, which must be same as membership actor identifier
 pub type LeadId<T> = <T as membership::members::Trait>::ActorId;
@@ -27,8 +27,9 @@ pub type RewardRelationshipId<T> = <T as recurringrewards::Trait>::RewardRelatio
 pub type BalanceOf<T> =
     <<T as stake::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
 
+/// The bureaucracy main _Trait_
 pub trait Trait<I: Instance>:
-    system::Trait + hiring::Trait + recurringrewards::Trait + membership::members::Trait
+    system::Trait + recurringrewards::Trait + membership::members::Trait
 {
 }
 
@@ -47,13 +48,10 @@ decl_storage! {
 
 decl_module! {
     pub struct Module<T: Trait<I>, I: Instance> for enum Call where origin: T::Origin {
-
-    }
-}
-
-impl<T: Trait<I>, I: Instance> Module<T, I> {
     /// Introduce a lead when one is not currently set.
-    pub fn set_lead(member: T::MemberId, role_account: T::AccountId) -> dispatch::Result {
+    pub fn set_lead(origin, member: T::MemberId, role_account: T::AccountId) -> dispatch::Result {
+        ensure_root(origin)?;
+
         // Ensure there is no current lead
         ensure!(
             <CurrentLeadId<T, I>>::get().is_none(),
@@ -73,7 +71,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
 
         // Construct lead
         let new_lead = Lead {
-            role_account: role_account.clone(),
+            role_account,
             reward_relationship: None,
             inducted: <system::Module<T>>::block_number(),
             stage: LeadRoleState::Active,
@@ -83,34 +81,36 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
         <LeadById<T, I>>::insert(new_lead_id, new_lead);
 
         // Update current lead
-        <CurrentLeadId<T, I>>::put(new_lead_id); // Some(new_lead_id)
+        <CurrentLeadId<T, I>>::put(new_lead_id);
 
         // Update next lead counter
         <NextLeadId<T, I>>::mutate(|id| *id += <LeadId<T> as One>::one());
 
-        // Trigger event
-//        Self::deposit_event(RawEvent::LeadSet(new_lead_id));
+        // Trigger event: TODO: create bureaucracy events
+        //        Self::deposit_event(RawEvent::LeadSet(new_lead_id));
 
         Ok(())
     }
+    }
+}
 
-    pub fn ensure_lead_is_set() -> Result<
-        (
-            LeadId<T>,
-            Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber>,
-        ),
-        &'static str,
-    > {
+impl<T: Trait<I>, I: Instance> Module<T, I> {
+    /// Checks that provided lead account id belongs to the current bureaucracy leader
+    pub fn ensure_is_lead_account(lead_account_id: T::AccountId) -> Result<(), &'static str> {
         // Ensure lead id is set
         let lead_id = Self::ensure_lead_id_set()?;
 
         // If so, grab actual lead
-        let lead = <LeadById<T,I>>::get(lead_id);
+        let lead = <LeadById<T, I>>::get(lead_id);
+
+        if lead.role_account != lead_account_id {
+            return Err(MSG_IS_NOT_LEAD_ACCOUNT);
+        }
 
-        // and return both
-        Ok((lead_id, lead))
+        Ok(())
     }
 
+    // checks that storage contains lead_id
     fn ensure_lead_id_set() -> Result<LeadId<T>, &'static str> {
         let opt_current_lead_id = <CurrentLeadId<T, I>>::get();
 
@@ -120,25 +120,4 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
             Err(MSG_CURRENT_LEAD_NOT_SET)
         }
     }
-
-    pub fn ensure_origin_is_set_lead(
-        origin: T::Origin,
-    ) -> Result<
-        (
-            LeadId<T>,
-            Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber>,
-        ),
-        &'static str,
-    > {
-        // Ensure lead is actually set
-        let (lead_id, lead) = Self::ensure_lead_is_set()?;
-
-        // Ensure is signed
-        let signer = ensure_signed(origin)?;
-
-        // Ensure signer is lead
-        ensure!(signer == lead.role_account, MSG_ORIGIN_IS_NOT_LEAD);
-
-        Ok((lead_id, lead))
-    }
 }

+ 33 - 0
runtime-modules/forum/Cargo.toml

@@ -30,10 +30,42 @@ git = 'https://github.com/paritytech/substrate.git'
 package = 'sr-io'
 rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
 
+[dependencies.bureaucracy]
+default_features = false
+package = 'substrate-bureaucracy-module'
+path = '../bureaucracy'
+version = '1.0.0'
+
 [dev-dependencies]
 runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
 primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
 
+[dev-dependencies.membership]
+default_features = false
+package = 'substrate-membership-module'
+path = '../membership'
+
+[dev-dependencies.minting]
+default_features = false
+package = 'substrate-token-mint-module'
+path = '../token-minting'
+
+[dev-dependencies.recurringrewards]
+default_features = false
+package = 'substrate-recurring-reward-module'
+path = '../recurring-reward'
+
+[dev-dependencies.balances]
+default_features = false
+git = 'https://github.com/paritytech/substrate.git'
+package = 'srml-balances'
+rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+
+[dev-dependencies.common]
+default_features = false
+package = 'substrate-common-module'
+path = '../common'
+
 [features]
 default = ['std']
 std = [
@@ -47,4 +79,5 @@ std = [
 	'system/std',
   	'balances/std',
 	'timestamp/std',
+	'bureaucracy/std',
 ]

+ 6 - 59
runtime-modules/forum/src/lib.rs

@@ -9,11 +9,11 @@
 #[cfg(feature = "std")]
 use serde_derive::{Deserialize, Serialize};
 
+use codec::{Decode, Encode};
 use rstd::borrow::ToOwned;
 use rstd::prelude::*;
-
-use codec::{Decode, Encode};
 use srml_support::{decl_event, decl_module, decl_storage, dispatch, ensure};
+use system::ensure_signed;
 
 mod mock;
 mod tests;
@@ -67,8 +67,6 @@ impl InputValidationLengthConstraint {
 const MAX_CATEGORY_DEPTH: u16 = 3;
 
 /// Error messages for dispatchables
-const ERROR_FORUM_SUDO_NOT_SET: &str = "Forum sudo not set.";
-const ERROR_ORIGIN_NOT_FORUM_SUDO: &str = "Origin not forum sudo.";
 const ERROR_CATEGORY_TITLE_TOO_SHORT: &str = "Category title too short.";
 const ERROR_CATEGORY_TITLE_TOO_LONG: &str = "Category title too long.";
 const ERROR_CATEGORY_DESCRIPTION_TOO_SHORT: &str = "Category description too long.";
@@ -96,18 +94,6 @@ const ERROR_CATEGORY_NOT_BEING_UPDATED: &str = "Category not being updated.";
 const ERROR_CATEGORY_CANNOT_BE_UNARCHIVED_WHEN_DELETED: &str =
     "Category cannot be unarchived when deleted.";
 
-//use srml_support::storage::*;
-
-//use sr_io::{StorageOverlay, ChildrenStorageOverlay};
-
-//#[cfg(feature = "std")]
-//use runtime_io::{StorageOverlay, ChildrenStorageOverlay};
-
-//#[cfg(any(feature = "std", test))]
-//use sr_primitives::{StorageOverlay, ChildrenStorageOverlay};
-
-use system::{ensure_root, ensure_signed};
-
 /// Represents a user in this forum.
 #[derive(Debug, Copy, Clone)]
 pub struct ForumUser<AccountId> {
@@ -317,7 +303,9 @@ impl<BlockNumber, Moment, AccountId> Category<BlockNumber, Moment, AccountId> {
 type CategoryTreePath<BlockNumber, Moment, AccountId> =
     Vec<Category<BlockNumber, Moment, AccountId>>;
 
-pub trait Trait: system::Trait + timestamp::Trait + Sized {
+pub trait Trait:
+    system::Trait + timestamp::Trait + bureaucracy::Trait<bureaucracy::Instance1> + Sized
+{
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
     type MembershipRegistry: ForumUserRegistry<Self::AccountId>;
@@ -344,9 +332,6 @@ decl_storage! {
         /// Post identifier value to be used for for next post created.
         pub NextPostId get(next_post_id) config(): PostId;
 
-        /// Account of forum sudo.
-        pub ForumSudo get(forum_sudo) config(): Option<T::AccountId>;
-
         /// Input constraints
         /// These are all forward looking, that is they are enforced on all
         /// future calls.
@@ -421,31 +406,6 @@ decl_module! {
 
         fn deposit_event() = default;
 
-        /// Set forum sudo.
-        fn set_forum_sudo(origin, new_forum_sudo: Option<T::AccountId>) -> dispatch::Result {
-            ensure_root(origin)?;
-
-            /*
-             * Question: when this routine is called by non sudo or with bad signature, what error is raised?
-             * Update ERror set in spec
-             */
-
-            // Hold on to old value
-            let old_forum_sudo = <ForumSudo<T>>::get();
-
-            // Update forum sudo
-            match new_forum_sudo.clone() {
-                Some(account_id) => <ForumSudo<T>>::put(account_id),
-                None => <ForumSudo<T>>::kill()
-            };
-
-            // Generate event
-            Self::deposit_event(RawEvent::ForumSudoSet(old_forum_sudo, new_forum_sudo));
-
-            // All good.
-            Ok(())
-        }
-
         /// Add a new category.
         fn create_category(origin, parent: Option<CategoryId>, title: Vec<u8>, description: Vec<u8>) -> dispatch::Result {
 
@@ -916,21 +876,8 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_forum_sudo_set() -> Result<T::AccountId, &'static str> {
-        match <ForumSudo<T>>::get() {
-            Some(account_id) => Ok(account_id),
-            None => Err(ERROR_FORUM_SUDO_NOT_SET),
-        }
-    }
-
     fn ensure_is_forum_sudo(account_id: &T::AccountId) -> dispatch::Result {
-        let forum_sudo_account = Self::ensure_forum_sudo_set()?;
-
-        ensure!(
-            *account_id == forum_sudo_account,
-            ERROR_ORIGIN_NOT_FORUM_SUDO
-        );
-        Ok(())
+        bureaucracy::Module::<T, bureaucracy::Instance1>::ensure_is_lead_account(account_id.clone())
     }
 
     fn ensure_is_forum_member(

+ 46 - 5
runtime-modules/forum/src/mock.rs

@@ -70,6 +70,10 @@ parameter_types! {
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
+    pub const InitialMembersBalance: u64 = 2000;
+    pub const ExistentialDeposit: u32 = 0;
+    pub const TransferFee: u32 = 0;
+    pub const CreationFee: u32 = 0;
 }
 
 impl system::Trait for Runtime {
@@ -97,6 +101,45 @@ impl timestamp::Trait for Runtime {
     type MinimumPeriod = MinimumPeriod;
 }
 
+impl bureaucracy::Trait<bureaucracy::Instance1> for Runtime {}
+
+impl recurringrewards::Trait for Runtime {
+    type PayoutStatusHandler = ();
+    type RecipientId = u64;
+    type RewardRelationshipId = u64;
+}
+
+impl membership::members::Trait for Runtime {
+    type Event = ();
+    type MemberId = u64;
+    type PaidTermId = u64;
+    type SubscriptionId = u64;
+    type ActorId = u64;
+    type InitialMembersBalance = InitialMembersBalance;
+}
+
+impl balances::Trait for Runtime {
+    type Balance = u64;
+    type OnFreeBalanceZero = ();
+    type OnNewAccount = ();
+    type Event = ();
+    type DustRemoval = ();
+    type TransferPayment = ();
+    type ExistentialDeposit = ExistentialDeposit;
+    type TransferFee = TransferFee;
+    type CreationFee = CreationFee;
+}
+pub type Balances = balances::Module<Runtime>;
+
+impl common::currency::GovernanceCurrency for Runtime {
+    type Currency = Balances;
+}
+
+impl minting::Trait for Runtime {
+    type Currency = Balances;
+    type MintId = u64;
+}
+
 impl Trait for Runtime {
     type Event = ();
     type MembershipRegistry = registry::TestMembershipRegistryModule;
@@ -382,13 +425,14 @@ pub fn assert_not_forum_sudo_cannot_update_category(
     update_operation: fn(OriginType, CategoryId) -> dispatch::Result,
 ) {
     let config = default_genesis_config();
-    let origin = OriginType::Signed(config.forum_sudo);
+    let forum_sudo = 33;
+    let origin = OriginType::Signed(forum_sudo);
 
     build_test_externalities(config).execute_with(|| {
         let category_id = create_root_category(origin.clone());
         assert_eq!(
             update_operation(NOT_FORUM_SUDO_ORIGIN, category_id),
-            Err(ERROR_ORIGIN_NOT_FORUM_SUDO)
+            Err(bureaucracy::MSG_ORIGIN_IS_NOT_LEAD)
         );
     });
 }
@@ -409,8 +453,6 @@ pub fn default_genesis_config() -> GenesisConfig<Runtime> {
         post_by_id: vec![],
         next_post_id: 1,
 
-        forum_sudo: 33,
-
         category_title_constraint: InputValidationLengthConstraint {
             min: 10,
             max_min_diff: 140,
@@ -489,7 +531,6 @@ pub fn genesis_config(
         next_thread_id,
         post_by_id: post_by_id.clone(),
         next_post_id,
-        forum_sudo,
         category_title_constraint: category_title_constraint.clone(),
         category_description_constraint: category_description_constraint.clone(),
         thread_title_constraint: thread_title_constraint.clone(),

+ 8 - 1
runtime/Cargo.toml

@@ -62,6 +62,7 @@ std = [
     'proposals_engine/std',
     'proposals_discussion/std',
     'proposals_codex/std',
+    'bureaucracy/std',
 ]
 
 # [dependencies]
@@ -373,4 +374,10 @@ version = '2.0.0'
 default_features = false
 package = 'substrate-proposals-codex-module'
 path = '../runtime-modules/proposals/codex'
-version = '2.0.0'
+version = '2.0.0'
+
+[dependencies.bureaucracy]
+default_features = false
+package = 'substrate-bureaucracy-module'
+path = '../runtime-modules/bureaucracy'
+version = '1.0.0'

+ 3 - 0
runtime/src/lib.rs

@@ -790,6 +790,9 @@ impl migration::Trait for Runtime {
     type Event = Event;
 }
 
+// Forum bureaucracy
+impl bureaucracy::Trait<bureaucracy::Instance1> for Runtime {}
+
 impl actors::Trait for Runtime {
     type Event = Event;
     type OnActorRemoved = HandleActorRemoved;