Honey Badger BFT共识协议详解

HoneyBadgerBFT是一种异步共识协议,克服了异步网络中确定性共识的难题。它利用阈值加密、可靠广播协议、二进制共识和ACS来确保安全性与效率。协议通过RBC保证消息一致性,BA算法达成二进制比特共识,最后通过ACS形成一致的结果。这一创新设计解决了传统共识协议在网络条件变化时性能下降的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阅读建议

Honey Badger BFT应用了很多前人的研究,进行了巧妙的构造和优化,初次学习往往难以理解。在阅读时可以先大致了解各个构造块的基本作用,再了解总体的共识过程。之后回过头来深入研究各个构造块的原理,特别是BA算法,是整个协议的核心内容。

背景知识

FLP定理指出,在异步网络中,不可能存在一个确定性的共识协议。在FLP定理的指导下,共识协议设计往往需要作出妥协——要么弱化网络条件的限制,要么引入随机性。我们常见的PBFT、Raft等,就是在半同步网络下实现了一致性,但这类共识在网络条件变化时,其吞吐量会显著降低。而以往的异步共识协议同样效率低下,完全无法满足实际需求。本文介绍的Honey Badger BFT则是第一个具备可行性的异步共识协议。

基本构造块

阈值加密(threshold encryption)

传统的非对称加密算法包含一对密钥(公钥 p k pk pk和私钥 s k sk sk),其中 p k pk pk用于消息加密, s k sk sk用于解密。
而门限加密则将私钥 s k sk sk分为 n n n份( s k i , i ∈ ( 1 , . . . , n ) sk_i,i \in(1, ..., n) ski,i(1,...,n)),对于 p k pk pk加密的密文 C C C,每个子密钥 s k i sk_i ski都可以生成一个解密块 σ i \sigma_i σi,至少 t t t个解密块合成后才能最终解密得到原始消息 m m m。阈值签名算法类似,只是把加密改成了签名。
阈值加密算法

可靠广播协议(RBC,Reliable broadcast)

由于在分布式系统中,并不存在这样的广播信道,使得节点只需要发送一次消息,就能使网络中的所有节点都接收到,消息任然需要系统成员之间通过点对点的通信来传播。
而 RBC协议则是用来保证消息传播的一致性,各节点遵循RBC协议进行通信,最终能达到广播消息的效果,即网络中的所有节点都能以相同的顺序接收到相同的消息
Honey Badger论文中使用了基于纠删码的可靠广播协议(Reliable broadcast with erasure codes)。
如图所示,消息发送方 P i P_i Pi发送消息 v v v的步骤如下:

  • P i P_i Pi用纠删码将消息 v v v分为 N N N块,每块以 s j s_j sj表示;
  • P i P_i Pi s j s_j sj为叶子节点构造Merkle树, h h h为Merkle根, b j b_j bj s j s_j sj的验证路径;
  • P i P_i Pi s j s_j sj和对应的Merkle树验证信息分别发送给其他所有节点,表示为 VAL ( h , b j , s j ) \texttt{VAL}(h,b_j,s_j) VAL(h,bj,sj)
  • 收到 VAL \texttt{VAL} VAL消息后,将其广播 ECHO ( h , b j , s j ) \texttt{ECHO}(h,b_j,s_j) ECHO(h,bj,sj)
  • 收到 ECHO ( h , b j , s j ) \texttt{ECHO}(h,b_j,s_j) ECHO(h,bj,sj)消息,验证Merkle树对应的路径是否正确,若不正确则忽略;
  • 收到 N − f N-f Nf个不同的 ECHO \texttt{ECHO} ECHO消息后,从中选择%N-2f%个,重新计算Merkle根 h ′ h' h,判断是否满足 h ′ = h h'=h h=h,若等式成立则广播 READY ( h ) \texttt{READY}(h) READY(h)
  • 收到 f + 1 f+1 f+1 READY ( h ) \texttt{READY}(h) READY(h)消息后,如果没有发送过 READY ( h ) \texttt{READY}(h) READY(h),那么广播 READY ( h ) \texttt{READY}(h) READY(h)
  • 收到 2 f + 1 2f+1 2f+1 READY ( h ) \texttt{READY}(h) READY(h)消息后,待接收到 N − 2 f N-2f N2f ECHO ( h , b j , s j ) \texttt{ECHO}(h,b_j,s_j) ECHO(h,bj,sj)消息后,即可解码出消息 v v v

