T02 HotStuff 入门:QC 认证、Lock 约束、Commit 最终化,是三件不同的事
四个节点、三票一个 quorum,交集里那个诚实节点堵死了双花;再顺着 demo 的七步一个 view,看 HighQC、LockedQC、Commit 三格如何整齐右移。
一句话版
这一讲把 HotStuff 拆成两句话:收到 2f + 1 票就把一个块变成有证据的 QC,收到连着三个这样的 QC 才敢说它已经定了。 中间那段看起来啰嗦的 HighQC / LockedQC 字段,都是在回答同一个问题——leader 随时可能挂、可能撒谎,凭什么相信它现在递过来的这个块。课件的 demo 把这套机制缩成四个节点、一个中央队列和几十个可单步执行的 STEP,好处是能亲眼看见三个字段一格一格往前挪,代价是它砍掉了签名、view change、真实网络这些真协议里最难的部分。看 demo 的时候要始终分清:哪些是 HotStuff 本身,哪些是为了教学装上去的轮子。
题目地图
| 页 | 考什么 | 主要失分点 |
|---|---|---|
| p.6–8 | 为什么 n ≥ 3f + 1、quorum 为什么要 2f + 1 | 只背数字,不会用交集算式推 |
| p.7 vs p.9 | basic 与 chained 两种形态的区别 | 把四阶段名字套到 demo 的每个 view 上 |
| p.11–15 | 正常路径七步、三个字段的取值 | 记住了顺序,说不出每步之后三格在哪 |
| p.16–18 | 投票安全规则、锁为什么可以被合法绕过 | 把两条件当「且」,于是认为锁死了就永远换不动 |
| p.19–20 | 三链提交、view 连续的要求 | 以为块有了 QC 就等于提交 |
| p.21–29 | 故障演练、性能主张、demo 的简化边界 | 把 demo 的教学简化当成协议特性 |
概念卡
① 法定人数与 quorum 交集
人话定义:一共 n = 4 个节点、最多坏 f = 1 个,那么凑齐 q = 2f + 1 = 3 票才算数。这个 3 不是拍脑袋定的,它要同时满足两件事:去掉 f 个坏节点后还剩多数,且任意两组三人必然重叠。
例子:Quorum A 是 N1、N2、N3,Quorum B 是 N2、N3、N4,交集至少 3 + 3 − 4 = 2 个人,大于 f = 1,说明交集里一定有诚实节点。
常见误解:交集有人就安全了
交集本身不产生安全性,它只是把矛盾逼到一个人身上。真正封死的是那条投票铁律——每个正确副本每个 view 至多投一票。两条合起来才有结论:想造出两个冲突的 QC,就得让交集里那个诚实节点在同一个 view 投两次,而它不会。
② QC、HighQC 与 LockedQC
人话定义:QC 是「2f + 1 票的打包凭证」,谁拿到都能验,也能转交给别人。HighQC 是我见过的 view 最高的那个 QC,负责往前跑;LockedQC 是三链里中间那个 QC,负责踩刹车。
例子:demo 界面每个节点显示五个字段——View / Leader、HighQC、LockedQC、Latest block、Commit block。链跑起来之后盯着看几轮就会发现,LockedQC 总比 HighQC 慢一格。
常见误解:两个字段记的是同一件事的不同写法
它们的职责相反。HighQC 越新越好,leader 靠收集其他人的 HighQC 决定从哪儿接着长;LockedQC 故意保守,它代表「我已经有理由相信这条分支可能会被提交」,所以要拦住随便切换。一个管活性,一个管安全性,把它们合并成一个字段,协议就塌了。
③ 链式结构与三链提交
人话定义:块 B 有了 QC,只说明它被认证过;它的儿子也有 QC,B 才升级成锁定依据;孙子也有 QC,B 才被提交。三个 QC 必须父子相连,而且 view 连续。
例子:正常路径跑到 STEP 20 时,HighQC 指 B3、LockedQC 指 B2、Commit 指 B1——B1 是最早那个凑满三代的块。
常见误解:中间断一格也能凑够三个
不行。view 连续是硬要求:如果 view 5、6 成链但 view 7 超时换人,那条三链就断了,得从新的起点重新积累。HotStuff 在网络不稳时延迟变大,根子就在这里:链老是攒到一半断掉,得重来。
④ Pacemaker 与 view 轮换
人话定义:谁当 leader、什么时候换人,由 Pacemaker 管;票怎么投、什么时候能提交,由安全规则管。两件事被刻意分开,改一个不影响另一个。
例子:demo 用最简单的轮转,Leader(view) = ((view − 1) mod 4) + 1,所以 view 1 到 4 依次由 N1 到 N4 当班,view 5 又轮回 N1。
常见误解:换 leader 属于安全机制
反过来。安全性在任何 leader 调度下都成立,哪怕连着一百个 view 都选到坏节点,也只会卡住不出块,不会出现两条冲突的已提交链。Pacemaker 决定的是「多久能恢复出块」,那是活性。协议宁可牺牲活性也不牺牲安全性,这条取舍贯穿整讲。
⑤ 线性通信与乐观响应
人话定义:线性通信指每轮的消息量随节点数线性增长;乐观响应指 leader 凑齐 2f + 1 个回复就立刻推进,而不是干等一个固定超时。
例子:PBFT 的全网互广是 O(n²),HotStuff 改成所有人只跟 leader 说话的星形拓扑,再用门限签名把 2f + 1 个签名压成一个,于是降到 O(n)。
常见误解:乐观响应意味着任何时候都能跑满速度
它有前提:只在 GST 之后、网络恢复正常同步时成立。GST 之前消息可以任意延迟,等不到 2f + 1 个回复就还是得靠超时兜底。这也是「部分同步模型」这个词的全部含义。
逐题拆解
为什么是 3f + 1 而不是 2f + 1 个节点。 用「减一再比较」推:quorum 取 2f + 1,最坏情况下这里面混了 f 个坏节点,还剩 f + 1 个诚实节点;要让这 f + 1 比剩下的坏节点多,需要 n − 2f > f,整理即 n > 3f。取整数就是 n ≥ 3f + 1。四个节点容一个坏人,是这条不等式的最小解。
basic 与 chained 的分界线。 p.7 画的 PREPARE → PRE-COMMIT → COMMIT → DECIDE 是 basic HotStuff,一个块要跑四个来回。p.9 之后 demo 演的是 chained 版本:每个 view 只跑一轮,但这一轮同时在为不同高度的块承担不同阶段的职责——你这轮给 B3 投的票,顺带把 B2 推成锁定依据、把 B1 推成已提交。这是整份课件最容易记串的地方,看到「四个阶段」先问一句说的是哪个版本。
正常路径七步循环。 每个 view 固定七步:leader 收集 HighQC、打包新块、广播、各节点按安全规则投票、leader 收票、凑满 2f + 1 形成 QC、推进到下一个 view。三个检查点值得背下来——STEP 6 之后是 (B1, B0, B0),STEP 13 之后是 (B2, B1, B0),STEP 20 之后是 (B3, B2, B1)。三格每次一起右移一格,这个节奏比记具体步号更有用。
两条投票安全条件为什么是「或」。 条件一是新块扩展自 LockedQC 锁住的块,条件二是新块携带的 QC 的 view 严格高于我 LockedQC 的 view。只要满足其中一条就能投。第一条守安全,第二条是逃生口:如果我锁在一条已经被网络抛弃的分支上,而别人拿出了更新的 QC 作为证据,我就该跟着换。锁拒绝的是没有依据的切换,不是所有切换。
锁规则的三行判定。 假设我的 LockedQC = QC(B1)、view = 1。新块扩展自 B1 → 接受;新块与 B1 冲突且携带的 QC view ≤ 1 → 拒绝;新块与 B1 冲突但携带 view = 2 的有效 QC → 接受,并顺势更新自己的锁。考试给你一个 view 和一条分支,照这三行套就行。
故障演练读出了什么。 leader 崩溃那次,活着的三个节点恰好就是法定人数,QC 照常形成,只是它属于新的 view 而非原来那个;崩掉的节点没有被踢出系统,只是没人再等它。有人扣票那次更干净——正常路径里第四票本来就是多余的,收到三票就够。把 4 → 有 QC、3 → 有 QC、2 → 没有 QC 这条边界记牢:故障不会降低法定人数,证据不足只意味着继续等。
课件里的坑
- [口径差异] p.7 的四阶段和 p.9 起的 demo 不是同一套流程,前者是 basic、后者是 chained。课件没有明写这个切换点,直接往下看会以为 demo 每个 view 也有四个阶段。(p.7、p.9)
- [口径差异] 「certified、locked、committed」在课件里都被随口叫成「确认」。它们是三个不同的协议状态,p.29 那句一行总结才把话说清楚。做题时把「确认」这个词拆开读。(p.29)
- [课件留白] 交集算式 3 + 3 − 4 = 2 用的是容斥原理,课件只给结论没给推导。自己补一句:两组各 3 人塞进 4 个位置,重叠至少 2 人。(p.8)
- [课件留白] 两条投票条件之间的「或」在幻灯片上只是排版并列,没有写明是析取关系。把它读成「且」,后面所有换 leader 的场景都解释不通。(p.17)
- [补充] demo 的提交规则课件自己标成「conservative teaching rule」,比协议实际需要的更严;真实实现会在能提交时就提交。看到 demo 比预期晚提交,先怀疑这条而非怀疑自己算错。(p.27)
- [补充] demo 明列六处简化:签名换成节点 ID 列表、view change 简化为直接读活节点的 HighQC、时序换成中央队列加逻辑时钟、提交规则从严、故障只模拟崩溃与扣票、恢复直接从可信节点拷状态。恶意分叉和双重投票根本没被模拟,所以别拿 demo 的运行结果论证协议能扛拜占庭行为。(p.27)
课后 10 分钟:考点复习
这 10 分钟怎么用:先把必背八条默一遍,再打开 demo 单步跑一个 view,跑到第七步暂停,闭着眼说出三个字段现在各指向哪个块,对不上就回去看逐题拆解那节。剩下的时间做变式题,别看答案。
必背
- n = 4、f = 1,法定人数 q = 2f + 1 = 3;两个 quorum 的交集 ≥ 3 + 3 − 4 = 2 > f,所以同一个 view 里不可能有两个冲突的 QC。
- 课件 p.7 的 PREPARE / PRE-COMMIT / COMMIT / DECIDE 属于 basic HotStuff;p.9 之后的 demo 是 chained HotStuff,一个 view 只跑一轮。
- HighQC 记「见过的最高 QC」负责推进,LockedQC 记「三链中间那个 QC」负责约束;链跑起来之后 LockedQC 比 HighQC 落后一格,起步阶段 p.20 表里两者同为 B0。
- 投票的两条安全条件是「或」:新块扩展自 LockedQC 锁住的块,或它携带的 QC 的 view 严格高于 LockedQC 的 view。
- 三链提交要求三个 QC 父子相连且 view 连续:B1 被认证、B2 的 QC 让 B1 成为锁定依据、B3 的 QC 才真正提交 B1。
- Leader(view) = ((view − 1) mod 4) + 1;正常路径每个 view 七步,STEP 6 / 13 / 20 的 (HighQC, LockedQC, Commit) 依次是 (B1, B0, B0)、(B2, B1, B0)、(B3, B2, B1)。
- leader 崩溃或有人扣票时,剩下三个节点恰好就是法定人数,QC 照样形成;故障不降低法定人数,证据不足只意味着等待。
- 线性通信来自星形拓扑加门限签名(PBFT 是 O(n²));乐观响应指凑齐 2f + 1 个回复就推进而非等固定超时,且只在 GST 之后成立。
完整例题
题:n = 4、f = 1。节点 N3 当前 LockedQC = QC(B1),其 view = 1。现在 view 3 的 leader 发来一个新块 B’,B’ 与 B1 冲突(不在 B1 那条分支上),随块携带一个 view = 2 的合法 QC。N3 该不该投票?投了会不会破坏安全性?
解:先查两条条件。条件一——B’ 扩展自 B1 吗?不,题目说冲突,条件一不满足。条件二——B’ 携带的 QC 的 view = 2,严格大于 LockedQC 的 view = 1,条件二满足。两条是「或」,所以 N3 应该投票,并把自己的锁更新到那个 view = 2 的 QC 上。
安全性为什么不破:那个 view = 2 的 QC 意味着至少 3 个节点在 view 2 认可了 B’ 所在的分支。而 B1 若要被提交,需要它、它的儿子、它的孙子三代连续拿 QC。如果 B1 的后代在 view 2 真的成了链,交集里的诚实节点就得在 view 2 同时给两条冲突分支投票,这被一票制封死。所以 view 2 的 QC 存在本身,就是「B1 那条线没走成」的证据——换过去是有依据的,不是任性。
变式题(先自己做)
变式 1:同样的局面,但 B’ 携带的 QC 的 view = 1,与 N3 的 LockedQC 同一个 view。N3 该怎么做?
提示
注意条件二写的是「严格高于」。同 view 意味着什么证据都没多给。
参考答案与自检(非官方评分标准)
拒绝投票。条件一不满足(冲突),条件二也不满足(view = 1 不严格大于 1)。同一个 view 里出现两条冲突分支,恰恰是最该警惕的情形——由一票制可知其中至多一条能凑出 QC,N3 没有理由放弃自己已经锁定的那条。这正是「锁」发挥作用的时刻。
变式 2:demo 跑到 STEP 13,某节点的三个字段显示 HighQC = QC(B2)、LockedQC = QC(B1)、Commit = B0。此时 B1 算不算已经定了?如果不算,还差什么?
提示
数一数以 B1 为起点,往下已经连出几个带 QC 的块。
参考答案与自检(非官方评分标准)
不算。B1 目前只走到「锁定依据」这一档:它自己有 QC,儿子 B2 也有 QC,两代成链。还差第三代——要等 B3 也拿到 QC(即 STEP 20),Commit 才会从 B0 移到 B1。判断口径是数连续带 QC 的代数,而不是看 LockedQC 指着谁。
变式 3:把节点数改成 n = 7,容错上限 f 最大能取多少?法定人数是多少?两个 quorum 的交集至少几人?
提示
先用 n ≥ 3f + 1 反解 f,再代入 q = 2f + 1,最后用容斥算交集。
参考答案与自检(非官方评分标准)
7 ≥ 3f + 1 解得 f ≤ 2,取 f = 2。法定人数 q = 2 × 2 + 1 = 5。交集至少 5 + 5 − 7 = 3 人,大于 f = 2,所以交集里至少有 1 个诚实节点,结论与 n = 4 的情形完全一致。这说明那条交集算式是通用的,换任何 n 都照着 2q − n > f 验一遍即可。
闪卡自测
-
QC 是什么?
2f + 1 张针对同一个块的票打包成的凭证,可验证、可转交。 -
HighQC 和 LockedQC 谁跑得快?
HighQC。链跑起来后 LockedQC 落后它一格,一个管推进一个管约束。 -
提交一个块需要几个连续的 QC?
三个,而且必须父子相连、view 连续。 -
投票的两条安全条件是「且」还是「或」?
或。第二条是允许有依据换分支的逃生口。 -
view 7 的 leader 是谁(n = 4 轮转)?
((7 − 1) mod 4) + 1 = 3,即 N3。 -
三个节点还活着时能形成 QC 吗?
能,3 恰好等于法定人数。两个就不行了。 -
HotStuff 相对 PBFT 的通信复杂度优势从哪来?
星形拓扑加门限签名,把 O(n²) 压到 O(n)。 -
乐观响应的前提是什么?
GST 之后网络恢复同步。此前仍需超时兜底。
下一步
这一讲搭好了骨架,真正花时间的是把 demo 跑起来单步走几轮,边走边在纸上记三个字段的位置——机制层面的理解几乎全在那张表里。下一步会接着讲这套协议在工程上怎么落地:门限签名的实际用法、view change 在真实网络里要处理的消息,以及 demo 里那六处简化各自对应真协议的哪一块。往前看的话,把 HotStuff 的四栏(部分同步、f、O(n)、不阻塞)填进协议对照表,跟后面的 PBFT、Raft 放在一起比,期末开卷时那张表比任何笔记都管用。
个人整理的学习笔记,不是官方材料;数字与结论以课件和讲师为准。