可否量化 SOL 网络拥堵的指标区调整优先费提高上链速度呢?判断 SOL 网络拥堵的指标,SOL 域名解析商 sns.id 网页上右上角显示 Congested network
, 从区块浏览器上看 TPS 普遍都有 4000+ 但 true TPS 真正属于用户交易的其实就只有几百 TPS,其余的 TPS 都是网络共识层投票等。
网络拥堵时,交易员/开发者/套利者等发出去的交易常常等很久都不上链,也听 space 上开发者抱怨交易很难上链或者优先费用卷的很高,如何利用优先费用 (priority fee)或者jito 小费 (jito tips)机制提高交易成功率和上链速度呢?
ComputeUnit 往后简称为 CU, sol 官方文档 how-to-use-priority-fees 中有个规则 2 的示例交易 (solscan)
文档说 set the Compute Unit Limit to 300 CUs while also adding a priority fee of 20000 micro-lamports
应该是这篇文章里面的 tx 太旧了,是以前验证者节点代码,最新的 agave 源码中如果是内置指令没有加 CUlimit 也会自动设置成 150, 第三方指令就 20 万
实际上这个交易忘了设置 CU limit 变成默认的 20 万 CU limit 每条指令 (最新验证者节点这个交易 CU limit 应该自动是 300 可能过于古老了) 所以收取了每笔交易基本费用,注意 CU price 单位是 micro lamports 要乘以 1e-6 转换成 SOL_lamports per CU 的量纲
5000 + (20000*1e-6 * 200000) = 9000 lamports SOL = 0.000009SOL
交易费用=5000lamports 基础费 + 账户租金费/开户费 + 优先费用,优先费用总值的竞价排名决定了交易在验证者出块的优先级
源码在 agave(solana 2.0 之后改名成 agave 项目继续维护了,原 github 地址不更新) 的 cost-model crate 中可以看到常量 DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT 就是 20 万
fn get_transaction_cost(
transaction: &impl TransactionWithMeta,
feature_set: &FeatureSet,
) -> (u64, u64, u64) {
let mut programs_execution_costs = 0u64;
let mut compute_unit_limit_is_set = false;
let mut has_user_space_instructions = false;
for (program_id, instruction) in transaction.program_instructions_iter() {
let ix_execution_cost =
if let Some(builtin_cost) = BUILTIN_INSTRUCTION_COSTS.get(program_id) {
*builtin_cost
} else {
has_user_space_instructions = true;
u64::from(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT)
};
programs_execution_costs = programs_execution_costs
.saturating_add(ix_execution_cost)
.min(u64::from(MAX_COMPUTE_UNIT_LIMIT));
if compute_budget::check_id(program_id) {
if let Ok(ComputeBudgetInstruction::SetComputeUnitLimit(_)) =
try_from_slice_unchecked(instruction.data)
再看一个同时设置了 CU price 和 limit 的例子:https://solscan.io/tx/BcBCS61y3GpYCHVzUZ3KK7v1M7PgYqNM8oyqx3oLq7XcxaYDW5SH1GQqvL5pkR91jypxh9sPDpztMby32oxEnre
agave 源码中 solana_compute_budget_program DEFAULT_COMPUTE_UNITS 是 150, 设置 CU limit/price和转账都是150
上述交易 CU limit 设置了 3000,交易有 2 个设置 CU 的指令和 18 次 SOL 转账的指令,加起来刚好是 (2+18)*150=3000 CU
10000*1e-6 * 3000 = 300 lamports
即便交易只用了 300CU 但设置了 20 万的 CU limit(如上述例子 1 的 tx), 也是按照 CU limit 20 万收取优先费用
所以交易中尽可能设置更低的 CU Limit,而且根据helius 文档 CULimit 越低的交易上链的优先级更大
常见的交易指令中消耗的 CU
像 jup swap 这样不确定的 CU 消耗 推荐用 simulate rpc 模拟执行获取 CU 消耗
原版 rpc 优先费 API 返回的是某个智能合约地址最近 150 区块交易中的最小值 (at least one successfully landed)
其实更推荐用 triton 增强型优先费 API 能查询到某智能合约最近大伙给的优先费的中位数
一般网络拥堵的时候我个人经验是 jupiter TURBO 等级的优先费用都要给到 0.2u~0.4u 不等
SOL 跟 EVM 不同的是,EVM 如果交易失败了 收取的是 gasPrice * gasUsed(实际消耗的 CU)
那么问题来了,对于一个预期利润是 10SOL 的套利交易,拿出了 80% 预期利润 8SOL 的优先费用贿赂矿工
但是交易因为滑点过大没抢单成功,交易失败了也要支付 8SOL 的优先费用,是非常昂贵的成本了
jito 的出现就解决了这个问题,jito 的交易不需要设置优先费用 CU price 的指令 (CU limit 还是建议要)
而是让交易最后加一个给 jito 8 个小费地址随机选一个转账的指令,为什么要随机选一个呢
如果大伙都往第一个小费地址打钱,8 个地址随机选一个可以提高吞吐量同时有 8 个 jito 小费指令可并行执行
所以发送给 jito 的交易失败发生回滚的话,最后一条小费指令不会执行,也就损失 5000lamports 的基础交易费用
很多 bot 的交易不直接发给 jito,而是通过 bloXroute 转发给 jito。因为 bloXroute 有一个 super bundle 的功能,能打包不冲突的交易,bundle 的 tip 也给的高,所以比直接发 jito 速度更快。
bloXroute 也是 jito 最大的合作伙伴之一,在 jito 那里有很高的账户等级;tip 给的高,只是快速上链的条件之一。其实还有其他一些基础设施上的配置,包括全球的节点布置,合作节点,网络拓扑优化等等
据说主要是交易机器人和一些 dex,做市商等采购 bloXroute 服务,我没用过就不评价了
§ 适用于 jito 加速交易的业务
笔者有次 LP 建仓发交易就说价格波动导致 tick 滑点变动交易失败,连续失败 4-5 次 每次亏损 0.4$的优先费用 如果用 jito 不断重试交易就不必亏这么多了
§ 适用于优先费用加速交易的业务
§ 既不要 jito 也不要优先费的业务
智能合约部署我的经验是推荐用 aws 免费节点+helius 免费 rpc 上传/部署智能合约
项目不急着上线失败就重试几次 (急的话 deploy 可加优先费用的命令行参数),失败的话会出现一些 program buffer 占用资金,稍后 solana program close 关掉后就能回收 SOL 了
由于 SOL 网络中当前 epoch POS 的 leader 顺序是确定的,也可以预测下个 leader 是 jito 的节点就给 jito 发交易,如果是 helius/triton 节点就用优先费给他们发
还有一种思路 nonceAccount 同时签名两个交易一个发 jito 一个发 helius,一个成功另一个自然因为 nonce 无效而失败
swqos 简单说就是质押量越大的验证者节点,在下个区块出块中能提交给 leader 节点的交易数更多,所以走质押量更大的节点 rpc 上链更快
听 solayer 在 space 说 要把 swqos 加速上链的机制做成 restaking 奖励,用户质押给项目方更多 SOL,项目的上链速度更快体验更好,项目方应该奖励给质押用户额外奖励这样的经济模型
swqos 节点基本是被 triton,helius 这样的大户厂商垄断了,quicknode 这样的知名厂商也没有,所以 solayer 能否打破这种垄断呢 (支持华语区项目打破垄断)
由于 triton 服务不对外公开销售了,所以也就只能用 helius 付费的 staked connection rpc 消耗的额度是普通 rpc 的 50 倍
由于 solana 网络拥堵时,发出去的交易可能被 rpc 节点丢弃没有发成功给 leader 节点了,或者等很久很久才上链,因此重试策略推荐阅读 triton 这篇文章 https://docs.triton.one/chains/solana/sending-txs
直到 http 轮询交易成功或者 ws 推送交易成功
由于笔者做的是套利业务对时效性要求极高 (行情过几秒后可能滑点巨大),所以我的做法是交易中插入一条超时 5s 指令
ws+http 轮询交易状态超过 5s 就认为是超时了,这样交易很久之后才上链会因为超时而失败