Tendermint中的Proof of Stake协议

在之前的文章中,我有介绍过Tendermint的共识协议:

https://mirror.xyz/0xEeEe921AA9FB236b66B22489FdF477066Dc3E74D/wbp32U9S193To3T-sCfY9_i5MZ6faO4vq3-kJqr5d4w

这是一种类似于pBFT的byzantine共识协议,pBFT共识于1999年被提出,但是一直没有大规模地落地于工业界。直到2008年,中本聪提出了采用了POW协议的比特币系统,才是第一个大规模落地的byzantine共识系统。pBFT一直没有大规模落地的原因有一点是因为协议的正确性需要保证+2/3的节点是合法的,因此在集群中节点的数量是固定的,而且新加入的节点需要比较严格的审查。如果我不对新加入的节点做严格审查,则恶意攻击者很容易搞一堆“肉鸡”节点发起攻击,破坏+2/3的正确性保证。但是如果我做了严格审查,并控制节点数量,那我还搞什么byzantine共识协议呢?直接采用性能更好的paxos/raft不是更好?(实际上有一些联盟链就是这么干的)。pBFT的缺点极大地限制了网络的规模。

在2013年比特币论坛有人提出了Proof of Stake的想法,Tendermint再后续将其和pBFT结合起来,解决了网络的规模的问题,使得BFT网络可以拥有动态的大规模网络节点(目前cosmos hub有150个验证节点)。只有质押了stake的节点才能拥有对应stake数量权重的投票权力,使得恶意的节点即使控制了大量的“肉鸡”节点,但是其并不能控制大量stake拥有者的私钥,因此也无法破坏协议。

相比于POW,POS还存在几个问题。一个是"Nothing at stake",说的是pow网络中恶意节点要制造网络分叉是要付出算力成本的,因为一份算力只能同时在一个分叉链上挖矿。但是在pos网络中,对两个不同的block做vote签名投票是成本很低的。因此在pos中引入了"惩罚"机制,验证者如果被检查出曾经对不同的分叉都做过vote将会被惩罚。

另一个问题是"Long Range Attack"。拥有一定数量的stake的验证者在撤回质押后,可以在历史block做分叉。在pow网络中,其他节点会遵循“最长链原则”继续挖矿,新分叉需要付出极大的算力成本才能成为最长链,因此攻击成本很高。但是在pos链中,构造链的成本很低,因此其他节点无法通过客观的“最长链原则”做出判断,只能主观地选择其中一个分叉。为了避免此类攻击,pos网络采用stake延迟赎回,加上最终确认点的策略。攻击者赎回stake需要一定时间,而block被确认后,状态将被最终确定,任何分叉行为将被拒绝。

最后一个问题是,网络中的“寡头”。如果某几个验证者上面质押了绝大多数的stake,他们将拥有决定性的话语权。这个问题tendermint并未在协议里解决,而是交给了链外的社区治理来决议。

最后,对比一下以太坊的Casper协议。tendermint是基于状态机的pos协议,而casper则是基于链的pos协议。基于状态机的pos协议在分布式cap中选择了cp,但是放弃了一定的可用性,避免了分叉的出现。基于链的pos协议则相反,cap中选择了ap,允许出现一定时间的分叉,但是拥有比较高的可用性。