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())
}

功能说明

  1. AuraUnincludedSegmenter:用于处理未包含在最终链中的区块段
  2. AuraConsensusDataProvider:提供Aura共识所需的数据
  3. slot_duration:获取区块链的slot持续时间
  4. 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,
        )
    }
}

关键点说明

  1. Slot配置:通过AuraSlotDuration设置每个slot的持续时间(毫秒),应与网络其他节点保持一致

  2. 权重配置BlockExecutionWeightAuraBlockImportWeight影响区块生产和导入的性能

  3. 验证人设置authorities()函数返回当前授权集,必须与中继链注册的验证人匹配

  4. 区块验证:可以通过实现BlockValidator trait来自定义验证逻辑

  5. SessionKeys:必须包含AuraId作为验证人身份标识

生产环境建议

  1. 建议slot持续时间设置在4-12秒之间
  2. 定期更新验证人集合以匹配中继链状态
  3. 监控区块生产和验证性能指标
  4. 考虑实现自定义的BlockValidator以增强安全性

这个完整示例展示了如何在Substrate平行链runtime中集成cumulus-primitives-aura库,实现Aura共识机制,并与中继链保持同步。

回到顶部