StarkNet 性能路线图

原文StarkNet Performance Roadmap
翻译及校对「StarkNet 中文社区」

概要

  • 与 L1 不同,有效性证明 Rollup 吞吐量不受限制。L2 有效性证明 Rollup 上可以产生更高的 TPS

  • StarkNet 性能路线图解决了系统中一个关键要素:排序器(sequencer)

  • 性能改进路线图如下:

    — 排序器并行化

    — Cairo 虚拟机用 Rust 实现

    — 排序器用 Rust 重新实现

  • 经过实战考验的证明器并不是瓶颈,处理量可以比现在更多!

介绍

StarkNet 大约在一年前登上主网,团队一开始专注于功能性,而现在重点转移到了提高性能上,通过一系列步骤来提升 StarkNet 用户体验。

在这篇文章中,将解释为什么只有有效性证明 Rollup 可以有广泛优化空间,并分享在 StarkNet 上实施这些优化的计划。其中一些已在 StarkNet Alpha 0.10.2 中实现,该版本于 11 月 16 日上线测试网,并在 11 月 28 日上线主网。那么在讨论解决方案之前,先来回顾一下性能的限制及其原因吧。

区块限制:有效性证明 Rollup 对比 L1

提高区块链可扩展性和 TPS 的一种潜在方式是取消区块限制(在 gas 或区块大小方面),同时保持出块时间不变。对生产区块者(L1 上的验证器和 L2 上的排序器)和组件性能要求更高。为此,现在团队的开发重点转移到优化 StarkNet 排序器上,下文将对此部分进行更详细的描述。

这里自然还会出现一个问题。为什么排序器优化仅限于有效性证明 Rollup?换句话说,为什么不能就在 L1 上优化,非要费事部署有效性证明 Rollup?在下一小节中,将阐述两者之间的根本区别,解释为什么可以在 L2 上进行广泛优化,而在 L1 不适用。

为什么 L1 吞吐量受限?

如果解除 L1 的区块限制,将会有个严重的问题。提高区块链的吞吐增长率,也会提高对全节点的需求,来保证跟进最新的状态。由于 L1 全节点必须重新执行所有的历史记录,区块大小的大幅增加(就 gas 而言)会带来巨大压力,再次导致较弱的机器退出系统,并将运行完整节点的能力留给足够强大的实体。结果就是,用户无法自己验证状态,也不能无需信任地参与网络。

所以应该限制 L1 吞吐量以维护真正去中心化和安全的系统。

为什么有效性证明 Rollup 不会因此受限?

只有从全节点的角度考虑,我们才能看到有效性证明 Rollup 的真正实力。L1 全节点需要重新执行整个历史记录以确保当前状态的正确性。而 StarkNet 节点只需要验证 STARK 证明,且这种验证所占用的计算资源呈指数级下降。特别是,从头开始同步不必涉及执行;节点可以从其他节点获取当前状态的转储,只需通过 STARK 证明来验证状态是否有效。这样就可以增加网络的吞吐量,而不增加全节点负载。

因此可以得出结论,优化 L2 排序器即是全方位提升系统性能,而在 L1 上是无法实现的。

未来的性能路线图

下文将讨论 StarkNet 排序器优化计划。

排序器并行化

路线图的第一步是将并行化引入交易执行,在 11 月 28 日上线主网的 StarkNet Alpha 0.10.2 中已引入。现在来深入了解下什么是并行化(这是个半技术性的部分,若要了解路线图,请跳到下一节)。

那么「交易并行化」是什么意思呢?简单来说,并行执行多个交易区块是不可能的,因为不同的交易可能是相互依赖的。下方示例中进行说明,假设有一个区块包含来自同一用户的三笔交易:

  • 交易 A:将 USDC 兑换为 ETH

  • 交易 B:用 ETH 购买某个 NFT

  • 交易 C:将 USDT 兑换为 BTC

显然,交易 A 必须在交易 B 之前发生,但交易 C 完全独立所以可以并行执行。如果每执行一笔交易需要 1 秒时间,那么引入并行化后,出块时间就可以从 3 秒减少到 2 秒。

