> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 完整重放

完整重放(Full Replay)允许节点通过简单地获取并按顺序重放错过的区块来追赶进度。这对于希望生成所有中间状态和交易产物的节点很有帮助。例如,一个 RPC 提供者可能会想要这样做,以确保它可以对被跳过的区块响应 `eth_call`、`eth_getBalance` 或 `eth_estimateGas` 等请求。

## 背景

尚未本地执行过 `forkpoint.root - delay` 区块的节点将在启动时进行 statesync(参见 [forkpoint 启动同步](/zh/monad-arch/consensus/forkpoint#startup-sync))。此外,节点不会响应超过 statesync\_threshold(600)个区块之前的 blocksync 请求。Statesync 是节点在协议内恢复的唯一方式。

本文档描述了一种*备选*方式来恢复节点,同时在节点停机时间超过 blocksync 提供窗口(600 个区块)的情况下回填历史状态。

请注意,如果 `node.toml` 中的 `statesync_threshold` 设置为一个更大的值,blocksync 将失败。

<Warning title="需要访问一个健康的节点">
  为了以完整的历史状态恢复故障节点,以下步骤*需要通过 SSH 访问在故障节点停机期间始终健康的节点*。

  设 `REMOTE_HOST` 为可用于恢复的健康节点。
</Warning>

## 步骤

1. 以 `monad` 用户身份 SSH 登录故障节点。
2. 确保 `node.toml` 中 `statesync_threshold = 600`

```bash theme={null}
$ grep statesync_threshold /home/monad/monad-bft/config/node.toml
statesync_threshold = 600
```

1. 停止 monad 服务

```bash theme={null}
sudo systemctl stop monad-bft monad-execution monad-rpc
```

1. 运行以下脚本以复制缺失的区块,然后执行到该点。您需要运行几次,因为在脚本执行期间链的最新高度会持续推进。

   1. 注意:在输出停止时,您需要手动中断进程(Ctrl - C)。

   2. 复制该脚本并命名为 `manual-sync.sh`

      ```bash theme={null}
      #!/usr/bin/env bash
      set -euo pipefail

      # Load config first so SSH_PORT, REMOTE_HOST, CHAIN etc are set
      source .env

      : "${SSH_PORT:?SSH_PORT must be set}"
      : "${REMOTE_HOST:?REMOTE_HOST must be set}"
      : "${CHAIN:?CHAIN must be set}"

      echo "Reading files from $REMOTE_HOST"
      echo "Using ssh port: $SSH_PORT"

      # Copy proposed and finalized header symlinks first
      rsync -avP -e "ssh -p $SSH_PORT" \
        "monad@$REMOTE_HOST:/home/monad/monad-bft/ledger/headers/*_head" \
        /home/monad/monad-bft/ledger/headers/

      # Copy new headers and bodies, but don't overwrite existing ones
      rsync -avP --ignore-existing -e "ssh -p $SSH_PORT" \
        "monad@$REMOTE_HOST:/home/monad/monad-bft/ledger/" \
        /home/monad/monad-bft/ledger/

      # Note: the --state-sync flag is NOT present
      /usr/local/bin/monad \
        --chain "$CHAIN" \
        --db /dev/triedb \
        --block_db /home/monad/monad-bft/ledger \
        --sq_thread_cpu 1 \
        --log_level INFO
      ```

   3. 运行脚本
      ```bash theme={null}
      REMOTE_HOST=node1.<provider>.com SSH_PORT=22 CHAIN=monad_mainnet bash manual-sync-step-1.sh
      ```

2. 一旦第一个脚本在 1 分钟内完成,运行以下脚本:

   1. 复制该脚本并命名为 `manual-sync-step-2.sh`
      ```bash theme={null}
      #!/usr/bin/env bash
      set -euo pipefail

      # Load config first so SSH_PORT, REMOTE_HOST, CHAIN etc are set
      source .env

      : "${SSH_PORT:?SSH_PORT must be set}"
      : "${REMOTE_HOST:?REMOTE_HOST must be set}"
      : "${CHAIN:?CHAIN must be set}"

      # Copy current forkpoint
      rsync -av -e "ssh -p $SSH_PORT" \
        "monad@$REMOTE_HOST:/home/monad/monad-bft/config/forkpoint/forkpoint.rlp" \
        /home/monad/monad-bft/config/forkpoint/
      rsync -av -e "ssh -p $SSH_PORT" \
        "monad@$REMOTE_HOST:/home/monad/monad-bft/config/forkpoint/forkpoint.toml" \
        /home/monad/monad-bft/config/forkpoint/forkpoint.toml
      rsync -av -e "ssh -p $SSH_PORT" \
        "monad@$REMOTE_HOST:/home/monad/monad-bft/config/validators/validators.toml" \
        /home/monad/monad-bft/config/validators/validators.toml

      systemctl start monad-bft monad-execution monad-rpc
      ```
   2. 运行脚本
      ```bash theme={null}
      REMOTE_HOST=node1.<provider>.com SSH_PORT=22 CHAIN=monad_mainnet bash manual-sync-step-2.sh
      ```

## 检查

要检查是否成功避开了 statesync,请对节点停机期间已终局化的区块发送 `eth_getBlockByNumber` RPC 请求。

```bash theme={null}
curl http://localhost:8080 \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0xdedbeef", false],"id":1}'
```
