Skip to content

Commit

Permalink
chore: add service id to slash operator for proper processing
Browse files Browse the repository at this point in the history
  • Loading branch information
drewstone committed Jan 21, 2025
1 parent aca7c3d commit 4f8adef
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 12 deletions.
1 change: 1 addition & 0 deletions pallets/rewards/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo<AccountId, Balance, Blo
fn slash_operator(
_operator: &AccountId,
_blueprint_id: tangle_primitives::BlueprintId,
_service_id: tangle_primitives::InstanceId,
_percentage: sp_runtime::Percent,
) {
}
Expand Down
6 changes: 5 additions & 1 deletion pallets/services/src/functions/approve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ impl<T: Config> Pallet<T> {
asset_exposures.len() <= T::MaxAssetsPerService::get() as usize,
Error::<T>::MaxAssetsPerServiceExceeded
);
// Ensure asset exposures length matches requested assets length
ensure!(
asset_exposures.len() == request.non_native_asset_security
)

// Find and update operator's approval state
let updated = request
Expand Down Expand Up @@ -256,7 +260,7 @@ impl<T: Config> Pallet<T> {
request_id,
service_id,
blueprint_id: request.blueprint,
assets: request.asset_security.iter().map(|a| a.asset.clone()).collect(),
assets: request.non_native_asset_security.iter().map(|a| a.asset.clone()).collect(),
});

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion pallets/services/src/functions/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl<T: Config> Pallet<T> {
let service_request = ServiceRequest {
blueprint: blueprint_id,
owner: caller.clone(),
asset_security: bounded_requirements,
non_native_asset_security: bounded_requirements,
ttl,
args,
permitted_callers,
Expand Down
7 changes: 6 additions & 1 deletion pallets/services/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ impl<T: crate::Config, Balance: Default>
true // For benchmarking, always return true
}

fn slash_operator(_operator: &T::AccountId, _blueprint_id: BlueprintId, _percentage: Percent) {
fn slash_operator(
_operator: &T::AccountId,
_blueprint_id: BlueprintId,
_service_id: InstanceId,
_percentage: Percent,
) {
// For benchmarking, do nothing
}

Expand Down
8 changes: 4 additions & 4 deletions pallets/services/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sp_runtime::{traits::Get, DispatchResult};
use tangle_primitives::{
services::{AssetSecurityCommitment, AssetSecurityRequirement, MembershipModel},
traits::MultiAssetDelegationInfo,
BlueprintId,
BlueprintId, InstanceId, JobCallId, ServiceRequestId,
};

pub mod functions;
Expand Down Expand Up @@ -524,17 +524,17 @@ pub mod module {
/// The next free ID for a service request.
#[pallet::storage]
#[pallet::getter(fn next_service_request_id)]
pub type NextServiceRequestId<T> = StorageValue<_, u64, ValueQuery>;
pub type NextServiceRequestId<T> = StorageValue<_, ServiceRequestId, ValueQuery>;

/// The next free ID for a service Instance.
#[pallet::storage]
#[pallet::getter(fn next_instance_id)]
pub type NextInstanceId<T> = StorageValue<_, u64, ValueQuery>;
pub type NextInstanceId<T> = StorageValue<_, InstanceId, ValueQuery>;

/// The next free ID for a service call.
#[pallet::storage]
#[pallet::getter(fn next_job_call_id)]
pub type NextJobCallId<T> = StorageValue<_, u64, ValueQuery>;
pub type NextJobCallId<T> = StorageValue<_, JobCallId, ValueQuery>;

/// The next free ID for a unapplied slash.
#[pallet::storage]
Expand Down
1 change: 1 addition & 0 deletions pallets/services/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo<AccountId, Balance, u64
fn slash_operator(
_operator: &AccountId,
_blueprint_id: tangle_primitives::BlueprintId,
_service_id: tangle_primitives::InstanceId,
_percentage: sp_runtime::Percent,
) {
// For mock implementation, do nothing
Expand Down
25 changes: 23 additions & 2 deletions pallets/services/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ fn test_ecdsa_key() -> [u8; 65] {
public_key.to_bytes().to_vec().try_into().unwrap()
}

fn get_security_requirement(a: AssetId, p: &[u8; 2]) -> AssetSecurityRequirement<AssetId> {
AssetSecurityRequirement {
asset: Asset::Custom(a),
min_exposure_percent: Percent::from_percent(p[0]),
max_exposure_percent: Percent::from_percent(p[1]),
}
}

fn get_security_commitment(a: AssetId, p: u8) -> AssetSecurityCommitment<AssetId> {
AssetSecurityCommitment { asset: Asset::Custom(a), exposure_percent: Percent::from_percent(p) }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum MachineKind {
Large,
Expand Down Expand Up @@ -92,6 +104,10 @@ fn cggmp21_blueprint() -> ServiceBlueprint<ConstraintsOf<Runtime>> {
registration_params: bounded_vec![],
request_params: bounded_vec![],
gadget: Default::default(),
supported_membership_models: bounded_vec![
MembershipModel::Fixed { min_operators: 1 },
MembershipModel::Dynamic { min_operators: 1, max_operators: None },
],
}
}

Expand Down Expand Up @@ -410,10 +426,14 @@ fn request_service() {
vec![alice.clone()],
vec![bob.clone(), charlie.clone(), dave.clone()],
Default::default(),
vec![USDC, WETH],
vec![
get_security_requirement(USDC, &[10, 20]),
get_security_requirement(WETH, &[10, 20])
],
100,
Asset::Custom(USDC),
0,
MembershipModel::Fixed { min_operators: 3 }
));

assert_eq!(ServiceRequests::<Runtime>::iter_keys().collect::<Vec<_>>().len(), 1);
Expand All @@ -422,7 +442,8 @@ fn request_service() {
assert_ok!(Services::approve(
RuntimeOrigin::signed(bob.clone()),
0,
Percent::from_percent(10)
Percent::from_percent(10),
vec![get_security_commitment(USDC, 10), get_security_commitment(WETH, 10),],
));

assert_events(vec![RuntimeEvent::Services(crate::Event::ServiceRequestApproved {
Expand Down
2 changes: 1 addition & 1 deletion precompiles/services/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ where
// Retrieve and validate the service request
let request = pallet_services::ServiceRequests::<Runtime>::get(request_id).unwrap();
// Treat the asset approval descriptions in order
let request_assets = request.asset_security;
let request_assets = request.non_native_asset_security;
let native_asset_exposure: Percent = Percent::from_percent(native_restaking_percent);
let non_native_asset_exposures: Vec<AssetSecurityCommitment<Runtime::AssetId>> =
request_assets
Expand Down
1 change: 1 addition & 0 deletions precompiles/services/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ impl tangle_primitives::traits::MultiAssetDelegationInfo<AccountId, Balance, u64
fn slash_operator(
_operator: &AccountId,
_blueprint_id: tangle_primitives::BlueprintId,
_service_id: tangle_primitives::InstanceId,
_percentage: sp_runtime::Percent,
) {
}
Expand Down
5 changes: 3 additions & 2 deletions primitives/src/services/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ pub struct ServiceRequest<C: Constraints, AccountId, BlockNumber, AssetId: Asset
pub owner: AccountId,
/// The assets required for this service along with their security requirements.
/// This defines both which assets are needed and how much security backing is required.
pub asset_security: BoundedVec<AssetSecurityRequirement<AssetId>, C::MaxAssetsPerService>,
pub non_native_asset_security:
BoundedVec<AssetSecurityRequirement<AssetId>, C::MaxAssetsPerService>,
/// Time-to-live for this request in blocks
pub ttl: BlockNumber,
/// Arguments for service initialization
Expand Down Expand Up @@ -347,7 +348,7 @@ impl<C: Constraints, AccountId, BlockNumber, AssetId: AssetIdT>
AssetId: PartialEq,
{
// Ensure commitments exist for all required assets
self.asset_security.iter().all(|req| {
self.non_native_asset_security.iter().all(|req| {
asset_commitments.iter().any(|commit| {
commit.asset == req.asset
&& commit.exposure_percent >= req.min_exposure_percent
Expand Down
16 changes: 16 additions & 0 deletions primitives/src/traits/multi_asset_delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,25 @@ pub trait MultiAssetDelegationInfo<AccountId, Balance, BlockNumber, AssetId> {
blueprint_id: crate::BlueprintId,
) -> bool;

/// Slash an operator for a particular blueprint and service. The slash
/// percentage defines the amount of assets delegated to the operator that
/// should be slashed.
///
/// This method iterates over all delegators and assets exposed by the service
/// and slashes them proportionally by the `percentage`.
///
/// # Parameters
///
/// * `operator`: A reference to the account identifier of the operator.
/// * `blueprint_id`: The blueprint ID of the corresponding service.
/// * `service_id`: The service ID where the slashing event originated from.
/// * `percentage`: The severity of the slashing event, as a percentage.
///
/// Method should not fail and should process entire slash.
fn slash_operator(
operator: &AccountId,
blueprint_id: crate::BlueprintId,
service_id: crate::InstanceId,
percentage: sp_runtime::Percent,
);

Expand Down
9 changes: 9 additions & 0 deletions primitives/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ pub type RoundIndex = u32;
/// Blueprint ID
pub type BlueprintId = u64;

/// Service request ID
pub type ServiceRequestId = u64;

/// Service instance ID
pub type InstanceId = u64;

/// Job call ID
pub type JobCallId = u64;

/// The address format for describing accounts.
pub type Address = MultiAddress<AccountId, Index>;

Expand Down

0 comments on commit 4f8adef

Please sign in to comment.