新消息:Helius 收购 Light Protocol
Agave 3.1 横幅
博客/更新

Agave 3.1 更新:你需要知道的一切

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

特别感谢 0xIchigo 和 Brian Wong 审阅本文的早期版本。

简介

Solana Agave 客户端的最新演进版本 Agave v3.1 正式发布!本次更新带来一系列广泛升级,改进了客户端性能、验证者运维和开发者体验。此次更新还包括多项重要的功能门控激活,为协议内区块奖励分配、大幅降低状态保证金(即租金),以及最受关注的 Alpenglow 共识升级奠定基础。

Agave 3.1 重要更新

  • 降低重放期间的磁盘 I/O
  • 更快的客户端重启
  • 交易处理速度提升 2 倍
  • 提高 CPI 账户信息上限*
  • 验证者投票账户 V4 与延迟佣金更新*
  • 减少 Turbine ChaCha 轮数*
  • 新增指令数据指针*
  • RPC 改进

* 功能门控升级

无论你是验证者运营者还是开发者,本指南都能为你提供充分利用最新改进所需的更新与洞察。本文各节均可独立阅读,方便读者聚焦与自己最相关的主题。 

截至本文撰写时,Agave 3.1.8 被视为主网升级候选版本(MUC),Anza 正在招募志愿者,协助将该版本的质押占比提升至 25%。各位验证者:是时候升级了!

客户端性能提升

Agave 此次重大版本带来多项性能提升。下面重点介绍其中几项最重要的改进。

降低重放期间的磁盘 I/O 

Agave 3.1 大幅减少了重放期间的磁盘活动。下图展示了 Agave 3.0 处理真实主网交易时,重放过程中的一个 10 秒性能分析窗口。磁盘操作(以红色标记显示)超过 1,100 次。这会带来问题,因为每次磁盘访问都会引入 I/O 等待时间,导致 banking 和重放出现抖动。 

在 Agave 3.1 中,重放期间的磁盘 I/O 显著减少。同样的 10 秒窗口内,磁盘操作少于 80 次,降幅达 93%。这不仅提高了重放稳定性,还减少了磁盘损耗,有助于延长磁盘寿命。

更快的客户端重启

客户端重启性能继续大幅提升,这主要得益于对 AccountsDB 的优化。在 Agave 1.* 的主要版本中,重启通常需要 30 分钟以上。Agave 2.* 将其缩短至 10 分钟以内。在 Agave 3.1 中,重启时间进一步下降,目前通常不到 1 分钟。展望未来,下一个主要版本 Agave 4.0 有望将重启时间压缩至 30 秒以内,进一步提高验证者在线时间,并缩短维护或意外故障后的恢复时间。

更快的交易处理

Agave 3.1 包含多项关键修复,显著提高了交易处理效率。此前,交易处理流水线中的错误导致 banking 工作线程将过多时间用于和历史证明同步,而不是执行交易。因此,在 leader 模式下,客户端约 61% 的时间都没有主动调度交易。

Agave 3.1 解决这些问题后,banking 工作线程如今会将约 ~91% 的时间用于处理交易。因此,交易处理速度提升了一倍,显著提高了吞吐量,也能更充分地利用 leader 时间。

其他值得一提的性能增强包括默认将账户索引完全保留在内存中。epoch 边界转换也得到显著改进,现在可在 400ms 内完成,而此前需要两秒以上,因此 epoch 切换期间跳过的 slot 大幅减少。

网络加固

Anza 通过持续压力测试、红队测试和实时态势监控,为 Agave 客户端的韧性投入大量资源。尽管这项工作的具体细节此前一直保密,但该计划如今已足够成熟,可以公开介绍这项重要工作。Anza 的专门 invalidator 团队会主动攻击 Solana 公共测试网,并且每小时运行一组新测试。 

测试主要分为两类。第一类聚焦网络层拒绝服务场景,对极端条件下的背压处理和负载卸除进行压力测试。第二类测试则会生成经过专门设计的区块,其中包含异常和对抗性交易,旨在挑战 Solana VM 的极限。

