Solana优先费不是“实际用了多少Compute Unit就付多少”。它按交易请求的CU limit和每CU价格计算,因此把limit设得远高于实际消耗,会为未使用的计算预算付优先费。
费用公式先写清单位
总费用由基础费和优先费组成。当前官方费用结构以每个签名的基础费为起点;优先费公式是:
优先费(lamports)= ceil(CU price(micro-lamports/CU)× CU limit ÷ 1,000,000)
CU price通过SetComputeUnitPrice设置,CU limit通过SetComputeUnitLimit设置。价格为0时没有优先费;limit不是越大越容易成功,它只限定最多可消耗计算并参与费用计算。
用模拟确定limit
构造与正式交易相同的指令和账户,先给模拟足够高但合法的CU limit,调用simulateTransaction读取unitsConsumed。再增加一小段业务安全余量,得到正式limit。若指令参数、账户数量或Token扩展变化,应重新模拟,不能永久缓存某个值。
| 设置问题 | 结果 | 排查 |
|---|---|---|
| limit低于实际消耗 | Compute Budget exceeded | 看模拟unitsConsumed与日志 |
| limit远高于需要 | 优先费多付 | 缩小余量重新估算 |
| price过低 | 拥堵时调度靠后 | 查询近期本地费用市场 |
| price很高但账户冲突 | 仍可能延迟或失败 | 检查写锁与交易状态 |
price从哪里来
优先费市场与交易要写入的账户有关,不能只取一个全网固定数。客户端可查询近期优先费样本或可靠服务的局部市场数据,再按目标确认速度选择百分位。对不紧急交易,应设置费用上限;对紧急交易,也要防止异常样本把price推到不可接受值。
基础费和优先费怎样分配
官方当前规则中,基础费按协议比例销毁并奖励出块验证者,优先费进入验证者奖励。协议参数可能随网络升级变化,因此页面应注明读取日期,钱包不要把分配比例写死进费用计算逻辑。
发送前的完整流程
先构造消息并模拟CU;再设置limit;获取与写账户相关的价格建议并设置price;调用getFeeForMessage核对最终消息费用;确认fee payer余额;发送后读取签名状态。交易失败通常仍会收取费用,不能把优先费当成功保险。
价格与上限是两个不同参数
ComputeBudgetProgram可设置compute unit limit和每个CU的micro-lamports价格。优先费大致按请求的CU上限乘价格计算,因此把limit盲目设得很高,即使实际没用满,也可能按较高请求值付费。合理做法是先模拟得到consumed units,加有限余量,再结合近期可写账户竞争情况选择价格。
RPC的优先费建议只能反映其观察窗口,不能保证下一leader接受。应用应记录模拟时slot、建议来源、最终费用和确认slot,连续失败时重新获取blockhash与费用,而不是只把价格翻倍。对不紧急交易还应提供等待与取消重签的选择。
模拟与发送差异见Solana交易模拟,slot和block height语义见Solana时间单位,PDA账户写锁与签名边界可参考Solana PDA。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。