> ## 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.

# 节点迁移(将全节点提升为验证者)

备份建议:
我们强烈建议备份所有验证者配置文件和密钥。这可确保在节点崩溃或意外故障时能够快速恢复。

有多种方式可以实现验证者节点的高可用。本文档专门提供了运行全节点并使用适当的配置文件和密钥将其提升为验证者的说明。

在计划内或计划外维护的情况下,验证者可以通过运行全节点以最小的停机时间迁移其节点密钥。该节点可以无缝转换为验证者,从而实现对共识的持续参与。

目前,停机会导致验证者及其委托人的奖励损失。但是,截至目前**链上尚未启用罚没(slashing)**。

按照以下步骤安全地迁移您的验证者角色,尽量减少停机时间,并维持网络健康。

## 前置条件

1. Monad 版本 >= `0.12.x`。
2. 验证者的 `id-secp` 和 `id-bls` 密钥。
3. 验证者的 `node.toml` 配置文件。
4. `.env` 文件中的 `KEYSTORE_PASSWORD` 值。

## 说明

1. 按照[全节点说明](/zh/node-ops/full-node-installation)将一个全节点同步到网络的最新高度。

2. 备份全节点上 `/home/monad/monad-bft/config` 目录下的现有配置文件,并将其移动到 `/opt/monad/backup`。
   * `/home/monad/monad-bft/config/node.toml`
   * `/home/monad/monad-bft/config/id-secp`
   * `/home/monad/monad-bft/config/id-bls`

3. 将验证者的 `id-secp`、`id-bls` 和 `node.toml` 复制到全节点上。

4. 在全节点上运行 `monad-sign-name-record` 实用程序,为新的 IP 地址生成一个名称记录签名。

```bash theme={null}
# Source the .env file to load the keystore password env variable
source /home/monad/.env
# Generate a name record and signature
monad-sign-name-record --ip $(curl -s4 ifconfig.me) \
--tcp-port 8000 \
--udp-port 8000 \
--node-config /home/monad/monad-bft/config/node.toml \
--authenticated-udp-port 8001 \
--self-record-seq-num 1 \
--keystore-path /home/monad/monad-bft/config/id-secp \
--password "$KEYSTORE_PASSWORD"
```

**示例输出:**

```bash theme={null}
self_address = "<IP>:8000"
self_record_seq_num = 1  # Incremented by 1 from the previous value
self_name_record_sig = "<HEX SIG>"
```

1. 在全节点上,用上述命令的输出(3 行)替换 `node.toml` 中的 `[peer_discovery]` 块。

<Info>
  * `self_record_seq_num` 每次节点执行迁移过程时都要递增。
  * 该值至关重要,因为它直接与 `self_name_record_sig` 关联,可确保节点身份在过渡期间的一致性和完整性。
</Info>

1. 如果原始验证者有(其他)与专用全节点相关的自定义配置,例如 `[[fullnode_dedicated.identities]]`,则需要将这些配置添加到全节点的 `node.toml` 中。为了保持与下游节点的连通性,所有下游对等节点必须在其 `node.toml` 配置中更新该验证者的名称记录。

2. 确保 `enable_publisher = true`、`enable_client = true` 且 `expand_to_group = true`。在 `expand_to_group = true` 模式下,全节点的支持依赖于全节点 `node.toml` 中指定的次要 raptorcast 对等节点。

3. 再次检查并确保将 **`beneficiary = `** 值从验证者的 `node.toml` 复制到了全节点的 `node.toml`。

4. 在验证者节点上,运行 `systemctl` 命令停止服务。

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

1. 验证验证者服务已停止。

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

1. 停止**全节点**服务,然后将其作为**验证者**重新启动。

```bash theme={null}
systemctl stop monad-bft monad-rpc monad-execution
sleep 1
systemctl start monad-bft monad-rpc monad-execution
```

1. 验证 systemd 服务正在运行:

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

# Check logs for each service
journalctl -fu monad-bft
journalctl -fu monad-execution
journalctl -fu monad-rpc
```

## 恢复原始验证者

如果您希望将原始验证者(A)恢复到其原有角色,您需要执行以下两种流程之一:

1. 重新同步 A - 这会因 statesync / blocksync 所需时间而产生一定的停机时间
   1. 将 B 节点的 `node.toml` 复制到 A 节点
   2. 在 A 上,使用节点 B 的 `node.toml` 并递增 `self_record_seq_num`,运行 `monad-sign-name-record`
   3. 更新 `node.toml` 中对应的两个字段
   4. 在临时验证者(B)上停止服务。
   5. 对 A 执行软重置或硬重置
2. 将 A 作为全节点运行,然后执行上述步骤
   1. 为 A 生成[新密钥](/zh/node-ops/full-node-installation#generate-keystores)
   2. 签署一个新的名称记录(参见上述说明)并[设置为专用节点](/zh/node-ops/full-node-installation)接入到某个验证者(例如您的临时验证者 B)
   3. 以角色互换的方式执行上述步骤。

<Warning title="节点名称管理">
  始终确保每个节点在各自的 `node.toml` 文件中保持不同的 `node_name` 值。

  * 如果节点 B 最初是一个 `node_name = "node_B"` 的全节点,当它回到全节点运行时应保留此名称
  * 节点 B 只应在迁移过程中临时使用节点 A 的 `node_name`
  * 恢复完成后,每个节点必须回到其原始 `node_name` 以避免冲突
</Warning>
