Skip to content

Commit

Permalink
Name the score of the election in election finalized event (paritytec…
Browse files Browse the repository at this point in the history
…h#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 <[email protected]>
  • Loading branch information
2 people authored and ark0f committed Feb 27, 2023
1 parent f5e3d47 commit 68953cc
Showing 1 changed file with 121 additions and 25 deletions.
146 changes: 121 additions & 25 deletions frame/election-provider-multi-phase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ pub enum ElectionError<T: Config> {
DataProvider(&'static str),
/// An error nested in the fallback.
Fallback(FallbackErrorOf<T>),
/// No solution has been queued.
NothingQueued,
}

// NOTE: we have to do this manually because of the additional where clause needed on
Expand Down Expand Up @@ -900,7 +902,7 @@ pub mod pallet {
let ejected_a_solution = <QueuedSolution<T>>::exists();
<QueuedSolution<T>>::put(ready);
Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Unsigned,
compute: ElectionCompute::Unsigned,
prev_ejected: ejected_a_solution,
});

Expand Down Expand Up @@ -948,7 +950,7 @@ pub mod pallet {
};

Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Emergency,
compute: ElectionCompute::Emergency,
prev_ejected: QueuedSolution::<T>::exists(),
});

Expand Down Expand Up @@ -1024,7 +1026,7 @@ pub mod pallet {

signed_submissions.put();
Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Signed,
compute: ElectionCompute::Signed,
prev_ejected: ejected_a_solution,
});
Ok(())
Expand Down Expand Up @@ -1062,7 +1064,7 @@ pub mod pallet {
};

Self::deposit_event(Event::SolutionStored {
election_compute: ElectionCompute::Fallback,
compute: ElectionCompute::Fallback,
prev_ejected: QueuedSolution::<T>::exists(),
});

Expand All @@ -1080,10 +1082,13 @@ pub mod pallet {
/// 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.
SolutionStored { election_compute: ElectionCompute, prev_ejected: bool },
/// The election has been finalized, with `Some` of the given computation, or else if the
/// election failed, `None`.
ElectionFinalized { election_compute: Option<ElectionCompute> },
SolutionStored { compute: ElectionCompute, prev_ejected: bool },
/// The election has been finalized, with the given computation and score.
ElectionFinalized { compute: ElectionCompute, score: ElectionScore },
/// 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.
Rewarded { account: <T as frame_system::Config>::AccountId, value: BalanceOf<T> },
/// An account has been slashed for submitting an invalid signed submission.
Expand Down Expand Up @@ -1530,23 +1535,25 @@ impl<T: Config> Pallet<T> {
// inexpensive (1 read of an empty vector).
let _ = Self::finalize_signed_phase();
<QueuedSolution<T>>::take()
.map_or_else(
|| {
T::Fallback::elect()
.map_err(|fe| ElectionError::Fallback(fe))
.map(|supports| (supports, ElectionCompute::Fallback))
},
|ReadySolution { supports, compute, .. }| Ok((supports, compute)),
)
.map(|(supports, compute)| {
Self::deposit_event(Event::ElectionFinalized { election_compute: Some(compute) });
.ok_or(ElectionError::<T>::NothingQueued)
.or_else(|_| {
T::Fallback::elect()
.map(|supports| ReadySolution {
supports,
score: Default::default(),
compute: ElectionCompute::Fallback,
})
.map_err(|fe| ElectionError::Fallback(fe))
})
.map(|ReadySolution { compute, score, supports }| {
Self::deposit_event(Event::ElectionFinalized { compute, score });
if Self::round() != 1 {
log!(info, "Finalized election round with compute {:?}.", compute);
}
supports
})
.map_err(|err| {
Self::deposit_event(Event::ElectionFinalized { election_compute: None });
Self::deposit_event(Event::ElectionFailed);
if Self::round() != 1 {
log!(warn, "Failed to finalize election round. reason {:?}", err);
}
Expand Down Expand Up @@ -1800,8 +1807,9 @@ mod tests {
use super::*;
use crate::{
mock::{
multi_phase_events, roll_to, AccountId, ExtBuilder, MockWeightInfo, MockedWeightInfo,
MultiPhase, Origin, Runtime, SignedMaxSubmissions, System, TargetIndex, Targets,
multi_phase_events, raw_solution, roll_to, AccountId, ExtBuilder, MockWeightInfo,
MockedWeightInfo, MultiPhase, Origin, Runtime, SignedMaxSubmissions, System,
TargetIndex, Targets,
},
Phase,
};
Expand Down Expand Up @@ -1967,7 +1975,10 @@ mod tests {
multi_phase_events(),
vec![
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.
Expand Down Expand Up @@ -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]
fn fallback_strategy_works() {
ExtBuilder::default().onchain_fallback(true).build_and_execute(|| {
Expand Down Expand Up @@ -2080,12 +2173,15 @@ mod tests {
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFinalized { election_compute: None },
Event::ElectionFailed,
Event::SolutionStored {
election_compute: ElectionCompute::Fallback,
compute: ElectionCompute::Fallback,
prev_ejected: false
},
Event::ElectionFinalized { election_compute: Some(ElectionCompute::Fallback) }
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: Default::default()
}
]
);
})
Expand Down

0 comments on commit 68953cc

Please sign in to comment.