skipPreflight 是教程一笔带过、生产代码常搞错的 Solana 参数之一。默认 false、文档简短、影响要 debug 够多交易才理解。大多数生产代码该设 true——但值得知道什么时候和为什么。
这篇讲 preflight 在做什么、什么情况下该跳过、什么情况下不该、以及把这件事做对的生产模式。
Preflight 实际是什么
调 sendTransaction 时,RPC 有选项在转发给 validator 前模拟交易。这个模拟就是"preflight"。它对当前链状态跑交易、看会不会成功、只在会成功时转发给 validator。
// 默认:preflight 开
connection.sendTransaction(tx, signers);
// = sendTransaction(tx, signers, { skipPreflight: false })
// 跳过 preflight
connection.sendTransaction(tx, signers, { skipPreflight: true });
Preflight 开时:
- RPC 模拟交易
- 模拟失败 RPC 返回错误不转发
- 模拟成功 RPC 正常转发
- 模拟加延迟(一个额外 RPC 内部步骤)
Preflight 关时:
- RPC 立刻转发交易
- 失败(如有)在交易实际链上执行时被发现
- 延迟减少但你可能为失败的交易付费
什么时候 skipPreflight: true
生产交易发送代码,几乎总是。原因:
你已经客户端验证过。 代码知道交易 well-formed、知道账户存在、知道数学对、你不需要 RPC 重模拟。
延迟重要。 去掉模拟步骤从提交路径剃下毫秒。延迟敏感用例(套利机器人、sniper 机器人)这重要。
需要时能自己模拟。 开发期间可以显式调 simulateTransaction 测试。生产里跳过自动模拟。
Preflight 不总可靠。 快变网络里,模拟时状态和执行时状态不同。模拟通过不保证执行成功。
// 生产典型 sendTransaction 调用
const signature = await connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
preflightCommitment: "processed", // skipPreflight: true 时被忽略
});
什么时候保持 Preflight 开
Preflight 值得它延迟成本的情况:
发送你没验证过的用户提交交易。 钱包 UI 接受用户构造的交易;你不完全信任;preflight 抓明显失败。
开发和 debug。 开发期间 preflight 失败反馈有用。迭代时延迟不重要。
成本敏感的不频繁交易。 你一笔一笔提交、失败交易花有意义费用、preflight 在本会失败的情况省钱。
你不完全理解的程序。 调第三方程序不确定账户对、preflight 帮。
机器人或 app 发很多你控制的交易这种常见情况、没一个适用、你该跳过 preflight。
Preflight 抓到错误时发生什么
Preflight 失败长这样:
Error: failed to send transaction: Transaction simulation failed:
Error processing Instruction 0: custom program error: 0x1
交易没被转发。你不付费。能修了重提。
对比没 preflight 的失败情况:
// 你成功调了 sendTransaction
// Signature: 5Pp3...
// 然后查交易状态:
{
err: { InstructionError: [0, { Custom: 1 }] }
}
交易被转发、被块包含、执行期间失败。你为失败的交易付了费。签名存在但交易出错。
如果你从来不查结果,你会以为交易成功了。设了 skipPreflight: true 但没有配合正确的确认逻辑——这就是这一类用户经常翻车的失败模式。
配 skipPreflight: true 的确认模式
跳 preflight 必须确认交易实际结果。模式:
const signature = await connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
});
// 等确认
const result = await connection.confirmTransaction(
{ signature, ...latestBlockhash },
"confirmed"
);
if (result.value.err) {
// 交易上链但执行失败
console.error("交易失败:", result.value.err);
// 决定重试、告警等
} else {
// 交易成功
console.log("已确认:", signature);
}
确认步骤闭环。没它你在盲飞交易实际工作。
常见错误
开发者搞错的:
设 skipPreflight: true 不确认。 交易静默失败;机器人操作者几天没注意。
生产高频发送设 skipPreflight: false。 每次提交加延迟。浪费 RPC 容量。
用 preflight 替代客户端验证。 构建交易前验证。Preflight 不是马虎代码的安全网。
信任 preflight 成功是保证。 网络状态变。200ms 前过了 preflight 的交易实际执行时可能失败。
设 skipPreflight: true 但用 preflightCommitment。 preflightCommitment 在 skipPreflight: true 时被忽略。设错误默认但不破坏。
skipPreflight 什么时候省真钱
延迟敏感场景跳 preflight 的经济论证:
竞争套利场景里、50ms 提交延迟差能意味着上 slot N 还是 slot N+1 的差。Slot N+1 成交明显更差。跨多笔交易累积成真 P&L。
Preflight 加 round-trip 延迟(你客户端 → RPC → 模拟 → RPC → 转发)。高频操作者,这 round-trip 是盈利和不盈利的差。
权衡:你为本会失败的交易付费(preflight 本会抓的)。大多数机器人这是总费小百分比、延迟改善容易回收。
配 skipPreflight 的其他发送选项
跳 preflight 时也考虑:
maxRetries: 0。 别让 RPC 静默重试。自己用新 blockhash 管重试。
直接用 sendRawTransaction。 预序列化交易;省 RPC 里少量工作。
显式设 compute unit budget 和 price。 Preflight 抓 CU 不够;没 preflight 你只在交易链上失败时发现。
加遥测。 每笔签名级别的投递记录在不靠 preflight 反馈时变更重要。
const signature = await connection.sendRawTransaction(
tx.serialize(),
{
skipPreflight: true,
maxRetries: 0,
}
);
这周可以做什么
有生产代码:
- 审 sendTransaction 调用。 生产里传
skipPreflight: true吗?没的话为什么? - 核实你发送后确认。 没确认静默失败累积。
- 同时设 maxRetries: 0。 自己管重试。
- 设显式 CU 预算和 priority fee。 别让默认在 preflight 不抓时咬你。
- 检查模拟交易匹配实际交易。 开发时跑 simulate 然后 send 对比。抓 preflight-vs-execution 偏差。
- 加每笔签名级别的遥测。 跟踪每笔提交交易结果。
BoltTx 提供什么
BoltTx 为生产提交模式做:
- 亚秒级确认附一致尾部表现
- 每笔签名级别的投递遥测——精确看每笔交易发生什么、不需要 preflight
- 原生 Anti-MEV 路由默认
- 专属 SWQoS + 优先级连接,拥堵下也能保证上链
- Tip-based 计费——只为上链交易付费
import { Connection } from "@solana/web3.js";
const connection = new Connection(
"https://bolttx.io/?api-key=YOUR_API_KEY",
"processed"
);
const signature = await connection.sendTransaction(tx, signers, {
skipPreflight: true,
maxRetries: 0,
});
免费档注册。用真实负载带 skipPreflight: true 加正确确认跑一周对比上链率。
常见问题
总该设 skipPreflight: true 吗? 生产高频发送是。一次性用户交易或开发,false 行。
会浪费费用在失败交易上吗? 你交易能失败的话、可能。客户端验证最小化这个。
skipPreflight: true 影响链上结果吗? 不。只影响 RPC 转发前做什么。一旦转发交易要么方式都一样执行。
为什么 preflight 默认开如果生产更差? 默认保守——假设你可能提交失败的。生产代码通常知道得更好。
能按交易动态选 skipPreflight 吗? 能。参数是按调用的。用户提交交易能设 false、系统生成的设 true。