FULL v0、Cursor、Manus、Same.dev、Lovable、Devin、Replit Agent、Windsurf Agent、VSCode Agent、Dia Browser、Trae AI 和 Cluely(以及其他开源)系统提示、工具和 AI 模型。
github: https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools
FULL v0、Cursor、Manus、Same.dev、Lovable、Devin、Replit Agent、Windsurf Agent、VSCode Agent、Dia Browser、Trae AI 和 Cluely(以及其他开源)系统提示、工具和 AI 模型。
github: https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools
当交易上链后,需要websocket尽快订阅到新发起的交易信息,但已有逻辑有2s左右延迟
{
"jsonrpc": "2.0",
"id": 1,
"method": "blockSubscribe",
"params": [
{ },
{ "commitment": "finalized" }
]
}
当前测试环境为私有网络,且仅有一个Validator
结果:链路优化后,延迟优化效果不明显
排除:排除WAF设置或防护逻辑,以及RPC同步相关对websocket的影响
修改blockSubscribe.commitment 参数
| 测试参数 | 最大延迟 | 概率 | 备注 |
|---|---|---|---|
| blockSubscribe (confirmed) | < 1s | 95% | 满足实时需求 |
| blockSubscribe (finalized) | ~ 2s | 均值 |
RPC节点需开启
--rpc-pubsub-enable-block-subscription
总结:当blockSubscribe.commitment 为confirmed时,满足实时性需求
下面继续做具体分析,以及安全性确认
Solana 分别引入了 processed、confirmed 和 finalized 三种 commitment
| Commitment 等级 | 状态说明 | 是否可能回滚 | 用途 |
|---|---|---|---|
processed |
当前 leader 节点已执行交易(未确认) | 可能被 fork | 快速响应 |
confirmed |
超过 1 个 superminority(2/3 vote)节点已投票确认 | 小概率回滚(如果 fork 被重组) | 较安全且快速 |
finalized |
已不可逆地写入链上(root slot) | 永不回滚 | 最终状态 |
Solana 是基于 Turbine + Tower BFT 共识 的区块链,允许 fork 存在,直到达成“supermajority lockout”:
tx1 达到 confirmed这种情况虽然极少发生(除非网络分叉非常激烈),但确实有可能,尤其在以下情况下:
结论:如果整个网络只有一个 validator,交易一旦被执行(即 processed),就等同于 finalized,不会被回滚或丢弃
原因:Solana 的分叉和回滚机制依赖于 多个 validator 的投票(tower consensus),但如果你只有一个 validator 节点(如私链或测试环境):
问题:在只有一个 Validator 的 Solana 网络中,为什么交易已经 confirmed,但还没有立即 finalized?不是说没有其他节点就没有分叉吗?
原因:因为 finalized 状态取决于 root slot 的推进,而 root slot 的推进有“延迟”或“惰性机制”,即使只有一个 validator。
Solana 的 finalized 并不是单纯根据是否有分叉来判断,而是依赖一个特殊机制:
finalizedfinalized| 机制 | 描述 |
|---|---|
| lockout period | Tower BFT 规定,validator 必须投票到一定深度才可推进 root |
| skip slot 会阻碍 | 如果出现 skipped slot(空块),会延迟 root 推进 |
| 安全考虑 | 即使是单节点,仍沿用同样安全逻辑,避免不同部署模式产生不一致行为 |
假设你只有一个 validator,slot 时间 400ms:
processedconfirmedfinalized所以即使没有其他 validator,
finalized仍然比confirmed晚 2~4 个 slot(~1.5 秒)



填入私有链对应的RPC,链ID 随意 (对于Solana链没有链ID,这里只是为了与EVM链类型共用布局)

只做演示,BCSkill 技术社区未对外提供私有Solana链支持

然后回到资产展示,选择新添加的网络即可

不要直接从 系统设置->节点列表->选择Solana->添加自定义节点
这里的添加只能添加Solana官方的节点,添加时会通过RPC 获取getGenesisHash,得到创世hash并与Solana 官方devnet testnet mainnet 进行比对,如果不一致则报错。
应该先添加完自定义网络后,再给自定义网络添加自定义节点

