新消息:Helius 收购 Light Protocol
异步程序执行:Solana APE 新纪元的黎明
博客/研究

异步程序执行:Solana APE 新纪元的黎明

研究员X 上的 Lostin
阅读需 29 分钟

引言

今年热闹非凡的 Breakpoint 大会充斥着激烈辩论和重磅发布主题演讲。在此期间,Solana 联合创始人 Anatoly Yakovenko 抽出时间,临时举办了一场未被录制的技术研讨会。他带着挂纸板和马克笔,深入讲解了自己极力倡导、视为 Solana 下一阶段演进方向的主题,也是本文的重点——异步执行。

为了介绍异步执行这一宏大愿景(下文简称 AE),我们将首先从宏观层面解释 AE 的核心概念和目标。随后,我们会分析 Solana 现有的执行与共识机制,为比较未来提出的架构奠定基础。接下来,我们将深入探讨围绕 AE 的各种提案,先从无 Bank 领导者开始,它是实现这一转变的必要跳板。我们还会回顾 2022 年最早的设计提案,并按时间顺序介绍较新的“终局架构”提案。这些提案超越了 AE,还包含多个并发区块生产者的设计实现。

AE:万米高空概览

这样想其实有点奇怪。它[验证者]所做的一切就是出块和投票。它根本不需要执行任何这些区块。创建区块时,它并不知道自己创建的是什么样的区块……你关心的只是就排序达成一致。至于值是什么,它并不在意。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

在 Solana 核心协议的语境中,AE 是指将执行与共识分离,使两者能够彼此独立运行的架构方法。网络无需实际执行交易,只需就交易顺序达成共识。排序达成一致后,任何人都可以执行交易并揭示事实。

采用这种方法时,领导者无需执行非投票交易即可构建区块,并通过 Turbine 将其传播到整个网络。验证者同样可以在不执行非投票交易的情况下对区块投票。共识仅限于交易的顺序和可用性,大幅减少达成共识所需的时间和步骤。借用 DBA 的 Jon Charbonneau 在一篇总结中的说法:排序决定事实,执行揭示事实。

这种方法与当前的共识运作方式截然不同。目前,领导者会先执行交易,再将其打包进区块;所有验证者也会先重放区块中的交易,然后再投票。

AE 之所以可行,是因为:

  1. 分叉选择不依赖程序执行
  2. 在确定性状态转换函数下,只能计算出一个正确状态。最终,每个人都会计算出相同的最终状态
  3. 无效交易可以被丢弃。失败交易垃圾信息给网络带来的成本相对较低,仅包括传播交易所需的 Turbine 带宽,以及账本中交易占用的额外存储空间
  4. 对于需要实时、低延迟计算完整状态的机器,例如专用 RPC 服务提供商运营的机器,可以专门为此用途配置资源

AE 具备许多潜在优势。

Yakovenko 甚至表示:“异步执行是少数几乎不需要做任何取舍的方案之一。”

  1. 更短的区块时间(200 毫秒)
  2. 更可靠的区块时间
  3. 更低的验证者要求
  4. 改善用户体验(更快达到最终性)
  5. 增强抗审查能力
  6. 缩短交易重排序的时间窗口
  7. 在区块之间结转未使用的容量
  8. 为多个并发区块生产者铺平道路(后文详述)

本文将详细探讨 AE 如何带来这些优势。

理解 AE 的另一种方式是:它允许投票程序独立于其他所有程序运行。投票程序和系统程序(始终必需)是一个 epoch 内达成共识所需的仅有程序。

围绕 Solana AE 的讨论已持续数年。Anatoly Yakovenko 最初的正式提案原名为 APEX(异步程序执行),可追溯至 2022 年 4 月。关于如何在 Solana 上实际实现 AE 的具体细节散见于多份 SIMD 和文章中,本文将大致按照时间顺序逐一介绍。毫无疑问,Yakovenko 是 Solana 社区中最积极公开支持和倡导 AE 的人,他在采访和播客节目中几乎从不错过讨论这一主题的机会。

术语

