Skip to content
tests.rs 62.4 KiB
Newer Older
		System::set_block_number(block);
		Timestamp::set_timestamp(block*5);	// a little late.
		Session::check_rotate_session(System::block_number());
		assert_eq!(Staking::current_era(), 0);
		assert_eq!(Session::current_index(), 2);

		assert_eq!(Staking::current_session_reward(), session_reward);
		assert_eq!(Staking::current_era_reward(), 2*session_reward);

		block = 9; // Block 9 => Session 3 => Era 1
		System::set_block_number(block);
		Timestamp::set_timestamp(block*5);
		Session::check_rotate_session(System::block_number());
		assert_eq!(Staking::current_era(), 1);
		assert_eq!(Session::current_index(), 3);

		// whats left to be shared is the sum of 3 rounds minus the validator's cut.
		let shared_cut = 3 * session_reward - validator_cut;
		// Validator's payee is Staked account, 11, reward will be paid here.
		assert_eq!(Balances::total_balance(&11), validator_initial_balance + shared_cut/2 + validator_cut);
		// Controller account will not get any reward.
		assert_eq!(Balances::total_balance(&10), 1);
		// Rest of the reward will be shared and paid to the nominator in stake.
		assert_eq!(Balances::total_balance(&2), 20 + shared_cut/2);
	});

}
#[test]
fn bond_extra_works() {
	// Tests that extra `free_balance` in the stash can be added to stake
	// NOTE: this tests only verifies `StakingLedger` for correct updates. 
	// See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`.
	with_externalities(&mut ExtBuilder::default().build(),
	|| {
		// Check that account 10 is a validator
		assert!(<Validators<Test>>::exists(10));
		// Check that account 10 is bonded to account 11
		assert_eq!(Staking::bonded(&11), Some(10));
		// Check how much is at stake
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));

		// Give account 11 some large free balance greater than total
		Balances::set_free_balance(&11, 1000000);
		// Check the balance of the stash account
		assert_eq!(Balances::free_balance(&11), 1000000);

		// Call the bond_extra function from controller, add only 100
		assert_ok!(Staking::bond_extra(Origin::signed(10), 100));
		// There should be 100 more `total` and `active` in the ledger
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));

		// Call the bond_extra function with a large number, should handle it
		assert_ok!(Staking::bond_extra(Origin::signed(10), u64::max_value()));
		// The full amount of the funds should now be in the total and active
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000000, active: 1000000, unlocking: vec![] }));

	});
}

