Skip to content

Commit

Permalink
Implement ban call logic
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrylavrenov committed Sep 2, 2024
1 parent 98a8935 commit a167686
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions crates/pallet-humanode-session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[allow(clippy::missing_docs_in_private_items)]
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_support::{pallet_prelude::*, storage::with_storage_layer};
use frame_system::pallet_prelude::*;

use super::*;
Expand Down Expand Up @@ -49,6 +49,9 @@ pub mod pallet {

/// The max amount of bioauth-powered session validators.
type MaxBioauthValidators: Get<u32>;

/// The maximum number of banned accounts.
type MaxBannedAccounts: Get<u32>;
}

#[pallet::pallet]
Expand All @@ -71,6 +74,11 @@ pub mod pallet {
#[pallet::storage]
pub type CurrentSessionIndex<T: Config> = StorageValue<_, SessionIndex, OptionQuery>;

/// A list of all banned accounts that can't be validators in the network.
#[pallet::storage]
pub type BannedAccounts<T: Config> =
StorageValue<_, BoundedVec<T::AccountId, T::MaxBannedAccounts>, ValueQuery>;

/// Possible errors.
#[pallet::error]
pub enum Error<T> {
Expand All @@ -81,20 +89,50 @@ pub mod pallet {
/// The provided account could not be found in current validators list or it was already
/// disabled.
AccountIsNotValidator,
/// The account is already banned.
AccountIsAlreadyBanned,
/// The BannedAccounts storage has reached the limit as BoundedVec.
TooManyBannedAccounts,
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Kick validator based on provided account id.
#[pallet::call_index(0)]
#[pallet::weight(0)]
pub fn kick_validator(origin: OriginFor<T>, account_id: T::AccountId) -> DispatchResult {
pub fn kick(origin: OriginFor<T>, account_id: T::AccountId) -> DispatchResult {
ensure_root(origin)?;

Self::disable(account_id)?;

Ok(())
}

/// Ban account.
#[pallet::call_index(1)]
#[pallet::weight(0)]
pub fn ban(origin: OriginFor<T>, account_id: T::AccountId) -> DispatchResult {
ensure_root(origin)?;

ensure!(
!Self::is_banned(&account_id),
Error::<T>::AccountIsAlreadyBanned
);

with_storage_layer(move || {
Self::disable(account_id.clone())?;

<BannedAccounts<T>>::try_mutate::<_, DispatchError, _>(move |banned_accounts| {
banned_accounts
.try_push(account_id)
.map_err(|_| Error::<T>::TooManyBannedAccounts)?;

Ok(())
})?;

Ok(())
})
}
}

#[pallet::hooks]
Expand Down Expand Up @@ -212,6 +250,13 @@ impl<T: Config> Pallet<T> {

Ok(())
}

/// Check whether the provided account is banned or not.
fn is_banned(account_id: &T::AccountId) -> bool {
BannedAccounts::<T>::get()
.iter()
.any(|banned_account_id| banned_account_id == account_id)
}
}

impl<T: Config> pallet_session::historical::SessionManager<T::AccountId, IdentificationFor<T>>
Expand Down

0 comments on commit a167686

Please sign in to comment.