如何确保区块链分片技术的数据完整性
虹桥大宝剑
发表于 2022-12-21 08:47:30
134
0
0
然而,分片的分区方面引发了一个重要的潜在问题:没有下载和验证特定分片的整个历史记录,参与者不一定能够确定它们与之交互的状态是一些有效的块序列的结果,而这样的块序列确实是碎片中的规范链。非分片区块链中不存在的问题。
( {+ u5 A7 \! I0 ^2 t
我们将首先提出一个简单的解决方案来解决许多共识协议提出的问题,然后分析这个解决方案如何破解以及尝试解决它的问题。, |4 L/ R+ g& V- \- x9 v# R1 V
+ P* Z0 ~ f- O8 e" t
假设的技术方案' ]# ~! e7 `2 W9 j4 |8 d: l3 A! F
数据有效性的解决方案如下:假设我们整个系统有数千个验证器,其中不超过20%是恶意的,否则会失败(例如无法联机生成一块)。如果我们对约200个验证器进行采样,假定超过1/3失败的概率为零。
1/3是一个重要的门槛。 其中BFT共识协议,它保证只要少于1/3的参与者失败,无论是通过崩溃还是以违反协议的某种方式行事,都将达成共识。( \7 v( X: U- p
; v _, T- k, B7 C
通过假设这个诚实的验证器百分比,如果分片中的当前验证器集为我们提供了一些区块,那么解决方案假定该区块是有效的,并且它建立在验证器认为是该分片的规范链的基础上。 当他们开始验证时, 验证器从前一组验证器中学习了规范链,这些验证器通过相同的假定构建在区块之上,该区块的上层是规范链的头部。 通过归纳,整个链是有效的,并且由于在任何一个节点都没有一组验证器产生分叉,解决方案也确定当前链是分片中唯一的链。( ~- E3 b' z9 x8 b" [ p0 E
+ V+ y$ a% f2 D' F6 q
粗体
如果我们假设验证器可能被破坏,这个简单的解决方案不起作用,这不是一个不合理的假设。在具有1000个分片的系统中破坏单个分片比破坏整个系统便宜得多。因此,协议的安全性随着分片的数量线性减少。为了确定一个区块的有效性,我们必须知道,在历史上的任何一个节点,系统中的任何分片都没有大多数验证者串通;对于自适应对手,我们不再具有确定性。正如我们在前一部分中所讨论的,串通验证器可以执行两种基本的恶意行为:创建分支,并生成无效的块。
恶意分叉可以通过交叉链接到Beacon链的块来解决,Beacon链通常被设计成比分片链具有更高的安全性。然而,生成无效的区块是需要解决的一个更具挑战性的问题。
数据的有效性
5 S5 q4 R" C% I1 t
深思下图,其中shared#1被破坏,恶意行为者产生无效区块B.假设在这个区块B中1000个令牌在Alice的帐户上凭空捏造。然后,恶意行为者在B之上生成有效的区块C(在某种意义上,C中的事务被正确应用),混淆无效区块B,并向shared#2发起交叉分片事务,将那些1000个令牌传递给Bob的帐户。从这一刻开始,不正确创建的标记位于shared#2中完全有效的区块链中。
应对策略
& O% W, O5 ~7 H8 A2 e
对于Shard#2的验证器,验证从中启动事务的区块。即使在上面的示例中,这也不起作用,因为区块C似乎完全有效。
对于Shard#2中的验证器,验证在启动事务的区块之前的一些大量区块。当然,对于由接收分片验证的任何数量的区块N,恶意验证器可以在它们产生的无效区块之上创建N + 1个有效区块。
, V1 A2 D7 c) J& y+ c# p8 p
解决这个问题的一个想法是将分片安排到一个无向图中,其中每个分片连接到其他几个分片,并且只允许相邻分片之间的交叉分片事务(例如,这就是Vlad Zamfir的分片基本上如何工作,以及类似的 想法用于嘉手纳的Chainweb)。 如果在不是邻居的分片之间需要交叉分片事务,则此事务通过多个分片进行路由。 在此设计中,每个分片中的验证器应该验证其分片中的所有块以及所有相邻分片中的所有块。 考虑下面的图,其中包含10个分片,每个分片有4个邻居,并且没有两个分片需要两个以上的分片用于交叉分片通信:7 H( |) z/ o+ O' R1 O9 _
, U" q$ m. W! `4 B0 h
Shard#2不仅验证了自己的区块链,还验证了所有邻居的区块链,包括Shard#1。 因此,如果Shard#1上的恶意actor试图创建一个无效的区块B,那么在它上面构建区块C并启动一个交叉分片事务,这样的交叉分片事务将不会通过,因为Shard#2将被验证 Shard#1的整个历史记录将导致它识别无效区块B./ v8 u+ N7 v: O4 I8 r
虽然破坏单个分片不再是可行的攻击,但破坏一些分片仍然是一个问题。 在下图中,破坏Shard#1和Shard#2的攻击者使用来自无效区块B的资金成功执行Shard#3的交叉分片事务:# J/ i+ A+ R# h% W) C3 V t
8 Z# I5 {( y& I4 o
Shard#3验证Shard#2中的所有区块,但不验证Shard#1中的区块,并且无法检测恶意区块。
3 A) q% m, W9 N5 t f6 o' i& q8 A
正确解决数据有效性有两个主要方向:渔夫(fishermen)和加密计算证明。& A* n4 \) A) N' f
R. z, O3 a, ]5 ~+ M8 g8 L. y$ {
渔夫(fishermen)9 U) M4 S5 ^8 S) ^6 W6 h
第一种方法背后的想法如下:无论何时为了任何目的在链之间传递区块头(例如交叉链接到信标链,或者交叉分片事务),在一段时间内任何诚实的验证器 可以提供块无效的证明。 有各种结构能够非常简洁地证明区块是无效的,因此接收节点的通信开销小于接收完整区块的通信开销。1 H% d5 L( @. j
只要在分片中至少有一个诚实的验证器,保证系统是安全的。/ Z1 e H% ]8 t# h& W1 o% ~
这是当今提出的协议中的主要方法。但是,这种方法有两个主要缺点:
' h# ^7 F y4 D, R4 j* m
挑战期需要足够长,以便诚实的验证者能够识别生成的区块,下载它,完全验证它,并在区块无效时准备挑战。引入这样的时期会显着减慢交叉分片交易。
当恶意节点垃圾邮件带有无效挑战时,挑战协议的存在会创建新的攻击向量。这个问题的解决方案是让挑战者在指定的账户里存入一些代币,待挑战成功时再返还。这只是一个部分解决方案,因为对手向系统发送垃圾邮件(并烧毁存款)带有无效挑战(例如,防止来自诚实验证者的有效挑战通过)可能仍然存在,这些攻击被称为恶意破坏攻击。
! g! }& R. G3 w5 H0 ]
渔民的两个问题没有一个令人满意的解决方案,但严格来说,使用渔民仍然比最终确定无效区块的可能性要好。
简洁的非交互知识论证$ i* d8 J0 m, X; A' v* P$ O6 B/ e
% H$ b% M' @( }/ Z& w
解决多碎片破坏的第二种方法是使用某种密码结构,它允许人们证明某个计算(例如从一组事务中计算块)被正确执行。
1 r3 l. x M; [( R
例如zk-STARKs和其他一些共识协议,以及一些在今天的区块链协议中被广泛地用于私人支付,最着名的是ZCash。这种共识协议主要问题是它们的计算速度非常慢。例如: Coda Protocol,使用zk-SNARKs专门证明区块链中的所有区块都是有效的,每次交易可能需要30秒来创建一个证明(这个数字现在可能更小)。 a. C8 t) t( z
有趣的是,证明不需要由可信方来计算,因为证明不仅证明它所构建的计算的有效性,而且证明本身的有效性。因此,这种证明的计算可以在一组参与者之间进行划分,其冗余度显著小于执行某些不可信计算所必需的冗余度。它还允许计算zk-SNARK的参与者在特定的硬件上运行,而不会降低系统的分散性。 M K& L. U+ q$ D8 a
) M* e: x) _$ i) {- K' N, l( _& F9 V
除了性能外,zk-SNARK的挑战是?* t6 G; W& |' s" f
存在较少研究和较少时间测试的密码学原语;+ s6 `# _) F: N
“Toxic waste” 是 zk-SNARK依赖于一组可信的设置,其中一组人执行一些计算,然后丢弃该计算的中间值。如果程序的所有参与者都串通并保留中间值,则可以创建假证据;
0 M3 E) H( I3 \$ k) e
系统设计中引入了额外的复杂性算法;
8 R: e) H0 @" [) H1 x
zk-SNARK仅适用于可能计算的子集,因此具有图灵完备智能合约语言的协议将无法使用SNARK来证明链的有效性;
数据的可用性
3 [! E: n- H! y$ v0 n
我们将要讨论的第二个问题是数据的可用性。通常,操作特定区块链的节点分为两组:完整节点,下载每个完整块并验证每个事务的节点,以及仅仅下载区块头的Light节点,并使用Merkle校样来处理状态和事务的部分有兴趣。
2 w, S( u8 u; h$ C2 @
现在,如果大部分主要完整节点串通,则它们可以生成有效或无效的区块,并将其散列发送到轻节点,但不透露块的全部内容。 他们可以通过各种方式从中受益。 例如,请看下图:! I2 I3 K' n7 n a( Z/ q! H
. M0 `4 U" t7 E4 X
目前这里有三个区块:前一个A,由诚实的验证者生成;B有验证者串通;接下来,C也将由诚实的验证者产生;
, |4 m: }' g! ^" N$ {0 e; p$ U
你是商人。当前区块(B)的验证器从先前的验证器接收到区块A,计算出您收到钱的区块,并向您发送该块的标题,其中包含您有钱的状态的Merkle证明(或Merkle)证明将有效汇款发送给您的有效交易)。确保交易最终确定,您就可以提供服务。7 J* H0 M4 L8 G9 i) t; c" p d
' D, [# l/ y9 @* u* [8 D/ g1 F
但是,验证器永远不会将区块B的全部内容分发给任何人。因此,区块C的诚实验证器无法检索块,并且被迫停止系统或构建在区块A之上,从而剥夺了您作为货币的商家的权利。. s' E& u# f& F) a" w' a, m1 ^1 e( |8 @
当我们将相同的场景应用于分片时,full和light节点的定义通常适用于每个分片:每个分片中的验证器下载该分片中的每个块并验证该分片中的每个事务,但验证系统中的其他节点,包括那些快照分片链状态进入信标链,只下载标题。因此,分片中的验证器实际上是该分片的完整节点,而系统中的其他参与者(包括信标链)作为轻节点操作。* n# d+ R" C0 O( R c
对于我们上面讨论过的渔夫方法,诚实的验证者需要能够下载与信标链交叉链接的区块。如果恶意验证器交叉链接无效区块的头(或用于启动交叉分片事务),而从未分发区块,则诚实的验证器无法进行挑战。5 T, {/ p+ \* P% q O
我们将介绍两种相互补充的解决方法:
7 N; K& d/ W4 r1 y5 {
监护证明proof-of-custody( C9 T; v0 ~$ N: r- x6 ]8 @
9 w4 P* T) b* J3 D/ y
要解决的最直接的问题是,区块一旦发布,是否可用?一个提出的想法是让所谓的公证人在分片之间轮换,而不是验证器,其唯一的工作是下载一个区块,并证明他们能够下载它。与验证器不同,它们可以更频繁地旋转,因为它们不需要下载分片的整个状态。- @& ]( E; J" q' l
这种天真的方法的问题是,以后无法证明公证员是否能够下载该区块,因此公证员可以选择始终证明他们能够下载该区块而不尝试检索它。对此的一种解决方案是公证员提供一些证据,或者投入一定数量的令牌来证明该区块已被下载。
* q, b( P6 W9 \0 a! E
纠删码技术(Erasure codes)% ]4 n% _( j* Q- i! e
; e' A4 C8 t, n: ~7 w
当特定的轻节点接收到一个区块的散列时,为了提高节点对该区块可用的信心,它可以尝试下载该区块的一些随机片段。这不是一个完整的解决方案,因为除非轻节点共同下载整个区块,否则恶意区块生产者可以选择保留未被任何轻节点下载的块的部分,因此仍然使区块不可用。
一种解决方案是使用一种称为Erasure Codes的结构,即使只有区块的某些部分可用,也可以恢复整个区块:
Polkadot和Ethereum Serenity都围绕这个想法进行了设计,为轻节点提供了合理地确信区块可用的方法。这两种方法都依赖于挑战,因此可能容易受到恶意攻击。; V4 J! n* t$ m9 k/ g r
长期可用性和结论
( F7 |: Q/ c& H/ s6 t# I
注意,上面讨论的所有方法都只证明了一个事实,即一个块一旦发布,并且立即可用。区块随后可能由于各种原因变得不可用:节点脱机、节点故意擦除历史数据等等。
4 E8 z* y: ], n6 D
一篇值得一提的解决方案的白皮书是Polyshard,即使几个分片完全丢失了它们的数据,Polyshard使用纠删码技术让跨分片区块依然可用。4 F, J) k& d8 N& J
& O1 k2 c$ d% _! W% N
由于预计系统中没有参与者能够验证所有分片中的所有链,因此分片协议的安全性需要以这样的方式设计:即使某些分片中的某些旧块变得完全不可用,系统也是安全的。
在设计安全协议时,数据有效性和数据可用性仍然是首先需要关注的问题。
成为第一个吐槽的人