RChain学习笔记[6]-Casper共识之安全证明

  • A+
所属分类:RChain知识库

在上一篇《Casper共识之估值函数》中介绍了验证者(validator)在打包区块时选择父级区块的逻辑,还剩下了一个问题-区块(block)在加入到DAG链后何时才能被认可?
认可即为共识,在解决“如何做”之前需要理解“为什么要这样”,所以本篇是下一篇的铺垫,解释Casper共识的原理。

1 概述

共识协议是在分布式环境中对某个命题在拜占庭容错度内(Byzantine Fault Tolerance)达成一致的算法。

Casper协议分为两部分

  • Casper CBC(Correct By Construction) : CBC是一个高度抽象的共识协议框架,同时也是方法论与过程。
    在各类实际的应用中,需要达成共识的命题逻辑多种多样。而CBC本身将具体的命题逻辑剥离出去,不关注具体的使用场景,然后建立通用的模型并证明此模型具有的特性。
    这样CBC就是一个通用的共识协议框架,能够适用于各种场景。
  • 派生协议 : 针对某个具体的场景与特定的命题逻辑,在CBC框架内进行细化与适配,从而得到具体的共识协议。
    • 比如全网需要在选择0和1这个命题上达成共识,则发展出来了Casper the Friendly Binary
    • 上一篇中讲到的通过GHOST对DAG链进行分支选择。分支选择也是一个需要达成共识的命题,因此就有了RChain所采用的Casper TFG(the Friendly GHOST)

所有这些派生协议无须再次证明自然地继承了CBC的安全性(Safety)证明 : 所有遵循协议的结点做出的选择都是一致的,它们不会做出相互冲突的选择。

2 模型

了解CBC协议可以查阅Vlad的论文。由于CBC是一个共识协议的抽象框架,直接理解起来有点费力。本文尝试结合RChain,对论文中的推导步骤尽量做出相对通俗的解释。

2.1 定义:协议状态与转换

首先,CBC定义了两个基本概念:协议状态(protocol states)和状态转换(transitions)。

  • 协议状态用σ表示,代表协议处于的某种状态。
  • 状态转换用−→表示。代表协议状态转换到了某个后续的状态。比如σ −→ σ'就表示协议状态σ转换到了状态σ'

同时协议状态也定义了两个基本性质

  • 传递性(transitivity) σ1 −→ σ2 ∧ σ2 −→ σ3 ⇒ σ1 −→ σ3 如果σ1转换为σ2,σ2转换到σ3, 那么σ1能够转换到σ3
  • 同一性(identity) σ −→ σ 每个状态都有个固有的状态转换到它自身

解释:协议状态是一个抽象的概念,在TFG中,协议状态具象成了消息的集合。具体到RChain中,协议状态即是前文中讲的消息状态树,其中包含了所有收到的以及当前验证者生成的区块。

而状态的转换即是在共识过程中对应的协议状态改变。在TFG中是消息集合的变化。具体在RChain中,当前验证者生成区块或者接受到来自其它验证者生成的区块,都会导致消息状态树的改变,这种改变即是转换。

2.2 定义:估值函数 Estimator

在上一篇中介绍的估值函数ε,在CBC中的定义为ε : |Σ| -> Prop(C)

  • |Σ| 定义为所有的协议状态以及协议状态的转换
  • -> Prop(C) 得出共识C的命题(propositions)

解释
估值函数根据协议状态与已经它们之间的转换得出某需要共识的命题。在TFG中有 e = ε(σ),根据消息状态树的状态选择父区块,也就是分支选择。

2.3 定义:估值安全 Estimate Safety

估值函数ε(σ) => p返回的估值(estimate)是命题p。在TFG中命题是某个分支选择。在RChain中具体到新区块的父区块选择。

