瀏覽代碼

Merge branch 'development' into linter_fixes

# Conflicts:
#	runtime-modules/proposals/codex/src/lib.rs
#	runtime-modules/proposals/codex/src/proposal_types/parameters.rs
Shamil Gadelshin 4 年之前
父節點
當前提交
44f8a82c9a

+ 22 - 2
node/src/chain_spec.rs

@@ -23,8 +23,8 @@ use node_runtime::{
     AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentWorkingGroupConfig,
     CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
     DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, IndicesConfig,
-    MembersConfig, Perbill, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
-    SudoConfig, SystemConfig, VersionedStoreConfig, DAYS, WASM_BINARY,
+    MembersConfig, Perbill, ProposalsCodexConfig, SessionConfig, SessionKeys, Signature,
+    StakerStatus, StakingConfig, SudoConfig, SystemConfig, VersionedStoreConfig, DAYS, WASM_BINARY,
 };
 pub use node_runtime::{AccountId, GenesisConfig};
 use primitives::{sr25519, Pair, Public};
@@ -299,5 +299,25 @@ pub fn testnet_genesis(
             channel_banner_constraint: crate::forum_config::new_validation(5, 1024),
             channel_title_constraint: crate::forum_config::new_validation(5, 1024),
         }),
+        proposals_codex: Some(ProposalsCodexConfig {
+            set_validator_count_proposal_voting_period: 43200u32,
+            set_validator_count_proposal_grace_period: 0u32,
+            runtime_upgrade_proposal_voting_period: 72000u32,
+            runtime_upgrade_proposal_grace_period: 72000u32,
+            text_proposal_voting_period: 72000u32,
+            text_proposal_grace_period: 0u32,
+            set_election_parameters_proposal_voting_period: 72000u32,
+            set_election_parameters_proposal_grace_period: 201_601_u32,
+            set_content_working_group_mint_capacity_proposal_voting_period: 43200u32,
+            set_content_working_group_mint_capacity_proposal_grace_period: 0u32,
+            set_lead_proposal_voting_period: 43200u32,
+            set_lead_proposal_grace_period: 0u32,
+            spending_proposal_voting_period: 72000u32,
+            spending_proposal_grace_period: 14400u32,
+            evict_storage_provider_proposal_voting_period: 43200u32,
+            evict_storage_provider_proposal_grace_period: 0u32,
+            set_storage_role_parameters_proposal_voting_period: 43200u32,
+            set_storage_role_parameters_proposal_grace_period: 14400u32,
+        }),
     }
 }

+ 1 - 1
runtime-modules/governance/src/council.rs

