pub(crate) fn horrible_npos_solution(
	do_reduce: bool,
) -> (CompactAssignments, Vec<ValidatorIndex>, ElectionScore) {
	let mut backing_stake_of: BTreeMap<AccountId, Balance> = BTreeMap::new();

	// self stake
	<Validators<Test>>::iter().for_each(|(who, _p)| {
		*backing_stake_of.entry(who).or_insert(Zero::zero()) += Staking::slashable_balance_of(&who)
	});

	// add nominator stuff
	<Nominators<Test>>::iter().for_each(|(who, nomination)| {
		nomination.targets.iter().for_each(|v| {
			*backing_stake_of.entry(*v).or_insert(Zero::zero()) +=
				Staking::slashable_balance_of(&who)
		})
	});

	// elect winners
	let mut sorted: Vec<AccountId> = backing_stake_of.keys().cloned().collect();
	sorted.sort_by_key(|x| backing_stake_of.get(x).unwrap());
	let winners: Vec<AccountId> = sorted
		.iter()
		.cloned()
		.take(Staking::validator_count() as usize)
		.collect();

	// create assignments
	let mut staked_assignment: Vec<StakedAssignment<AccountId>> = Vec::new();
	<Nominators<Test>>::iter().for_each(|(who, nomination)| {
		let mut dist: Vec<(AccountId, ExtendedBalance)> = Vec::new();
		nomination.targets.iter().for_each(|v| {
			if winners.iter().find(|w| *w == v).is_some() {
				dist.push((*v, ExtendedBalance::zero()));
			}
		});

		if dist.len() == 0 {
			return;
		}

		// assign real stakes. just split the stake.
		let stake = Staking::slashable_balance_of(&who) as ExtendedBalance;
		let mut sum: ExtendedBalance = Zero::zero();
		let dist_len = dist.len();
		{
			dist.iter_mut().for_each(|(_, w)| {
				let partial = stake / (dist_len as ExtendedBalance);
				*w = partial;
				sum += partial;
			});
		}

		// assign the leftover to last.
		{
			let leftover = stake - sum;
			let last = dist.last_mut().unwrap();
			last.1 += leftover;
		}

		staked_assignment.push(StakedAssignment {
			who,
			distribution: dist,
		});
	});

	// Ensure that this result is worse than seq-phragmen. Otherwise, it should not have been used
	// for testing.
	let score = {
		let (_, _, better_score) = prepare_submission_with(true, true, 0, |_| {});

		let support = build_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
		let score = evaluate_support(&support);

		assert!(sp_npos_elections::is_score_better::<Perbill>(
			better_score,
			score,
			MinSolutionScoreBump::get(),
		));

		score
	};

	if do_reduce {
		reduce(&mut staked_assignment);
	}

	let snapshot_validators = Staking::snapshot_validators().unwrap();
	let snapshot_nominators = Staking::snapshot_nominators().unwrap();
	let nominator_index = |a: &AccountId| -> Option<NominatorIndex> {
		snapshot_nominators.iter().position(|x| x == a).map(|i| i as NominatorIndex)
	};
	let validator_index = |a: &AccountId| -> Option<ValidatorIndex> {
		snapshot_validators.iter().position(|x| x == a).map(|i| i as ValidatorIndex)
	};

	// convert back to ratio assignment. This takes less space.
	let assignments_reduced =
		sp_npos_elections::assignment_staked_to_ratio::<AccountId, OffchainAccuracy>(staked_assignment);

	let compact =
		CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index)
			.unwrap();

	// winner ids to index
	let winners = winners.into_iter().map(|w| validator_index(&w).unwrap()).collect::<Vec<_>>();

	(compact, winners, score)
}
// winners will be chosen by simply their unweighted total backing stake. Nominator stake is
// distributed evenly.
winners will be chosen by simply their unweighted total backing stake. Nominator stake is
distributed evenly.
winners will be chosen by simply their unweighted total backing stake . Nominator stake is distributed evenly .
pub(crate) fn horrible_npos_solution(
	do_reduce: bool,
) -> (CompactAssignments, Vec<ValidatorIndex>, ElectionScore) {
	let mut backing_stake_of: BTreeMap<AccountId, Balance> = BTreeMap::new();
	// self stake
	<Validators<Test>>::iter().for_each(|(who, _p)| {
		*backing_stake_of.entry(who).or_insert(Zero::zero()) += Staking::slashable_balance_of(&who)
	});
	// add nominator stuff
	<Nominators<Test>>::iter().for_each(|(who, nomination)| {
		nomination.targets.iter().for_each(|v| {
			*backing_stake_of.entry(*v).or_insert(Zero::zero()) +=
				Staking::slashable_balance_of(&who)
		})
	});
	// elect winners
	let mut sorted: Vec<AccountId> = backing_stake_of.keys().cloned().collect();
	sorted.sort_by_key(|x| backing_stake_of.get(x).unwrap());
	let winners: Vec<AccountId> = sorted
		.iter()
		.cloned()
		.take(Staking::validator_count() as usize)
		.collect();
	// create assignments
	let mut staked_assignment: Vec<StakedAssignment<AccountId>> = Vec::new();
	<Nominators<Test>>::iter().for_each(|(who, nomination)| {
		let mut dist: Vec<(AccountId, ExtendedBalance)> = Vec::new();
		nomination.targets.iter().for_each(|v| {
			if winners.iter().find(|w| *w == v).is_some() {
				dist.push((*v, ExtendedBalance::zero()));
			}
		});
		if dist.len() == 0 {
			return;
		}
		// assign real stakes. just split the stake.
		let stake = Staking::slashable_balance_of(&who) as ExtendedBalance;
		let mut sum: ExtendedBalance = Zero::zero();
		let dist_len = dist.len();
		{
			dist.iter_mut().for_each(|(_, w)| {
				let partial = stake / (dist_len as ExtendedBalance);
				*w = partial;
				sum += partial;
			});
		}
		// assign the leftover to last.
		{
			let leftover = stake - sum;
			let last = dist.last_mut().unwrap();
			last.1 += leftover;
		}
		staked_assignment.push(StakedAssignment {
			who,
			distribution: dist,
		});
	});
	// Ensure that this result is worse than seq-phragmen. Otherwise, it should not have been used
	// for testing.
	let score = {
		let (_, _, better_score) = prepare_submission_with(true, true, 0, |_| {});
		let support = build_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
		let score = evaluate_support(&support);
		assert!(sp_npos_elections::is_score_better::<Perbill>(
			better_score,
			score,
			MinSolutionScoreBump::get(),
		));
		score
	};
	if do_reduce {
		reduce(&mut staked_assignment);
	}
	let snapshot_validators = Staking::snapshot_validators().unwrap();
	let snapshot_nominators = Staking::snapshot_nominators().unwrap();
	let nominator_index = |a: &AccountId| -> Option<NominatorIndex> {
		snapshot_nominators.iter().position(|x| x == a).map(|i| i as NominatorIndex)
	};
	let validator_index = |a: &AccountId| -> Option<ValidatorIndex> {
		snapshot_validators.iter().position(|x| x == a).map(|i| i as ValidatorIndex)
	};
	// convert back to ratio assignment. This takes less space.
	let assignments_reduced =
		sp_npos_elections::assignment_staked_to_ratio::<AccountId, OffchainAccuracy>(staked_assignment);
	let compact =
		CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index)
			.unwrap();
	// winner ids to index
	let winners = winners.into_iter().map(|w| validator_index(&w).unwrap()).collect::<Vec<_>>();
	(compact, winners, score)
}
pub ( crate ) fn horrible_npos_solution ( do_reduce : bool , ) -> ( CompactAssignments , Vec < ValidatorIndex > , ElectionScore ) { let mut backing_stake_of : BTreeMap < AccountId , Balance > = BTreeMap :: new ( ) ; // self stake < Validators < Test > > :: iter ( ) . for_each ( | ( who , _p ) | { * backing_stake_of . entry ( who ) . or_insert ( Zero :: zero ( ) ) += Staking :: slashable_balance_of ( & who ) } ) ; // add nominator stuff < Nominators < Test > > :: iter ( ) . for_each ( | ( who , nomination ) | { nomination . targets . iter ( ) . for_each ( | v | { * backing_stake_of . entry ( * v ) . or_insert ( Zero :: zero ( ) ) += Staking :: slashable_balance_of ( & who ) } ) } ) ; // elect winners let mut sorted : Vec < AccountId > = backing_stake_of . keys ( ) . cloned ( ) . collect ( ) ; sorted . sort_by_key ( | x | backing_stake_of . get ( x ) . unwrap ( ) ) ; let winners : Vec < AccountId > = sorted . iter ( ) . cloned ( ) . take ( Staking :: validator_count ( ) as usize ) . collect ( ) ; // create assignments let mut staked_assignment : Vec < StakedAssignment < AccountId > > = Vec :: new ( ) ; < Nominators < Test > > :: iter ( ) . for_each ( | ( who , nomination ) | { let mut dist : Vec < ( AccountId , ExtendedBalance ) > = Vec :: new ( ) ; nomination . targets . iter ( ) . for_each ( | v | { if winners . iter ( ) . find ( | w | * w == v ) . is_some ( ) { dist . push ( ( * v , ExtendedBalance :: zero ( ) ) ) ; } } ) ; if dist . len ( ) == 0 { return ; } // assign real stakes. just split the stake. let stake = Staking :: slashable_balance_of ( & who ) as ExtendedBalance ; let mut sum : ExtendedBalance = Zero :: zero ( ) ; let dist_len = dist . len ( ) ; { dist . iter_mut ( ) . for_each ( | ( _ , w ) | { let partial = stake / ( dist_len as ExtendedBalance ) ; * w = partial ; sum += partial ; } ) ; } // assign the leftover to last. { let leftover = stake - sum ; let last = dist . last_mut ( ) . unwrap ( ) ; last . 1 += leftover ; } staked_assignment . push ( StakedAssignment { who , distribution : dist , } ) ; } ) ; // Ensure that this result is worse than seq-phragmen. Otherwise, it should not have been used // for testing. let score = { let ( _ , _ , better_score ) = prepare_submission_with ( true , true , 0 , | _ | { } ) ; let support = build_support_map :: < AccountId > ( & winners , & staked_assignment ) . unwrap ( ) ; let score = evaluate_support ( & support ) ; assert ! ( sp_npos_elections is_score_better Perbill ( better_score score MinSolutionScoreBump get ( ) ) ) ; score } ; if do_reduce { reduce ( & mut staked_assignment ) ; } let snapshot_validators = Staking :: snapshot_validators ( ) . unwrap ( ) ; let snapshot_nominators = Staking :: snapshot_nominators ( ) . unwrap ( ) ; let nominator_index = | a : & AccountId | -> Option < NominatorIndex > { snapshot_nominators . iter ( ) . position ( | x | x == a ) . map ( | i | i as NominatorIndex ) } ; let validator_index = | a : & AccountId | -> Option < ValidatorIndex > { snapshot_validators . iter ( ) . position ( | x | x == a ) . map ( | i | i as ValidatorIndex ) } ; // convert back to ratio assignment. This takes less space. let assignments_reduced = sp_npos_elections :: assignment_staked_to_ratio :: < AccountId , OffchainAccuracy > ( staked_assignment ) ; let compact = CompactAssignments :: from_assignment ( assignments_reduced , nominator_index , validator_index ) . unwrap ( ) ; // winner ids to index let winners = winners . into_iter ( ) . map ( | w | validator_index ( & w ) . unwrap ( ) ) . collect :: < Vec < _ > > ( ) ; ( compact , winners , score ) }
winners will be chosen by simply their unweighted total backing stake.
winners will be chosen by simply their unweighted total backing stake .
do_reduce
bool
do_reduce
bool