读懂区块链共识机制 :PoW、PoS、PAXOS、RAFT、PBFT

所谓“共识机制”,是通过特殊节点的投票,在很短的时间内完成对交易的验证和确认;对一笔交易,如果利益不相干的若干个节点能够达成共识,我们就可以认为全网对此也能够达成共识。再通俗一点来讲,如果中国一名微博大V、美国一名虚拟币玩家、一名非洲留学生和一名欧洲旅行者互不相识,但他们都一致认为你是个好人,那么基本上就可以断定你这人还不坏。

百度百科

Consensus

当谈及分布式环境中的共识时,一般涉及到两种类型的节点:

  • Legitimate nodes:诚实节点,觉得你是好人,就投票你为好人
  • Malicious nodes:恶意节点,行为“恶劣”,颠倒黑白

此外,即使发生任何故障,我们的系统也必须正常运行。有两种类型的故障会发生:

  • Crash failure:诚实节点发生的故障(消息延迟、不可送达)
  • Byzantine failure:恶意节点造成的故障(篡改消息、不按套路执行协议)

因此,区块链共识协议的主要责任有:

  • 保持账本(区块链)中的数据的有序性、安全性
  • 在区块链网络中的节点之间达成协议,即提供拜占庭协议(即使出现拜占庭式的失败,也不会造成太大影响)
拜占庭协议(Byzantine Agreement)采用的方法是确保可以通过分布式的方法达成共识,即使出现了拜占庭式的失败也不会影响。“拜占庭失败”可以理解为恶意节点造成的故障。

下面列出一些著名的DLT(分布式账本)以及它们所使用的共识算法:

DLT Consensus Algorithm Used Description
Bitcoin PoW 应用 PoW 来生产新的货币
Ethereum PoW 首次收到传入操作的账户
Hyperledger PBFT 如果 2/3 的成员对新的区块达成共识,那么该区块就成为区块链的一部分
Parity PoS 要求矿工提供一定数量加密货币的所有权,而不要求其算力
Hashgraph Virtual voting-based consensus algorithm
Tezos PoS

Proof of Work(PoW)

比特币区块链的共识机制,PoW是为公共区块链设计的。在PoW中,共识能否最终达成是不被保证的。在PoW中,矿工既是leader node又是validator node。

节点通过计算随机哈希散列的数值解争夺记账权,求得正确的数值解以生成区块的能力是节点算力的具体表现,算力越高,就越有可能解得数值。计算出哈希值的节点才能够向区块链中添加区块,并获得奖励。某个节点获胜的概率为

其中,i代表每个参与节点,N是节点的总数量,φi代表节点i的算力。

PoW存在的问题:

  • 如果某两个矿工同时解出了PoW puzzle,就会造成所谓的fork
  • 达成共识所需周期长
  • 耗费大量计算资源
  • 双花问题(double spending)
假如我们微信钱包里有 100 块钱的庞大资产,我们先去饭店吃了顿饭,结果微信出了 bug,这一笔钱并没有被银行同步,还留在钱包里,于是我们又能拿着同样的 100 块钱去看场电影,这就属于双花问题。在区块链系统中,由于共识机制导致区块确认时间长,用一个数字货币去进行一次交易,可以在这笔交易还未被确认完成前,进行第二笔交易,这就会造成双花问题。

PoW的容错能力:

  • PoW可能会遭到51%算力攻击。当系统中有合作关系的恶意节点所控制的算力,超过诚实节点所控制的算力,系统就有被攻击的风险。
  • 可以容忍拜占庭失败
  • 可以有效抵御“女巫攻击”(Sybil Attack),即少数恶意节点构造多个虚假身份,并利用这些身份控制或影响网络的大量正常节点。

Proof of Stake(PoS)

在权益证明(PoS)类共识协议中,矿工的选择取决于每个节点携带的“权益”(如加密货币)数量,而不是其计算能力。

PoS 相比 PoW 会消耗更少的资源,缩短达成共识所需的时间。当然,PoS 也存在自己的一些问题,例如,在 PoS 中,奖励的授予方式应该是使所有节点都有平等的机会参与到采矿过程中。否则,每次获胜的都为权益较高的矿工,每次得到奖励的也是它。而且如果有任何延迟或链接的连接问题,节点可能没有账本的最新副本,因此会导致同步问题。

下面这张图总结了PoS相比PoW的一些区别:

PAXOS

最基本的分布式共识(一致性)算法,允许在不可靠的通信条件下(信息可以延迟、丢失或者重复,但没有出错)对一个值达成共识。

PAXOS的核心idea是,如果有一半以上的进程选择了一个值,那么依据多数人代表整体的原则,这个值就是共识。

PAXOS中的节点:

  • Proposer:提出要达成一致的值。某个选取的Proposer作为一个单的的 leader,提出一个新的决议,它处理客户的请求。
  • Acceptor:Acceptor根据若干规则和条件对决议进行评估,并决定接受还是拒绝Proposer提出的建议。
  • Learner:获取Acceptor达成一致的值

