Browse Source

Migrate to the extrinsic execution model

Shamil Gadelshin 5 years ago
parent
commit
e5da8ee992

+ 1 - 0
runtime-modules/proposals/codex/Cargo.toml

@@ -20,6 +20,7 @@ std = [
     'proposal_discussion/std',
     'stake/std',
     'balances/std',
+    'membership/std',
 ]
 
 

+ 6 - 19
runtime-modules/proposals/codex/src/lib.rs

@@ -17,7 +17,6 @@ mod tests;
 
 use codec::Encode;
 use rstd::clone::Clone;
-use rstd::marker::PhantomData;
 use rstd::prelude::*;
 use rstd::str::from_utf8;
 use rstd::vec::Vec;
@@ -25,7 +24,6 @@ use srml_support::{decl_error, decl_module, decl_storage, ensure, print};
 use system::{ensure_root, RawOrigin};
 
 use proposal_engine::*;
-pub use proposal_types::{ProposalType, RuntimeUpgradeProposalExecutable, TextProposalExecutable};
 
 /// 'Proposals codex' substrate module Trait
 pub trait Trait:
@@ -112,12 +110,7 @@ decl_module! {
             ensure!(text.len() as u32 <=  T::TextProposalMaxLength::get(),
                 Error::TextProposalSizeExceeded);
 
-            let text_proposal = TextProposalExecutable{
-                title: title.clone(),
-                description: description.clone(),
-                text,
-               };
-            let proposal_code = text_proposal.encode();
+            let proposal_code = <Call<T>>::text_proposal(title.clone(), description.clone(), text);
 
             let (cloned_origin1, cloned_origin2) =  Self::double_origin(origin);
 
@@ -134,8 +127,7 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                text_proposal.proposal_type(),
-                proposal_code,
+                proposal_code.encode(),
             )?;
 
              <ThreadIdByProposalId<T>>::insert(proposal_id, discussion_thread_id);
@@ -156,13 +148,7 @@ decl_module! {
             ensure!(wasm.len() as u32 <= T::RuntimeUpgradeWasmProposalMaxLength::get(),
                 Error::RuntimeProposalSizeExceeded);
 
-            let proposal = RuntimeUpgradeProposalExecutable{
-                title: title.clone(),
-                description: description.clone(),
-                wasm,
-                marker : PhantomData::<T>
-               };
-            let proposal_code = proposal.encode();
+            let proposal_code = <Call<T>>::text_proposal(title.clone(), description.clone(), wasm);
 
             let (cloned_origin1, cloned_origin2) =  Self::double_origin(origin);
 
@@ -179,13 +165,14 @@ decl_module! {
                 title,
                 description,
                 stake_balance,
-                proposal.proposal_type(),
-                proposal_code,
+                proposal_code.encode(),
             )?;
 
             <ThreadIdByProposalId<T>>::insert(proposal_id, discussion_thread_id);
         }
 