在讨论 AE 之前,简要定义两个将频繁出现的关键术语会很有帮助:无 Bank 领导者和多个并发区块生产者(MCBP)。概括如下:

  • 无 Bank 领导者:无需执行交易即可创建区块的领导者
  • 异步执行(AE):共识与执行完全分离
  • 多个并发区块生产者(MCBP):顾名思义,在同一个 slot 内并发生成多个区块‍

无 Bank 领导者是实现完整 AE 的必要步骤。同样,成功实现 AE 也是之后引入多个并发区块生产者(MCBP)的必要条件,后者也称为多个并发领导者(MCL)。关于 AE 的讨论经常与 MCBP 一并展开。Yakovenko 主张将两者都作为 Solana“终局架构”的关键组成部分。

Solana 并不是唯一研究这些架构增强方案的区块链。Monad 计划将共识和执行解耦到不同线程中,以实现 AE。同样,以太坊研究社区也已对引入多个并发提议者的可能性探索了一段时间。

Yakovenko 的提案仍在社区中持续引发讨论,因为实现这些提案需要大幅修改 Solana 核心协议。并非所有人都认同 AE 是最佳前进方向。毫不夸张地说,完整实现 Yakovenko 提出的终局架构,将彻底改变 Solana 的运行方式,并增加协议的整体复杂度。

在深入分析 AE 之前,我们需要回顾 Solana 当前的执行与共识机制,并特别关注本文后面会提到的方面。我们还会分析投票和非投票交易的数据,从中获得更多洞见,为后续讨论提供依据。已经熟悉并充分理解这些机制的读者可以跳过下一节。

同步执行(当今的 Solana)

执行

Solana 采用连续区块构建方式,在分配的 400 毫秒 slot 内动态组装并流式传输区块。每位领导者会连续获分配四个 slot(1.6 秒),随后轮换。要让区块获得网络接受,领导者必须验证并执行区块中的每笔交易。此外,所有其他活跃并参与共识的验证者都会重新验证并重新执行区块中的每笔交易。

领导者通过 Gulfstream 和 QUIC 接收交易数据包,数据包随后进入交易处理单元(TPU)。TPU 是领导者负责区块生产的核心逻辑。TPU 通过三个开放端口接收数据包:

  • tpu:处理代币转账、NFT 铸造和程序指令等常规交易
  • tpu_vote:仅处理投票交易
  • tpu_forwards:如果当前领导者无法处理所有交易,则会通过此端口将未处理的数据包转发给下一位领导者‍

在开始任何形式的排序或执行之前,所有交易数据包都要经过严格的验证和健全性检查,包括签名验证、检查签名数量是否正确,以及剔除重复交易。请注意,投票交易与非投票交易采用独立的签名验证流程。

区块构建发生在 Banking Stage。bank 表示给定区块处的状态。交易会并行处理并打包到账本条目中,每个条目是一批包含 64 笔互不冲突的交易。所有交易都包含其将读取和写入的完整账户列表。借助这一设计,验证者可以轻松选择互不冲突的交易,在各个条目中执行。如果交易写入同一账户(两次写入),或者分别读取和写入同一账户(读取 + 写入),就会产生冲突。冲突交易会进入不同条目并按顺序执行,而互不冲突的交易则会并行执行。

六个线程并行处理交易,其中四个专门处理非投票交易,两个仅处理投票交易。在 Banking Stage 中,共识投票会被视为具有特权的交易:统一定价为 0.000005 SOL,消耗 2,100 个计算单元(CU),并由投票程序执行。 

交易被分组到条目后,由 Solana 虚拟机(SVM)执行。交易所需的账户会被锁定;系统会检查交易是否足够新,且之前尚未处理。随后加载账户并执行交易逻辑,更新账户状态。条目的哈希会发送给历史证明(PoH)服务进行记录。执行成功后,所有更改都会提交到 bank,并解除各账户的锁定。

协议并未规定区块内有效交易的排序方式。链的最终状态由所有已确认交易共同决定。始终可以根据区块链历史,以确定性方式重新创建这一状态(例如,从创世区块或快照开始重放账本)。

