Skip to content

Commit

Permalink
Merge branch 'main' into feat/caller-for-jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
salman01zp authored Nov 22, 2023
2 parents 57c54c7 + 1a5526a commit 8070b6e
Show file tree
Hide file tree
Showing 9 changed files with 721 additions and 201 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions pallets/roles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ serde = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-balances = { workspace = true }
pallet-staking = { workspace = true }
pallet-session = { workspace = true }
pallet-timestamp = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
sp-staking = { workspace = true }
tangle-primitives = {workspace = true, default-features = false }
frame-benchmarking = { workspace = true, optional = true }
frame-election-provider-support = { workspace = true }

[dev-dependencies]
hex-literal = { workspace = true }
Expand All @@ -40,8 +45,13 @@ std = [
"sp-runtime/std",
"sp-std/std",
"sp-io/std",
"sp-staking/std",
"pallet-balances/std",
"tangle-primitives/std"
"pallet-staking/std",
"pallet-session/std",
"pallet-timestamp/std",
"tangle-primitives/std",
"frame-election-provider-support/std",
]

try-runtime = ["frame-support/try-runtime"]
Expand All @@ -50,5 +60,9 @@ runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-balances/runtime-benchmarks"
"sp-staking/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"frame-election-provider-support/runtime-benchmarks",
]
125 changes: 84 additions & 41 deletions pallets/roles/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.

use super::*;
use frame_support::{pallet_prelude::DispatchResult, traits::WithdrawReasons};
use sp_runtime::Saturating;
use sp_runtime::{DispatchResult, Percent, Saturating};
use tangle_primitives::{roles::RoleType, traits::roles::RolesHandler};

/// Implements RolesHandler for the pallet.
Expand All @@ -30,16 +29,7 @@ impl<T: Config> RolesHandler<T::AccountId> for Pallet<T> {
/// # Returns
/// Returns `true` if the validator is permitted to work with this job type, otherwise `false`.
fn is_validator(address: T::AccountId, role: RoleType) -> bool {
let assigned_role = AccountRolesMapping::<T>::get(address);
match assigned_role {
Some(r) =>
if r == role {
return true
},
None => return false,
}

false
Self::has_role(address, role)
}

/// Slash validator stake for the reported offence. The function should be a best effort
Expand All @@ -64,6 +54,84 @@ impl<T: Config> RolesHandler<T::AccountId> for Pallet<T> {

/// Functions for the pallet.
impl<T: Config> Pallet<T> {
/// Add new role to the given account.
///
/// # Parameters
/// - `account`: The account ID of the validator.
/// - `role`: Selected role type.
pub fn add_role(account: T::AccountId, role: RoleType) -> DispatchResult {
AccountRolesMapping::<T>::try_mutate(&account, |roles| {
if !roles.contains(&role) {
roles.try_push(role.clone()).map_err(|_| Error::<T>::MaxRoles)?;

Ok(())
} else {
Err(Error::<T>::HasRoleAssigned.into())
}
})
}

/// Remove role from the given account.
///
/// # Parameters
/// - `account`: The account ID of the validator.
/// - `role`: Selected role type.
pub fn remove_role(account: T::AccountId, role: RoleType) -> DispatchResult {
AccountRolesMapping::<T>::try_mutate(&account, |roles| {
if roles.contains(&role) {
roles.retain(|r| r != &role);

Ok(())
} else {
Err(Error::<T>::NoRoleAssigned.into())
}
})
}

/// Check if the given account has the given role.
///
/// # Parameters
/// - `account`: The account ID of the validator.
/// - `role`: Selected role type.
///
/// # Returns
/// Returns `true` if the validator is permitted to work with this job type, otherwise `false`.
pub fn has_role(account: T::AccountId, role: RoleType) -> bool {
let assigned_roles = AccountRolesMapping::<T>::get(account);
match assigned_roles.iter().find(|r| **r == role) {
Some(_) => true,
None => false,
}
}

/// Check if account can chill, unbound and withdraw funds.
///
/// # Parameters
/// - `account`: The account ID of the validator.
///
/// # Returns
/// Returns boolean value.
pub fn can_exit(account: T::AccountId) -> bool {
let assigned_roles = AccountRolesMapping::<T>::get(account);
if assigned_roles.is_empty() {
// Role is cleared, account can chill, unbound and withdraw funds.
return true
}
false
}

/// Calculate max re-stake amount for the given account.
///
/// # Parameters
/// - `total_stake`: Total stake of the validator
///
/// # Returns
/// Returns the max re-stake amount.
pub fn calculate_max_re_stake_amount(total_stake: BalanceOf<T>) -> BalanceOf<T> {
// User can re-stake max 50% of the total stake
Percent::from_percent(50) * total_stake
}

/// Get the total amount of the balance that is locked for the given stash.
///
/// # Parameters
Expand All @@ -73,7 +141,7 @@ impl<T: Config> Pallet<T> {
/// The total amount of the balance that can be slashed.
pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf<T> {
// Weight note: consider making the stake accessible through stash.
Self::ledger(&stash).map(|l| l.total_locked).unwrap_or_default()
Self::ledger(&stash).map(|l| l.total).unwrap_or_default()
}

/// Slash the given amount from the stash account.
Expand All @@ -85,9 +153,9 @@ impl<T: Config> Pallet<T> {
address: T::AccountId,
slash_amount: T::CurrencyBalance,
) -> sp_runtime::DispatchResult {
let mut ledger = Self::ledger(&address).ok_or(Error::<T>::InvalidStashController)?;
let mut ledger = Self::ledger(&address).ok_or(Error::<T>::AccountNotPaired)?;
let (_imbalance, _missing) = T::Currency::slash(&address, slash_amount.into());
ledger.total_locked = ledger.total_locked.saturating_sub(slash_amount.into());
ledger.total = ledger.total.saturating_sub(slash_amount.into());
Self::update_ledger(&address, &ledger);
Self::deposit_event(Event::Slashed { account: address, amount: slash_amount });
Ok(())
Expand All @@ -102,36 +170,11 @@ impl<T: Config> Pallet<T> {
/// # Note
/// This function will set a lock on the stash account.
pub(crate) fn update_ledger(staker: &T::AccountId, ledger: &RoleStakingLedger<T>) {
T::Currency::set_lock(
ROLES_STAKING_ID,
&ledger.stash,
ledger.total_locked,
WithdrawReasons::all(),
);
<Ledger<T>>::insert(staker, ledger);
}

/// Kill the stash account and remove all related information.
pub(crate) fn kill_stash(stash: &T::AccountId) -> DispatchResult {
pub(crate) fn kill_stash(stash: &T::AccountId) {
<Ledger<T>>::remove(&stash);
Ok(())
}

/// Unbond the stash account.
///
/// # Parameters
/// - `ledger`: The ledger of the stash account.
///
/// # Note
/// This function will remove the lock on the stash account.
pub(super) fn unbond(ledger: &RoleStakingLedger<T>) -> DispatchResult {
let stash = ledger.stash.clone();
if ledger.total_locked > T::Currency::minimum_balance() {
// Remove the lock.
T::Currency::remove_lock(ROLES_STAKING_ID, &stash);
// Kill the stash and related information.
Self::kill_stash(&stash)?;
}
Ok(())
}
}
Loading

0 comments on commit 8070b6e

Please sign in to comment.