Anza 系统化地构建攻击场景,并开发相应防御措施。这项工作基于贴近现实的威胁模型,涵盖恶意且消息灵通、拥有合理质押量的验证者能够实施的行为,以及资金充足、技术高超的外部开发者可能发起的攻击。

这种充分准备在 12 月得到了验证。当时 Solana 承受了一场持续数周的大规模 DDoS 攻击,据报道峰值接近 6 Tbps,是有记录以来针对分布式系统的最大规模攻击之一。尽管攻击规模极其庞大,网络几乎未受到可测量的影响,整个攻击期间始终保持亚秒级确认和稳定的 slot 延迟。

提高 CPI 账户信息上限

SIMD-0339:提高 CPI 账户信息上限计划在 Agave 3.1 发布周期内于主网激活。该提案将跨程序调用(CPI)的账户信息上限从 64 提高到 255,增幅接近 4 倍,解决了长期困扰开发者的难题:需要通过 CPI 传递大量账户列表的程序将不再受原有限制。账户信息是传入 CPI 系统调用的序列化账户元数据,让被调用程序可以读取调用方提供的账户。

此前,每次系统调用的 CPI 仅限传递 64 条账户信息。这一限制迫使程序在调用 CPI 前对账户列表去重并重新构建,增加了复杂度和开销。实际上,许多真实程序经常超过这一阈值,例如 DFlow 或 Jupiter 等 DEX 聚合器的封装程序。

除提高上限外,此功能门控还会引入计算单元成本变更,成本将根据传入 CPI 的账户信息和指令账户数量变化。这能继续激励程序尽量减少账户用量。 

由于只是提高上限,此项变更完全向后兼容,不会影响现有程序的行为。

验证者投票账户 V4 与延迟佣金更新

Agave 3.1 发布周期内计划激活的两项功能门控更新对验证者运营者尤为重要。第一项是 SIMD-0185:投票账户 V4,它引入新版投票账户状态,以支持即将到来的协议升级,包括 Alpenglow、区块收入分配和佣金机制改进。

目前,投票账户只能存储单一佣金率。但随着 SIMD-0123:区块收入共享所述的协议内区块收入分配功能即将推出,验证者需要能够为不同收入来源设置不同的佣金率。

此外,包括基础费用和优先费在内的所有区块费用收入,目前都会存入验证者身份账户。这可能带来运维和安全问题,因为身份账户不能使用冷钱包;它必须频繁为 Turbine 和 Gossip 等关键网络协议签署消息。

投票账户 V4 通过新增字段扩展投票状态(见下方代码块),从而解决这些限制,让验证者可以分别配置通胀奖励和区块收入的佣金率及收款账户。此次更新还移除了旧版 prior_voters 字段。

代码
pub struct VoteStateV4 {
    pub node_pubkey: Pubkey,
    pub authorized_withdrawer: Pubkey,

    /// REMOVED
    /// commission: u8,

    /// NEW: the collector accounts for validator income
    pub inflation_rewards_collector: Pubkey,
    pub block_revenue_collector: Pubkey,

    /// NEW: basis points (0-10,000) that represent how much of each income
    /// source should be given to this VoteAccount
    pub inflation_rewards_commission_bps: u16,
    pub block_revenue_commission_bps: u16,

    /// NEW: reward amount pending distribution to stake delegators
    pub pending_delegator_rewards: u64,

    /// NEW: compressed bls pubkey for alpenglow
    pub bls_pubkey_compressed: Option<[u8; 48]>

    pub votes: VecDeque<LandedVote>,
    pub root_slot: Option<Slot>,

    /// UPDATED: serialization structure of the AuthorizedVoters map is
    /// unchanged but will now contain entries for the previous epoch.
    pub authorized_voters: AuthorizedVoters,

    /// REMOVED
    /// prior_voters: CircBuf<(Pubkey, Epoch, Epoch)>,

    pub epoch_credits: Vec<(Epoch, u64, u64)>,
    pub last_timestamp: BlockTimestamp,
}

作为此次更新的一部分,佣金值将以基点存储。但 Vote Program 中现有的 UpdateCommission 指令仅支持整数百分比形式的佣金值。在 SIMD-0291:以基点表示佣金率获采纳前,佣金率仍将限制为整数百分比,因此目前的佣金计算应继续使用整数百分比值。