CBC中对估值的安全性(estimate safety)定义:S(p,σ) <=> ∀ σ', σ−→σ' ε(σ') => p

  • S(p,σ) 表示pσ状态下是安全的
  • <=> 当且仅当
  • ∀ σ', σ−→σ' 表示σ'σ任意的未来状态
  • ε(σ') => p 估值函数对于σ'状态输出p

解释:对于σ的任意未来状态σ',当且仅当ε(σ')输出p,则pσ状态下是安全的。
具体到RChain,如果某个区块选择的分支是未来任意后续区块选择分支的一部分,那么这个区块的选择就是安全的。
估值安全是一种本地属性(local property),它表示在某个验证者的视角内,对于某个区块的分支选择与历史区块以及未来区块的分支选择之间的关系。

2.4 定义:共同未来状态 σ1 ∼ σ2

σ1 ∼ σ2 <=> ∃σ3 : (σ1 → σ3) ∧ (σ2 → σ3)

  • σ1 ∼ σ2 表示σ1σ2存在共同的未来状态
  • <=> 当且仅当
  • (σ1 → σ3) ∧ (σ2 → σ3)σ3是它们各自的未来状态
RChain学习笔记[6]-Casper共识之安全证明
σ1 ∼ σ2

解释σ1σ2共同未来状态表示它们都能够转换到相同的状态σ3
特别要注意的是,此定义的重点在于存在某种共同的未来状态,并不是说双方一定要向此未来状态转换。

3 安全性证明 - 第一部分

从上面的定义出发开始证明。

3.1 引理I:前向安全性 Forwards Safety

∀σ' : σ−→σ', S(p,σ) ⇒ S(p,σ')

解释:证明过程如下

  • 对于σ'的任意未来状态σ'',由于状态的传递性σ−→σ'−→σ''σ''σ'的未来状态必定也是σ的未来状态。
  • pσ状态下是安全的,根据估值安全的定义,对于σ的任意未来状态都会输出同样的命题p
  • 因此对于σ'的任意未来状态σ'',都有ε(σ'') => p, 这正是估值安全的定义,所以有S(p,σ')

所以有:如果pσ状态下是安全的,那么pσ的任意未来状态σ'下也是安全的。
在RChain中的含义是,如果某区块的分支选择是安全的,那么对于未来任意区块该选择都是安全的

3.2 引理II:当前一致性 Current Consistency

S(p, σ) ⇒ ¬S(¬p, σ)

解释:证明过程如下

  • 如果pσ状态下是安全的,那么对于σ的任意未来状态σ'都有ε(σ') => p
  • ¬pp的逆命题,p¬p不可能同时为真。
  • 而任意未来状态下ε(σ')都是输出p命题,不可能输出¬p
  • 那么S(¬p, σ)一定为假,也就是说¬pσ状态下是不安全的,也就是¬S(¬p, σ)

这条引理的含义是,如果pσ状态下安全的估值,那么其它与此估值矛盾的估值都是不安全的。
在TFG中的含义是,在某区块的分支选择上,不存在多个相互矛盾且安全的分支选择
比如命题p在某区块表示“选择分支a”;那么¬p表示“不选择分支a”。
如果“选择分支a”是安全的,那么“不选择分支a”的其它分支选择肯定是不安全的。

3.3 引理III:后向一致性 Backwards Consistency

∀σ : σ → σ', S(p, σ') ⇒ ¬S(¬p, σ)

解释:如果pσ'状态下是安全的,那么它的逆命题¬p在此状态的前置状态下一定是不安全的。
证明此引理需要反证法。

  • 首先假设逆命题¬pσ状态下是安全的
  • 根据引理I,¬pσ的任意未来状态σ'下也是安全的,即S(¬p, σ')
  • 根据引理II,有¬S(p, σ'),而这与S(p, σ')矛盾
  • 因此,逆命题¬pσ状态下一定是不安全的,即¬S(¬p, σ)

在RChain中的含义:如果某区块的分支选择是安全的,那么任何前置区块中与当前分支选择矛盾的选择都是不安全的

3.4 证明:从估值安全到共识安全

