共识算法:从PBFT到HotStuff的拜占庭容错演进
一、引言
区块链的核心:在不可信网络中达成一致。从Liskov 1999年PBFT到2018年Facebook LibraBFT(HotStuff),历经20年从理论到生产的演进。本文将逐层推导共识算法的安全性证明和工程实现。
二、PBFT:三阶段协议的经典
2.1 协议流程
Client Request
│
▼
Primary (Leader) ───Pre-Prepare──→ Replica 1
───Pre-Prepare──→ Replica 2
───Pre-Prepare──→ Replica 3 (n=3f+1=4, f=1)
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Prepare(1) Prepare(2) Prepare(3) ← 至少2f+1=3个Prepare
│ │ │
└─────────────┼─────────────┘
▼
Commit(1,2,3) ← 至少2f+1个Commit
│
▼
Reply → Client
2.2 核心实现
go
type PBFT struct {
view uint64 // 当前视图(View = Leader编号)
seq uint64 // 序列号
phase Phase // PrePrepare/Prepare/Commit
replicas map[uint64]*Replica
f int // 最大容错数
log *MessageLog
timer *time.Timer
}
const (
PrePrepare Phase = iota
Prepare
Commit
)
type ConsensusMessage struct {
Type Phase
View uint64
Seq uint64
Digest [32]byte // 提案Hash
SenderID uint64
Signature []byte
}
// Pre-Prepare: Leader广播提案
func (p *PBFT) sendPrePrepare(request []byte) {
digest := sha256.Sum256(request)
msg := &ConsensusMessage{
Type: PrePrepare,
View: p.view,
Seq: p.seq,
Digest: digest,
SenderID: p.id,
}
msg.Signature = p.sign(msg)
p.broadcast(msg)
}
// Prepare: 副本确认收到有效提案
func (p *PBFT) handlePrePrepare(msg *ConsensusMessage) error {
// 验证: View匹配 + 签名有效 + 未处理过
if msg.View != p.view { return ErrWrongView }
if !p.verifySignature(msg) { return ErrInvalidSig }
if p.log.Has(msg.View, msg.Seq) { return ErrDuplicate }
p.log.Add(msg)
p.sendPrepare(msg.Digest)
return nil
}
func (p *PBFT) sendPrepare(digest [32]byte) {
msg := &ConsensusMessage{
Type: Prepare,
View: p.view,
Seq: p.seq,
Digest: digest,
}
msg.Signature = p.sign(msg)
p.broadcast(msg)
p.checkPrepared()
}
// Prepared条件: 2f+1个Prepare消息(含自身)
func (p *PBFT) checkPrepared() {
prepares := p.log.GetPrepares(p.view, p.seq)
// ★ 核心不变量: prepared(m,v,n) → 不会有其他m'在(v,n)被committed
if len(prepares) >= 2*p.f+1 {
p.preparedCertificate = prepares
p.sendCommit(prepares[0].Digest)
}
}
// Committed条件: 2f+1个Commit消息 → 最终确定性!
func (p *PBFT) checkCommitted() {
commits := p.log.GetCommits(p.view, p.seq)
if len(commits) >= 2*p.f+1 {
p.committedCertificate = commits
p.execute(commits[0].Digest) // 执行请求,不可回滚
p.sendReply()
}
}
// View Change: Leader超时→换Leader
func (p *PBFT) startViewChange() {
p.view++
p.phase = PrePrepare
msg := &ViewChangeMessage{
NewView: p.view,
LastSeq: p.seq,
PreparedCert: p.preparedCertificate, // ★ 关键:携带prepared证明
}
p.broadcast(msg)
}
// ★ 安全性证明核心:View Change必须携带prepared证明
// 新Leader收集2f+1个ViewChange消息后,选取最新prepared的seq继续
func (p *PBFT) handleNewView(msgs []*ViewChangeMessage) {
// 1. 找到最高prepared的序列号
maxPrepared := findMaxPreparedSeq(msgs)
// 2. 对其prepared消息重新做PrePrepare(保证不冲突)
if maxPrepared > 0 {
p.rePropose(maxPrepared)
}
// 3. 继续处理新请求
p.seq = maxPrepared + 1
}
2.3 形式化安全证明
定理1 (Safety): PBFT不会产生分叉
证明: 假设两个冲突的请求m和m'都在序列号n被提交
→ 需要两个不同的quorum: Q1和Q2,各含至少2f+1个节点
→ |Q1|+|Q2| ≥ 2(2f+1) = 4f+2 > 3f+1 = n
→ 至少f+1个节点同时在两个quorum中
→ 诚实节点不可能对同一seq投两种票 → 矛盾
定理2 (Liveness): 在view change后最终能达成共识
→ 新Leader的ViewChange消息包含prepared certificate
→ 至少2f+1个节点接受了prepared消息
→ 新Leader可以继续推进
三、Tendermint:PBFT的实用化
go
// Tendermint简化PBFT:去掉了PrePrepare,用提议+预投票+预提交三阶段
type TendermintConsensus struct {
height int64
round int32
step Step // Propose/Prevote/Precommit
validators *ValidatorSet
}
const (
Propose Step = iota // 提议者广播区块
Prevote // 验证者投票(类似PBFT Prepare)
Precommit // 验证者提交(类似PBFT Commit)
)
// Tendermint关键改进:
// 1. Round-based: 每一轮有固定Proposer(基于VRF选择)
// 2. 锁定机制: Precommit后锁定区块,新轮必须解锁或重提案
// 3. 超时递增: 每轮timeout+=delta,避免活锁
func (tc *TendermintConsensus) enterNewRound(round int32) {
tc.round = round
tc.step = Propose
// Proposer = validators[height % len(validators)]
if tc.isProposer() {
block := tc.createBlock()
tc.broadcastProposal(block)
}
// 超时进入下一轮
tc.scheduleTimeout(tc.timeoutDuration())
}
四、HotStuff:链式BFT革命
4.1 三链确认规则
Leader每次只提出一个区块,累积QC(Quorum Certificate):
Block1 ──→ Block2 ──→ Block3 ──→ Block4
│ │ │ │
QC1 QC2 QC3 QC4
(Prepare) (PreCommit) (Commit) (Decide)
★ 关键: Block3携带Block1的Commit QC → Block1被最终确定!
4.2 核心实现
go
// HotStuff的精妙: View Number同时作为Phase指示器
// view%3==0 → Prepare, view%3==1 → PreCommit, view%3==2 → Commit
type HotStuff struct {
view uint64
bLock *Block // 最高PreCommit的块
bExec *Block // 最高Commit的块
bLeaf *Block // 最新块
qcHigh *QuorumCert // 最高QC
}
type QuorumCert struct {
Type Phase
View uint64
BlockHash [32]byte
Sigs []Signature // 包含2f+1个签名
}
// ★ 单链Leader提议(线性通信! PBFT需要O(n²))
func (hs *HotStuff) onPropose(block *Block) {
// 1. 验证前驱QC(Leader必须附带最新QC)
if !hs.verifyQC(block.Justify) { return }
// 2. 更新安全规则: fork必须扩展bLock(PreCommit的块)
if block.Parent.View < hs.bLock.View {
// 不在bLock之后的分叉 → 拒绝
return
}
// 3. 发送Vote(带签名)
hs.sendVote(block)
}
// ★ Leader收集2f+1个Vote → QC
func (hs *HotStuff) onReceiveVotes(block *Block, votes []*Vote) {
if len(votes) >= 2*hs.f+1 {
qc := hs.aggregateQC(votes)
hs.updateHighQC(qc)
// ★ 三链确认: 检查祖父区块
b1 := block // 当前
b2 := block.Parent // 父
b3 := block.Parent.Parent // 祖父
if b1.Justify.View == b2.View+1 && b2.Justify.View == b3.View+1 {
// b3已获得连续三代QC → Finalize b3
hs.commitBlock(b3)
}
}
}
// ★ 领导者更换: Pacemaker
func (hs *HotStuff) onLeaderTimeout() {
hs.view++
hs.startViewChange()
hs.broadcast(NewViewMessage{View: hs.view, HighQC: hs.qcHigh})
// O(n)消息复杂度(vs PBFT O(n²))
}
4.3 性能对比
| 协议 | 消息复杂度 | 延迟 | 吞吐量 | 验证者上限 |
|---|---|---|---|---|
| PBFT | O(n²) | 3RTT | ~1K TPS | ~30 |
| Tendermint | O(n²) | 2RTT | ~5K TPS | ~100 |
| HotStuff | O(n) | 3RTT | ~50K TPS | ~1000 |
| Avalanche | O(k·log n) | <1s | ~4500 TPS | 无上限 |
五、Avalanche:随机抽样共识
5.1 Snowball Protocol
go
type Snowball struct {
k int // 每轮抽样数
alpha int // 多数阈值
beta int // 连续确认轮数
preference Color // 当前偏好(0或1)
count int // 连续偏好计数
}
func (s *Snowball) decide() Color {
for {
// 1. 随机抽样k个节点
samples := randSample(s.network, s.k)
// 2. 查询偏好
votes := query(samples)
majority := tally(votes)
// 3. 更新偏好
if countOf(majority) >= s.alpha {
if s.preference == majority {
s.count++
} else {
s.preference = majority
s.count = 1
}
}
// 4. 连续beta轮 → 确定
if s.count >= s.beta {
return s.preference
}
}
}
// 优势:
// - 无Leader,完全去中心化
// - 吞吐量与节点数无关(每次只抽样k个)
// - 亚秒级最终确定性
// - 支持数万验证者
六、总结
区块链共识的演化路径:
- PBFT(1999) --- 奠基理论:3f+1容错+三阶段协议
- Tendermint(2014) --- 工程化:round-based+锁机制+增量超时
- HotStuff(2018) --- 革命性:线性消息复杂度+流水线+三链确认
- Avalanche(2020) --- 新范式:随机抽样+亚稳态+无Leader
选择:联盟链用PBFT,公链PoS用HotStuff,高去中心化用Avalanche。