Name the score of the election in election finalized event (#12069)

* Name the score of the election in ElectionFinalized event

* fmt

* 1.Adjust the logic of the function 'do_elect()'.
2.Add one test that does ElectionCompute::Signed and one that does ElectionCompute::Unsigned to check 'Event::SolutionStored' and 'Event::ElectionFinalized'

* Fix from kian

* fmt and update comment.

Co-authored-by: kianenigma <kian@parity.io>
This commit is contained in:
ZhiYong
2022-09-01 18:39:25 +08:00
committed by GitHub
parent f67c06ce22
commit 3e63e70b26
@@ -494,6 +494,8 @@ pub enum ElectionError<T: Config> {
DataProvider(&'static str), DataProvider(&'static str),
/// An error nested in the fallback. /// An error nested in the fallback.
Fallback(FallbackErrorOf<T>), Fallback(FallbackErrorOf<T>),
/// No solution has been queued.
NothingQueued,
} }
// NOTE: we have to do this manually because of the additional where clause needed on // NOTE: we have to do this manually because of the additional where clause needed on
@@ -900,7 +902,7 @@ pub mod pallet {
let ejected_a_solution = <QueuedSolution<T>>::exists(); let ejected_a_solution = <QueuedSolution<T>>::exists();
<QueuedSolution<T>>::put(ready); <QueuedSolution<T>>::put(ready);
Self::deposit_event(Event::SolutionStored { Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Unsigned, compute: ElectionCompute::Unsigned,
prev_ejected: ejected_a_solution, prev_ejected: ejected_a_solution,
}); });
@@ -948,7 +950,7 @@ pub mod pallet {
}; };
Self::deposit_event(Event::SolutionStored { Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Emergency, compute: ElectionCompute::Emergency,
prev_ejected: QueuedSolution::<T>::exists(), prev_ejected: QueuedSolution::<T>::exists(),
}); });
@@ -1024,7 +1026,7 @@ pub mod pallet {
signed_submissions.put(); signed_submissions.put();
Self::deposit_event(Event::SolutionStored { Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Signed, compute: ElectionCompute::Signed,
prev_ejected: ejected_a_solution, prev_ejected: ejected_a_solution,
}); });
Ok(()) Ok(())
@@ -1062,7 +1064,7 @@ pub mod pallet {
}; };
Self::deposit_event(Event::SolutionStored { Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Fallback, compute: ElectionCompute::Fallback,
prev_ejected: QueuedSolution::<T>::exists(), prev_ejected: QueuedSolution::<T>::exists(),
}); });
@@ -1080,10 +1082,13 @@ pub mod pallet {
/// solution is unsigned, this means that it has also been processed. /// solution is unsigned, this means that it has also been processed.
/// ///
/// The `bool` is `true` when a previous solution was ejected to make room for this one. /// The `bool` is `true` when a previous solution was ejected to make room for this one.
SolutionStored { election_compute: ElectionCompute, prev_ejected: bool }, SolutionStored { compute: ElectionCompute, prev_ejected: bool },
/// The election has been finalized, with `Some` of the given computation, or else if the /// The election has been finalized, with the given computation and score.
/// election failed, `None`. ElectionFinalized { compute: ElectionCompute, score: ElectionScore },
ElectionFinalized { election_compute: Option<ElectionCompute> }, /// An election failed.
///
/// Not much can be said about which computes failed in the process.
ElectionFailed,
/// An account has been rewarded for their signed submission being finalized. /// An account has been rewarded for their signed submission being finalized.
Rewarded { account: <T as frame_system::Config>::AccountId, value: BalanceOf<T> }, Rewarded { account: <T as frame_system::Config>::AccountId, value: BalanceOf<T> },
/// An account has been slashed for submitting an invalid signed submission. /// An account has been slashed for submitting an invalid signed submission.
@@ -1530,23 +1535,25 @@ impl<T: Config> Pallet<T> {
// inexpensive (1 read of an empty vector). // inexpensive (1 read of an empty vector).
let _ = Self::finalize_signed_phase(); let _ = Self::finalize_signed_phase();
<QueuedSolution<T>>::take() <QueuedSolution<T>>::take()
.map_or_else( .ok_or(ElectionError::<T>::NothingQueued)
|| { .or_else(|_| {
T::Fallback::elect() T::Fallback::elect()
.map_err(|fe| ElectionError::Fallback(fe)) .map(|supports| ReadySolution {
.map(|supports| (supports, ElectionCompute::Fallback)) supports,
}, score: Default::default(),
|ReadySolution { supports, compute, .. }| Ok((supports, compute)), compute: ElectionCompute::Fallback,
) })
.map(|(supports, compute)| { .map_err(|fe| ElectionError::Fallback(fe))
Self::deposit_event(Event::ElectionFinalized { election_compute: Some(compute) }); })
.map(|ReadySolution { compute, score, supports }| {
Self::deposit_event(Event::ElectionFinalized { compute, score });
if Self::round() != 1 { if Self::round() != 1 {
log!(info, "Finalized election round with compute {:?}.", compute); log!(info, "Finalized election round with compute {:?}.", compute);
} }
supports supports
}) })
.map_err(|err| { .map_err(|err| {
Self::deposit_event(Event::ElectionFinalized { election_compute: None }); Self::deposit_event(Event::ElectionFailed);
if Self::round() != 1 { if Self::round() != 1 {
log!(warn, "Failed to finalize election round. reason {:?}", err); log!(warn, "Failed to finalize election round. reason {:?}", err);
} }
@@ -1800,8 +1807,9 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
mock::{ mock::{
multi_phase_events, roll_to, AccountId, ExtBuilder, MockWeightInfo, MockedWeightInfo, multi_phase_events, raw_solution, roll_to, AccountId, ExtBuilder, MockWeightInfo,
MultiPhase, Origin, Runtime, SignedMaxSubmissions, System, TargetIndex, Targets, MockedWeightInfo, MultiPhase, Origin, Runtime, SignedMaxSubmissions, System,
TargetIndex, Targets,
}, },
Phase, Phase,
}; };
@@ -1967,7 +1975,10 @@ mod tests {
multi_phase_events(), multi_phase_events(),
vec![ vec![
Event::SignedPhaseStarted { round: 1 }, Event::SignedPhaseStarted { round: 1 },
Event::ElectionFinalized { election_compute: Some(ElectionCompute::Fallback) } Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: Default::default()
}
], ],
); );
// All storage items must be cleared. // All storage items must be cleared.
@@ -2016,6 +2027,88 @@ mod tests {
}) })
} }
#[test]
fn check_events_with_compute_signed() {
ExtBuilder::default().build_and_execute(|| {
roll_to(14);
assert_eq!(MultiPhase::current_phase(), Phase::Off);
roll_to(15);
assert!(MultiPhase::current_phase().is_signed());
let solution = raw_solution();
assert_ok!(MultiPhase::submit(crate::mock::Origin::signed(99), Box::new(solution)));
roll_to(30);
assert_ok!(MultiPhase::elect());
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::Rewarded { account: 99, value: 7 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Signed,
score: ElectionScore {
minimal_stake: 40,
sum_stake: 100,
sum_stake_squared: 5200
}
}
],
);
})
}
#[test]
fn check_events_with_compute_unsigned() {
ExtBuilder::default().build_and_execute(|| {
roll_to(25);
assert!(MultiPhase::current_phase().is_unsigned());
// ensure we have snapshots in place.
assert!(MultiPhase::snapshot().is_some());
assert_eq!(MultiPhase::desired_targets().unwrap(), 2);
// mine seq_phragmen solution with 2 iters.
let (solution, witness) = MultiPhase::mine_solution().unwrap();
// ensure this solution is valid.
assert!(MultiPhase::queued_solution().is_none());
assert_ok!(MultiPhase::submit_unsigned(
crate::mock::Origin::none(),
Box::new(solution),
witness
));
assert!(MultiPhase::queued_solution().is_some());
roll_to(30);
assert_ok!(MultiPhase::elect());
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Unsigned,
prev_ejected: false
},
Event::ElectionFinalized {
compute: ElectionCompute::Unsigned,
score: ElectionScore {
minimal_stake: 40,
sum_stake: 100,
sum_stake_squared: 5200
}
}
],
);
})
}
#[test] #[test]
fn fallback_strategy_works() { fn fallback_strategy_works() {
ExtBuilder::default().onchain_fallback(true).build_and_execute(|| { ExtBuilder::default().onchain_fallback(true).build_and_execute(|| {
@@ -2080,12 +2173,15 @@ mod tests {
vec![ vec![
Event::SignedPhaseStarted { round: 1 }, Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 }, Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized { election_compute: None }, Event::ElectionFailed,
Event::SolutionStored { Event::SolutionStored {
election_compute: ElectionCompute::Fallback, compute: ElectionCompute::Fallback,
prev_ejected: false prev_ejected: false
}, },
Event::ElectionFinalized { election_compute: Some(ElectionCompute::Fallback) } Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: Default::default()
}
] ]
); );
}) })