diff --git a/pallets/collator-selection/src/lib.rs b/pallets/collator-selection/src/lib.rs index d0c1308fa..79f17bbc1 100644 --- a/pallets/collator-selection/src/lib.rs +++ b/pallets/collator-selection/src/lib.rs @@ -219,7 +219,7 @@ pub mod pallet { /// Destination account for slashed amount. #[pallet::storage] - pub type SlashDestination = StorageValue<_, ::AccountId>; + pub type SlashDestination = StorageValue<_, T::AccountId, OptionQuery>; #[pallet::genesis_config] #[derive(DefaultNoBound)] @@ -480,6 +480,22 @@ pub mod pallet { Ok(()) } + + /// Set slash destination. + /// Use `Some` to deposit slashed balance into destination or `None` to burn it. + #[pallet::call_index(6)] + #[pallet::weight(T::DbWeight::get().reads_writes(1, 1))] + pub fn set_slash_destination( + origin: OriginFor, + destination: Option, + ) -> DispatchResult { + T::UpdateOrigin::ensure_origin(origin)?; + match destination { + Some(account) => >::put(account), + None => >::kill(), + } + Ok(()) + } } impl Pallet { diff --git a/pallets/collator-selection/src/tests.rs b/pallets/collator-selection/src/tests.rs index d38050660..17299bf42 100644 --- a/pallets/collator-selection/src/tests.rs +++ b/pallets/collator-selection/src/tests.rs @@ -18,7 +18,7 @@ use crate as collator_selection; use crate::{ mock::*, CandidacyBond, CandidateInfo, Candidates, DesiredCandidates, Error, Invulnerables, - LastAuthoredBlock, NonCandidates, + LastAuthoredBlock, NonCandidates, SlashDestination, }; use frame_support::{ assert_noop, assert_ok, @@ -628,3 +628,30 @@ fn cannot_set_genesis_value_twice() { // collator selection must be initialized before session. collator_selection.assimilate_storage(&mut t).unwrap(); } + +#[test] +fn set_slash_destination() { + new_test_ext().execute_with(|| { + assert_eq!(SlashDestination::::get(), None); + + // only UpdateOrigin can update + assert_noop!( + CollatorSelection::set_slash_destination(RuntimeOrigin::signed(1), Some(1)), + sp_runtime::DispatchError::BadOrigin + ); + + // set destination + assert_ok!(CollatorSelection::set_slash_destination( + RuntimeOrigin::signed(RootAccount::get()), + Some(1), + )); + assert_eq!(SlashDestination::::get(), Some(1)); + + // remove destination + assert_ok!(CollatorSelection::set_slash_destination( + RuntimeOrigin::signed(RootAccount::get()), + None, + )); + assert_eq!(SlashDestination::::get(), None); + }); +}