Repository: paritytech/substrate
File: frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs (Rust)

Code before:
		// not delayed.
		for _ in 0..100 {
			roll_one(pool_state.clone(), false);
			let current_phase = ElectionProviderMultiPhase::current_phase();

			let result = match QueuedSolution::<Runtime>::get() {
				Some(_solution) if !current_phase.is_unsigned() =>
					Err("solution must be queued only in unsigned phase."),
				None if current_phase.is_unsigned() =>
					Err("solution must be queued during unsigned phase."),
				_ => Ok(()),
			};

			assert_ok!(result);
		}
		// test ocw solution queue if submission in unsigned phase is delayed.
		for _ in 0..100 {
			roll_one(pool_state.clone(), true);

			let result = match QueuedSolution::<Runtime>::get() {
				Some(_solution) =>
					Err("solution must never be submitted since it has been delayed."),
				_ => Ok(()),
			};

			assert_ok!(result);
		}
	})
}

#[test]
/// Replicates the Kusama incident of 8th Dec 2022 and its resolution through the governance
/// fallback.
///
/// After enough slashes exceeded the `Staking::OffendingValidatorsThreshold`, the staking pallet
/// set `Forcing::ForceNew`. When a new session starts, staking will start to force a new era and
/// calls <EPM as election_provider>::elect(). If at this point EPM and the staking miners did not
/// have enough time to queue a new solution (snapshot + solution submission), the election request
/// fails. If there is no election fallback mechanism in place, EPM enters in emergency mode.
/// Recovery: Once EPM is in emergency mode, subsequent calls to `elect()` will fail until a new
/// solution is added to EPM's `QueuedSolution` queue. This can be achieved through
/// `Call::set_emergency_election_result` or `Call::governance_fallback` dispatchables. Once a new
/// solution is added to the queue, EPM phase transitions to `Phase::Off` and the election flow
/// restarts. Note that in this test case, the emergency throttling is disabled.
fn enters_emergency_phase_after_forcing_before_elect() {
	let epm_builder = EpmExtBuilder::default().disable_emergency_throttling();
	let (mut ext, pool_state, _) = ExtBuilder::default().epm(epm_builder).build_offchainify();

	ext.execute_with(|| {
		log!(
			trace,

Review comment (suggestion):
```suggestion
			assert_ok!(QueuedSolution::<Runtime>::get().ok_or("solution must never be submitted since it has been delayed."));
```

Code after:
		// not delayed.
		for _ in 0..100 {
			roll_one(pool_state.clone(), false);
			let current_phase = ElectionProviderMultiPhase::current_phase();

			assert!(
				match QueuedSolution::<Runtime>::get() {
					Some(_) => current_phase.is_unsigned(),
					None => !current_phase.is_unsigned(),
				},
				"solution must be queued *only* in unsigned phase"
			);
		}

		// test ocw solution queue if submission in unsigned phase is delayed.
		for _ in 0..100 {
			roll_one(pool_state.clone(), true);
			assert_eq!(
				QueuedSolution::<Runtime>::get(),
				None,
				"solution must never be submitted and stored since it is delayed"
			);
		}
	})
}

#[test]
/// Replicates the Kusama incident of 8th Dec 2022 and its resolution through the governance
/// fallback.
///
/// After enough slashes exceeded the `Staking::OffendingValidatorsThreshold`, the staking pallet
/// set `Forcing::ForceNew`. When a new session starts, staking will start to force a new era and
/// calls <EPM as election_provider>::elect(). If at this point EPM and the staking miners did not
/// have enough time to queue a new solution (snapshot + solution submission), the election request
/// fails. If there is no election fallback mechanism in place, EPM enters in emergency mode.
/// Recovery: Once EPM is in emergency mode, subsequent calls to `elect()` will fail until a new
/// solution is added to EPM's `QueuedSolution` queue. This can be achieved through
/// `Call::set_emergency_election_result` or `Call::governance_fallback` dispatchables. Once a new
/// solution is added to the queue, EPM phase transitions to `Phase::Off` and the election flow
/// restarts. Note that in this test case, the emergency throttling is disabled.
fn enters_emergency_phase_after_forcing_before_elect() {
	let epm_builder = EpmExtBuilder::default().disable_emergency_throttling();
	let (mut ext, pool_state, _) = ExtBuilder::default().epm(epm_builder).build_offchainify();

	ext.execute_with(|| {
		log!(
			trace,
			"current validators (staking): {:?}",
			<Runtime as pallet_staking::SessionInterface<AccountId>>::validators()
		);
		let session_validators_before = Session::validators();