Browse Source

Merge pull request #1767 from ondratra/council_referendum_connection

council - referendum start infallible
Bedeho Mender 4 years ago
parent
commit
2f7e0be55c

+ 4 - 14
runtime-modules/council/src/lib.rs

@@ -57,7 +57,7 @@ use serde::{Deserialize, Serialize};
 use sp_arithmetic::traits::BaseArithmetic;
 use sp_runtime::traits::{Hash, MaybeSerialize, Member};
 use std::marker::PhantomData;
-use system::{ensure_signed, RawOrigin};
+use system::ensure_signed;
 
 use referendum::{OptionResult, ReferendumManager};
 
@@ -303,10 +303,6 @@ decl_error! {
         /// Candidate can't vote for himself.
         CantVoteForYourself,
 
-        /// Invalid runtime implementation broke the council. This error shouldn't happen
-        /// and in case of bad implementation should be discovered in the first block when referendum start will fail.
-        InvalidRuntimeImplementation,
-
         /// Invalid membership.
         MembershipIdNotMatchAccount,
 
@@ -471,9 +467,8 @@ impl<T: Trait> Module<T> {
             return;
         }
 
-        // TODO: try to find way how to get rid of unwrap here or staticly ensure it will not fail here
         // update state
-        Mutations::<T>::finalize_announcing_period(&stage_data).unwrap(); // starting referendum should always start if implementation is valid - unwrap
+        Mutations::<T>::finalize_announcing_period(&stage_data);
 
         // emit event
         Self::deposit_event(RawEvent::VotingPeriodStarted(stage_data.candidates_count));
@@ -605,14 +600,11 @@ impl<T: Trait> Mutations<T> {
     }
 
     /// Change the council stage from the announcing to the election stage.
-    fn finalize_announcing_period(stage_data: &CouncilStageAnnouncing) -> Result<(), Error<T>> {
+    fn finalize_announcing_period(stage_data: &CouncilStageAnnouncing) {
         let extra_winning_target_count = T::CouncilSize::get() - 1;
-        let origin = RawOrigin::Root;
 
-        // IMPORTANT - because starting referendum can fail it has to be the first mutation!
         // start referendum
-        T::Referendum::start_referendum(origin.into(), extra_winning_target_count)
-            .map_err(|_| Error::<T>::InvalidRuntimeImplementation)?;
+        T::Referendum::force_start(extra_winning_target_count);
 
         let block_number = <system::Module<T>>::block_number();
 
@@ -623,8 +615,6 @@ impl<T: Trait> Mutations<T> {
             }),
             changed_at: block_number + 1.into(), // set next block as the start of next phase (this function is invoke on block finalization)
         });
-
-        Ok(())
     }
 
     /// Elect new council after successful election.

+ 26 - 1
runtime-modules/referendum/src/lib.rs

@@ -138,6 +138,10 @@ pub trait ReferendumManager<Origin, AccountId, Hash> {
     /// Start a new referendum.
     fn start_referendum(origin: Origin, extra_winning_target_count: u64) -> Result<(), ()>;
 
+    /// Start referendum independent of the current state.
+    /// If an election is running before calling this function, it will be discontinued without any winners selected.
+    fn force_start(extra_winning_target_count: u64);
+
     /// Calculate commitment for a vote.
     fn calculate_commitment(
         account_id: &AccountId,
@@ -232,6 +236,9 @@ decl_event! {
         /// Referendum started
         ReferendumStarted(u64),
 
+        /// Referendum started
+        ReferendumStartedForcefully(u64),
+
         /// Revealing phase has begun
         RevealingStageStarted(),
 
@@ -358,7 +365,6 @@ decl_module! {
             Ok(())
         }
 
-
         /// Release a locked stake.
         #[weight = 10_000_000]
         pub fn release_voting_stake(origin) -> Result<(), Error<T, I>> {
@@ -449,6 +455,25 @@ impl<T: Trait<I>, I: Instance> ReferendumManager<T::Origin, T::AccountId, T::Has
         Ok(())
     }
 
+    /// Start referendum independent of the current state.
+    /// If an election is running before calling this function, it will be discontinued without any winners selected.
+    fn force_start(extra_winning_target_count: u64) {
+        let winning_target_count = extra_winning_target_count + 1;
+
+        // remember if referendum is running
+        let referendum_running = !matches!(Stage::<T, I>::get(), ReferendumStage::Inactive);
+
+        // update state
+        Mutations::<T, I>::start_voting_period(&winning_target_count);
+
+        // emit event
+        if referendum_running {
+            Self::deposit_event(RawEvent::ReferendumStartedForcefully(winning_target_count));
+        } else {
+            Self::deposit_event(RawEvent::ReferendumStarted(winning_target_count));
+        }
+    }
+
     /// Calculate commitment for a vote.
     fn calculate_commitment(
         account_id: &<T as system::Trait>::AccountId,

+ 4 - 3
runtime-modules/referendum/src/mock.rs

@@ -556,9 +556,10 @@ impl InstanceMocks<Runtime, Instance0> {
     ) -> () {
         // check method returns expected result
         assert_eq!(
-            Module::<Runtime, Instance0>::release_stake(
-                InstanceMockUtils::<Runtime, Instance0>::mock_origin(origin),
-            ),
+            Module::<Runtime, Instance0>::release_voting_stake(InstanceMockUtils::<
+                Runtime,
+                Instance0,
+            >::mock_origin(origin),),
             expected_result,
         );