每个 bank 都有一个对应的 BankHash,它是以下内容的 SHA256 哈希:

  • 父级 BankHash - 直接父区块的 BankHash
  • 账户 DeltaHash - 当前区块中所有发生状态变化的账户所组成的 16 叉 Merkle 树根
  • 签名数量 - 当前区块中的交易签名总数
  • 最后一个区块哈希
代码
hashv(&[
	parent_bankhash,
	accounts_delta_hash,
	num_sigs,
	blockhash,
])

BankHash 是验证者针对每个 slot 投票的加密承诺。

共识

验证者需要三个账户来完成投票流程:

身份账户

这个系统账户是所有投票交易的签名者和费用支付者,也是直接存储在服务器硬件上的热密钥对。顾名思义,该账户的公钥充当验证者的网络身份。创建投票账户时必须使用身份账户。

投票账户

这是委托者委托其 SOL 的账户。该地址用于查询账户,而非签署交易。

提款账户

此账户用于从投票账户中提取资金,也可以更改身份账户。该账户的私钥通常存储在安全的多签钱包或冷钱包中,并且必须与验证者身份密钥对及投票权限密钥对不同。

验证者签署的每一张投票(示例)都包含验证者的公钥,以及一个用于标识其所投区块的哈希。验证者提交正确且成功的投票后,会获得积分。

网络不会等到所有验证者都对新生成的区块达成一致后,才开始生成下一个区块。因此,两个不同区块连接到同一个父区块并形成分叉的情况并不少见。验证者必须对这些分叉投票,并使用 Tower BFT 决定采用哪一个。Tower BFT 是原始实用拜占庭容错(pBFT)的一种变体。 

当存在相互竞争的分叉时,网络会最终确定其中一个分叉,验证者则放弃已被舍弃分叉中的区块。每个 slot 都有预先确定的领导者,并且只会接受该领导者生成的区块;单个 slot 不能有两个候选区块。因此,潜在分叉的数量仅限于一种“存在/不存在”式的跳过列表,这类分叉可能出现在领导者轮换 slot 的边界处。 

验证者一旦选择某个分叉,就会在锁定时间到期前持续承诺该分叉,也就是说,它必须至少在一段时间内坚持自己的选择。这一机制激励验证者谨慎投票,选择它们认为最有可能被纳入的分叉,即“最重”的分叉。

当三分之二的绝对多数对某个区块投票时,该区块即被视为获得乐观确认。在其上方又构建 31 个区块后,该区块即达到最终性。Solana 历史上从未出现过获得乐观确认的区块最终未达到最终性的情况。

分叉达到最终性后,该区块会连同 bank 中的账户更新一起成为根区块,其祖先区块则会刷入磁盘。此外,来自更早 bank、但不属于最终 bank 祖先的所有账户更新都会被剪除。

投票交易与非投票交易

正如我们所见,在 Solana 上,交易执行流程与通过 Tower BFT 达成共识紧密交织。投票交易和非投票交易遵循同一路径:它们被捆绑进条目,由 SVM 执行,在历史证明(PoH)stream 中加盖时间戳,并通过 Turbine 传播到网络。这个统一流程确保验证者以一致方式看待共识状态,因为如果仅通过 gossip 服务传播投票,验证者之间可能产生分歧。这种分歧可能让验证者对哪个分叉更可能正确产生不同判断。连续构建区块需要连续投票,尤其是在确认之前区块的过程中。

这种捆绑方式带来的一个副作用,是 Solana 每秒交易数(TPS)指标引发了争议。原始指标同时包含投票交易和非投票交易,而大多数同类行业网络并非如此。因此,业界开始采用排除投票交易的“真实 TPS”指标,以便更准确地衡量交易容量。

观察 Solana 最近的活动可以发现,投票交易数量高于非投票交易,每个区块平均略低于 1,000 笔。

投票交易仅占每个区块总计算单元的一小部分,平均每个区块略高于 200 万 CU,并稳定保持在 210 万至 230 万 CU 之间。这只占 Solana 区块 4,800 万 CU 计算上限的 4.5%。

