Skip to content

Commit 0893fcc

Browse files
kianenigmabkchr
andauthored
Properly filter out duplicate voters in elections. (#6693)
* Prevent duplicate voter * Update primitives/npos-elections/src/lib.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
1 parent d0ded53 commit 0893fcc

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

src/tests.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,101 @@ fn bond_with_little_staked_value_bounded() {
17151715
});
17161716
}
17171717

1718+
#[test]
1719+
fn bond_with_duplicate_vote_should_be_ignored_by_npos_election() {
1720+
ExtBuilder::default()
1721+
.validator_count(2)
1722+
.nominate(false)
1723+
.minimum_validator_count(1)
1724+
.build()
1725+
.execute_with(|| {
1726+
// disable the nominator
1727+
assert_ok!(Staking::chill(Origin::signed(100)));
1728+
// make stakes equal.
1729+
assert_ok!(Staking::bond_extra(Origin::signed(31), 999));
1730+
1731+
assert_eq!(
1732+
<Validators<Test>>::iter()
1733+
.map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().total))
1734+
.collect::<Vec<_>>(),
1735+
vec![(31, 1000), (21, 1000), (11, 1000)],
1736+
);
1737+
assert_eq!(<Nominators<Test>>::iter().map(|(n, _)| n).collect::<Vec<_>>(), vec![]);
1738+
1739+
// give the man some money
1740+
let initial_balance = 1000;
1741+
for i in [1, 2, 3, 4,].iter() {
1742+
let _ = Balances::make_free_balance_be(i, initial_balance);
1743+
}
1744+
1745+
assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller));
1746+
assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 11, 11, 21, 31,]));
1747+
1748+
assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller));
1749+
assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31]));
1750+
1751+
// winners should be 21 and 31. Otherwise this election is taking duplicates into account.
1752+
1753+
let sp_npos_elections::ElectionResult {
1754+
winners,
1755+
assignments,
1756+
} = Staking::do_phragmen::<Perbill>().unwrap();
1757+
let winners = sp_npos_elections::to_without_backing(winners);
1758+
1759+
assert_eq!(winners, vec![31, 21]);
1760+
// only distribution to 21 and 31.
1761+
assert_eq!(assignments.iter().find(|a| a.who == 1).unwrap().distribution.len(), 2);
1762+
});
1763+
}
1764+
1765+
#[test]
1766+
fn bond_with_duplicate_vote_should_be_ignored_by_npos_election_elected() {
1767+
// same as above but ensures that even when the duple is being elected, everything is sane.
1768+
ExtBuilder::default()
1769+
.validator_count(2)
1770+
.nominate(false)
1771+
.minimum_validator_count(1)
1772+
.build()
1773+
.execute_with(|| {
1774+
// disable the nominator
1775+
assert_ok!(Staking::chill(Origin::signed(100)));
1776+
// make stakes equal.
1777+
assert_ok!(Staking::bond_extra(Origin::signed(31), 99));
1778+
1779+
assert_eq!(
1780+
<Validators<Test>>::iter()
1781+
.map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().total))
1782+
.collect::<Vec<_>>(),
1783+
vec![(31, 100), (21, 1000), (11, 1000)],
1784+
);
1785+
assert_eq!(<Nominators<Test>>::iter().map(|(n, _)| n).collect::<Vec<_>>(), vec![]);
1786+
1787+
// give the man some money
1788+
let initial_balance = 1000;
1789+
for i in [1, 2, 3, 4,].iter() {
1790+
let _ = Balances::make_free_balance_be(i, initial_balance);
1791+
}
1792+
1793+
assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller));
1794+
assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 11, 11, 21, 31,]));
1795+
1796+
assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller));
1797+
assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31]));
1798+
1799+
// winners should be 21 and 31. Otherwise this election is taking duplicates into account.
1800+
1801+
let sp_npos_elections::ElectionResult {
1802+
winners,
1803+
assignments,
1804+
} = Staking::do_phragmen::<Perbill>().unwrap();
1805+
1806+
let winners = sp_npos_elections::to_without_backing(winners);
1807+
assert_eq!(winners, vec![21, 11]);
1808+
// only distribution to 21 and 31.
1809+
assert_eq!(assignments.iter().find(|a| a.who == 1).unwrap().distribution.len(), 2);
1810+
});
1811+
}
1812+
17181813
#[test]
17191814
fn new_era_elects_correct_number_of_validators() {
17201815
ExtBuilder::default()

0 commit comments

Comments
 (0)