深入解析Starknet Bolt升级

Starknet的最新升级(v0.13.2)Bolt引入了两大变化:并行执行和区块打包,旨在实现以太坊的快速和便宜的区块空间。并行执行使得非争用交易可以同时执行,从而降低交易确认时间和费用;而区块打包则通过生成单一证明来同时验证多个Starknet L2区块,从而减少资源使用和操作成本。这些改进将有助于提升Starknet的性能并确保其在L2空间的竞争力。

Starknet最新的升级(v0.13.2)名为Bolt,带来了两个主要改变:并行执行区块打包。虽然这两个功能彼此独立,但都支持向快速、便宜的区块空间目标的推进,而这些区块空间由以太坊的加密方式保障。

并行执行允许非争用交易(即不触及相同状态的交易)同时执行。通过实施并行执行,像Starknet这样的L2可以在不增加资源使用的情况下减少执行时间。这意味着用户的交易费用降低,交易确认时间显著改善。

区块打包优化了Starknet在以太坊L1上对blobspace的使用:通过区块打包,序列器可以生成一个证明来同时验证多个Starknet L2区块。这将blobspace的使用与L2区块生产频率脱钩,并摊平了证明验证成本。这两者都减少了Starknet序列器的运营成本,这意味着用户每笔交易支付更少。

正如我们所说,Bolt使Starknet更加便宜和快速!本报告将提供Bolt升级的详细分析,重点在于并行执行和区块打包,并探讨其对Starknet性能的影响。

快速回顾Rollups

Rollups是第二层(L2)扩展解决方案,旨在通过将计算移出链来扩展底层的一层(L1)区块链。通过将执行移出链,Rollups可以优化可扩展性(便宜和快速的交易),而L1为L2交易提供安全性。

Rollups通常被称为“从L1继承安全性”。这本质上意味着它们继承L1提供的共识和数据可用性保障。此外,L1还通过与Rollup之间的安全桥接提供了安全保障。

当序列器将L2区块发布到L1时,L1提供了对该信息的可用性和顺序性保证。从这里,L2节点可以在没有信任的情况下,运用这些信息以及节点实现中描述的Rollup规则,计算出公认的L2链。

为了方便L1和L2之间的安全桥接,L1要求证明它目前遵循的L2链是正确的,并且不包含非法状态更改(例如双重支付)。Rollups需要证明状态更改的有效性,确保L1不会基于非法状态授权从Rollup进行提款。

Rollups基于如何向L1证明状态更改的有效性而有所不同:

  • 有效性Rollups依赖于有效性证明来客观验证执行的正确性。提议者允许在提交有效性证明给Rollup合约的情况下提出一个新的Rollup状态。
  • 乐观Rollups依赖于缺失欺诈证明来主观验证执行的正确性。提议者在没有证据的情况下提交状态更新,但是Rollup合约可以撤销任何被欺诈证明成功挑战的状态更新。

Rollups还向基础层提供了足够的数据,以便感兴趣的方重构L2状态。虽然乐观Rollups必须发布完整的交易数据,以便使挑战者能够计算欺诈证明,但有效性Rollups并没有这样的要求(有效性证明保证了正确执行)。但是,从信任最小化的角度来看,在L1上发布完整交易数据仍然是有用的(无信任状态重建和无权限提款)。

Starknet是一个有效性Rollup,它使用可扩展的透明知识证明(STARKs)来证明状态更改的有效性。对Starknet的最新升级——代号Bolt——添加了并行执行和区块打包。在接下来的部分中,我们将解释这两个功能是如何工作的,以及它们为Starknet用户带来了什么改善。

Starknet Bolt升级改变了什么?

从高层次来看,Bolt升级改变了Starknet的执行、证明和数据可用性机制。

优化执行

在Bolt升级之前,Starknet交易是由序列器按顺序执行的——一个接一个。顺序执行简单,但效率非常低。这种效率低下是因为没有利用现代计算机提供的多个独立处理单元和一组交易的并行性。

顺序执行

并行执行

并行性是衡量给定集合中的交易独立程度的一个指标。例如,考虑下面的三笔交易集:

  • 交易1:Alice想给Bob发送1个STRK
  • 交易2:Caitlyn想给Danny发送100个ETH
  • 交易3:Caitlyn想给Ella发送100个ETH