与非投票交易相比,投票交易所需的时间和计算量非常稳定。这是一个关键点,本文稍后还会再次讨论。非投票交易的 CU 并不稳定,导致硬件资源利用效率低下。 ‍

在运行时中保证精确的执行时间非常困难,因为它更像是一种近似测量。区块平均以控制在 400 毫秒内为目标,但偶尔会出现尖峰。这些尖峰可以被视为 bug,相关团队一直在努力识别并修复它们,从而持续改进系统。

一个 epoch 包含 432,000 个 slot。如果每个 slot 都恰好为 400 毫秒,那么一个 epoch 将精确持续 48 小时。然而,从历史数据可以看出,epoch 很少能够达到这一目标,甚至可能从未达到。过去一年中,一个 epoch 通常需要 2.1 至 2.3 天。

同步执行要求所有已质押并参与共识的验证者,针对任一区块中最坏情况下的执行时间超额配置资源。因此,Solana 的验证者硬件要求相对较高。

至此,我们对 Solana 当前共识和执行机制的回顾告一段落,重点介绍了与后续讨论相关的部分。如需更全面的概览,建议阅读我们之前发布的 Helius 博客文章,了解共识、PoH、Turbine 和 Solana 的运行原理。接下来几节将探讨 Solana 协议设计未来可能发生的变化。

APEX,2022 年

Yakovenko 最早的正式 AE 提案可以追溯到 2022 年 4 月,名为 APEX(异步程序执行)。这份相对简短的提案提出了如何分离共识与执行的具体方案,并引入将状态拆分为两个隔离域的概念:默认的“域 0”和投票程序所在的“域 1”。这种设置将投票程序与 bank 的其余部分分离。‍

所有账户都只属于一个域;交易不能读取或写入多个域中的账户。任何这样做的交易都会立即失败并被忽略。系统程序同时存在于两个域中,而投票程序是域 1 中唯一的另一个程序。

一条特殊的系统指令(SystemInstruction::MoveDomains)提供了一种机制,允许账户在每个 epoch 内跨域移动一次,以便向投票账户转入或从中转出 SOL。

该提案还引入了 ForkHash 的概念,它与 BankHash 相对应。计算 ForkHash 时只评估域 1 中的投票程序指令,而 BankHash 则评估域 0 中的所有非投票程序指令。投票指令引用 ForkHash。BankHash 的计算在共识验证者投票的根之外完成。此前,选择分叉并对其投票,需要完整评估和执行 bank 中的所有交易。现在,分叉选择中唯一需要评估的交易是涉及投票程序的交易。

这项早期设计留下了许多尚未解答的问题,但确立了隔离域这一基础概念,后文还会再次讨论。

无 Bank 领导者

无 Bank 领导者是指无需执行非投票交易即可自由生成区块的领导者,这是实现 AE 的关键前提。在一篇名为通往无 Bank 模式之路的博客文章中,Anza 工程师 Andrew Fitzgerald 以同为 Anza 成员的 Tao Zhu 早期提出的无 Bank 领导者提案(SIMD-005,2022 年 12 月,已关闭)为基础,继续推进这一思路。Fitzgerald 概述了在 Solana 上引入无 Bank 领导者所需的多项更改,并具体指出协议施加的三类关键约束限制了 AE 的实现:区块约束、条目约束和交易约束。

目前,只要违反其中任何约束,整个区块都会失效。消除这些限制后,Solana 协议将为 AE 开辟可行路径,并提升协议在区块生产和验证方面的灵活性。以下是各种约束形式的概要:‍

区块约束

这些约束作用于整个区块,包括: 

  • 区块必须包含 64 个 tick
  • 区块的最后一个条目必须是 tick
  • 所有区块条目中的交易都必须处于区块限制范围内

条目约束

此类别的主要约束是条目不能包含相互冲突的交易。Fitzgerald 于去年 11 月提交了 SIMD 0083:放宽条目约束,专门处理这一问题。该 SIMD 已获接受。

交易级约束

这是最大的类别,可以进一步分成三个子类别:

