关于 Steem 的 Checkpoint 功能

in #witness2 days ago (edited)

作用

在 checkpoint 之前的区块可以跳过某些验证(加速 replay)。

跳过的验证包括:

  • 见证人签名验证
  • 交易签名验证
  • 交易重复检查
  • 区块大小检查
  • TaPoS 检查
  • 权限检查
  • Undo history 检查
  • 见证人调度检查
  • 操作验证
  • 不变量验证

使用方法

steemd --checkpoint '[10000000,"0000000000000000000000000000000000000000"]' \
       --checkpoint '[20000000,"1111111111111111111111111111111111111111"]' \
       --replay-blockchain

上面的命令意思: 在 20000000 高度之前,跳过所有验证,但是在 10000000 和 20000000 要验证一下这两个高度的区块 ID。

设置多个 checkpoint 的好处是,如果有错误可以在最短的时间退出。

批量获取区块ID

#!/bin/bash

# 配置参数
RPC_URL="https://api.steem.fans"         # steemd RPC地址
START_BLOCK=10000000                    # 起始区块高度(1000万)
STEP=10000000                           # 步长(1000万)
TARGET_BLOCK=101683978                  # 目标区块高度
OUTPUT_FILE="block_id_list.txt"         # 原始结果文件
FINAL_CMD_FILE="steemd_replay_cmd.sh"   # 最终命令输出文件

# 清空文件
> "$OUTPUT_FILE"
> "$FINAL_CMD_FILE"

# 存储checkpoint的临时数组
checkpoints=()

# 打印脚本信息
echo "开始获取区块ID,起始高度: $START_BLOCK, 步长: $STEP, 目标高度: $TARGET_BLOCK"
echo "RPC地址: $RPC_URL"
echo "原始结果将保存到: $OUTPUT_FILE"
echo "最终steemd命令将保存到: $FINAL_CMD_FILE"
echo "========================================"

# 循环获取每个步长的区块ID
current_block=$START_BLOCK
while [ $current_block -le $TARGET_BLOCK ]; do
    # 构建JSON请求数据
    request_data=$(cat <<EOF
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "block_api.get_block",
  "params": {
    "block_num": $current_block
  }
}
EOF
    )

    # 发送RPC请求并获取响应(添加30秒超时,避免卡死)
    echo "正在获取区块高度 $current_block 的ID..."
    response=$(curl -s -m 30 -X POST "$RPC_URL" \
      -H "Content-Type: application/json" \
      -d "$request_data")

    # 检查curl请求是否成功
    if [ $? -ne 0 ]; then
        echo "错误: 连接RPC服务器失败 (区块高度: $current_block),可能是网络超时/服务不可用"
        block_id="获取失败"
        result="区块高度: $current_block | Block ID: $block_id"
    else
        # 解析block_id(兼容无数据/空值场景)
        block_id=$(echo "$response" | jq -r '.result.block?.block_id // "无数据"')
        if [ "$block_id" = "null" ] || [ "$block_id" = "" ]; then
            block_id="无数据"
        fi
        result="区块高度: $current_block | Block ID: $block_id"
        
        # 仅收集有效block_id(排除"无数据"/"获取失败")
        if [ "$block_id" != "无数据" ] && [ "$block_id" != "获取失败" ]; then
            checkpoints+=("[${current_block},\"${block_id}\"]")
        fi
    fi

    # 输出原始结果并写入文件
    echo "$result"
    echo "$result" >> "$OUTPUT_FILE"

    # 计算下一个区块高度
    current_block=$((current_block + STEP))

    # 延迟0.5秒,避免请求过快触发限流
    sleep 0.5
done

echo "========================================"
echo "获取完成!开始生成steemd命令..."

# 构建最终的steemd命令
cmd="steemd"
for checkpoint in "${checkpoints[@]}"; do
    cmd+=" --checkpoint '${checkpoint}'"
done
cmd+=" \\\n       --replay-blockchain"

# 格式化命令(添加换行和缩进)
formatted_cmd=$(echo -e "$cmd" | sed 's/ \\\n       / \\\n       /g')

# 输出到控制台
echo -e "\n生成的steemd命令:"
echo -e "$formatted_cmd"

# 写入命令文件(便于直接执行)
echo -e "#!/bin/bash\n" > "$FINAL_CMD_FILE"
echo -e "$formatted_cmd" >> "$FINAL_CMD_FILE"
chmod +x "$FINAL_CMD_FILE"

echo -e "\n所有结果:"
echo "1. 原始日志: $OUTPUT_FILE"
echo "2. 可执行命令文件: $FINAL_CMD_FILE"
echo "========================================"

运行上面的命令,最后可以得到每一千万块的高度的区块ID的最后执行命令。

steemd \
  --checkpoint '[10000000,"009896808b5ae162e14e64b1bf9552000d6f63ec"]' \
  --checkpoint '[20000000,"01312d0047be2e999509f9d7a84132e434d2e8bf"]' \
  --checkpoint '[30000000,"01c9c38015c03fb3e82802a5845816804074e0e2"]' \
  --checkpoint '[40000000,"02625a000d8be8b1085b94d25e0c20daf1e9be56"]' \
  --checkpoint '[50000000,"02faf080f4ce5ee4e5322eaaf61f55c4c61b37b1"]' \
  --checkpoint '[60000000,"0393870095e625e1b718a93f63d97c714577bc12"]' \
  --checkpoint '[70000000,"042c1d8095801ca478ce037246bb4a3c41801bcf"]' \
  --checkpoint '[80000000,"04c4b400197b3469dca15d8855aee13721b29165"]' \
  --checkpoint '[90000000,"055d4a80816c96d39bc1c59d5b980bf0d6a69489"]' \
  --checkpoint '[100000000,"05f5e1007b3ba475ae1c8dfaaa35306a174c96aa"]' \
  --replay-blockchain

同时可以得到一个记录文件:

区块高度: 10000000 | Block ID: 009896808b5ae162e14e64b1bf9552000d6f63ec
区块高度: 20000000 | Block ID: 01312d0047be2e999509f9d7a84132e434d2e8bf
区块高度: 30000000 | Block ID: 01c9c38015c03fb3e82802a5845816804074e0e2
区块高度: 40000000 | Block ID: 02625a000d8be8b1085b94d25e0c20daf1e9be56
区块高度: 50000000 | Block ID: 02faf080f4ce5ee4e5322eaaf61f55c4c61b37b1
区块高度: 60000000 | Block ID: 0393870095e625e1b718a93f63d97c714577bc12
区块高度: 70000000 | Block ID: 042c1d8095801ca478ce037246bb4a3c41801bcf
区块高度: 80000000 | Block ID: 04c4b400197b3469dca15d8855aee13721b29165
区块高度: 90000000 | Block ID: 055d4a80816c96d39bc1c59d5b980bf0d6a69489
区块高度: 100000000 | Block ID: 05f5e1007b3ba475ae1c8dfaaa35306a174c96aa
Sort:  

Upvoted! Thank you for supporting witness @jswit.

Thank you for sharing on steem! I'm witness fuli, and I've given you a free upvote. If you'd like to support me, please consider voting at https://steemitwallet.com/~witnesses 🌟

Great post! Featured in the hot section by @punicwax.