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(RuntimeOrigin::signed(RootAccount::get()), 7),77 Error::<Test>::ValidatorNotRegistered78 );79 });80}8182#[test]83fn it_should_remove_invulnerables() {84 new_test_ext().execute_with(|| {85 assert_ok!(CollatorSelection::add_invulnerable(86 RuntimeOrigin::signed(RootAccount::get()),87 188 ));89 assert_ok!(CollatorSelection::add_invulnerable(90 RuntimeOrigin::signed(RootAccount::get()),91 292 ));9394 95 assert_noop!(96 CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),97 BadOrigin98 );99100 assert_ok!(CollatorSelection::remove_invulnerable(101 RuntimeOrigin::signed(RootAccount::get()),102 2103 ));104 assert_eq!(CollatorSelection::invulnerables(), vec![1]);105106 107 assert_noop!(108 CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 1),109 Error::<Test>::TooFewInvulnerables110 );111 });112}113114#[test]115fn set_desired_candidates_works() {116 new_test_ext().execute_with(|| {117 118 assert_eq!(CollatorSelection::desired_candidates(), 2);119120 121 assert_ok!(CollatorSelection::set_desired_candidates(122 RuntimeOrigin::signed(RootAccount::get()),123 7124 ));125 assert_eq!(CollatorSelection::desired_candidates(), 7);126127 128 assert_noop!(129 CollatorSelection::set_desired_candidates(RuntimeOrigin::signed(1), 8),130 BadOrigin131 );132 });133}134135#[test]136fn set_candidacy_bond() {137 new_test_ext().execute_with(|| {138 139 assert_eq!(CollatorSelection::candidacy_bond(), 10);140141 142 assert_ok!(CollatorSelection::set_candidacy_bond(143 RuntimeOrigin::signed(RootAccount::get()),144 7145 ));146 assert_eq!(CollatorSelection::candidacy_bond(), 7);147148 149 assert_noop!(150 CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),151 BadOrigin152 );153 });154}155156#[test]157fn cannot_register_candidate_if_too_many() {158 new_test_ext().execute_with(|| {159 160 <crate::DesiredCandidates<Test>>::put(0);161162 163 assert_noop!(164 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),165 Error::<Test>::TooManyCandidates,166 );167168 169 <crate::DesiredCandidates<Test>>::put(1);170 assert_ok!(CollatorSelection::register_as_candidate(171 RuntimeOrigin::signed(4)172 ));173174 175 assert_noop!(176 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),177 Error::<Test>::TooManyCandidates,178 );179 })180}181182#[test]183fn cannot_unregister_candidate_if_too_few() {184 new_test_ext().execute_with(|| {185 186 <crate::DesiredCandidates<Test>>::put(1);187 assert_ok!(CollatorSelection::register_as_candidate(188 RuntimeOrigin::signed(4)189 ));190191 192 assert_noop!(193 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),194 Error::<Test>::TooFewCandidates,195 );196 })197}198199#[test]200fn cannot_register_as_candidate_if_invulnerable() {201 new_test_ext().execute_with(|| {202 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);203204 205 assert_noop!(206 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),207 Error::<Test>::AlreadyInvulnerable,208 );209 })210}211212#[test]213fn cannot_register_as_candidate_if_keys_not_registered() {214 new_test_ext().execute_with(|| {215 216 assert_noop!(217 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),218 Error::<Test>::ValidatorNotRegistered219 );220 })221}222223#[test]224fn cannot_register_dupe_candidate() {225 new_test_ext().execute_with(|| {226 227 assert_ok!(CollatorSelection::register_as_candidate(228 RuntimeOrigin::signed(3)229 ));230 let addition = CandidateInfo {231 who: 3,232 deposit: 10,233 };234 assert_eq!(CollatorSelection::candidates(), vec![addition]);235 assert_eq!(CollatorSelection::last_authored_block(3), 10);236 assert_eq!(Balances::free_balance(3), 90);237238 239 assert_noop!(240 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),241 Error::<Test>::AlreadyCandidate,242 );243 })244}245246#[test]247fn cannot_register_as_candidate_if_poor() {248 new_test_ext().execute_with(|| {249 assert_eq!(Balances::free_balance(&3), 100);250 assert_eq!(Balances::free_balance(&33), 0);251252 253 assert_ok!(CollatorSelection::register_as_candidate(254 RuntimeOrigin::signed(3)255 ));256257 258 assert_noop!(259 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),260 BalancesError::<Test>::InsufficientBalance,261 );262 });263}264265#[test]266fn register_as_candidate_works() {267 new_test_ext().execute_with(|| {268 269 assert_eq!(CollatorSelection::desired_candidates(), 2);270 assert_eq!(CollatorSelection::candidacy_bond(), 10);271 assert_eq!(CollatorSelection::candidates(), Vec::new());272 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);273274 275 assert_eq!(Balances::free_balance(&3), 100);276 assert_eq!(Balances::free_balance(&4), 100);277278 assert_ok!(CollatorSelection::register_as_candidate(279 RuntimeOrigin::signed(3)280 ));281 assert_ok!(CollatorSelection::register_as_candidate(282 RuntimeOrigin::signed(4)283 ));284285 assert_eq!(Balances::free_balance(&3), 90);286 assert_eq!(Balances::free_balance(&4), 90);287288 assert_eq!(CollatorSelection::candidates().len(), 2);289 });290}291292#[test]293fn leave_intent() {294 new_test_ext().execute_with(|| {295 296 assert_ok!(CollatorSelection::register_as_candidate(297 RuntimeOrigin::signed(3)298 ));299 assert_eq!(Balances::free_balance(3), 90);300301 302 assert_ok!(CollatorSelection::register_as_candidate(303 RuntimeOrigin::signed(5)304 ));305 assert_eq!(Balances::free_balance(5), 90);306307 308 assert_noop!(309 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),310 Error::<Test>::NotCandidate311 );312313 314 assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));315 assert_eq!(Balances::free_balance(3), 100);316 assert_eq!(CollatorSelection::last_authored_block(3), 0);317 });318}319320#[test]321fn authorship_event_handler() {322 new_test_ext().execute_with(|| {323 324 Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);325326 327 assert_eq!(Balances::free_balance(4), 100);328 assert_ok!(CollatorSelection::register_as_candidate(329 RuntimeOrigin::signed(4)330 ));331 332 Authorship::on_initialize(1);333334 let collator = CandidateInfo {335 who: 4,336 deposit: 10,337 };338339 assert_eq!(CollatorSelection::candidates(), vec![collator]);340 assert_eq!(CollatorSelection::last_authored_block(4), 0);341342 343 assert_eq!(Balances::free_balance(4), 140);344 345 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);346 });347}348349#[test]350fn fees_edgecases() {351 new_test_ext().execute_with(|| {352 353 Authorship::on_initialize(1);354 355 Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);356 357 assert_eq!(Balances::free_balance(4), 100);358 assert_ok!(CollatorSelection::register_as_candidate(359 RuntimeOrigin::signed(4)360 ));361 362 Authorship::on_initialize(1);363364 let collator = CandidateInfo {365 who: 4,366 deposit: 10,367 };368369 assert_eq!(CollatorSelection::candidates(), vec![collator]);370 assert_eq!(CollatorSelection::last_authored_block(4), 0);371 372 assert_eq!(Balances::free_balance(4), 90);373 374 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);375 });376}377378#[test]379fn session_management_works() {380 new_test_ext().execute_with(|| {381 initialize_to_block(1);382383 assert_eq!(SessionChangeBlock::get(), 0);384 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);385386 initialize_to_block(4);387388 assert_eq!(SessionChangeBlock::get(), 0);389 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);390391 392 assert_ok!(CollatorSelection::register_as_candidate(393 RuntimeOrigin::signed(3)394 ));395396 397 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);398 399 assert_eq!(CollatorSelection::candidates().len(), 1);400401 initialize_to_block(10);402 assert_eq!(SessionChangeBlock::get(), 10);403 404 assert_eq!(Session::validators(), vec![1, 2]);405 406 assert_eq!(Session::queued_keys().len(), 3);407 408 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);409410 initialize_to_block(20);411 assert_eq!(SessionChangeBlock::get(), 20);412 413 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);414 });415}416417#[test]418fn kick_mechanism() {419 new_test_ext().execute_with(|| {420 421 assert_ok!(CollatorSelection::register_as_candidate(422 RuntimeOrigin::signed(3)423 ));424 assert_ok!(CollatorSelection::register_as_candidate(425 RuntimeOrigin::signed(4)426 ));427 initialize_to_block(10);428 assert_eq!(CollatorSelection::candidates().len(), 2);429 initialize_to_block(20);430 assert_eq!(SessionChangeBlock::get(), 20);431 432 assert_eq!(CollatorSelection::candidates().len(), 1);433 434 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);435 let collator = CandidateInfo {436 who: 4,437 deposit: 10,438 };439 assert_eq!(CollatorSelection::candidates(), vec![collator]);440 assert_eq!(CollatorSelection::kick_threshold(), 1);441 assert_eq!(CollatorSelection::last_authored_block(4), 20);442 initialize_to_block(30);443 444 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);445 446 assert_eq!(Balances::free_balance(3), 100);447 });448}449450#[test]451fn should_not_kick_mechanism_too_few() {452 new_test_ext().execute_with(|| {453 454 assert_ok!(CollatorSelection::register_as_candidate(455 RuntimeOrigin::signed(3)456 ));457 assert_ok!(CollatorSelection::register_as_candidate(458 RuntimeOrigin::signed(5)459 ));460 initialize_to_block(10);461 assert_eq!(CollatorSelection::candidates().len(), 2);462 initialize_to_block(20);463 assert_eq!(SessionChangeBlock::get(), 20);464 465 assert_eq!(CollatorSelection::candidates().len(), 1);466 467 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);468 let collator = CandidateInfo {469 who: 5,470 deposit: 10,471 };472 assert_eq!(CollatorSelection::candidates(), vec![collator]);473 assert_eq!(CollatorSelection::last_authored_block(4), 20);474 initialize_to_block(30);475 476 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);477 478 assert_eq!(Balances::free_balance(3), 100);479 });480}481482#[test]483#[should_panic = "duplicate invulnerables in genesis."]484fn cannot_set_genesis_value_twice() {485 sp_tracing::try_init_simple();486 let mut t = frame_system::GenesisConfig::default()487 .build_storage::<Test>()488 .unwrap();489 let invulnerables = vec![1, 1];490491 let collator_selection = collator_selection::GenesisConfig::<Test> {492 desired_candidates: 2,493 candidacy_bond: 10,494 kick_threshold: 1,495 invulnerables,496 };497 498 collator_selection.assimilate_storage(&mut t).unwrap();499}