关于共识
共识,就是一群具有各方面差异性的人在某方面达成了一致意见,并将其上升成为共同遵守的规则。 共识机制指的是一个群体用以达成并维护共识的方式
当前人类共识的特点
人类文明选择通过武力建立中心化权威以构建与维护群体共识。
不仅因为在文明早期这一方式最为快捷,更由于依靠中心化权威的管理方式更加高效和稳固。
区块链中的共识
范围:网络环境
作用的对象:所属权各异的计算机
逻辑:去中心化的方式进行记账
共识机制在记账过程中重点解决两个问题
完全对等的节点之间如何竞争记账权。
同时获得记账权后如何处理?(保留最长链的方式)
工作量证明(Power of Work)
区块链中的每个节点都能参与数据处理,打包区块,为了保证网络各个节点能够达成一致,PoW就规定当一笔交易产生以后,每个节点都需要通过自己的算力与他人竞争,争夺记账的权利。而竞争的方式就是每过大约十分钟的时间,就会进行一场竞赛。
参与的节点通过算力,不断寻找一个随机数NONCE,谁先找到符合条件的NONCE值,通知全网,获得认可,谁就拥有打包记账的权利。最终,他打包的区块就会连接到区块链的链上,同时,他处理的数据也会被其他节点记入自己的账本中。
权益证明(Proof of Stake)
PoW因为人人都可以自由参与成为节点,而节点之间又通过竞争的方式参与数据的处理,一笔数据要经过这么多人的处理,势必会造成资源浪费,效率低下的问题。
PoS之所以能够解决这个问题,是因为它提高了节点参与数据处理的门槛。它规定,虽然每一个人都可以自由加入成为节点,但是只有满足一定条件的节点,比如持有达到一定数量的代币才可以成为验证节点,也就是候选人,成为候选人以后,系统会通过算法,选出满足条件的节点作为出块节点,每隔一段时间,会重新筛选。选举过程中,算法会保证选举完全随机,不能被某一节点操控。
委托权益证明(Delegated Proof of Stake)
委托权益证明是指全网络的所有用户通过投票的方式,选举少数代表,即节点,代替所有用户履行验证和记账相关事务。同时,系统会产生少量代币,奖励代理节点。 这种共识机制类似于美国议会制度或者我们的人大代表制度。但是选举不是每四年一届,而是随时都在进行。如果代理节点无法履行相关事务,就会被淘汰,大家就会选出新的节点,履行相关职能。
共识机制和分布式网络
区块链是一个分布式系统。 共识机制负责安全地更新分布式网络中的数据状态,使其状态达成统一。
- 共识机制是决定按照哪一个参与节点记账和确保交易安全完成的重要手段。
- 共识机制同时满足一致性和有效性。
- 共识机制可以确保区块链不存在区别对待,从而达到公平分配。
- 共识机制具有激励的能力
共识的价值
金银铜和纸币在进行物质交换的过程中都被赋予了价值,这个价值就是“共识价值”
共识可以产生价值:个人认知的千差万别,也注定了共识的稀缺性,有共识就有价值,创造价值就是创造共识!
问题:
1、 共识机制主要解决区块链中的哪两个问题?
2、 简述共识机制和分布式网络的关系
分布式系统的基本概念
模型
节点
节点是指一个可以独立按照分布式协议完成一组逻辑的程序个体
节点往往是一个操作系统上的进程
节点也可以认为是一个物理机或虚拟机(容器)
存储
节点可以通过将数据写入与节点在同一台机器的本地存储设备保存数据 存储、读取数据的节点称为有状态的节点,反之称为无状态的节点。
异常
- 机器宕机
- 网络异常
消息丢失:发生网络拥塞、路由变动、设备异常等情况时
消息乱序:IP网络的存储转发机制、路由不确定性
数据错误:比特错误,校验后会丢弃
不可靠的TCP:TCP协议本身是可靠的,由于网络异常导致分布式系统中TCP通信的不可靠 - 存储数据丢失
- 无法归类的异常
分布式系统的三态
请求结果:“成功”、“失败”、“超时(未知)” “不成功”即指“失败”或“超时”两种状态之一
副本
副本(replica/copy)指在分布式系统中为数据或服务提供的冗余。
对于数据副本指在不同的节点上持久化同一份数据。
副本一致性
分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。
副本一致性是针对分布式系统而言的,不是针对某一个副本而言。
强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。 强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。
单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。 单调读写
会话一致性(session consistency):任何用户在某一次会话内一旦读到某个数据在某次更新后的值,这个用户在这次会话过程中不会再读到比这个值更旧的值。 例如HTTP访问中的Session
最终一致性(eventual consistency):最终一致性要求一旦更新成功,各个副本上的数据最终将达到完全一致的状态,但达到完全一致状态所需要的时间不能保障。
弱一致性(week consistency):一旦某个更新成功,用户无法在一个确定时间内读到这次更新的值,且即使在某个副本上读到了新的值,也不能保证在其他副本上可以读到新的值。 例如浏览器的缓存 副本有可能达到一致
性能
- 系统的吞吐能力,指系统在某一时间可以处理的数据总量,通常可以用系统每秒处理的总的数据量来衡量;
- 系统的响应延迟,指系统完成某一功能需要使用的时间;
- 系统的并发能力,指系统可以同时完成某一功能的能力,通常也用QPS(query per second)来衡量;
可用性
系统的可用性(availability)指系统在面对各种异常时可以正确提供服务的能力。系统的可用性可以用系统停服务的时间与正常服务的时间的比例来衡量,也可以用某功能的失败次数与成功次数的比例来衡量。
可扩展性
系统的可扩展性(scalability)指分布式系统通过扩展集群机器规模提高系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。
一致性
分布式系统为了提高可用性,总是不可避免的使用副本的机制,从而引发副本一致性的问题。根据具体的业务需求的不同,分布式系统总是提供某种一致性模型,并基于此模型提供具体的服务。
1、分布式系统中的异常包括哪些?
2、简述分布式系统中副本的概念,副本的一致性包括哪几种?
分布式系统一致性
系统模型
一致性是指分布式系统中的多个服务节点,给定一列操作,在特定协议的保障下,使这些节点对外呈现的状态是一致的,即保证集群中所有服务节点中的数据完全相同并且能够对某个提案(proposal)达成一致。
网络模型
网络模型根据系统中的时序模式分为同步网络和异步网络
同步网络中所有节点的时钟误差存在上限,并且网络的传输时间有上限
异步网络则与同步网络相反:节点的时钟漂移无上限,消息的传输时间是任意长的,节点计算的速度也不可预料。
故障模型
拜占庭(Byzantine)故障:这是最难处理的情况,系统内会发生任意类型的错误,发生错误的节点被称为拜占庭节点。
拜占庭节点不仅会出现硬件错误、宕机甚至会向其他节点发送错误消息。
崩溃-恢复(Crash-Recovery)故障:比拜占庭类故障多了一个限制,节点总是按照程序逻辑执行,结果是正确的,但是不保证消息返回的时间。
崩溃-遗漏(Crash-Omission)故障:比崩溃-恢复多一个非健忘的限制,即节点崩溃之前能把状态完整地保存在持久存储上,启动之后可以再次按照以前的状态继续执行和通信。
崩溃-停止(Crash-Stop)故障:崩溃-停止是理想化的故障模型,一个节点出现故障后立即停止接收和发送所有消息,或者网络出现故障无法进行任何通信。
一致性算法据此也可大致分为拜占庭容错(Byzantine Fault Tolerance, BFT)算法和崩溃容错(Crash Fault Tolerance, CFT )算法
拜占庭将军问题内涵
在缺少可信任的中央节点和可信任的通道的情况下,分布在网络中的各个节点应如何达成共识。
两种解决拜占庭将军问题的算法:
口信消息型解决方案(A solution with oral message);
签名消息型解决方案(A solution with signed message).
拜占庭将军问题是分布式系统领域最复杂的容错模型, 它描述了如何在存在恶意行为(如消息篡改或伪造)的情况下使分布式系统达成一致。是我们理解分布式一致性协议和算法的重要基础。
如果存在m个叛将,那么至少需要3m+1个将军,才能最终达到一致的行动方案。
口信消息型解决方案(A solution with oral message)
对于口信消息(Oral message)的定义如下:
A1. 任何已经发送的消息都将被正确传达;
A2. 消息的接收者知道是谁发送了消息;
A3. 消息的缺席可以被检测。
在口信消息型解决方案中,首先发送消息的将军称为指挥官,其余将军称为副官。对于3忠1叛的场景需要进行两轮作战信息协商,如果没有收到作战信息那么默认撤退。
指挥官为叛将的场景,在第一轮作战信息协商中,指挥官向General A、B发送了撤退的消息,但是为了扰乱General C的决定向其发送了进攻的消息。在第二轮中,由于所有副官均为忠将,因此都将来自指挥官的消息正确地发送给其余两位副官。最终所有忠将都能达成一致撤退的计划。
如上所述,对于口信消息型拜占庭将军问题,如果叛将人数为m,将军人数不少于3m+1,那么最终能达成一致的行动计划。值的注意的是,在这个算法中,叛将人数m是已知的,且叛将人数m决定了递归的次数,即叛将数m决定了进行作战信息协商的轮数,如果存在m个叛将,则需要进行m+1轮作战信息协商。 这也是上述存在1个叛将时需要进行两轮作战信息协商的原因。
签名消息型解决方案(A solution with signed message)
对签名消息的定义是在口信消息定义的基础上增加了如下两条:
A4. 忠诚将军的签名无法伪造,而且对他签名消息的内容进行任何更改都会被发现;
A5. 任何人都能验证将军签名的真伪。
忠将率先发起作战协商的场景,General A率先向General B、C发送了进攻消息,一旦叛将General C篡改了来自General A的消息,那么General B将发现作战信息被General C篡改,General B将执行General A发送的消息。
叛将率先发起作战协商的场景,叛将General C率先发送了误导的作战信息,那么General A、B将发现General C发送的作战信息不一致,因此判定其为叛将。可对其进行处理后再进行作战信息协商。
FLP定理
FLP给出了一个的结论:在异步通信场景,即使只有一个进程失败,也没有任何算法能保证非失败进程达到一致性。
FLP定理-模型
1)异步通信
与同步通信的最大区别是没有时钟、不能时间同步、不能使用超时、不能探测失败、消息可任意延迟、消息可乱序。
2)通信健壮
只要进程非失败,消息虽会被无限延迟,但最终会被送达;并且消息仅会被送达一次(无重复)。
3)fail-stop模型
进程失败如同宕机,不再处理任何消息。相对Byzantine模型,不会产生错误消息。
4)失败进程数量
最多一个进程失败。
分布式算法衡量的标准
- Termination(终止性):非失败进程最终可以做出选择。
- Agreement(一致性):所有的进程必须做出相同的决议。
- Validity(合法性):进程的决议值,必须是其他进程提交的请求值。 终止性,描述了算法必须在有限时间内结束,不能无限循环下去;一致性描述了我们期望的相同决议;合法性是为了排除进程初始值对自身的干扰。
案例分析
假设有A、B、C、D、E五个进程就是否提交事务为例,每个进程都有一个随机的初始值提交(0)或回滚(1)来向其他进程发送请求,进程自己必须接收到其他进程的请求后才能根据请求内容作出本地是提交还是回滚的决定,不能仅根据自己的初始值做出决定。 算法P:每个节点根据多数派表决的方式判断本地是提交还是回滚。
C选择一直等待,导致C没有做出最终决策,形成不确定的Configuration。如果某个Configuration是确定的,则认为一致性是可以达成。
C或者按照某种既定的规则选择提交或回滚,后续可能E正常而C失败,C做了最终决策失败后无人可知。
极端情况:每次都构造出一个“不确定”的Configuration,比如每次都是已经做出决议的C失败,而之前失败的E复活(在异步场景中,无法真正区分进程是失败,还是消息延迟)
在任何算法之上,都能构造出这样一些永远都不确定的Configuration。
CAP理论
CAP 三个字母分别代表了分布式系统中三个相互矛盾的属性:
Consistency (一致性):CAP 理论中的副本一致性特指强一致性;
Availability(可用性):指系统在出现异常时已经可以提供服务;
Tolerance to the partition of network (分区容忍):指系统可以对网络分区这种异常情况进行容错处理;
CAP理论指出:无法设计一种分布式协议,使得同时完全具备 CAP 三个属性,即
1)该种协议下的副本始终是强一致性,
2)服务始终是可用的,
3)协议可以容忍任何网络分区异常;
分布式系统协议只能在CAP这三者间有所折中。
基于CAP定理,需要根据不同场景的不同业务要求来进行算法上的权衡。对于分布式存储系统来说,网络连接故障是无法避免的,在设计系统时不得不考虑分区容忍性,实际上只能在一致性和可用性之间进行权衡。
1、 什么是拜占庭将军问题?问题的本质如何理解?
拜占庭帝国(Byzantine Empire)军队的几个师驻扎在敌城外,每个师都由各自的将军指挥。将军们只能通过信使相互沟通。在观察敌情之后,他们必须制定一个共同的行动计划,如进攻(Attack)或者撤退(Retreat),且只有当半数以上的将军共同发起进攻时才能取得胜利。然而, 其中一些将军可能是叛徒,试图阻止忠诚的将军达成一致的行动计划。更糟糕的是,负责消息传递的信使也可能是叛徒,他们可能篡改或伪造消息,也可能使得消息丢失。
2、 简述FLP和CAP定理,并说明你对他们的认识。
分布式一致性算法
两阶段提交协议
两阶段提交(two phase commit)协议是一种历史悠久的分布式控制协议。
最早用于在分布式数据库中,实现分布式事务。
在经典的分布式数据库模型中,同一个数据库的各个副本运行在不同的节点上,每个副本的数据要求完全一致。
流程描述
参与的节点分为两类:一个中心化协调者节点(coordinator)和N 个参与者节点(participant)
在第一阶段,协调者询问所有的参与者是否可以提交事务(请参与者投票),所有参与者向协调者投票。
在第二阶段,协调者根据所有参与者的投票结果做出是否事务可以全局提交的决定,并通知所有的参与者执行该决定。
Phase 1 Prepare:
1.TC(协调者)写本地日志,并持久化。TC向所有参与者发送Prepare T消息。
2.各参与者收到Prepare T消息,根据自身情况,决定是否提交事务。
如果决定提交,参与者写日志并持久化,向TC发送Ready T消息。如果决定不提交,参与者写日志并持久化,向TC发送Abort T消息,本地也进入事务abort流程。
Phase 2 Commit :
1.当TC收到所有节点的回应,或者等待超时,决定事务commit或abort。
如果所有参与者回应Ready T,则TC先写日志并持久化,再向所有参与者发送Commit T消息。如果收到至少一个参与者Abort T回应,或者在超时时间内有参与者未回应,则TC先写日志,再向所有参与者发送Abort T消息。
2.参与者收到TC的消息后,写或日志并持久化。
PAXOS协议
工程角度实现了一种最大化保障分布式系统一致性(存在极小的概率无法实现一致)的机制
Paxos是首个得到证明并被广泛应用的共识算法,其原理类似两阶段提交算法,进行了泛化和扩展,通过消息传递来逐步消除系统中的不确定状态。
Paxos 协议中,有三类节点:
Proposer:提案者。Proposer 可以有多个,Proposer 提出议案(Value)。所谓 Value在工程中可以是任何操作,对同一轮 Paxos过程,最多只有一个 Value被批准。
Acceptor:批准者。Acceptor有M个,Proposer提出的Value必须获得超过半数(M/2+1)的 Acceptor批准后才能通过。Acceptor 之间完全对等独立。
Learner:学习者。Learner学习被批准的 value。所谓学习就是通过读取各个 Acceptor 对 Value的选择结果,如果某个 value 被超过半数Acceptor 通过,则 Learner 学习到了这个 value。某个Value需要获得W=M/2 + 1 的Acceptor 批准,从而学习者需要至少读取M/2+1个Accpetor,至多读取M个Acceptor 的结果后,能学习到一个通过的 Value。
协议描述-Proposer流程
准备阶段:
1.向所有的Acceptor 发送消息“Prepare(b)”。这里b是 Paxos 的轮数,每轮递增。
2.如果收到任何一个 Acceptor 发送的消息“Reject(b)”,则对于这个Proposer而言本轮Paxos失败,将轮数b设置为 b+1 后重新步骤 1;
批准阶段:
3.如果接收到的 Acceptor 的“Promise(b, vi)”消息达到 M/2+1 个。vi表示Acceptor 最近一次在 i 轮批准过 Value V。
3.1 如果收到的“Promise(b, v)”消息中,V都为空,Proposer 选择一个 value V,向所有 Acceptor广播Accept(b, v);
3.2 否则在所有收到的“Promise(b, vi)”消息中,选择 i 最大的 value V,向所有 Acceptor 广播消息 Accept(b, v);
4.如果收到Nack(B)(否定应答),将轮数b设置为b+1 后重新步骤 1;
协议描述- Acceptor流程
准备阶段:
1.接受某个Propeser 的消息 Prepare(b)。
1.1 如果 b>B,回复Promise(b, v_B),设置 B=b; 表示保证不再接受编号小于b的提案。参数B是该 Acceptor 收到的最大Paxos 轮数编号;V 是Acceptor 批准的 value,可以为空。
1.2 否则,回复Reject(B)
批准阶段:
2.接收 Accept(b, v)。
2.1 如果 b < B, 回复Nack(B),提示proposer有一个更大编号的提案被这个Acceptor 接收。
2.2 否则设置 V=v。表示这个Acceptor 批准的 Value 是 v,并广播Accepted 消息。
实例
1.初始状态
2.Proposer 向所有Accpetor 发送“Prepare(1)”,所有 Acceptor 正确处理,并回复 Promise(1, NULL)
3.Proposer 收到 5 个 Promise(1, NULL),满足多余半数的 Promise 的 value 为空,此时发送Accept(1, v1),其中 v1 是Proposer 选择的 Value
4.v1 被超过半数的Acceptor 批准,v1 即是本次Paxos 协议实例批准的 Value。如果 Learner学习 value,学到的只能是 v1
批准的 Value 无法改变
当前的状态
假设 Proposer 发送“prepare(4)消息”,由于 4 大于所有的Accpetor 的B 值,所有收到 prepare 消息的Acceptor 回复 promise 消息。但前三个 Acceptor 只能回复 promise(4, v1_3),后两个Acceptor 回复 promise(4, NULL)。
回复3 个promise 消息中,至少有1个消息是promise(4, v1_3),至多3个消息都是promise(4,v1_3)。另一方面,Proposer 始终不可能收到 3 个 promise(4, NULL)消息,最多收到 2 个。综上,按协议流程,Proposer 发送的 accept 消息只能是“accept(4, v1)”,而不能自由选择 value。
最后的状态
竞争及活锁
Paxos 协议引入了轮数的概念,高轮数的 paxos 提案可以抢占低轮数的 paxos 提案,从而避免了死锁的发生。 这种设计却引入了“活锁”的可能,即 Proposer 相互不断以更高的轮数提出议案,使得每轮 Paxos 过程都无法最终完成,从而无法批准任何一个 value。
Proposer 1 以 b=1 提起议案,发送 prepare(1)消息,各 Acceptor 都正确处理,回应 promise(1, NULL)
Proposer 2 以 b=2 提起议案,发送 prepare(2)消息,
各 Acceptor 都正确处理,回应 promise(2, NULL)
Proposer 1 收到 5 个 promise(1, NULL)消息,选择
value 为 v1 发送 accept(1, v1)消息,然而这个消息
被所有的Acceptor 拒绝,收到 5 个 Nack(2)消息。
Proposer 1 以 b=3 提起议案…
Raft算法
Leader(领导者) :负责日志的同步管理,处理来自客户端的请求,与Follower保持HeartBeat的联系;
Follower(追随者) :响应 Leader 的日志同步请求,响应Candidate的邀票请求,以及把客户端请求到Follower的事务转发(重定向)给Leader;
Candidate(候选者:负责选举投票,集群刚启动或者Leader宕机时,状态为Follower的节点将转为Candidate并发起选举,选举胜出(获得超过半数节点的投票)后,从Candidate转为Leader状态。
Raft三个子问题
选举(Leader Election) :当 Leader 宕机或者集群初创时,一个新的 Leader 需要被选举出来;
日志复制(Log Replication:Leader 接收来自客户端的请求并将其以日志条目的形式复制到集群中的其它节点,并且强制要求其它节点的日志和自己保持一致;
安全性(Safety):果有任何的服务器节点已经应用了一个确定的日志条目到它的状态机中,那么其它服务器节点不能在同一个日志索引位置应用一个不同的指令。
选举
第一阶段:所有节点都是 Follower
所有节点的状态都是 Follower,初始 Term(任期)为 0。
同时启动选举定时器,每个节点的选举定时器超时时间都在 100~500 毫秒之间且并不一致(避免同时发起选举)
第二阶段:Follower 转为 Candidate 并发起投票
没有 Leader,Followers 无法与 Leader 保持心跳(HeartBeat),节点启动后在一个选举定时器周期内未收到心跳和投票请求,则状态转为候选者 Candidate 状态,且 Term 自增。
并向集群中所有节点发送投票请求并且重置选举定时器。
第三阶段:投票策略
请求节点的 Term 大于自己的 Term,且自己尚未投票给其它节点,则接受请求,把票投给它;
请求节点的 Term 小于自己的 Term,且自己尚未投票,则拒绝请求,将票投给自己。
第四阶段:Candidate 转为 Leader
一轮选举过后,正常情况下,会有一个 Candidate 收到超过半数节点(M/2 + 1)的投票,它将胜出并升级为 Leader。
定时发送心跳给其它的节点,其它节点会转为 Follower 并与 Leader 保持同步。
日志复制
在一个 Raft 集群中,只有 Leader 节点能够处理客户端的请求
客户端的每一个请求都包含一条被复制状态机执行的指令。Leader 把这条指令作为一条新的日志条目(Entry)附加到日志中去,然后并行得将附加条目发送给 Followers,让它们复制这条日志条目。
当这条日志条目被 Followers 安全复制,Leader 会将这条日志条目应用到它的状态机中,然后把执行的结果返回给客户端。
如果 Follower 崩溃或者运行缓慢,再或者网络丢包,Leader 会不断得重复尝试附加日志条目(尽管已经回复了客户端)直到所有的 Follower 都最终存储了所有的日志条目,确保强一致性。
日志结构
第一阶段:客户端请求提交到 Leader
Leader 在收到请求后,会将它作为日志条目(Entry)写入本地日志中。
此时该 Entry 的状态是未提交(Uncommitted),Leader 并不会更新本地数据,因此它是不可读的。
第二阶段:Leader 将 Entry 发送到其它 Follower
Leader 与 Followers 之间保持着心跳联系,随心跳 Leader 将追加的 Entry(AppendEntries)并行地发送给其它的 Follower,并让它们复制这条日志条目。
第三阶段:Leader 等待 Followers 回应
写入本地日志中,返回 Success;
一致性检查失败,拒绝写入,返回 False。
在发送追加日志条目的时候,Leader 会把新的日志条目紧接着之前条目的索引位置(prevLogIndex), Leader 任期号(Term)也包含在其中。如果 Follower 在它的日志中找不到包含相同索引位置和任期号的条目,那么它就会拒绝接收新的日志条目,因为出现这种情况说明 Follower 和 Leader 不一致。
第四阶段:Leader 回应客户端
Leader会向客户端回应 OK,表示写操作成功
第五阶段,Leader通知Followers Entry 已提交
Leader 回应客户端后,将随着下一个心跳通知 Followers,Followers 收到通知后也会将 Entry 标记为提交状态
算法安全性
-
Election Safety
在任意指定Term内,最多选举出一个Leader 2. Leader Append-Only Leader从不“重写”或者“删除”本地Log,仅仅“追加”本地Log 3. Log Matching 如果两个节点上的日志项拥有相同的Index和Term,那么这两个节点[0, Index]范围内的Log完全一致 4. Leader Completeness 如果某个日志项在某个Term被commit,那么后续任意Term的Leader均拥有该日志项 5. State Machine Safety 一旦某个server将某个日志项应用于本地状态机,以后所有server对于该偏移都将应用相同日志项。
简述Paxos协议的原理和流程?
简述Raft算法3个子问题的解决过程。
PoW工作量证明
简单理解就是一份证明,用来确认你做过一定量的工作
PoW系统中一定有两个角色,工作者和验证者,他们需要具有以下特点:
(1) 工作者需要完成的工作必须有一定的量,这个量由工作验证者给出。
(2) 验证者可以迅速的检验工作量是否达标。
(3) 工作者无法自己"创造工作",必须由验证者发布工作。
工作者无法找到很快完成工作的办法。
中本聪在其比特币奠基性论文中设计了PoW 共识机制,其核心思想是通过引入分布式节点的算力竞争来保证数据一致性和共识的安全性
为了使区块头能体现区块所包含的所有交易,在区块的构造过程中,需要将该区块要包含的交易列表,通过Merkle Tree算法生成Merkle Root Hash,作为交易列表的摘要存到区块头中。
计算方法
其中data是将时间戳、版本号、区块高度等信息组合的数据(header),nonce为一种随机值,D(d)为目标值,d为挖矿难度,随着挖矿难度增加,目标值与哈希值也会越难匹配。从式(1)可以看出,PoW是一个不断枚举的过程,算法使用嵌套哈希函数求解,当新的交易数据出现时,各个区块链节点开始全力运算,当某个节点最先满足式(1)则被称为矿工
在比特币中规定每产生2016块就会对难度值进行相应的调整,一个区块的验证时间一般为10min左右
1.当前时间段的全网未确认交易, 并增加一个用于发行新比特币奖励的 Coinbase 交易, 形成当前区块体的交易集合;
2.区块体交易集合的Merkle根记入区块头, 并填写区块头的其他元数据, 其中随机数 Nonce 置零;
3.数 Nonce 加 1; 计算当前区块头的双 SHA256 哈希值, 如果小于或等于目标哈希值, 则成功搜索到合适的随机数并获得该区块的记账权; 否则继续步骤 3 直到任一节点搜索到合适的随机数为止;
4.一定时间内未成功, 则更新时间戳和未确认交易集合、重新计算 Merkle 根后继续搜索。
难度目标值
由此公式及难度位的值 0x1903a30c,可得: target = 0x03a30c * 2^(0x08 * (0x19 - 0x03)) => target = 0x03a30c * 2^(0x08 * 0x16) => target = 0x03a30c * 2^0xB0 按十进制计算为: => target = 238,348 * 2^176 => target = 22,829,202,948,393,929,850,749,706,076,701,368,331,072,452,018,388,575,715,328 转化为十六进制后为: => target =0x0000000000000003A30C00000000000000000000000000000000000000000000 也就是说⾼度为277,316的有效区块的头信息哈希值是⼩于这个目标值的。
难度的调整是在每个完整节点中独立自动发生的. 每2,016个区块中的所有节点都会调整难度。 难度的调整公式是由最新2,016个区块的花费时长与20,160分钟(两周,即这些区块以10分钟一个速率所期望花费的时长)比较得出的。
算法特点
(1)效率低。在比特币系统中的区块容量只有1MB,其网络中交易量大约为7笔/s,出块时间则为10min左右。
(2)消耗大。由于矿工节点在挖矿的过程中需要大量的电力与流处理器等挖矿机器。
(3)化程度较低。中本聪设计比特币挖矿的初衷是每个人都用CPU来挖矿,而现在算力大部分掌握在算力矿池手中,矿池与矿池也会联盟来竞争记账权利。
PoS
PoS机制全称是proof of stake,即为权益证明 PoS机制主要是通过权益记账的方式来解决网络的效率低下,资源浪费和各节点的一致性问题
原理:提高了节点处理数据的门槛,它规定每个人可以自由的加入进来成为节点,但只有满足一定条件的节点,比如抵押一定数量的代币才有资格成为验证节点,每隔一段时间,会重新选择,选举的结果不能被操纵,也不能被预测,从而避免网络被某一节点所控制。
权益证明共识算法的记账权决定于节点的币龄大小,其中币龄表示为持币数量与持币时间之积。根据币龄权值的大小关系降低了计算机 Hash 计算的难度,这有效缓解了工作量证明的算力浪费,缩短了共识时间,提高了共识的效率。
算法流程
PoS共识算法不需要矿工枚举所有的随机数 Nonce,而是在 1 s 内只允许一次哈希值,大大减轻了计算工作量,从而减缓了算力竞争带来的资源消耗。
算法举例:
例如当前全网的难度值是4369,A矿工的输入的币龄是15,那么A矿工的目标值为 65535,换算成十六进制就是 0xFFFF,完整的哈希长度假设是8个字节,也就是 0x0000FFFF。而B矿工比较有钱,他输入的币龄是240,那么B矿工的目标值就是 0x000FFFFF,所以B矿工获得记账权的概率肯定要比A高。
算法特点
PoS 是通过权益大小来寻找哈希值,不存在因算力竞争浪费能源的问题。
由于 PoS 共识算法采用类似“币龄”的权益 值,并对成功挖矿者采用了币龄“清零”机制,PoS 共识算法更加公平。
为了防止节点离线积累币龄,2014 年 Vasin 提出了 PoS2.0并应用到黑币(BlackCoin)中,从而使黑币从模式发展到了纯 PoS 共识模式。PoS2.0 共识算法中的权益大小与用户当时的 PoW+PoS 共识在线时间成正比,这种激励机制有效增强了区块链 P2P 网络的健壮性。
PoS共识算法容易产生分叉,且区块链的去中心化特点被弱化。
DPoS
针对PoS共识算法主要存在离线节点积累币龄和某些拥有权益的节点无意挖矿等缺陷,2014年4月,Larimer在PoS共识算法的基础上提出了委托权益证明(delegated proof of stake,DPoS)共识算法。
DPoS共识算法引入了类似企业董事会的管理机制, 权益持有者通过投票方式选择能够代表自己利益的委托人(票数与持有代币的多少成正比),被选出的受信任的委托人需要交纳一定数量的保证金,最后形成一个由101个委托人组成的集合。
该集合中的委托人将以平等的权利按规则轮流作为出块者生成区块,并从每笔交易的手续费中获得收益。
DPoS 通过选举见证人的方式行使权利,具体流程如下:
(1) 选举出块者。见证人即代表,通过持有选票者投票选举产生。见证人在系统中保持中立,每24小时更新一次,且投票情况决定其收益。持有选票的节点根据自己的意愿给被选举节点投票,投票的总数大于全网票数的 1/2 则选举有效,得票最高的101个节点成为见证人。
(2) 提出区块。见证人轮流产生区块,签名、添加时间戳、广播新块。见证人在规定时间内没有产生新块,超时后,将由下一个见证人产生新区块。
(3) 验证区块。“董事会”中的其他见证人将验证新产生区块的合法性,验证结果为 合法新区块才能上链。
(4) 更新区块链。验证结果合法的新区块上链,更新区块链。
DPoS算法的优点:
(1) 能耗更低。DPoS在确保网络安全的前提下,能够降低全网功耗,网络运营成本比较低。
(2) 交易更快。减少了记账节点 数量,提升了区块验证和记账速度,能达到秒级共识。
DPoS算法的缺点:
(1) 节点收益不够合理。DPoS 按照得票股份分红,落选的备选见证人节点对于整个系统产生的边际收益小,分红收益低,对于落选的备选见证人节点收益分配不合理。
(2) 投票积极性不高。投票需要花费各种资源,使大多数节点积极性降低,甚至有百分之九十的持股人都从未参与过投票。
(3) 安全隐患。对于出现离线节点、坏节点或恶意节点的情况,DPoS不能及时处理,因此网络安全存在极大的隐患。
PBFT
PBFT中将节点分为客户端节点(Client)和共识节点,共识节点包含主节点(Primary)和副本节点(Replica)。
Client负责发送请求;
Primary负责对请求消息进行排序,并将相关消息广播至所有Replica,每轮共识过程有且只有一个Primary;
Replica负责区块共识,在验 证并通过来自Primary的消息之后执行相关操作并将结果返回给 Client,每轮共识过程有多个Replica且工作内容类似。
主要流程
PBFT的共识属于典型的三阶段,分别为预准备(preprepare)、准备(prepare)和确认(commit)等阶段,主要过程如下
(1) Client 提出请求,将请求消息发送给Primary;
(2) 预准备阶段:Primary接收请求消息,对请求消息进行处理形成预准备消息,然后将预准备消息广播发送至所有Replica;
(3) 准备阶段:所有Replica节点接收预准备消息,验证预准备消息摘要是否被篡改, 若未被篡改,则将预准备消息处理成为准备消息,然后将准备消息广播至所有共识节点;
(4) 确认阶段:共识节点接收并验证准备消息,若准备消息为真则将生成的确认消息广播至其他的共识节点;
(5) 共识节点在接收和验证确认消息后,生成结果,然后将结果返回给Client。
PBFT算法前提,采用密码学算法保证节点之间的消息传送是不可篡改的。
PBFT容忍无效或者恶意节点数:f,为了保障整个系统可以正常运转,需要有2f+1个正常节点,系统的总节点数为:|R| = 3f + 1。也就是说,PBFT算法可以容忍小于1/3个无效或者恶意节点
PBFT是一种状态机副本复制算法,所有的副本在一个视图(view)轮换的过程中操作,主节点通过视图编号以及节点数集合来确定。PBFT共识算法使用视图view记录每个节点的共识状态,相同视图节点维护相同的Leader和Replicas节点列表,与RAFT算法中的term类似
1. REQUEST:
客户端c向主节点p发送<REQUEST, o, t, c>请求。
o: 请求的具体操作,t: 请求时客户端追加的时间戳,c:客户端标识。
REQUEST: 包含消息内容m,以及消息摘要d(m)。客户端对请求进行签名。
2. PRE-PREPARE:
主节点收到客户端的请求,需要进行以下校验:客户端请求消息签名是否正确。
(1)非法请求丢弃。
(2)正确请求,则分配一个编号n,编号n主要用于对客户端的请求进行排序。
3. PREPARE:
(1) 主节点PRE-PREPARE消息签名是否正确。
(2) 当前副本节点是否已经收到了一条在同一v下并且编号也是n,但是签名不同的PRE-PREPARE信息。
(3) d与m的摘要是否一致。
(4) n是否在区间[h, H]内。
非法请求丢弃。
正确请求,则副本节点i向其他节点包括主节点发送一条<PREPARE, v, n, d, i>消息, i是当前副本节点编号。<PREPARE, v, n, d, i>进行副本节点i的签名。
4. COMMIT:
主节点和副本节点收到PREPARE消息,需要进行以下校验:
(1) 副本节点PREPARE消息签名是否正确。
(2) 当前副本节点是否已经收到了同一视图v下的n。
(3) n是否在区间[h, H]内。
(4) d是否和当前已收到PRE-PPREPARE中的d相同
非法请求丢弃。
如果副本节点i收到了2f+1个验证通过的PREPARE消息,则向其他节点包括主节点发送一条<COMMIT, v, n, d, i>消息。<COMMIT, v, n, d, i>进行副本节点i的签名。
5. REPLY:
5. REPLY:
主节点和副本节点收到COMMIT消息,需要进行以下校验:
(1) 副本节点COMMIT消息签名是否正确。
(2) 当前副本节点是否已经收到了同一视图v下的n。
(3) d与m的摘要是否一致。
(4) n是否在区间[h, H]内。
非法请求丢弃。
如果副本节点i收到了2f+1个验证通过的COMMIT消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求操作o,并返回<REPLY, v, t, c, i, r>给客户端,r:是请求操作结果,客户端如果收到f+1个相同的REPLY消息,说明客户端发起的请求已经达成全网共识,否则客户端需要判断是否重新发送请求给主节点。
Checkpoint和Stable checkpoint
- checkpoint 就是当前节点处理的最新请求序号。比如一个节点正在共识的一个请求编号是101,那么对于这个节点,它的 checkpoint 就是101。
- stable checkpoint 就是大部分节点 (2f+1) 已经共识完成的最大请求序号。比如系统有 4 个节点,三个节点都已经共识完了的请求编号是 213 ,那么这个 213 就是 stable checkpoint 了。
- stable checkpoint的作用:因为每个节点在日志中应该记录下之前曾经共识过什么请求,但如果一直记录下去,数据会越来越大,所以应该有一个机制来实现对数据的删除。
高低水位区间
- 实际上当副本节点i向其他节点发出CheckPoint消息后,其他节点还没有完成K条请求,所以不会立即对i的请求作出响应,它还会按照自己的节奏,向前行进,但此时发出的CheckPoint并未形成StablePoint,为了防止i的处理请求过快,设置一个上文提到的高低水位区间[h, H]来解决这个问题。
- 低水位h等于上一个stable checkpoint的编号,高水位H = h + L,其中L是我们指定的数值,等于checkpoint周期处理请求数K的整数倍,可以设置为L = 2K。当副本节点i处理请求超过高水位H时,此时就会停止脚步,等待stable checkpoint发生变化,再继续前进。
视图切换
- 如果主节点作恶,它可能会给不同的请求编上相同的序号,或者不去分配序号,或者让相邻的序号不连续。备份节点应当有职责来主动检查这些序号的合法性。
- 如果主节点掉线或者作恶不广播客户端的请求,客户端设置超时机制,超时的话,向所有副本节点广播请求消息。副本节点检测出主节点作恶或者下线,发起视图切换(View Change)协议。
- view-change:各副本节点(Replica) 认为主节点(Primary)有问题时,会向其它节点发送view-change消息
- view-change-ack:各节点接收到2*f+1 个view-change消息后,选举当前存活的节点编号最小的节点成为新的主节点,并向该节点发送view-change-ack消息
- new-view:当新的主节点收到2*f+1个其它节点的view-change-ack消息后,向其它节点广播new-view消息。注意:从节点不会发起new-view事件
算法特点
PBFT算法由于每个副本节点都需要和其他节点进行P2P的共识同步,因此随着节点的增多,性能会下降的很快,但是在较少节点的情况下可以有不错的性能,并且分叉的几率很低。
共识算法对比
简述PoW、PoS和DPoS共识机制的原理。
简述PBFT算法的流程。