论文:Lamport L, Shostak R, Pease M. The Byzantine generals problem[M]//Concurrency: the works of leslie lamport. 2019: 203-226.
在分布式计算的场景下,不同的处理器计算出不同的结果,但最终需要使得各个处理器达成一致。
拜占庭帝国的将军们在开疆拓土,将军们各领一军。目前他们正在对一个城池商量行动方案,将军们分别观察敌情,利用无噪声信道通信。仅当半数以上的将军同时发起进攻时才会取得胜利,否则应当集体撤退避免失败。
同时,在将军们内部可能会有一些叛徒,叛徒会通过发送一些矛盾的信息来干扰忠诚将军的判断。我们不限制叛徒的能力,他们可以做任何事情。
我们想要解决如下问题:所有的忠诚将军需要确定一致的行动计划,且少量叛徒无法使得忠诚的将军们采取糟糕的行动。我们使用少数服从多数策略进行投票。为了满足上述条件,需要
下面,我们考虑简化版本的拜占庭将军问题: 1 1 1个主将发送指令给 n − 1 n-1 n−1个副将,并满足 the interactive consistency conditions,
原始版本的拜占庭将军问题,可以通过调用 n n n次上述问题的解,使得所有的忠诚将军 j ≠ i j \neq i j=i对某个将军 i i i所发送的行动 v ( i ) v(i) v(i)达成一致。然后,将军们各自根据 v ( 1 ) , ⋯ , v ( n ) v(1),\cdots,v(n) v(1),⋯,v(n)进行少数服从多数的投票。由于消息列表一致,因此投票结果相同,忠诚的将军们对军事行动达成一致。
我们先定义口头消息(oral message)通信系统,它满足以下假设
另外,针对叛徒主将不发送消息的情形,忠诚副将也必须采取某种行动,默认“retreat”。
首先,我们证明:对于拜占庭三将军问题(即 1 1 1个叛徒 2 2 2个忠诚将军)无解。
如图所示,
于是,在图2中的副将 1 1 1无法区分谁是叛徒,他只能选择“attack”。同样的,副将 2 2 2也无法区分谁是叛徒,他只能选择“retreat”。这与 IC1 矛盾。

我们将证明:如果存在 m m m个叛徒,那么 n ≤ 3 m n \le 3m n≤3m个将军的问题无解。
假设存在这种解,我们称它为阿尔巴尼亚将军(Albanian generals)算法。然后我们让拜占庭将军(Byzantine generals)来模拟这些阿尔巴尼亚将军:拜占庭主将模拟 1 1 1个阿尔巴尼亚主将以及 m − 1 m-1 m−1个阿尔巴尼亚副将,另外两个拜占庭副将各自模拟 m m m个阿尔巴尼亚副将。由于只有一个拜占庭叛徒,因此至多存在 m m m个阿尔巴尼亚叛徒。调用阿尔巴尼亚算法,这些阿尔巴尼亚将军是满足 IC1 和 IC2 的。那么,
这就给出了拜占庭三将军问题的一个解。然而,我们已经证明拜占庭三将军问题不可解,矛盾!
我们给出 Oral Message algorithms O M ( m ) OM(m) OM(m),这里 m ∈ N m \in \mathbb N m∈N,算法用于解决 “存在至多 m m m个叛徒,且将军数量 n ≥ 3 m + 1 n \ge 3m+1 n≥3m+1” 的拜占庭将军问题。
Algorithm O M ( 0 ) OM(0) OM(0)
Algorithm O M ( m ) , m ≥ 1 OM(m),\, m \ge 1 OM(m),m≥1
注意,忠诚的将军都会诚实地执行上述算法,而叛徒会以任意方式执行任何动作。
容易看出,迭代过程形成了一颗树,根节点有 n − 1 n-1 n−1个分支,第二层节点有 n − 2 n-2 n−2个分支,等等。算法 O M ( m − k ) OM(m-k) OM(m−k)被反复调用了 ( n − 1 ) ⋯ ( n − k ) = A k n (n-1)\cdots(n-k) = A^n_k (n−1)⋯(n−k)=Akn次,算法 O M ( 0 ) OM(0) OM(0)被调用了 A m n A_m^n Amn次,通信量还是蛮大的。但可以证明,这些通信都是必要的。
Proof:
基础,当 m = 0 m=0 m=0时,不存在叛徒,主将忠诚,算法 O M ( 0 ) OM(0) OM(0)明显满足 IC2。
假设, ∀ m > 0 , O M ( m − 1 ) \forall m>0,\,OM(m-1) ∀m>0,OM(m−1)满足 IC2。
归纳,在算法 O M ( m ) OM(m) OM(m)里的第一步,忠诚的主将下令 v v v给 n − 1 n-1 n−1个副将;然后第二步,各个副将分别执行 O M ( m − 1 ) OM(m-1) OM(m−1);根据假设,如果副将 i i i是忠诚的,那么其他忠诚副将 j ≠ i j \neq i j=i将会获得这个副将的命令 v i = v v_i = v vi=v,满足 IC2(自然满足 IC1,消息列表一致);由于 n − 1 > 2 k + ( m − 1 ) ≥ 2 k n-1 > 2k+(m-1) \ge 2k n−1>2k+(m−1)≥2k,因此这些副将中忠诚的占严格多数,因此第三步中忠诚的副将计算 m a j o r i t y ( v 1 , ⋯ , v n − 1 ) = v majority(v_1,\cdots,v_{n-1})=v majority(v1,⋯,vn−1)=v,这就是忠诚主将的命令,满足 IC2。
Proof:
基础,当 m = 0 m=0 m=0时,当 m = 0 m=0 m=0时,不存在叛徒,主将忠诚,算法 O M ( 0 ) OM(0) OM(0)明显满足 IC2,自然也满足 IC1。
假设, ∀ m > 0 , O M ( m − 1 ) \forall m>0,\,OM(m-1) ∀m>0,OM(m−1)满足 IC2 和 IC1。
归纳,在算法 O M ( m ) OM(m) OM(m)里的第一步,主将下令 v v v给 n − 1 n-1 n−1个副将,
综上所述, O M ( m ) OM(m) OM(m)满足 IC1。
容易看出,正是因为叛徒的强大欺诈能力,使得拜占庭将军问题的解决方案十分困难。下面,使用签名方案来约束其能力:
另外,叛徒们可以互相勾结,互相伪造签名。
这种签名消息(signed messages)在传递的过程中,被将军们不断确认并附加签名,例如 v : i : j v:i:j v:i:j表示,消息 v v v被将军 i i i发布并签名,然后将军 j j j确认接收到了消息 v v v并认为 i i i的签名合法。
在约束叛徒的能力后,拜占庭三将军问题可解!事实上,算法可以处理存在 m m m个叛徒的任意数量 n n n的拜占庭将军问题。当然 n ≥ m + 2 n \ge m+2 n≥m+2问题才有意义。
首先,我们需要一个选择函数 c h o i c e choice choice,针对命令集合 V V V(相同元素至多出现 1 1 1次)
一般地, c h o i c e choice choice选择为有序集合 V V V的中位元素(the median element)。主将编号为 0 0 0,任意的副将 i ≠ 0 i \neq 0 i=0都维护着一个命令集合 V i V_i Vi,初始化为空集。
Algorithm S M ( m ) , m ≥ 0 SM(m),\, m \ge 0 SM(m),m≥0
同样的,忠诚的将军都会诚实地执行上述算法,而叛徒会以任意方式(但被限制了欺诈能力)执行任何动作。
在步骤2里,副将 i i i忽略任何不符合正确签名格式的值。对于不合法签名的消息,其来源一定为叛徒。对于叛徒主将不发送消息给副将 i i i的情况,忠诚副将 i i i不需要做任何动作(不要默认"retreat",这与口头消息算法不同)。如果叛徒主将不给任何副将发送消息,那么忠诚副将的集合 V i V_i Vi都为空集。如果叛徒们只给某一个忠诚副将发消息,忠诚副将将会广播给其他所有副将。如果忠诚副将收到了多个有效的 v 1 : 0 , v 2 : 0 , ⋯ v_1:0,v_2:0,\cdots v1:0,v2:0,⋯,那么主将一定是叛徒(可能是主将发送了矛盾指令给不同副将,也可以是串通的叛徒副将伪造了命令 v ′ : 0 v':0 v′:0),只要忠诚副将的 V V V保证一致即可,来确定最终的行动一致。
在步骤3里,可以使用超时机制(time-out)来确定不会再收到新的消息。
Proof:
如果主将是忠诚的,那么第一步中他发送相同的 v : 0 v:0 v:0给所有副将。而所有忠诚副将都将接受 v v v并写入 V V V。另外,叛徒副将无法伪造出 v ′ : 0 v':0 v′:0,因此忠诚副将不会再在 V V V中添加指令。因此,所有忠诚副将都将在第三步执行 c h o i c e ( { v } ) = v choice(\{v\}) = v choice({v})=v,满足IC2,此时也满足 IC1。
如果主将是叛徒,我们可以证:第二步结束后,任意两个忠诚副将的集合相等 V i = V j V_i = V_j Vi=Vj,也就是如果副将 i i i获得过 v v v,那么副将 j j j也一定获得了命令 v v v。令副将 i i i在接收到 v : 0 : j 1 : ⋯ : j k v:0:j_1:\cdots:j_k v:0:j1:⋯:jk时,将 v v v添加到了 V i V_i Vi里
因此,所有忠诚副将的命令集合 V i V_i Vi都相同,执行 c h o i c e choice choice后采取相同的行动计划,符合 IC1。
综上所述, O M ( m ) OM(m) OM(m)满足 IC1 和 IC2。
前面的口头消息算法和签名消息算法,它们的信道都是支持任意两个将军之间的直接通信的。也就是说,它们的通信网络拓扑是完全图。
Lamport 等人在论文中也给出了针对 p − p- p−正则图的口头消息的解决方案。大体上说,就是根据节点 i i i的正则邻居集(regular set of neighbors) N = { i 1 , ⋯ , i p } N=\{i_1,\cdots,i_p\} N={i1,⋯,ip},递归调用算法 O M ( m , p ) OM(m,p) OM(m,p),一层一层地(到主将的路程)传递命令。根据正则邻居的消息 { v i 1 , ⋯ , v i p } \{v_{i_1},\cdots,v_{i_p}\} {vi1,⋯,vip}来进行少数服从多数的投票。
具体算法不写了,诸位自行查阅原始论文 o(´^`)o
在口头消息算法中,需要一个满足A1, A2, A3的信道。在签名消息算法中,额外需要满足A4, A5。