clean the interface of supports map (#9674)

* clean the interface of supports map, make it a bit cleaner and more efficients

* Fix stiff

* fix one test

* Fix warnings
This commit is contained in:
Kian Paimani
2021-09-10 19:39:48 +01:00
committed by GitHub
parent b3092ead23
commit be69e4d2b2
14 changed files with 67 additions and 189 deletions
@@ -143,7 +143,7 @@ fn solution_with_size<T: Config>(
let solution =
<SolutionOf<T>>::from_assignment(&assignments, &voter_index, &target_index).unwrap();
let score = solution.clone().score(&winners, stake_of, voter_at, target_at).unwrap();
let score = solution.clone().score(stake_of, voter_at, target_at).unwrap();
let round = <MultiPhase<T>>::round();
assert!(score[0] > 0, "score is zero, this probably means that the stakes are not set.");
@@ -535,8 +535,6 @@ pub enum FeasibilityError {
InvalidVote,
/// A voter is invalid.
InvalidVoter,
/// A winner is invalid.
InvalidWinner,
/// The given score was invalid.
InvalidScore,
/// The provided round is incorrect.
@@ -1395,17 +1393,8 @@ impl<T: Config> Pallet<T> {
let target_at = helpers::target_at_fn::<T>(&snapshot_targets);
let voter_index = helpers::voter_index_fn_usize::<T>(&cache);
// First, make sure that all the winners are sane.
// OPTIMIZATION: we could first build the assignments, and then extract the winners directly
// from that, as that would eliminate a little bit of duplicate work. For now, we keep them
// separate: First extract winners separately from solution, and then assignments. This is
// also better, because we can reject solutions that don't meet `desired_targets` early on.
let winners = winners
.into_iter()
.map(|i| target_at(i).ok_or(FeasibilityError::InvalidWinner))
.collect::<Result<Vec<T::AccountId>, FeasibilityError>>()?;
// Then convert solution -> assignment. This will fail if any of the indices are gibberish.
// Then convert solution -> assignment. This will fail if any of the indices are gibberish,
// namely any of the voters or targets.
let assignments = solution
.into_assignment(voter_at, target_at)
.map_err::<FeasibilityError, _>(Into::into)?;
@@ -1441,14 +1430,10 @@ impl<T: Config> Pallet<T> {
// This might fail if the normalization fails. Very unlikely. See `integrity_test`.
let staked_assignments = assignment_ratio_to_staked_normalized(assignments, stake_of)
.map_err::<FeasibilityError, _>(Into::into)?;
// This might fail if one of the voter edges is pointing to a non-winner, which is not
// really possible anymore because all the winners come from the same `solution`.
let supports = sp_npos_elections::to_supports(&winners, &staked_assignments)
.map_err::<FeasibilityError, _>(Into::into)?;
let supports = sp_npos_elections::to_supports(&staked_assignments);
// Finally, check that the claimed score was indeed correct.
let known_score = (&supports).evaluate();
let known_score = supports.evaluate();
ensure!(known_score == score, FeasibilityError::InvalidScore);
Ok(ReadySolution { supports, compute, score })
@@ -1653,7 +1638,7 @@ mod feasibility_check {
});
assert_noop!(
MultiPhase::feasibility_check(raw, COMPUTE),
FeasibilityError::InvalidWinner
FeasibilityError::NposElection(sp_npos_elections::Error::SolutionInvalidIndex)
);
})
}
@@ -30,8 +30,8 @@ use sp_core::{
H256,
};
use sp_npos_elections::{
assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, to_without_backing,
ElectionResult, EvaluateSupport, ExtendedBalance, NposSolution,
assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, ElectionResult,
EvaluateSupport, ExtendedBalance, NposSolution,
};
use sp_runtime::{
testing::Header,
@@ -157,13 +157,14 @@ pub fn raw_solution() -> RawSolution<SolutionOf<Runtime>> {
let RoundSnapshot { voters, targets } = MultiPhase::snapshot().unwrap();
let desired_targets = MultiPhase::desired_targets().unwrap();
let ElectionResult { winners, assignments } = seq_phragmen::<_, SolutionAccuracyOf<Runtime>>(
desired_targets as usize,
targets.clone(),
voters.clone(),
None,
)
.unwrap();
let ElectionResult { winners: _, assignments } =
seq_phragmen::<_, SolutionAccuracyOf<Runtime>>(
desired_targets as usize,
targets.clone(),
voters.clone(),
None,
)
.unwrap();
// closures
let cache = helpers::generate_voter_cache::<Runtime>(&voters);
@@ -171,11 +172,9 @@ pub fn raw_solution() -> RawSolution<SolutionOf<Runtime>> {
let target_index = helpers::target_index_fn_linear::<Runtime>(&targets);
let stake_of = helpers::stake_of_fn::<Runtime>(&voters, &cache);
let winners = to_without_backing(winners);
let score = {
let staked = assignment_ratio_to_staked_normalized(assignments.clone(), &stake_of).unwrap();
to_supports(&winners, &staked).unwrap().evaluate()
to_supports(&staked).evaluate()
};
let solution =
<SolutionOf<Runtime>>::from_assignment(&assignments, &voter_index, &target_index).unwrap();
@@ -26,7 +26,6 @@ use codec::{Decode, Encode, HasCompact};
use frame_support::{
storage::bounded_btree_map::BoundedBTreeMap,
traits::{Currency, Get, OnUnbalanced, ReservableCurrency},
DebugNoBound,
};
use sp_arithmetic::traits::SaturatedConversion;
use sp_npos_elections::{is_score_better, ElectionScore, NposSolution};
@@ -113,7 +112,7 @@ pub enum InsertResult<T: Config> {
/// Mask type which pretends to be a set of `SignedSubmissionOf<T>`, while in fact delegating to the
/// actual implementations in `SignedSubmissionIndices<T>`, `SignedSubmissionsMap<T>`, and
/// `SignedSubmissionNextIndex<T>`.
#[cfg_attr(feature = "std", derive(DebugNoBound))]
#[cfg_attr(feature = "std", derive(frame_support::DebugNoBound))]
pub struct SignedSubmissions<T: Config> {
indices: SubmissionIndicesOf<T>,
next_idx: u32,
@@ -315,7 +315,7 @@ impl<T: Config> Pallet<T> {
SolutionOf::<T>::try_from(assignments).map(|s| s.encoded_size())
};
let ElectionResult { assignments, winners } = election_result;
let ElectionResult { assignments, winners: _ } = election_result;
// Reduce (requires round-trip to staked form)
let sorted_assignments = {
@@ -374,8 +374,7 @@ impl<T: Config> Pallet<T> {
let solution = SolutionOf::<T>::try_from(&index_assignments)?;
// re-calc score.
let winners = sp_npos_elections::to_without_backing(winners);
let score = solution.clone().score(&winners, stake_of, voter_at, target_at)?;
let score = solution.clone().score(stake_of, voter_at, target_at)?;
let round = Self::round();
Ok((RawSolution { solution, score, round }, size))