读取投票状态的现有工具或程序(包括质押程序)将更新,以支持新版投票账户。

延迟佣金更新

对验证者运营者而言,第二项重要的功能门控更新是 SIMD-0249:延迟佣金更新。此项变更允许验证者随时提交佣金更新,同时确保更新至少经过一个完整 epoch 后才会生效。

投票程序将移除现有的限制,即不再禁止在 epoch 前半段提高佣金。协议不再限制提交佣金变更的时间,而是要求变更延迟生效。这意味着验证者可以自由调整佣金率,但新费率至少要等待一个完整 epoch 后才能生效。

这种延迟机制也有利于质押委托人,让他们能提前一个完整 epoch 得知即将发生的佣金变更并作出反应。更重要的是,它能阻止“佣金跑路”:恶意验证者会在 epoch 边界前不久将佣金临时提高到 100% 以攫取奖励,随后又迅速恢复正常水平。

降低状态保证金(租金)

高额状态保证金要求通常被称为“租金”,仍是制约 Solana 开发者长期扩展能力的最重要因素之一。如今,主网上的状态保证金十分昂贵,每 GB 存储空间的成本约为 100 万美元。例如,创建一个新的代币账户(ATA)需要略高于 0.002 SOL,按当前价格计算约为 0.25 美元。这使大规模直接代币空投的成本高得难以承受,也为小额支付和稳定币支付应用带来阻力;这些应用要么必须补贴代币账户创建成本,要么将其转嫁给最终用户。

减轻这一负担的第一步是 SIMD-0194:弃用免租阈值,计划在 Agave 3.1 发布周期内激活。这标志着更广泛行动的开始,目标是大幅降低并简化存储成本,让应用能够扩展至数百万用户,而无需承担高昂的状态相关资金要求。此外,目前还有三项 SIMD 正在推进,将直接解决状态保证金成本并进一步降低租金。

SIMD-0194 简化了未来的租金更新。目前,对链上程序而言,计算账户是否免租的成本相对较高。现有的 `Rent::minimum_balance` 计算使用浮点(f64)运算,每次调用大约消耗 256 个计算单元。SIMD-0194 从免租逻辑中移除浮点运算后,这一开销将降至仅 8 CU。

这一改进通过弃用 exempt_threshold(f64)字段实现,从而不再需要程序执行浮点计算来判断免租状态。

作为变更的一部分,lamports_per_byte_year 将重命名为 lamports_per_byte,默认值从 3480 翻倍至 6960,以反映免租条件在历史上一直被定义为持有相当于两年租金的金额。需要强调的是,此次更新不会改变账户达到免租条件所需的金额,只会简化并标准化该值的表示和计算方式。

此次更新完全向后兼容,不会影响已部署的现有程序。

展望未来:SIMD-0437

在预计今年晚些时候推出的其他租金相关 SIMD 中,最重要的是 SIMD-0437:逐步将 `lamports_per_byte` 降至 696。该提案制定了一套结构化时间表,通过逐步将 `lamports_per_byte` 从 6960 降至 696,使长期状态保证金成本降低 10 倍。

SIMD-0437 取代了此前的 SIMD-0436,后者提议一次性降低 50%。SIMD-0437 则引入更细化的五步下调计划:6333 → 5080 → 2575 → 1322 → 696。

将变更划分为多个阶段,既能让网络持续观察和评估状态增长,也能将最具争议的降幅拆分为不同步骤,以便开展更清晰的讨论和治理。

Agave 3.1 发布周期的其他重要更新

严格执行 32 个数据 shred 和 32 个编码 shred

目前,Turbine 接受每个 FEC 集包含数量不定的 shred。这种行为增加了不必要的复杂度,却没有带来实质性收益。验证 shred 索引会变得更加困难,因为接收方需要通过编码 shred 来确定索引边界。即将激活的 SIMD-0317:强制使用 32 个数据 shred + 32 个编码 shred功能门控将统一这一行为,要求每个 FEC 集必须包含正好 32 个数据 shred 和 32 个编码 shred。此项变更还会增强对双重签名的检测能力,为今后实施罚没处罚等执行机制提供依据。

