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}52535455#[test]56fn it_should_add_invulnerables() {57 new_test_ext().execute_with(|| {58 assert_ok!(CollatorSelection::add_invulnerable(59 RuntimeOrigin::signed(RootAccount::get()),60 161 ));62 assert_ok!(CollatorSelection::add_invulnerable(63 RuntimeOrigin::signed(RootAccount::get()),64 265 ));66 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);6768 69 assert_noop!(70 CollatorSelection::add_invulnerable(RuntimeOrigin::signed(1), 3),71 BadOrigin72 );7374 75 assert_noop!(76 CollatorSelection::add_invulnerable(77 RuntimeOrigin::signed(RootAccount::get()),78 779 ),80 Error::<Test>::ValidatorNotRegistered81 );82 });83}8485#[test]86fn it_should_remove_invulnerables() {87 new_test_ext().execute_with(|| {88 assert_ok!(CollatorSelection::add_invulnerable(89 RuntimeOrigin::signed(RootAccount::get()),90 191 ));92 assert_ok!(CollatorSelection::add_invulnerable(93 RuntimeOrigin::signed(RootAccount::get()),94 295 ));9697 98 assert_noop!(99 CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),100 BadOrigin101 );102103 assert_ok!(CollatorSelection::remove_invulnerable(104 RuntimeOrigin::signed(RootAccount::get()),105 2106 ));107 assert_eq!(CollatorSelection::invulnerables(), vec![1]);108109 110 assert_noop!(111 CollatorSelection::add_invulnerable(112 RuntimeOrigin::signed(RootAccount::get()), 113 1114 ),115 Error::<Test>::NotInvulnerable116 );117 });118}119120#[test]121fn set_desired_candidates_works() {122 new_test_ext().execute_with(|| {123 124 assert_eq!(CollatorSelection::desired_candidates(), 2);125126 127 assert_ok!(CollatorSelection::set_desired_candidates(128 RuntimeOrigin::signed(RootAccount::get()),129 7130 ));131 assert_eq!(CollatorSelection::desired_candidates(), 7);132133 134 assert_noop!(135 CollatorSelection::set_desired_candidates(RuntimeOrigin::signed(1), 8),136 BadOrigin137 );138 });139}140141#[test]142fn set_candidacy_bond() {143 new_test_ext().execute_with(|| {144 145 assert_eq!(CollatorSelection::candidacy_bond(), 10);146147 148 assert_ok!(CollatorSelection::set_candidacy_bond(149 RuntimeOrigin::signed(RootAccount::get()),150 7151 ));152 assert_eq!(CollatorSelection::candidacy_bond(), 7);153154 155 assert_noop!(156 CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),157 BadOrigin158 );159 });160}161162#[test]163fn cannot_register_candidate_if_too_many() {164 new_test_ext().execute_with(|| {165 166 <crate::DesiredCandidates<Test>>::put(0);167168 169 assert_noop!(170 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),171 Error::<Test>::TooManyCandidates,172 );173174 175 <crate::DesiredCandidates<Test>>::put(1);176 assert_ok!(CollatorSelection::register_as_candidate(177 RuntimeOrigin::signed(4)178 ));179180 181 assert_noop!(182 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),183 Error::<Test>::TooManyCandidates,184 );185 })186}187188#[test]189fn cannot_unregister_candidate_if_too_few() {190 new_test_ext().execute_with(|| {191 192 <crate::DesiredCandidates<Test>>::put(1);193 assert_ok!(CollatorSelection::register_as_candidate(194 RuntimeOrigin::signed(4)195 ));196197 198 assert_noop!(199 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),200 Error::<Test>::TooFewCandidates,201 );202 })203}204205#[test]206fn cannot_register_as_candidate_if_invulnerable() {207 new_test_ext().execute_with(|| {208 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);209210 211 assert_noop!(212 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),213 Error::<Test>::AlreadyInvulnerable,214 );215 })216}217218#[test]219fn cannot_register_as_candidate_if_keys_not_registered() {220 new_test_ext().execute_with(|| {221 222 assert_noop!(223 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),224 Error::<Test>::ValidatorNotRegistered225 );226 })227}228229#[test]230fn cannot_register_dupe_candidate() {231 new_test_ext().execute_with(|| {232 233 assert_ok!(CollatorSelection::register_as_candidate(234 RuntimeOrigin::signed(3)235 ));236 let addition = CandidateInfo {237 who: 3,238 deposit: 10,239 };240 assert_eq!(CollatorSelection::candidates(), vec![addition]);241 assert_eq!(CollatorSelection::last_authored_block(3), 10);242 assert_eq!(Balances::free_balance(3), 90);243244 245 assert_noop!(246 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),247 Error::<Test>::AlreadyCandidate,248 );249 })250}251252#[test]253fn cannot_register_as_candidate_if_poor() {254 new_test_ext().execute_with(|| {255 assert_eq!(Balances::free_balance(&3), 100);256 assert_eq!(Balances::free_balance(&33), 0);257258 259 assert_ok!(CollatorSelection::register_as_candidate(260 RuntimeOrigin::signed(3)261 ));262263 264 assert_noop!(265 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),266 BalancesError::<Test>::InsufficientBalance,267 );268 });269}270271#[test]272fn register_as_candidate_works() {273 new_test_ext().execute_with(|| {274 275 assert_eq!(CollatorSelection::desired_candidates(), 2);276 assert_eq!(CollatorSelection::candidacy_bond(), 10);277 assert_eq!(CollatorSelection::candidates(), Vec::new());278 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);279280 281 assert_eq!(Balances::free_balance(&3), 100);282 assert_eq!(Balances::free_balance(&4), 100);283284 assert_ok!(CollatorSelection::register_as_candidate(285 RuntimeOrigin::signed(3)286 ));287 assert_ok!(CollatorSelection::register_as_candidate(288 RuntimeOrigin::signed(4)289 ));290291 assert_eq!(Balances::free_balance(&3), 90);292 assert_eq!(Balances::free_balance(&4), 90);293294 assert_eq!(CollatorSelection::candidates().len(), 2);295 });296}297298#[test]299fn leave_intent() {300 new_test_ext().execute_with(|| {301 302 assert_ok!(CollatorSelection::register_as_candidate(303 RuntimeOrigin::signed(3)304 ));305 assert_eq!(Balances::free_balance(3), 90);306307 308 assert_ok!(CollatorSelection::register_as_candidate(309 RuntimeOrigin::signed(5)310 ));311 assert_eq!(Balances::free_balance(5), 90);312313 314 assert_noop!(315 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),316 Error::<Test>::NotCandidate317 );318319 320 assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));321 assert_eq!(Balances::free_balance(3), 100);322 assert_eq!(CollatorSelection::last_authored_block(3), 0);323 });324}325326#[test]327fn authorship_event_handler() {328 new_test_ext().execute_with(|| {329 330 Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);331332 333 assert_eq!(Balances::free_balance(4), 100);334 assert_ok!(CollatorSelection::register_as_candidate(335 RuntimeOrigin::signed(4)336 ));337 338 Authorship::on_initialize(1);339340 let collator = CandidateInfo {341 who: 4,342 deposit: 10,343 };344345 assert_eq!(CollatorSelection::candidates(), vec![collator]);346 assert_eq!(CollatorSelection::last_authored_block(4), 0);347348 349 assert_eq!(Balances::free_balance(4), 140);350 351 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);352 });353}354355#[test]356fn fees_edgecases() {357 new_test_ext().execute_with(|| {358 359 Authorship::on_initialize(1);360 361 Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);362 363 assert_eq!(Balances::free_balance(4), 100);364 assert_ok!(CollatorSelection::register_as_candidate(365 RuntimeOrigin::signed(4)366 ));367 368 Authorship::on_initialize(1);369370 let collator = CandidateInfo {371 who: 4,372 deposit: 10,373 };374375 assert_eq!(CollatorSelection::candidates(), vec![collator]);376 assert_eq!(CollatorSelection::last_authored_block(4), 0);377 378 assert_eq!(Balances::free_balance(4), 90);379 380 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);381 });382}383384#[test]385fn session_management_works() {386 new_test_ext().execute_with(|| {387 initialize_to_block(1);388389 assert_eq!(SessionChangeBlock::get(), 0);390 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);391392 initialize_to_block(4);393394 assert_eq!(SessionChangeBlock::get(), 0);395 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);396397 398 assert_ok!(CollatorSelection::register_as_candidate(399 RuntimeOrigin::signed(3)400 ));401402 403 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);404 405 assert_eq!(CollatorSelection::candidates().len(), 1);406407 initialize_to_block(10);408 assert_eq!(SessionChangeBlock::get(), 10);409 410 assert_eq!(Session::validators(), vec![1, 2]);411 412 assert_eq!(Session::queued_keys().len(), 3);413 414 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);415416 initialize_to_block(20);417 assert_eq!(SessionChangeBlock::get(), 20);418 419 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);420 });421}422423#[test]424fn kick_mechanism() {425 new_test_ext().execute_with(|| {426 427 assert_ok!(CollatorSelection::register_as_candidate(428 RuntimeOrigin::signed(3)429 ));430 assert_ok!(CollatorSelection::register_as_candidate(431 RuntimeOrigin::signed(4)432 ));433 initialize_to_block(10);434 assert_eq!(CollatorSelection::candidates().len(), 2);435 initialize_to_block(20);436 assert_eq!(SessionChangeBlock::get(), 20);437 438 assert_eq!(CollatorSelection::candidates().len(), 1);439 440 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);441 let collator = CandidateInfo {442 who: 4,443 deposit: 10,444 };445 assert_eq!(CollatorSelection::candidates(), vec![collator]);446 assert_eq!(CollatorSelection::kick_threshold(), 1);447 assert_eq!(CollatorSelection::last_authored_block(4), 20);448 initialize_to_block(30);449 450 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);451 452 assert_eq!(Balances::free_balance(3), 100);453 });454}455456#[test]457fn should_not_kick_mechanism_too_few() {458 new_test_ext().execute_with(|| {459 460 assert_ok!(CollatorSelection::register_as_candidate(461 RuntimeOrigin::signed(3)462 ));463 assert_ok!(CollatorSelection::register_as_candidate(464 RuntimeOrigin::signed(5)465 ));466 initialize_to_block(10);467 assert_eq!(CollatorSelection::candidates().len(), 2);468 initialize_to_block(20);469 assert_eq!(SessionChangeBlock::get(), 20);470 471 assert_eq!(CollatorSelection::candidates().len(), 1);472 473 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);474 let collator = CandidateInfo {475 who: 5,476 deposit: 10,477 };478 assert_eq!(CollatorSelection::candidates(), vec![collator]);479 assert_eq!(CollatorSelection::last_authored_block(4), 20);480 initialize_to_block(30);481 482 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);483 484 assert_eq!(Balances::free_balance(3), 100);485 });486}487488#[test]489#[should_panic = "duplicate invulnerables in genesis."]490fn cannot_set_genesis_value_twice() {491 sp_tracing::try_init_simple();492 let mut t = frame_system::GenesisConfig::default()493 .build_storage::<Test>()494 .unwrap();495 let invulnerables = vec![1, 1];496497 let collator_selection = collator_selection::GenesisConfig::<Test> {498 desired_candidates: 2,499 candidacy_bond: 10,500 kick_threshold: 1,501 invulnerables,502 };503 504 collator_selection.assimilate_storage(&mut t).unwrap();505}