+// *************** Extrinsic to execute
+
         /// Text proposal extrinsic. Should be used as callable object to pass to the engine module.
         fn text_proposal(
             origin,

+ 25 - 47
runtime-modules/proposals/codex/src/proposal_types/mod.rs

@@ -1,53 +1,31 @@
-use codec::Decode;
-use num_enum::{IntoPrimitive, TryFromPrimitive};
-use rstd::convert::TryFrom;
-use rstd::prelude::*;
+pub(crate) mod parameters {
+    use crate::{BalanceOf, ProposalParameters};
 
-use crate::{ProposalCodeDecoder, ProposalExecutable};
-
-pub mod parameters;
-mod runtime_upgrade;
-mod text_proposal;
-
-pub use runtime_upgrade::RuntimeUpgradeProposalExecutable;
-pub use text_proposal::TextProposalExecutable;
-
-/// Defines allowed proposals types. Integer value serves as proposal_type_id.
-#[derive(Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
-#[repr(u32)]
-pub enum ProposalType {
-    /// Text(signal) proposal type
-    Text = 1,
-
-    /// Runtime upgrade proposal type
-    RuntimeUpgrade = 2,
-}
-
-impl ProposalType {
-    fn compose_executable<T: system::Trait>(
-        &self,
-        proposal_data: Vec<u8>,
-    ) -> Result<Box<dyn ProposalExecutable>, &'static str> {
-        match self {
-            ProposalType::Text => TextProposalExecutable::decode(&mut &proposal_data[..])
-                .map_err(|err| err.what())
-                .map(|obj| Box::new(obj) as Box<dyn ProposalExecutable>),
-            ProposalType::RuntimeUpgrade => {
-                <RuntimeUpgradeProposalExecutable<T>>::decode(&mut &proposal_data[..])
-                    .map_err(|err| err.what())
-                    .map(|obj| Box::new(obj) as Box<dyn ProposalExecutable>)
-            }
+    // Proposal parameters for the upgrade runtime proposal
+    pub(crate) fn upgrade_runtime<T: crate::Trait>(
+    ) -> ProposalParameters<T::BlockNumber, BalanceOf<T>> {
+        ProposalParameters {
+            voting_period: T::BlockNumber::from(50000u32),
+            grace_period: T::BlockNumber::from(10000u32),
+            approval_quorum_percentage: 80,
+            approval_threshold_percentage: 80,
+            slashing_quorum_percentage: 80,
+            slashing_threshold_percentage: 80,
+            required_stake: Some(<BalanceOf<T>>::from(50000u32)),
         }
     }
-}
 
-impl<T: system::Trait> ProposalCodeDecoder<T> for ProposalType {
-    fn decode_proposal(
-        proposal_type: u32,
-        proposal_code: Vec<u8>,
-    ) -> Result<Box<dyn ProposalExecutable>, &'static str> {
-        Self::try_from(proposal_type)
-            .map_err(|_| "Unsupported proposal type")?
-            .compose_executable::<T>(proposal_code)
+    // 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(50000u32),
+            grace_period: T::BlockNumber::from(10000u32),
+            approval_quorum_percentage: 40,
+            approval_threshold_percentage: 51,
+            slashing_quorum_percentage: 80,
+            slashing_threshold_percentage: 80,
+            required_stake: Some(<BalanceOf<T>>::from(500u32)),
+        }
     }
 }

+ 0 - 27
runtime-modules/proposals/codex/src/proposal_types/parameters.rs

@@ -1,27 +0,0 @@
-use crate::{BalanceOf, ProposalParameters};
-
-// Proposal parameters for the upgrade runtime proposal
-pub(crate) fn upgrade_runtime<T: crate::Trait>() -> ProposalParameters<T::BlockNumber, BalanceOf<T>>
-{
-    ProposalParameters {
-        voting_period: T::BlockNumber::from(50000u32),
-        grace_period: T::BlockNumber::from(10000u32),
-        approval_quorum_percentage: 80,
-        approval_threshold_percentage: 80,
-        slashing_quorum_percentage: 80,
-        slashing_threshold_percentage: 80,
-        required_stake: Some(<BalanceOf<T>>::from(50000u32)),
-    }
-}
-// 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(50000u32),
-        grace_period: T::BlockNumber::from(10000u32),
-        approval_quorum_percentage: 40,
-        approval_threshold_percentage: 51,
-        slashing_quorum_percentage: 80,
-        slashing_threshold_percentage: 80,
-        required_stake: Some(<BalanceOf<T>>::from(500u32)),
-    }
-}

+ 0 - 39
runtime-modules/proposals/codex/src/proposal_types/runtime_upgrade.rs

@@ -1,39 +0,0 @@
-use codec::{Decode, Encode};
-use rstd::marker::PhantomData;
-use rstd::prelude::*;
-
-use runtime_primitives::traits::ModuleDispatchError;
-use srml_support::dispatch;
-
-use crate::{ProposalExecutable, ProposalType};
-
-/// Text (signal) proposal executable code wrapper. Prints its content on execution.
-#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug, Default)]
-pub struct RuntimeUpgradeProposalExecutable<T> {
-    /// Proposal title
-    pub title: Vec<u8>,
-
-    /// Proposal description
-    pub description: Vec<u8>,
-
-    /// Text proposal main text
-    pub wasm: Vec<u8>,
-
-    /// Marker for the system::Trait. Required to execute runtime upgrade proposal on exact runtime.
-    pub marker: PhantomData<T>,
-}
-
-impl<T> RuntimeUpgradeProposalExecutable<T> {
-    /// Converts runtime proposal type to proposal_type_id
-    pub fn proposal_type(&self) -> u32 {
-        ProposalType::RuntimeUpgrade.into()
-    }
-}
-
-impl<T: system::Trait> ProposalExecutable for RuntimeUpgradeProposalExecutable<T> {
-    fn execute(&self) -> dispatch::Result {
-        // Update wasm code of node's runtime:
-        <system::Module<T>>::set_code(system::RawOrigin::Root.into(), self.wasm.clone())
-            .map_err(|err| err.as_str())
-    }
-}