说明:

  • RBC协议的核心在于通过 Echo \texttt{Echo} Echo传递消息,通过 Reday \texttt{Reday} Reday表明消息已经发送完毕。
  • 在基于纠删码的RBC协议中, s j s_j sj N N N个消息中有 2 f 2f 2f个是冗余消息,用于防止恶意和失效节点。该协议通过调动全网节点发送消息分块 s j s_j sj来代替单个leader直接向全网广播消息,避免了leader的带宽瓶颈。
  • 论文中的算法表述容易造成误导,比如图中红框部分,实际含义是:在节点 P i P_i Pi构造出 VAL ( h , b j , s j ) \texttt{VAL}(h,b_j,s_j) VAL(h,bj,sj)后,将其作为RBC协议的输入,“upon receiving”是指RBC协议收到 VAL \texttt{VAL} VAL后,相当于 P i P_i Pi调用了RBC协议,而不是说将 VAL \texttt{VAL} VAL发送给了其他人,后续的算法也要注意这种表述。
    • 该协议的复杂度为 O ( N ∣ v ∣ + λ N 2 log ⁡ N ) O\left(N|v|+\lambda N^{2} \log N\right) O(Nv+λN2logN),当消息本身足够大时( ∣ v ∣ ≫ λ N 2 log ⁡ N |v| \gg{\lambda N^{2} \log N} vλN2logN ),复杂度可以表示为 O ( N ∣ v ∣ ) O(N|v|) O(Nv),等价于发送方向所有节点一对一直接发送消息的复杂度,因此说是渐进最优的。
      Reliable broadcast

二进制共识(BA,Binary Agreement)和公共硬币(Common Coin)

BA算法使全网节点对一个二进制比特的值达成共识,即全网共同生成0或1。BA算法满足以下属性:

  • 一致性(Agreement):如果任何正确的节点输出比特 b b b,那么每个正确的节点都会输出 b b b
  • 中止性(Termination):如果所有正确的节点都接收到了输入,则每个正确的节点都能产生输出。
  • 有效性(Validity):如果有任何正确的节点输出了 b b b,则至少有一个正确的节点接收 b b b作为输入。

BA算法流程如下:

  • 接收输入 b i n p u t b_{input} binput后,设置 est 0 : = b i n p u t \texttt{est}_0:=b_{input} est0:=binput,并在后续每轮中进行如下操作(以第 r r r轮为例):
    • 广播 BVAL r ( b ) \texttt{BVAL}_r(b) BVALr(b)
    • 设置 bin_values r ( b ) : = { } \texttt{bin{\_}values}_r(b):=\{\} bin_valuesr(b):={}
    • f + 1 f+1 f+1个节点接收到 BVAL r ( b ) \texttt{BVAL}_r(b) BVALr(b)后,如果还没有发送过 BVAL r ( b ) \texttt{BVAL}_r(b) BVALr(b),那么广播 BVAL r ( b ) \texttt{BVAL}_r(b) BVALr(b)
    • 2 f + 1 2f+1 2f+1个节点接收到 BVAL r ( b ) \texttt{BVAL}_r(b) BVALr(b)后,设置 bin_values r ( b ) = bin_values r ∪ { b } \texttt{bin{\_}values}_r(b)=\texttt{bin{\_}values}_r\cup\{b\} bin_valuesr(b)=bin_valuesr{b}
    • bin_values r ( b ) ≠ ∅ \texttt{bin{\_}values}_r(b)\neq \emptyset bin_valuesr(b)=
      • 广播 AUX r ( w ) \texttt{AUX}_r(w) AUXr(w),其中 w ∈ bin_values r w \in \texttt{bin{\_}values}_r wbin_valuesr
      • 等至少接收到 N − f N-f Nf AUX r \texttt{AUX}_r AUXr消息后,此时这些消息中包含的 b b b值的集合 vals \texttt{vals} vals bin_values r \texttt{bin{\_}values}_r bin_valuesr的子集(因为在本步骤运行的时候,可能还会收到其他的 BVAL r \texttt{BVAL}_r BVALr加入 bin_values r \texttt{bin{\_}values}_r bin_valuesr
      • s ← Coin r ⋅ GetCoin ( ) s \leftarrow \texttt{Coin}_{r} \cdot \texttt{GetCoin}() sCoinrGetCoin()
      • 如果 vals = { b } \texttt{vals}=\{b\} vals={b},则
        • est r + 1 : = b \texttt{est}_{r+1}:=b estr+1:=b
        • 如果 ( b = s % 2 ) (b=s\%2) (b=s%2)则输出 b b b
      • 否则 est r + 1 : = s % 2 \texttt{est}_{r+1}:=s\%2 estr+1:=s%2
  • 继续循环,直到在某一轮输出值 b b b,且对于 r ′ > r r'>r r>r,有 Coin r ′ = b \texttt{Coin}_{r'}=b Coinr=b
    Byzantine Agreement
    论文中使用了基于阈值签名的公共硬币方案实现BA算法(即上述的 GetCoin ( ) \texttt{GetCoin}() GetCoin())。
    算法中 sid \texttt{sid} sid是一个唯一的随机数,可以看做是 coin \texttt{coin} coin的名字
  • 可信设置环节:由一个可信的分发方运行 p k , { s k i } ← ThresholdSetup pk,\{sk_i\} \leftarrow \texttt{ThresholdSetup} pk,{ski}ThresholdSetup来生成公共公钥和私钥碎片 { s k i } \{sk_i\} {ski} s k i sk_i ski对应发放给 P i P_i Pi
  • 当调用 GetCoincoin \texttt{GetCoincoin} GetCoincoin时,广播 ThresholdSign p k ( s k i , sid ) \texttt{ThresholdSign}_{pk}(sk_i,\texttt{sid}) ThresholdSignpk(ski,sid)
  • 在接收到至少 f + 1 f+1 f+1个签名碎片后,将其合成为完整签名: sig ← ThresholdCombine p k ( s k i , sid ) \texttt{sig} \leftarrow \texttt{ThresholdCombine}_{pk}(sk_i,\texttt{sid}) sigThresholdCombinepk(ski,sid),并用公钥验证 ThresholdVerify p k ( sid ) \texttt{ThresholdVerify}_{pk}(\texttt{sid}) ThresholdVerifypk(sid),若合法,则生成签名
    common coin based on threshold signatures
    说明:
  • 各方首先生成一个同样的一个二进制数 b b b
  • 之后通过一个公共的硬币来判断是否要取这个 b b b作为最终的输出,如果不满足判断条件,那就进入下一轮,重复上述步骤

