Rust提名池性能基准测试库pallet-nomination-pools-benchmarking的使用,优化Substrate链上质押池性能评估
以下是根据您提供的内容整理的完整示例demo,展示了如何使用pallet-nomination-pools-benchmarking库来评估Substrate链上质押池的性能:
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite};
use frame_system::RawOrigin;
use pallet_nomination_pools::{BondExtra, Pallet as Pools};
use pallet_nomination_pools::Config as PoolsConfig;
use pallet_nomination_pools_benchmarking::Pallet as PoolsBench;
// 生成验证人账户的辅助函数
fn generate_validator<T: PoolsConfig>(index: u32) -> T::AccountId {
let account = frame_benchmarking::account("validator", index, 0);
account.into()
}
benchmarks! {
// 基准测试:创建新的提名池
create {
let caller: T::AccountId = whitelisted_caller();
let amount = T::Currency::minimum_balance() * 10u32.into();
T::Currency::make_free_balance_be(&caller, amount);
}: _(RawOrigin::Signed(caller), amount)
verify {
// 验证池是否创建成功
assert_eq!(Pools::<T>::last_pool_id(), 1u32.into());
}
// 基准测试:提名验证人
nominate {
let n in 1 .. T::MaxNominations::get();
let caller: T::AccountId = whitelisted_caller();
let amount = T::Currency::minimum_balance() * 10u32.into();
T::Currency::make_free_balance_be(&caller, amount);
let pool_id = Pools::<T>::create(RawOrigin::Signed(caller.clone()).into(), amount)?;
let validators = (0..n).map(|i| generate_validator::<T>(i)).collect::<Vec<_>>();
}: _(RawOrigin::Signed(caller), pool_id, validators)
verify {
// 验证提名操作是否成功
assert!(Pools::<T>::nominations(pool_id).is_some());
}
// 基准测试:质押更多资金
bond_extra {
let caller: T::AccountId = whitelisted_caller();
let initial_amount = T::Currency::minimum_balance() * 10u32.into();
let extra_amount = T::Currency::minimum_balance() * 5u32.into();
T::Currency::make_free_balance_be(&caller, initial_amount + extra_amount);
let pool_id = Pools::<T>::create(RawOrigin::Signed(caller.clone()).into(), initial_amount)?;
}: _(RawOrigin::Signed(caller), BondExtra::FreeBalance(extra_amount))
verify {
// 验证质押金额是否正确增加
let member = Pools::<T>::pool_members(&caller).unwrap();
assert_eq!(member.points, initial_amount + extra_amount);
}
// 基准测试:解绑质押资金
unbond {
let caller: T::AccountId = whitelisted_caller();
let amount = T::Currency::minimum_balance() * 10u32.into();
T::Currency::make_free_balance_be(&caller, amount * 2u32.into());
let pool_id = Pools::<T>::create(RawOrigin::Signed(caller.clone()).into(), amount)?;
}: _(RawOrigin::Signed(caller), pool_id, amount)
verify {
// 验证解绑操作是否成功
let member = Pools::<T>::pool_members(&caller).unwrap();
assert!(member.unbonding_eras.len() > 0);
}
}
impl_benchmark_test_suite!(
PoolsBench,
crate::mock::new_test_ext(),
crate::mock::Test,
);
这个完整示例在原有基础上增加了:
- 解绑质押资金的基准测试
- 每个基准测试的验证逻辑
- 生成验证人账户的辅助函数
- 更完整的类型导入
使用该库可以全面评估提名池的各种操作性能,包括创建、提名、质押和解绑等关键操作。建议在测试环境中运行这些基准测试,并根据结果优化链上参数配置。
1 回复
Rust提名池性能基准测试库pallet-nomination-pools-benchmarking使用指南
概述
pallet-nomination-pools-benchmarking
是Substrate框架中的一个专用库,用于对提名池(pallet-nomination-pools)进行性能基准测试。该库帮助开发者评估和优化Substrate链上质押池的性能表现,确保网络在高负载下仍能保持稳定运行。
主要功能
- 提供标准化的提名池操作基准测试
- 测量不同操作在链上的执行时间和资源消耗
- 帮助确定合理的权重(weights)参数
- 评估不同硬件配置下的性能表现
使用方法
1. 添加依赖
首先需要在runtime的Cargo.toml中添加基准测试依赖:
[dev-dependencies]
pallet-nomination-pools-benchmarking = { version = "4.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-vX.Y.Z" }
2. 配置基准测试
在runtime的benchmarking模块中配置提名池基准测试:
#[cfg(feature = "runtime-benchmarks")]
mod benches {
use super::*;
use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
impl pallet_nomination_pools_benchmarking::Config for Runtime {}
frame_benchmarking::benchmarks! {
join_pool {
// 基准测试代码
}
// 其他操作基准测试
}
}
3. 运行基准测试
使用Substrate的benchmark子命令运行测试:
./target/release/your-node benchmark pallet \
--chain=dev \
--execution=wasm \
--wasm-execution=compiled \
--pallet=pallet_nomination_pools \
--extrinsic="*" \
--steps=50 \
--repeat=20 \
--output=./pallets/nomination-pools/src/weights.rs
4. 常见基准测试示例
加入质押池基准测试
join_pool {
let caller: T::AccountId = whitelisted_caller();
let bond = 100 * DOLLARS;
let pool_id = Pools::<T>::create(bond, caller.clone()).unwrap();
}: _(RawOrigin::Signed(caller), pool_id, bond)
创建新池基准测试
create {
let caller: T::AccountId = whitelisted_caller();
let bond = 100 * DOLLARS;
}: _(RawOrigin::Signed(caller), bond)
提名基准测试
nominate {
let n in 1 .. MAX_VALIDATORS;
let caller: T::AccountId = whitelisted_caller();
let bond = 100 * DOLLARS;
let pool_id = Pools::<T>::create(b bond, caller.clone()).unwrap();
let validators = create_validators::<T>(n);
frame_system::Pallet::<T>::set_block_number(1u32.into());
}: _(RawOrigin::Signed(caller), pool_id, validators)
完整示例代码
以下是一个完整的提名池基准测试示例,包含创建池、加入池和提名验证人等操作:
// runtime/src/benchmarking.rs
#[cfg(feature = "runtime-benchmarks")]
mod nomination_pools_benchmarking {
use super::*;
use frame_benchmarking::{benchmarks, whitelisted_caller};
use frame_system::RawOrigin;
use pallet_nomination_pools::Pallet as Pools;
// 实现配置trait
impl pallet_nomination_pools_benchmarking::Config for Runtime {}
// 定义基准测试模块
benchmarks! {
// 创建新池的基准测试
create {
// 创建白名单调用者账户
let caller: T::AccountId = whitelisted_caller();
// 设置质押金额
let bond = 100 * DOLLARS;
}: _(RawOrigin::Signed(caller), bond)
// 加入质押池的基准测试
join_pool {
let caller: T::AccountId = whitelisted_caller();
let bond = 100 * DOLLARS;
// 先创建一个池
let pool_id = Pools::<T>::create(bond, caller.clone()).unwrap();
}: _(RawOrigin::Signed(caller), pool_id, bond)
// 提名验证人的基准测试
nominate {
// n的范围从1到最大验证人数
let n in 1 .. MAX_VALIDATORS;
let caller: T::AccountId = whitelisted_caller();
let bond = 100 * DOLLARS;
// 创建池
let pool_id = Pools::<T>::create(bond, caller.clone()).unwrap();
// 创建n个验证人
let validators = create_validators::<T>(n);
// 设置区块号
frame_system::Pallet::<T>::set_block_number(1u32.into());
}: _(RawOrigin::Signed(caller), pool_id, validators)
// 其他操作可以继续添加...
}
// 辅助函数,创建指定数量的验证人
fn create_validators<T: Config>(count: u32) -> Vec<T::AccountId> {
(0..count).map(|i| account("validator", i, 0)).collect()
}
}
优化建议
- 权重校准:根据基准测试结果调整操作权重,确保区块处理时间合理
- 硬件评估:在不同硬件配置上运行测试,确定最优节点配置
- 参数调优:根据测试结果调整链上参数如:
- 最大池数量
- 最大池成员数
- 最大验证人提名数
- 监控关键指标:重点关注:
- 执行时间
- 存储读写次数
- 内存使用情况
输出解释
基准测试完成后,会生成类似以下输出:
Pallet: "pallet_nomination_pools", Extrinsic: "join_pool", Lowest values: [], Highest values: [], Steps: 50, Repeat: 20
Raw Storage Info:
Storage: NominationPools PoolMembers (r:1, w:1)
Storage: NominationPools CounterForPoolMembers (r:1, w:1)
Storage: System Account (r:1, w:1)
Storage: Balances Locks (r:1, w:1)
Storage: NominationPools BondedPools (r:1, w:0)
Storage: NominationPools RewardPools (r:1, w:0)
Median Slopes Analysis
Extrinsic Time: 123.456 µs
Storage Reads: 5
Storage Writes: 3
通过这些数据可以评估操作的成本并相应调整链参数。
注意事项
- 基准测试应在与生产环境相似的硬件上运行
- 测试数据应覆盖各种边界情况
- 定期重新运行基准测试,特别是在Substrate版本升级后
- 考虑网络延迟和IO性能对实际运行的影响