您正在查看: 2025年5月

Solana调整出块时间为50ms,并且保持recent_blockhash(120秒)过期时间不变

背景

比如想基于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

MAX_RECENT_BLOCKHASHES 为什么要 调整为 2400

这是因为你想要 每个 slot 时间为 50ms,而官方默认是 400ms,两者时间差 8 倍。

解释为什么需要把 MAX_RECENT_BLOCKHASHES 调整到 2400

1. 官方默认参数回顾:

参数 数值
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 秒)。


2. 你想改成 50ms/slot

50ms = 0.05秒,等于官方 0.4秒的 18\frac{1}{8}81。

在 120 秒内,会有:


3. 为了保持 blockhash 有效时间不变

你必须保存最近 2400 个 blockhash(对应 2400 个 slot),才能覆盖 120 秒内所有 slot。


4. 计算验证

MAX_RECENT_BLOCKHASHES = MAX_HASH_AGE_IN_SECONDS * DEFAULT_TICKS_PER_SECOND / DEFAULT_TICKS_PER_SLOT

现在参数改成:

  • MAX_HASH_AGE_IN_SECONDS = 120
  • DEFAULT_TICKS_PER_SECOND = 1000 (tick 速度提高了)
  • DEFAULT_TICKS_PER_SLOT = 50

计算:


总结

每 slot 时间 slot 数(120秒内) 需保存最近 blockhash 数量 MAX_RECENT_BLOCKHASHES
400ms 300 300
50ms 2400 2400

所以,MAX_RECENT_BLOCKHASHES 调整为 2400 是为了匹配新的更快 slot 频率,保证 blockhash 在 120 秒内仍有效

solana-genesis 初始化

对于初始化时也需要对应的加入启动参数

--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"

wsl: 无法配置 networkingMode Nat) (网络,回退到 networkingMode VirtioProxy。

1. 更新 WSL

wsl --update

2. 确保使用的是 WSL 2

wsl -l -v

如果显示为 WSL 1,可以通过以下方式转换:

wsl --set-version <发行版名称> 2

3. 启用相关功能

确保 Hyper-V 和虚拟机平台启用:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
dism.exe /online /enable-feature /featurename:Microsoft-Hyper-V-All /all /norestart

然后重启电脑。