异步公共子集(ACS,Asynchronous Common Subset)

简而言之,网络中的各节点通过各自的输入,最终能经过ACS达成共识,生成一个一致的结果。ACS满足以下属性:

  1. Validity(有效性):如果一个正确的节点输出了集合 v \textbf{v} v,那么 ∣ v ∣ > N − f |\textbf{v}|>N-f v>Nf,且 v \textbf{v} v至少包含 N − 2 f N-2f N2f个正确节点的输入
  2. Agreement(一致性):如果一个正确的节点输出了集合 v \textbf{v} v,那么每个节点都会输出集合 v \textbf{v} v
  3. Totality(全局性):如果 N − f N-f Nf个正确节点收到了输入,那么所有正确节点都会产生输出。

而ACS又是基于上述的RBC协议和BA算法来实现的。各个节点通过RBC协议广播自己对BA算法的输入,即所有节点并发地运行BA算法,最终形成一个长度为 N N N的二进制值列表,由这个二进制列表来决定最终提交哪些交易。
ACS流程如下:

  • { RBC i } N \{\texttt{RBC}_i\}_N {RBCi}N来表示RBC协议的 N N N个实例, P i P_i Pi对应为 { RBC i } \{\texttt{RBC}_i\} {RBCi}的发送方。 { BA i } N \{\texttt{BA}_i\}_N {BAi}N代表BA算法的 N N N个实例。
  • 接收到输入 v i v_i vi后,将其输入到 RBC i \texttt{RBC}_i RBCi广播
  • 在收到从 RBC j \texttt{RBC}_j RBCj发送的 v j v_j vj后,如果给 BA i \texttt{BA}_i BAi输入,那么对 BA i \texttt{BA}_i BAi输入1
  • 如果已经接收到了至少 N − f N-f Nf BA \texttt{BA} BA实例传递的值 1 ,那么后续所有还未输入的 BA \texttt{BA} BA实例都输入为0
  • 一旦所有的 BA \texttt{BA} BA实例都完成,令 C ⊂ [ 1 , . . . , N ] C \subset{[1,...,N]} C[1,...,N]表示为每个生成 1 的BA 实例的索引。等待每个 RBC j \texttt{RBC}_j RBCj的输出 v j v_j vj,其中 j ∈ C j \in C jC。最终输出 U j ∈ C v j U_{j \in C^{v_j}} UjCvj