在这里先假设σ1σ2有共同的未来状态σ3,也就是σ1 ∼ σ2。在此假设的基础上做如下推导:

  • σ1和它的未来状态σ3间使用引理I,得出 S(p,σ1) ⇒ S(p,σ3)。即p如果在σ1状态安全一定也在σ3状态下安全。
  • σ3和它的过去状态σ2间使用引理III,得出 S(p,σ3) ⇒ ¬S(¬p,σ2)。即p如果在σ3状态下安全则它的逆命题¬p在过去状态σ2一定不安全。
RChain学习笔记[6]-Casper共识之安全证明
证明过程

因此σ1σ2彼此之间也有了关系:S(p,σ1) ⇒ ¬S(¬p,σ2), 而它等价于

  • ¬(S(p, σ1) ∧ S(¬p, σ2)) 不可能同时存在命题pσ1状态估值安全而逆命题¬pσ2状态也估值安全
  • ¬S(p, σ1) ∨ ¬S(¬p, σ2) 不可能同时存在命题pσ1状态估值不安全而逆命题¬pσ2状态也估值不安全

命题p在具有未来共同未来状态的σ1σ2中,要么命题p对于它们都是安全的;要么逆命题¬p对于它们都是安全的。而协议的参与者如果都做出使命题p都对于自己的协议状态估值安全的决定,它们就命题p做出了一致的决定,不会产生冲突。这也就证明了共识协议的安全性(Safety)。

具体到RChain中,有两个验证者v1和v2。v1在σ1状态下做出了估值安全的分支选择e1,同时v2在σ2状态下做出了安全估值的分支选择e2,现在假设它们有一个未来的共同状态σ3。
根据e = ε(σ),它们必定在未来的共同状态选择了相同的分支。
而又根据估值安全的特性,e1/e2这两个分支选择必定被未来的分支选择包含,它们在未来某刻选择了相同的分支。而GHOST选择的分支是唯一的,那么可以直观得到e1和e2这两个分支选择必定是其中一个包含(或等于)另外一个。也就是说,验证者选择的分支必定一致。

结论:具有共同未来状态的协议参与者如果都做出估值安全的决定,必将有共识安全

4 安全性证明 - 第二部分

第一部分的证明是不完备的,因为它假设了σ1σ2总是存在共同未来状态。共同的未来状态σ3并不是说σ1σ2一定要向此状态进行转换,而是作为证明中的一个跳板,通过两个引理的依次代入而得出σ1σ2之间的确定性关系。
只要σ1σ2存在任何理论上共同的未来状态,那么第一部分的证明总是有效的。
因此接下来需要考虑:σ1σ2是否总是存在共同的未来状态?

4.1 非平凡 Non-triviality

非平凡是数学用语,比如“零除以任何实数都等于零”这个命题在0这个实数上是非平凡的。非平凡表示存在特例。

在TFG中,协议状态即是消息的集合。那么对于任意两个协议状态σ1σ2,它们的并集σ1∪σ2必定是它们的共同未来状态。这个推导看上去是没有问题的,但它却是非平凡的。

在有这样一种情况:如果命题p和逆命题¬pσ0状态都不是估值安全的。σ0状态有两个后续状态σ1σ2,其中命题pσ1状态下是估值安全的,逆命题¬pσ2状态下也是估值安全的。

RChain学习笔记[6]-Casper共识之安全证明
Non-triviaity
  • 首先假设σ1σ2在这种情况下有共同的未来状态σ3
  • 根据引理I,S(p,σ1) ⇒ S(p,σ3)S(¬p,σ1) ⇒ S(¬p,σ3)。即S(p,σ3) ∧ S(¬p,σ3),命题p和逆命题¬pσ3状态下同时安全。
  • 根据引理II,S(p,σ3) ⇒ ¬S(¬p, σ3),命题p和逆命题¬pσ3状态下不可能同时安全。
  • 上述两部推导结果矛盾,因此假设不成立。σ1σ2在这种情况下不可能有共同的未来状态。

