背景
当交易上链后,需要websocket尽快订阅到新发起的交易信息,但已有逻辑有2s左右延迟
目前逻辑
{
"jsonrpc": "2.0",
"id": 1,
"method": "blockSubscribe",
"params": [
{ },
{ "commitment": "finalized" }
]
}
当前测试环境为私有网络,且仅有一个Validator
优化延迟
优化链路
- 原有链路:监听服务 -> WAF -> RPC -> Validator
- 压缩链路
- 监听服务 -> RPC -> Validator
- 去除WAF防护过程造成的延迟
- 保留RPC对Validator压力防护
- 监听服务 -> Validator
- 在1的基础上去除RPC同步Validator区块的时间
- 在链路路径上,为最短路径,只适合核心私有服务,时间优先
阶段测试结果
结果:链路优化后,延迟优化效果不明显
排除:排除WAF设置或防护逻辑,以及RPC同步相关对websocket的影响
修改参数
修改blockSubscribe.commitment 参数
测试结果
| 测试参数 |
最大延迟 |
概率 |
备注 |
| blockSubscribe (confirmed) |
< 1s |
95% |
满足实时需求 |
| blockSubscribe (finalized) |
~ 2s |
均值 |
|
RPC节点需开启 --rpc-pubsub-enable-block-subscription
总结:当blockSubscribe.commitment 为confirmed时,满足实时性需求
下面继续做具体分析,以及安全性确认
整体分析
commitment
Solana 分别引入了 processed、confirmed 和 finalized 三种 commitment
| Commitment 等级 |
状态说明 |
是否可能回滚 |
用途 |
processed |
当前 leader 节点已执行交易(未确认) |
可能被 fork |
快速响应 |
confirmed |
超过 1 个 superminority(2/3 vote)节点已投票确认 |
小概率回滚(如果 fork 被重组) |
较安全且快速 |
finalized |
已不可逆地写入链上(root slot) |
永不回滚 |
最终状态 |
安全分析
confirmed 还可能丢弃?
Solana 是基于 Turbine + Tower BFT 共识 的区块链,允许 fork 存在,直到达成“supermajority lockout”:
举个例子:
- Leader A 在 slot 100 产出 block1,包含你的交易 tx1
- 多数 validator 已投票确认 →
tx1 达到 confirmed
- 但 Leader B 在 slot 100 提出了 fork block2(没有 tx1)
- 网络切换了分叉,block2 成为主链,block1 被丢弃
- 最终你会看到 tx1 消失
这种情况虽然极少发生(除非网络分叉非常激烈),但确实有可能,尤其在以下情况下:
- 网络波动严重(多个 validator 未及时同步)
- 特别是在 devnet/testnet 上更常见
- 冲突交易竞争激烈(如套利机器人密集交易)
单一Validator
结论:如果整个网络只有一个 validator,交易一旦被执行(即 processed),就等同于 finalized,不会被回滚或丢弃
原因:Solana 的分叉和回滚机制依赖于 多个 validator 的投票(tower consensus),但如果你只有一个 validator 节点(如私链或测试环境):
- 所有交易处理都只走 一个 chain path
- 没有投票机制(自己 vote 自己)
- 没有 fork、没有分歧
- 所有被处理的 block/slot 会直接成为 root → 立即 finalized
延迟分析
问题:在只有一个 Validator 的 Solana 网络中,为什么交易已经 confirmed,但还没有立即 finalized?不是说没有其他节点就没有分叉吗?
原因:因为 finalized 状态取决于 root slot 的推进,而 root slot 的推进有“延迟”或“惰性机制”,即使只有一个 validator。
Solana 的 finalized 并不是单纯根据是否有分叉来判断,而是依赖一个特殊机制:
Tower BFT + Root Slot 推进规则:
- 每个 validator 会有自己的 "lockout" 投票历史,形成“投票树”
- 当 validator 在连续的 slot 上投票到一定深度,就能推进 root slot
- 只有 root 之后的 slot 才会被标记为
finalized
即使只有一个 validator:
- 它仍然要投票 → 进入 lockout(自己 vote 自己)
- 它仍然需要满足 一定的 slot 深度 才能将旧 slot 设为 root
- root slot 推进后,对应的交易和 block 才被认为是
finalized
为什么存在“延迟 finalized”?
| 机制 |
描述 |
| lockout period |
Tower BFT 规定,validator 必须投票到一定深度才可推进 root |
| skip slot 会阻碍 |
如果出现 skipped slot(空块),会延迟 root 推进 |
| 安全考虑 |
即使是单节点,仍沿用同样安全逻辑,避免不同部署模式产生不一致行为 |
举例
假设你只有一个 validator,slot 时间 400ms:
- 你在 slot 100 发出一笔交易
- 交易执行完成 →
processed
- 自己投票确认该 block →
confirmed
- 继续生产 slot 101、102...
- 到 slot 104 时,系统满足 root 推进条件,slot 100 被设为 root → 现在它才是
finalized
所以即使没有其他 validator,finalized 仍然比 confirmed 晚 2~4 个 slot(~1.5 秒)
最终总结
- 通过blockSubscribe (confirmed) 满足业务实时性要求
- 单一Validator,通过订阅confirmed,不存在安全性问题