在这里插入图片描述
论文对ACS的具体执行给出了图例解释:
从节点0的角度,他会收到来自节点 1 ∼ 3 ( N = 4 , f = 1 ) 1\sim3(N=4,f=1) 13(N=4,f=1)的RBC广播,图中给出了三种不同的情况

  • 正常情况下,节点0收到了节点1的广播 RBC 1 \texttt{RBC}_1 RBC1,则对 BA 1 \texttt{BA}_1 BA1输入1(1等价于yes)
  • 节点0接收到 RBC 2 \texttt{RBC}_2 RBC2时已经收到了 N − f N-f Nf BA \texttt{BA} BA输出1,因此他对 BA 2 \texttt{BA}_2 BA2输入0,但由于其他节点已经收到了 RBC 2 \texttt{RBC}_2 RBC2并为 BA 2 \texttt{BA}_2 BA2输入1,因此最终 BA 2 \texttt{BA}_2 BA2仍然输出1
  • RBC 3 \texttt{RBC}_3 RBC3还未完成, BA 3 \texttt{BA}_3 BA3就已经被输入0,且由于其他节点也没有为 BA 3 \texttt{BA}_3 BA3投票,因此最终 BA 3 \texttt{BA}_3 BA3输出0

Illustrated examples of ACS executions.

说明

  • 各方用RBC广播将自己的值 v i v_i vi,也会从RBC中接收其他节点的值 v j v_j vj,同时运行 N N N B A BA BA算法,如果接收到了 v j v_j vj,那对应的 BA j \texttt{BA}_j BAj输入1
  • 如果在 N − f N-f Nf BA \texttt{BA} BA算法中都已经输入了1,那后续其他的 BA \texttt{BA} BA算法都输出0
  • N N N B A BA BA算法完成后,节点选择那些输出为1的BA算法所对应的 v k v_k vk消息,由于 B A BA BA算法的一致性,网络中所有节点都会作出相同的选择,即最终所有节点都选择了相同的消息 v k v_k vk

共识流程

在了解了上述的构建块后,下面以节点 P i P_i Pi的角度,阐述Honey Badger BFT的共识流程。其中 B B B是系统设定参数, r r r表示在第 r r r轮。

  • 节点 P i P_i Pi从自己的交易池的前 B B B个交易中随机选择 ⌊ B / N ⌋ \lfloor B / N\rfloor B/N个作为提案( proposed \texttt{proposed} proposed
  • 将提案加密 x : = TPKE.Enc(PK,proposed) x:=\texttt{TPKE.Enc(PK,proposed)} x:=TPKE.Enc(PK,proposed)
  • x x x作为 ACS [ r ] \texttt{ACS}[r] ACS[r]的输入
  • ACS [ r ] \texttt{ACS}[r] ACS[r]中接收 { v j } j ∈ S \{v_j\}_{j \in S} {vj}jS,其中 S ⊂ [ 1 , . . . , N ] S \subset [1,...,N] S[1,...,N]
  • 对于所有 j ∈ S j \in S jS
    • e j : = TPKE.DecShare ( S K i , v j ) e_j:=\texttt{TPKE.DecShare}(SK_i,v_j) ej:=TPKE.DecShare(SKi,vj)
    • 广播 DEC ( r , j , i , e j ) \texttt{DEC}(r,j,i,e_j) DEC(r,j,i,ej)
    • DEC ( r , j , i , e ( j , k ) ) \texttt{DEC}(r,j,i,e_(j,k)) DEC(r,j,i,e(j,k))接收至少 f + 1 f+1 f+1个消息
    • 解码 y j : = TPKE.Dec ( P K i , { k , e j , k } ) y_j:=\texttt{TPKE.Dec}(PK_i,\{k,e_{j,k}\}) yj:=TPKE.Dec(PKi,{k,ej,k})
  • block r : = sorted ( U j ∈ C v j ) \texttt{block}_r:=\texttt{sorted}(U_{j \in C^{v_j}}) blockr:=sorted(UjCvj) sorted \texttt{sorted} sorted即对收集的交易排序,组成为区块 block r \texttt{block}_r blockr
  • 设置 buf : = buf-block r \texttt{buf}:=\texttt{buf-block}_r buf:=buf-blockr
    HoneyBadgerBFT
    说明:
  • 第一步中,随机选择交易是为了各个节点选择的交易尽可能不同(同一笔交易可能被发给了不同节点拿来构造区块)
  • 将提案加密是为了防止审查攻击,以防止一些恶意节点在ACS中故意不给包含特定交易的节点投票
  • 最终通过ACS生成一个共识列表(即在ACS中,BA输出为1的节点),各节点对成功共识的提案进行解密,生成解密碎片(share),收集到足够的碎片即可解密出交易内容
  • 将交易构造成一个区块后即可上链,同时各节点将已经成功共识的交易从自己的交易池中删去。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值