Flashblocks深度解析:我们如何使Base速度提升10倍

本文介绍了Base链通过引入Flashblocks技术,将区块时间从2秒缩短到200毫秒,实现了亚秒级的交易预确认。文章详细阐述了Flashblocks的原理、sequencer架构的演变,以及交易在Base主网上的生命周期,并深入探讨了为确保系统可靠性和性能所做的优化措施,例如启用构建器故障转移、优化状态根计算等。

为了构建一个面向全球经济的开放网络,我们专注于通过亚美分、亚秒级的交易使 Base Chain 更快、更便宜。今年早些时候,我们在 Base 主网上推出了 Flashblocks,通过将有效区块时间从 2 秒减少到仅仅 200 毫秒,使得 Base 速度提升了 10 倍。

该功能于 7 月 16 日上线,结束了从测试网到主网为期四个月的开发之旅。我们公开构建,并希望分享更多关于 Flashblocks 的技术细节、我们在旅程中遇到的挑战以及我们学到的经验。如果你正在寻找关于将你的应用程序或基础设施提供商与 Flashblocks 集成的支持,我们建议你查看这篇博客文章常见问题解答页面

Flashblocks 入门

以前,Base 每 2 秒生成一个新区块。通过 Flashblocks(使用 Flashbots 构建),构建者在该 2 秒窗口内流式传输 200 毫秒的子区块,从而提供亚秒级预确认,使交易感觉即时。

post image

每个区块有 10 个 Flashblocks,其中每个 Flashblock (flashblock_i) 最多可以包含常规区块总 gas 预算的 i/10。一系列 Flashblocks 被组合起来以重新创建一个完整的区块。

现在我们已经介绍了 Flashblocks 是什么,让我们深入了解我们如何在 Base Chain 中实现它们。

排序器架构

作为 Flashblocks 发布的一部分,我们在排序器中添加了几个新的基础设施组件。为了更好地理解这些变化,我们分享了 Flashblocks 前后排序器架构的样子。

Flashblocks 之前的架构

在 Base,我们运营一个高可用性排序器系统,拥有五个排序器实例。

post image

每个排序器由以下基础设施组件组成:

  • Op-node: 标准的 op-stack 共识层 (CL) 软件

  • Op-geth: 标准的 op-stack 执行层 (EL) 软件

    • op-node 和 op-geth 通过 Engine APIs 进行区块构建通信。
  • Op-conductor: 高可用性控制组件,带有用于领导者选举的 raft 共识

一个排序器实例充当“领导者”,负责通过构建区块并通过 P2P 将其传播到其他节点来进行排序。其余四个排序器充当同步链的 follower Base 节点。如果当前领导者在指定阈值内停止区块生产,则会发生领导权转移。

带有 Flashblocks 的架构

通过 Flashblocks,我们在高可用性系统中的每个单独排序器中集成了几个新组件,以允许添加更多自定义区块构建功能。这些包括:

  • Rollup-boost (CL<>EL Engine API 代理)

    • 为什么 Flashblocks 需要它: 通过在 Engine API 调用上添加受控拦截点,无需修改 CL 即可与 EL 共享 Flashblocks。它将风险本地化,并允许我们进行协议外试验

    • 它解锁了什么: 用于未来区块构建演进(例如,多构建器)的稳定接口,无需重构 CL/EL

  • Op-rbuilder(协议外构建器,@ 200 毫秒 cadence)

    • 为什么 Flashblocks 需要它: 产生亚秒级 Flashblocks,与 EL 解耦

    • 它解锁了什么: 用于新区块构建机制的可插拔构建器表面(例如,MEV 感知策略、跨多个构建器的拍卖)

  • Websocket proxy (Flashblocks 流扇出)

    • 为什么 Flashblocks 需要它: 一个广播层,以便许多消费者可以读取 Flashblocks 流,而不会对构建器造成 DoS 攻击
  • Node-reth(公开预确认的 RPC 表面)

    • 为什么 Flashblocks 需要它: 将流式 Flashblocks 转换为熟悉的 RPC,以便应用程序和钱包可以在没有新 SDK 或协议更改的情况下使用预确认状态

post image

rollup-boost 和 op-rbuilder 最初由 Flashbots 构建并目前由其维护。而在 Base 方面,我们构建并维护 websocket proxy 和 node-reth,并且根据我们的需求对 rollup-boost 和 op-rbuilder 进行了特定更改。在下面的可靠性部分中会更详细地解释。

鉴于这些变化,现在提交到 Base 的交易如何进行?

Base 主网交易的生命周期

让我们追踪一下当用户向 mainnet-base.org 发送 eth_sendRawTransaction 时,交易的旅程。在 Flashblocks 前后,此流程相似,但区块构建算法有所修改。该请求经过以下阶段:

post image

  1. 该请求首先到达我们的 DNS 提供商,以解析 mainnet-base.org

  2. 从那里,它被路由到路由软件 Proxyd 的负载均衡器

  3. Proxyd 然后将请求路由到私有 mempool

  4. mempool 接收请求并将交易作为待处理交易插入其 txpool 中

  5. mempool 维护与 EL(op-geth、op-rbuilder)的 P2P 连接,确保所有待处理交易都在 EL 中同步以进行区块构建

  6. 在每个区块构建循环中,EL 从其 txpool 中选择交易

Flashblocks 区块构建

在 Flashblocks 上线后,我们使用 op-rbuilder 作为区块构建器。在 op-rbuilder 中,正如之前的博客文章中所解释的那样,以下因素决定何时选择交易

  1. 交易费用:对于每个 200 毫秒的区块构建循环,交易按其费用排序,与 op-geth 相同

  2. 交易 gas 限制和剩余 gas 可用量:对于每个 flashblock FB_j,最多可以使用 j/10 的总区块 gas 限制。因此,交易必须具有足够的费用,并且保持在该 flashblock 的可用 gas 范围内

捕获上述因素的 Flashblock 区块构建的伪代码如下

FUNCTION BuildFlashblocks(pending_transactions, total_block_gas_limit):
    flashblocks = []
    block_gas_used = 0

    FOR j FROM 0 TO MAX_FLASHBLOCKS_PER_BLOCK:
        NEXT_TIME = MONOTONIC_NOW() + 150ms // 下一个区块开始时间
        current_flashblock_gas_limit = (j / 10) * total_block_gas_limit

        // 按费用(降序)对未决交易进行排序
        sorted_transactions = SORT_BY_FEE_DESC(pending_transactions)
        // 根据可用的 gas 选择交易
        selected_transactions = TOP_TRANSACTIONS_WITHIN_GAS_LIMIT(sorted_transactions, current_flashblock_gas_limit, block_gas_used)

        // 执行交易
        executed_info, gas_used = EXECUTE_TX(selected_transactions)
        block_gas_used += gas_used
        // 通过计算区块哈希和状态根来构建 flashblock
        flashblock = BUILD_BLOCK(flashblock, executed_info)

 // 在构建下一个闪存块之前,等待剩余的时间
        WAIT_UNTIL(NEXT_TIME)
    END FOR

    RETURN flashblocks
END FUNCTION

有关 op-rbuilder 中的完整实现,请参见此处

Flashblocks RPC 节点 (Node-reth)

一旦交易被选择并挖掘,它将作为流式传输到 websocket proxy 的 flashblock 数据的一部分包含在内,RPC 节点会监听该数据。RPC 节点缓存 flashblock 数据。可以在此处找到数据流的确切定义,我们也在我们的文档页面中更彻底地解释了它。

post image

当调用 flashblocks 支持的 RPC 方法时,它会从缓存中检索数据并在可用时返回它。(例如,eth_getTransactionReceipt

可靠性和性能改进

在 Flashblocks 的开发过程中,我们进行了一些改进,以确保系统具有高可用性,并且可以始终以 200 毫秒的速度生成 Flashblocks。

启用构建器故障转移

随着 op-rbuilder 的集成,有必要将构建器健康状况纳入 op-conductor 的健康检查中。我们启用了 healthcheck to rollup-boost,它验证构建器是否在链的顶端保持同步。如果构建器滞后,op-conductor 将启动领导权转移。

这显着提高了 Flashblocks 的可用性,因为 Flashblocks 不会因不健康的构建器而经历长时间的中断。但是,缺点是如果所有构建器都关闭,op-conductor 将无法选出健康的领导者,从而导致链停止。然而,所有构建器同时关闭的可能性很小,使其成为一个合理的折衷方案。

优化状态根计算

在最初的设计中,为每个 flashblock 计算状态根。这是因为很难确定哪个 flashblock 最终将成为构建器需要返回给 op-node 的最终确定区块。没有状态根,op-node 无法将该区块提升为最终确定区块。

虽然这种方法对于 Base Sepolia 来说运行正常,但 Base Mainnet 上的高交易量使得每个状态根计算平均花费大约 130 毫秒。这使得总区块构建时间接近 200 毫秒,难以构建超过 9 个 flashblock,从而可能降低吞吐量。

为了解决这个问题,我们没有让构建器为每个 flashblock 计算状态根,而是修改了 rollup-boost 以从构建器获取交易,然后使用额外的 FCU 使用 op-geth 构建具有状态根的区块。(非常感谢 Flashbots 的 Ferran 提供的建议!)

post image

由于此更改,P50 Flashblock 构建时间从 150 毫秒大幅降至仅 10 毫秒,从而消除了此问题作为启动障碍。

post image

解决 Geth 和 Reth 之间交易池的差异

将我们的构建器从 op-geth(基于 Geth)迁移到 op-rbuilder(基于 Reth)意味着从使用 Geth 的交易池实现转移到 Reth 的交易池实现。

在启动后不久,我们观察到一些异常行为:Coinbase 零售 staking 团队的交易停止被包含,导致大量交易积压。

然后,我们深入研究了 Geth 和 Reth 交易池实现之间的差异,并确定了以下区别:

Geth

  • Pending: 没有 nonce 间隙的下一个 nonce 交易。

  • Queued: 具有 nonce 间隙的交易。

Reth

  • Pending: 费用高于基础费用的下一个 nonce 交易。

  • Queued:

    • Basefee subpool:低于基础费用的交易,即使它们是下一个 nonce。

    • 具有 nonce 间隙的交易。

因此,如果一个交易是下一个 nonce 交易,但费用低于基础费用,则它将保持 Geth 的 pending 状态,但会被 Reth 排队。一旦达到交易池生存期值,排队的交易将被删除,并且 Geth 不会重新广播这些交易,因为它始终假设 pending 交易已成功 P2P'd。

为了解决这个问题,我们构建了 Mempool-rebroadcaster。此工具检查 Geth 和 Reth txpool 之间的差异,并在它们之间重新广播交易。这确保了即使交易从 Reth 中删除,它仍然会被再次拾取。

降低重组率

在我们的初始实现中,构建器将 flashblock 直接发送到 websocket proxy。由于构建器不了解 op-node 分配的实际区块构建时间,这可能会导致尾部 flashblock 重组:尾部 flashblock 已流式传输出去,但未包含在实际区块中。

Flashbots 团队添加了一种新机制,即构建器不流式传输到 websocket proxy,而是流式传输到 rollup-boost,然后 rollup-boost 流式传输到 websocket proxy。它的工作方式如下

post image

  • Op-node 将 FCU 发送到 rollup-boost,rollup-boost 将 FCU 代理到 op-rbuilder 以启动区块构建

  • 在每个区块构建循环中,op-rbuilder 将 flashblock 流式传输到 rollup-boost,rollup-boost 将 flashblock 存储在一个名为 best_payload 的变量中

  • 在区块构建结束时,op-node 将 get_payload 发送到 rollup-boost,rollup-boost 返回 best_payload,并清除 best_payload

  • 如果 op-rbuilder 继续发送具有相同 payload_id 的 flashblock,则它将被拒绝

这大大提高了我们的重组率,将其从 0.2% 降低到有效为 0:

post image

未来的工作

RPC 改进

我们目前正在添加新的 Flashblocks 感知 RPC:eth_calleth_estimateGas。我们的实现涉及让节点复制最新的状态,在其之上回放 Flashblock 流,并针对该覆盖层执行请求。这使得模拟和 gas 估算反映预确认状态。该功能正在积极开发中,将在验证和测试后发布。

Websocket

Websocket 是交易者和托管自己的 RPC 节点的团队的低延迟主干。我们的目标是以高可用性和反压控制来运营公共 websocket。但是,值得注意的是,应用程序应尽量避免依赖 websocket,因为 RPC 提供稳定的 RPC 行为并在 Flashblocks 关闭时自动故障转移到常规区块。

其他区块构建更新

启用自定义构建器 (op-rbuilder) 作为 Flashblocks 发布的一部分,为更多的区块构建创新铺平了道路,有可能为 Base 用户释放更多的区块空间容量和效率,甚至为开发人员提供独特的功能。要了解任何计划的区块构建更改的最新信息,请关注我们的文档状态页面

参与进来

如果你有兴趣帮助我们构建一个能够提高创新、创造力和自由的全球经济,我们正在招聘,并期待收到你的来信。

在社交媒体上关注我们,以了解最新信息:XX 上的 Base 团队)| Farcaster | Discord

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

0 条评论

请先 登录 后评论
Base 中文
Base 中文
江湖只有他的大名,没有他的介绍。