静态约束

无需了解任何额外状态即可验证的约束。其中包括签名验证、交易大小、读写地址列表中列出的账户数量,以及交易数据格式合规性(即交易必须能够反序列化)‍

这一交易级约束子类别无需修改。

Bank 状态约束

其中包括检查交易签名是否唯一,以确保该交易尚未被纳入近期区块,以及时效验证(即交易必须包含近期区块哈希)

这一子类别需要了解 bank 的近期状态。

账户状态交易约束

限制最严格的约束子类别,包括地址查找表(ALT)解析、nonce 检查、费用支付者检查和可执行性检查

这一子类别需要了解先前的交易。

Fitzgerald 在 SIMD 0082:放宽交易约束中正式提出了对此类约束的更改,该提案目前仍处于开放状态。

正如 Fitzgerald 指出的,AE 的首要要求是区块验证不能依赖账户状态。如果验证区块需要使用先前交易的结果,就无法异步执行该区块。因此,区块验证必须消除对账户状态的依赖。此外,其中许多约束都没有必要如此严格。

例如,在当前协议或拟议更改下,签名者没有足够 lamport 支付费用的交易都不应执行。但采用拟议更改后,即使区块中包含这种交易,也不会导致区块的其余部分被标记为无效。

总体而言,Fitzgerald 的工作为如何修改 Banking Stage 以给 AE 铺平道路提供了实用框架,并概述了实现 AE 所需的许多共识变更步骤。

APExB 2023:AE 与 MCBP 相遇

异步程序执行将把整个 Solana 状态变成一个 rollup。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

2023 年 3 月,在最初的 APEX 设计提出近一年后,Yakovenko 发布了一份更全面、更详细的提案,名为异步程序执行与广播(APExB)SIMD 0023。该提案不止涉及 AE 的实现,还提出了一个包含集成多个并发区块生产者(MCBP)的更宏大愿景。

该提案引入了“构建者”的概念,它们是独立于领导者的实体。构建者是质押节点,负责创建完全由非投票交易组成的 UserBlocks。这些 UserBlocks 通过 Turbine 树传播,并拥有自己的“UserBlockSlots”。默认情况下,每个常规 slot 有两个 UserBlockSlots。

构建者拥有独立于领导者日程的日程。可以安排多个构建者并发构建 UserBlocks。计算单元会在构建者和 UserBlock slot 之间平均分配。例如,一个包含两个构建者、两个 UserBlock slot 且 CU 上限为 4800 万的区块,其 UserBlock slot 的 CU 上限将为 1200 万(48/4)。

领导者按照领导者日程照常创建由共识投票组成的区块,同时构建者并发生成并传输用户交易的 UserBlocks。UserBlocks 会注明其 slot 编号,并由构建者签名,以防领导者操纵或排除区块的某一部分。领导者通过 Turbine 收到 UserBlock 后,会使用该 UserBlock 的哈希生成 UserBlockEntry,并将此 UserBlockEntry 添加到历史证明(PoH)中。

验证者不能对尚未收到相应 UserBlocks 的区块投票;否则,由于数据可能被扣留,便无法保证每个人都能执行这些数据。不过,他们可以先仅执行投票并对领导者区块投票,之后再执行 UserBlock 交易。验证者只在最重分叉上执行 UserBlocks,并且投票时只需提交其最新的 BankHash,而该值可能对应更早的父 slot。验证者对 VoteHashes 投票,其作用与 APEX 2022 提案中的 ForkHashes 相同——本质上是仅针对投票交易的 BankHash。

构建者日程

如果每个网络区块有十个 UserBlock 构建者,每个构建者将获得 10% 的 Turbine shred 和 10% 的可用计算资源。构建者通过两种流程安排:随机分配和持久分配。

在每个 epoch 的边界,会根据质押权重选择流程分配随机构建者。持久 UserBlock slot 则通过荷兰式拍卖系统分配,授予愿意销毁最多 SOL 的最高出价者。

交易优先级排序 

