大多数人测 Solana 交易延迟的方式,是给 sendTransaction 这个调用计时。那个数字告诉你的是"RPC 用了多久说收到了",几乎完全不能说明交易什么时候落块。
两者可以差好几个 slot,而钱就是在这个差里丢的。
是四段,不是一个数字
大家嘴里的"延迟",其实是四件事叠在一起:
① 构造与签名 本地,亚毫秒
② 你的进程 → RPC 一次网络往返
③ RPC → 出块方 你看不见
④ 被收录进区块 取决于费用和竞争
给 sendTransaction 计时,测的是第 2 段,然后就停了。★slot 是在第 3、4 段累积的,而这两段都不出现在你的客户端指标里。★
这就是为什么一个机器人可以报告很低的平均延迟,却稳定地在价格已经跑掉之后才到。
唯一真正重要的测量
从提交到收录之间的 slot 距离。 其它一切都是代理指标。
const submitSlot = await connection.getSlot("processed");
const sig = await connection.sendRawTransaction(raw, {
skipPreflight: true,
maxRetries: 0,
});
// 之后,等它落块:
const status = await connection.getSignatureStatuses([sig], {
searchTransactionHistory: true,
});
const landSlot = status.value[0]?.slot;
log({
sig,
submitSlot,
landSlot,
slotGap: landSlot ? landSlot - submitSlot : null, // null = 从未上链
});
★之所以用 slot 距离,是因为这才是链真正在意的单位。★ 毫秒描述的是你的网络状况,slot 描述的是你的结果。
要跟踪分布,不是平均值。一个"平均两个 slot"的系统,如果由一半 1 个、一半 3 个组成,和一个稳定落在 2 个的系统完全不是一回事。
如果你已经测过、而 slot 差就是问题所在,免费领个 BoltTx key 改一行就能拿来做对比。
给每一段埋点
当总耗时不理想时,分段计时能告诉你该看哪里。大多数团队只测总数,然后只能靠猜。
const t0 = performance.now();
const { blockhash, lastValidBlockHeight } =
await connection.getLatestBlockhash("confirmed");
const t1 = performance.now();
const tx = buildAndSign(blockhash);
const t2 = performance.now();
const sig = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: true,
maxRetries: 0,
});
const t3 = performance.now();
log({
blockhashFetch: t1 - t0, // 第 2 段,入站
buildAndSign: t2 - t1, // 第 1 段
submitCall: t3 - t2, // 第 2 段,出站
blockhashAge: t3 - t1, // ★有效期已经被花掉多少★
});
blockhashAge 是几乎没人跟踪、但最该跟踪的一个:它是交易还没到 RPC 就已经消耗掉的那部分有效期。这个值大的话,你真实的重试预算比你以为的短很多。
平均值为什么会骗人
Solana 上的延迟分布不是对称的。大多数交易紧紧聚在一起,少数明显更慢。平均值落在两者之间,哪一个都不描述。
如果你的策略机会窗口只有一两个 slot,★你活在慢的那一小撮里,不在平均值上★ —— 因为慢的情况和拥堵相关,而拥堵又和值得交易的时刻相关。
这也是为什么服务商之间的延迟对比常常没什么信息量。轻负载时所有路径表现都差不多;差别出现在区块空间被抢的时候,而一个在安静下午跑的基准测试恰好捕捉不到它。
连接复用是白捡的延迟
第 2 段里有一件完全归你控制、却经常被忽略的事。
每笔交易都新建 TLS 连接,意味着在字节真正开始传之前要先完成一次完整握手。在复用连接上这笔开销直接消失,而且热连接上 HTTPS 的成本和纯 HTTP 基本一样。
import { Agent } from "undici";
// 让连接在多次发送之间保持热的,而不是每次都重新握手。
const agent = new Agent({
keepAliveTimeout: 60_000,
connections: 8,
});
对持续发送的机器人来说,★这是你在每一笔交易上都在白付的延迟★,而且毫无必要。
上链应该是什么水平
我们投递节点上的真实交易:中位确认 336 毫秒 —— 不到一个 slot。
如果你自己的分布明显比这个宽,差距在第 3 段或第 4 段 —— 路由或费用 —— 而不在你的代码里。
修延迟,按这个顺序
从上往下走。前面几项很便宜,而且能解释大部分情况。
复用连接。 免费、立竿见影,而且往往是第 2 段里最大的单项收益。
后台刷新 blockhash。 用时才取会在热路径上加一次往返。改成缓存 + 定时刷新。
打开 skipPreflight。 preflight 要花一次往返,而且模拟的是你不会落进去的那个 slot —— 它可能通过了却什么都没告诉你。
按实时行情算 priority fee。 写死的值两个方向都错:清闲时浪费,竞争时不够。
然后才看提交路径。 如果上面四项都干净、而 slot 差在高负载下仍然拉大,剩下的就是通往出块方的那条路,以及它背后的质押权重。
★最后这一项是唯一没法在应用层代码里修的★,所以它应该排在末尾而不是开头。
BoltTx 在这里的位置
我们做的是第 3 段。不做索引,不做解析历史,不做 NFT 元数据。
提交走我们自建的四区域投递节点,带 SWQoS 路由,不暴露公共 mempool —— 交易在落块之前,传输途中观察不到。你在本地签名,我们不托管资金、不代签、不修改交易内容。
tip 带在交易里,从你自己的钱包链上支付。交易 revert 的话 tip 跟着一起 revert —— 这是 Solana 原子交易的机制决定的。只有到达链上的交易才计费。
免费领 API key,没有月费:
// 选离你机器人最近的区域
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");
接上之后记录一周的 slot 距离,对比分布而不是平均值。
常见问题
Solana 交易延迟指什么? 从提交一笔签好名的交易,到它被收录进区块之间的时间。通常用 slot 距离而不是毫秒来衡量,因为 slot 才是链真正用来排程的单位。
Solana 交易延迟该怎么正确测量?
记录提交时的 slot 和落块时的 slot,然后跟踪差值。给 sendTransaction 计时只测了到你 RPC 的往返,而那只是四段中的一段。
为什么我的 RPC 延迟很低,交易还是慢? 因为 RPC 延迟测的是你到端点的往返,不是之后发生的事。向出块方转发、以及等待被收录,是客户端计时永远看不到的另外两段。
Solana 交易的 slot 距离多少算好? 对延迟敏感的业务来说,两个 slot 内落块是个合理目标。但一致性更重要 —— 一个紧凑的分布胜过一个带长尾的低平均值。
为什么要看分布而不是平均值? 因为 Solana 的延迟分布是偏斜的。大多数交易聚在一起,少数慢很多,而慢的那些和拥堵相关。如果你的机会窗口很短,你活在慢的那一小撮里,不在平均值上。
连接复用真的能降延迟吗? 能,而且可测量。新建 TLS 连接要先完成完整握手,交易字节才开始传。复用连接上这笔开销没了,而且 HTTPS 和纯 HTTP 成本基本一致。
blockhash age 是什么,为什么重要? 它是你的交易到达 RPC 之前,那个约 150 个区块的有效期已经被消耗掉多少。值很大意味着你真实的重试预算比想象中短得多。
该用 skipPreflight 来降延迟吗? 生产环境的发送方通常该用。preflight 要花一次网络往返,而且模拟的是当前 slot 而不是你会落进去的那个 —— 它花了时间,却预测不了你的结果。
为什么拥堵时延迟会变差? 区块空间被抢、priority fee 上涨、提交路径上任何薄弱环节都不再隐形。而且延迟不是均匀变差的 —— 分布是被拉开,不是整体平移。
怎么对比两家 RPC 的延迟? 交替往两边发交易,按网络状况分桶,对比 slot 距离的分布。在清闲时段跑的对比,测的是"所有路径都一样"的那种情况。
延迟和上链率哪个更重要? 它们是同一个测量的两种看法。一笔花了太多 slot 的交易,最终会因为 blockhash 过期而根本不上链。跟踪 slot 距离,并把"从未上链"当成同一个分布的尾部。
独占节点能降低交易延迟吗? 它能改善第 2 段,因为去掉了共享容量的排队。但改变不了第 3 段 —— 那里验证节点接不接收取决于质押权重,而不是这个节点是不是你独占的。
有什么工具能测 Solana 交易延迟? 除了你自己的日志,不需要别的。每笔记录提交 slot、落块 slot、blockhash age,然后聚合。第三方基准测的是别人的网络位置,不是你的。
为什么我测出的延迟和服务商公布的数字不一样? 公布的数字通常是在一台位置很好的测试机上、在平常状况下测的往返。你的数字包含了你自己的地理位置、你的连接处理方式、以及你实际在其中交易的那种拥堵。
地理位置对 Solana 交易延迟影响大吗? 对延迟敏感的业务来说足够大。网络往返往往是你能直接控制的最大一项,所以提交到就近端点,通常比微优化代码收益更大。