Hotstuff源码分析(七)(代码总结)

1.前言

在前几章笔者深入hotstuff源码进行分析,对底层逻辑、共识运作机制、签名算法等进行了详细的分析。在“前言”章节时笔者对hotsutff发出了一些疑问,因此在这一章,笔者将根据几天来对代码的分析对hotstuff算法进一步总结(不止包括算法逻辑,也涵盖代码实现逻辑)。

2.总结

  • 三段式共识

在流水线模式中,三段式共识是依靠区块状态实现的,一个区块会经历【抓取、交付】(这里可以理解为获取区块信息,一般提议者先获取了再提议,追随者是先接受提议再获取)、提议、投票以及决策。而“投票”动作后协议会获取下一个提议区块开始新的流程。是否决策要看后面的区块是否有正确引用待决策的区块,只要待决策的区块在锁定区块的分支上(自己或引用的区块有引用锁定区块),并且其后面分支上有3代新的区块,则认为该区块可以决策(笔者之前一直以为要重复发送同一个区块的不同类型比如propose、precommit,commit信息,太笨了)。

/* three-step HotStuff */
    const block_t &blk2 = nblk->qc_ref;
    if (blk2 == nullptr) return; // 如果 blk2 为 null,返回
    /* decided blk could possibly be incomplete due to pruning */
    if (blk2->decision) return; // 如果 blk2 已经决策,返回
    update_hqc(blk2, nblk->qc); // 更新 HQC

    const block_t &blk1 = blk2->qc_ref;
    if (blk1 == nullptr) return; // 如果 blk1 为 null,返回
    if (blk1->decision) return; // 如果 blk1 已经决策,返回
    if (blk1->height > b_lock->height) b_lock = blk1; // 更新 b_lock

    const block_t &blk = blk1->qc_ref;
    if (blk == nullptr) return; // 如果 blk 为 null,返回
    if (blk->decision) return; // 如果 blk 已经决策,返回

    /* commit requires direct parent */
    if (blk2->parents[0] != blk1 || blk1->parents[0] != blk) return; // 确保父区块关系正确

/* otherwise commit */
    std::vector<block_t> commit_queue; // 用于存储需要提交的区块
    block_t b;
    for (b = blk; b->height > b_exec->height; b = b->parents[0])
    { /* TODO: also commit the uncles/aunts */
        commit_queue.push_back(b); // 将需要提交的区块添加到队列中
    }
    if (b != b_exec)
        throw std::runtime_error("safety breached :( " +
                                std::string(*blk) + " " +
                                std::string(*b_exec)); // 确保安全性,如果不符合预期则抛出异常

    for (auto it = commit_queue.rbegin(); it != commit_queue.rend(); it++)
    {
        const block_t &blk = *it;
        blk->decision = 1; // 标记区块为已决策
        do_consensus(blk); // 执行共识过程
        LOG_PROTO("commit %s", std::string(*blk).c_str()); // 记录提交日志
        for (size_t i = 0; i < blk->cmds.size(); i++)
            do_decide(Finality(id, 1, i, blk->height,
                                blk->cmds[i], blk->get_hash())); // 执行决策操作
    }
    b_exec = blk; // 更新 b_exec
  • 提议者轮换机制

在代码中,暂时没有实现在新一轮共识发起时对提议者进行轮换,只有在超时时才会对提议者进行轮换。

  • 验证池机制

在代码实现中,代码在证书验证(QC证书的验证)、投票验证(part证书验证)时使用了验证池多线程机制,加快了验证速度。

  • 两重网络

在代码中有客户端网络以及副本网络,客户端网络用于客户端与副本之间的通信,副本网络用于副本之间的通信。其中pacemaker是这两重网络与协议之间的桥梁。外部网络通过pacemaker将命令提交给内部网络,pacemaker辅助协议以及内部网络完成什么时候提议、什么时候轮换、怎么轮换等。

  • 事件驱动机制

除了pacemaker,代码中会使用event库注册很多类型的事件循环驱动,比如副本网络会注册信息接受事件驱动程序、验证池会注册验证队列驱动机制(有新的验证信息进入队列会自动执行验证)、协议会注册超时机制等等。

  • 异步交互机制

为了避免因异步多程序工作(接受新的提议、发起新的提议、投票、接受投票等等一起工作)引起的逻辑混乱。代码使用promiss库,会对某些任务赋予promiss,当任务完成时会解决promiss,然后自动调用对应于该promiss的回调函数,以实现逻辑连贯。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值