@@ -136,7 +136,7 @@ decl_module! {
 
         /// Sets the capacity of the the council mint, if it doesn't exist, attempts to
         /// create a new one.
-        fn set_council_mint_capacity(origin, capacity: minting::BalanceOf<T>) {
+        pub fn set_council_mint_capacity(origin, capacity: minting::BalanceOf<T>) {
             ensure_root(origin)?;
 
             if let Some(mint_id) = Self::council_mint() {

+ 8 - 6
runtime-modules/proposals/codex/Cargo.toml

@@ -25,6 +25,8 @@ std = [
     'governance/std',
     'mint/std',
     'roles/std',
+    'common/std',
+    'content_working_group/std',
 ]
 
 
@@ -91,12 +93,6 @@ git = 'https://github.com/paritytech/substrate.git'
 package = 'srml-staking'
 rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
 
-[dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
 [dependencies.stake]
 default_features = false
 package = 'substrate-stake-module'
@@ -173,6 +169,12 @@ git = 'https://github.com/paritytech/substrate.git'
 package = 'sr-staking-primitives'
 rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
 
+[dev-dependencies.runtime-io]
+default_features = false
+git = 'https://github.com/paritytech/substrate.git'
+package = 'sr-io'
+rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+
 # don't rename the dependency it is causing some strange compiler error:
 # https://github.com/rust-lang/rust/issues/64450
 [dev-dependencies.srml-staking-reward-curve]

+ 123 - 70
runtime-modules/proposals/codex/src/lib.rs

@@ -34,6 +34,10 @@
 //! - [governance](../substrate_governance_module/index.html)
 //! - [content_working_group](../substrate_content_working_group_module/index.html)
 //!
+//! ### Notes
+//! The module uses [ProposalEncoder](./trait.ProposalEncoder.html) to encode the proposal using
+//! its details. Encoded byte vector is passed to the _proposals engine_ as serialized executable code.
+
 // Clippy linter warning. TODO: remove after the Constaninople release
 #![allow(clippy::type_complexity)]
 // disable it because of possible frontend API break
@@ -48,20 +52,19 @@
 // #![warn(missing_docs)]
 
 mod proposal_types;
+
 #[cfg(test)]
 mod tests;
 
-use codec::Encode;
 use common::origin_validator::ActorOriginValidator;
 use governance::election_params::ElectionParameters;
 use proposal_engine::ProposalParameters;
-use roles::actors::{Role, RoleParameters};
+use roles::actors::RoleParameters;
 use rstd::clone::Clone;
 use rstd::convert::TryInto;
 use rstd::prelude::*;
 use rstd::str::from_utf8;
 use rstd::vec::Vec;
-use runtime_io::blake2_256;
 use sr_primitives::traits::SaturatedConversion;
 use sr_primitives::traits::{One, Zero};
 use sr_primitives::Perbill;
@@ -70,7 +73,7 @@ use srml_support::traits::{Currency, Get};
 use srml_support::{decl_error, decl_module, decl_storage, ensure, print};
 use system::{ensure_root, RawOrigin};
 
-pub use proposal_types::ProposalDetails;
+pub use proposal_types::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
 
 // Percentage of the total token issue as max mint balance value. Shared with spending
 // proposal max balance percentage.
@@ -99,6 +102,9 @@ pub trait Trait:
         MemberId<Self>,
         Self::AccountId,
     >;
+
+    /// Encodes the proposal usint its details
+    type ProposalEncoder: ProposalEncoder<Self>;
 }
 
 /// Balance alias for `stake` module
@@ -256,6 +262,74 @@ decl_storage! {
                 T::AccountId,
                 T::MemberId
             >;
+
+        /// Voting period for the 'set validator count' proposal
+        pub SetValidatorCountProposalVotingPeriod get(set_validator_count_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'set validator count' proposal
+        pub SetValidatorCountProposalGracePeriod get(set_validator_count_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'runtime upgrade' proposal
+        pub RuntimeUpgradeProposalVotingPeriod get(runtime_upgrade_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'runtime upgrade' proposal
+        pub RuntimeUpgradeProposalGracePeriod get(runtime_upgrade_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'set election parameters' proposal
+        pub SetElectionParametersProposalVotingPeriod get(set_election_parameters_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'set election parameters' proposal
+        pub SetElectionParametersProposalGracePeriod get(set_election_parameters_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'text' proposal
+        pub TextProposalVotingPeriod get(text_proposal_voting_period) config(): T::BlockNumber;
+
+        /// Grace period for the 'text' proposal
+        pub TextProposalGracePeriod get(text_proposal_grace_period) config(): T::BlockNumber;
+
+        /// Voting period for the 'set content working group mint capacity' proposal
+        pub SetContentWorkingGroupMintCapacityProposalVotingPeriod get(set_content_working_group_mint_capacity_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'set content working group mint capacity' proposal
+        pub SetContentWorkingGroupMintCapacityProposalGracePeriod get(set_content_working_group_mint_capacity_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'set lead' proposal
+        pub SetLeadProposalVotingPeriod get(set_lead_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'set lead' proposal
+        pub SetLeadProposalGracePeriod get(set_lead_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'spending' proposal
+        pub SpendingProposalVotingPeriod get(spending_proposal_voting_period) config(): T::BlockNumber;
+
+        /// Grace period for the 'spending' proposal
+        pub SpendingProposalGracePeriod get(spending_proposal_grace_period) config(): T::BlockNumber;
+
+        /// Voting period for the 'evict storage provider' proposal
+        pub EvictStorageProviderProposalVotingPeriod get(evict_storage_provider_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'evict storage provider' proposal
+        pub EvictStorageProviderProposalGracePeriod get(evict_storage_provider_proposal_grace_period)
+            config(): T::BlockNumber;
+
+        /// Voting period for the 'set storage role parameters' proposal
+        pub SetStorageRoleParametersProposalVotingPeriod get(set_storage_role_parameters_proposal_voting_period)
+            config(): T::BlockNumber;
+
+        /// Grace period for the 'set storage role parameters' proposal
+        pub SetStorageRoleParametersProposalGracePeriod get(set_storage_role_parameters_proposal_grace_period)
+            config(): T::BlockNumber;
     }
 }
 
@@ -279,8 +353,8 @@ decl_module! {
                 Error::TextProposalSizeExceeded);
 
             let proposal_parameters = proposal_types::parameters::text_proposal::<T>();
-            let proposal_code =
-                <Call<T>>::execute_text_proposal(title.clone(), description.clone(), text.clone());
+            let proposal_details = ProposalDetails::<BalanceOfMint<T>, BalanceOfGovernanceCurrency<T>, T::BlockNumber, T::AccountId, MemberId<T>>::Text(text);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -288,9 +362,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::Text(text),
+                proposal_details,
             )?;
         }
 
@@ -308,12 +382,9 @@ decl_module! {
             ensure!(wasm.len() as u32 <= T::RuntimeUpgradeWasmProposalMaxLength::get(),
                 Error::RuntimeProposalSizeExceeded);
 
-            let wasm_hash = blake2_256(&wasm);
-
-            let proposal_code =
-                <Call<T>>::execute_runtime_upgrade_proposal(title.clone(), description.clone(), wasm);
-
             let proposal_parameters = proposal_types::parameters::runtime_upgrade_proposal::<T>();
+            let proposal_details = ProposalDetails::RuntimeUpgrade(wasm);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -321,9 +392,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::RuntimeUpgrade(wasm_hash.to_vec()),
+                proposal_details,
             )?;
         }
 
@@ -341,9 +412,8 @@ decl_module! {
 
             Self::ensure_council_election_parameters_valid(&election_parameters)?;
 
-            let proposal_code =
-                <governance::election::Call<T>>::set_election_parameters(election_parameters);
-
+            let proposal_details = ProposalDetails::SetElectionParameters(election_parameters);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
             let proposal_parameters =
                 proposal_types::parameters::set_election_parameters_proposal::<T>();
 
@@ -353,9 +423,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::SetElectionParameters(election_parameters),
+                proposal_details,
             )?;
         }
 
@@ -378,11 +448,10 @@ decl_module! {
                 Error::InvalidStorageWorkingGroupMintCapacity
             );
 
-            let proposal_code =
-                <content_working_group::Call<T>>::set_mint_capacity(mint_balance);
-
             let proposal_parameters =
                 proposal_types::parameters::set_content_working_group_mint_capacity_proposal::<T>();
+            let proposal_details = ProposalDetails::SetContentWorkingGroupMintCapacity(mint_balance);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -390,9 +459,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::SetContentWorkingGroupMintCapacity(mint_balance),
+                proposal_details,
             )?;
         }
 
@@ -421,13 +490,10 @@ decl_module! {
                 Error::InvalidSpendingProposalBalance
             );
 
-            let proposal_code = <governance::council::Call<T>>::spend_from_council_mint(
-                balance,
-                destination.clone()
-            );
-
             let proposal_parameters =
                 proposal_types::parameters::spending_proposal::<T>();
+            let proposal_details = ProposalDetails::Spending(balance, destination);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -435,13 +501,12 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::Spending(balance, destination),
+                proposal_details,
             )?;
         }
 
-
         /// Create 'Set lead' proposal type.
         /// This proposal uses `replace_lead()` extrinsic from the `content_working_group`  module.
         pub fn create_set_lead_proposal(
@@ -460,11 +525,10 @@ decl_module! {
                 );
             }
 
-            let proposal_code =
-                <content_working_group::Call<T>>::replace_lead(new_lead.clone());
-
             let proposal_parameters =
                 proposal_types::parameters::set_lead_proposal::<T>();
+            let proposal_details = ProposalDetails::SetLead(new_lead);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -472,9 +536,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::SetLead(new_lead),
+                proposal_details,
             )?;
         }
 
@@ -488,11 +552,10 @@ decl_module! {
             stake_balance: Option<BalanceOf<T>>,
             actor_account: T::AccountId,
         ) {
-            let proposal_code =
-                <roles::actors::Call<T>>::remove_actor(actor_account.clone());
-
             let proposal_parameters =
                 proposal_types::parameters::evict_storage_provider_proposal::<T>();
+            let proposal_details = ProposalDetails::EvictStorageProvider(actor_account);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -500,9 +563,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::EvictStorageProvider(actor_account),
+                proposal_details,
             )?;
         }
 
@@ -526,11 +589,10 @@ decl_module! {
                 Error::InvalidValidatorCount
             );
 
-            let proposal_code =
-                <staking::Call<T>>::set_validator_count(new_validator_count);
-
             let proposal_parameters =
                 proposal_types::parameters::set_validator_count_proposal::<T>();
+            let proposal_details = ProposalDetails::SetValidatorCount(new_validator_count);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -538,9 +600,9 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::SetValidatorCount(new_validator_count),
+                proposal_details,
             )?;
         }
 
@@ -556,13 +618,10 @@ decl_module! {
         ) {
             Self::ensure_storage_role_parameters_valid(&role_parameters)?;
 
-            let proposal_code = <roles::actors::Call<T>>::set_role_parameters(
-                Role::StorageProvider,
-                role_parameters
-            );
-
             let proposal_parameters =
                 proposal_types::parameters::set_storage_role_parameters_proposal::<T>();
+            let proposal_details =  ProposalDetails::SetStorageRoleParameters(role_parameters);
+            let proposal_code = T::ProposalEncoder::encode_proposal(proposal_details.clone());
 
             Self::create_proposal(
                 origin,
@@ -570,47 +629,41 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal_code.encode(),
+                proposal_code,
                 proposal_parameters,
-                ProposalDetails::SetStorageRoleParameters(role_parameters),
+                proposal_details,
             )?;
         }
 
 // *************** Extrinsic to execute
 
         /// Text proposal extrinsic. Should be used as callable object to pass to the `engine` module.
-        fn execute_text_proposal(
+        pub fn execute_text_proposal(
             origin,
-            title: Vec<u8>,
-            _description: Vec<u8>,
-            _text: Vec<u8>,
+            text: Vec<u8>,
         ) {
             ensure_root(origin)?;
             print("Text proposal: ");
-            let title_string_result = from_utf8(title.as_slice());
-            if let Ok(title_string) = title_string_result{
-                print(title_string);
+            let text_string_result = from_utf8(text.as_slice());
+            if let Ok(text_string) = text_string_result{
+                print(text_string);
             }
         }
 
         /// Runtime upgrade proposal extrinsic.
         /// Should be used as callable object to pass to the `engine` module.
-        fn execute_runtime_upgrade_proposal(
+        pub fn execute_runtime_upgrade_proposal(
             origin,
-            title: Vec<u8>,
-            _description: Vec<u8>,
             wasm: Vec<u8>,
         ) {
             let (cloned_origin1, cloned_origin2) =  Self::double_origin(origin);
             ensure_root(cloned_origin1)?;
 
-            print("Runtime upgrade proposal: ");
-            let title_string_result = from_utf8(title.as_slice());
-            if let Ok(title_string) = title_string_result{
-                print(title_string);
-            }
+            print("Runtime upgrade proposal execution started.");
 
             <system::Module<T>>::set_code(cloned_origin2, wasm)?;
+
+            print("Runtime upgrade proposal execution finished.");
         }
     }
 }

+ 16 - 1
runtime-modules/proposals/codex/src/proposal_types/mod.rs

@@ -8,6 +8,21 @@ use serde::{Deserialize, Serialize};
 use crate::ElectionParameters;
 use roles::actors::RoleParameters;
 
+/// Encodes proposal using its details information.
+pub trait ProposalEncoder<T: crate::Trait> {
+    /// Encodes proposal using its details information.
+    fn encode_proposal(proposal_details: ProposalDetailsOf<T>) -> Vec<u8>;
+}
+
+/// _ProposalDetails_ alias for type simplification
+pub type ProposalDetailsOf<T> = ProposalDetails<
+    crate::BalanceOfMint<T>,
+    crate::BalanceOfGovernanceCurrency<T>,
+    <T as system::Trait>::BlockNumber,
+    <T as system::Trait>::AccountId,
+    crate::MemberId<T>,
+>;
+
 /// Proposal details provide voters the information required for the perceived voting.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Clone, PartialEq, Debug)]
@@ -15,7 +30,7 @@ pub enum ProposalDetails<MintedBalance, CurrencyBalance, BlockNumber, AccountId,
     /// The text of the `text` proposal
     Text(Vec<u8>),
 
-    /// The hash of wasm code for the `runtime upgrade` proposal
+    /// The wasm code for the `runtime upgrade` proposal
     RuntimeUpgrade(Vec<u8>),
 
     /// Election parameters for the `set election parameters` proposal

+ 20 - 19
runtime-modules/proposals/codex/src/proposal_types/parameters.rs

@@ -1,11 +1,11 @@
-use crate::{get_required_stake_by_fraction, BalanceOf, ProposalParameters};
+use crate::{get_required_stake_by_fraction, BalanceOf, Module, ProposalParameters};
 
 // Proposal parameters for the 'Set validator count' proposal
 pub(crate) fn set_validator_count_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(43200u32),
-        grace_period: T::BlockNumber::from(0u32),
+        voting_period: <Module<T>>::set_validator_count_proposal_voting_period(),
+        grace_period: <Module<T>>::set_validator_count_proposal_grace_period(),
         approval_quorum_percentage: 66,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
@@ -18,8 +18,8 @@ pub(crate) fn set_validator_count_proposal<T: crate::Trait>(
 pub(crate) fn runtime_upgrade_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(72000u32),
-        grace_period: T::BlockNumber::from(72000u32),
+        voting_period: <Module<T>>::runtime_upgrade_proposal_voting_period(),
+        grace_period: <Module<T>>::runtime_upgrade_proposal_grace_period(),
         approval_quorum_percentage: 80,
         approval_threshold_percentage: 100,
         slashing_quorum_percentage: 60,
@@ -31,8 +31,8 @@ pub(crate) fn runtime_upgrade_proposal<T: crate::Trait>(
 // Proposal parameters for the text proposal
 pub(crate) fn text_proposal<T: crate::Trait>() -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(72000u32),
-        grace_period: T::BlockNumber::from(0u32),
+        voting_period: <Module<T>>::text_proposal_voting_period(),
+        grace_period: <Module<T>>::text_proposal_grace_period(),
         approval_quorum_percentage: 66,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
@@ -45,8 +45,8 @@ pub(crate) fn text_proposal<T: crate::Trait>() -> ProposalParameters<T::BlockNum
 pub(crate) fn set_election_parameters_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(72000u32),
-        grace_period: T::BlockNumber::from(201_601_u32),
+        voting_period: <Module<T>>::set_election_parameters_proposal_voting_period(),
+        grace_period: <Module<T>>::set_election_parameters_proposal_grace_period(),
         approval_quorum_percentage: 66,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
@@ -59,8 +59,9 @@ pub(crate) fn set_election_parameters_proposal<T: crate::Trait>(
 pub(crate) fn set_content_working_group_mint_capacity_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(43200u32),
-        grace_period: T::BlockNumber::from(0u32),
+        voting_period: <Module<T>>::set_content_working_group_mint_capacity_proposal_voting_period(
+        ),
+        grace_period: <Module<T>>::set_content_working_group_mint_capacity_proposal_grace_period(),
         approval_quorum_percentage: 50,
         approval_threshold_percentage: 75,
         slashing_quorum_percentage: 60,
@@ -73,8 +74,8 @@ pub(crate) fn set_content_working_group_mint_capacity_proposal<T: crate::Trait>(
 pub(crate) fn spending_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(72000u32),
-        grace_period: T::BlockNumber::from(14400u32),
+        voting_period: <Module<T>>::spending_proposal_voting_period(),
+        grace_period: <Module<T>>::spending_proposal_grace_period(),
         approval_quorum_percentage: 66,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
@@ -87,8 +88,8 @@ pub(crate) fn spending_proposal<T: crate::Trait>(
 pub(crate) fn set_lead_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(43200u32),
-        grace_period: T::BlockNumber::from(0u32),
+        voting_period: <Module<T>>::set_lead_proposal_voting_period(),
+        grace_period: <Module<T>>::set_lead_proposal_grace_period(),
         approval_quorum_percentage: 66,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
@@ -101,8 +102,8 @@ pub(crate) fn set_lead_proposal<T: crate::Trait>(
 pub(crate) fn evict_storage_provider_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(43200u32),
-        grace_period: T::BlockNumber::from(0u32),
+        voting_period: <Module<T>>::evict_storage_provider_proposal_voting_period(),
+        grace_period: <Module<T>>::evict_storage_provider_proposal_grace_period(),
         approval_quorum_percentage: 50,
         approval_threshold_percentage: 75,
         slashing_quorum_percentage: 60,
@@ -115,8 +116,8 @@ pub(crate) fn evict_storage_provider_proposal<T: crate::Trait>(
 pub(crate) fn set_storage_role_parameters_proposal<T: crate::Trait>(
 ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
     ProposalParameters {
-        voting_period: T::BlockNumber::from(43200u32),
-        grace_period: T::BlockNumber::from(14400u32),
+        voting_period: <Module<T>>::set_storage_role_parameters_proposal_voting_period(),
+        grace_period: <Module<T>>::set_storage_role_parameters_proposal_grace_period(),
         approval_quorum_percentage: 75,
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,

+ 8 - 0
runtime-modules/proposals/codex/src/tests/mock.rs

@@ -3,6 +3,7 @@
 // TODO: remove after post-Rome substrate upgrade
 #![allow(array_into_iter)]
 
+use crate::{ProposalDetailsOf, ProposalEncoder};
 pub use primitives::{Blake2Hasher, H256};
 use proposal_engine::VotersParameters;
 use sr_primitives::curve::PiecewiseLinear;
@@ -249,6 +250,13 @@ impl crate::Trait for Test {
     type TextProposalMaxLength = TextProposalMaxLength;
     type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
     type MembershipOriginValidator = ();
+    type ProposalEncoder = ();
+}
+
+impl ProposalEncoder<Test> for () {
+    fn encode_proposal(_proposal_details: ProposalDetailsOf<Test>) -> Vec<u8> {
+        Vec::new()
+    }
 }
 
 impl system::Trait for Test {

+ 1 - 2
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -8,7 +8,6 @@ use system::RawOrigin;
 use crate::{BalanceOf, Error, ProposalDetails};
 use proposal_engine::ProposalParameters;
 use roles::actors::RoleParameters;
-use runtime_io::blake2_256;
 use srml_support::dispatch::DispatchResult;
 
 pub use mock::*;
@@ -223,7 +222,7 @@ fn create_runtime_upgrade_common_checks_succeed() {
                 )
             },
             proposal_parameters: crate::proposal_types::parameters::runtime_upgrade_proposal::<Test>(),
-            proposal_details: ProposalDetails::RuntimeUpgrade(blake2_256(b"wasm").to_vec()),
+            proposal_details: ProposalDetails::RuntimeUpgrade(b"wasm".to_vec()),
         };
         proposal_fixture.check_all();
     });

+ 3 - 0
runtime/Cargo.toml

@@ -59,6 +59,9 @@ std = [
     'roles/std',
     'service_discovery/std',
     'storage/std',
+    'proposals_engine/std',
+    'proposals_discussion/std',
+    'proposals_codex/std',
 ]
 
 # [dependencies]

+ 2 - 0
runtime/src/integration/proposals/mod.rs

@@ -3,9 +3,11 @@
 mod council_elected_handler;
 mod council_origin_validator;
 mod membership_origin_validator;
+mod proposal_encoder;
 mod staking_events_handler;
 
 pub use council_elected_handler::CouncilElectedHandler;
 pub use council_origin_validator::CouncilManager;
 pub use membership_origin_validator::{MemberId, MembershipOriginValidator};
+pub use proposal_encoder::ExtrinsicProposalEncoder;
 pub use staking_events_handler::StakingEventsHandler;

+ 51 - 0
runtime/src/integration/proposals/proposal_encoder.rs

@@ -0,0 +1,51 @@
+use crate::{Call, Runtime};
+use proposals_codex::{ProposalDetails, ProposalDetailsOf, ProposalEncoder};
+use roles::actors::Role;
+
+use codec::Encode;
+use rstd::vec::Vec;
+
+/// _ProposalEncoder_ implementation. It encodes extrinsics with proposal details parameters
+/// using Runtime Call and parity codec.
+pub struct ExtrinsicProposalEncoder;
+impl ProposalEncoder<Runtime> for ExtrinsicProposalEncoder {
+    fn encode_proposal(proposal_details: ProposalDetailsOf<Runtime>) -> Vec<u8> {
+        match proposal_details {
+            ProposalDetails::Text(text) => {
+                Call::ProposalsCodex(proposals_codex::Call::execute_text_proposal(text)).encode()
+            }
+            ProposalDetails::SetElectionParameters(election_parameters) => Call::CouncilElection(
+                governance::election::Call::set_election_parameters(election_parameters),
+            )
+            .encode(),
+            ProposalDetails::SetContentWorkingGroupMintCapacity(mint_balance) => {
+                Call::ContentWorkingGroup(content_working_group::Call::set_mint_capacity(
+                    mint_balance,
+                ))
+                .encode()
+            }
+            ProposalDetails::Spending(balance, destination) => Call::Council(
+                governance::council::Call::spend_from_council_mint(balance, destination),
+            )
+            .encode(),
+            ProposalDetails::SetLead(new_lead) => {
+                Call::ContentWorkingGroup(content_working_group::Call::replace_lead(new_lead))
+                    .encode()
+            }
+            ProposalDetails::EvictStorageProvider(actor_account) => {
+                Call::Actors(roles::actors::Call::remove_actor(actor_account)).encode()
+            }
+            ProposalDetails::SetValidatorCount(new_validator_count) => {
+                Call::Staking(staking::Call::set_validator_count(new_validator_count)).encode()
+            }
+            ProposalDetails::SetStorageRoleParameters(role_parameters) => Call::Actors(
+                roles::actors::Call::set_role_parameters(Role::StorageProvider, role_parameters),
+            )
+            .encode(),
+            ProposalDetails::RuntimeUpgrade(wasm_code) => Call::ProposalsCodex(
+                proposals_codex::Call::execute_runtime_upgrade_proposal(wasm_code),
+            )
+            .encode(),
+        }
+    }
+}

+ 3 - 2
runtime/src/lib.rs

@@ -59,7 +59,7 @@ pub use srml_support::{
 pub use staking::StakerStatus;
 pub use timestamp::Call as TimestampCall;
 
-use integration::proposals::{CouncilManager, MembershipOriginValidator};
+use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder, MembershipOriginValidator};
 
 /// An index to a block.
 pub type BlockNumber = u32;
@@ -866,6 +866,7 @@ impl proposals_codex::Trait for Runtime {
     type MembershipOriginValidator = MembershipOriginValidator<Self>;
     type TextProposalMaxLength = TextProposalMaxLength;
     type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
+    type ProposalEncoder = ExtrinsicProposalEncoder;
 }
 
 construct_runtime!(
@@ -913,7 +914,7 @@ construct_runtime!(
         // --- Proposals
         ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
         ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
-        ProposalsCodex: proposals_codex::{Module, Call, Storage, Error},
+        ProposalsCodex: proposals_codex::{Module, Call, Storage, Error, Config<T>},
         // ---
 	}
 );

+ 372 - 10
runtime/src/test/proposals_integration.rs

@@ -2,18 +2,22 @@
 
 #![cfg(test)]
 
-use crate::{ProposalCancellationFee, Runtime};
+use crate::{BlockNumber, ElectionParameters, ProposalCancellationFee, Runtime};
 use codec::Encode;
 use governance::election::CouncilElected;
 use membership::members;
+use membership::role_types::Role;
 use proposals_engine::{
-    ActiveStake, BalanceOf, Error, FinalizationData, Proposal, ProposalDecisionStatus,
-    ProposalParameters, ProposalStatus, VoteKind, VotersParameters, VotingResults,
+    ActiveStake, ApprovedProposalStatus, BalanceOf, Error, FinalizationData, Proposal,
+    ProposalDecisionStatus, ProposalParameters, ProposalStatus, VoteKind, VotersParameters,
+    VotingResults,
 };
-use sr_primitives::traits::DispatchResult;
+use roles::actors::RoleParameters;
+
+use sr_primitives::traits::{DispatchResult, OnFinalize, OnInitialize};
 use sr_primitives::AccountId32;
 use srml_support::traits::Currency;
-use srml_support::StorageLinkedMap;
+use srml_support::{StorageLinkedMap, StorageMap, StorageValue};
 use system::RawOrigin;
 
 use crate::CouncilManager;
@@ -26,9 +30,14 @@ fn initial_test_ext() -> runtime_io::TestExternalities {
     t.into()
 }
 
+type Balances = balances::Module<Runtime>;
+type System = system::Module<Runtime>;
 type Membership = membership::members::Module<Runtime>;
 type ProposalsEngine = proposals_engine::Module<Runtime>;
 type Council = governance::council::Module<Runtime>;
+type Election = governance::election::Module<Runtime>;
+type ProposalCodex = proposals_codex::Module<Runtime>;
+type Mint = minting::Module<Runtime>;
 
 fn setup_members(count: u8) {
     let authority_account_id = <Runtime as system::Trait>::AccountId::default();
@@ -71,6 +80,30 @@ fn setup_council() {
     .is_ok());
 }
 
+pub(crate) fn increase_total_balance_issuance_using_account_id(
+    account_id: AccountId32,
+    balance: u128,
+) {
+    type Balances = balances::Module<Runtime>;
+    let initial_balance = Balances::total_issuance();
+    {
+        let _ = <Runtime as stake::Trait>::Currency::deposit_creating(&account_id, balance);
+    }
+    assert_eq!(Balances::total_issuance(), initial_balance + balance);
+}
+
+// Recommendation from Parity on testing on_finalize
+// https://substrate.dev/docs/en/next/development/module/tests
+fn run_to_block(n: BlockNumber) {
+    while System::block_number() < n {
+        <System as OnFinalize<BlockNumber>>::on_finalize(System::block_number());
+        <ProposalsEngine as OnFinalize<BlockNumber>>::on_finalize(System::block_number());
+        System::set_block_number(System::block_number() + 1);
+        <System as OnInitialize<BlockNumber>>::on_initialize(System::block_number());
+        <ProposalsEngine as OnInitialize<BlockNumber>>::on_initialize(System::block_number());
+    }
+}
+
 struct VoteGenerator {
     proposal_id: u32,
     current_account_id: AccountId32,
@@ -129,11 +162,8 @@ impl Default for DummyProposalFixture {
     fn default() -> Self {
         let title = b"title".to_vec();
         let description = b"description".to_vec();
-        let dummy_proposal = proposals_codex::Call::<Runtime>::execute_text_proposal(
-            title.clone(),
-            description.clone(),
-            b"text".to_vec(),
-        );
+        let dummy_proposal =
+            proposals_codex::Call::<Runtime>::execute_text_proposal(b"text".to_vec());
 
         DummyProposalFixture {
             parameters: ProposalParameters {
@@ -365,3 +395,335 @@ fn proposal_reset_succeeds() {
         assert_eq!(CouncilManager::<Runtime>::total_voters_count(), 0);
     });
 }
+
+struct CodexProposalTestFixture<SuccessfulCall>
+where
+    SuccessfulCall: Fn() -> DispatchResult<proposals_codex::Error>,
+{
+    successful_call: SuccessfulCall,
+    member_id: u64,
+}
+
+impl<SuccessfulCall> CodexProposalTestFixture<SuccessfulCall>
+where
+    SuccessfulCall: Fn() -> DispatchResult<proposals_codex::Error>,
+{
+    fn call_extrinsic_and_assert(&self) {
+        setup_members(15);
+        setup_council();
+
+        let account_id: [u8; 32] = [self.member_id as u8; 32];
+        increase_total_balance_issuance_using_account_id(account_id.clone().into(), 500000);
+
+        assert_eq!((self.successful_call)(), Ok(()));
+
+        let proposal_id = 1;
+
+        let mut vote_generator = VoteGenerator::new(proposal_id);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+
+        run_to_block(2);
+
+        let proposal = ProposalsEngine::proposals(proposal_id);
+
+        assert_eq!(
+            proposal,
+            Proposal {
+                status: ProposalStatus::approved(ApprovedProposalStatus::Executed, 1),
+                title: b"title".to_vec(),
+                description: b"body".to_vec(),
+                voting_results: VotingResults {
+                    abstentions: 0,
+                    approvals: 5,
+                    rejections: 0,
+                    slashes: 0,
+                },
+                ..proposal
+            }
+        );
+    }
+}
+
+#[test]
+fn text_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 10;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_text_proposal(
+                    RawOrigin::Signed(account_id.into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    b"text".to_vec(),
+                )
+            },
+        };
+
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+    });
+}
+
+#[test]
+fn set_lead_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 10;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_set_lead_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    Some((member_id as u64, account_id.into())),
+                )
+            },
+        };
+
+        assert!(content_working_group::Module::<Runtime>::ensure_lead_is_set().is_err());
+
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert!(content_working_group::Module::<Runtime>::ensure_lead_is_set().is_ok());
+    });
+}
+
+#[test]
+fn spending_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 10;
+        let account_id: [u8; 32] = [member_id; 32];
+        let new_balance = <BalanceOf<Runtime>>::from(5555u32);
+
+        let target_account_id: [u8; 32] = [12; 32];
+
+        assert!(Council::set_council_mint_capacity(RawOrigin::Root.into(), new_balance).is_ok());
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_spending_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    new_balance,
+                    target_account_id.clone().into(),
+                )
+            },
+        };
+
+        assert_eq!(
+            Balances::free_balance::<AccountId32>(target_account_id.clone().into()),
+            0
+        );
+
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(
+            Balances::free_balance::<AccountId32>(target_account_id.into()),
+            new_balance
+        );
+    });
+}
+
+#[test]
+fn set_content_working_group_mint_capacity_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 1;
+        let account_id: [u8; 32] = [member_id; 32];
+        let new_balance = <BalanceOf<Runtime>>::from(55u32);
+
+        let mint_id =
+            Mint::add_mint(0, None).expect("Failed to create a mint for the content working group");
+        <content_working_group::Mint<Runtime>>::put(mint_id);
+
+        assert_eq!(Mint::get_mint_capacity(mint_id), Ok(0));
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_set_content_working_group_mint_capacity_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    new_balance,
+                )
+            },
+        };
+
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(Mint::get_mint_capacity(mint_id), Ok(new_balance));
+    });
+}
+
+#[test]
+fn set_election_parameters_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 1;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        let election_parameters = ElectionParameters {
+            announcing_period: 14400,
+            voting_period: 14400,
+            revealing_period: 14400,
+            council_size: 4,
+            candidacy_limit: 25,
+            new_term_duration: 14400,
+            min_council_stake: 1,
+            min_voting_stake: 1,
+        };
+        assert_eq!(Election::announcing_period(), 0);
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_set_election_parameters_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(3750u32)),
+                    election_parameters,
+                )
+            },
+        };
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(Election::announcing_period(), 14400);
+    });
+}
+
+#[test]
+fn evict_storage_provider_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 1;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        let target_member_id = 3;
+        let target_account: [u8; 32] = [target_member_id; 32];
+        let target_account_id: AccountId32 = target_account.into();
+
+        <roles::actors::Parameters<Runtime>>::insert(
+            Role::StorageProvider,
+            roles::actors::RoleParameters::default(),
+        );
+
+        <roles::actors::AccountIdsByRole<Runtime>>::insert(
+            Role::StorageProvider,
+            vec![target_account_id.clone()],
+        );
+
+        <roles::actors::ActorByAccountId<Runtime>>::insert(
+            target_account_id.clone(),
+            roles::actors::Actor {
+                member_id: target_member_id as u64,
+                role: Role::StorageProvider,
+                account: target_account_id,
+                joined_at: 1,
+            },
+        );
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_evict_storage_provider_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(500u32)),
+                    target_account.into(),
+                )
+            },
+        };
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(
+            <roles::actors::AccountIdsByRole<Runtime>>::get(Role::StorageProvider),
+            Vec::new()
+        );
+    });
+}
+
+#[test]
+fn set_storage_role_parameters_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 1;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        <roles::actors::Parameters<Runtime>>::insert(
+            Role::StorageProvider,
+            RoleParameters::default(),
+        );
+
+        let target_role_parameters = RoleParameters {
+            startup_grace_period: 700,
+            ..RoleParameters::default()
+        };
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_set_storage_role_parameters_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    target_role_parameters.clone(),
+                )
+            },
+        };
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(
+            <roles::actors::Parameters<Runtime>>::get(Role::StorageProvider),
+            Some(target_role_parameters)
+        );
+    });
+}
+
+#[test]
+fn set_validator_count_proposal_execution_succeeds() {
+    initial_test_ext().execute_with(|| {
+        let member_id = 1;
+        let account_id: [u8; 32] = [member_id; 32];
+
+        let new_validator_count = 8;
+        assert_eq!(<staking::ValidatorCount>::get(), 0);
+
+        let codex_extrinsic_test_fixture = CodexProposalTestFixture {
+            member_id: member_id as u64,
+            successful_call: || {
+                ProposalCodex::create_set_validator_count_proposal(
+                    RawOrigin::Signed(account_id.clone().into()).into(),
+                    member_id as u64,
+                    b"title".to_vec(),
+                    b"body".to_vec(),
+                    Some(<BalanceOf<Runtime>>::from(1250u32)),
+                    new_validator_count,
+                )
+            },
+        };
+        codex_extrinsic_test_fixture.call_extrinsic_and_assert();
+
+        assert_eq!(<staking::ValidatorCount>::get(), new_validator_count);
+    });
+}