From 20ef36f1b2976d1c99ed7b7f353534a7aa2795c2 Mon Sep 17 00:00:00 2001
From: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Date: Thu, 19 May 2022 12:54:40 +0100
Subject: [PATCH] add missing events to elections fallback (#11436)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* add missing events to elections fallback

* Update frame/election-provider-multi-phase/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/election-provider-multi-phase/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* add test

* fix

* fmt

* Update frame/support/src/storage/types/nmap.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
---
 .../election-provider-multi-phase/src/lib.rs  | 56 ++++++++++++++++++-
 .../election-provider-multi-phase/src/mock.rs |  6 +-
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs
index 36d2373c9f6..7d8559050f3 100644
--- a/substrate/frame/election-provider-multi-phase/src/lib.rs
+++ b/substrate/frame/election-provider-multi-phase/src/lib.rs
@@ -948,6 +948,11 @@ pub mod pallet {
 				compute: ElectionCompute::Emergency,
 			};
 
+			Self::deposit_event(Event::SolutionStored {
+				election_compute: ElectionCompute::Emergency,
+				prev_ejected: QueuedSolution::<T>::exists(),
+			});
+
 			<QueuedSolution<T>>::put(solution);
 			Ok(())
 		}
@@ -1057,6 +1062,11 @@ pub mod pallet {
 				compute: ElectionCompute::Fallback,
 			};
 
+			Self::deposit_event(Event::SolutionStored {
+				election_compute: ElectionCompute::Fallback,
+				prev_ejected: QueuedSolution::<T>::exists(),
+			});
+
 			<QueuedSolution<T>>::put(solution);
 			Ok(())
 		}
@@ -1792,7 +1802,7 @@ mod tests {
 	use crate::{
 		mock::{
 			multi_phase_events, roll_to, AccountId, ExtBuilder, MockWeightInfo, MockedWeightInfo,
-			MultiPhase, Runtime, SignedMaxSubmissions, System, TargetIndex, Targets,
+			MultiPhase, Origin, Runtime, SignedMaxSubmissions, System, TargetIndex, Targets,
 		},
 		Phase,
 	};
@@ -2038,6 +2048,50 @@ mod tests {
 		})
 	}
 
+	#[test]
+	fn governance_fallback_works() {
+		ExtBuilder::default().onchain_fallback(false).build_and_execute(|| {
+			roll_to(25);
+			assert_eq!(MultiPhase::current_phase(), Phase::Unsigned((true, 25)));
+
+			// Zilch solutions thus far.
+			assert!(MultiPhase::queued_solution().is_none());
+			assert_eq!(MultiPhase::elect().unwrap_err(), ElectionError::Fallback("NoFallback."));
+
+			// phase is now emergency.
+			assert_eq!(MultiPhase::current_phase(), Phase::Emergency);
+			assert!(MultiPhase::queued_solution().is_none());
+
+			// no single account can trigger this
+			assert_noop!(
+				MultiPhase::governance_fallback(Origin::signed(99), None, None),
+				DispatchError::BadOrigin
+			);
+
+			// only root can
+			assert_ok!(MultiPhase::governance_fallback(Origin::root(), None, None));
+			// something is queued now
+			assert!(MultiPhase::queued_solution().is_some());
+			// next election call with fix everything.;
+			assert!(MultiPhase::elect().is_ok());
+			assert_eq!(MultiPhase::current_phase(), Phase::Off);
+
+			assert_eq!(
+				multi_phase_events(),
+				vec![
+					Event::SignedPhaseStarted { round: 1 },
+					Event::UnsignedPhaseStarted { round: 1 },
+					Event::ElectionFinalized { election_compute: None },
+					Event::SolutionStored {
+						election_compute: ElectionCompute::Fallback,
+						prev_ejected: false
+					},
+					Event::ElectionFinalized { election_compute: Some(ElectionCompute::Fallback) }
+				]
+			);
+		})
+	}
+
 	#[test]
 	fn snapshot_too_big_failure_onchain_fallback() {
 		// the `MockStaking` is designed such that if it has too many targets, it simply fails.
diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs
index afce24ff6e3..bbc2d6d43be 100644
--- a/substrate/frame/election-provider-multi-phase/src/mock.rs
+++ b/substrate/frame/election-provider-multi-phase/src/mock.rs
@@ -18,7 +18,9 @@
 use super::*;
 use crate::{self as multi_phase, unsigned::MinerConfig};
 use frame_election_provider_support::{
-	data_provider, onchain, ElectionDataProvider, NposSolution, SequentialPhragmen,
+	data_provider,
+	onchain::{self, UnboundedExecution},
+	ElectionDataProvider, NposSolution, SequentialPhragmen,
 };
 pub use frame_support::{assert_noop, assert_ok, pallet_prelude::GetDefault};
 use frame_support::{
@@ -379,7 +381,7 @@ impl crate::Config for Runtime {
 	type WeightInfo = ();
 	type BenchmarkingConfig = TestBenchmarkingConfig;
 	type Fallback = MockFallback;
-	type GovernanceFallback = NoFallback<Self>;
+	type GovernanceFallback = UnboundedExecution<OnChainSeqPhragmen>;
 	type ForceOrigin = frame_system::EnsureRoot<AccountId>;
 	type MaxElectingVoters = MaxElectingVoters;
 	type MaxElectableTargets = MaxElectableTargets;
-- 
GitLab