静态指令限制

目前,包含超过 64 条顶层指令的交易可以通过初始净化检查,但会在运行时失败。这会让注定失败的交易进入流水线并消耗调度器资源,造成不必要的调度工作。

即将激活的 SIMD-0160:静态指令限制功能门控通过在交易净化阶段强制执行 64 条指令的上限来解决这一问题。变更后,任何超过 64 条顶层指令(包括 CPI 调用)的交易都无法通过净化,并会被立即拒绝。

减少 Turbine ChaCha 轮数

SIMD-0332:将 Turbine 的 ChaCha 轮数从 20 减至 8为 Turbine 的区块数据传播能力带来幅度不大但意义明确的性能改进。目前,Turbine 在构建区块传播树时使用 ChaCha20 对按质押权重排列的验证者进行确定性洗牌。这种随机排序对于防止审查攻击非常重要,但也会增加计算开销。

ChaCha 轮次相当于确定性扰乱器,每一轮都会应用变换,让输出更加随机。更多轮次可提供更强的密码学安全性,但也会增加计算成本。

随着 Agave 转向 XDP,重传发送几乎可以瞬间完成,这意味着加权洗牌步骤如今占据了大部分运行时间。每个 shred 大约需要 ~1 微秒,将洗牌算法从 ChaCha20 调整为 ChaCha8,既能让流程保持足够的随机性以抵御审查,又能避免其成为瓶颈。

新增指令数据指针

目前,sBPF 程序必须解析序列化输入区域中的账户部分,才能定位指令数据。由于序列化布局将账户置于指令数据之前,程序必须遍历所有账户条目后才能到达指令数据段。这会给主要(或完全)处理指令数据的程序增加不必要的工作。

即将激活的 SIMD-0321:VM 寄存器 2 指令数据指针功能门控通过在程序入口点的 VM 寄存器 r2 中提供一个指向指令数据的 64 位指针来改进这一点。该指针直接引用输入区域中指令数据部分的起始位置,让程序无需先解析账户部分,即可立即访问指令数据。这样可消除解析开销,减少计算单元消耗。

**兼容性说明:**此功能仅对目前不会在入口点读取 r2 的程序向后兼容。任何错误依赖入口点 r2 中原有未初始化值或垃圾值的程序,都会在此功能激活后出错。

RPC 改进

当提供格式错误的过滤器时,getProgramAccounts RPC 端点现在会返回正确的 JSON-RPC 错误。此前,无效过滤器会被静默忽略,导致 RPC 调用回退为未过滤查询,经常意外触发高成本请求,并给 RPC 节点带来不必要的负载。经过此次改进,错误过滤器将返回清晰的错误,避免意外执行资源密集型查询,并显著简化调试。

此外,simulateTransaction() 和 sendTransaction() 预检阶段中的签名验证失败,现在会通过模拟结果的 err 字段返回 TransactionError::SignatureFailure,而不再作为 JSON-RPC API 错误(-32003)抛出。

因此,此前依赖捕获 JSON-RPC 异常来处理签名验证失败的应用,现在应改为直接从模拟响应中获取这些错误。已经在模拟结果中具体化并处理 TransactionError 值的应用,现在可以预期在这些验证点收到 TransactionError::SignatureFailure。

总结

Agave v3.1 是一次重要的客户端升级,带来多项性能提升和优化,包括降低磁盘 I/O、加快交易处理,以及改进 RPC 错误处理。Agave 在网络加固方面取得了显著进展,在对抗性条件下具备更强的韧性。此版本也标志着大幅降低状态保证金的第一步。

Anza 继续展现其差异化优势:它是业内唯一一个在整个技术栈中持续交付改进的核心开发团队,甚至包括向 Linux 内核提交补丁。随着 Agave 3.1 即将为网络提供支持,Solana 持续证明自身的扩展能力。

展望未来,下一个里程碑是 Agave 4.0 和 Alpenglow 测试网的上线,目前计划于 5 月初推出。

更多资源

订阅 Helius

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

放大图片