Rust区块链开发库cumulus-primitives-aura的使用:支持Substrate共识机制与Aura协议的高效集成
Rust区块链开发库cumulus-primitives-aura的使用:支持Substrate共识机制与Aura协议的高效集成
安装
在项目目录中运行以下Cargo命令:
cargo add cumulus-primitives-aura
或者在Cargo.toml中添加以下行:
cumulus-primitives-aura = "0.19.0"
使用示例
以下是cumulus-primitives-aura库的使用示例,展示了如何集成Aura共识机制到Substrate区块链中:
use cumulus_primitives_aura::{AuraUnincludedSegmenter, AuraConsensusDataProvider};
use sc_consensus_aura::{ImportQueueParams, SlotProportion, AuraImportQueue};
use sp_consensus_aura::sr25519::{AuthorityPair, AuthorityId};
use sc_service::{Configuration, TaskManager};
use std::sync::Arc;
// 创建Aura共识的导入队列
pub fn create_aura_import_queue(
config: &Configuration,
client: Arc<Client>,
task_manager: &TaskManager,
) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error> {
let slot_duration = cumulus_primitives_aura::slot_duration(&config.chain_spec)?;
AuraImportQueue::<Block, _, _, _>::new(
ImportQueueParams {
block_import: client.clone(),
justification_import: Some(client.clone()),
client: client.clone(),
create_inherent data_providers: move |_, ()| async move {
Ok(())
},
spawner: &task_manager.spawn_essential_handle(),
registry: config.prometheus_registry(),
check_for_equivocation: Default::default(),
telemetry: None,
slot_duration,
// 设置验证者比例
validator_proportion: SlotProportion::new(2f32 / 3f32),
}
)
}
// 创建Aura共识数据提供者
pub fn aura_consensus_data_provider(
client: Arc<Client>,
public_key: AuthorityId,
) -> Box<dyn ProvideConsensusData<Block>> {
Box::new(AuraConsensusDataProvider::new(client, public_key))
}
// 设置Aura未包含段分割器
pub fn aura_unincluded_segmenter() -> Box<dyn UnincludedSegmenter<Block>> {
Box::new(AuraUnincludedSegmenter::new())
}
完整示例代码
use cumulus_primitives_aura::{AuraUnincludedSegmenter, AuraConsensusDataProvider};
use sc_consensus_aura::{ImportQueueParams, SlotProportion, AuraImportQueue};
use sp_consensus_aura::sr25519::{AuthorityPair, AuthorityId};
use sc_service::{Configuration, TaskManager};
use std::sync::Arc;
use sp_runtime::traits::Block as BlockT;
use sc_client_api::backend::Backend;
// 假设我们有以下类型定义
type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
type Client = sc_service::client::Client<Backend>;
type Header = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
// 创建完整的Aura共识服务
pub fn create_aura_consensus_service(
config: &Configuration,
client: Arc<Client>,
task_manager: &TaskManager,
public_key: AuthorityId,
) -> Result<(
Box<dyn sc_consensus::ImportQueue<Block>>,
Box<dyn ProvideConsensusData<Block>>,
Box<dyn UnincludedSegmenter<Block>>,
), sc_service::Error> {
// 创建Aura导入队列
let import_queue = create_aura_import_queue(config, client.clone(), task_manager)?;
// 创建Aura共识数据提供者
let consensus_data_provider = aura_consensus_data_provider(client.clone(), public_key);
// 创建Aura未包含段分割器
let unincluded_segmenter = aura_unincluded_segmenter();
Ok((import_queue, consensus_data_provider, unincluded_segmenter))
}
// 创建Aura共识的导入队列
pub fn create_aura_import_queue(
config: &Configuration,
client: Arc<Client>,
task_manager: &TaskManager,
) -> Result<sc_consensus::DefaultImportQueue<Block>, sc_service::Error> {
let slot_duration = cumulus_primitives_aura::slot_duration(&config.chain_spec)?;
AuraImportQueue::<Block, _, _, _>::new(
ImportQueueParams {
block_import: client.clone(),
justification_import: Some(client.clone()),
client: client.clone(),
create_inherent_data_providers: move |_, ()| async move {
Ok(())
},
spawner: &task_manager.spawn_essential_handle(),
registry: config.prometheus_registry(),
check_for_equivocation: Default::default(),
telemetry: None,
slot_duration,
// 设置验证者比例
validator_proportion: SlotProportion::new(2f32 / 3f32),
}
)
}
// 创建Aura共识数据提供者
pub fn aura_consensus_data_provider(
client: Arc<Client>,
public_key: AuthorityId,
) -> Box<dyn ProvideConsensusData<Block>> {
Box::new(AuraConsensusDataProvider::new(client, public_key))
}
// 设置Aura未包含段分割器
pub fn aura_unincluded_segmenter() -> Box<dyn UnincludedSegmenter<Block>> {
Box::new(AuraUnincludedSegmenter::new())
}
功能说明
- AuraUnincludedSegmenter:用于处理未包含在最终链中的区块段
- AuraConsensusDataProvider:提供Aura共识所需的数据
- slot_duration:获取区块链的slot持续时间
- ImportQueueParams:配置Aura导入队列的参数
许可证
Apache-2.0
1 回复
Rust区块链开发库cumulus-primitives-aura的使用指南
以下是基于您提供内容的完整示例demo:
完整平行链runtime集成示例
//! 平行链runtime集成Aura共识的完整示例
use frame_support::{
construct_runtime, parameter_types,
traits::{Contains, KeyOwnerProofSystem, Randomness},
weights::Weight,
};
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_runtime::{
traits::{Block as BlockT, IdentifyAccount, Verify},
Perbill,
};
use cumulus_primitives_aura::{AuraUnincludedSegment, InherentDataProvider};
// 1. 定义runtime宏
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
Aura: pallet_aura,
// 其他pallet...
}
);
// 2. 配置Aura参数
parameter_types! {
pub const BlockHashCount: u32 = 250;
pub const AuraSlotDuration: u64 = 6000; // 6秒一个slot
pub const BlockExecutionWeight: Weight = Weight::from_parts(5_000_000, 0);
pub const AuraBlockImportWeight: Weight = Weight::from_parts(1_000_000, 0);
}
// 3. 实现Aura配置trait
impl pallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = MaxAuthorities;
}
// 4. 实现cumulus-primitives-aura配置
impl cumulus_primitives_aura::Config for Runtime {
type RuntimeInherentData = InherentDataProvider;
type UnincludedSegment = AuraUnincludedSegment<Self>;
}
// 5. 实现AuraApi
impl_runtime_apis! {
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
fn slot_duration() -> sp_consensus_aura::Slot {
sp_consensus_aura::Slot::from_millis(AuraSlotDuration::get())
}
fn authorities() -> Vec<AuraId> {
pallet_aura::Authorities::<Runtime>::get().to_vec()
}
}
}
// 6. 设置SessionKeys
impl_opaque_keys! {
pub struct SessionKeys {
pub aura: AuraId,
// 其他密钥如gran等...
}
}
// 7. runtime执行环境设置
pub fn create_runtime() -> Result<Runtime, Box<dyn std::error::Error>> {
let inherent_data_providers = InherentDataProviders::new();
inherent_data_providers
.register_provider(InherentDataProvider)
.map_err(Into::into)?;
// 其他runtime初始化...
Ok(Runtime)
}
// 8. 自定义区块验证器示例
struct CustomBlockValidator;
impl cumulus_primitives_aura::BlockValidator<Block> for CustomBlockValidator {
fn validate_block(
&self,
block: &Block,
parent_header: &Header,
) -> Result<(), Box<dyn std::error::Error>> {
// 这里可以添加自定义验证逻辑
// 例如验证特定交易或状态转换
// 调用默认验证
cumulus_primitives_aura::validate_block(
&Default::default(),
&mut BlockExecutor::new(backend.clone()),
&backend,
)
}
}
关键点说明
-
Slot配置:通过
AuraSlotDuration
设置每个slot的持续时间(毫秒),应与网络其他节点保持一致 -
权重配置:
BlockExecutionWeight
和AuraBlockImportWeight
影响区块生产和导入的性能 -
验证人设置:
authorities()
函数返回当前授权集,必须与中继链注册的验证人匹配 -
区块验证:可以通过实现
BlockValidator
trait来自定义验证逻辑 -
SessionKeys:必须包含AuraId作为验证人身份标识
生产环境建议
- 建议slot持续时间设置在4-12秒之间
- 定期更新验证人集合以匹配中继链状态
- 监控区块生产和验证性能指标
- 考虑实现自定义的
BlockValidator
以增强安全性
这个完整示例展示了如何在Substrate平行链runtime中集成cumulus-primitives-aura库,实现Aura共识机制,并与中继链保持同步。