交易1与交易2和交易3完全独立——因为它访问的是不同的状态部分(Alice的余额)——可以并行执行。然而,交易2和交易3是冲突的,因为它们想访问相同的状态——Caitlyn的ETH余额。这些交易不能并行执行,否则我们将得到冲突的结果。

为了举例说明:

  • 假设Caitlyn的余额是300个ETH,交易2和交易3同时开始。两个交易将初始余额读取为Caitlyn的账户上的300个ETH,从中扣除转账金额(300 - 100 = 200),并将200个ETH写入存储Caitlyn账户余额的内存位置。
  • 然后,交易2和交易3分别读取Danny和Ella的余额,并给这两个用户的余额各添加100个ETH。Caitlyn的余额将减少100个ETH,但200个ETH将被记入——实际上相当于从无到有产生了100个ETH。

避免这些类型的冲突(以及复杂的缓解机制)是为什么以太坊选择顺序执行。然而,尽管顺序执行降低了复杂性并提高了安全性,但它导致了硬件的低效率。更糟糕的是,硬件设计的趋势表明,顺序执行在未来几年将变得越来越低效。

图4显示了过去50年硬件设计的趋势。相关的要点是什么?自2000年代中期以来,单线程性能(紫色圆圈)一直处于停滞状态,而逻辑核心的数量大约在同一时间增加。我们可以根据这些数据得出两个结论:

  • 硬件设计者通过增加更多的独立处理单元来扩展电脑芯片,而不是提高单个单元的性能。
  • 任何继续依赖于单个处理单元性能提升的系统,在新硬件上也会经历性能提升的停滞。

图 4: 微处理器趋势

近年来,管理交易冲突和确保并行执行正确性的复杂算法已经出现。Block-STM(基于Fikunmi等人的论文*)就是这样一种算法,并且是Starknet新并行执行引擎的核心部分。我们将在后面的部分分析Block-STM算法。

优化证明和数据可用性

Starknet的SHARP(共享证明器的缩写)一直利用递归证明尽可能地降低验证成本。递归证明本质上是一个“证明的证明”,其中一个证明验证一个或多个证明的正确性。以下是SHARP生成递归证明的概要:

  • SHARP系统将要执行的一组程序(一个“任务”)作为输入,并为该任务生成一个执行证明。这些“程序”是L2区块,证明证明了交易的正确性。
  • 证明发送到另一个程序以验证证明,并将证明验证程序转换为一个任务。SHARP将新的任务作为输入并生成另一个证明(这个证明确认前一个证明的有效性)。
  • 该过程(证明 → 任务 → 证明)重新开始,并继续进行,直到达到目标,此时最终的证明(现在是原始证明的高度压缩版本)被发布到L1。

图 5: 递归证明生成

这个设计大大摊平了成本,主要有两个原因:

  • 后续的任务并不是单个程序或交易,证明成本以次线性增长。这意味着“程序/交易”数量越多,节省的成本就越大。通过为每个区块创建证明,而不是为每个交易创建证明,交易费用可以大幅降低。
  • 递归大大压缩了证明,导致“证明的证明”在L1上的验证成本显著低于初始证明或任何中间证明。

尽管证明系统非常好,但还存在进一步节省成本的机会。例如,每个任务都是一个单独的Starknet区块,并且每个区块设计为占用L1上的一个blob。这导致了某些低效,具体如下:

在Bolt之前,Starknet并没有(也仍然没有)常规的区块时间;而是一个L2区块在满足两个条件时发布到L1:(1)执行了一blob大小的数据(2)距离上一个区块六分钟。但是,由于需求大部分区块是由于六分钟限制发送到L1(而不是DA限制)。

上述情况导致blob(而不是区块)经常被(严重)低效利用,产生不必要的高Gas费用。Starknet区块还有 固定成本,理论上可以通过将上述相同的递归技术应用于制作多个区块的证明来降低。

区块打包通过使用递归证明的二叉树来解决这些问题。我们将在文章的后面部分讨论区块打包。

Bolt 第一部分:并行执行****

如前所述,顺序执行效率低下(并且随着时间的推移只会变得更加低效),而天真的并行执行会产生无效结果。生产并行执行引擎会小心避免不一致的结果。

处理并行执行有两种方法:悲观并发控制(PCC)乐观并发控制(OCC)。PCC和OCC都是交易处理单元(TPU)。以下是来自Block-STM与SVM:并行执行引擎比较:的交易处理单元定义。