每个 UserBlock 都被视为在领导者对其编码的 UserBlockSlot 期间同时创建。对于 UserBlockSlot 中的每个 UserBlock,交易会在执行前按优先费排序。如果来自两个不同区块的交易具有相同优先级,则根据哪个 UserBlock 先出现在领导者的 PoH 中进行排序。这意味着**优先费决定执行优先级。**重复或无效的 UserBlocks 交易会被跳过,不会更改状态。如果多个 UserBlockEntries 包含同一笔交易,第二笔会被跳过。

上图:在场景 1 中,尽管交易 B 较晚进入 PoH 流,但仍会被优先处理。在场景 2 中,交易 C 与交易 D 的优先费相同,但其区块在 PoH 流中出现得更早,因此交易 C 会被优先处理。

在这种设计下,构建者将获取全部 MEV。该提案并未确定构建者和领导者应如何分配用户交易费。

构建者还可以创建 BundleTransactions,即 UserBlock 内按顺序以单个批次执行的交易组。这些交易也可以添加优先费,使整个 bundle 作为一个批次获得执行优先权,类似于当前的 Jito bundle 实现。

Epoch 边界

质押权重会影响分叉选择,并在每个 epoch 边界更新。这对设计有重要影响。验证者必须完成非投票交易的执行追赶,才能在越过该 epoch 边界后继续投票。

不过,Yakovenko 指出,“节点不可能落后太多,因为总体 CU 上限是按同步执行设置的。但有了异步执行选项,追赶会容易得多。如果不处理网络,原始账本处理速度要快 20 到 30 倍。”

注意事项

多个构建者会让资源管理变得更复杂。客户端可以选择离自己最近的构建者,但每个 UserBlock 的优先费可能不同,而且用户发送交易时往往不知道哪个区块可能会饱和。

其优势包括调度的可预测性。应用可以竞标运行所需的区块带宽比例,并创建专用排序器,确保交易最终结算到链上。引入随机 UserBlock 构建者至关重要,因为这可以防止持久区块构建者审查交易并阻止交易最终上链。

Solana 2024 中的 APE

在今年 6 月发布的一篇题为异步程序执行(APE)的 X 文章中,Yakovenko 进一步完善了 2022 年 APEX 提案最初描述的执行域概念。

执行域原名 Domain 0 和 Domain 1,现已分别更名为投票执行域(VED)和用户执行域(UED)。其目的保持不变——将共识投票与交易执行完全隔离。

执行域被定义为不同的程序集合,以及它们交互的键和值;每个集合都独立于其他集合执行:

  • 执行域可以在不同的线程和核心上运行,并在物理隔离的机器上于不同时间完成 
  • 执行域 A 无法读取或写入执行域 B 中的任何值 
  • 不同执行域可以共享在任一域执行期间保持一致的状态
  • 费用支付方决定交易在哪个域中执行
  • 需要一种协议来同步域间状态,并支持键和值的移动

投票执行域(VED)组件

  • SystemProgram:用于转账
  • VoteProgram:用于投票的核心程序。该程序是静态的,必须同时存在于 UED 和 VED 中
  • VoteProgram Sysvars:用于投票的变量
  • 投票权限:获准投票的账户
  • 投票费用支付方:支付投票相关费用的账户
  • 费用支付方资助账户:可更新的账户,可用于将 SOL 转入 VED

不在 VED 中的账户均被视为 UED 的一部分。

投票账户必须激活。激活后的下一个 epoch,它们会被纳入 VED。停用后,它们会在下一个 epoch 从 VED 中移除。提案还为资金转入和转出 VED 规定了正式流程。

账户会按照类似 Linux 文件权限(R 读取、W 写入和 X 执行)的约定,记录其映射到的执行域。共有四种有效映射:

只有 Vote Program 和 System Program 账户可以在 VED 与 UED 之间移动。System Program 提供了一个接口,用于将 System 账户和 Vote Program 账户移入或移出 VED。这种方法不再需要显式的 FeePayerFunding 账户。任何 System 账户都可以在 VED 和 UED 之间重新映射,从而在域间转移资金。