+ 0 - 38
runtime-modules/proposals/codex/src/proposal_types/text_proposal.rs

@@ -1,38 +0,0 @@
-use codec::{Decode, Encode};
-use rstd::prelude::*;
-
-use rstd::str::from_utf8;
-use srml_support::{dispatch, print};
-
-use crate::{ProposalExecutable, ProposalType};
-
-/// Text (signal) proposal executable code wrapper. Prints its content on execution.
-#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug, Default)]
-pub struct TextProposalExecutable {
-    /// Text proposal title
-    pub title: Vec<u8>,
-
-    /// Text proposal description
-    pub description: Vec<u8>,
-
-    /// Text proposal main text
-    pub text: Vec<u8>,
-}
-
-impl TextProposalExecutable {
-    /// Converts text proposal type to proposal_type_id
-    pub fn proposal_type(&self) -> u32 {
-        ProposalType::Text.into()
-    }
-}
-
-impl ProposalExecutable for TextProposalExecutable {
-    fn execute(&self) -> dispatch::Result {
-        print("Proposal: ");
-        print(from_utf8(self.title.as_slice()).unwrap());
-        print("Description:");
-        print(from_utf8(self.description.as_slice()).unwrap());
-
-        Ok(())
-    }
-}

+ 2 - 0
runtime-modules/proposals/discussion/Cargo.toml

@@ -16,6 +16,8 @@ std = [
     'system/std',
     'timestamp/std',
     'serde',
+    'membership/std',
+    'common/std',
 ]
 
 

+ 11 - 7
runtime-modules/proposals/engine/Cargo.toml

@@ -12,12 +12,16 @@ std = [
     'rstd/std',
     'srml-support/std',
     'primitives/std',
-    'runtime-primitives/std',
     'system/std',
     'timestamp/std',
     'serde',
     'stake/std',
     'balances/std',
+    'sr-primitives/std',
+    'governance/std',
+    'membership/std',
+    'common/std',
+
 ]
 
 
@@ -48,12 +52,6 @@ git = 'https://github.com/paritytech/substrate.git'
 package = 'sr-std'
 rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
 