TPU通常与虚拟机(VM)相结合,但又有所不同。区块链虚拟机如EVM、SVM和MoveVM是高级语言虚拟机……TPU通常是感兴趣的主题,负责管理整个交易执行管道,包括创建和管理VM实例。

悲观并发控制基于以下假设设计,即将在要执行的交易集中,许多交易将发生冲突,即它们将接触相同的状态。PCC 防止这些冲突。

为防止冲突,PCC要求交易提前声明它在读取/写入操作时将访问哪些状态部分。交易处理单元可以利用此信息以确保冲突交易按顺序(而不是并行)执行。一些TPU还使用锁来强制执行这种行为(锁(又名互斥锁)是一种用于防止对内存位置进行并发访问的机制)。

也就是说,基于PCC的执行会产生某些权衡。首先,提供访问列表(标识交易接触的内存插槽)的要求,降低了开发体验,并减少了可用应用的范围。其次,调度交易可能会产生不必要的开销——尤其是在没有冲突的情况下。

乐观并发控制的设计假设在于给定集合中的许多交易将不会发生冲突,即它们不会写入相同的状态。因此,OCC TPU在所有可用资源上执行交易集,并仅尝试检测冲突。如果检测到冲突,冲突的交易将被执行和重新验证,直到整个集合通过并可以被提交。

OCC TPU不会因为调度而产生开销,因此在冲突较少的情况下它们往往表现更好。基于OCC的交易处理单元还拥有更优的开发体验和更广泛的使用案例,因为状态依赖性不需要提前知道。

然而,当交易集高度争用时,OCC的表现不如PCC。我们在我们的文章中对TPU设计进行了更为详细的讨论,并比较了OCC和PCC的方法。

Starknet的新TPU采用了OCC的方法。更具体地说,它是Block-STM算法的实现。Block-STM以乐观方式执行交易,假设所有可用资源不会冲突,并在执行后验证没有冲突的交易并发执行。在深入探讨Starknet的新架构之前,有必要了解一些关键定义:

  1. 状态:状态是某个对象在某一时刻的条件。在区块链上下文中,通常指的是一部分内存的值,例如,一个地址的余额是(部分)其状态。
  2. 可序列化性:如果串行和并行执行一组交易产生相同的结果,那么就说并行执行保持了可序列化性的特性。
  3. 冲突:当且仅当至少有一个交易希望写入两个交易都希望访问的某个状态部分(可以是读或写)时,两个交易被称为冲突。如果两个交易仅从某个状态部分读取数据,那么就没有冲突,但如果至少有一个交易正在写入该状态部分,则这些交易不能并行执行而不破坏可序列化性。我们在上述Caitlyn、Danny和Ella的例子中讨论了一个示例情况。
  4. 依赖关系:当且仅当两个交易都写入同一内存位置,且txj在串行顺序中位于txi之后时,交易txj被称为依赖于(或为)交易txi。如果txitxj之后,那么txi将依赖于txj
  5. 多版本数据结构:多版本数据结构是指每次写入数据结构时都会为数据结构创建一个新版本。它不是在原地更改值,而是创建一个新的特定于写入的版本,值的优势在于,它允许在内存的同一区域进行大量并发的读取和写入。我们稍后将探讨这种优势的用处。

在定义解释完之后,我们可以继续讨论Block-STM是如何工作的。

Block-STM如何工作

Block-STM的输入是一个交易队列(有序列表),这个列表通常称为BLOCK。这个列表的排序可以是任意方式;唯一的要求是必须有一个明确定义的顺序。因此,给定一个包含交易的集合T {t0…tn},这些交易被排序为 {t0 > t1 > t2 … > tn}(读作t0优先于t1t1优先于t2等等)。

在执行过程中,会创建两个集合——执行集合E和验证集合V。E跟踪尚未执行的交易,而V跟踪已执行但尚未验证的交易。

每笔交易还与一个代号n相关联,以跟踪它已执行(和重新执行)的次数。这些集合的初始状态是E包含所有交易,而V为空,即E = {t0,1 > t1,1 > t2,1 > … > tn,1}和V = {}

通过这些有序的交易集合,每个用于执行的线程在三阶段循环中循环:

  1. 检查完成
  2. 查找下一个任务
  3. 执行任务

检查完成

在这一步中,线程同时检查V和E。如果两个集合都为空,并且没有正在执行的交易,则说明当前批交易已完全执行,可以将结果提交到存储中。

查找下一个任务