领导者只为自己创建的区块执行 VED 域,这意味着他们掌握的 UED 费用支付方状态信息可能不完整。收到区块后,验证者会先执行 VED 交易。生成的 VED 状态用于计算 VED Hash,随后验证者使用该值投票。 

UED 重放会跳过费用支付方无效的交易。UED 状态更新会计算称为 UED Hash 的 Bankhash。如果三分之一或更多验证者提交了不同的 UED Hash,所有节点都必须停止运行并向运营者发出警报。

新功能激活

共识现已与执行解耦,因此 VoteProgram 必须能够处理 VED 投票可能跨越 epoch 边界的场景。这会导致新功能的激活时间与 UED 中同 VoteProgram 交互的交易不同。

2024 终局架构

考虑到应用和核心开发者的多样性,值得规划每年进行一次重大协议变更。如果只能选择一个,我会投票支持异步执行。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

2024 年初,Yakovenko 发布了终局架构,大胆展望了 Solana 的未来:成为一个拥有 10,000 个节点、区块时间为 120 毫秒的网络。该文档重申并扩展了早期设计提案,同时强调采用 AE 是实现这一宏伟愿景的路径。

无 Bank 领导者

总结如下:

● 领导者维护费用支付账户余额的缓存

● 如果费用支付方作为系统转账来源的可写账户,或作为可写账户与 system program 一起传递给其他程序,则费用支付余额会被设为 0

● 根据声明的 CU 打包区块,依照本地费用优先级排序持续打包,直至区块已满,并从费用支付方余额缓存中扣除交易费 

● BankHash 计算会补充费用支付账户余额缓存 

领导者最初可以通过查询多个全节点或 RPC 来获取费用支付方的账户余额。在极少数节点提供错误数据的情况下,结果会是交易失败,而非共识失败。如果费用支付方余额已过时,可能会导致区块内出现垃圾交易,但不会影响共识。失败交易垃圾信息的成本相对较低,主要包括传播交易所需的 Turbine 带宽,以及它们在账本中占用的额外存储空间。此外,Temporal 和 Firedancer 团队都在积极开发工具,通过过滤无效交易、去重,以及阻止因读写锁冲突而必然失败的交易等机制,在垃圾交易进入区块前予以缓解。

这一问题很容易检测和监控。运营者可以跟踪领导者表现并评估区块中的垃圾交易规模,从而快速解决问题,并在必要时切换到备用数据源。由于验证者有动力实现收益最大化,他们也有动力维护准确的费用支付方账户余额缓存。

固定规模的子委员会

要在拥有 10,000 个节点的大型网络中实现 AE,就必须引入固定规模、轮换制的投票委员会,这将对共识机制构成重大改变。无论质押节点总数是多少,这项变更都能稳定共识投票的资源成本。Yakovenko 提议,由 200 或 400 个节点组成的轮换委员会就已足够。这样的设置让验证者能以最低状态要求参与共识投票,仅需维护法定人数、质押权重和投票账户余额。其内存占用很小,相应的快照文件也能轻松分发,并在重启时重新初始化。

真正讽刺的是,异步执行落地后,Solana 共识验证者或许能在 FPGA 上运行。用于 1 万个投票账户的 Turbine + tower 可以轻松装进 FPGA。可能只需要约 4 MB 的状态用于跟踪。

Anatoly Yakovenko
Anatoly Yakovenko
Solana 联合创始人

在拜占庭容错(BFT)协议中使用固定规模的轮换子委员会是一种成熟的概念,Tron 等同类网络已将其用于生产环境。它基于委员会抽样方法,即选择一个规模较小的委员会来处理共识,再将结果中继到由副本组成的整个网络。

Solana 的初始方案可以只是为投票分配固定数量的 CU,并在每个 epoch 选择按质押量排名靠前且能容纳在这些 CU 内的验证者来跟踪分叉选择。其他验证者仍会投票并获得奖励,但其投票不会纳入分叉选择。

投票账户

● 投票账户必须拥有足够支付两个 epoch 投票费用的 SOL 

● 投票交易必须是简单投票

● 如果余额超过一个 epoch 的投票费用,则允许从投票账户中提取 SOL