Phases in PAXOS

Prepare Phase

  1. Proposer收到客户提出的就某个值达成共识的请求;
  2. Proposer向大多数或所有接受者发送一个消息prepare(n);
  3. Acceptor接收到prepare(n) 消息,并进行回应。

在第二步中,n代表proposal number,它必须是全局唯一的,且要大于该Proposer之前使用过的proposal number。如果Proposer没有收到来自大多数Acceptor的响应,那么它需要增大n,重新发送。

在第三步中,如果Acceptor之前没有做出过任何响应,那么它会回复 promise(n) 消息,并承诺会忽略之后任何小于n的proposal number。而如果Acceptor之前有做出过回应,即对某个小于n的proposal number回复了promise(n) 消息,那么进一步可分为两种情况:

  • 如果它还没有收到来自之前Proposer的accept消息,那么它会存储现在更高的proposal number n,回复promise(n) 消息;
  • 如果它已经收到了来自之前Proposer的accept消息,那么它一定已经相应的回复了accepted消息,在这种情况下,它会把之前这个full proposal连同 promise(n) 消息一起回复,表明我之前已经接收过值了。

Accept Phase

  1. Proposer等待,直到得到大多数Acceptor对该proposal number n的回应;
  2. 评估应该在accept消息中发送什么v值;
  3. 给Acceptor发送accept(n, v) 消息,v值是实际要达成一致的值;
  4. Acceptor接收到accept(n, v) 消息后,要么回复accepted(n, v) 消息并将该消息发给所有learners,要么直接忽略;
  5. 如果大多数Acceptor都接受了v值这个提议,那么就达成共识了。

第二步细节:如果Proposer收到的promise消息中有带有full proposal 的,那么它会将v值增大,如果都没有full proposal的话,v值可以随便选取。

第四步细节:Acceptor接收到accept(n, v) 消息后:

  • 如果它之前已经承诺过不接受这个proposal number,它就会忽略这个消息;
  • 如果它之前回复过promise(n) 了,那么它就回复accepted(n, v) 消息并将该消息发给所有learners。

Replicated And Fault Tolerant(RAFT)

RAFT允许集群的重新配置,这使得集群成员的改变不需要中断服务。它还允许日志压缩,以缓解节点崩溃后缓慢重建的问题并减少消耗的存储。

一个RAFT集群中的节点可分为以下三种:

  • Leader:接收客户请求,组织日志复制给其它节点,并管理与Follower的通信
  • Follower:节点在本质上是被动的,只对远程过程调用(RPC)做出响应。它们从不主动发起任何通信,只会接受leader的复制日志,对leader言听计从
  • Candidate:尝试成为leader的节点,会发起投票请求

RAFT主要包括两个阶段:

  • leader election
  • log replication

这里先将三个节点之间的状态转换图给出,具体过程可以往下看。

Leader Election

Leader Election会基于一个心跳(heartbeat)机制来触发leader的选举过程:

  1. 所有的节点一开始都是Follower;
  2. 如果Follower持续收到来自leader或者candidate的远程过程调用,那么它们只会保持自己Follower的身份;
  3. 如果特定时间内某个Follower没有收到来自leader的心跳包,表明leader可能已经失效了,那么该Follower就会变为Candidate,发起新的选举,尝试变为leader。
  4. 如果Candidate 收到了大多数的选票,那么它就“竞选”成功,成为leader。但如果多个Follower同时变为Candidate,且它们的选票不相上下,那么此时就无法决出胜者,RAFT为每轮选举都设置了超时时间,如果在这段时间内还没有选出新的leader(election timeout),那么就会开启新一轮的选举过程。

不管是在Follower变为Candidate时的等待时间,还是选举时的timeout时间,都可能会发送这样的情况:不同Follower设置的等待时间或者不同Candidate的timeout时间相同,那么这一轮选举超时了,下一轮同样的Follower又变为了Candidate,相同的timeout时间内还是没有从这些Candidate中还是没有选出leader,又进入下一轮…

因此我们在实际中会将Candidate的timeout时间以及Follower的等待时间随机化,每轮选举后,每个Candidate都会让自己的任期号+= 1,这样我们每轮就可以选择任期号最大的那个Candidate,减小冲突的概率。此外,发生冲突的选举后,Candidate间隔下一次选举的时间也要随机化。

上图中还缺少一点,如果candidate收到了来自leader的心跳包,那么说明选举结束了,它会变为follower。

Log Replication

  1. 客户给leader发送请求;
  2. leader会给该请求添加一个任期号(term)以及索引(index),使得该请求或命令在日志中能够被唯一识别,然后将该请求添加到自己的日志中;
  3. 并行地给follower发送AppendEntries RPC,将新的日志项传递给follower。
  4. 当集群中的大多数follower都追加了该请求后,leader会提交该日志, 并执行指令改变状态机的状态,并返回结果给客户。它也会通过AppendEntries RPC告诉follower日志已经被提交,以便让follower也开始执行指令改变它们自己状态机的状态