#[test]
fn bond_extra_and_withdraw_unbonded_works() {
	// * Should test
	// * Given an account being bonded [and chosen as a validator](not mandatory)
	// * It can add extra funds to the bonded account.
	// * it can unbond a portion of its funds from the stash account.
	// * Once the unbonding period is done, it can actually take the funds out of the stash.
	with_externalities(&mut ExtBuilder::default()
		.reward(10) // it is the default, just for verbosity
		.nominate(false)
		.build(), 
	|| {
		// Set payee to controller. avoids confusion
		assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
		// Set unbonding era (bonding_duration) to 2
		assert_ok!(Staking::set_bonding_duration(2));
		// Give account 11 some large free balance greater than total
		Balances::set_free_balance(&11, 1000000);
		// Check the balance of the stash account
		assert_eq!(Balances::free_balance(&11), 1000000);
		// Initial config should be correct
		assert_eq!(Staking::sessions_per_era(), 1);
		assert_eq!(Staking::current_era(), 0);
		assert_eq!(Session::current_index(), 0);

		assert_eq!(Staking::current_session_reward(), 10);

		// check the balance of a validator accounts.
		assert_eq!(Balances::total_balance(&10), 1);

		// confirm that 10 is a normal validator and gets paid at the end of the era.
		System::set_block_number(1);
		Timestamp::set_timestamp(5);
		Session::check_rotate_session(System::block_number()); 
		assert_eq!(Staking::current_era(), 1);
		assert_eq!(Session::current_index(), 1);

		// NOTE: despite having .nominate() in extBuilder, 20 doesn't have a share since
		// rewards are paid before election in new_era()
		assert_eq!(Balances::total_balance(&10), 1 + 10);

		// Initial state of 10
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));
		assert_eq!(Staking::stakers(&10), Exposure { total: 1000, own: 1000, others: vec![] });


		// deposit the extra 100 units 
		Staking::bond_extra(Origin::signed(10), 100).unwrap();

		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));
		// Exposure is a snapshot! only updated after the next era update.
		assert_ne!(Staking::stakers(&10), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });

		// trigger next era.
		System::set_block_number(2);Timestamp::set_timestamp(10);Session::check_rotate_session(System::block_number()); 
		assert_eq!(Staking::current_era(), 2);
		assert_eq!(Session::current_index(), 2);

		// ledger should be the same.
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));
		// Exposure is now updated.
		assert_eq!(Staking::stakers(&10), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });
		// Note that by this point 10 also have received more rewards, but we don't care now.
		// assert_eq!(Balances::total_balance(&10), 1 + 10 + MORE_REWARD);

		// Unbond almost all of the funds in stash.
		Staking::unbond(Origin::signed(10), 1000).unwrap();
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { 
			stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] }));

		// Attempting to free the balances now will fail. 2 eras need to pass.
		Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { 
			stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] }));

		// trigger next era.
		System::set_block_number(3);Timestamp::set_timestamp(15);Session::check_rotate_session(System::block_number()); 
		assert_eq!(Staking::current_era(), 3);
		assert_eq!(Session::current_index(), 3);

		// nothing yet
		Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { 
			stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] }));

		// trigger next era.
		System::set_block_number(4);Timestamp::set_timestamp(20);Session::check_rotate_session(System::block_number()); 
		assert_eq!(Staking::current_era(), 4);
		assert_eq!(Session::current_index(), 4);
		
		Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
		// Now the value is free and the staking ledger is updated.
		assert_eq!(Staking::ledger(&10), Some(StakingLedger { 
			stash: 11, total: 100, active: 100, unlocking: vec![] }));
	})
}

