前言
StarkNet将一年前在主网推出,对StarkNet的构建主要集中在功能层面。现在,将注意力转移到网络性能改善上,目标是通过一些列的功能改进来改善StarkNet的使用体验。
区块限制:Validity Rollups vs L1
提高区块链可扩展性和 TPS 的一种潜在方法是解除区块限制(在gas/size方面),同时保持区块时间不变。这将需要区块生产者(L1 上的validators,L2 上的sequencers)付出更多努力,因此需要更有效地实施这些组件。为此,现在将重点转移到 StarkNet sequencer optimizations上,以下部分中是更详细的描述。
这里自然会出现一个问题。为什么 sequencer 优化仅限于validity rollups,也就是说,为什么我们不能在 L1 上实现相同的改进并完全避免validity rollups的复杂性?在下一节中,将会说明两者之间存在根本区别,可以广泛在L2 进行的优化并不能在L1进行。
为什么 L1 吞吐量有限?
不幸的是,解除对 L1 的区块限制会遇到一个重大陷阱。通过提高链的增长率,我们也增加了全节点的需求,他们试图跟上最新的状态。由于 L1 全节点必须重新执行所有历史记录,块大小的大幅增加(就gas而言)会给它们带来巨大压力,再次导致较弱的机器退出系统并保留运行全节点的能力仅限于足够大的实体。结果,用户将无法自己验证状态并无信任地参与网络。
这让我们明白 L1 吞吐量应该受到限制,以维护一个真正去中心化和安全的系统。
为什么相同的障碍不影响validity rollups?
只有从全节点的角度考虑,我们才能看到有效性汇总所提供的真正力量。 L1 全节点需要重新执行整个历史以确保当前状态的正确性。 StarkNet 节点只需要验证 STARK 证明,而这种验证所占用的计算资源量呈指数级下降。特别是,从头开始同步不一定涉及执行;一个节点可能会从其对等节点接收到当前状态的转储,并且只能通过 STARK 证明来验证该状态是否有效。这使我们能够在不增加全节点要求的情况下增加网络的吞吐量。
因此,我们得出结论,L2 sequencer受到整个优化范围的影响,这在 L1 上是不可能的。
Sequencer 并行化
那么“事务并行化”是什么意思呢?老实说,并行执行一个交易块是不可能的,因为不同的交易可能是相互依赖的。这在以下示例中进行了说明。考虑一个包含来自同一用户的三笔交易的区块:
Tx A:将USDC换成ETH
Tx B:为 NFT 支付 ETH
Tx C:USDT换BTC
显然,Tx A 必须在 Tx B 之前发生,但 Tx C 完全独立于两者并且可以并行执行。如果每笔交易需要 1 秒来执行,那么通过引入并行化,出块时间可以从 3 秒减少到 2 秒。
问题的症结在于,事先并不知道交易的依赖关系。实际上,只有当从示例中执行Tx B 时,才能看到它依赖于Tx A 所做的更改。更正式地说,这种依赖性源于Tx B 从Tx A 写入的存储单元中读取这一事实。可以将Tx视为一个依赖图,其中存在从Tx A 到Tx B 的一条边,当且仅当 A 写入一个由 B 读取的存储单元,因此必须在 B 之前执行。下图显示了一个这种依赖图的示例:
在上面的示例中,每一列都可以并行执行,这是最佳调度(事实上,会按顺序执行事务 1-9)。
为了克服事先不知道依赖图的事实,考虑参考 Aptos Labs 开发的 BLOCK-STM 的理念,将乐观并行化引入到 StarkNet sequencer中。在这种范式下,我们乐观地尝试并行运行事务并在发现冲突时重新执行。例如,我们可以并行执行图 1 中的Tx 1-4,之后才发现 Tx 4 依赖于 Tx1。因此,它的执行是无用的(。在这种情况下,我们将重新执行 Tx4。
值得注意的是,可以在乐观并行化之上添加许多优化。例如,与其天真地等待每次执行结束,可以在发现使它无效的依赖项时中止执行。
另一个例子是优化重新执行哪些交易的选择。假设包含图 1 中所有事务的块被送入具有五个 CPU 内核的定序器。首先,尝试并行执行交易 1-5。如果完成的顺序是Tx2,Tx3,Tx4,Tx1,最后是Tx5,那么只有在Tx4已经执行完之后,我们才会发现依赖Tx1→Tx4——说明应该重新执行。实际上,可能也想重新执行 Tx5,因为考虑到 Tx4 的新执行,它的行为可能会有所不同。然而,可以遍历由执行已经终止的交易构建的依赖图,只重新执行依赖于 Tx4 的交易,而不是仅仅重新执行现在无效的 Tx4 之后的所有交易。
Cairo-VM 的新 Rust 实现
StarkNet 中的智能合约是用 Cairo 编写的,并在 Cairo-VM 中执行,该规范出现在 Cairo 论文中。目前,sequencer正在使用 Cairo-VM 的 python 实现。为了优化 VM 实现性能,我们发起了用 Rust 重写 VM 的工作。感谢 Lambdaclass 的出色工作,他们现在是 StarkNet 生态系统中一个非常宝贵的团队,这项工作很快就会取得成果。
VM 的 Rust 实现 cairo-rs 现在可以执行原生 Cairo 代码。下一步是处理智能合约的执行和与 pythonic sequencer的集成。一旦与 cairo-rs 集成,音序器的性能有望显着提高。
Rust 对 sequencer重新实现
我们从 python 到 rust 以提高性能的转变不仅限于 Cairo VM。除了上述改进之外,我们还计划用 Rust 从头开始重写sequencer。除了 Rust 的内部优势之外,这还为sequencer的其他优化提供了机会。举几个例子,可以采用 cairo-rs 的好处,而无需 python-rust 通信的开销,可以完全重新设计状态的存储和访问方式(今天是基于 Patricia-Trie 结构)。
Provers呢?
在整篇文章中,我们都没有提到有效性汇总中最重要的元素——prover。可以想象,作为可以说是架构中最复杂的组件,它应该是瓶颈,因此也是优化的重点。有趣的是,现在 StarkNet 的瓶颈是更“标准”的组件。今天,特别是对于递归证明,可以将比测试网/主网上的当前流量更多的交易放入证明中。事实上,今天,StarkNet 区块与 StarkEx 交易一起得到证明,后者有时会产生数十万 NFT 铸造。
Summary
并行化、Rust 等——为即将到来的 StarkNet 版本中改进的 TPS 做好准备。
参考
https://starkware.medium.com/starknet-performance-roadmap-bb7aae14c7de