-[dependencies.runtime-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
 [dependencies.srml-support]
 default_features = false
 git = 'https://github.com/paritytech/substrate.git'
@@ -78,6 +76,12 @@ default-features = false
 git = 'https://github.com/paritytech/substrate.git'
 rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
 
+[dependencies.sr-primitives]
+default_features = false
+git = 'https://github.com/paritytech/substrate.git'
+package = 'sr-primitives'
+rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+
 [dependencies.stake]
 default_features = false
 package = 'substrate-stake-module'

+ 16 - 13
runtime-modules/proposals/engine/src/lib.rs

@@ -41,17 +41,19 @@ pub(crate) mod types;
 #[cfg(test)]
 mod tests;
 
+use codec::Decode;
 use rstd::prelude::*;
-
-use runtime_primitives::traits::Zero;
+use sr_primitives::traits::Zero;
+use sr_primitives::DispatchError;
 use srml_support::traits::{Currency, Get};
 use srml_support::{
     decl_event, decl_module, decl_storage, dispatch, ensure, Parameter, StorageDoubleMap,
 };
-use system::ensure_root;
+use system::{ensure_root, RawOrigin};
 
 use common::origin_validator::ActorOriginValidator;
 use membership::origin_validator::MemberId;
+use srml_support::dispatch::Dispatchable;
 
 /// Proposals engine trait.
 pub trait Trait:
@@ -77,9 +79,6 @@ pub trait Trait:
     /// Provides data for voting. Defines maximum voters count for the proposal.
     type TotalVotersCounter: VotersParameters;
 
-    /// Converts proposal code binary to executable representation
-    type ProposalCodeDecoder: ProposalCodeDecoder<Self>;
-
     /// Proposal Id type
     type ProposalId: From<u32> + Parameter + Default + Copy;
 
@@ -100,6 +99,11 @@ pub trait Trait:
 
     /// Defines max simultaneous active proposals number.
     type MaxActiveProposalLimit: Get<u32>;
+
+    /// Proposals executable code. Can be instantiated by external module Call enum members.
+    type ProposalCode: Parameter
+        + Dispatchable<Origin = Self::Origin, Error = DispatchError>
+        + Default;
 }
 
 decl_event!(
@@ -262,7 +266,6 @@ impl<T: Trait> Module<T> {
         title: Vec<u8>,
         description: Vec<u8>,
         stake_balance: Option<types::BalanceOf<T>>,
-        proposal_type: u32,
         proposal_code: Vec<u8>,
     ) -> Result<T::ProposalId, &'static str> {
         let account_id =
@@ -306,7 +309,6 @@ impl<T: Trait> Module<T> {
             title,
             description,
             proposer_id: proposer_id.clone(),
-            proposal_type,
             status: ProposalStatus::Active,
             voting_results: VotingResults::default(),
             stake_data,
@@ -366,18 +368,19 @@ impl<T: Trait> Module<T> {
         if let ProposalStatus::Finalized(finalized_status) = proposal.status.clone() {
             let proposal_code = Self::proposal_codes(proposal_id);
 
-            let proposal_code_result =
-                T::ProposalCodeDecoder::decode_proposal(proposal.proposal_type, proposal_code);
+            let proposal_code_result = T::ProposalCode::decode(&mut &proposal_code[..]);
 
             let approved_proposal_status = match proposal_code_result {
                 Ok(proposal_code) => {
-                    if let Err(error) = proposal_code.execute() {
-                        ApprovedProposalStatus::failed_execution(error)
+                    if let Err(error) = proposal_code.dispatch(T::Origin::from(RawOrigin::Root)) {
+                        ApprovedProposalStatus::failed_execution(
+                            error.message.unwrap_or("Dispatch error"),
+                        )
                     } else {
                         ApprovedProposalStatus::Executed
                     }
                 }
-                Err(error) => ApprovedProposalStatus::failed_execution(error),
+                Err(error) => ApprovedProposalStatus::failed_execution(error.what()),
             };
 
             let proposal_execution_status =

+ 0 - 3
runtime-modules/proposals/engine/src/types/mod.rs

@@ -131,9 +131,6 @@ pub struct StakeData<StakeId, AccountId> {
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
 pub struct Proposal<BlockNumber, ProposerId, Balance, StakeId, AccountId> {
-    /// Proposal type id
-    pub proposal_type: u32,
-
     /// Proposals parameter, characterize different proposal types.
     pub parameters: ProposalParameters<BlockNumber, Balance>,
 

+ 1 - 1
runtime-modules/proposals/engine/src/types/stakes.rs

@@ -3,7 +3,7 @@ use crate::Trait;
 use rstd::convert::From;
 use rstd::marker::PhantomData;
 use rstd::rc::Rc;
-use runtime_primitives::traits::Zero;
+use sr_primitives::traits::Zero;
 use srml_support::traits::{Currency, ExistenceRequirement, Imbalance, WithdrawReasons};
 use srml_support::StorageMap;
 

+ 6 - 1
runtime/src/lib.rs

@@ -818,7 +818,6 @@ impl proposals_engine::Trait for Runtime {
     type ProposerOriginValidator = MembershipOriginValidator<Self>;
     type VoterOriginValidator = proposals_engine::CouncilManager<Self>;
     type TotalVotersCounter = proposals_engine::CouncilManager<Self>;
-    type ProposalCodeDecoder = proposals_codex::ProposalType;
     type ProposalId = u32;
     type StakeHandlerProvider = proposals_engine::DefaultStakeHandlerProvider;
     type CancellationFee = ProposalCancellationFee;
@@ -826,6 +825,12 @@ impl proposals_engine::Trait for Runtime {
     type TitleMaxLength = ProposalTitleMaxLength;
     type DescriptionMaxLength = ProposalDescriptionMaxLength;
     type MaxActiveProposalLimit = ProposalMaxActiveProposalLimit;
+    type ProposalCode = Call;
+}
+impl Default for Call {
+    fn default() -> Self {
+        panic!("shouldn't call default for Call");
+    }
 }
 
 parameter_types! {