#[test]
fn slot_stake_is_least_staked_validator_and_limits_maximum_punishment() {
	// Test that slot_stake is determined by the least staked validator
	// Test that slot_stake is the maximum punishment that can happen to a validator
	// Note that rewardDestination is the stash account by default
	// Note that unlike reward slash will affect free_balance, not the stash account.
	with_externalities(&mut ExtBuilder::default().nominate(false).build(), || {
		// Confirm validator count is 2
		assert_eq!(Staking::validator_count(), 2);
		// Confirm account 10 and 20 are validators
		assert!(<Validators<Test>>::exists(&10) && <Validators<Test>>::exists(&20));
		// Confirm 10 has less stake than 20
		assert!(Staking::stakers(&10).total < Staking::stakers(&20).total);
		assert_eq!(Staking::stakers(&10).total, 1000);
		assert_eq!(Staking::stakers(&20).total, 2000);

		// Give the man some money.
		Balances::set_free_balance(&10, 1000);
		Balances::set_free_balance(&20, 1000);

		// Confirm initial free balance.
		assert_eq!(Balances::free_balance(&10), 1000);
		assert_eq!(Balances::free_balance(&20), 1000);

		// We confirm initialized slot_stake is this value
		assert_eq!(Staking::slot_stake(), Staking::stakers(&10).total);
		
		// Now lets lower account 20 stake
		<Stakers<Test>>::insert(&20, Exposure { total: 69, own: 69, others: vec![] });
		assert_eq!(Staking::stakers(&20).total, 69);
		<Ledger<Test>>::insert(&20, StakingLedger { stash: 22, total: 69, active: 69, unlocking: vec![] });

		// New era --> rewards are paid --> stakes are changed
		System::set_block_number(1);
		Timestamp::set_timestamp(5);
		Session::check_rotate_session(System::block_number());

		assert_eq!(Staking::current_era(), 1);
		// -- new balances + reward
		assert_eq!(Staking::stakers(&10).total, 1000 + 10);
		assert_eq!(Staking::stakers(&20).total, 69 + 10);

		// -- Note that rewards are going directly to stash, not as free balance.
		assert_eq!(Balances::free_balance(&10), 1000);
		assert_eq!(Balances::free_balance(&20), 1000);

		// -- slot stake should also be updated.
		assert_eq!(Staking::slot_stake(), 79);

		// // If 10 gets slashed now, despite having +1000 in stash, it will be slashed byt 79, which is the slot stake
		Staking::on_offline_validator(10, 4);
		// // Confirm user has been reported
		assert_eq!(Staking::slash_count(&10), 4);
		// // check the balance of 10 (slash will be deducted from free balance.)
		assert_eq!(Balances::free_balance(&10), 1000 - 79);
		

#[test]
fn on_free_balance_zero_stash_removes_validator() {
	// Tests that validator storage items are cleaned up when stash is empty
	// Tests that storage items are untouched when controller is empty
	with_externalities(&mut ExtBuilder::default()
		.existential_deposit(10)
		.build(),
	|| {
		// Check that account 10 is a validator
		assert!(<Validators<Test>>::exists(10));
		// Check the balance of the validator account
		assert_eq!(Balances::free_balance(&10), 256);
		// Check the balance of the stash account
		assert_eq!(Balances::free_balance(&11), 256000);
		// Check these two accounts are bonded
		assert_eq!(Staking::bonded(&11), Some(10));

		// Set some storage items which we expect to be cleaned up
		// Initiate slash count storage item
		Staking::on_offline_validator(10, 1);
		// Set payee information
		assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash));

		// Check storage items that should be cleaned up
		assert!(<Ledger<Test>>::exists(&10));
		assert!(<Validators<Test>>::exists(&10));
		assert!(<SlashCount<Test>>::exists(&10));
		assert!(<Payee<Test>>::exists(&10));

		// Reduce free_balance of controller to 0
		Balances::set_free_balance(&10, 0);
		// Check total balance of account 10
		assert_eq!(Balances::total_balance(&10), 0);

		// Check the balance of the stash account has not been touched
		assert_eq!(Balances::free_balance(&11), 256000);
		// Check these two accounts are still bonded
		assert_eq!(Staking::bonded(&11), Some(10));

		// Check storage items have not changed
		assert!(<Ledger<Test>>::exists(&10));
		assert!(<Validators<Test>>::exists(&10));
		assert!(<SlashCount<Test>>::exists(&10));
		assert!(<Payee<Test>>::exists(&10));

		// Reduce free_balance of stash to 0
		Balances::set_free_balance(&11, 0);
		// Check total balance of stash
		assert_eq!(Balances::total_balance(&11), 0);

		// Check storage items do not exist
		assert!(!<Ledger<Test>>::exists(&10));
		assert!(!<Validators<Test>>::exists(&10));
		assert!(!<Nominators<Test>>::exists(&10));
		assert!(!<SlashCount<Test>>::exists(&10));
		assert!(!<Payee<Test>>::exists(&10));
		assert!(!<Bonded<Test>>::exists(&11));
	});
}

#[test]
fn on_free_balance_zero_stash_removes_nominator() {
	// Tests that nominator storage items are cleaned up when stash is empty
	// Tests that storage items are untouched when controller is empty
	with_externalities(&mut ExtBuilder::default()
		.existential_deposit(10)
		.build(),
	|| {
		// Make 10 a nominator
		assert_ok!(Staking::nominate(Origin::signed(10), vec![20]));
		// Check that account 10 is a nominator
		assert!(<Nominators<Test>>::exists(10));
		// Check the balance of the nominator account
		assert_eq!(Balances::free_balance(&10), 256);
		// Check the balance of the stash account
		assert_eq!(Balances::free_balance(&11), 256000);
		// Check these two accounts are bonded
		assert_eq!(Staking::bonded(&11), Some(10));

		// Set payee information
		assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash));


		// Check storage items that should be cleaned up
		assert!(<Ledger<Test>>::exists(&10));
		assert!(<Nominators<Test>>::exists(&10));
		assert!(<Payee<Test>>::exists(&10));

		// Reduce free_balance of controller to 0
		Balances::set_free_balance(&10, 0);
		// Check total balance of account 10
		assert_eq!(Balances::total_balance(&10), 0);

		// Check the balance of the stash account has not been touched
		assert_eq!(Balances::free_balance(&11), 256000);
		// Check these two accounts are still bonded
		assert_eq!(Staking::bonded(&11), Some(10));

		// Check storage items have not changed
		assert!(<Ledger<Test>>::exists(&10));
		assert!(<Nominators<Test>>::exists(&10));
		assert!(<Payee<Test>>::exists(&10));

		// Reduce free_balance of stash to 0
		Balances::set_free_balance(&11, 0);
		// Check total balance of stash
		assert_eq!(Balances::total_balance(&11), 0);

		// Check storage items do not exist
		assert!(!<Ledger<Test>>::exists(&10));
		assert!(!<Validators<Test>>::exists(&10));
		assert!(!<Nominators<Test>>::exists(&10));
		assert!(!<SlashCount<Test>>::exists(&10));
		assert!(!<Payee<Test>>::exists(&10));
		assert!(!<Bonded<Test>>::exists(&11));
	});
}

