Skip to content

Commit

Permalink
Feature/clusters benchmarking (#159)
Browse files Browse the repository at this point in the history
- benchmarks for clusters
- weights for clusters
- extended node_provider_auth
- create staker

---------

Co-authored-by: aie0 <149175774+aie0@users.noreply.github.com>
  • Loading branch information
Raid5594 and aie0 authored Nov 28, 2023
1 parent df7b36e commit 0bd280b
Show file tree
Hide file tree
Showing 12 changed files with 732 additions and 174 deletions.
329 changes: 165 additions & 164 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions pallets/ddc-clusters/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
codec = { package = "parity-scale-codec", version = "3.1.5", 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" }
hex-literal = "^0.3.1"
Expand All @@ -18,6 +19,7 @@ sp-runtime = { default-features = false, git = "https://github.com/paritytech/su
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.31" }

[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-randomness-collective-flip = { 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" }
Expand All @@ -41,3 +43,10 @@ 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",
]
113 changes: 113 additions & 0 deletions pallets/ddc-clusters/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//! DdcStaking pallet benchmarking.

use ddc_primitives::{ClusterGovParams, ClusterId, ClusterParams, NodePubKey};
pub use frame_benchmarking::{
account, benchmarks, impl_benchmark_test_suite, whitelist_account, whitelisted_caller,
BenchmarkError,
};
use frame_system::RawOrigin;
use pallet_contracts::chain_extension::UncheckedFrom;
use sp_runtime::{AccountId32, Perbill};
use sp_std::prelude::*;
use testing_utils::*;

use super::*;
use crate::{cluster::ClusterProps, Pallet as DdcClusters};

const USER_SEED: u32 = 999666;
const USER_SEED_2: u32 = 999555;

benchmarks! {
where_clause { where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]> }

create_cluster {
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let cluster_params = ClusterParams { node_provider_auth_contract: Some(user.clone()) };
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,
};
}: _(RawOrigin::Root, cluster_id, user.clone(), user, cluster_params, cluster_gov_params)
verify {
assert!(Clusters::<T>::contains_key(cluster_id));
}

add_node {
let bytes = [0u8; 32];
let node_pub_key = NodePubKey::CDNPubKey(AccountId32::from(bytes));
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 1_000_000u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let _ = config_cluster_and_node::<T>(user.clone(), node_pub_key.clone(), cluster_id);
}: _(RawOrigin::Signed(user.clone()), cluster_id, node_pub_key.clone())
verify {
assert!(ClustersNodes::<T>::contains_key(cluster_id, node_pub_key));
}

remove_node {
let bytes = [0u8; 32];
let node_pub_key = NodePubKey::CDNPubKey(AccountId32::from(bytes));
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let balance = <T as pallet::Config>::Currency::minimum_balance() * 1_000_000u32.into();
let _ = <T as pallet::Config>::Currency::make_free_balance_be(&user, balance);
let _ = config_cluster_and_node::<T>(user.clone(), node_pub_key.clone(), cluster_id);
let _ = DdcClusters::<T>::add_node(
RawOrigin::Signed(user.clone()).into(),
cluster_id,
node_pub_key.clone()
);
}: _(RawOrigin::Signed(user.clone()), cluster_id, node_pub_key.clone())
verify {
assert!(!ClustersNodes::<T>::contains_key(cluster_id, node_pub_key));
}

set_cluster_params {
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let user_2 = account::<T::AccountId>("user", USER_SEED_2, 0u32);
let _ = config_cluster::<T>(user.clone(), cluster_id);
let new_cluster_params = ClusterParams { node_provider_auth_contract: Some(user_2.clone()) };
}: _(RawOrigin::Signed(user.clone()), cluster_id, new_cluster_params)
verify {
assert_eq!(Clusters::<T>::try_get(cluster_id).unwrap().props, ClusterProps { node_provider_auth_contract: Some(user_2) });
}

set_cluster_gov_params {
let cluster_id = ClusterId::from([1; 20]);
let user = account::<T::AccountId>("user", USER_SEED, 0u32);
let _ = config_cluster::<T>(user, cluster_id);
let new_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: 10u32.into(),
cdn_chill_delay: 5u32.into(),
cdn_unbonding_delay: 5u32.into(),
storage_bond_size: 10u32.into(),
storage_chill_delay: 5u32.into(),
storage_unbonding_delay: 5u32.into(),
unit_per_mb_stored: 1,
unit_per_mb_streamed: 1,
unit_per_put_request: 1,
unit_per_get_request: 1,
};
}: _(RawOrigin::Root, cluster_id, new_cluster_gov_params.clone())
verify {
assert_eq!(ClustersGovParams::<T>::try_get(cluster_id).unwrap(), new_cluster_gov_params);
}
}
28 changes: 22 additions & 6 deletions pallets/ddc-clusters/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
#![recursion_limit = "256"]
#![feature(is_some_and)] // ToDo: delete at rustc > 1.70

pub mod weights;
use crate::weights::WeightInfo;

#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;
#[cfg(any(feature = "runtime-benchmarks", test))]
pub mod testing_utils;

#[cfg(test)]
pub(crate) mod mock;
#[cfg(test)]
Expand All @@ -26,7 +34,7 @@ use ddc_primitives::{
};
use ddc_traits::{
cluster::{ClusterCreator, ClusterVisitor, ClusterVisitorError},
staking::{StakingVisitor, StakingVisitorError},
staking::{StakerCreator, StakingVisitor, StakingVisitorError},
};
use frame_support::{
assert_ok,
Expand Down Expand Up @@ -68,7 +76,9 @@ pub mod pallet {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
type NodeRepository: NodeRepository<Self>; // todo: get rid of tight coupling with nodes-pallet
type StakingVisitor: StakingVisitor<Self>;
type StakerCreator: StakerCreator<Self, BalanceOf<Self>>;
type Currency: LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;
type WeightInfo: WeightInfo;
}

#[pallet::event]
Expand Down Expand Up @@ -97,6 +107,8 @@ pub mod pallet {
/// Cluster candidate should not plan to chill.
NodeChillingIsProhibited,
NodeAuthContractCallFailed,
NodeAuthContractDeployFailed,
NodeAuthNodeAuthorizationNotSuccessful,
}

#[pallet::storage]
Expand Down Expand Up @@ -180,7 +192,7 @@ pub mod pallet {
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
#[pallet::weight(10_000)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::create_cluster())]
pub fn create_cluster(
origin: OriginFor<T>,
cluster_id: ClusterId,
Expand All @@ -199,7 +211,7 @@ pub mod pallet {
)
}

#[pallet::weight(10_000)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::add_node())]
pub fn add_node(
origin: OriginFor<T>,
cluster_id: ClusterId,
Expand Down Expand Up @@ -248,7 +260,7 @@ pub mod pallet {
Ok(())
}

#[pallet::weight(10_000)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::remove_node())]
pub fn remove_node(
origin: OriginFor<T>,
cluster_id: ClusterId,
Expand All @@ -269,7 +281,7 @@ pub mod pallet {
}

// Sets Governance non-sensetive parameters only
#[pallet::weight(10_000)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::set_cluster_params())]
pub fn set_cluster_params(
origin: OriginFor<T>,
cluster_id: ClusterId,
Expand All @@ -287,7 +299,7 @@ pub mod pallet {
}

// Requires Governance approval
#[pallet::weight(10_000)]
#[pallet::weight(<T as pallet::Config>::WeightInfo::set_cluster_gov_params())]
pub fn set_cluster_gov_params(
origin: OriginFor<T>,
cluster_id: ClusterId,
Expand Down Expand Up @@ -501,6 +513,10 @@ pub mod pallet {
match error {
NodeProviderAuthContractError::ContractCallFailed =>
Error::<T>::NodeAuthContractCallFailed,
NodeProviderAuthContractError::ContractDeployFailed =>
Error::<T>::NodeAuthContractDeployFailed,
NodeProviderAuthContractError::NodeAuthorizationNotSuccessful =>
Error::<T>::NodeAuthNodeAuthorizationNotSuccessful,
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion pallets/ddc-clusters/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![allow(dead_code)]

use ddc_primitives::{ClusterId, NodePubKey};
use ddc_traits::staking::{StakingVisitor, StakingVisitorError};
use ddc_traits::staking::{StakerCreator, StakingVisitor, StakingVisitorError};
use frame_support::{
construct_runtime, parameter_types,
traits::{ConstU32, ConstU64, Everything, Nothing},
Expand Down Expand Up @@ -190,11 +190,15 @@ impl crate::pallet::Config for Test {
type Currency = Balances;
type NodeRepository = DdcNodes;
type StakingVisitor = TestStakingVisitor;
type StakerCreator = TestStaker;
type WeightInfo = ();
}

pub(crate) type DdcStakingCall = crate::Call<Test>;
pub(crate) type TestRuntimeCall = <Test as frame_system::Config>::RuntimeCall;
pub struct TestStakingVisitor;
pub struct TestStaker;

impl<T: Config> StakingVisitor<T> for TestStakingVisitor {
fn has_activated_stake(
_node_pub_key: &NodePubKey,
Expand All @@ -210,6 +214,18 @@ impl<T: Config> StakingVisitor<T> for TestStakingVisitor {
}
}

impl<T: Config> StakerCreator<T, BalanceOf<T>> for TestStaker {
fn bond_stake_and_participate(
_stash: T::AccountId,
_controller: T::AccountId,
_node: NodePubKey,
_value: BalanceOf<T>,
_cluster_id: ClusterId,
) -> sp_runtime::DispatchResult {
Ok(())
}
}

pub struct ExtBuilder;

impl ExtBuilder {
Expand Down
74 changes: 72 additions & 2 deletions pallets/ddc-clusters/src/node_provider_auth.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use codec::Encode;
use ddc_primitives::{NodePubKey, NodeType};
use frame_support::weights::Weight;
use hex_literal::hex;
use pallet_contracts::chain_extension::UncheckedFrom;
use sp_std::prelude::Vec;
use sp_runtime::traits::Hash;
use sp_std::{prelude::Vec, vec};

use crate::Config;

Expand All @@ -17,7 +19,7 @@ const EXTENSION_CALL_GAS_LIMIT: Weight =
Weight::from_ref_time(5_000_000_000_000).set_proof_size(u64::MAX);

pub struct NodeProviderAuthContract<T: Config> {
contract_id: T::AccountId,
pub contract_id: T::AccountId,
caller_id: T::AccountId,
}

Expand Down Expand Up @@ -61,11 +63,79 @@ where
Ok(is_authorized)
}

pub fn deploy_contract(
&self,
caller_id: T::AccountId,
) -> Result<Self, NodeProviderAuthContractError> {
pub const CTOR_SELECTOR: [u8; 4] = hex!("9bae9d5e");

fn encode_constructor() -> Vec<u8> {
let mut call_data = CTOR_SELECTOR.to_vec();
let x = 0_u128;
for _ in 0..9 {
x.encode_to(&mut call_data);
}
call_data
}

// Load the contract code.
let wasm = &include_bytes!("./test_data/node_provider_auth_white_list.wasm")[..];
let _wasm_hash = <T as frame_system::Config>::Hashing::hash(wasm);
let contract_args = encode_constructor();

// Deploy the contract.
let contract_id = pallet_contracts::Pallet::<T>::bare_instantiate(
caller_id.clone(),
Default::default(),
EXTENSION_CALL_GAS_LIMIT,
None,
wasm.into(),
contract_args,
vec![],
false,
)
.result
.map_err(|_| NodeProviderAuthContractError::ContractDeployFailed)?
.account_id;

Ok(Self::new(contract_id, caller_id))
}

pub fn authorize_node(
&self,
node_pub_key: NodePubKey,
) -> Result<bool, NodeProviderAuthContractError> {
pub const ADD_DDC_NODE_SELECTOR: [u8; 4] = hex!("7a04093d");

let call_data = {
// is_authorized(node_provider: AccountId, node: Vec<u8>, node_variant: u8) -> bool
let args: ([u8; 4], Vec<u8>) =
(ADD_DDC_NODE_SELECTOR, node_pub_key.encode()[1..].to_vec());
args.encode()
};

let _ = pallet_contracts::Pallet::<T>::bare_call(
self.caller_id.clone(),
self.contract_id.clone(),
Default::default(),
EXTENSION_CALL_GAS_LIMIT,
None,
call_data,
false,
)
.result
.map_err(|_| NodeProviderAuthContractError::NodeAuthorizationNotSuccessful)?;

Ok(true)
}

pub fn new(contract_id: T::AccountId, caller_id: T::AccountId) -> Self {
Self { contract_id, caller_id }
}
}

pub enum NodeProviderAuthContractError {
ContractCallFailed,
ContractDeployFailed,
NodeAuthorizationNotSuccessful,
}
Loading

0 comments on commit 0bd280b

Please sign in to comment.