跳转到主要内容
本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
每笔 Solana 交易都会设置(隐式或显式)两个参数:计算单元限额(交易可消耗的最大计算单元,默认为 200,000 × 交易中指令数,但受每笔交易上限)和优先费用,单位为微拉波(micro-lamports)每计算单元。这两个参数设置不足都会导致交易失败——计算单元限额过低会引发 ProgramFailedToComplete;优先费用过低则交易会一直未确认直到过期。

两项设置

  • setComputeUnitLimit(units) — 限制计算资源消耗;交易最多支付 units 个计算单元。
  • setComputeUnitPrice(microLamports) — 优先费用竞价,单位为微拉波每计算单元。总优先费用 = units × microLamports × 1e-6 拉波。
费用计算:250k 计算单元限额加上 50k 微拉波/计算单元的价格,优先费用为 250_000 × 50_000 / 1e6 = 12,500 拉波 ≈ 0.0000125 SOL ≈ $0.003(按 $200 SOL 价格)。在这个规模上,优先费用对于大多数用户交换是微不足道的,但对于每天执行 1000 笔交易的机器人来说则是显著成本。

每条指令的计算单元基准

基准数据来自主网执行日志,取多次运行的平均值。数字均为近似值(±15%);建议针对特定流程重新测量。 CLMM 中”tick 跨越”行数是最大的计算单元变量。如果你不知道交换会跨越多少个 tick,应按最坏情况预算——8 个跨越是硬上限(程序最多加载 8 个 tick 数组)。

组合交易

将各个指令的预算相加,再加上:
  • 每个 CPI 帧 +1,500 计算单元 — 运行时对每次跨程序调用的固定开销。
  • 每次创建 ATA +20,000 计算单元create_associated_token_account 并非免费。
  • setComputeUnitLimit / setComputeUnitPrice 各 +5,000 计算单元
示例:一笔创建输出 ATA 并包裹原生 SOL 的用户交换:
缓冲:将计算单元限额设置在预期用量的约 25% 以上。低估成本会导致整个交易失败;高估则只会按比例增加优先费用成本(优先费用 = units × microLamports,所以高出 25% 的预算就多花费 25% 的优先费用)。

优先费用估算

Solana 的本地费用市场意味着优先费用是按可写账户计算的。写入热账户(热门池状态)的交易费用高于写入冷账户的交易。全局费用水平不是 Raydium 交换的正确指标;你需要的是涉及的特定池的费用。

策略 1:RPC 提供商估算器

每个主要 RPC 提供商都发布优先费用估算器,可查询特定账户的最近费用:
大多数提供商的优先级划分:Min / Low / Medium / High / VeryHigh / UnsafeMax,映射到百分位数: 提供商:Helius(getPriorityFeeEstimate)、Triton(getRecentPrioritizationFees + 账户列表)、QuickNode(类似)。

策略 2:直接 RPC 查询

使用标准 getRecentPrioritizationFees RPC:
这是原生 Solana RPC 方法,适用于任何提供商。缺点:样本量小(150 个 slot ≈ 60 秒)且噪声大。为获得更平滑的估算,使用提供商的聚合服务。

策略 3:历史自调优

对于保持恒定流量的机器人,跟踪自身的成功率与过期率:
这种方式比公共估算器调整得更快,并捕捉公共估算器不一定能看到的按池结构。

处理计算单元耗尽失败

症状:交易失败,错误信息为 exceeded maximum number of instructions allowed (200000)ProgramFailedToComplete 诊断:
修复:
  1. 提升计算单元限额。 如果交易在 200k 预算中使用了 195k,提高到 300k。
  2. 分拆交易。 如果达到了 1.4M 的每笔交易上限,分成两笔交易。Farm 的「harvest 然后 stake」是经典的需要分拆的场景(当奖励较多时)。
  3. 精简账户。 每增加一个可写账户会增加约 2,000 计算单元。删除未使用的账户在边界情况下会有帮助。
  4. 使用查找表。 LUT 查找约 50 计算单元每解析地址,相比完整账户引用的 5,000 计算单元可节省成本。

处理卡住的交易

症状:交易已提交但从未确认,最终以 BlockhashNotFound 过期。 诊断:
  • getSignatureStatuses([sig]) 返回 null → 领导者从未看到。
  • 返回 { confirmationStatus: null } → 领导者看到但未纳入。
修复:
  1. 提升优先费用。 用 2 倍的当前费用重新提交。
  2. 用新的最近区块哈希重建。 区块哈希生命周期约 60 秒;超过这个时间交易不论费用多少都无效。
  3. 多 RPC 广播。 某些 RPC 与领导者的连接更好。并行提交到 3–5 个 RPC。
  4. 切换到 Jito 束。/zh/integration-guides/routing-and-mev。束绕过公共数据包队列。
重试逻辑框架:

在网络拥堵下

当网络拥堵时(Jupiter / Jito 束仪表板显示积压、RPC 延迟飙升、交易过期率攀升),调整: 监视拥堵信号:
  • 优先费用第 75 百分位 > 500k 微拉波:拥堵。
  • Jito 第 50 百分位小费 > 0.001 SOL:拥堵。
  • RPC 响应 p99 > 2 秒:RPC 特定问题或拥堵。

机器人费用预算

每天运行约 1000 笔交易的交易机器人需要优先费用预算。粗略估计:
这是最低限度。在拥堵期间,乘以 5–10 倍。对于稳定流量的机器人,计划约 $150–300/月 的优先费用成本。 必须在特定 slot 中落地的机器人(清算、套利)持续支付第 95 百分位费用,花费约 10 倍。在这个规模下,Jito 束小费占主导——通常 $1000+/月——但替代方案(被抢先或过期)更糟。

陷阱

1. 忘记设置计算单元限额

默认是 200k 计算单元 × (交易中的指令数)。单条指令交换默认 200k;这足以满足 SPL Token 的 CPMM,但不足以满足有 tick 跨越的 CLMM 或任何 Token-2022。务必显式设置。

2. 优先费用针对错误的账户

如果根据代币铸币厂估算优先费用,但热账户是池状态,估算就太低了。对于 Raydium,池状态是正确的可写账户目标。

3. 费用随计算单元限额缩放

total_priority_fee = units × microLamports。将 units 从 200k 提升到 1M(50k 微拉波/计算单元)会将优先费用乘以 5 倍。不要为了以防万一而过度预算计算单元;要测量。

4. 默认交易版本

Legacy 交易的账户限制较低;V0 交易配合地址查找表解锁更大的路由。SDK 默认在 txVersion: TxVersion.V0 中使用 V0。除非需要钱包兼容性,否则不要降低到 legacy。

5. skipPreflight 隐藏计算单元错误

skipPreflight: true 发送交易时不进行本地模拟。节省约 100 毫秒但失去了计算单元耗尽的早期反馈。仅在重试时使用,不要在首次尝试时使用。

参考资源

来源: