区块链 --- 共识算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链 --- 共识算法相关的知识,希望对你有一定的参考价值。
参考技术APoW算法是一种防止分布式服务资源被滥用、拒绝服务攻击的机制。它要求节点进行适量消耗时间和资源的复杂运算,并且其运算结果能被其他节点快速验算,以耗用时间、能源做担保,以确保服务与资源被真正的需求所使用。
PoW算法中最基本的技术原理是使用哈希算法。假设求哈希值Hash(r),若原始数据为r(raw),则运算结果为R(Result)。
R = Hash(r)
哈希函数Hash()的特性是,对于任意输入值r,得出结果R,并且无法从R反推回r。当输入的原始数据r变动1比特时,其结果R值完全改变。在比特币的PoW算法中,引入算法难度d和随机值n,得到以下公式:
Rd = Hash(r+n)
该公式要求在填入随机值n的情况下,计算结果Rd的前d字节必须为0。由于哈希函数结果的未知性,每个矿工都要做大量运算之后,才能得出正确结果,而算出结果广播给全网之后,其他节点只需要进行一次哈希运算即可校验。PoW算法就是采用这种方式让计算消耗资源,而校验仅需一次。
PoS算法要求节点验证者必须质押一定的资金才有挖矿打包资格,并且区域链系统在选定打包节点时使用随机的方式,当节点质押的资金越多时,其被选定打包区块的概率越大。
POS模式下,每个币每天产生1币龄,比如你持有100个币,总共持有了30天,那么,此时你的币龄就为3000。这个时候,如果你验证了一个POS区块,你的币龄就会被清空为0,同时从区块中获得相对应的数字货币利息。
节点通过PoS算法出块的过程如下:普通的节点要成为出块节点,首先要进行资产的质押,当轮到自己出块时,打包区块,然后向全网广播,其他验证节点将会校验区块的合法性。
DPoS算法和PoS算法相似,也采用股份和权益质押。
但不同的是,DPoS算法采用委托质押的方式,类似于用全民选举代表的方式选出N个超级节点记账出块。
选民把自己的选票投给某个节点,如果某个节点当选记账节点,那么该记账节点往往在获取出块奖励后,可以采用任意方式来回报自己的选民。
这N个记账节点将轮流出块,并且节点之间相互监督,如果其作恶,那么会被扣除质押金。
通过信任少量的诚信节点,可以去除区块签名过程中不必要的步骤,提高了交易的速度。
拜占庭问题:
拜占庭是古代东罗马帝国的首都,为了防御在每块封地都驻扎一支由单个将军带领的军队,将军之间只能靠信差传递消息。在战争时,所有将军必须达成共识,决定是否共同开战。
但是,在军队内可能有叛徒,这些人将影响将军们达成共识。拜占庭将军问题是指在已知有将军是叛徒的情况下,剩余的将军如何达成一致决策的问题。
BFT:
BFT即拜占庭容错,拜占庭容错技术是一类分布式计算领域的容错技术。拜占庭假设是对现实世界的模型化,由于硬件错误、网络拥塞或中断以及遭到恶意攻击等原因,计算机和网络可能出现不可预料的行为。拜占庭容错技术被设计用来处理这些异常行为,并满足所要解决的问题的规范要求。
拜占庭容错系统 :
发生故障的节点被称为 拜占庭节点 ,而正常的节点即为 非拜占庭节点 。
假设分布式系统拥有n台节点,并假设整个系统拜占庭节点不超过m台(n ≥ 3m + 1),拜占庭容错系统需要满足如下两个条件:
另外,拜占庭容错系统需要达成如下两个指标:
PBFT即实用拜占庭容错算法,解决了原始拜占庭容错算法效率不高的问题,算法的时间复杂度是O(n^2),使得在实际系统应用中可以解决拜占庭容错问题
PBFT是一种状态机副本复制算法,所有的副本在一个视图(view)轮换的过程中操作,主节点通过视图编号以及节点数集合来确定,即:主节点 p = v mod |R|。v:视图编号,|R|节点个数,p:主节点编号。
PBFT算法的共识过程如下:客户端(Client)发起消息请求(request),并广播转发至每一个副本节点(Replica),由其中一个主节点(Leader)发起提案消息pre-prepare,并广播。其他节点获取原始消息,在校验完成后发送prepare消息。每个节点收到2f+1个prepare消息,即认为已经准备完毕,并发送commit消息。当节点收到2f+1个commit消息,客户端收到f+1个相同的reply消息时,说明客户端发起的请求已经达成全网共识。
具体流程如下 :
客户端c向主节点p发送<REQUEST, o, t, c>请求。o: 请求的具体操作,t: 请求时客户端追加的时间戳,c:客户端标识。REQUEST: 包含消息内容m,以及消息摘要d(m)。客户端对请求进行签名。
主节点收到客户端的请求,需要进行以下交验:
a. 客户端请求消息签名是否正确。
非法请求丢弃。正确请求,分配一个编号n,编号n主要用于对客户端的请求进行排序。然后广播一条<<PRE-PREPARE, v, n, d>, m>消息给其他副本节点。v:视图编号,d客户端消息摘要,m消息内容。<PRE-PREPARE, v, n, d>进行主节点签名。n是要在某一个范围区间内的[h, H],具体原因参见 垃圾回收 章节。
副本节点i收到主节点的PRE-PREPARE消息,需要进行以下交验:
a. 主节点PRE-PREPARE消息签名是否正确。
b. 当前副本节点是否已经收到了一条在同一v下并且编号也是n,但是签名不同的PRE-PREPARE信息。
c. d与m的摘要是否一致。
d. n是否在区间[h, H]内。
非法请求丢弃。正确请求,副本节点i向其他节点包括主节点发送一条<PREPARE, v, n, d, i>消息, v, n, d, m与上述PRE-PREPARE消息内容相同,i是当前副本节点编号。<PREPARE, v, n, d, i>进行副本节点i的签名。记录PRE-PREPARE和PREPARE消息到log中,用于View Change过程中恢复未完成的请求操作。
主节点和副本节点收到PREPARE消息,需要进行以下交验:
a. 副本节点PREPARE消息签名是否正确。
b. 当前副本节点是否已经收到了同一视图v下的n。
c. n是否在区间[h, H]内。
d. d是否和当前已收到PRE-PPREPARE中的d相同
非法请求丢弃。如果副本节点i收到了2f+1个验证通过的PREPARE消息,则向其他节点包括主节点发送一条<COMMIT, v, n, d, i>消息,v, n, d, i与上述PREPARE消息内容相同。<COMMIT, v, n, d, i>进行副本节点i的签名。记录COMMIT消息到日志中,用于View Change过程中恢复未完成的请求操作。记录其他副本节点发送的PREPARE消息到log中。
主节点和副本节点收到COMMIT消息,需要进行以下交验:
a. 副本节点COMMIT消息签名是否正确。
b. 当前副本节点是否已经收到了同一视图v下的n。
c. d与m的摘要是否一致。
d. n是否在区间[h, H]内。
非法请求丢弃。如果副本节点i收到了2f+1个验证通过的COMMIT消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求操作o,并返回<REPLY, v, t, c, i, r>给客户端,r:是请求操作结果,客户端如果收到f+1个相同的REPLY消息,说明客户端发起的请求已经达成全网共识,否则客户端需要判断是否重新发送请求给主节点。记录其他副本节点发送的COMMIT消息到log中。
如果主节点作恶,它可能会给不同的请求编上相同的序号,或者不去分配序号,或者让相邻的序号不连续。备份节点应当有职责来主动检查这些序号的合法性。
如果主节点掉线或者作恶不广播客户端的请求,客户端设置超时机制,超时的话,向所有副本节点广播请求消息。副本节点检测出主节点作恶或者下线,发起View Change协议。
View Change协议 :
副本节点向其他节点广播<VIEW-CHANGE, v+1, n, C , P , i>消息。n是最新的stable checkpoint的编号, C 是 2f+1验证过的CheckPoint消息集合, P 是当前副本节点未完成的请求的PRE-PREPARE和PREPARE消息集合。
当主节点p = v + 1 mod |R|收到 2f 个有效的VIEW-CHANGE消息后,向其他节点广播<NEW-VIEW, v+1, V , O >消息。 V 是有效的VIEW-CHANGE消息集合。 O 是主节点重新发起的未经完成的PRE-PREPARE消息集合。PRE-PREPARE消息集合的选取规则:
副本节点收到主节点的NEW-VIEW消息,验证有效性,有效的话,进入v+1状态,并且开始 O 中的PRE-PREPARE消息处理流程。
在上述算法流程中,为了确保在View Change的过程中,能够恢复先前的请求,每一个副本节点都记录一些消息到本地的log中,当执行请求后副本节点需要把之前该请求的记录消息清除掉。
最简单的做法是在Reply消息后,再执行一次当前状态的共识同步,这样做的成本比较高,因此可以在执行完多条请求K(例如:100条)后执行一次状态同步。这个状态同步消息就是CheckPoint消息。
副本节点i发送<CheckPoint, n, d, i>给其他节点,n是当前节点所保留的最后一个视图请求编号,d是对当前状态的一个摘要,该CheckPoint消息记录到log中。如果副本节点i收到了2f+1个验证过的CheckPoint消息,则清除先前日志中的消息,并以n作为当前一个stable checkpoint。
这是理想情况,实际上当副本节点i向其他节点发出CheckPoint消息后,其他节点还没有完成K条请求,所以不会立即对i的请求作出响应,它还会按照自己的节奏,向前行进,但此时发出的CheckPoint并未形成stable。
为了防止i的处理请求过快,设置一个上文提到的 高低水位区间[h, H] 来解决这个问题。低水位h等于上一个stable checkpoint的编号,高水位H = h + L,其中L是我们指定的数值,等于checkpoint周期处理请求数K的整数倍,可以设置为L = 2K。当副本节点i处理请求超过高水位H时,此时就会停止脚步,等待stable checkpoint发生变化,再继续前进。
在区块链场景中,一般适合于对强一致性有要求的私有链和联盟链场景。例如,在IBM主导的区块链超级账本项目中,PBFT是一个可选的共识协议。在Hyperledger的Fabric项目中,共识模块被设计成可插拔的模块,支持像PBFT、Raft等共识算法。
Raft基于领导者驱动的共识模型,其中将选举一位杰出的领导者(Leader),而该Leader将完全负责管理集群,Leader负责管理Raft集群的所有节点之间的复制日志。
下图中,将在启动过程中选择集群的Leader(S1),并为来自客户端的所有命令/请求提供服务。 Raft集群中的所有节点都维护一个分布式日志(复制日志)以存储和提交由客户端发出的命令(日志条目)。 Leader接受来自客户端的日志条目,并在Raft集群中的所有关注者(S2,S3,S4,S5)之间复制它们。
在Raft集群中,需要满足最少数量的节点才能提供预期的级别共识保证, 这也称为法定人数。 在Raft集群中执行操作所需的最少投票数为 (N / 2 +1) ,其中N是组中成员总数,即 投票至少超过一半 ,这也就是为什么集群节点通常为奇数的原因。 因此,在上面的示例中,我们至少需要3个节点才能具有共识保证。
如果法定仲裁节点由于任何原因不可用,也就是投票没有超过半数,则此次协商没有达成一致,并且无法提交新日志。
数据存储:Tidb/TiKV
日志:阿里巴巴的 DLedger
服务发现:Consul& etcd
集群调度:HashiCorp Nomad
只能容纳故障节点(CFT),不容纳作恶节点
顺序投票,只能串行apply,因此高并发场景下性能差
Raft通过解决围绕Leader选举的三个主要子问题,管理分布式日志和算法的安全性功能来解决分布式共识问题。
当我们启动一个新的Raft集群或某个领导者不可用时,将通过集群中所有成员节点之间协商来选举一个新的领导者。 因此,在给定的实例中,Raft集群的节点可以处于以下任何状态: 追随者(Follower),候选人(Candidate)或领导者(Leader)。
系统刚开始启动的时候,所有节点都是follower,在一段时间内如果它们没有收到Leader的心跳信号,follower就会转化为Candidate;
如果某个Candidate节点收到大多数节点的票,则这个Candidate就可以转化为Leader,其余的Candidate节点都会回到Follower状态;
一旦一个Leader发现系统中存在一个Leader节点比自己拥有更高的任期(Term),它就会转换为Follower。
Raft使用基于心跳的RPC机制来检测何时开始新的选举。 在正常期间, Leader 会定期向所有可用的 Follower 发送心跳消息(实际中可能把日志和心跳一起发过去)。 因此,其他节点以 Follower 状态启动,只要它从当前 Leader 那里收到周期性的心跳,就一直保持在 Follower 状态。
当 Follower 达到其超时时间时,它将通过以下方式启动选举程序:
根据 Candidate 从集群中其他节点收到的响应,可以得出选举的三个结果。
共识算法的实现一般是基于复制状态机(Replicated state machines),何为 复制状态机 :
简单来说: 相同的初识状态 + 相同的输入 = 相同的结束状态 。不同节点要以相同且确定性的函数来处理输入,而不要引入一下不确定的值,比如本地时间等。使用replicated log是一个很不错的注意,log具有持久化、保序的特点,是大多数分布式系统的基石。
有了Leader之后,客户端所有并发的请求可以在Leader这边形成一个有序的日志(状态)序列,以此来表示这些请求的先后处理顺序。Leader然后将自己的日志序列发送Follower,保持整个系统的全局一致性。注意并不是强一致性,而是 最终一致性 。
日志由有序编号(log index)的日志条目组成。每个日志条目包含它被创建时的任期号(term),和日志中包含的数据组成,日志包含的数据可以为任何类型,从简单类型到区块链的区块。每个日志条目可以用[ term, index, data]序列对表示,其中term表示任期, index表示索引号,data表示日志数据。
Leader 尝试在集群中的大多数节点上执行复制命令。 如果复制成功,则将命令提交给集群,并将响应发送回客户端。类似两阶段提交(2PC),不过与2PC的区别在于,leader只需要超过一半节点同意(处于工作状态)即可。
leader 、 follower 都可能crash,那么 follower 维护的日志与 leader 相比可能出现以下情况
当出现了leader与follower不一致的情况,leader强制follower复制自己的log, Leader会从后往前试 ,每次AppendEntries失败后尝试前一个日志条目(递减nextIndex值), 直到成功找到每个Follower的日志一致位置点(基于上述的两条保证),然后向后逐条覆盖Followers在该位置之后的条目 。所以丢失的或者多出来的条目可能会持续多个任期。
要求候选人的日志至少与其他节点一样最新。如果不是,则跟随者节点将不投票给候选者。
意味着每个提交的条目都必须存在于这些服务器中的至少一个中。如果候选人的日志至少与该多数日志中的其他日志一样最新,则它将保存所有已提交的条目,避免了日志回滚事件的发生。
即任一任期内最多一个leader被选出。这一点非常重要,在一个复制集中任何时刻只能有一个leader。系统中同时有多余一个leader,被称之为脑裂(brain split),这是非常严重的问题,会导致数据的覆盖丢失。在raft中,两点保证了这个属性:
因此, 某一任期内一定只有一个leader 。
当集群中节点的状态发生变化(集群配置发生变化)时,系统容易受到系统故障。 因此,为防止这种情况,Raft使用了一种称为两阶段的方法来更改集群成员身份。 因此,在这种方法中,集群在实现新的成员身份配置之前首先更改为中间状态(称为联合共识)。 联合共识使系统即使在配置之间进行转换时也可用于响应客户端请求,它的主要目的是提升分布式系统的可用性。
区块链:3共识算法 拜占庭将军问题
区块链:3、共识算法 拜占庭将军问题
区块链系统采用分布式共识算法在无中心节点控制,又可能存在破坏节点的环境下确立系统状态,从而建立信任。区块链因此也被称为信任机器。
共识算法因不同的应用场景而有所不同。
从区块链的部署架构来看,有适合于公有链的共识算法,也有适合于联盟链或私有链的共识算法。公有链上的共识算法一般需要支持高扩展性,能够在共识节点动态出入网络的情况下保证共识流程的节奏,同时又要防止拜占庭节点对网络的攻击。
不同的共识算法在一致性、 正确性、可终止性、交易吞吐量、记账频率、扩展性和安全性上各有不同。在实际应用中,需要根据应用场景,选择能满足应用需求的共识算法。
分布式共识算法是分布式系统中保证系统状态一致性的重要技术,是分布式文件系统、分布式数据库的重要基础。
两阶段提交(Two-PhaseCommit)
在数据库系统中,两阶段提交(Two-PhaseCommit)是一个普遍使用的保证一致性的方法。两阶段提交由一个协调节点(Coordinator)居中控制。
第一阶段:协调节点会向所有节点发送一个询问“是否准备好”的消息,各节点会响应该消息。
第二阶段:如果各节点的响应都是准备好的回复,协调节点会向各节点发“提交"指令,否则会发“回滚”指令。
这样所有节点的状态都会保持一致, 要么提交新的状态,要么回滚成以前的状态。
两阶段提交协议在没有出现节点故障的情况下可以保证系统状态的一致性,但是当协调节点和另外一个节点同时出故障的时候,系统没有办法知道故障节点的状态,因此无法决定是提交还是回滚。
三阶段提交(Three-Phase Commit)
为了解决这个问题,三阶段提交(Three-Phase Commit)协议被提出来:
即在正式提交前,协调节点再发一次“准备提交”的消息,在收到所有节点的回复后,协调节点才发“提交”的指令。
三阶段提交能部分解决两阶段提交中协调节点和另一节点同时出故障的问题,但是系统过分依赖一个协调节点,另外其余节点也没有办法形成对协调节点是否出现故障的共识,因此,无论两阶段提交还是三阶段提交,都不能作为一个分布式共识算法,只能在通常情况下保障分布式系统的一致性。
两阶段提交和三阶段提交多数用在同步通信的分布式系统中,而通常的分布式系统是由多个主机通过吊少通信方式组成网络集群。在这样的一个异步系统中,需要主机之间进行状态复制,以保证每个主机达成一致的状态共识。 然而,异步系统中可能出现无法通信的故障主机,而主机的性能可能下降、网络可能拥塞,这些可能导致错误信息在系统内传播。因此需要在默认不可靠的异步网络中建立容错协议,以确保各主机达成安全可靠的状态共识。
利用区块链构造基于互联网的去中心化账本,需要解决的首要问题是如何实现不同账本节点上账个数据的一致性和正确性。这就需要借鉴已有的、在分布式系统中实现状态共识的算法,确定网络中选择记账节点的机制,以及如何保障账本数据在全网中形成正确、一致的共识。
在20世纪80年代出现的分布式系统共识算法,是区块链共识算法的基础。
一、拜占庭将军问题 .
拜占庭将军问题是区块链平台的共识机制需要解决的一个核心问题。
1、问题提出与约束条件
拜占庭将军问题是Leslie Lamport在20世纪80年代提出的一个假象问题。拜占庭是东罗马帝国的首都,由于当时拜占庭罗马帝国国土辽阔,每支军队的驻地分隔很远,将军们只能靠信使传递消息。发生战争时,将军们必须制订统一的行动计划。然而,这些将军中有叛徒。叛徒希望通过发布错误消息来影响忠诚的将军们制定统一的行动计划,以达到破坏忠诚的将军们统一行动的目的。因此,将军们必须有一个预定的方法协议,满足两个条件:
1、使所有忠诚的将军能够达成一致;
2、少数几个叛徒不能使忠诚的将军做出错误的计划。
条件2比较难用形式化方式描述,这里需要了解的是将军们怎么做决策。一般来说,每个将军会把他观察到的敌情派通信员告知其他将军。假设v(i)是第i个将军通知其他将军的消息,每个将军会采用某种方法把所有收到的消息v(1)…v(n)组成一个单一的行动计划,其中n是将军的数目。
条件1可以通过采用同一方法组成行动计划来达到
条件2则可以通过某种鲁棒性方式来达到,例如,通过多数人的意见来决定最后的行动计划。
如果要满足条件1,下列条件必须满足:
(1)每个忠诚的将军必须收到相同的命令值v(1)...v(n)。(v(i)是第i个将军的命令);
(2)如果第i个将军是忠诚的,那么他发送的命令和每个忠诚将军收到的v(i)相同。
Lamport把以上所有将军互相发命令的问题简化成一个将军发指令给n-1个副官,从而得出拜占庭将军问题。
拜占庭将军问题——一个发送命令的指挥官要发一个命令给其余n-1个副官,使得:
C1:所有忠诚的接收命令的副官遵守相同的命令;
C2: 如果发送命令的指挥官是忠诚的,那么所有忠诚的接收命令的副官将遵守所接收的命令。
拜占庭将军论断
Lamport指出在将军通过通信员口头传递信息的情况下,只要有1/3以上的叛徒,则没法保证忠诚的副官能达成一致的行动。
Lamport采用一个简单的图来说明在一个指挥官两个副官的情况下,只要有一个叛徒存在,就不可能达成共识。当指挥官是叛徒的情况下,忠诚的副官1和副官2没法遵从同样的命令,因此没办法保障C1的成立。
Lamport对拜占庭将军问题的研究表明,当n>3m时,即叛徒的个数m小于将军总数n的1/3时,通过口头同步通信(假设通信是可靠的),可以构造同时满足C1和C2的解决方案,即将军们可以达成一致的命令。
但如果通信是可认证、防篡改伪造的(如采用PKI认证,消息签名等),则在任意多的叛徒(至少得有两个忠诚将军)的情况下都可以找到解决方案。
Lamport对口头同步通信的定义如下:
A1.每个发送的消息都会被正确接收;
A2.接收消息的人知道是谁发送的消息;
A3.消息没有发送可以被检测到。
Lamport利用递归的方式定义了一个能在系统中叛徒少于1/3的将军总数的情况用口头同步信息达成共识的算法,简单表示成OM (m),即在最多m个叛徒的情况下,采算法能使总共超过3m+1的将军解决拜占庭将军的问题。该算法假设有一个majority函数,当大多数的vi值等于v,则maijority(vI,…,vn-1)等于v。如果vi不存在,该函数值是RETREAT (撤退是缺省值)。
2、算法与定理
(1)算法OM(0)(m=0,没有叛徒的情况)
①指挥官发他的值(相当于命令)给每一个副官。
②每个副官用他接收到指挥官的值作为当前值,如果没有接收到,用RETREAT (缺省是撤退)。
(2)算法OM (m), m>0
①将军发他的值给每一个副官。
②对每个i,让vi等于副官i从指挥官那里接收到的命令,或者如果没有接收到指令的话值就是RETREAT (缺省撤退)。副官i作为算法0M(m-1)的将军,发vi给其他n-2个副官。
③对每个i,以及每个j≠i,让vj等于第2步中采用算法0M(m-1)副官i从副官j接收到的值,或者没有收到值则缺省为RETREAT。副官i取majority(v1, … vn-1)的值。
为了证明算法OM(m)对任意m都能解决拜占庭将军问题,要先证明以下引理:
引理1:对任意m和k,如果有多于2k+m个将军和最多k个叛徒,算法OM (m)满足C2。
证明采用归纳法。
C2 只是规定在指挥官是忠诚的情况下需要满足的条件。
根据A1,可以很容易看出当指挥官是忠诚的时候,OM (0)成立,所以引理1在m=0的情况下成立。
我们现在假设在m-1, m>0的情况下成立,
我们只需要证明m情况下也成立,通过数学归纳法,我们可以得出引理1成立。
在算法OM(m)第一步,忠诚的指挥官发一个值v给所有n-1个副官。
在第二步,每个忠诚的副官递归调用0M (m-1),总共n-1个将军。
根据假设n>2k+m,我们可以得到n-1>2k+(m-1),
所以我们可以采用归纳法来得出每个忠诚的副官从第j个忠诚的副官处得到vj=v。
因为最多只有k个叛徒,并且n-1>2k+(m-1)>2k,所以n-1个副官中的多数是忠诚的。
因此,每个忠诚的副官都在n-1个副官的多数中收到vi=y,
所以他在第三步会得到majort(1,,n-1)=v,证明了C2,
即当指挥官是忠诚的情况下,所有忠诚的副官都执行接收的命令。
以下定理确认算法OM(m)能解决拜占庭将军问题。
定理1:对任意m,如果在至多m个叛徒而将军数超过3m个的情况下,算法OM (m)满足条件C1和C2。
采用归纳法来证明。
如果没有叛徒,很容易得出OM(0)满足C1和C2。
我们假设定理在OM (m-1)时成立,然后我们只需要证明在 OM (m), m>0时也成立。.
首先我们考虑将军是忠诚的情况。
在引理1中,使r=m,我们可以得出OM(m)满足C2。
如果将军是忠诚的,C1也会自动满足。
所以我们只需要在将军是叛徒的情况下验证C1。
最多只有m个叛徒,由于指挥官是其中一个,因此有m-1个副官是叛徒。
因为有超过m个将军,会有超过3m-1个副官,而且3m-1>3(m-1).
我们因此采用递归法来得出OM(m-1)满足条件C1和C2。
所以,对每个j,任何两个忠诚的副官在第三步的时候即会得到相同的vi.
(如果两个副官中的一个是副官j, 可以从C2中得出,否则可以从C1中得出)
因此,任意两个忠诚的副官都可以得到一样的向量v1,...,vn-1
因此会在第三步在一样的majority(v1,...vn-1),证明Cl成立。
3、拜占庭将军问题实质
综上所述,拜占庭将军问题的实质就是要寻找一个方法,使得在有故障得情况下能建立系统的共识。
在分布式系统中,特别是在区块链网络中的环境也和拜占庭将军的环境类似,有运行正常的服务器,有存在故障的服务器, 还有破坏者的服务器(类似叛变的拜占庭将军)。
共识算法的核心是在正常的节点间形成对网络状态的共识,也就是解决拜占庭将军问题。
二、 共识系统的基本定义
拜占庭将军问题在一个分布式系统中是一个非常有挑战的问题。
先给出分布式计算中有关拜占庭缺陷和故障的4个定义。
拜占庭缺陷: 任何从不同观察者角度看表现出不同症状的缺陷。
拜占庭故障:在需要共识的系统中由于拜占庭缺陷导致丧失系统服务。
宕机缺陷:在需要共识的系统中导致进程停止运行发生的缺陷;该缺陷不对系统产生其他副作用。
宕机恢复故障: 在需要共识的系统中导致进程停止运行发生的故障:该故障在重启进程后恢复,不对系统产生其他副作用。
在分布式系统中,不是所有的缺陷或障都能称为拜占庭缺陷或故障。像宕机、丟消息等缺陷或故障不能算作拜占庭缺陷或故障。
拜占庭缺陷或故障是最严重缺陷或故障。拜占庭缺陷有不可预测、任意性的特点,例如遭黑客破坏、中木马的服务器就是一个拜占庭服务器的例子。
在一个分布式系统中,所有的进程都有一个初始值。在这种情况下,共识问题就是要寻找一个算法和协议,使得该协议满足以下三个属性:
1 )一致性(Agreement):所有的非缺陷进程都必须同意同一个值。
2)正确性(Validity):所有非缺陷的进程所同意的值必须来自非故障进程所提议的值。
3)可结束性(Termination): 每个非缺陷的进程必须最终确定一个值 。
通常也把满足一致性和正确性称为安全性(Safety),而满足可结束性称为活性(Liveness)。
在异步通信的分布式系统中,只要有一个拜占庭缺陷的进程,就不可能找到一个共识算法可同时满足上述要求的一致性、正确性和可结束性,也就是说,不能同时满足安全性和活性。
在实际情况下,根据不同的假设条件,有很多不同的共识算法被设计出来,这些算法各有优势和局限。算法的假设条件有以下几种情况。
1)故障模型:非拜占庭故障/拜占庭故障。
2)通信类型:同步/异步。
3)通信网络连接:节点间直连数。
4)信息发送者身份:实名/匿名。
5)通信通道稳定性:通道可靠/不可靠。
6)消息认证性:认证消息/非认证消息。
通常使用的共识算法,如果按照严格的FLP异步通信的假设,往往只满足安全性而牺牲活性。
也就是说,大部分使用的异步通信网络下的共识算法,往往不能保证在有限的时间内总能达成共识。
参考文献
[1]邹均.于斌.庄鹏.邢春晓.区块链核心技术与应用.机械工业出版社
以上是关于区块链 --- 共识算法的主要内容,如果未能解决你的问题,请参考以下文章