Rust区块链共识引擎sp-consensus-beefy的使用,Substrate框架下的BEEFY协议实现与节点验证功能

以下是关于Rust区块链共识引擎sp-consensus-beefy在Substrate框架下的完整使用示例,包含BEEFY协议实现与节点验证功能:

完整BEEFY协议实现Demo

use sp_consensus_beefy::{
    beefy, crypto, mmr, known_payloads, 
    Commitment, Payload, SignedCommitment, ValidatorSet,
    BeefyApi, BeefyJustification, BeefyDataProvider, MMRLeaf, MmrHasher
};
use sp_runtime::traits::{Block as BlockT, NumberFor, Header as HeaderT, Hash, BlakeTwo256};
use sp_api::{ProvideRuntimeApi, BlockId};
use sp_blockchain::HeaderBackend;
use sp_core::{H256, sr25519};
use std::sync::Arc;

// 1. 定义BEEFY验证人集
fn create_validator_set() -> ValidatorSet<sr25519::AuthorityId> {
    let authorities = vec![
        sr25519::Public::from_raw([1; 32]).into(),
        sr25519::Public::from_raw([2; 32]).into(),
        sr25519::Public::from_raw([3; 32]).into(),
    ];
    ValidatorSet::new(authorities, 1)
}

// 2. 创建并签名BEEFY承诺
fn create_signed_commitment<Block: BlockT>(
    block_number: NumberFor<Block>,
    validator_set: &ValidatorSet<sr25519::AuthorityId>,
) -> SignedCommitment<NumberFor<Block>, sr25519::Signature> {
    let payload = Payload::from_single_entry(
        known_payloads::MMR_ROOT_ID,
        H256::random().as_bytes().to_vec(),
    );
    
    Commitment {
        payload,
        block_number,
        validator_set_id: validator_set.id(),
    }
    .sign(&sr25519::Public::from_raw([1; 32]).into(), validator_set)
    .expect("签名应该成功")
}

// 3. 验证BEEFY承诺
fn verify_commitment<Block: BlockT>(
    signed_commitment: &SignedCommitment<NumberFor<Block>, sr25519::Signature>,
    validator_set: &ValidatorSet<sr25519::AuthorityId>,
) -> bool {
    signed_commitment.verify(validator_set).is_ok()
}

// 4. MMR叶子节点创建
fn create_mmr_leaf<Block: BlockT>(
    block_number: NumberFor<Block>,
    block_hash: Block::Hash,
    parent_hash: Block::Hash,
    next_validator_set: ValidatorSet<sr25519::AuthorityId>,
) -> MMRLeaf<Block::Header, MmrHasher<Block>> {
    MMRLeaf {
        version: beefy::MMRLeafVersion::new(0),
        parent_number_and_hash: (block_number.saturating_sub(1.into()), parent_hash),
        beefy_next_authority_set: next_validator_set,
        leaf_extra: Vec::new(),
        block_hash,
    }
}

// 5. BEEFY验证器实现
struct BeefyVerifier<Block: BlockT, Client> {
    client: Arc<Client>,
}

impl<Block, Client> BeefyVerifier<Block, Client>
where
    Block: BlockT,
    Client: ProvideRuntimeApi<Block> + HeaderBackend<Block> + Send + Sync + 'static,
    Client::Api: BeefyApi<Block>,
{
    pub fn verify_justification(
        &self,
        justification: BeefyJustification<Block>,
        validator_set: ValidatorSet<sr25519::AuthorityId>,
    ) -> Result<(), sp_runtime::DispatchError> {
        let block_id = BlockId::hash(justification.commitment.block_hash);
        let header = self.client.header(block_id)?;
        
        beefy::verify_beefy_justification::<Block>(
            &justification,
            validator_set,
            header.as_ref().map(|h| h.number()),
        )
    }
}

// 6. 自定义BEEFY数据提供者
struct MyBeefyDataProvider<Block: BlockT> {
    current_block: NumberFor<Block>,
}

impl<Block: BlockT> BeefyDataProvider<Block> for MyBeefyDataProvider<Block> {
    fn best_block_number(&self) -> NumberFor<Block> {
        self.current_block
    }
    