#[test]
fn phragmen_poc_works() {
	// Tests the POC test of the phragmen, mentioned in the paper and reference implementation.
	// Initial votes:
	// vote_list = [
	// 		("A", 10.0, ["X", "Y"]),
	// 		("B", 20.0, ["X", "Z"]),
	// 		("C", 30.0, ["Y", "Z"])
	// ]
	//
	// Sequential Phragmén gives
	// Z  is elected with stake  35.0 and score  0.02
	// Y  is elected with stake  25.0 and score  0.04
	//
	// A  has load  0.04 and supported 
	// X  with stake  0.0 Y  with stake  10.0 
	// B  has load  0.02 and supported 
	// X  with stake  0.0 Z  with stake  20.0 
	// C  has load  0.04 and supported 
	// Y  with stake  15.0 Z  with stake  15.0 
	// 
	// NOTE: doesn't X/Y/Z's stash value make a difference here in phragmen? 
	with_externalities(&mut ExtBuilder::default()
		.nominate(false)
		.build(),
	|| {
		// initial setup of 10 and 20, both validators.
		assert_eq!(Session::validators(), vec![20, 10]);

		assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));
		assert_eq!(Staking::ledger(&20), Some(StakingLedger { stash: 21, total: 2000, active: 2000, unlocking: vec![] }));

		assert_eq!(Staking::validators(10), ValidatorPrefs::default());
		assert_eq!(Staking::validators(20), ValidatorPrefs::default());

		assert_eq!(Balances::free_balance(10), 1);
		assert_eq!(Balances::free_balance(20), 1);
		
		// no one is a nominator
		assert_eq!(<Nominators<Test>>::enumerate().count(), 0 as usize);

		// Bond [30, 31] as the third validator
		assert_ok!(Staking::bond(Origin::signed(31), 30, 1000, RewardDestination::default()));
		assert_ok!(Staking::validate(Origin::signed(30), ValidatorPrefs::default()));

		// bond [2,1](A), [4,3](B), [6,5](C) as the 3 nominators
		// Give all of them some balance to be able to bond properly.
		for i in &[1, 3, 5] { Balances::set_free_balance(i, 50); }
		// Linking names to the above test:
		// 10 => X
		// 20 => Y
		// 30 => Z
		assert_ok!(Staking::bond(Origin::signed(1), 2, 10, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(2), vec![10, 20]));

		assert_ok!(Staking::bond(Origin::signed(3), 4, 20, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(4), vec![10, 30]));

		assert_ok!(Staking::bond(Origin::signed(5), 6, 30, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(6), vec![20, 30]));

		// New era => election algorithm will trigger
		System::set_block_number(1);
		Session::check_rotate_session(System::block_number());

		// Z and Y are chosen 
		assert_eq!(Session::validators(), vec![30, 20]);

		// with stake 35 and 25 respectively

		// This is only because 30 has been bonded on the fly, exposures are stored at the very end of the era. 
		// 35 is the point, not 'own' Exposure.
		assert_eq!(Staking::stakers(30).own, 0); 
		assert_eq!(Staking::stakers(30).total, 0 + 35);
		// same as above. +25 is the point
		assert_eq!(Staking::stakers(20).own, 2010);
		assert_eq!(Staking::stakers(20).total, 2010 + 25);  

		// 30(Z) was supported by B-4 and C-6 with stake 20 and 15 respectively.
		assert_eq!(Staking::stakers(30).others.iter().map(|e| e.value).collect::<Vec<BalanceOf<Test>>>(), vec![15, 20]);
		assert_eq!(Staking::stakers(30).others.iter().map(|e| e.who).collect::<Vec<BalanceOf<Test>>>(), vec![6, 4]);
		
		// 20(Y) was supported by A-2 and C-6 with stake 10 and 15 respectively.
		assert_eq!(Staking::stakers(20).others.iter().map(|e| e.value).collect::<Vec<BalanceOf<Test>>>(), vec![15, 10]);
		assert_eq!(Staking::stakers(20).others.iter().map(|e| e.who).collect::<Vec<BalanceOf<Test>>>(), vec![6, 2]);
	});
}

