Skip to content

Commit

Permalink
feat: add roles metadata for validators (#309)
Browse files Browse the repository at this point in the history
* feat: add roles metadata for validators

* merge fixes

* clippy fixes

* clippy fixes
  • Loading branch information
1xstj authored Nov 22, 2023
1 parent 1a5526a commit 8f28726
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 72 deletions.
20 changes: 6 additions & 14 deletions pallets/jobs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use sp_std::{prelude::*, vec::Vec};
use tangle_primitives::{
jobs::{JobId, JobInfo, JobKey, PhaseOneResult, ValidatorOffence},
traits::{
jobs::{JobResultVerifier, JobToFee},
jobs::{JobToFee, MPCHandler},
roles::RolesHandler,
},
};
Expand Down Expand Up @@ -71,11 +71,7 @@ pub mod module {
type RolesHandler: RolesHandler<Self::AccountId>;

/// The job result verifying mechanism
type JobResultVerifier: JobResultVerifier<
Self::AccountId,
BlockNumberFor<Self>,
BalanceOf<Self>,
>;
type MPCHandler: MPCHandler<Self::AccountId, BlockNumberFor<Self>, BalanceOf<Self>>;

/// The origin which may set filter.
type ForceOrigin: EnsureOrigin<Self::RuntimeOrigin>;
Expand Down Expand Up @@ -210,7 +206,7 @@ pub mod module {

for participant in participants {
ensure!(
T::RolesHandler::is_validator(participant.clone(), job_key.clone().into()),
T::RolesHandler::is_validator(participant.clone(), job_key.clone()),
Error::<T>::InvalidValidator
);

Expand Down Expand Up @@ -238,7 +234,7 @@ pub mod module {
// Ensure the phase one participants are still validators
for participant in result.participants {
ensure!(
T::RolesHandler::is_validator(participant.clone(), job_key.clone().into()),
T::RolesHandler::is_validator(participant.clone(), job_key.clone()),
Error::<T>::InvalidValidator
);

Expand Down Expand Up @@ -339,7 +335,7 @@ pub mod module {
};

// Validate the result
T::JobResultVerifier::verify(&job_info, phase1_result.clone(), result.clone())?;
T::MPCHandler::verify(&job_info, phase1_result.clone(), result.clone())?;

// If phase 1, store in known result
if job_info.job_type.is_phase_one() {
Expand Down Expand Up @@ -483,11 +479,7 @@ pub mod module {
ensure!(participants.contains(&validator), Error::<T>::JobNotFound);

// Validate the result
T::JobResultVerifier::verify_validator_report(
validator.clone(),
offence.clone(),
signatures,
)?;
T::MPCHandler::verify_validator_report(validator.clone(), offence.clone(), signatures)?;

// Slash the validator
T::RolesHandler::slash_validator(validator.clone(), offence)?;
Expand Down
14 changes: 9 additions & 5 deletions pallets/jobs/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub type AccountId = u128;
pub type Balance = u128;
pub type BlockNumber = u64;

use tangle_primitives::{jobs::*, roles::RoleType};
use tangle_primitives::jobs::*;

impl frame_system::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
Expand Down Expand Up @@ -128,7 +128,7 @@ impl JobToFee<AccountId, BlockNumber> for MockJobToFeeHandler {
pub struct MockRolesHandler;

impl RolesHandler<AccountId> for MockRolesHandler {
fn is_validator(address: AccountId, _role_type: RoleType) -> bool {
fn is_validator(address: AccountId, _role_type: JobKey) -> bool {
let validators = [1, 2, 3, 4, 5];
validators.contains(&address)
}
Expand All @@ -138,9 +138,9 @@ impl RolesHandler<AccountId> for MockRolesHandler {
}
}

pub struct MockJobResultVerifier;
pub struct MockMPCHandler;

impl JobResultVerifier<AccountId, BlockNumber, Balance> for MockJobResultVerifier {
impl MPCHandler<AccountId, BlockNumber, Balance> for MockMPCHandler {
fn verify(
job: &JobInfo<AccountId, BlockNumber, Balance>,
phase_one_data: Option<PhaseOneResult<AccountId, BlockNumber>>,
Expand All @@ -161,6 +161,10 @@ impl JobResultVerifier<AccountId, BlockNumber, Balance> for MockJobResultVerifie
) -> DispatchResult {
Ok(())
}

fn validate_authority_key(_validator: AccountId, _authority_key: Vec<u8>) -> DispatchResult {
Ok(())
}
}

parameter_types! {
Expand All @@ -173,7 +177,7 @@ impl Config for Runtime {
type Currency = Balances;
type JobToFee = MockJobToFeeHandler;
type RolesHandler = MockRolesHandler;
type JobResultVerifier = MockJobResultVerifier;
type MPCHandler = MockMPCHandler;
type PalletId = JobsPalletId;
type WeightInfo = ();
}
Expand Down
28 changes: 23 additions & 5 deletions pallets/roles/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,39 @@
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.

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

/// Implements RolesHandler for the pallet.
impl<T: Config> RolesHandler<T::AccountId> for Pallet<T> {
/// Validates if the given address has the given role.
///
/// # Parameters
/// - `address`: The account ID of the validator.
/// - `role`: The key representing the type of job.
/// - `job`: The key representing the type of job.
///
/// # 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 {
Self::has_role(address, role)
fn is_validator(address: T::AccountId, job_key: JobKey) -> bool {
let assigned_roles = AccountRolesMapping::<T>::get(address);

let mut found_role = false;

for assigned_role in assigned_roles {
match job_key {
JobKey::DKG | JobKey::DKGSignature =>
if assigned_role.is_tss() {
found_role = true;
},
JobKey::ZkSaasPhaseOne | JobKey::ZkSaasPhaseTwo =>
if assigned_role.is_zksaas() {
found_role = true;
},
}
}

return found_role
}

/// Slash validator stake for the reported offence. The function should be a best effort
Expand Down
24 changes: 20 additions & 4 deletions pallets/roles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use tangle_primitives::traits::jobs::MPCHandler;

#[pallet::pallet]
#[pallet::without_storage_info]
Expand All @@ -108,6 +109,9 @@ pub mod pallet {
#[pallet::constant]
type MaxRolesPerAccount: Get<u32>;

/// The config that verifies MPC related functions
type MPCHandler: MPCHandler<Self::AccountId, BlockNumberFor<Self>, BalanceOf<Self>>;

type WeightInfo: WeightInfo;
}

Expand Down Expand Up @@ -203,7 +207,16 @@ pub mod pallet {
let role = record.role;
let re_stake_amount = record.re_staked;
// Check if role is already assigned.
ensure!(!Self::has_role(stash_account.clone(), role), Error::<T>::HasRoleAssigned);
ensure!(
!Self::has_role(stash_account.clone(), role.clone()),
Error::<T>::HasRoleAssigned
);

// validate the metadata
T::MPCHandler::validate_authority_key(
stash_account.clone(),
role.clone().get_authority_key(),
)?;

// Re-staking amount of record should meet min re-staking amount requirement.
let min_re_staking_bond = MinReStakingBond::<T>::get();
Expand All @@ -225,7 +238,7 @@ pub mod pallet {

// Now that records are validated we can add them and update ledger
for record in records {
Self::add_role(stash_account.clone(), record.role)?;
Self::add_role(stash_account.clone(), record.role.clone())?;
Self::deposit_event(Event::<T>::RoleAssigned {
account: stash_account.clone(),
role: record.role,
Expand Down Expand Up @@ -258,14 +271,17 @@ pub mod pallet {
);

// check if role is assigned.
ensure!(Self::has_role(stash_account.clone(), role), Error::<T>::NoRoleAssigned);
ensure!(
Self::has_role(stash_account.clone(), role.clone()),
Error::<T>::NoRoleAssigned
);

// TODO: Call jobs manager to remove the services.
// On successful removal of services, remove the role from the mapping.
// Issue link for reference : https://github.com/webb-tools/tangle/issues/292

// Remove role from the mapping.
Self::remove_role(stash_account.clone(), role)?;
Self::remove_role(stash_account.clone(), role.clone())?;
// Remove stash account related info.
Self::kill_stash(&stash_account);

Expand Down
30 changes: 29 additions & 1 deletion pallets/roles/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ use sp_core::H256;
use sp_runtime::{
testing::{Header, UintAuthorityId},
traits::IdentityLookup,
BuildStorage, Perbill,
BuildStorage, DispatchResult, Perbill,
};
use tangle_primitives::{jobs::*, traits::jobs::MPCHandler};

pub type AccountId = u64;
pub type Balance = u128;
pub type BlockNumber = u64;

impl frame_system::Config for Runtime {
type RuntimeOrigin = RuntimeOrigin;
Expand Down Expand Up @@ -74,6 +77,30 @@ impl pallet_balances::Config for Runtime {
type MaxFreezes = ();
}

pub struct MockMPCHandler;

impl MPCHandler<AccountId, BlockNumber, Balance> for MockMPCHandler {
fn verify(
_job: &JobInfo<AccountId, BlockNumber, Balance>,
_phase_one_data: Option<PhaseOneResult<AccountId, BlockNumber>>,
_result: Vec<u8>,
) -> DispatchResult {
Ok(())
}

fn verify_validator_report(
_validator: AccountId,
_offence: ValidatorOffence,
_report: Vec<u8>,
) -> DispatchResult {
Ok(())
}

fn validate_authority_key(_validator: AccountId, _authority_key: Vec<u8>) -> DispatchResult {
Ok(())
}
}

impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = ();
Expand Down Expand Up @@ -203,6 +230,7 @@ impl pallet_staking::Config for Runtime {
impl Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type MaxRolesPerAccount = ConstU32<2>;
type MPCHandler = MockMPCHandler;
type WeightInfo = ();
}

Expand Down
Loading

0 comments on commit 8f28726

Please sign in to comment.