问题的症结所在是事先并不知道交易的依赖关系。实际上,只有当执行交易 B 时,才能知道它依赖于交易 A 所做的更改。更正式一点的说法是,这种依赖性源于交易 B 从交易 A 写入的存储单元中读取的事实。可以把交易看作一个依赖图,从交易 A 到交易 B 有一个边界,仅当 A 写入以一个由 B 读取的存储单元时,交易 B 才可以执行。下图显示了这种依赖图的一个示例:

在上面这个示例中,每一列都可以并行执行,这是最佳安排(一般会按顺序执行交易 1-9)。

为克服事先不知道依赖图这一难题,团队根据 Aptos Labs 开发的 BLOCK-STM 为 StarkNet 排序器引入了乐观并行化(optimistic parallelization)。在此范式下,系统将乐观地尝试并行执行交易,在发现冲突时重新执行。例如,并行执行图中的交易 1-4 时,会发现交易 4 依赖于交易 1。因此,它的执行是无效的(尽管执行交易 4 需要依照交易 1 执行后的状态,但先尝试对照交易 1 相同的状态同步执行)。在这种情况下,将重新执行交易 4。

请注意,乐观并行还有许多可优化之处。比如,不是单纯等待每次执行结束再判断,而是可以在发现有无效交易依赖项时中止执行。

另一个可以优化的例子是选择哪些交易来重新执行。假设上图中所有交易打包进一个区块送入 5 核 CPU 的排序器。首先尝试并行执行交易 1-5,如果完成顺序是交易2、交易 3、交易 4、交易 1,最后是交易 5,那么只有在交易 4 已经执行完之后,才会发现交易 4 依赖于交易 1,此时应重新执行。一般可能会想也重新执行交易 5,因为考虑到重新执行交易 4 可能会导致交易 5 的行为有所不同。然后,遍历执行已终止的交易所构建的依赖图,可以发现只需重新执行依赖于交易 4 的交易,而不是仅仅交易 4 无效之后重新执行所有交易。

Cairo 虚拟机的 Rust 新实现

StarkNet 中的智能合约是用 Cairo 编写的,并在 Cairo 虚拟机中执行,说明可查阅 Cairo 白皮书。目前,排序器使用 Python 版 Cairo 虚拟机实现。为优化虚拟机的实现性能,开发团队正在用 Rust 重写虚拟机。感谢 Lambdaclass 的出色工作,他们是 StarkNet 生态系统中非常宝贵的团队,这项工作也很快就会取得成果。

虚拟机的 Rust 实现(cairo-rs)现在可以执行原生 Cairo 代码。下一步是处理智能合约的执行,并与 python 兼容的排序器集成,一旦与 cairo-rs 集成,排序器的性能有望得到显著提升。

排序器用 Rust 重新实现

从 python 转到 Rust 对性能的提升不仅限于 Cairo 虚拟机。除了上述改进之外,团队还计划用 Rust 重新开始写排序器。除了 Rust 的内部优势之外,还能从其他方面优化排序器。比如可以兼容 cairo-rs,无需负担 python-rust 的通信开销。也可以完全重新设计状态的存储和访问方式(现在是基于 Patricia-Trie 结构)。

关于证明器

在上文中还未提到有效性证明 Rollup 里最重要的原件 — 证明器。可以想象,作为可以说是架构中最为复杂的组件,证明器应该是性能瓶颈,因此也应该是优化的重点。但有趣的是,现在 StarkNet 的瓶颈是更加「标准」的组件。特别是有了递归证明,证明中的可容纳交易量比当前测试网和主网更高。事实上,StarkNet 区块与 StarkEx 交易一起得到有效的证明,后者有时会有数十万 NFT 的铸造事件。

总结

为即将到来的 StarkNet 新版本中改进的 TPS 做好准备吧,敬请期待并行化、Rust 还有更多!

Subscribe to Starknet 中文
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.