● 要移除所有 lamport,Vote CLOSE 指令必须等待整个 epoch 结束。投票账户会在第一个 epoch 被标记为 CLOSE,但只能在第二个 epoch 执行 CLOSE

CLOSE 允许提取所有 SOL 并删除投票账户。账户一旦被标记为 CLOSE,就只能删除,无法重新开启

● 投票包含 VoteBankHash,而不是常规 BankHash 

BankHashes

验证者使用与当前 BankHash 相同的格式,为简单投票交易计算 VoteBankHash,并忽略所有其他交易。这些 VoteBankHashes 会纳入上一个 VoteBankHash,而不是完整的 BankHash。

对于由三分之二绝对多数乐观确认的区块,验证者还会开始计算 UserBankHash,其中包含除已在 VoteBankHash 中考虑的状态转换之外的所有状态转换。

每个 slot 都会通过组合 VoteBankHash、UserBankHash 和上一个 BankHash 来计算 BankHash。排名前 99.5% 的验证者每 100 个 slot 会在投票中提交一次此 BankHash。此外,一些节点可以通过 gossip 网络广播 BankHash,以表明未检测到非确定性。

假设提交完整 BankHash 的验证者少于三分之二。在这种情况下,领导者可以将用户交易和可写账户的区块空间减少 50%,防止利用漏洞过度增加重放时间。

每个 epoch 只需计算一次状态,以确定下一组法定人数,确保共识节点与领导者保持同步。执行可以在与共识节点分离的机器上聚合并批量处理。需要同步执行的用户(大多数应用和 RPC)可以投入专用硬件资源,实时处理每次状态转换,无需等待更广泛的网络。

注意事项

向用户提供实时状态数据的 RPC 提供商没有签名可验证其本地计算的状态是否与更广泛网络计算的状态一致。不过,一旦分叉最终确定,网络就会收敛到唯一且正确的规范状态,并且可以确定性地计算该状态。为尽量降低运行时错误或数据损坏的风险,旨在提供准确状态数据的节点应运行多个节点。如果检测到任何状态执行差异,应立即停止运行。

此外,用户可以提交断言 BankHash 或触发中止的交易。只有当计算出的 BankHash 与 RPC 提供商向用户提供的值一致时,网络才会处理这些交易。

结论

Yakovenko 为 Solana 设想了一个大胆的未来:通过采用 AE,将区块时间缩短至 120 毫秒,并大幅增加节点数量。然而,要实现这一未来,就需要让不同的客户端团队和更广泛的 Solana 开发者社区围绕这一愿景达成共识,并解决实施此类变更所带来的重大工程挑战。 

多位知名社区成员对其中许多拟议变更表达了担忧。Firedancer 团队的 Richard Patel 警告称,“为区块生产者实现异步执行相当复杂,而且伴随着重大风险。”

尽管支持 AE,Jito Labs 的 Zano Sherwani 仍批评了 MCBP,并表示,“多个并发提议者是一个糟糕的解决方案,它正四处寻找自己要解决的问题。它给协议带来的复杂性,与其试图解决的问题(如果真有的话)并不相称。”

在最近的一期播客中,当被问及多个区块构建者时,Helius 的 Mert Mumtaz 回答:“我还没有完全信服。”

毫无疑问,AE 有望带来显著的性能提升。更短的区块时间意味着更快的确认和更好的用户体验,同时还能增强抗审查能力,并缩短交易重新排序的时间窗口。

不过,我们也必须仔细评估其缺点,包括协议复杂性可能上升,以及对 RPC 提供商的依赖增强。在某些特定场景中,这些提供商可能是唯一能够实时掌握链上最新状态的参与者。

AE 是 Solana 的一次重大升级。我们希望通过本文提高 Solana 开发者社区对 AE 即将带来的激动人心变化的认识,并鼓励大家围绕这一重要话题展开更充分、更知情的讨论。

衷心感谢 0xIchigo 和 Anatoly Yakovenko 审阅本文的早期版本。

其他资源

订阅 Helius

及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新

放大图片