    fn next_authorities(&self, _block: NumberFor<Block>) -> Option<ValidatorSet<sr25519::AuthorityId>> {
        Some(create_validator_set())
    }
}

// 主函数示例
fn main() {
    type BlockNumber = u64;
    type BlockHash = H256;
    
    // 1. 初始化验证人集
    let validator_set = create_validator_set();
    
    // 2. 创建BEEFY承诺
    let commitment = create_signed_commitment::<BlockNumber>(42, &validator_set);
    
    // 3. 验证承诺
    if verify_commitment(&commitment, &validator_set) {
        println!("✅ BEEFY承诺验证成功");
    } else {
        println!("❌ BEEFY承诺验证失败");
    }
    
    // 4. 创建MMR叶子节点
    let mmr_leaf = create_mmr_leaf::<BlockNumber>(
        42,
        H256::random(),
        H256::random(),
        validator_set.clone(),
    );
    println!("📄 创建的MMR叶子节点: {:?}", mmr_leaf);
    
    // 5. 初始化数据提供者
    let data_provider = MyBeefyDataProvider { current_block: 42 };
    println!("🔄 当前最佳块号: {}", data_provider.best_block_number());
}

关键组件说明

  1. ValidatorSet - BEEFY验证人集合,包含验证人公钥列表和集合ID
  2. Commitment - 包含块号、验证人集ID和有效负载的BEEFY承诺
  3. SignedCommitment - 由验证人签名后的承诺,包含签名信息
  4. MMRLeaf - 用于BEEFY协议的Merkle Mountain Range叶子节点结构
  5. BeefyJustification - 包含多个验证人签名的证明结构

使用说明

  1. 首先添加依赖到Cargo.toml:
sp-consensus-beefy = "26.0.0"
  1. 主要功能包括:
  • 创建和验证BEEFY验证人集
  • 生成和验证BEEFY承诺
  • MMR叶子节点生成
  • BEEFY证明验证
  • 自定义数据提供者实现
  1. 该示例展示了BEEFY协议的核心功能,可根据实际需求进行扩展。

注意事项

  1. 实际使用时需要集成到Substrate节点中
  2. 验证人签名需要使用真实的密钥对
  3. MMR树的维护需要与区块链状态同步
  4. 验证人集更新需要遵循链上治理机制

1 回复

Rust区块链共识引擎sp-consensus-beefy的使用:Substrate框架下的BEEFY协议实现与节点验证功能

以下是基于提供内容的完整示例demo,展示如何在Substrate节点中完整集成BEEFY共识引擎:

//! 完整BEEFY共识引擎集成示例

use sc_client_api::Backend;
use sc_consensus::BlockImport;
use sc_network::NetworkService;
use sc_service::{Configuration, TaskManager};
use sp_api::ProvideRuntimeApi;
use sp_consensus_beefy::{
    BeefyApi, BeefyKeystore, BeefyParams, Commitment, SignedCommitment, ValidatorSet,
};
use sp_runtime::traits::Block as BlockT;
use std::sync::Arc;

// 1. 实现BeefyApi trait
impl<Block, Runtime> BeefyApi<Block> for Runtime
where
    Block: BlockT,
    Runtime: ProvideRuntimeApi<Block>,
    Runtime::Api: BeefyRuntimeApi<Block>,
{
    fn validator_set() -> ValidatorSet<Self::AuthorityId> {
        // 从runtime获取当前验证人集合
        Beefy::validator_set()
    }
}

// 2. 启动BEEFY服务
pub fn start_beefy<Block, Runtime, Client, Network, BI>(
    client: Arc<Client>,
    network: Arc<Network>,
    task_manager: &mut TaskManager,
    keystore: Arc<BeefyKeystore>,
    config: &Configuration,
) -> Result<(), sc_service::Error>
where
    Block: BlockT,
    Runtime: BeefyApi<Block>,
    Client: ProvideRuntimeApi<Block> + 'static,
    Network: NetworkService<Block, Block::Hash> + 'static,
    BI: BlockImport<Block> + 'static,
{
    // 配置BEEFY参数
    let beefy_params = BeefyParams {
        client: client.clone(),
        key_store: keystore,
        network: network.clone(),
        protocol_name: config.protocol_id.clone(),
        task_manager,
        fork_notify: None,
        metrics: None,
    };

    // 启动BEEFY gadget
    let beefy = beefy::start_beefy_gadget::<Block, Runtime>(beefy_params);

    // 注册BEEFY网络协议
    network.register_beefy_protocol(
        config.protocol_id.clone(),
        beefy.message_sender(),
    );

    Ok(())
}

// 3. 验证人功能实现
pub mod validator {
    use super::*;

    /// 验证BEEFY签名承诺
    pub fn verify_commitment<Block: BlockT>(
        signed_commitment: &SignedCommitment<Block::Hash, NumberFor<Block>, crypto::Signature>,
        validator_set: &ValidatorSet<crypto::Public>,
    ) -> bool {
        // 验证签名是否匹配验证人集合
        signed_commitment.verify(validator_set)
    }

    /// 为BEEFY承诺创建签名
    pub async fn sign_commitment<Block: BlockT>(
        keystore: &BeefyKeystore,
        commitment: Commitment<Block::Hash, NumberFor<Block>>,
    ) -> Option<crypto::Signature> {
        // 使用keystore为承诺签名
        keystore.sign(&commitment.encode())
    }
}

// 4. 链规范配置示例
pub mod chain_spec {
    use super::*;

    pub fn testnet_config() -> Result<ChainSpec, String> {
        let wasm_binary = include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/runtime.wasm");

        Ok(ChainSpec::from_genesis(
            "Testnet",
            "testnet",
            move || testnet_genesis(
                wasm_binary,
                // 初始验证人配置
                vec![
                    authority_keys_from_seed("Alice"),
                    authority_keys_from_seed("Bob"),
                ],
            ),
            vec![],
            None,
            None,
            None,
            None,
        ))
    }

    fn testnet_genesis(
        wasm_binary: &[u8],
        initial_authorities: Vec<AuthorityKeys>,
    ) -> GenesisConfig {
        GenesisConfig {
            system: SystemConfig {
                code: wasm_binary.to_vec(),
            },
            beefy: Some(BeefyConfig {
                authorities: initial_authorities.iter()
                    .map(|x| x.beefy_id.clone())
                    .collect(),
            }),
            // 其他模块配置...
        }
    }
}

// 5. 验证人节点启动示例
pub fn run_validator_node(config: Configuration) -> Result<(), sc_service::Error> {
    // 初始化基础服务组件...
    
    if config.role.is_authority() {
        // 获取BEEFY密钥库
        let beefy_keystore = keystore_container
            .sync_keystore()
            .beefy_keystore()
            .expect("验证人节点必须配置BEEFY密钥库");

        if beefy_keystore.keys().is_empty() {
            log::warn!("没有找到BEEFY密钥,此验证人将不参与BEEFY共识");
        }

        // 启动BEEFY服务
        start_beefy::<Block, Runtime, _, _, _>(
            client.clone(),
            network.clone(),
            &mut task_manager,
            beefy_keystore,
            &config,
        )?;
    }

    // 启动其他服务...
    Ok(())
}

关键组件说明

  1. BeefyApi实现:为Runtime提供验证人集合信息

  2. BEEFY服务启动:配置并启动BEEFY共识引擎

  3. 验证人功能

    • 验证签名承诺
    • 为区块承诺创建签名
  4. 链规范配置

    • 在创世块中配置初始BEEFY验证人
    • 设置BEEFY特定参数
  5. 验证人节点

    • 检查并加载BEEFY密钥
    • 作为验证人参与BEEFY共识

使用建议

  1. 对于验证人节点,确保配置了有效的BEEFY密钥
  2. BEEFY应与GRANDPA最终性工具配合使用
  3. 跨链桥接场景下,可以使用BEEFY生成轻量级证明
  4. 定期监控BEEFY共识参与情况
回到顶部