#[test]
fn phragmen_election_works() {
	// tests the encapsulated phragmen::elect function.
	with_externalities(&mut ExtBuilder::default().nominate(false).build(), || {
		// initial setup of 10 and 20, both validators
		assert_eq!(Session::validators(), vec![20, 10]);

		// no one is a nominator
		assert_eq!(<Nominators<Test>>::enumerate().count(), 0 as usize);

		// Bond [30, 31] as the third validator
		assert_ok!(Staking::bond(Origin::signed(31), 30, 1000, RewardDestination::default()));
		assert_ok!(Staking::validate(Origin::signed(30), ValidatorPrefs::default()));

		// bond [2,1](A), [4,3](B), as 2 nominators
		// Give all of them some balance to be able to bond properly.
		for i in &[1, 3] { Balances::set_free_balance(i, 50); }
		assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(2), vec![10, 20]));

		assert_ok!(Staking::bond(Origin::signed(3), 4, 45, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(4), vec![10, 30]));

		let rounds =     || 2 as usize;
		let validators = || <Validators<Test>>::enumerate();
		let nominators = || <Nominators<Test>>::enumerate();
		let stash_of =  |w| Staking::stash_balance(&w);
		let min_validator_count = Staking::minimum_validator_count() as usize;

		let winners = phragmen::elect::<Test, _, _, _, _>(
			rounds,
			validators,
			nominators,
			stash_of,
			min_validator_count
		);

		// 10 and 30 must be the winners
		assert_eq!(winners.iter().map(|w| w.who).collect::<Vec<BalanceOf<Test>>>(), vec![10, 30]);

		let winner_10 = winners.iter().filter(|w| w.who == 10).nth(0).unwrap();
		let winner_30 = winners.iter().filter(|w| w.who == 30).nth(0).unwrap();

		// python implementation output:
		/*
		10  is elected with stake  26.31578947368421 and score  0.02
		30  is elected with stake  23.684210526315788 and score  0.042222222222222223

		2  has load  0.02 and supported 
		10  with stake  5.0 20  with stake  0.0 
		4  has load  0.042222222222222223 and supported 
		10  with stake  21.31578947368421 30  with stake  23.684210526315788 
		*/

		assert_eq!(winner_10.exposure.total, 1000 + 26);
		assert_eq!(winner_10.score, Perquintill::from_fraction(0.02));
		assert_eq!(winner_10.exposure.others[0].value, 21);
		assert_eq!(winner_10.exposure.others[1].value, 5);

		assert_eq!(winner_30.exposure.total, 23);
		assert_eq!(winner_30.score, Perquintill::from_quintillionths(42222222222222222));
		assert_eq!(winner_30.exposure.others[0].value, 23);
	})
}

