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!(117 CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),118 BadOrigin119 );120 });121}122123#[test]124fn cannot_register_candidate_if_too_many() {125 new_test_ext().execute_with(|| {126 127 <crate::DesiredCandidates<Test>>::put(0);128129 130 assert_noop!(131 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),132 Error::<Test>::TooManyCandidates,133 );134135 136 <crate::DesiredCandidates<Test>>::put(1);137 assert_ok!(CollatorSelection::register_as_candidate(138 RuntimeOrigin::signed(4)139 ));140141 142 assert_noop!(143 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(5)),144 Error::<Test>::TooManyCandidates,145 );146 })147}148149#[test]150fn cannot_unregister_candidate_if_too_few() {151 new_test_ext().execute_with(|| {152 153 <crate::DesiredCandidates<Test>>::put(1);154 assert_ok!(CollatorSelection::register_as_candidate(155 RuntimeOrigin::signed(4)156 ));157158 159 assert_noop!(160 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),161 Error::<Test>::TooFewCandidates,162 );163 })164}165166#[test]167fn cannot_register_as_candidate_if_invulnerable() {168 new_test_ext().execute_with(|| {169 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);170171 172 assert_noop!(173 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(1)),174 Error::<Test>::AlreadyInvulnerable,175 );176 })177}178179#[test]180fn cannot_register_as_candidate_if_keys_not_registered() {181 new_test_ext().execute_with(|| {182 183 assert_noop!(184 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),185 Error::<Test>::ValidatorNotRegistered186 );187 })188}189190#[test]191fn cannot_register_dupe_candidate() {192 new_test_ext().execute_with(|| {193 194 assert_ok!(CollatorSelection::register_as_candidate(195 RuntimeOrigin::signed(3)196 ));197 let addition = CandidateInfo {198 who: 3,199 deposit: 10,200 };201 assert_eq!(CollatorSelection::candidates(), vec![addition]);202 assert_eq!(CollatorSelection::last_authored_block(3), 10);203 assert_eq!(Balances::free_balance(3), 90);204205 206 assert_noop!(207 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(3)),208 Error::<Test>::AlreadyCandidate,209 );210 })211}212213#[test]214fn cannot_register_as_candidate_if_poor() {215 new_test_ext().execute_with(|| {216 assert_eq!(Balances::free_balance(&3), 100);217 assert_eq!(Balances::free_balance(&33), 0);218219 220 assert_ok!(CollatorSelection::register_as_candidate(221 RuntimeOrigin::signed(3)222 ));223224 225 assert_noop!(226 CollatorSelection::register_as_candidate(RuntimeOrigin::signed(33)),227 BalancesError::<Test>::InsufficientBalance,228 );229 });230}231232#[test]233fn register_as_candidate_works() {234 new_test_ext().execute_with(|| {235 236 assert_eq!(CollatorSelection::desired_candidates(), 2);237 assert_eq!(CollatorSelection::candidacy_bond(), 10);238 assert_eq!(CollatorSelection::candidates(), Vec::new());239 assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);240241 242 assert_eq!(Balances::free_balance(&3), 100);243 assert_eq!(Balances::free_balance(&4), 100);244245 assert_ok!(CollatorSelection::register_as_candidate(246 RuntimeOrigin::signed(3)247 ));248 assert_ok!(CollatorSelection::register_as_candidate(249 RuntimeOrigin::signed(4)250 ));251252 assert_eq!(Balances::free_balance(&3), 90);253 assert_eq!(Balances::free_balance(&4), 90);254255 assert_eq!(CollatorSelection::candidates().len(), 2);256 });257}258259#[test]260fn leave_intent() {261 new_test_ext().execute_with(|| {262 263 assert_ok!(CollatorSelection::register_as_candidate(264 RuntimeOrigin::signed(3)265 ));266 assert_eq!(Balances::free_balance(3), 90);267268 269 assert_ok!(CollatorSelection::register_as_candidate(270 RuntimeOrigin::signed(5)271 ));272 assert_eq!(Balances::free_balance(5), 90);273274 275 assert_noop!(276 CollatorSelection::leave_intent(RuntimeOrigin::signed(4)),277 Error::<Test>::NotCandidate278 );279280 281 assert_ok!(CollatorSelection::leave_intent(RuntimeOrigin::signed(3)));282 assert_eq!(Balances::free_balance(3), 100);283 assert_eq!(CollatorSelection::last_authored_block(3), 0);284 });285}286287#[test]288fn authorship_event_handler() {289 new_test_ext().execute_with(|| {290 291 Balances::make_free_balance_be(&CollatorSelection::account_id(), 105);292293 294 assert_eq!(Balances::free_balance(4), 100);295 assert_ok!(CollatorSelection::register_as_candidate(296 RuntimeOrigin::signed(4)297 ));298 299 Authorship::on_initialize(1);300301 let collator = CandidateInfo {302 who: 4,303 deposit: 10,304 };305306 assert_eq!(CollatorSelection::candidates(), vec![collator]);307 assert_eq!(CollatorSelection::last_authored_block(4), 0);308309 310 assert_eq!(Balances::free_balance(4), 140);311 312 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 55);313 });314}315316#[test]317fn fees_edgecases() {318 new_test_ext().execute_with(|| {319 320 Authorship::on_initialize(1);321 322 Balances::make_free_balance_be(&CollatorSelection::account_id(), 5);323 324 assert_eq!(Balances::free_balance(4), 100);325 assert_ok!(CollatorSelection::register_as_candidate(326 RuntimeOrigin::signed(4)327 ));328 329 Authorship::on_initialize(1);330331 let collator = CandidateInfo {332 who: 4,333 deposit: 10,334 };335336 assert_eq!(CollatorSelection::candidates(), vec![collator]);337 assert_eq!(CollatorSelection::last_authored_block(4), 0);338 339 assert_eq!(Balances::free_balance(4), 90);340 341 assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 5);342 });343}344345#[test]346fn session_management_works() {347 new_test_ext().execute_with(|| {348 initialize_to_block(1);349350 assert_eq!(SessionChangeBlock::get(), 0);351 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);352353 initialize_to_block(4);354355 assert_eq!(SessionChangeBlock::get(), 0);356 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);357358 359 assert_ok!(CollatorSelection::register_as_candidate(360 RuntimeOrigin::signed(3)361 ));362363 364 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);365 366 assert_eq!(CollatorSelection::candidates().len(), 1);367368 initialize_to_block(10);369 assert_eq!(SessionChangeBlock::get(), 10);370 371 assert_eq!(Session::validators(), vec![1, 2]);372 373 assert_eq!(Session::queued_keys().len(), 3);374 375 assert_eq!(SessionHandlerCollators::get(), vec![1, 2]);376377 initialize_to_block(20);378 assert_eq!(SessionChangeBlock::get(), 20);379 380 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3]);381 });382}383384#[test]385fn kick_mechanism() {386 new_test_ext().execute_with(|| {387 388 assert_ok!(CollatorSelection::register_as_candidate(389 RuntimeOrigin::signed(3)390 ));391 assert_ok!(CollatorSelection::register_as_candidate(392 RuntimeOrigin::signed(4)393 ));394 initialize_to_block(10);395 assert_eq!(CollatorSelection::candidates().len(), 2);396 initialize_to_block(20);397 assert_eq!(SessionChangeBlock::get(), 20);398 399 assert_eq!(CollatorSelection::candidates().len(), 1);400 401 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);402 let collator = CandidateInfo {403 who: 4,404 deposit: 10,405 };406 assert_eq!(CollatorSelection::candidates(), vec![collator]);407 assert_eq!(CollatorSelection::last_authored_block(4), 20);408 initialize_to_block(30);409 410 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 4]);411 412 assert_eq!(Balances::free_balance(3), 100);413 });414}415416#[test]417fn should_not_kick_mechanism_too_few() {418 new_test_ext().execute_with(|| {419 420 assert_ok!(CollatorSelection::register_as_candidate(421 RuntimeOrigin::signed(3)422 ));423 assert_ok!(CollatorSelection::register_as_candidate(424 RuntimeOrigin::signed(5)425 ));426 initialize_to_block(10);427 assert_eq!(CollatorSelection::candidates().len(), 2);428 initialize_to_block(20);429 assert_eq!(SessionChangeBlock::get(), 20);430 431 assert_eq!(CollatorSelection::candidates().len(), 1);432 433 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);434 let collator = CandidateInfo {435 who: 5,436 deposit: 10,437 };438 assert_eq!(CollatorSelection::candidates(), vec![collator]);439 assert_eq!(CollatorSelection::last_authored_block(4), 20);440 initialize_to_block(30);441 442 assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 5]);443 444 assert_eq!(Balances::free_balance(3), 100);445 });446}447448#[test]449#[should_panic = "duplicate invulnerables in genesis."]450fn cannot_set_genesis_value_twice() {451 sp_tracing::try_init_simple();452 let mut t = frame_system::GenesisConfig::default()453 .build_storage::<Test>()454 .unwrap();455 let invulnerables = vec![1, 1];456457 let collator_selection = collator_selection::GenesisConfig::<Test> {458 desired_candidates: 2,459 candidacy_bond: 10,460 invulnerables,461 };462 463 collator_selection.assimilate_storage(&mut t).unwrap();464}