上述过程的日志追加可看下图:

Practical Byzantine Fault Tolerance (PBFT)

从名字中也可以看出,PBFT被设计用来在有拜占庭错误的情况下提供共识。

PBFT包含三个子协议:

  • normal operation:该协议在一切正常,无错发生的情况下运行
  • view change:在leader节点出错的情况下运行
  • checkpointing:丢弃系统中的旧数据

PBFT同样也有三种节点:

  • replicas:每个PBFT协议中的参与者(包括leader和backup)
  • leader:也叫primary,每个轮次都会有一个leader来与客户通信,leader不变,则一直为同一个view
  • backup:除去leader外的其它所有节点

如果想要容忍拜占庭错误,那么节点的最小数量应为n=3f+1,也就是说,如果要容忍f个故障,那么这个系统必须要有n个节点。只要系统中的节点数量保持n≥3f+1,PBFT就可以提供拜占庭容错。

PBFT协议的执行分为3个阶段:

  • Pre-prepare
  • Prepare
  • Commit

Pre-prepare Phases

  1. leader从客户端接收一个请求;
  2. 为该请求分配对应的序列号,序列号代表着请求被执行的顺序;
  3. 将该请求信息(pre-prepare message)广播到所有backups备份。

Prepare Phase

  1. backups只会接收之前未接收过的序列号或者不同view对应的pre-prepare消息;
  2. 将prepare消息发给所有节点。

Commit Phases

  1. 收到prepare消息的replica对消息进行验证(是否为相同的请求、view以及序列号),直到集齐2f+1个验证好的消息;
  2. 广播commit消息给所有replica;
  3. 如果集齐2f+1个到达的有效commit消息,说明决议通过;
  4. 执行该请求/决议
  5. 返回给客户reply消息,包含处理结果

下图为一个在normal operation协议下运行的PBFT基本过程,这是最简单过程,因为为了达到n≥3f+1的要求,系统中至少需要4个节点。

关于RAFT算法的最大容错节点数量是(n-1)/2,而PBFT算法的最大容错节点数量是(n-1)/3 的补充说明:(《深入剖析区块链的共识算法Raft&PBFT》)

对于RAFT算法,它只支持容错故障节点,不支持容错作恶节点。故障节点就是节点因为系统繁忙、宕机或者网络问题等其它异常情况导致的无响应,出现这种情况的节点就是故障节点(也就是我们开头提到过的诚实节点的故障,Crash failure)。作恶节点除了可以故意对集群的其它节点的请求无响应之外,还可以故意发送错误的数据,或者给不同的其它节点发送不同的数据,使整个集群的节点最终无法达成共识,这种节点就是作恶节点(也就是我们开头提到过的恶意节点造成的故障,Byzantine failure)。

RAFT算法只支持容错故障节点,假设集群总节点数为n,故障节点数为f,根据小数服从多数的原则,集群里正常节点只需要比f个节点再多一个节点,即f+1个节点,正确节点的数量就会比故障节点数量多,那么集群就能达成共识。因此RAFT算法支持的最大容错节点数量是(n-1)/2。

对于PBFT算法,因为PBFT算法的除了需要支持容错故障节点之外,还需要支持容错作恶节点。假设集群节点数为n,有问题的节点为f。有问题的节点中,可以既是故障节点,也可以是作恶节点,或者只是故障节点或者只是作恶节点。如果故障节点和作恶节点都是不同的节点,那么就会有f个作恶节点和f个故障节点。当发现节点是作恶节点后,会被集群排除在外,剩下f个故障节点,那么根据小数服从多数的原则,集群里正常节点只需要比f个节点再多一个节点,即f+1个节点,正确节点的数量就会比故障节点数量多,那么集群就能达成共识。所以,所有类型的节点数量加起来就是f+1个正确节点,f个故障节点和f个问题节点,即至少需要3f+1个节点。

Metrics of Consensus

IT系统的性能和可扩展性一直是用来衡量区块链共识算法的关键非功能性指标。

Performance

Transaction Throughput:

交易吞吐量被定义为区块链网络每秒钟可以处理的交易(Tx)数量。它可以通过如下公式进行计算:

其中,Block Time为将一个区块添加到区块链中所花费的平均时间。

显然,区块尺寸越大,吞吐量就越高,而Block Time或者交易规模越大,吞吐量就越小。(固定其余两个量)

当交易大小为500 Bytes,Block Time为10s时,吞吐量随区块大小变化如下图所示:

版权声明:本文为CSDN博主「如松茂矣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:

https://blog.csdn.net/myDarli...

文章来源:CSDN博主「如松茂矣」
文章原标题:《区块链共识机制 (Consensus)(PoW,PoS,PAXOS,RAFT,PBFT)》
如有侵权请与我们联系删除。

你可能感兴趣的:(区块链)