具体到RChain中,消息状态树的区块总是增加的,假设有两颗不同的消息状态树,如果把它们的区块合并成一颗新的消息状态树,即是它们的共同未来状态。这种说法貌似是正确的,但如果某个恶意验证者在某个状态下(也就是某个高度),输出了两个截然不同的区块且分支选择不同。那么这个恶意验证者生成的这两个区块是无法合并到同一颗消息状态树中,也就没有共同的未来状态。恶意验证者的这种行为称之为“模棱两可”(Equivocation),它属于拜占庭错误,具体的细节后文再论。

“零除以任何实数都等于零”这个命题加上额外条件排除非平凡域后,就有了“零除以任何非零实数都等于零”这个正确的命题了。
同样, 对于原命题“σ1∪σ2σ1σ2的共同未来状态”加上额外的条件“σ1∪σ2中具有少于N个拜占庭错误”就排除掉非平凡域,这个命题就是正确的了。

所以验证者需要计算(count)拜占庭错误以便将它们排除掉。

4.2 安全性证明:结论

将上面第一部分和第二部分结合起来,有:

在少于N个拜占庭错误的情况下,协议参与者如果都做出估值安全的决定,必将有共识安全。这个结论将作为下一篇判断区块是否达成共识的关键。

5 错误类型

现在回过头去看,验证者在打包的过程中,可能存在下面几类错误。

5.1 无效的消息

这个很好剔除掉,验证者在接收到其它验证者的区块时,必须在本地重算(replay)一次得到相同的结果才能加入到本地的消息状态树。因此无效的消息不可能触发协议状态转换。

5.2 消息延迟、丢失或者乱序

由于Casper是异步协议,消息(区块)发送给其它验证者并不需要确认返回,因此可能由于网络原因导致消息的延迟、丢失或者乱序。乱序比较好处理,因为每个区块都有justifications字段,能够方便地在消息状态树中重建出正确的顺序。

对于延迟或丢失,接收方是无法分辨是由于网络原因造成还是发送方造成,因此使用同样的逻辑处理它们。消息延迟、丢失会对共识协议的活性(liveness)产生负面影响,也就是延迟区块达到最终安全性的时间。因此Casper并不是完全异步的协议,会有超时判断机制。

如果出现某验证者经常性地延迟或丢失消息,会将此验证者从验证池中踢出(eject),以保证共识协议的活性。至于会不会对保证金进行少量的罚没,目前还没有定论。

5.3 Equivocation

从攻击者的角度来说,想要对其它验证者的协议状态产生不利影响并不是那么容易的事情。

首先区块内包含的状态改变必须依据规则化简,否则就是前文中的无效消息。其次,如果故意丢失或者延迟消息,则会被踢出。

拜占庭叛徒验证者在打包过程中,唯一能够做手脚的在于估值e = ε(σ),也就是对父区块的选择上。但也不是那么容易,因为`ε`对于所有的验证者都是一致的,所以验证者并不能随意地为新区块选择父区块。

RChain为了提高并行度,特别是吞吐率,必须允许所有验证者能够同时打包且它们的包有可能同时进入到DAG链。这也是选择CasperTFG的原因-如果RChain采用BTC那样的方式每次只允许一个验证者出块,必将大大限制并行度。

在这样的情况下,每个验证者任何时候都能够出块,而且打包的成本很低。这就会导致Nothing-at-stake的问题。验证者也有动机这么做:只有进入到DAG被认可的区块才能收到Rewards,那么验证者为了提高自己获得奖励的概率,小心地构造σ,在同一高度输出多个不同分支选择的块,从而会引起上文所说的Equivocation。如果全网的拜占庭错误数过大,最终会导致共识失败,也就是无法取得一致性。

PoS对这类行为的惩罚是非常严厉的。发现一次会罚没所有的保证金。每个区块中有signature字段,由打包的验证者签名无法伪造。如果其它验证者发现某验证者在同一高度有两个不同的区块,通过调用PoS的Slash API罚没验证者所有的保证金。当然,检举的验证者会获得奖励,来源于保证金。这就是PoS防止拜占庭错误的机制:每个验证者的stake也是其它验证者监督它的奖金。

下一篇将会解释具体如何判断区块进入了共识安全的状态。

 

本文转载自知乎 隔壁老王粑粑

查看原文

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: