
什么是 Firedancer?深入解析 Solana 2.0
目录
- 本文讲了什么?
- 什么是验证者?什么是验证者客户端多样性?
- Jump 为什么要构建新的验证者客户端?
- 为什么光速还是太慢?
- 什么是 Firedancer?
- Firedancer 如何运作?
- 模块化架构
- 网络处理
- 构建系统
- Firedancer 为什么这么快?
- 高级数据并行
- 利用 FPGA 实现高速网络通信
- 优化用于网络通信的 Reed-Solomon 编码
- Firedancer 如何保障安全?
- 机遇
- 挑战
- 实施纵深防御设计
- 实施内嵌式安全计划
- Firedancer 当前进展如何?Frankendancer 又是什么?
- 实际运行了哪些功能?
- 性能表现如何?
- Frankendancer 已在测试网上线
- 结论
- 其他资源 / 延伸阅读
- 附录
- 计算机硬件与网络简介
- 中央处理器(CPU)
- 图形处理器(GPU)
- 随机存取存储器(RAM)
- 磁盘存储
- 主板
- 入站与出站
- 流水线与数据并行
- 现场可编程门阵列(FPGA)
衷心感谢 Firedancer 团队审阅本文。
本文讲了什么?
Solana 是速度最快的区块链,但它还可以更快。当前的 Solana Labs 验证者客户端表现出色,但主要针对快速上市进行了优化。凭借事后总结的经验、从零开始的机会,以及数十年的高性能计算经验,Jump 致力于让 Solana 变得更快、更可靠。Jump 正在运用其高频交易经验开发 Firedancer。这是所有区块链中性能最强的验证者客户端。它计划使用 C 编程语言彻底重写 Solana 当前的验证者客户端。
本文将探讨验证者以及验证者客户端多样性的重要性。接着,我们会介绍 Jump 为何要构建新的验证者客户端,以及其高频交易经验为何让它成为开发 Firedancer 的理想团队。然后,我们将说明 Firedancer 是什么、如何运作、为什么速度快、如何保障安全,以及目前的开发状态。
读完本文后,你将全面了解 Jump 的新验证者客户端。你会熟悉其突破性的优化,以及这些优化如何让它成为所有区块链中性能最强的验证者客户端。你还会理解 Firedancer 对 Solana 网络性能和可靠性为何至关重要。要了解 Firedancer,读这一篇就够了。
附录包含一份完全可以跳过的计算机硬件与网络基础指南。添加这部分内容是为了向普通读者提供必要背景,帮助他们理解本文涉及的高级硬件和网络概念。尽管如此,正文仍会在必要处补充上下文。本文力求通俗易懂,让所有 Solana 用户都能理解 Firedancer 及其重要意义。
什么是验证者?什么是验证者客户端多样性?
验证者是参与权益证明区块链的计算机。验证者构成了 Solana 网络的骨干,负责处理交易并参与共识。验证者通过锁定一定数量的 Solana 原生代币作为质押,帮助保护网络安全。你可以把它看作一笔保证金,让验证者在经济利益上与网络绑定。这种经济关联会激励验证者准确、高效地完成任务,因为它们会因贡献而获得奖励。恶意或错误行为也会让验证者受到惩罚。验证者行为不当时,其质押会在称为罚没的过程中被削减。因此,为增加质押,验证者最明智的选择就是正确履行职责。
验证者客户端是验证者用于履行职责的应用程序。客户端是验证者的运行基础,使用其密码学上唯一的身份参与共识。
拥有多个彼此独立的客户端,可以在某个实现发生故障时提高容错能力。例如,如果没有任何客户端控制超过 33% 的质押,那么影响活性的崩溃或漏洞就不会导致网络瘫痪。同样,如果某个客户端存在导致无效状态转换的漏洞,只要使用该客户端的质押低于 33%,网络就能避免安全性故障。这是因为网络的大部分仍会保持有效状态,防止区块链发生分裂或分叉。因此,验证者客户端多样性可以增强网络韧性,因为一个客户端中的漏洞或弱点不会拖垮整个网络。
客户端多样性通过各客户端承载的质押比例和可用客户端总数来衡量。截至本文撰写时,Solana 网络上共有 1979 个验证者。这些验证者在主网上使用的两个客户端分别由 Solana Labs 和 Jito Labs 提供。Solana 于 2020 年 3 月上线时只有一个验证者客户端,由 Solana Labs 开发。2022 年 8 月,Jito Labs 发布了第二个验证者客户端。该客户端是 Solana Labs 代码的一个分叉,由 Jito 维护和部署。该客户端针对区块中的 MEV(最大可提取价值)提取进行了优化。由于 Solana 在没有内存池的情况下流式传输区块,Jito 的客户端创建了一个伪内存池。顺带一提,内存池是待处理且尚未确认的交易队列。伪内存池允许验证者搜索这些交易,以最佳方式将它们打包,并提交到 Jito 的区块引擎。
截至 2023 年 10 月,Solana Labs 客户端承载了 68.55% 的活跃质押,而 Jito 承载了 31.45%。与 Solana Foundation 上一份健康报告相比,使用 Jito 客户端的验证者数量增长了 16%。Jito 客户端使用量的增长表明,客户端多样性正朝着积极方向发展。
尽管这一增长令人振奋,但情况并不完美。必须强调的是,Jito 的客户端是 Solana Labs 客户端的分叉。这意味着 Jito 与原始验证者代码库共享许多组件,因此可能会受到同样影响 Labs 客户端的漏洞或攻击手段影响。在理想的未来,Solana 至少会有四个独立的验证者客户端。不同团队将使用不同的编程语言构建这些客户端。任何单一实现承载的质押都不会超过 33%,每个客户端各自承载约 ~25%。这种理想化配置将消除整个验证者技术栈中的单点故障。
要实现这样的未来,开发第二个独立验证者客户端至关重要,而 Jump 正致力于让它成为现实。
Jump 为什么要构建新的验证者客户端?
Solana 主网过去曾四次停止出块,每次都需要数百名验证者手动修复。这些中断引发了外界对 Solana 网络可靠性的担忧。Jump 认为协议本身没有问题,而停机源于影响共识的软件模块问题。因此,Jump 正在开发新的验证者客户端来解决这些问题。该客户端的总体目标是提高 Solana 网络的稳定性和效率。
开发独立的验证者客户端是一项艰巨任务。不过,这并不是 Jump 第一次构建可靠的全球网络。过去,证券交易(即股票买卖)由做市专家手动执行。随着电子交易平台出现,证券交易市场变得更加开放。这种开放性加剧了竞争、推动了自动化,并降低了投资者的交易时间和成本。做市专家之间由此展开了一场技术军备竞赛。
交易者为交易而生。要实现最佳交易体验,软件、硬件和网络解决方案都不能妥协。这些系统必须具备高机器智能、低实时延迟、高吞吐量、高适应性、高可扩展性、高可靠性和高度可追责性。
通用解决方案(即公司可以直接购买的软件)无法带来竞争优势。连续十次以第二名的速度向交易所发送正确订单,是一种代价高昂的亏钱方式。高频交易领域的激烈竞争推动了持续不断的开发周期,以构建顶尖的全球交易基础设施。
这个场景可能听起来很熟悉。成功交易系统的要求与成功区块链的要求十分相似。区块链需要成为高性能、容错且低延迟的网络。缓慢的区块链是一项失败的技术,无法满足现代企业应用的需求,只会阻碍创新、可扩展性和现实世界中的实用价值。Jump 拥有二十多年扩展全球网络和开发高性能系统的经验,是创建独立验证者客户端的理想团队。Jump Trading 首席科学官 Kevin Bowers 正在负责这一过程。
为什么光速还是太慢?
Kevin Bowers 曾详细阐述为什么光速仍然太慢。光速是一个有限常数,它自然限制了单个晶体管能够处理的计算数量。目前,比特通过在晶体管中移动的电子来表示。香农容量定理(即一条信道能够无差错传输的最大数据量)限制了通过晶体管传输的比特数量。受基础物理学和信息论限制,计算速度取决于电子穿过物质的速度,以及能够传输的数据量。当超级计算机被推向极限时,这些约束就会显现出来。因此,“计算机处理数字的能力与移动数字的能力之间存在巨大差距。”
以 Intel Core i9 13900K CPU 为例。它拥有 24 个 x86 核心,基础时钟频率为 2.2 GHz,最高睿频为 5.8 GHz。在最坏情况下,光需要在这颗 CPU 上移动总计 ~52.0 mm。该 CPU 的曼哈顿距离(即沿相互垂直的坐标轴测量两点间的距离)约为 ~73.6 mm。在 CPU 达到 5.8 GHz 的最高睿频时,光在空气中可以传播约 ~51.7 mm。这意味着在一个时钟周期内,信号几乎可以在 CPU 上的任意两点之间完成一次往返。
实际情况要糟糕得多。这些测量使用的是光在空气中的传播速度,而这些信号实际要穿过二氧化硅(SiO2)。在一个 5.8 GHz 时钟周期内,光在二氧化硅中只能传播约 ~26.2 mm。在硅(Si)中,光在一个 5.8 GHz 时钟周期内只能传播约 ~15.0 mm,略多于 CPU 长边的一半。
Firedancer 团队认为,近年来计算技术的进步主要在于将更多核心装入 CPU,而不是让核心变得更快。当人们需要更高性能时,通常会被建议购买更多硬件。当吞吐量是瓶颈时,这种方法暂时有效。但真正的瓶颈是光速。这种自然限制会导致决策陷入停滞。由于系统包含许多组件,而且没有哪个组件得到了充分优化,因此单项优化不会立即产生回报。未得到优化的部分会随着时间推移变得更糟,因为它们可用的计算资源会越来越少。那么,现在该怎么办?
在高性能计算领域,最终一切都必须得到优化。最终目标是为生产交易和量化研究构建系统,让它们在全球范围内以物理学和信息论所允许的极限运行。这包括创建定制网络交换技术,以及针对这些物理限制设计无锁算法。Jump 既是一家交易公司,也是一家科技公司。Jump 和 Solana 当前面临的问题惊人地相似。在科幻与现实交汇的技术前沿,Jump 正在开发 Firedancer。
什么是 Firedancer?
Firedancer 是由 Firedancer 团队使用 C 编程语言开发的一款全新、完全独立的验证者客户端。凭借模块化架构、极少的依赖项和广泛的测试流程,Firedancer 从设计之初就将可靠性放在首位。它计划对 Solana Labs 客户端的三个功能组件进行大规模重写:网络、运行时和共识。每一层都针对最高性能进行了优化,因此客户端的运行能力只会受到验证者硬件的限制。这与验证者目前因软件效率不足而面临的性能限制不同。借助 Firedancer,Solana 将能够随带宽和硬件扩展。
Firedancer 的目标是:
- 记录并标准化 Solana 协议(最终,人们应该只需阅读文档,无需查看 Rust 验证者代码,就能创建 Solana 验证者)
- 提高验证者客户端多样性
- 改善生态系统性能
Firedancer 如何运作?
模块化架构
Firedancer 凭借独特的模块化架构,与当前的 Solana 验证者客户端形成鲜明区别。Solana Labs 的 Rust 验证者客户端以单一进程运行,而 Firedancer 则由许多称为 tile 的独立 Linux C 进程组成。一个 tile 就是一个进程加上一些内存。这种 tile 架构是 Firedancer 运行理念,以及实现稳健性和效率的方法基础。
进程是运行中程序的一个实例。它是现代操作系统的基本组成部分,代表一组指令的执行。每个进程都有自己的内存空间和由操作系统分配的资源,并且独立于其他进程运行。进程就像大型工厂中的独立工人,使用自己的工具和工作空间处理特定任务。
在 Firedancer 中,每个 tile 都是一个职责明确的独立进程。例如,QUIC tile 负责处理传入的 QUIC 流量,并将封装后的交易转发到 verify tile。verify tile 负责签名验证,其他 tile 也各自承担相应职责。这些 tile 独立且并发运行,共同实现系统的整体功能。独立的 Linux 进程可以形成规模较小、相互隔离的故障域。这意味着一个 tile 中的问题对整个系统的影响极小,也就是“爆炸半径”很小。这种方法不同于 Solana Labs 的 Rust 客户端,因为单点故障不会立即危及整个验证者。
Firedancer 架构的一项关键优势,是能够在几秒内替换和升级任意 tile,并且不会产生任何停机时间。这与 Solana Labs 的 Rust 客户端形成鲜明对比,后者在升级前必须完全关闭。造成这种差异的原因是 Rust 缺乏 ABI(应用程序二进制接口)稳定性,因此无法在纯 Rust 环境中即时升级。C 进程受益于 C 运行时模型的二进制稳定性,可以显著减少升级造成的停机时间。之所以能够做到这一点,是因为 tile 在不同工作区中管理验证者状态。只要验证者保持通电,这些共享内存对象就会持续存在。每个 tile 在重启或升级时,都可以从上次中断的位置无缝恢复处理。
总体而言,Firedancer 采用可感知 NUMA、基于 tile 的架构构建。我们将在下一节解释这意味着什么。现在你只需知道,它会为每个线程提供专用硬件资源。在这种架构中,每个 tile 使用 1 个 CPU 核心。它在 tile 之间提供高性能消息传递,并针对内存局部性、资源布局和组件延迟进行了优化。
网络处理
随着 Solana 网络扩展到每秒千兆位的速度,Firedancer 的网络处理能力旨在应对其高强度需求。该过程分为传入和传出活动。
传入活动主要围绕接收用户交易展开。Firedancer 的性能至关重要,因为如果验证者在数据包处理上落后,共识消息就可能丢失。目前 Solana 节点的运行带宽约为 ~0.2 Gbps,而 Jump 节点记录到的最大峰值约为 ~40 GBps。这一带宽峰值表明,网络需要稳健且可扩展的入口处理解决方案。
传出活动包括区块打包、区块创建和发送分片。其中每一步对于 Solana 网络安全、高效地运行都至关重要。这些任务的性能不仅会影响吞吐量,也会影响网络的整体可靠性。
Firedancer 旨在解决 Solana 点对点交易处理接口过去存在的弱点。Solana 点对点接口过去的一项主要缺陷,是缺少针对传入交易的拥塞控制。这一缺陷曾导致 2021 年 9 月 14 日(17 小时)和 2022 年 4 月 30 日(7 小时)的重大网络中断。
为此,Solana 实施了多项网络升级,以正确处理高交易负载。Firedancer 也采用 QUIC 进行流量控制。QUIC 是一种多路复用传输网络协议,也是 HTTP/3 的基础。它在 DDoS 防护和网络流量管理方面发挥着重要作用。不过必须注意,在某些情况下,其成本可能高于收益。QUIC 与数据中心用于缓解 DDoS 攻击的专用硬件结合使用,可以消除交易洪泛攻击背后的动机。
QUIC 长达 151 页的规范给开发工作带来了相当大的复杂性。由于找不到满足其许可、性能和可靠性要求的现有 C 库,Firedancer 团队构建了自己的实现。Firedancer 的 QUIC 实现昵称为 fd_quic,引入了优化的数据结构和算法,以最大限度减少内存分配并防止内存耗尽。
Firedancer 的自定义网络栈是其处理能力的核心。该网络栈完全从零设计,旨在利用接收端扩展(RSS)。RSS 是一种硬件加速的网络负载均衡形式,通过将网络流量分配到不同 CPU 核心来提高网络处理的并行度。每个 CPU 核心都能以极低开销处理一部分传入流量。这种方法无需复杂的调度器、锁和原子操作,因此性能优于传统的纯软件负载均衡。
Firedancer 引入了一个新的消息传递框架,用于组合由高性能 tile 构成的应用程序。这些 tile 可以利用 AF_XDP 绕过受套接字机制限制的内核网络。AF_XDP 是一个针对高性能数据包处理进行优化的地址族。使用 AF_XDP 后,Firedancer 可以直接从网络接口缓冲区读取数据。
这套 tile 系统在 Firedancer 技术栈中实现了多种高性能计算概念,包括:
- NUMA 感知 - NUMA(非统一内存访问)是一种计算机内存设计,其中处理器访问自身内存的速度快于访问其他处理器关联的内存。对 Firedancer 而言,具备 NUMA 感知能力意味着客户端可以高效处理多处理器配置中的内存。这对大规模交易处理非常重要,因为它能优化可用硬件资源的利用率。
- 缓存局部性 - 缓存局部性是指使用已存在于处理器附近缓存中的数据。这通常是时间局部性(即最近访问过的数据)的一种复杂形式。在 Firedancer 中,重视缓存局部性意味着它在处理网络数据时能够最大限度降低延迟并提高速度。
- 无锁并发 - 无锁并发是指设计无需锁机制(例如互斥锁)即可管理并发操作的算法。对 Firedancer 而言,无锁并发允许多个网络操作并行执行,而不会因锁产生延迟。无锁并发增强了 Firedancer 同时处理大量交易的能力。
- 大页面尺寸 - 在内存管理中使用大页面尺寸,可以通过减少页表查询和潜在的内存碎片来帮助处理数据集。对 Firedancer 而言,这意味着更高的内存处理效率,有助于处理大量网络数据。
构建系统
Firedancer 的构建系统遵循一套指导原则,以确保可靠性和一致性。它强调尽可能减少外部依赖,并将构建流程中涉及的所有工具也视为依赖项。这包括将编译器在内的每个依赖项固定到确切版本。该系统的一个关键方面,是在构建步骤中实现环境隔离。由于构建流程不受系统环境影响,环境隔离增强了可移植性。
Firedancer 为什么这么快?
高级数据并行
Firedancer 在 ED25519 签名验证等密码学任务中,使用现代处理器提供的高级数据并行能力。现代 CPU 支持单指令多数据(SIMD)指令,可同时处理多个数据元素,并针对每个 CPU 周期执行多条指令进行了优化。让单条指令并行处理数据元素的数组或向量,通常在面积、时间和功耗方面更高效。从这个角度看,相较于单纯提升处理速度,改进并行数据处理可以为吞吐量带来更显著的提升。
Firedancer 使用数据并行的一个领域是优化签名验证计算。这种方法可以同时处理数据元素的数组或向量,从而最大限度提高吞吐量并降低延迟。这一 ED25519 实现的核心是伽罗瓦域算术。这种算术非常适合密码学算法和二进制计算。在伽罗瓦域中,加、减、乘、除等运算的定义方式与计算机系统的二进制特性一致。下面是一个由 23 定义的伽罗瓦域示例:
唯一的问题是,ED25519 使用的是由 2255-19 定义的伽罗瓦域。可以把域元素视为从 0 到 2255-19 的数字。基本运算如下:
- x + y → 小学加法 mod 2255-19
- x - y → 小学减法 mod 2255-19
- x * y → 小学乘法 mod 2255-19
- 1/x → x 的 2255-21 次方 mod 2255-19
加法、减法和乘法几乎都属于 uint256_t 数学运算(即无符号整数运算,其中最大值为 2256-1)。除法则很难计算。通用 CPU 和 GPU 不支持 uint256_t 数学运算,更不用说“近似 uint256_t 数学运算”,以及极其困难的特殊除法。要实现这种数学运算并获得极高性能,关键在于我们能多好地模拟它。
Firedancer 的实现通过更灵活地看待数字来拆解算术运算。如果应用小学长除法和长乘法的原理,在列与列之间进位,就可以并行处理这些列。模拟这种数学运算的最快方式,是将 uint256_t 表示为六个 43 位数字,并保留 9 位用于“进位”。这样既能使用 CPU 现有的 64 位运算,又能为进位位提供足够空间。这种数字排列方式减少了频繁传播进位的需要,让 Firedancer 能更高效地处理大数。
该实现将算术计算重组为并行化的列求和,以利用数据并行。并行处理各列把原本的顺序瓶颈转化为可并行任务,从而加速整体计算。Firedancer 还使用 AVX512 及其 IFMA 扩展(AVX512-IFMA)等向量化指令集。这些指令集可以处理上文介绍的伽罗瓦域算术,从而提升速度和效率。
Firedancer 由 AVX512 加速的实现非常快。在单个 2.3 GHz Icelake 服务器核心上,其每核心时钟周期的性能超过 2022 年 Breakpoint 演示的两倍。该实现实现了 100% 的向量通道利用率和大规模数据并行化。这是 Firedancer 团队又一次出色的证明:受光速延迟影响,并行处理彼此独立的任务,要比逐个处理任务容易得多,即使为后者配备定制硬件也是如此。
利用 FPGA 实现高速网络通信
每个 CPU 核心每秒可处理约 ~30,000 次签名验证。虽然 CPU 节能高效,但无法满足大规模操作的需求。这一限制源于其顺序处理方式。每个 GPU 核心可将处理能力提升至每秒约 ~100 万次验证。不过,GPU 单块功耗高达约 ~300W,并且批处理会带来固有延迟。
FPGA 是更出色的替代方案。它们的吞吐量与 GPU 相当,但功耗显著降低,每块 FPGA 约为 50W。其延迟也低于 GPU 的十毫秒。FPGA 的延迟约为 ~200 微秒,为实时处理提供了响应快得多的解决方案。与 GPU 的批处理不同,Firedancer 中的 FPGA 以流式方式逐笔处理交易。Firedancer 使用 FPGA 后,在 8 块 FPGA 的总功耗低于 400 W 时,实现了每秒 800 万次签名验证的惊人吞吐量。
团队在 Breakpoint 2022 上展示了 Firedancer 的 ED25519 签名验证流程。该流程包含多个阶段,包括在纯 RTL 流水线中计算 SHA-512,以及在定制 ECC-CPU 处理器流水线中执行各种检查和计算。简单来说,Firedancer 团队为其定制处理器编写了编译器和汇编器,从 RFC(征求意见稿)中提取 Python 代码,通过运算符重载对象运行代码以生成机器码,然后将机器码放到 ECC-CPU 上运行。
需要注意的是,Firedancer 采用 AWS 加速器外形规格,以平衡稳健性和网络连接能力。这一选择解决了直接网络连接带来的挑战,因为云服务提供商通常会限制此功能。借助这一选择,Firedancer 可在云基础设施的约束下,无缝集成其高级能力。
必须认识到,不同操作需要实际的物理空间,而不只是概念上的数据空间。Firedancer 根据这一点,对物理组件进行策略性排列,让它们彼此靠近并可重复使用。借助这种配置,Firedancer 最大限度提高了 FPGA 的效率,在一台已有 8 年历史的机器上,使用已有 7 年历史的 FPGA 实现了 800 万 TPS。
优化用于网络通信的 Reed-Solomon 编码
网络通信面临的根本挑战,是向全球广播新交易。互联网的点对点特性、有限的带宽和延迟问题,限制了通过网络直接广播等传统方案的实现。以环形或树形结构分发数据可以部分解决这些问题,但由于数据包可能在传输过程中丢失,仍然不够完善。
Reed-Solomon 编码为这些问题提供了一种巧妙的解决方案。它在数据传输中引入冗余(即奇偶校验信息),以恢复丢失的数据包。其概念基于“两点确定一条直线”的原理,直线上的任意两点都可以还原原始数据点。根据数据点构建多项式,并将该函数的不同点放入不同数据包中分发。只要接收方至少收到两个数据包,就能重建原始数据。
之所以构建多项式,是因为使用传统的直线点公式(y = mx + b)计算速度很慢。Firedancer 使用拉格朗日多项式这一专门的多项式构建方法来加速处理。它简化了 Reed-Solomon 编码所需多项式的创建过程,还能将这一过程转换为更高效的矩阵-向量乘积,并适用于高阶多项式。该矩阵高度结构化,其模式会递归重复,因此第一行就能完全确定整个模式。这种结构意味着可以用更快的方式完成所有乘法。Firedancer 使用一篇 2016 年文章提出的 O(n log n) 方法与该矩阵相乘,这是目前已知用于 Reed-Solomon 编码、理论上最快的方法。与传统方法相比,它可以高效计算奇偶校验信息:
- RS 编码超过 ~120 Gbps/核心
- RS 解码最高可达 ~50 Gbps/核心
- 这些指标均与当前约 ~8 Gbps/核心的 RS 编码(rust-rse)相比
借助这种优化的 Reed-Solomon 编码方法,Firedancer 计算奇偶校验信息的速度比传统方法快 14 倍。由此实现快速可靠的数据编码和解码流程,而这对在全球范围内保持高吞吐量和低延迟至关重要。
Firedancer 如何保障安全?
机遇
目前所有验证者都使用基于原始验证者客户端的软件。如果 Firedancer 与 Solana Labs 客户端保持独立,就能提高 Solana 的客户端和供应链多样性。这包括使用相似的依赖项,以及使用 Rust 开发客户端。
Solana Labs 和 Jito 验证者客户端都以单一进程运行。单体应用投入生产后,很难再为其添加安全机制。运行这些客户端的验证者若要在纯 Rust 中进行即时安全升级,就必须停机。Firedancer 团队则可以从一开始就在新客户端中构建安全架构。
Firedancer 还能从既有经验中学习。Solana Labs 在创业环境中开发了验证者客户端。快节奏的环境意味着 Labs 必须迅速行动,尽快将产品推向市场。这为后续开发埋下了隐患。Firedancer 团队可以审视 Labs 和其他链上团队的做法,并思考:如果能从零开始开发验证者客户端,他们会做出哪些不同选择。
挑战
尽管 Firedancer 与 Solana Labs 客户端相互独立,但仍必须精确复现其行为。否则会带来安全隐患,因为不兼容可能引发共识 bug。可以通过激励一定比例的质押同时运行两个客户端来缓解这一风险,并在较长时间内将 Firedancer 的占比控制在总质押量的 33% 以下。无论如何,Firedancer 团队都需要实现协议的完整功能集,不论正确或安全地实现这些功能有多困难。一切都必须与 Firedancer 保持一致。因此,团队不能孤立地开发代码,而必须对照 Labs 客户端的功能进行审查。缺少规范和文档进一步加剧了这一问题,这意味着 Firedancer 不得不引入协议中的低效结构。
Firedaner 团队还必须注意,他们正在使用 C 开发新客户端。C 不具备 Rust 等语言原生提供的内存安全保障。Firedancer 代码库的主要目标之一,是减少内存安全漏洞的出现频率及其影响。由于 Firedancer 是一个快速推进的项目,这一目标需要得到特别关注。Firedancer 必须找到一种既能保持开发速度,又不会引入此类 bug 的方法。OS 沙箱是将 tile 与 OS 隔离的做法。tile 只能访问完成工作所需的资源,并执行必要的系统调用。由于每个 tile 都有明确的用途,而且大部分客户端代码由 Firedancer 团队开发,因此会按照最小权限原则尽可能缩减 tile 的权限。
实施纵深防御设计
所有软件迟早都会出现安全漏洞。Firedancer 从软件必然存在 bug 这一前提出发,选择限制任何单一漏洞可能造成的影响。这种方法称为纵深防御。纵深防御是一种使用多种安全措施保护资产的策略。如果攻击者攻破系统的一部分,仍有其他措施可以阻止威胁影响整个技术栈。Firedancer 的设计旨在降低从漏洞到利用阶段之间的风险。例如,攻击者很难利用内存安全漏洞。
这是因为,防范此类攻击已经是一个得到深入研究的问题。C 的内存安全经过了广泛研究,因此形成了一系列加固技术和编译器功能,团队将它们用于 Firedancer。即使攻击者能够绕过行业最佳实践,也很难通过漏洞利用攻破系统。这得益于 tile 隔离和 OS 沙箱。
tile 隔离源于 Firedancer 的并行架构。由于每个 tile 都运行自己的 Linux 进程,因此都有明确且单一的用途。例如,QUIC tile 负责处理传入的 QUIC 流量,并将封装的交易转发到 verify tile。随后,verify tile 负责签名验证。QUIC tile 与 verify tile 通过共享内存接口进行通信(即 Linux 进程可以相互传递数据)。两个 tile 之间的共享内存接口充当隔离边界。如果 QUIC tile 存在 bug,导致攻击者可在其处理恶意 QUIC 数据包时执行任意代码,也不会影响其他 tile。在单体进程中,这会立即导致系统失陷。如果攻击者在多个验证者上利用该漏洞,可能会损害整个网络。攻击者或许能降低 QUIC tile 的性能,但 Firedancer 的设计将其影响范围限制在 QUIC tile 内。
OS 沙箱是将 tile 与 OS 隔离的做法。tile 只能访问完成工作所需的资源,并执行必要的系统调用。由于每个 tile 都有明确的用途,而且几乎所有代码都由 Firedancer 团队开发,因此会按照最小权限原则尽可能缩减 tile 的权限。每个 tile 都被放置在各自的 Linux 命名空间中,只能看到有限的系统视图。这种受限视图可防止 tile 访问文件系统的大部分内容、网络以及同一系统上运行的任何其他进程。命名空间提供了安全优先的边界。不过,如果攻击者掌握用于权限提升的内核漏洞利用,仍可能绕过这一边界。系统调用接口是内核中 tile 能够触达的最后一个攻击向量。为防范此风险,Firedancer 使用 seccomp-BPF,在内核处理系统调用前对其进行过滤。客户端可以将 tile 限制为只能使用一组选定的系统调用。在某些情况下,还可以过滤系统调用的参数。这一点很重要,因为 Firedancer 可以确保读写系统调用仅操作特定文件描述符。
实施内嵌式安全计划
Firedancer 在设计时将全面的安全计划融入开发的每个阶段。该客户端的安全计划由开发团队和安全团队持续协作推进,为安全的区块链技术树立了新标准。
这一流程从自助式模糊测试基础设施开始。顺带说明,模糊测试是一种自动检测崩溃或错误状况的技术,这些情况可能表明存在漏洞。具体做法是对所有接受不可信用户输入的组件进行压力测试,包括 P2P 接口(解析器)和 SBPF 虚拟机。OSS-Fuzz 在代码变更过程中持续保持模糊测试覆盖。安全团队还设置了专用的 ClusterFuzzer 实例,用于持续执行覆盖率引导的模糊测试。开发人员和安全工程师还会提供模糊测试工具(即针对安全关键组件的特殊单元测试版本)。开发人员也可以提交新的模糊测试,系统会自动获取并执行这些测试。目标是在所有部分进入下一阶段之前,对其进行充分的模糊测试。
内部代码审查有助于发现工具遗漏的 bug。此阶段重点关注高风险、高影响的组件,并作为反馈机制反哺安全计划的其他环节。团队会运用所有经验,通过这些审查提高模糊测试覆盖率、针对特定 bug 类别引入新的静态分析检查,甚至进行大规模代码重构,从设计层面消除复杂的攻击向量。行业领先专家开展的外部安全审查和活跃的 bug 赏金计划,将在发布前后补充这些内部审查。
Firedancer 还在多个测试网络上接受了广泛的压力测试。这些测试网络将遭遇节点复制、网络链路故障、数据包洪泛和共识违规等攻击与故障。它们承受的负载远高于主网上任何现实场景。
于是,问题来了:Firedancer 目前处于什么状态?
Firedancer 当前进展如何?Frankendancer 又是什么?
Firedancer 团队正在以渐进方式开发 Firedancer,推动验证者客户端模块化。这与其文档化和标准化目标一致。该方法可确保 Firedancer 跟上 Solana 的最新发展,并促成了 Frankendancer 的诞生。Frankendancer 是一种混合客户端模型,Firedancer 团队将其已开发的组件集成到现有验证者客户端基础设施中。这一开发流程支持逐步改进和测试新功能。
Frankendancer 就像把一辆跑车开进车流。随着更多组件完成开发、瓶颈被消除,其性能将不断提高。这种模块化开发流程打造了可定制、灵活的验证者环境。开发人员可以修改或替换验证者客户端中的特定组件,以满足自身需求。
实际运行了哪些功能?
Frankendancer 实现了 Solana 验证者的全部网络功能:
- 入站:QUIC、TPU、Sigverify、Dedup
- 出站:区块打包,创建/签名/发送 shred(Turbine)
Frankendancer 在 Solana Labs 的 Rust 运行时和共识代码之上,使用 Firedancer 的高性能 C 网络代码。
Frankendancer 的架构着眼于高端硬件优化。它既支持运行标准 Linux 操作系统的低端普通云主机,Firedancer 团队也在针对高核心数服务器优化 Frankendancer。长期目标是利用云端已有的硬件来提高效率和性能。该客户端支持同时建立多个连接、硬件加速、用于分配负载的随机流量导向(即确保网络流量均匀分布),以及大量进程边界,从而增强组件之间的安全性。
技术效率是 Frankendancer 的基石。系统避免在关键路径中进行内存分配和原子操作,所有分配都在初始化时完成 NUMA 优化。这一设计可确保最高效率和性能。此外,系统能够以异步方式远程检查组件,并可灵活管理 tile(异步启动、停止和重启),从而进一步增强稳健性和适应能力。
性能表现如何?
在网络入站侧,Frankendancer 的每个 tile 每秒可处理 1,000,000 笔交易(TPS)。由于每个 tile 使用 1 个 CPU 核心,其性能会随所用核心数线性扩展。Frankendancer 仅使用四个核心就实现了这一成绩,并跑满了一块 25 Gbps 网卡(NIC)。
通过 Turbine 优化,Frankendancer 显著改善了网络出站操作。目前的标准节点硬件可实现每个 tile 6 Gbps 的速度。其中包括 shredding 速度的大幅提升(即如何拆分区块数据并通过网络发送给验证者)。与当前的标准 Solana 节点相比,Frankendancer 在不使用 Merkle 树时,shredding 速度提高约 ~22%;使用 Merkle 树时,速度则接近翻倍。这显著改善了当前验证者的区块传播和交易摄取性能。
Firedancer 的网络性能表明,它已经达到硬件极限。它实现了当前标准验证者硬件所能达到的最高性能。这是一个重要的技术里程碑,证明该客户端能够高效、有效地处理极端工作负载。
Frankendancer 已在测试网上线
Frankendancer 目前已在测试网上完成质押、投票和区块生产,并与其他约 ~2900 个 Solana Labs 和 Jito 验证者兼容共存。这一实时部署证明了 Firedancer 在通用硬件上的强劲性能。它目前运行在一台 Equinix Metal m3.large.x86 服务器上,由 AMD EPYC 7513 CPU 提供算力。许多其他验证者也使用相同类型的服务器。它提供了一种经济实惠的解决方案,按需价格因地点而异,每小时费用介于 $3.10 到 $4.65。
随着 Firedancer 不断迈向主网上线,节点硬件也迎来了多种可能性:
- 当前的验证者硬件可让每个节点获得高得多的性能容量
- Firedancer 的高效率让验证者能够使用更便宜、规格更低的硬件,同时维持相近的性能水平
- Firedancer 的设计使其能够充分利用硬件和带宽的进步
这些进展,加上 Wiredancer(即 Firedancer 团队的硬件加速实验)和基于 Rust 的模块化 Runtime/SVM 等其他计划,使 Firedancer 成为面向未来的解决方案。
Firedancer 的进展还引发了关于验证者能否在 Firedancer 旁同时运行 Solana Labs 客户端的讨论,这一过程称为 side-caring。该方法可以利用两个客户端各自的优势,并降低任一客户端的问题对整体网络造成的潜在影响,从而最大限度提高网络活性。此外,这也引发了人们对 Jito 等项目是否会考虑 fork Firedancer 的猜测。这可能进一步优化 MEV 提取和交易处理效率。只有时间能给出答案。
结论
开发者通常认为操作占用的是数据空间,而非物理空间。在光速这一自然限制下,这种假设会导致系统运行缓慢,无法正确优化硬件。在高度对抗且竞争激烈的环境中,我们不能再一味给 Solana 堆砌更多硬件,并期待它表现得更好。我们需要进行优化。Firedancer 彻底改变了验证者客户端的架构与运行方式。通过构建可靠、高度模块化且高性能的验证者客户端,Firedancer 团队正在为 Solana 的大规模普及做好准备。
无论你是初级开发者,还是普通的 Solana 用户,了解 Firedancer 及其重要性都至关重要。这项技术成就让目前市场上速度最快、性能最强的区块链更进一步。Solana 旨在成为一个高吞吐量、低延迟的全球状态机。Firedancer 朝着全面实现这些目标迈出了一大步。
如果你读到了这里,感谢你,匿名朋友!请务必在下方填写电子邮件地址,这样就不会错过 Solana 的任何最新动态。准备好深入探索了吗?立即加入我们的 Discord,在性能最强的区块链上开始构建未来。
其他资源 / 延伸阅读
附录
计算机硬件与网络简介
计算机是一种能够通过编程自动执行一系列算术或逻辑操作的机器。这些操作涵盖从基本计算自动化到复杂数据处理的各种任务。计算机的核心是结合硬件和软件组件,以执行指令并管理数据。硬件由物理组件构成,软件则包括指导硬件如何运行的程序和操作系统。
有效计算通常涉及四类资源:计算、内存、磁盘存储和网络。计算主要由 CPU、GPU 以及可能的 FPGA 负责,速度极快,每秒可执行数十亿次操作。访问 RAM 通常比在 CPU 中执行计算更慢。磁盘存储提供可用于计算的长期存储方案。然而,从固态硬盘(SSD)和机械硬盘(HDD)访问数据的速度远慢于 CPU 操作。SSD 通常要慢数千倍,而 HDD 则慢数万倍。此外,包括互联网和本地网络在内的网络速度最慢,甚至可能比 CPU 慢一百万倍以上。
理解这些速度差异,对于掌握 Firedancer 等高性能计算应用的设计原则和效率考量至关重要。CPU 的计算速度构成基准,而内存、磁盘存储和网络访问会按速度递减的顺序逐层增加延迟。
中央处理器(CPU)
CPU,即中央处理器,是计算机实现功能的基石,也是机器的大脑。CPU 执行软件指令、完成计算,并根据接收到的输入做出决策。它通过处理由 0 和 1 组成的二进制信号来工作。每个独特的二进制代码序列都对应一条特定指令,由 CPU 解释并执行。这些指令按顺序处理,CPU 完成一个操作后才会继续下一个操作。这种顺序处理指令的方式是 CPU 发挥作用的基础,决定了它如何执行复杂计算并根据接收到的输入做出决策。
现代 CPU 通常采用多核设计。这意味着单个芯片内包含多个称为核心的处理单元。每个核心都可以独立执行指令,从而实现任务的并行处理。多核架构增强了 CPU 同时处理多个操作的能力,显著提升了整体性能。不过,需要注意的是,每个核心内部仍然按顺序处理操作。因此,CPU 非常适合复杂的顺序任务,但在处理大量较简单的并行任务时效率不高。
CPU 还配有缓存,即 CPU 内部小型的高速内存单元。这些缓存存储经常访问的数据和指令,与从 RAM 获取数据相比,检索速度更快。缓存通常分为多个层级(L1、L2、L3,有时还有 L4),每一级的容量和速度各不相同。L1 缓存容量最小、速度最快,因此会被优先访问。如果其中没有所需数据,CPU 会检查容量更大、速度略慢的 L2 缓存,以此类推。这种分层缓存系统减少了 CPU 等待 RAM 数据的时间,并提升了整体处理速度。高效利用缓存对 Firedancer 等应用意义重大,因为 CPU 与 RAM 之间的距离可能会影响性能。这一点与我们关于光速和使用 FPGA 的讨论尤其相关。
顺带一提,“x86” 是指遵循特定架构的一系列 CPU,该架构最初由 Intel 开发。这种架构以广泛的软件兼容性著称,因为市面上销售的大多数台式机和笔记本电脑都基于 x86 架构系列。
图形处理器(GPU)
GPU 是一种专用处理器,最初用于加速计算机图形中的图像和视频渲染。其主要功能是管理并提升图形性能,尤其适用于视频游戏或 3D 建模等需要高分辨率视觉效果和复杂图形计算的任务。
随着时间推移,GPU 的用途已经超越最初的设计目标。得益于其架构,GPU 在更广泛的数据处理任务中发挥着重要作用。它具备高效并行处理能力,因此非常适合需要同时处理大型数据集的应用。在区块链技术中,GPU 广泛用于加密货币挖矿。GPU 能够比 CPU 更高效地处理并行的密码学计算工作负载,因此在这一领域表现出色。
随机存取存储器(RAM)
RAM 是计算机的短期存储器,用于存储当前正在使用或处理的数据。CPU 会在这里“记住”当前正在处理的内容,并保留相关信息,以便快速访问和处理。
纠错码(ECC)RAM 能够检测并纠正常见的内部数据损坏。这项功能在重视数据准确性的环境中至关重要,例如科学计算、金融交易或区块链节点。ECC RAM 可以自动识别并修复所存储数据中的轻微错误。该纠错过程由 RAM 模块中的额外硬件执行,这些硬件会检查所存储的数据。
非 ECC RAM 是标准计算机和消费设备中更常见的内存类型。虽然它不具备 ECC RAM 的纠错能力,但通常速度更快、价格更低。由于成本效益高,而且标准桌面计算中发生数据错误的风险相对较低,因此非 ECC RAM 更适合一般用途。
磁盘存储
磁盘存储负责长期保留数据,即使计算机关闭也不会丢失。磁盘存储主要有两种类型:机械硬盘(HDD)和固态硬盘(SSD)。
HDD 是较早出现的磁盘驱动器,将数据存储在称为盘片的磁性圆盘上。盘片与磁头配合使用,磁头通常安装在可移动的执行器臂上。磁盘旋转时,执行器臂上的读写磁头会访问数据。HDD 的机械结构,包括旋转磁盘和移动磁头,使其速度比 SSD 慢。不过,HDD 能以更低的价格提供更大的存储容量,因此是大容量存储的高性价比选择。
另一方面,SSD 使用闪存存储数据。闪存是一种可擦除、可重新编程的电子式非易失性存储方案。使用闪存意味着 SSD 与 HDD 不同,不包含任何移动部件,而是由互连的闪存芯片存储数据。SSD 比 HDD 更快,因为它可以立即访问数据,无需等待磁盘旋转或读写磁头定位数据。这种速度使 SSD 非常适合需要快速检索数据的应用。不过,与 HDD 相比,这种速度也意味着每 GB 的成本更高。
此外,还有 NVMe(非易失性内存主机控制器接口) SSD。这类 SSD 旨在通过计算机的高速外设组件互连(PCIe)总线充分发挥其高速潜力。与传统 SSD 相比,NVMe 硬盘速度显著更快、延迟更低。它们非常适合高频交易和区块链应用等密集型工作负载,因为这些场景对快速数据处理和检索至关重要。虽然 NVMe 价格更高,但正逐渐成为高性能计算的标准配置。
主板
来源:Reddit 的 r/buildapc 帖子中的 Gigabyte X570 Elite 示意图
计算机主板是一块大型电路板,用于连接计算机的各个部件并支持它们相互通信。这些部件包括 CPU、GPU、RAM、存储设备,以及键盘和鼠标等外围设备。
主板是所有活动的中心枢纽。它确保每个组件都能彼此有效通信。主板在配电方面也至关重要,负责将电源提供的电力输送到各个主要部件,确保每个组件获得运行所需的适当电力。
主板负责管理系统内部的数据流。它管理数据从 CPU 到 RAM 的传输以进行处理、从 RAM 到存储设备的传输以进行保存,以及从 GPU 到显示输出的传输以完成视觉渲染。此外,主板还包含系统的 BIOS(基本输入/输出系统)。BIOS 是系统控制和监控不可或缺的一部分。BIOS 会在计算机启动时初始化并测试硬件,还会持续关注系统健康状况,监控温度、电压和风扇转速等因素。
在 Firedancer 的设计中,主板架构发挥着关键作用。CPU 与 RAM 的距离会显著影响性能,因为距离越短,数据传输速度越快。这一距离对于 Firedancer 这类要求高吞吐量、低延迟的应用至关重要。因此,NUMA 感知架构以及对 FPGA 的潜在应用,正好符合 Firedancer 对优化内存分配和处理效率的需求。本文后面将介绍 NUMA 感知的含义以及 FPGA 是什么。
操作系统、虚拟机与内核级优化
操作系统(OS)是管理计算机硬件和软件的核心软件。它充当中间层,促进用户与计算机硬件之间的交互。它为用户提供与系统交互的界面,并为各种应用程序分配和管理资源。常见的操作系统包括 Windows、macOS 和 Linux。
内核是每个操作系统的核心。它是直接与系统硬件交互的关键组件。内核完全控制系统中的一切,负责管理内存分配、进程调度和输入/输出请求。通过在这一底层运行,内核对系统性能和稳定性发挥着至关重要的作用。
系统调用(syscall)是用户应用程序与内核之间的接口。当应用程序需要执行必须访问系统资源的操作时,例如读取文件或发送网络数据,它会发起 syscall。随后,内核代表应用程序执行所请求的操作。这一机制确保系统资源受到控制地访问,从而维护系统的安全性和稳定性。
虚拟机(VM)是对物理计算机的软件模拟。它们运行在虚拟机管理程序之上,即一种在宿主机上创建和管理虚拟环境的软件,并在隔离环境中复现物理计算机的全部功能。VM 具有多项优势,包括通过隔离提升安全性、提高资源效率,以及为测试和开发提供灵活性。
在 Firedancer 的背景下,理解这些概念至关重要。Firedancer 采用了多项内核级优化来提升性能:
- 大型静态分配: Firedancer 使用大型静态分配来尽量减少动态内存分配,即使用可供其他进程共享的共享内存分配。在这种方式下,内存只分配一次并重复使用,从而减少频繁分配和释放产生的开销。
- 绕过标准库: 标准库函数通常会增加额外的抽象层,对某些操作而言效率可能较低。Firedancer 会绕过这些标准库,直接发起 syscall。介绍 Firedancer 的 tile 架构及其如何优化网络性能时,我们会更深入地讨论这一点。
Firedancer 会尽可能避免 syscall 以及与 OS 交互,因为这些操作会显著拖慢任务。
入站与出站
入站和出站是用于描述数据流入和流出计算机系统或网络的术语。
入站是指数据进入系统。这是一个宽泛的概念,涵盖从互联网接收数据、接受用户输入,或从 IoT(物联网)设备的传感器收集信息等各种活动。对于服务器或区块链等网络系统,入站涉及接收交易请求、用户查询或需要处理或存储的传入数据流等关键任务。高效处理入站数据对于系统的响应能力和功能至关重要。
出站是指从系统发出的数据。这包括在线发送信息、生成对用户请求的响应,或将处理后的数据传输到其他系统。对于联网系统,出站包括发送已验证的交易、广播区块链更新,或将数据发送到外部存储位置。妥善管理出站数据对于正确信息分发,以及确保系统与网络其他部分有效通信至关重要。
流水线与数据并行
可以把流水线想象成工厂里的装配线。它将复杂流程拆分为多个较小且连续的阶段。流水线中的每个阶段都会执行一项特定操作。这种方式对于重复或连续的处理任务非常高效,就像区块链持续处理交易一样。
数据并行采用了不同的方法,它会同时但彼此独立地处理多个元素。这就像工厂拥有不止一条装配线来处理数据。这种方式适合能够拆分为更小子任务的工作。对于区块链,尤其是 Firedancer 这类系统,数据并行对于并发处理交易或数据处理任务至关重要。Firedancer 的并行处理能力能够最大化计算吞吐量并缩短处理时间。
可以把流水线的每个阶段想象成工厂中的独立工作站。每个工作站都能独立且并发运行。这意味着,当一个阶段处理一部分数据时,下一个阶段可以同时处理另一部分数据。这种方式允许多个流水线阶段同时运行,显著提高吞吐量。Firedancer 将流水线的顺序处理效率与并行机制的同步处理能力相结合,从而处理大量交易。
现场可编程门阵列(FPGA)
现场可编程门阵列(FPGA)是一种用途广泛的集成电路,可以在制造完成后进行编程或重新配置。这类电路具备传统硬件组件所不具备的适应能力。它们由大量相互连接的可编程逻辑块组成,每个逻辑块都能执行多种数字功能。这种设计让 FPGA 在速度、并行处理和适应能力至关重要的应用中拥有极高的灵活性和效率。
典型的 FPGA 由微型可编程元件组成,所有元件均通过可编程线路连接。这个由部件和连接组成的复杂网络,让用户可以对芯片的不同区域进行编程,以执行特定任务,从而创建完全定制的处理环境。
FPGA 通过同时使用这些微型可编程元件,在并行处理方面表现出色。其结构有利于实现高效的流水线处理,让数据持续流经各个处理阶段。设计良好的流水线可以将系统吞吐量与延迟解耦。虽然这种流水线生成输出的时间可能比传统 CPU 更长,但系统能够同时处理多个输入数据流。每个操作的延迟对整体数据流影响很小,就像水流经软管一样。
在 Firedancer 中,FPGA 具有显著优势。它们可以将数据流水线直接连接到网络。传统配置中的 GPU 依赖 CPU 移动数据,而 FPGA 在处理网络流量时效率更高。直接连接能力以及创建定制处理方案的能力,例如在 FPGA 结构上构建软处理器,使其在开发高性能验证者客户端时极具价值。
相关文章
订阅 Helius
及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新


