Add Ability to Add/Remove Invulnerable Collators (#2596)

* add add and remove invulnerable dispatchables

* add migration

* fix benchmarking code

* add weights

* add migration to runtimes

* clippy

* pass SafeCallFilter

* make try-runtime work

* typos

Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com>

* better insert and added test

* fix try-runtime update

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <git@kchr.de>

* Update pallets/collator-selection/src/migration.rs

* check events in test

* Update pallets/collator-selection/src/migration.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* just dispatchresult

* only sp_std for try-runtime

---------

Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
joe petrowski
2023-05-29 15:03:48 +02:00
committed by GitHub
parent 4899e4e9da
commit 23584c7b42
30 changed files with 713 additions and 41 deletions
+133 -4
View File
@@ -20,7 +20,7 @@ use frame_support::{
traits::{Currency, GenesisBuild, OnInitialize},
};
use pallet_balances::Error as BalancesError;
use sp_runtime::traits::BadOrigin;
use sp_runtime::{testing::UintAuthorityId, traits::BadOrigin};
#[test]
fn basic_setup_works() {
@@ -29,6 +29,7 @@ fn basic_setup_works() {
assert_eq!(CollatorSelection::candidacy_bond(), 10);
assert!(CollatorSelection::candidates().is_empty());
// genesis should sort input
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
});
}
@@ -36,11 +37,12 @@ fn basic_setup_works() {
#[test]
fn it_should_set_invulnerables() {
new_test_ext().execute_with(|| {
let new_set = vec![1, 2, 3, 4];
let mut new_set = vec![1, 4, 3, 2];
assert_ok!(CollatorSelection::set_invulnerables(
RuntimeOrigin::signed(RootAccount::get()),
new_set.clone()
));
new_set.sort();
assert_eq!(CollatorSelection::invulnerables(), new_set);
// cannot set with non-root.
@@ -50,7 +52,7 @@ fn it_should_set_invulnerables() {
);
// cannot set invulnerables without associated validator keys
let invulnerables = vec![7];
let invulnerables = vec![42];
assert_noop!(
CollatorSelection::set_invulnerables(
RuntimeOrigin::signed(RootAccount::get()),
@@ -61,6 +63,133 @@ fn it_should_set_invulnerables() {
});
}
#[test]
fn add_invulnerable_works() {
new_test_ext().execute_with(|| {
initialize_to_block(1);
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
let new = 3;
// function runs
assert_ok!(CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
new
));
System::assert_last_event(RuntimeEvent::CollatorSelection(
crate::Event::InvulnerableAdded { account_id: new },
));
// same element cannot be added more than once
assert_noop!(
CollatorSelection::add_invulnerable(RuntimeOrigin::signed(RootAccount::get()), new),
Error::<Test>::AlreadyInvulnerable
);
// new element is now part of the invulnerables list
assert!(CollatorSelection::invulnerables().to_vec().contains(&new));
// cannot add with non-root
assert_noop!(CollatorSelection::add_invulnerable(RuntimeOrigin::signed(1), new), BadOrigin);
// cannot add invulnerable without associated validator keys
let not_validator = 42;
assert_noop!(
CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
not_validator
),
Error::<Test>::ValidatorNotRegistered
);
});
}
#[test]
fn invulnerable_limit_works() {
new_test_ext().execute_with(|| {
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
// MaxInvulnerables: u32 = 20
for ii in 3..=21 {
// only keys were registered in mock for 1 to 5
if ii > 5 {
Balances::make_free_balance_be(&ii, 100);
let key = MockSessionKeys { aura: UintAuthorityId(ii) };
Session::set_keys(RuntimeOrigin::signed(ii).into(), key, Vec::new()).unwrap();
}
assert_eq!(Balances::free_balance(ii), 100);
if ii < 21 {
assert_ok!(CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
ii
));
} else {
assert_noop!(
CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
ii
),
Error::<Test>::TooManyInvulnerables
);
}
}
let expected: Vec<u64> = (1..=20).collect();
assert_eq!(CollatorSelection::invulnerables(), expected);
// Cannot set too many Invulnerables
let too_many_invulnerables: Vec<u64> = (1..=21).collect();
assert_noop!(
CollatorSelection::set_invulnerables(
RuntimeOrigin::signed(RootAccount::get()),
too_many_invulnerables
),
Error::<Test>::TooManyInvulnerables
);
assert_eq!(CollatorSelection::invulnerables(), expected);
});
}
#[test]
fn remove_invulnerable_works() {
new_test_ext().execute_with(|| {
initialize_to_block(1);
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
assert_ok!(CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
4
));
assert_ok!(CollatorSelection::add_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
3
));
assert_eq!(CollatorSelection::invulnerables(), vec![1, 2, 3, 4]);
assert_ok!(CollatorSelection::remove_invulnerable(
RuntimeOrigin::signed(RootAccount::get()),
2
));
System::assert_last_event(RuntimeEvent::CollatorSelection(
crate::Event::InvulnerableRemoved { account_id: 2 },
));
assert_eq!(CollatorSelection::invulnerables(), vec![1, 3, 4]);
// cannot remove invulnerable not in the list
assert_noop!(
CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(RootAccount::get()), 2),
Error::<Test>::NotInvulnerable
);
// cannot remove without privilege
assert_noop!(
CollatorSelection::remove_invulnerable(RuntimeOrigin::signed(1), 3),
BadOrigin
);
});
}
#[test]
fn set_desired_candidates_works() {
new_test_ext().execute_with(|| {
@@ -157,7 +286,7 @@ fn cannot_register_as_candidate_if_keys_not_registered() {
new_test_ext().execute_with(|| {
// can't 7 because keys not registered.
assert_noop!(
CollatorSelection::register_as_candidate(RuntimeOrigin::signed(7)),
CollatorSelection::register_as_candidate(RuntimeOrigin::signed(42)),
Error::<Test>::ValidatorNotRegistered
);
})