如果V或E任一集合包含交易,Block-STM选择索引最低的交易(而不是代号)作为下一个任务,即如果E包含{t1,3 , t3,1, t5,2}而V包含 {t0,1, t2,4, t4,3},那么交易t0的验证任务将被选为下一个任务。

执行任务

一旦确定并选择了下一个任务,便开始执行。在这一步结束时,算法循环回到检查完成。这一过程持续进行,直到两个集合的交易都为空。

让我们看一下执行和验证期间发生了什么。

在执行某笔交易期间,Block-STM算法为每笔交易填充两个集合(每笔交易);一个读取集(Ri,n)和一个写入集(Wn,i)。读取集包含交易在执行期间从中读取的所有内存位置,而写入集包含其写入的所有内存位置。在执行过程中,交易将其写入应用于多版本数据结构,但读取则稍微复杂一些。

在Block-STM中,当交易想要从数据结构中读取时,它会检查由优先级最低的写入(拥有更高优先级的交易)写入的值。例如,如果tx1tx2tx7都写入了一个内存位置,而tx5想要从该位置读取,则它读取对应于tx2的数据结构版本。

这样做是为了保证可序列化性;因为tx5应该在tx2之后执行,而在tx7之前,因此它应使用tx2写入的值,而不是tx7。在这个示例中,tx7必须重新执行,因为它应读取tx5写入的值,而不是tx2或任何更高优先级的交易。如果使用的是单版本数据结构,则tx2写入的值将不可用,冲突将不可避免。

对于某个验证任务,该交易的读取集将与其在执行期间读取的内存位置的当前值进行比较。例如,如果tx2在执行期间读取了账户B,则在验证期间,会读取该账户B的内存位置(牢记我们之前建立的读取定义)。如果两个值相同,则意味着在tx2的执行过程中,没有更高优先权的交易(例如tx0tx1)写入过该位置。这使得tx2标记为已验证,但还不可以提交。

该交易不被认为是安全提交,因为由于种种原因,一个低优先级的交易可能在该交易被验证后执行。因此在我们的运行示例中,如果tx1触碰到账户B并且在tx2通过验证后才触碰,那么tx2需要重新执行。

为此,任何交易完成执行后,所有在验证中通过且优先级低于的交易都需要重新验证,以确保它们与该交易不冲突。例如,如果tx1tx3tx4已通过验证,而tx2完成执行,则tx3tx4必须重新验证,以确保它们不会冲突(并且是tx2的依赖)。

如果交易未通过验证,即与它并发执行的写入同一状态的更高优先级交易已执行,那么该交易的写入被标记为脏(因为值错误)。但是,而不是完全从数据库中删除这些值,它们被标记为估算。

估算标志告诉任何读取该内存位置的交易,位置中的值不正确,因此这些交易会暂停执行。这是为了避免删除,因为该失败验证的交易重新执行时,原则上可能会向与之前的执行相同的内存位置写入。

通过将内存位置标记为估算而不是完全删除,可以提前捕获依赖关系(即失败验证的交易),从而避免不必要的重新执行。这一启发性措施大大减少了浪费的工作。

整合

Block-STM对并行化的完整方法可总结如下:

  • 一组交易的BLOCK起初为有序列表,具备明确定义的串行顺序。按优先级顺序在可用资源上执行这些交易。
  • 在执行过程中,跟踪交易的读取和写入集,并从多版本数据结构中读取或写入。当交易完成执行后,它会经过验证,以确保它没有与任何冲突交易并发执行。
  • 如果交易通过验证,则将其从E和V中移除。当交易通过验证时,所有已验证且优先级低于的交易也会重新计划进行验证。
  • 如果交易未通过验证,则将其重新计划进行执行。当所有交易均已执行和验证后,此BLOCK就安全可提交,并将结果写入永久存储。

下面是一个示例:

图 6: Block-STM 示例

这是对Block-STM工作方式的概述,更多详细信息可以在我们报告这里和原始Block-STM论文这里中找到。

Block-STM如何提高Starknet性能?

为了量化添加Block-STM的重要性,我们进行了一些基准测试,以评估其与顺序执行相比的性能提升,结果如下所示。

图 7: Block-STM在1k区块大小下的性能

图 8: Block-STM在10k区块大小下的性能

结果表明,随着使用的线程数量(类似于独立处理单元)的增加,性能也在提高。较大区块的改进更加显著,在仅使用16个线程的情况下,实现了顺序执行的9倍性能提升。我们发现,对于较大区块,结果更为明显。

