123456789101112131415161718192021222324252627282930313233use crate as collator_selection;34use crate::{mock::*, CandidateInfo, Error};35use frame_support::{36 assert_noop, assert_ok,37 traits::{Currency, GenesisBuild, OnInitialize},38};39use pallet_balances::Error as BalancesError;40use sp_runtime::traits::BadOrigin;4142#[test]43fn basic_setup_works() {44 new_test_ext().execute_with(|| {45 assert_eq!(CollatorSelection::desired_candidates(), 2);46 assert_eq!(CollatorSelection::candidacy_bond(), 10);4748 assert!(CollatorSelection::candidates().is_empty());49 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);50 });51}5253#[test]54fn it_should_set_invulnerables() {55 new_test_ext().execute_with(|| {56 let new_set = vec![1, 2, 3, 4];57 assert_ok!(CollatorSelection::set_invulnerables(58 RuntimeOrigin::signed(RootAccount::get()),59 new_set.clone()60 ));61 assert_eq!(CollatorSelection::invulnerables(), new_set);6263 64 assert_noop!(65 CollatorSelection::set_invulnerables(RuntimeOrigin::signed(1), new_set.clone()),66 BadOrigin67 );6869 70 let invulnerables = vec![7];71 assert_noop!(72 CollatorSelection::set_invulnerables(73 RuntimeOrigin::signed(RootAccount::get()),74 invulnerables.clone()75 ),76 Error::<Test>::ValidatorNotRegistered77 );78 });79}8081#[test]82fn set_desired_candidates_works() {83 new_test_ext().execute_with(|| {84 85 assert_eq!(CollatorSelection::desired_candidates(), 2);8687 88 assert_ok!(CollatorSelection::set_desired_candidates(89 RuntimeOrigin::signed(RootAccount::get()),90 791 ));92 assert_eq!(CollatorSelection::desired_candidates(), 7);9394 95 assert_noop!(96 CollatorSelection::set_desired_candidates(RuntimeOrigin::signed(1), 8),97 BadOrigin98 );99 });100}101102#[test]103fn set_candidacy_bond() {104 new_test_ext().execute_with(|| {105 106 assert_eq!(CollatorSelection::candidacy_bond(), 10);107108 109 assert_ok!(CollatorSelection::set_candidacy_bond(110 RuntimeOrigin::signed(RootAccount::get()),111 7112 ));113 assert_eq!(CollatorSelection::candidacy_bond(), 7);114115 116 assert_noop!(CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8), BadOrigin);117 });118}119120#[test]121fn cannot_register_candidate_if_too_many() {122 new_test_ext().execute_with(|| {123 124 <crate::DesiredCandidates<Test>>::put(0);125126 127 assert_noop!(128 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),129 Error::<Test>::TooManyCandidates,130 );131132 133 <crate::DesiredCandidates<Test>>::put(1);134 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));135136 137 assert_noop!(138 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),139 Error::<Test>::TooManyCandidates,140 );141 })142}143144#[test]145fn cannot_unregister_candidate_if_too_few() {146 new_test_ext().execute_with(|| {147 148 <crate::DesiredCandidates<Test>>::put(1);149 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));150151 152 assert_noop!(153 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),154 Error::<Test>::TooFewCandidates,155 );156 })157}158159#[test]160fn cannot_register_as_candidate_if_invulnerable() {161 new_test_ext().execute_with(|| {162 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);163164 165 assert_noop!(166 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),167 Error::<Test>::AlreadyInvulnerable,168 );169 })170}171172#[test]173fn cannot_register_as_candidate_if_keys_not_registered() {174 new_test_ext().execute_with(|| {175 176 assert_noop!(177 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),178 Error::<Test>::ValidatorNotRegistered179 );180 })181}182183#[test]184fn cannot_register_dupe_candidate() {185 new_test_ext().execute_with(|| {186 187 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));188 let addition = CandidateInfo { who: 3, deposit: 10 };189 assert_eq!(CollatorSelection::candidates(), vec![addition]);190 assert_eq!(CollatorSelection::last_authored_block(3), 10);191 assert_eq!(Balances::free_balance(3), 90);192193 194 assert_noop!(195 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),196 Error::<Test>::AlreadyCandidate,197 );198 })199}200201#[test]202fn cannot_register_as_candidate_if_poor() {203 new_test_ext().execute_with(|| {204 assert_eq!(Balances::free_balance(&3), 100);205 assert_eq!(Balances::free_balance(&33), 0);206207 208 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));209210 211 assert_noop!(212 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),213 BalancesError::<Test>::InsufficientBalance,214 );215 });216}217218#[test]219fn register_as_candidate_works() {220 new_test_ext().execute_with(|| {221 222 assert_eq!(CollatorSelection::desired_candidates(), 2);223 assert_eq!(CollatorSelection::candidacy_bond(), 10);224 assert_eq!(CollatorSelection::candidates(), Vec::new());225 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);226227 228 assert_eq!(Balances::free_balance(&3), 100);229 assert_eq!(Balances::free_balance(&4), 100);230231 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));232 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));233234 assert_eq!(Balances::free_balance(&3), 90);235 assert_eq!(Balances::free_balance(&4), 90);236237 assert_eq!(CollatorSelection::candidates().len(), 2);238 });239}240241#[test]242fn leave_intent() {243 new_test_ext().execute_with(|| {244 245 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));246 assert_eq!(Balances::free_balance(3), 90);247248 249 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)));250 assert_eq!(Balances::free_balance(5), 90);251252 253 assert_noop!(254 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),255 Error::<Test>::NotCandidate256 );257258 259 assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));260 assert_eq!(Balances::free_balance(3), 100);261 assert_eq!(CollatorSelection::last_authored_block(3), 0);262 });263}264265#[test]266fn authorship_event_handler() {267 new_test_ext().execute_with(|| {268 269 Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);270271 272 assert_eq!(Balances::free_balance(4), 100);273 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));274 275 Authorship::on_initialize(1);276277 let collator = CandidateInfo { who: 4, deposit: 10 };278279 assert_eq!(CollatorSelection::candidates(), vec![collator]);280 assert_eq!(CollatorSelection::last_authored_block(4), 0);281282 283 assert_eq!(Balances::free_balance(4), 140);284 285 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);286 });287}288289#[test]290fn fees_edgecases() {291 new_test_ext().execute_with(|| {292 293 Authorship::on_initialize(1);294 295 Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);296 297 assert_eq!(Balances::free_balance(4), 100);298 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));299 300 Authorship::on_initialize(1);301302 let collator = CandidateInfo { who: 4, deposit: 10 };303304 assert_eq!(CollatorSelection::candidates(), vec![collator]);305 assert_eq!(CollatorSelection::last_authored_block(4), 0);306 307 assert_eq!(Balances::free_balance(4), 90);308 309 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);310 });311}312313#[test]314fn session_management_works() {315 new_test_ext().execute_with(|| {316 initialize_to_block(1);317318 assert_eq!(SessionChangeBlock::get(), 0);319 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);320321 initialize_to_block(4);322323 assert_eq!(SessionChangeBlock::get(), 0);324 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);325326 327 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));328329 330 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);331 332 assert_eq!(CollatorSelection::candidates().len(), 1);333334 initialize_to_block(10);335 assert_eq!(SessionChangeBlock::get(), 10);336 337 assert_eq!(Session::validators(), vec![1, 2]);338 339 assert_eq!(Session::queued_keys().len(), 3);340 341 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);342343 initialize_to_block(20);344 assert_eq!(SessionChangeBlock::get(), 20);345 346 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);347 });348}349350#[test]351fn kick_mechanism() {352 new_test_ext().execute_with(|| {353 354 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));355 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(4)));356 initialize_to_block(10);357 assert_eq!(CollatorSelection::candidates().len(), 2);358 initialize_to_block(20);359 assert_eq!(SessionChangeBlock::get(), 20);360 361 assert_eq!(CollatorSelection::candidates().len(), 1);362 363 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);364 let collator = CandidateInfo { who: 4, deposit: 10 };365 assert_eq!(CollatorSelection::candidates(), vec![collator]);366 assert_eq!(CollatorSelection::last_authored_block(4), 20);367 initialize_to_block(30);368 369 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);370 371 assert_eq!(Balances::free_balance(3), 100);372 });373}374375#[test]376fn should_not_kick_mechanism_too_few() {377 new_test_ext().execute_with(|| {378 379 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)));380 assert_ok!(CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)));381 initialize_to_block(10);382 assert_eq!(CollatorSelection::candidates().len(), 2);383 initialize_to_block(20);384 assert_eq!(SessionChangeBlock::get(), 20);385 386 assert_eq!(CollatorSelection::candidates().len(), 1);387 388 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);389 let collator = CandidateInfo { who: 5, deposit: 10 };390 assert_eq!(CollatorSelection::candidates(), vec![collator]);391 assert_eq!(CollatorSelection::last_authored_block(4), 20);392 initialize_to_block(30);393 394 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);395 396 assert_eq!(Balances::free_balance(3), 100);397 });398}399400#[test]401#[should_panic = "duplicate invulnerables in genesis."]402fn cannot_set_genesis_value_twice() {403 sp_tracing::try_init_simple();404 let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();405 let invulnerables = vec![1, 1];406407 let collator_selection = collator_selection::GenesisConfig::<Test> {408 desired_candidates: 2,409 candidacy_bond: 10,410 invulnerables,411 };412 413 collator_selection.assimilate_storage(&mut t).unwrap();414}