You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Substrate基准测试中注册密钥库扩展或生成密钥对?

解决方案:在Pallet基准测试中生成密钥对

方法一:无需密钥库的确定性密钥对生成

如果不需要动态生成密钥对,使用固定种子创建密钥对是最简单的方案,无需依赖密钥库或std环境。

步骤

  1. 确保依赖特性开启:在Cargo.toml中,为runtime-benchmarking特性添加sp-core/full-crypto支持:
[features]
runtime-benchmarking = [
    "frame-benchmarking/runtime-benchmarking",
    "sp-core/full-crypto",
    "sp-runtime/runtime-benchmarking",
    # 其他你的pallet所需的基准测试依赖
]
  1. 在基准测试中生成密钥对:使用Pair::from_seed方法从固定种子创建密钥对:
// 你的pallet基准测试代码中
use sp_core::sr25519::Pair;
use sp_runtime::traits::IdentifyAccount;

benchmark! {
    name: TransferWithPreGeneratedKey;
    setup: {
        // 使用固定32字节种子生成密钥对
        let seed = [0x2a; 32];
        let pair = Pair::from_seed(&seed);
        let sender = pair.public().into_account();
        
        // 为测试账户充值(如果需要)
        frame_system::Pallet::<T>::set_balance(&sender, 1_000_000_000_000);
        let recipient = <T::AccountId as Default>::default();
    };
    execute: {
        // 在基准测试逻辑中使用生成的账户
        Pallet::<T>::transfer(Origin::signed(sender), recipient, 1000)?;
    };
}
  1. 生成多组唯一密钥对:如果需要多个不同账户,可以通过递增种子值实现:
// 生成第n个唯一密钥对
let seed = [n as u8; 32];
let pair = Pair::from_seed(&seed);

方法二:在基准测试外部环境中注入测试密钥库

如果必须使用RuntimeAppPublic::generate_pair方法,可以通过自定义外部环境注册内存密钥库。

步骤

  1. 自定义基准测试外部环境:在runtime的benchmarking.rs中创建包含密钥库的外部环境:
use sp_keystore::{Keystore, KeystorePtr, KeystoreExt};
use frame_benchmarking::BenchmarkingSetup;
use sp_externalities::ExternalitiesExt;

pub struct RuntimeBenchmarkSetup;

impl BenchmarkingSetup<Runtime> for RuntimeBenchmarkSetup {
    fn setup() -> sp_externalities::TestExternalities {
        let mut ext = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
        
        // 创建内存密钥库
        let keystore = Keystore::in_memory();
        let keystore_ptr = KeystorePtr::new(keystore);
        
        // 注册密钥库扩展到外部环境
        ext.register_extension(KeystoreExt(keystore_ptr));
        
        sp_externalities::TestExternalities::new(ext)
    }
}
  1. 在基准测试中使用密钥库生成密钥对:
// 你的pallet基准测试代码中
use sp_keystore::KeystoreExt;
use sp_runtime::traits::RuntimeAppPublic;

benchmark! {
    name: DynamicKeyPairGeneration;
    setup: {
        // 从外部环境中获取密钥库
        let keystore = sp_externalities::with_context(|ext| {
            ext.get::<KeystoreExt>().unwrap().clone()
        });
        
        // 使用密钥库生成新密钥对
        let (public_key, _) = <T::AccountId as sp_runtime::traits::AccountId>::Public::generate_pair(Some(&*keystore));
        let account_id = public_key.into_account();
    };
    execute: {
        // 使用生成的账户执行基准测试逻辑
        Pallet::<T>::protected_call(Origin::signed(account_id), args)?;
    };
}

注意事项

  • 确定性密钥对方案更适合基准测试,因为它能保证每次运行的输入一致,便于性能对比。
  • 内存密钥库仅在基准测试过程中存在,不会持久化任何数据。

内容的提问来源于stack exchange,提问作者Ju Piece

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:30:50