我们的测试显示,在高度争用负载下,Block-STM性能确实显著下降,但行业标准做法是在此类期间回退到顺序执行。我们建议Starknet采用相同的机制,以保留在高度争用工作负载下的吞吐量。总的来说,添加Block-STM将大幅提升并保护Starknet的未来。

v0.13.2升级中捆绑的第二个重大更改是区块打包,我们将接着讨论。

Bolt 第二部分:区块打包****

如前所述,Bolt之前,每个Starknet区块都是其自己的任务,这导致每个区块固定的成本。此外,系统的设计是每个区块都需要自己的blob,无论该区块实际消耗了多少数据。

在一个始终有高需求的世界中,这并不是问题,但Starknet当前提供的区块空间超过了需求,因此浪费了许多资源,这可能造成每月损失数百ETH。为了进一步强调Bolt之前的情况的严重性,这里是发布一个区块到L1的成本。

  1. 每个事实注册23K Gas – 属于验证证明和注册
  2. 每个注册SHARP内存页需56K Gas
  3. 每个状态更新需136K Gas
    1. 使用KZG预编译来采样一个blob需要50K Gas,
    2. 运行状态更新函数需要86K Gas。

这大约合计215K Gas per块,这个成本是固定的,即无论每个区块包含多少数据,与区块数量有关的关系为$Cost = num blocks * 215000$。解决此问题的理想方案应是费用与发布的数据量相关,而不是与区块的数量相关。而区块打包正是通过SNAR树实现了这一目标。

SNAR树****

Starknet的应用递归(SNAR)树是一种在Bolt中引入的新类型的二叉树,以解决上述问题。SNAR树具有以下结构:每个叶子节点是一个Starknet区块,而其他所有级别的节点都是其子节点的递归证明。作为所有其他证明的递归证明,根节点是发送给共享证明器(SHARP)的最终任务。

图 9: SNAR树

图 10: SNAR树在区块打包工作流中的作用

SNAR树的作用?

SNAR树的主要好处在于,不再是每个证明发布一个区块,而是可以将多个Starknet区块摊平到同一个L1更新中。SNAR树根节点现在仅在满足两个可配置限制中的一个时发布到L1:要么是DA限制(6个blob大小的数据),要么是在树中添加了一定数量的叶子(叶子即区块)。

这种设计使得交易的成本与区块的数量脱钩。现在,仍然存在某个固定成本来自于在每个区块中运行StarkNet OS(SNOS)——但总的来说这些成本是脱钩的。现在的数据如下:

  1. 每个任务的SHARP内存注册:23K Gas,(与之前相同)
  2. 每个任务的SHARP内存页面:36K Gas(因SHARP优化从56K降至36K),
  3. 每个任务的状态更新等于:
    1. 86K Gas(与之前相同) +
    2. 50K Gas × blob使用数量。(当每个块只消耗一个blob时,这个数值就是50K x 1,从而得出之前的136K Gas数字)。

下图的图11展示了在之前的设计与现在(在Bolt之下)之间,Gas成本随区块数变化的情况:

图 11: 打包与未打包的验证成本

显而易见,区块打包大大降低了L1上的验证成本,这无疑将导致Starknet用户的Gas价格降低。

结论

Bolt中进行的更改:通过Block-STM的乐观并行执行和通过专有的SNAR进行的区块打包,可以总结为:更快且更便宜。

并行执行减少了执行时间,随后减少了拥堵,这将在高流量期间降低Gas费用,而SNAR树解决了相关的数据可用性和证明成本。有趣的是,这次升级使Starknet成为第一个具备并行执行的L2,并使其在L2领域成为一个主要竞争者。值得注意的是,这些变化的影响不太可能立即显现,特别是并行执行这一方面,但它们对确保Starknet和整个以太坊生态系统未来至关重要。

你可以在这里找到关于Bolt和Starknet的更多信息。

参考文献

Starknet的“Bolt”升级:2秒交易已到来

什么是Starknet

Starknet v0.13.2预发布说明

https://book.starknet.io/ch03-03-provers.html

乐观并行化复兴

即将推出的功能:Starknet的应用递归

Starknet的成本和费用

Block-STM与Sealevel:并行执行引擎比较

  • 原文链接: research.2077.xyz/unpack...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
2077 Research
2077 Research
https://research.2077.xyz