Skip to content

Commit

Permalink
feat: Add time based fee to jobs based on ttl (#454)
Browse files Browse the repository at this point in the history
* feat: Add time based fee to jobs based on ttl

* fix lint

* fix lint

* add storage fee per byte
  • Loading branch information
1xstj authored Feb 5, 2024
1 parent 802ef40 commit c4907e6
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 9 deletions.
10 changes: 8 additions & 2 deletions pallets/dkg/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use frame_system::pallet_prelude::BlockNumberFor;
use parity_scale_codec::Encode;
use sp_core::{ecdsa, sr25519};
use sp_io::{crypto::sr25519_verify, hashing::keccak_256, EcdsaVerifyError};
use sp_runtime::traits::Get;
use sp_std::{default::Default, vec::Vec};
use tangle_primitives::jobs::*;

Expand Down Expand Up @@ -58,9 +59,14 @@ impl<T: Config> Pallet<T> {
let validator_count =
job.job_type.clone().get_participants().expect("checked_above").len();
let validator_fee = fee_info.dkg_validator_fee * (validator_count as u32).into();
validator_fee.saturating_add(fee_info.base_fee)
let storage_fee = fee_info.storage_fee_per_byte * T::MaxKeyLen::get().into();
validator_fee.saturating_add(fee_info.base_fee).saturating_add(storage_fee)
} else {
fee_info.base_fee.saturating_add(fee_info.sig_validator_fee)
let storage_fee = fee_info.storage_fee_per_byte * T::MaxSignatureLen::get().into();
fee_info
.base_fee
.saturating_add(fee_info.sig_validator_fee)
.saturating_add(storage_fee)
}
}

Expand Down
1 change: 1 addition & 0 deletions pallets/dkg/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ fn set_fees_works() {
dkg_validator_fee: 5,
sig_validator_fee: 5,
refresh_validator_fee: 5,
storage_fee_per_byte: 1,
};

// Dispatch a signed extrinsic.
Expand Down
8 changes: 8 additions & 0 deletions pallets/dkg/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub struct FeeInfo<Balance: MaxEncodedLen> {

/// The fee for refresh existing DKG.
pub refresh_validator_fee: Balance,

/// The storage fee per byts
pub storage_fee_per_byte: Balance,
}

impl<Balance: MaxEncodedLen> FeeInfo<Balance> {
Expand All @@ -58,4 +61,9 @@ impl<Balance: MaxEncodedLen> FeeInfo<Balance> {
pub fn get_sig_validator_fee(self) -> Balance {
self.sig_validator_fee
}

/// Get the storage fee per byte
pub fn get_storage_fee_per_byte(self) -> Balance {
self.storage_fee_per_byte
}
}
20 changes: 19 additions & 1 deletion pallets/jobs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub use weights::WeightInfo;
pub mod module {
use super::*;
use scale_info::prelude::fmt::Debug;
use sp_runtime::Saturating;
use tangle_primitives::roles::RoleType;

#[pallet::config]
Expand Down Expand Up @@ -213,6 +214,10 @@ pub mod module {
#[pallet::getter(fn next_job_id)]
pub type NextJobId<T: Config> = StorageValue<_, JobId, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn time_fee)]
pub type TimeFeePerBlock<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;

#[pallet::pallet]
pub struct Pallet<T>(_);

Expand Down Expand Up @@ -309,7 +314,12 @@ pub mod module {
ensure!(job.expiry > now, Error::<T>::JobAlreadyExpired);

// charge the user fee for job submission
let fee = T::JobToFee::job_to_fee(&job);
let processing_fee = T::JobToFee::job_to_fee(&job);
let ttl_u32: u32 =
job.ttl.try_into().map_err(|_| sp_runtime::ArithmeticError::Underflow)?;
let time_fee = Self::time_fee() * ttl_u32.into();
let fee = processing_fee.saturating_add(time_fee);

T::Currency::transfer(
&caller,
&Self::rewards_account_id(),
Expand Down Expand Up @@ -598,5 +608,13 @@ pub mod module {
Ok(())
})
}

#[pallet::call_index(5)]
#[pallet::weight(T::WeightInfo::withdraw_rewards())]
pub fn set_time_fee(origin: OriginFor<T>, new_fee: BalanceOf<T>) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;
TimeFeePerBlock::<T>::set(new_fee);
Ok(())
}
}
}
3 changes: 1 addition & 2 deletions pallets/jobs/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use frame_support::{
construct_runtime, parameter_types,
traits::{ConstU128, ConstU32, ConstU64, Contains, Everything},
};
use frame_system::EnsureSigned;
use pallet_session::historical as pallet_session_historical;
use sp_core::{
sr25519::{self},
Expand Down Expand Up @@ -352,7 +351,7 @@ parameter_types! {

impl Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ForceOrigin = EnsureSigned<AccountId>;
type ForceOrigin = frame_system::EnsureRoot<AccountId>;
type Currency = Balances;
type JobToFee = MockJobToFeeHandler;
type RolesHandler = Roles;
Expand Down
45 changes: 45 additions & 0 deletions pallets/jobs/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1397,3 +1397,48 @@ fn switch_active_independent_profile_to_shared_should_work_if_active_restake_sum
}
});
}

#[test]
fn test_fee_charged_for_jobs_submission() {
new_test_ext(vec![ALICE, BOB, CHARLIE, DAVE, EVE]).execute_with(|| {
System::set_block_number(1);

// setup time fees
assert_ok!(Jobs::set_time_fee(RuntimeOrigin::root(), 1));

let threshold_signature_role_type = ThresholdSignatureRoleType::ZengoGG20Secp256k1;

// all validators sign up in roles pallet
let profile = shared_profile();
for validator in [ALICE, BOB, CHARLIE, DAVE, EVE] {
assert_ok!(Roles::create_profile(
RuntimeOrigin::signed(mock_pub_key(validator)),
profile.clone()
));
}

Balances::make_free_balance_be(&mock_pub_key(TEN), 100);

let submission = JobSubmission {
expiry: 10,
ttl: 20,
job_type: JobType::DKGTSSPhaseOne(DKGTSSPhaseOneJobType {
participants: [ALICE, BOB, CHARLIE, DAVE, EVE]
.iter()
.map(|x| mock_pub_key(*x))
.collect::<Vec<_>>()
.try_into()
.unwrap(),
threshold: 3,
permitted_caller: Some(mock_pub_key(TEN)),
role_type: threshold_signature_role_type,
}),
};
assert_ok!(Jobs::submit_job(RuntimeOrigin::signed(mock_pub_key(TEN)), submission));

// Fees charged
// 1. 1unit per participant
// 2. 1unit per ttl block (20)
assert_eq!(Balances::free_balance(mock_pub_key(TEN)), 100 - 5 - 20);
});
}
12 changes: 10 additions & 2 deletions pallets/zksaas/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use super::*;
use crate::types::BalanceOf;
use frame_support::{pallet_prelude::DispatchResult, sp_runtime::Saturating};
use frame_system::pallet_prelude::BlockNumberFor;
use sp_core::crypto::ByteArray;
use sp_runtime::traits::Get;
use tangle_primitives::{jobs::*, verifier::*};

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -47,9 +49,15 @@ impl<T: Config> Pallet<T> {
let validator_count =
job.job_type.clone().get_participants().expect("checked_above").len();
let validator_fee = fee_info.circuit_fee * (validator_count as u32).into();
validator_fee.saturating_add(fee_info.base_fee)
let data_stored: usize = sp_core::ecdsa::Public::LEN * validator_count;
let storage_fee = fee_info.storage_fee_per_byte * (data_stored as u32).into();
validator_fee.saturating_add(fee_info.base_fee).saturating_add(storage_fee)
} else {
fee_info.base_fee.saturating_add(fee_info.get_prove_fee())
let storage_fee = fee_info.storage_fee_per_byte * T::MaxProofLen::get().into();
fee_info
.base_fee
.saturating_add(fee_info.get_prove_fee())
.saturating_add(storage_fee)
}
}

Expand Down
6 changes: 4 additions & 2 deletions pallets/zksaas/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ type F = ark_bn254::Fr;
#[test]
fn set_fees_works() {
new_test_ext().execute_with(|| {
let new_fee = FeeInfo { base_fee: 10, circuit_fee: 5, prove_fee: 5 };
let new_fee =
FeeInfo { base_fee: 10, circuit_fee: 5, prove_fee: 5, storage_fee_per_byte: 1 };

// should fail for non update origin
assert_noop!(ZKSaaS::set_fee(RuntimeOrigin::signed(10), new_fee.clone()), BadOrigin);
Expand All @@ -54,7 +55,8 @@ fn set_fees_works() {
#[test]
fn proof_verification_works() {
new_test_ext().execute_with(|| {
let new_fee = FeeInfo { base_fee: 10, circuit_fee: 5, prove_fee: 5 };
let new_fee =
FeeInfo { base_fee: 10, circuit_fee: 5, prove_fee: 5, storage_fee_per_byte: 1 };
// Dispatch a signed extrinsic.
assert_ok!(ZKSaaS::set_fee(RuntimeOrigin::signed(1), new_fee.clone()));

Expand Down
8 changes: 8 additions & 0 deletions pallets/zksaas/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ pub struct FeeInfo<Balance: MaxEncodedLen> {

/// The fee for Proof generation.
pub prove_fee: Balance,

/// The storage fee per byte
pub storage_fee_per_byte: Balance,
}

impl<Balance: MaxEncodedLen> FeeInfo<Balance> {
Expand All @@ -55,4 +58,9 @@ impl<Balance: MaxEncodedLen> FeeInfo<Balance> {
pub fn get_prove_fee(self) -> Balance {
self.prove_fee
}

/// Get the storage fee per byte
pub fn get_storage_fee_per_byte(self) -> Balance {
self.storage_fee_per_byte
}
}

0 comments on commit c4907e6

Please sign in to comment.