#[test]
fn switching_roles() {
	// Show: It should be possible to switch between roles (nominator, validator, idle) with minimal overhead.
	with_externalities(&mut ExtBuilder::default()
		.nominate(false)
		.sessions_per_era(3)
		.build(),
	|| {
		assert_eq!(Session::validators(), vec![20, 10]);

		// put some money in account that we'll use.
		for i in 1..7 { Balances::set_free_balance(&i, 5000); }

		// add 2 nominators
		assert_ok!(Staking::bond(Origin::signed(1), 2, 2000, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(2), vec![10, 6]));

		assert_ok!(Staking::bond(Origin::signed(3), 4, 500, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(4), vec![20, 2]));
		
		// add a new validator candidate
		assert_ok!(Staking::bond(Origin::signed(5), 6, 1500, RewardDestination::Controller));
		assert_ok!(Staking::validate(Origin::signed(6), ValidatorPrefs::default()));

		// new block 
		System::set_block_number(1);
		Session::check_rotate_session(System::block_number());

		// no change 
		assert_eq!(Session::validators(), vec![20, 10]);

		// new block 
		System::set_block_number(2);
		Session::check_rotate_session(System::block_number());

		// no change 
		assert_eq!(Session::validators(), vec![20, 10]);

		// new block --> ne era --> new validators
		System::set_block_number(3);
		Session::check_rotate_session(System::block_number());

		// with current nominators 10 and 4 have the most stake
		assert_eq!(Session::validators(), vec![6, 10]);

		// 2 decides to be a validator. Consequences: 
		// 6 will not be chosen in the next round (no votes)
		// 2 itself will be chosen + 20 who now has the higher votes
		// 10 wil have no votes.
		assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default()));

		System::set_block_number(4);
		Session::check_rotate_session(System::block_number());
		assert_eq!(Session::validators(), vec![6, 10]);

		System::set_block_number(5);
		Session::check_rotate_session(System::block_number());
		assert_eq!(Session::validators(), vec![6, 10]);

		// ne era 
		System::set_block_number(6);
		Session::check_rotate_session(System::block_number());
		assert_eq!(Session::validators(), vec![2, 20]);
	});
}

#[test]
fn wrong_vote_is_null() {
	with_externalities(&mut ExtBuilder::default()
		.session_length(1)
		.sessions_per_era(1)
		.nominate(false)
		.validator_pool(true)
	.build(),
	|| {
		// from the first era onward, only two will be chosen
		assert_eq!(Session::validators(), vec![40, 30, 20, 10]);

		// put some money in account that we'll use.
		for i in 1..3 { Balances::set_free_balance(&i, 5000); }

		// add 1 nominators
		assert_ok!(Staking::bond(Origin::signed(1), 2, 2000, RewardDestination::default()));
		assert_ok!(Staking::nominate(Origin::signed(2), vec![
			10, 20, 			// good votes 
			1, 2, 15, 1000, 25  // crap votes. No effect.
		]));

		// new block 
		System::set_block_number(1);
		Session::check_rotate_session(System::block_number());

		assert_eq!(Session::validators(), vec![20, 10]);
	});
}