Solana构建发起交易时,返回错误
(*jsonrpc.RPCError)(0xc00739b530)({
Code: (int) -32602,
Message: (string) (len=122) "base64 encoded solana_sdk::transaction::versioned::VersionedTransaction too large: 1668 bytes (max: encoded/raw 1644/1232)",
Data: (interface {}) <nil>
})
交易的大小超过1232 字节限制
static_assertions::const_assert_eq!(PACKET_DATA_SIZE, 1232);
/// Maximum over-the-wire size of a Transaction
/// 1280 是 IPv6 最小 MTU
/// 40 字节是 IPv6 报头的大小
/// 8 字节是分片报头的大小
pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8;
PACKET_DATA_SIZE 硬编码,不可配置,为保障节点间数据传输的稳定和安全性
拆分交易,将多个逻辑拆分到多笔交易
比如想基于Solana运行一个Layer2网络或者应用链,需要尽可能的加快出块时间{从综合测试和其它类似项目综合分析,50ms是最快最稳定的},
如果单一的降低出块时间,会导致 recent_blockhash过期时间变短,从而可能导致交易发送时容易报 “Blockhash not found”
下面我们将给出如何实现50ms的slot,并保持recent_blockhash过期时间(120s)不变的方案
agave\sdk\program\src\clock.rs
/// 每秒 tick 数:PoH 产生 tick 的速度(原为 160)
pub const DEFAULT_TICKS_PER_SECOND: u64 = 1000; // 1000 ticks = 1秒
/// 每 slot 包含 tick 数(原为 64)
pub const DEFAULT_TICKS_PER_SLOT: u64 = 50; // 50 ticks = 1 slot
/// blockhash 最大有效时间(保持主网一致)
pub const MAX_HASH_AGE_IN_SECONDS: u64 = 120; // blockhash 有效时间 120秒
Solana 会自动计算:
pub const MAX_RECENT_BLOCKHASHES: usize =
MAX_HASH_AGE_IN_SECONDS * DEFAULT_TICKS_PER_SECOND as usize / DEFAULT_TICKS_PER_SLOT as usize;
// => 2400
这是因为你想要 每个 slot 时间为 50ms,而官方默认是 400ms,两者时间差 8 倍。
MAX_RECENT_BLOCKHASHES 调整到 2400| 参数 | 数值 |
|---|---|
| MAX_HASH_AGE_IN_SECONDS | 120 s |
| DEFAULT_TICKS_PER_SECOND | 160 |
| DEFAULT_TICKS_PER_SLOT | 64 |
| MAX_RECENT_BLOCKHASHES | 300 |
计算:

意味着最近 120 秒内链上大约有 300 个 slot(因为每 slot 约 0.4 秒)。
50ms = 0.05秒,等于官方 0.4秒的 18\frac{1}{8}81。
在 120 秒内,会有:

blockhash 有效时间不变你必须保存最近 2400 个 blockhash(对应 2400 个 slot),才能覆盖 120 秒内所有 slot。
MAX_RECENT_BLOCKHASHES = MAX_HASH_AGE_IN_SECONDS * DEFAULT_TICKS_PER_SECOND / DEFAULT_TICKS_PER_SLOT
现在参数改成:
计算:

| 每 slot 时间 | slot 数(120秒内) | 需保存最近 blockhash 数量 MAX_RECENT_BLOCKHASHES |
|---|---|---|
| 400ms | 300 | 300 |
| 50ms | 2400 | 2400 |
所以,MAX_RECENT_BLOCKHASHES 调整为 2400 是为了匹配新的更快 slot 频率,保证 blockhash 在 120 秒内仍有效
对于初始化时也需要对应的加入启动参数
--ticks-per-slot 50
#!/bin/bash
RPC_URL="https://api.mainnet-beta.solana.com"
# Step 1: 获取最新 blockhash
echo "Fetching latest blockhash..."
RESPONSE=$(curl -s -X POST $RPC_URL \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getLatestBlockhash"}')
BLOCKHASH=$(echo $RESPONSE | jq -r '.result.value.blockhash')
echo " Got blockhash: $BLOCKHASH"
echo " Starting to monitor validity..."
SECONDS_ELAPSED=0
INTERVAL=1 # 每次检测间隔,单位秒
while true; do
VALID_RESPONSE=$(curl -s -X POST $RPC_URL \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"isBlockhashValid\",\"params\":[\"$BLOCKHASH\"]}")
IS_VALID=$(echo $VALID_RESPONSE | jq -r '.result.value')
if [ "$IS_VALID" = "true" ]; then
echo "[$SECONDS_ELAPSED s] Blockhash still valid"
sleep $INTERVAL
SECONDS_ELAPSED=$((SECONDS_ELAPSED + INTERVAL))
else
echo "[$SECONDS_ELAPSED s] Blockhash EXPIRED"
break
fi
done
echo " Total validity duration: $SECONDS_ELAPSED seconds"