HotStuff简介

HotStuff是一个BFT共识协议:

    Basic HotStuff 
->  Chained HotStuff         // 流水线提高吞吐   
->  Event-driven HotStuff    // Safety与Liveness解耦, 实现更简洁

basic hotstuff中leader提出的一个proposal需要距离如下阶段才能提交执行: Prepare -> PreCommit -> Commit -> Decide, 每个阶段的作用:

  • Prepare: leader在此阶段会从replica提出的proposal中挑选出一条来广播。replica通过SafeNode()判断自己是否可以接受leader发来的proposal.
  • PreCommit: leader得知n-f个节点接受了这一提议, 并广播这一共识(QC)及其门限签名。replica收到这个QC并且验证通过, 便得知系统中有n-f个节点可以接受这个节点, 随后返回签名给leader。
  • Commit: leader得知n-f个节点已经得知系统中n-f个节点可以接受proposal这一消息, 随后计算QC和门限签名放入Commit MSG中。replica收到该消息后, 便锁定该proposal, 但是还没执行, 随后告知leader。
  • Decide: leader收到n-f个签名后得知n-f个节点已经锁定了proposal, 随后广播Commit阶段的共识。replica收到MSG后就可以执行proposal了。

最后, leader和replica会进入下一个view. 至于如何进行leader election, 由开发者自行决定。

在Basic hotstuff的3pc过程中, 每个阶段的行为和数据结构都高度一致。Chained hotstuff在Basic hotstuff的基础上进行改进, 利用新proposal的PrepareMSG来更新前面若干个节点的状态, 把提交过程流水线化.

image.png

如上图, 通过流水线化, 当b*进入Prepare阶段, 那么:

节点  b  <------ b'  <------ b''  <------ b*
阶段  Decide     Commit      PreCommit    Prepare   
动作  执行       锁定

Event-driven HotStuff在Chained HotStuff的基础上, 将实现分为了两部分, 其中负责Liveness功能(如选举, 超时, 同步view)的称为Pacemaker. 另一部分负责Safety, 主要通过Msg来更新节点状态, 笔者将这部分称为StateMachine。

事件驱动的HotStuff

Pacemaker

struct Pacemaker{
    qc_high // 所见过最高的、已投票的QC
    b_leaf  // 叶子节点
}

Pacemaker的动作:
image.png
image.png

  • update_qc_high()如果新qc比pm持有的qc更高,那么更新qc_high和b_leaf.
  • on_beat(cmd),如果本节点是新leader,通过调用sm.on_propose()来创建叶子并且将其广播给所有replica。
  • on_next_sync_view(), 向leader发送NewViewMSG带上自己的qc_high
  • on_recv_new_view(), 当leader收到NewView时, 如果附带的qc比自己持有的qc更高,就更新qc_high和b_leaf.

StateMachine

sturct StateMachine{
    Vmapper     // node 到它的投票集合的映射
    vheight     // 最新的, 自己已投票的节点的高度, 等同于view number
    b_lock      // 锁定的节点
    b_exec      // 最后一个已执行的节点
}

StateMachine的动作:
image.png
image.png

  • create_leaf()创建叶子节点
  • update(b*)更新节点b*及其父节点b'', b', b. 并且更新b_lock = b', 执行b
  • on_commit(b), 递归执行b
  • on_recv_proposal(b_new), 如果b_new.height比自己的vheight要高,而且满足SAFENODE()谓词, 就签名并且回复。随后更新b_new状态
  • on_recv_vote(), 计算门限签名和qc, 并且调用pacemaker.update_qc_height()
  • on_propose(), 创建叶子并且将其广播,随后返回叶子。

一次无故障的提交流程

  1. 首先上层app把新的cmd交付给hotstuff node。
  2. replica根据某种自定义方式生成proposal, 也就是node b_new。
  3. on_recv_new_view()中, replica把node发送给leader。
  4. leader.pacemaker挑选出最高的node, 调用on_beat()将其广播给所有replica。
  5. replica受到NewViewMSG后会调用on_recv_proposal(), 如果新node的高度更高而且满足SafeNode()谓词, 那么会返回自己的签名。无论是否接受新node, on_recv_proposal()都会调用update(b_new)
  6. leader通过on_recv_vote()来计算门限签名, 调用pm.update_qc_high()来更新qc_high。
  7. replica等待b_new提交。这需要连续三个节点b <- b' <- b'', 如果b被提交了, 那么之前的节点也会提交。
  8. b_new被提交, 执行cmds。
  9. replica告知客户端cmds已执行。

其他

为何SAFENODE(b_new)为假也调用update(b_new)

update(b_new)并没有对b_new做任何动作。此时b_new处于Prepare阶段, 可能是个恶意的proposal。

但收到到b_new节点时, replica可以知道, b_new的三个祖先b, b', b''的分别进入了Decide, Commit, PreCommit阶段, 因此它做如下动作:

  1. 如果b'比已锁定的b_lock要更高(等价于viewNumebr更大), 那么锁定b'
  2. 如果b, b', b''三者连续, 那么递归提交b 及其之前的节点。

justify.node与parent的区别

结合上面可以看到, 实际上b, b', b''三者可能不连续:


 c1 <- b <- a1 <- a2 <- b' <- b1 <- b2 <- b''
      _________________      __________

// 所谓ancesty gap, leader超时导致进入下一个阶段

如上图: b''.justify.node == b', 而b''.parent == b2.
on_commit(b'')时, 会依次提交b1 <- b2 <- b''

从执行过程来看: 创建新节点时会将pacemaker.qc_high作为新节点的justify, 那么qc_high何时更新? 通过以下途径调用pacemaker.update_qc_high()更新:

  • leader: on_recv_vote(), 计算出qc后得知b_new已经被接受了, 因此更新自己的。
  • replica: on_recv_proposal() -> update(b_new) -> update_qc_high(b_new.justify)。replica投给b_new了, 自然也就确认了b_new.justify。

pacemaker.qc_high与sm.vheight

这两个变量不是对应的。vheight在节点投票给b_new后更新为b_new.height. 一般来说qc_high.node.height <= vheight

动态增删节点

Raft算法支持集群运行过程中动态增加或删除节点的功能,称之为成员变更(membership change). Raft有两种成员变更的方式,最为简单的是每次增删一个节点, 这种情况下不会出现两个Majority的情况因此是安全的。另一种是一次性增添任意个节点, 这种情况下可能破坏safety。

HotStuff与Raft相似, 因此也会有这种风险。如果HotStuff支持节点的增删, 需要门限签名也能在这种变化中正常工作((dynamic threshold signature)), 否则安全性会被破坏。

比如n=3f+1,每次需要至少2f+1个, 当系统又新加入了n个节点后, 每次需要至少2*2n/3 + 1 = 4f+2个签名。如果签名机制仍然维持原来的2n/3 + 1的阈值, 那恶意leader就可以随意写入了。

或者放弃动态变更的能力, 一旦启动系统成员就不可改变。

参考资料

  1. hotstuff paper
  2. event-driven hotstuff in go
  3. https://zhuanlan.zhihu.com/p/...
  4. https://eprint.iacr.org/2008/045.pdf

Tsukami
9 声望9 粉丝

语雀: [链接]