许可区块链中联盟之间的安全协作
传统挑战
- 联盟之间的安全协作是提供优质服务的必要条件。这种协作可以通过跨链协议处理
- 两阶段提交和两阶段锁定跨链协议无法应用在联盟可能是恶意的场景中
两阶段协定
分布式数据最重要的是保证数据存储顺序的一致性(事务执行需要一致)
- 数据库的操作 具有 原子性:
- 事务结果是要么成功提交(事务的全部写入都成功持久化)
- 要么全部丢弃(事务的所有写入都被回滚,即取消或者扔掉)。
原子性能够避免失败的事务通过半完成(half-finished)或者半更新(half-updated)的结果来破坏数据库系统
例如:A向B转账100,要么AB的账户同时产生对应的变化,要么AB的账号都不变
两阶段提交
两阶段提交(2PC,two-phase commit)是一种在多个节点上实现原子事务的算法——即,保证所有节点要么都提交,要么都中止。
协调者:可以理解为领导者,但这个领导者也可以是独立于其他结点的一个可信机构TA。
阶段0:协调者准备写入数据,开启一个事务ID
阶段1:向每个参与者发送 prepare 请求,询问他们是否能够提交。1. 如果所有参与者都回复“可以”(yes),表示能够提交,则协调者就会进入第二阶段发出提交( commit )请求,此时,提交事实上才开始执行。
如果回复“可以”,意味着参与者让渡了中止事务的权利(给协调者),其确认该事务能够在任何情况下都能被提交,但此时并没有真正地提交。
阶段2:如果全部YES,那么才可以commit,数据才算真正写磁盘。否则,协调者会对所有参与者发送带有该事务 ID 的中止请求。
如果某个参与者请求失败或者超时,则协调者会对其进行无限重试,直到成功。不允许走回头路
因此,该协议有两个重要的“不可回退点”:
- 当某个参与者回复“可以”时,就做出了(将来无论发生什么)肯定可以提交的承诺。(当然,协调者可以中止事务)
- 当协调者决定提交时,该决定一旦做出(写入磁盘),就是不可撤回的。
故障情况
如果任何一个参与者(participant)或者网络故障时的系统行为:
- 如果任意准备提交(prepare)请求失败,则协调者中止事务。
- 如果任意提交(commit)或者中止(abort)请求失败,则协调者会进行无限重试。
- 在第一阶段没有回复ok之前,可以单方面的中止事务
- 回复ok之后,只能 死等 。参与者事务的这种状态称为存疑(in doubt)或者未定(uncertain)。
这里不能简单的用超时机制来处理这种 死等,因为无法确定另一个结点是否回复了ok,如果另一结点提交了事务,那么也会导致不一致。
传统方案:参与者之间可以互相沟通+辅助超时机制以确定该如何进行下一步
两阶段锁定
两段锁协议的内容
- 在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁
- 在释放一个封锁之后,事务不再获得任何其他封锁。
哪里有问题?数据库!
恶意联盟的可能性——
在分布式数据库中,database1和database2只会遵守程序约定,进行数据存储和故障恢复。
- 但是,在联盟链视角中,database1和database2其实是联盟结点,我们不能保证联盟结点都会诚实行事。恶意联盟可能会故意发送冲突的交易或信息。
两阶段协定要求每条区块链都由一个预定的容错集群进行维护,以便进行共识的回滚。但是要求每个区块链的容错集群都是容错的(或者诚实守信的)是不正确的。
5个联合体:供应商、制造商、买方、承运商和中间商。每个联盟内部使用区块链来处理内部交易,但它们还需要通过跨链交易与其他联盟进行协作。在这种情况下,这些联合体之间存在着利益冲突。
不能简单地假设他们总是诚实地行事
例如,协调器可以将冲突的跨链消息发送给不同的联盟。
缺乏撤销操作——
在传统方案中,一旦跨链交易的某个阶段被提交,就没有简单的方法来撤销该操作。这在出现错误或恶意行为时可能导致问题。
性能——
传统的跨链解决方案可能在处理大量跨链交易时性能不佳
提出
- 使用全局跨链账本来增强两阶段提交和两阶段锁定跨链协议的安全性。
- 基于账本框架,我们使得两阶段提交和两阶段锁定跨链协议支持撤销操作,并且可以在存在恶意联盟的情况下工作
安全假设
$C_i$:第i号联盟链
$L_i$:联盟链内部的账本,$L_g$:联盟链全局账本
联盟内外定义
【同联盟消息查询】
结点能读取自己联盟内的账本
【跨联盟消息查询】
需要一个联盟的多数结点同时发送消息给目标联盟结点。具体过程见下
共识消息:当一个联盟(例如Ci)想要发送消息给另一个联盟(例如Cj)时,首先该联盟内的所有节点需要就发送的消息达成共识。消息接收:接收联盟(Cj)中的节点需要接收到足够多的相同消息副本,以抵御潜在的恶意行为。具体来说,如果发送联盟(Ci)中有f个恶意节点,接收联盟中的节点需要接收到f+1个匹配的消息副本。
【两种交易类型】
- 内部交易,只会影响$L_i$
- 跨链交易,会影响$L_i$ 和$L_g$
- 跨链事务被划分为若干个跨链子事务执行跨链协议
- 例如,两阶段提交跨链协议中的表决、提交、中止等操作
行为定义
- 结点
- 诚实:这里的诚实仅代表是否遵守联盟内部的协定
- 不诚实
- 联盟
- 正常:这里的正常仅代表是否遵守联盟之间的协定
- 恶意
不失一般性,联盟和结点的行为相互独立,即便所有结点都是正常的,联盟也可以是恶意的。(例如:所有内部结点均遵从同一个恶意协定,对这个联盟来说,这个结点是诚实的)
例如:恶意联盟中的不诚实 结点就是 敌方中的我方卧底
从两方面考察共识算法的安全性——
- 安全
- 活性:不会死锁
为什么PBFT 需要至少3f+1个节点?
为了保证 liveness,当收到 n-f 个节点的消息时,系统需要继续执行下一步(因为可能f个恶意节点故意不发消息,永远也等不到)。
为了保证 safety,任意两个 n-f 消息集合的交集必须保证至少有 f+1 个节点,因为这样才能保证至少有一个正常节点。因此 (n-f) + (n-f) – n >= f+1,即n >= 3f+1。
全局账本
理性化模型
两阶段提交的时候可能产生恶意攻击,为了保证数据一致性,最重要的是保证事务操作的顺序一致。我们就再引入一个共识账本,记录跨链事务。
为了保证安全性,使用一个全局账本来记录所有跨链交易的顺序。
白色代表内部交易,灰色代表跨链子交易的(例如投票、确认)
每个跨链交易都会提交两份事务,比如联盟1确认准备好,他会再自己的账本里面存储事务,同时全局账本里面存储事务。
这里的事务是指“子事务”,可以为了更方便的精细控制和回滚。
如何实现全局账本?
如果类似于理想化模型中,单独再拉一条链出来,性能开销、存储开销是很大的,而且谁管理?谁存储也是一个问题。
实例1:CAPER
全局账本由所有结点共同维护。所有的跨链交易相链接即成为一条$L_g$
每个事务不仅具有在本地区块链上的顺序,更有一个指针(编号顺序)指向下一个跨链分片。
(如左图)
- 一致性问题:通过将Lg集成到Li中,CAPER确保了数据的一致性。这意味着,无论是查看本地账本还是全局跨链账本,都能得到关于跨链交易的完整和一致的信息。
实例2:哈希图
安全的跨链协议
定义
一个跨链事务:$\tau=(Con^{\tau},Mod^{\tau})$
一个事务需要得到锁涉及到 跨链的交易 的 所有约束集 的限制
- Constraints(约束集):
- 约束集是指一组规则或条件,这些规则或条件必须在跨链交易被执行之前得到满足。
- 在跨链交易中,
Conτ(Li)
表示交易τ在账本Li上的约束集。这些约束可能包括交易签名的有效性、涉及的账户余额是否充足、交易是否满足特定的业务逻辑等。 - 约束的目的是确保交易在执行前账本的状态是一致的,并且交易执行是合法的。
- Modifications(修改集):
- 修改集是指跨链交易τ执行后对账本状态所做的更改。
- 在跨链交易中,
Modτ(Li)
表示交易τ在账本Li上所做的修改集。这些修改可能包括账户余额的增减、智能合约状态的更新、新的区块的创建等。 - 修改集定义了交易执行后账本状态的变化,是交易执行结果的直接体现。
τ 会被拆分为多个子步骤,区块链账本记录的是每个子步骤
τ是跨链交易的总体描述,而tx是τ中的一个具体操作或步骤。在账本(Li和Lg)中记录的是具体的交易实例tx,而不是跨链交易τ本身。账本记录了组成τ的各个步骤,即各个tx,以及它们的序列编号。这些tx共同定义了τ的状态和历史。
协议步骤
Vote
验证交易的约束,所有对这个交易有限制的联盟都需要走此步骤
一旦约束条件被验证,参与的节点将生成两种可能的投票之一:
- 提交投票(Commit vote):表示为
Votc,τ,L
,如果节点决定交易τ应该被提交到账本L。- 本地更改:如果投票结果是提交(即生成了
Votc,τ,L
),节点将在本地账本L上执行一些更改,包括:- 修改本地数据:根据交易τ的内容,更新账本L中相应的数据记录。
- 获取锁(Locking):为了防止冲突,对涉及的账本资源进行锁定,以确保在交易最终提交前,这些资源不会被其他交易修改。
- 本地更改:如果投票结果是提交(即生成了
- 中止投票(Abort vote):表示为
Vota,τ,L
,如果节点决定交易τ不应该被提交,可能是因为某些约束条件未得到满足。
Commit
所有对这个交易有修改内容的联盟都需要走此步骤
- 目的:当交易τ在所有相关的联盟账本中都获得了足够的提交投票,并且决定被提交时,就会执行提交步骤。
- 操作:
- 修改数据:在账本L中正式应用交易τ所涉及的数据修改。这包括但不限于更新账户余额、记录新的智能合约状态等。
- 释放锁:释放在之前的投票步骤中为保持数据一致性而获得的所有锁。这一步确保了其他等待的交易可以访问之前被锁定的数据资源。
Abort
- 目的:如果在投票步骤中交易τ获得的投票不足以提交,或者在交易过程中遇到错误或违反了某些规则,就会执行中止步骤。
- 操作:
- 回滚更改:撤销在投票步骤中对账本L所做的任何本地数据修改,确保账本状态回到交易τ之前的状态。
- 释放锁:释放在投票步骤中获得的所有锁,允许其他交易继续进行。
Revoke
- 目的:在某些情况下,即使交易τ已经开始了提交过程,也可能需要撤销之前的提交投票。撤销步骤允许这样做,通常是由于检测到错误、违反规则、超时或其他异常情况。
- 操作:
- 提交撤销:在$L_g$中提交一个撤销全局事务
- 撤销投票:将之前的提交投票(
Votc,τ,L
)替换为中止投票(Vota,τ,L
),表明交易τ不再被提交。 - 回滚更改:如果交易τ已经开始执行但后来被撤销,需要撤销所有已经进行的数据修改,将账本L的状态恢复到交易τ之前的状态。
- 释放锁:释放在投票步骤中获得的锁,以便其他交易可以使用这些资源。
状态机
流程:
- 提出一个事务τ
- 联盟内部决定是否commit或者 abort
- 如果commit,则加入本地账本$L_i$,并发给外部
- 关联的外部联盟的领导者 进行投票过程 是否commit 或者abort
- 如果commit,则上链$L_g$
- 如果commit,则上链$L_g$
安全性分析
如果满足活性、一致性和有效性的性质,则跨链协议是安全的
活性(Liveness)
- 定义:活性保证了如果跨链交易τ被至少一个诚实的节点在诚实的联盟(honest concerned consortium)中提出,那么这个交易最终将被诚实的联盟要么提交(committed),要么中止(aborted)。
- 证明:
- τ被诚实结点提出,因此他们会运行正常的共识协议,并向外部提出跨链请求;其他涉及到的联盟会进行投票,并给出响应
- 此时 恶意联盟可能采取几种行为(如发送冲突投票(例如commit变abort)、撤销投票、延迟投票等)
- 即使在恶意联盟可能采取的几种行为(如发送冲突投票、撤销投票、延迟投票等)下,跨链交易τ最终仍然能够达到一个确定的状态(提交或中止)。这是因为诚实的联盟会根据预定义的协议和规则进行投票,并在全局跨链账本(Lg)中记录这些投票,从而推动交易向前发展。
一致性(Consistency)
- 定义:一致性确保了如果存在多个并发访问诚实联盟账本状态且存在冲突的交易,那么至多只有一个交易能够被提交。
- 证明:
- 通过假设存在两个冲突的交易τ1和τ2,并说明即使在诚实联盟的影响下,由于每个交易都会锁定相关的状态对象,并且直到协议结束才会释放,因此不可能同时提交两个冲突的交易。如
- 果τ2在τ1提交后到达,τ2将因为账本状态已改变而被中止。
有效性(Validity)
- 定义:有效性确保了交易只有在根据诚实联盟账本状态验证为有效时才会被提交。
- 证明:如果一个交易τ在Lg中被提出为有效的提交交易(tx(Comτ,L)),那么它只有在所有涉及的联盟都投票提交τ并且在Lg中序列化了提交投票(tx(Votc,τ,L))时才有效。
- 注意,每次投票到$L_g$都会经过$BFT_g$。所以这样能防止万一某个涉及到的联盟是恶意结点,在投票阶段本应该是正确的,投反对票。此时交易只能被abort。
- 诚实的联盟会根据账本Li的状态来验证τ的有效性,包括检查约束条件、解锁相关状态对象等。只有当τ有效时,诚实的节点才会投票提交它。
由于恶意节点只占一小部分,传统的共识即刻解决
收获
- 共识协议的相关写法、安全性证明的写法
- 区块体双指针的提出的构造
- 跨链子交易的思想(对事务进行拆分,能实现更精细化的控制)