Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/customers benchmarking #149

Merged
merged 12 commits into from
Nov 22, 2023
3 changes: 3 additions & 0 deletions Cargo.lock

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

28 changes: 1 addition & 27 deletions pallets/ddc-clusters/src/cluster.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::pallet::Error;
use codec::{Decode, Encode};
use ddc_primitives::ClusterId;
use ddc_primitives::{ClusterId, ClusterParams};
use frame_support::{pallet_prelude::*, parameter_types};
use scale_info::TypeInfo;
use sp_runtime::Perbill;

parameter_types! {
pub MaxClusterParamsLen: u16 = 2048;
Expand All @@ -22,31 +21,6 @@ pub struct ClusterProps<AccountId> {
pub node_provider_auth_contract: AccountId,
}

// ClusterParams includes Governance non-sensetive parameters only
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)]
pub struct ClusterParams<AccountId> {
pub node_provider_auth_contract: AccountId,
}

// ClusterGovParams includes Governance sensetive parameters
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)]
#[scale_info(skip_type_params(Balance, BlockNumber, T))]
pub struct ClusterGovParams<Balance, BlockNumber> {
pub treasury_share: Perbill,
pub validators_share: Perbill,
pub cluster_reserve_share: Perbill,
pub cdn_bond_size: Balance,
pub cdn_chill_delay: BlockNumber,
pub cdn_unbonding_delay: BlockNumber,
pub storage_bond_size: Balance,
pub storage_chill_delay: BlockNumber,
pub storage_unbonding_delay: BlockNumber,
pub unit_per_mb_stored: u128,
pub unit_per_mb_streamed: u128,
pub unit_per_put_request: u128,
pub unit_per_get_request: u128,
}

impl<AccountId> Cluster<AccountId> {
pub fn new(
cluster_id: ClusterId,
Expand Down
69 changes: 55 additions & 14 deletions pallets/ddc-clusters/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ pub(crate) mod mock;
mod tests;

use crate::{
cluster::{Cluster, ClusterGovParams, ClusterParams},
cluster::Cluster,
node_provider_auth::{NodeProviderAuthContract, NodeProviderAuthContractError},
};
use ddc_primitives::{ClusterId, ClusterPricingParams, NodePubKey, NodeType};
use ddc_primitives::{
ClusterGovParams, ClusterId, ClusterParams, ClusterPricingParams, NodePubKey, NodeType,
};
use ddc_traits::{
cluster::{ClusterVisitor, ClusterVisitorError},
cluster::{ClusterCreator, ClusterVisitor, ClusterVisitorError},
staking::{StakingVisitor, StakingVisitorError},
};
use frame_support::{
Expand All @@ -39,7 +41,7 @@ use pallet_ddc_nodes::{NodeRepository, NodeTrait};
use sp_runtime::SaturatedConversion;
use sp_std::prelude::*;

mod cluster;
pub mod cluster;
mod node_provider_auth;

/// The balance type of this pallet.
Expand Down Expand Up @@ -129,16 +131,13 @@ pub mod pallet {
cluster_gov_params: ClusterGovParams<BalanceOf<T>, T::BlockNumber>,
) -> DispatchResult {
ensure_root(origin)?; // requires Governance approval
let cluster =
Cluster::new(cluster_id, cluster_manager_id, cluster_reserve_id, cluster_params)
.map_err(Into::<Error<T>>::into)?;
ensure!(!Clusters::<T>::contains_key(cluster_id), Error::<T>::ClusterAlreadyExists);

Clusters::<T>::insert(cluster_id, cluster);
ClustersGovParams::<T>::insert(cluster_id, cluster_gov_params);
Self::deposit_event(Event::<T>::ClusterCreated { cluster_id });

Ok(())
Self::do_create_clusters(
cluster_id,
cluster_manager_id,
cluster_reserve_id,
cluster_params,
cluster_gov_params,
)
}

#[pallet::weight(10_000)]
Expand Down Expand Up @@ -247,6 +246,27 @@ pub mod pallet {
}
}

impl<T: Config> Pallet<T> {
pub fn do_create_clusters(
Raid5594 marked this conversation as resolved.
Show resolved Hide resolved
cluster_id: ClusterId,
cluster_manager_id: T::AccountId,
cluster_reserve_id: T::AccountId,
cluster_params: ClusterParams<T::AccountId>,
cluster_gov_params: ClusterGovParams<BalanceOf<T>, T::BlockNumber>,
) -> DispatchResult {
let cluster =
Cluster::new(cluster_id, cluster_manager_id, cluster_reserve_id, cluster_params)
.map_err(Into::<Error<T>>::into)?;
ensure!(!Clusters::<T>::contains_key(cluster_id), Error::<T>::ClusterAlreadyExists);

Clusters::<T>::insert(cluster_id, cluster);
ClustersGovParams::<T>::insert(cluster_id, cluster_gov_params);
Self::deposit_event(Event::<T>::ClusterCreated { cluster_id });

Ok(())
}
}

impl<T: Config> ClusterVisitor<T> for Pallet<T> {
fn cluster_has_node(cluster_id: &ClusterId, node_pub_key: &NodePubKey) -> bool {
ClustersNodes::<T>::get(cluster_id, node_pub_key).is_some()
Expand Down Expand Up @@ -309,6 +329,27 @@ pub mod pallet {
}
}

impl<T: Config> ClusterCreator<T, BalanceOf<T>> for Pallet<T>
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
fn create_new_cluster(
cluster_id: ClusterId,
cluster_manager_id: T::AccountId,
cluster_reserve_id: T::AccountId,
cluster_params: ClusterParams<T::AccountId>,
cluster_gov_params: ClusterGovParams<BalanceOf<T>, T::BlockNumber>,
) -> DispatchResult {
Self::do_create_clusters(
cluster_id,
cluster_manager_id,
cluster_reserve_id,
cluster_params,
cluster_gov_params,
)
}
}

impl<T> From<StakingVisitorError> for Error<T> {
fn from(error: StakingVisitorError) -> Self {
match error {
Expand Down
4 changes: 2 additions & 2 deletions pallets/ddc-clusters/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Tests for the module.

use super::{mock::*, *};
use ddc_primitives::{ClusterId, NodePubKey};
use ddc_primitives::{ClusterId, ClusterParams, NodePubKey};
use frame_support::{assert_noop, assert_ok, error::BadOrigin};
use frame_system::Config;
use hex_literal::hex;
Expand Down Expand Up @@ -166,7 +166,7 @@ fn add_and_delete_node_works() {
assert_ok!(DdcClusters::set_cluster_params(
RuntimeOrigin::signed(AccountId::from([1; 32])),
ClusterId::from([1; 20]),
cluster::ClusterParams { node_provider_auth_contract: contract_id },
ClusterParams { node_provider_auth_contract: contract_id },
));

// Node doesn't exist
Expand Down
25 changes: 20 additions & 5 deletions pallets/ddc-customers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@ version = "0.1.0"
edition = "2021"

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
ddc-primitives = { version = "0.1.0", default-features = false, path = "../../primitives" }
ddc-traits = { version = "0.1.0", default-features = false, path = "../../traits" }
frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31", optional = true }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
log = { version = "0.4.17", default-features = false }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }

# 3rd Party
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
log = { version = "0.4.17", default-features = false }
rand_chacha = { version = "0.2", default-features = false, optional = true }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }

# Cere
ddc-primitives = { version = "0.1.0", default-features = false, path = "../../primitives" }
ddc-traits = { version = "0.1.0", default-features = false, path = "../../traits" }

[dev-dependencies]
frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }
Expand All @@ -29,7 +36,15 @@ std = [
"ddc-primitives/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking?/std",
"scale-info/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = [
"ddc-primitives/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
153 changes: 153 additions & 0 deletions pallets/ddc-customers/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
//! DdcStaking pallet benchmarking.
#![cfg(feature = "runtime-benchmarks")]

use super::*;
use crate::Pallet as DdcCustomers;
use ddc_primitives::{ClusterGovParams, ClusterId, ClusterParams};
use frame_benchmarking::{account, benchmarks, whitelist_account};
use frame_support::traits::Currency;
use sp_runtime::Perbill;
use sp_std::prelude::*;

pub type BalanceOf<T> =
<<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

use frame_system::{Pallet as System, RawOrigin};

const USER_SEED: u32 = 999666;

benchmarks! {
create_bucket {
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);

let cluster_gov_params: ClusterGovParams<BalanceOf<T>, T::BlockNumber> = ClusterGovParams {
treasury_share: Perbill::default(),
validators_share: Perbill::default(),
cluster_reserve_share: Perbill::default(),
cdn_bond_size: 100u32.into(),
cdn_chill_delay: 50u32.into(),
cdn_unbonding_delay: 50u32.into(),
storage_bond_size: 100u32.into(),
storage_chill_delay: 50u32.into(),
storage_unbonding_delay: 50u32.into(),
unit_per_mb_stored: 10,
unit_per_mb_streamed: 10,
unit_per_put_request: 10,
unit_per_get_request: 10,
};

let _ = <T as pallet::Config>::ClusterCreator::create_new_cluster(
ClusterId::from([1; 20]),
user.clone(),
user.clone(),
ClusterParams { node_provider_auth_contract: user.clone() },
cluster_gov_params
);

whitelist_account!(user);
}: _(RawOrigin::Signed(user), cluster_id)
verify {
assert_eq!(Pallet::<T>::buckets_count(), 1);
}

deposit {
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 100u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let amount = <T as pallet::Config>::Currency::minimum_balance() * 50u32.into();

whitelist_account!(user);
}: _(RawOrigin::Signed(user.clone()), amount)
verify {
assert!(Ledger::<T>::contains_key(user));
}

deposit_extra {
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 200u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let amount = <T as pallet::Config>::Currency::minimum_balance() * 50u32.into();

let _ = DdcCustomers::<T>::deposit(RawOrigin::Signed(user.clone()).into(), amount);

whitelist_account!(user);
}: _(RawOrigin::Signed(user.clone()), amount)
verify {
assert!(Ledger::<T>::contains_key(user));
}

unlock_deposit {
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 200u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let amount = <T as pallet::Config>::Currency::minimum_balance() * 50u32.into();

let _ = DdcCustomers::<T>::deposit(RawOrigin::Signed(user.clone()).into(), amount);

whitelist_account!(user);
}: unlock_deposit(RawOrigin::Signed(user.clone()), amount)
verify {
assert!(Ledger::<T>::contains_key(user));
}

// Worst case scenario, 31/32 chunks unlocked after the unlocking duration
withdraw_unlocked_deposit_update {

System::<T>::set_block_number(1u32.into());

let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 2000u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let amount = <T as pallet::Config>::Currency::minimum_balance() * 32u32.into();

let _ = DdcCustomers::<T>::deposit(RawOrigin::Signed(user.clone()).into(), amount);

for _k in 1 .. 32 {
let _ = DdcCustomers::<T>::unlock_deposit(RawOrigin::Signed(user.clone()).into(), <T as pallet::Config>::Currency::minimum_balance() * 1u32.into());
}

System::<T>::set_block_number(5256001u32.into());

whitelist_account!(user);
}: withdraw_unlocked_deposit(RawOrigin::Signed(user.clone()))
verify {
let ledger = Ledger::<T>::try_get(user).unwrap();
assert_eq!(ledger.active, amount / 32u32.into());
}

// Worst case scenario, everything is removed after the unlocking duration
withdraw_unlocked_deposit_kill {

System::<T>::set_block_number(1u32.into());

let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let user2 = account::<T::AccountId>("user", USER_SEED, 1u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 2000u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user2, balance);
let amount = <T as pallet::Config>::Currency::minimum_balance() * 32u32.into();

let _ = DdcCustomers::<T>::deposit(RawOrigin::Signed(user.clone()).into(), amount);
// To keep the balance of pallet positive
let _ = DdcCustomers::<T>::deposit(RawOrigin::Signed(user2).into(), amount);


for _k in 1 .. 33 {
let _ = DdcCustomers::<T>::unlock_deposit(RawOrigin::Signed(user.clone()).into(), <T as pallet::Config>::Currency::minimum_balance() * 1u32.into());
}

System::<T>::set_block_number(5256001u32.into());

whitelist_account!(user);
}: withdraw_unlocked_deposit(RawOrigin::Signed(user.clone()))
verify {
assert!(!Ledger::<T>::contains_key(user));
}

impl_benchmark_test_suite!(
DdcCustomers,
crate::mock::ExtBuilder.build(),
crate::mock::Test,
);
}
Loading
Loading