# 用Aptos源或Docker来搭建全节点

你可以跑一个自己的全节点，来同步Aptos区块链，并且保持最新状态。通过请求其他Aptos全节点和验证节点，全节点能够复制整体区块链状态。

另外，你也可以使用Aptos Labs提供的全节点。不过这类全节点会有频率限制，可能影响到你的开发。维护一个自己的全节点，可以直接同步Aptos区块链，避免这种频率限制。

任何人都可以搭建全节点。本教程讲解了如何配置一个公共全节点，从而连接到Aptos开发网络。

{% hint style="info" %}
💡 Tips：

你的公共全节点，通过本地电脑localhost:8080端口可访问的REST端点，来连接到Aptos开发网。
{% endhint %}

## 在你开始之前

在你开始本教程之前，阅读下列章节：

* 验证节点的概念
* 全节点的概念
* REST规范

## 硬件要求

我们推荐如下硬件配置：

* 搭建一个生产等级的全节点：
  * CPU：4核 (Intel Xeon Skylake或更新)
  * 内存：8GB RAM
* 搭建一个开发或测试用的全节点：
  * CPU：双核
  * 内存：4GB RAM

## 存储要求

Aptos存储的数据量，取决于区块链账本历史（长度）以及链上状态的数量（例如账户）。这些值取决于若干因素，包括：区块链历史，平均交易频次和账本修剪者

{% hint style="info" %}
考虑到开发网络每周会进行重置，预计Aptos不会需要几个G级别的存储量。参见Aptos Discord上的#devnet-release频道
{% endhint %}

## 配置一个全节点

你可以选择下面两种方式中的一种，来配置公共全节点：

1. 通过源代码来搭建和运行[aptos-core](https://github.com/aptos-labs/aptos-core)
2. 使用Docker

## 方法一：通过源代码来搭建和运行[aptos-core](https://github.com/aptos-labs/aptos-core)

1. 克隆Aptos仓库

```
git clone <https://github.com/aptos-labs/aptos-core.git>
```

1.  通过`cd` 来进入 `aptos-core` 文件夹

    ```
    cd aptos-core
    ```
2.  执行下方所示的 `scripts/dev_setup.sh` Bash 脚本，来准备开发环境

    ```
    ./scripts/dev_setup.sh
    ```
3.  更新你的shell环境

    ```
    source ~/.cargo/env
    ```

开发环境准备好之后，就可以开始设置全节点了。

1. 执行`git checkout --track origin/devnet`来检查`devnet` 分支
2. 确保当前工作文件夹为 `aptos-core`. 执行`cp config/src/config/test_data/public_full_node.yaml fullnode.yaml` 来创建全节点配置模板的副本。需要编辑这个文档，来确保全节点：
   * 包含Aptos开发网络所发布正确的创世部分
   * 通过开发网络发布的检查点文档`waypoint.txt`，来正确同步开发网络，并且，
   * 在你的本地机器上，保存开发网络数据库。
3. 确保当前工作文件夹为 `aptos-core`. Aptos开发网络发布了`genesis.blob`和`waypoint.txt` ，完成下载：
   *   点击下载[genesis](https://devnet.aptoslabs.com/genesis.blob)，或者在终端执行下方命令：

       ```
       curl -O <https://devnet.aptoslabs.com/genesis.blob>
       ```
   *   点击下载[waypoint](https://devnet.aptoslabs.com/waypoint.txt)并保存，或者在终端执行下方命令：

       ```
       curl -O <https://devnet.aptoslabs.com/waypoint.txt>
       ```
4. 如下，在当前工作文件夹，编辑`fullnode.yaml`文件
   *   在`fullnode.yaml`中编辑`base.waypoint.from_file`，明确指定刚才下载的`waypoint.txt` 路径。默认路径为当前工作文件夹。例如：

       ```
       base:
         waypoint:
           from_file: "./waypoint.txt"
       ```
   *   对于`genesis_file_location` 字段，提供`genesis.blob` 文件的全路径作为值。例如：

       ```
       genesis_file_location: "./genesis.blob"
       ```
   *   对于`base`中的`data_dir`字段，明确指定你想要在本地存储开发网络数据库的文件夹，可以是你本地的任意地方。例如，你可以在主目录中创建一个名为`my-full-node/data`的文件夹，按如下声明：

       ```
       data_dir: "/path/to/my/homedir/my-full-node/data"
       ```
5.  执行下方命令，开始运行你的本地全节点：

    ```
    cargo run -p aptos-node --release -- -f ./fullnode.yaml
    ```

现在你已经成功配置，并开始运行一个连接到Aptos开发网络的全节点。

{% hint style="info" %}
&#x20;这个过程将创建一个二进制发布的版本：&#x20;

`aptos-core/target/release/aptos-node` . 这个版本将在本质上快于debug binaries，但缺少对于开发有用的debug信息。为了建立一个debug binary，忽略`--release`
{% endhint %}

## 方法二：使用Docker

这部分讲解如何使用Docker来搭建和运行全节点。

通过Docker来运行Aptos-core，目前仅支持X86-64型CPU，不支持ARM64（包括使用M1/M2的Mac电脑）。

目前只发布了支持X86-64型CPU的Docker镜像。如果你使用M1/M2(ARM64)型的Mac电脑，请使用方法一。如果对于M1/M2型Mac电脑的支持对你来说很重要，可以留言并关注这个话题：[https://github.com/aptos-labs/aptos-core/issues/1412](https://github.com/aptos-labs/aptos-core/issues/1412)

1. 安装[Docker](https://docs.docker.com/get-docker/)
2.  为你本地的公共关节点创建一个文件夹，并使用`cd`命令进入，例如：

    ```
    mkdir aptos-fullnode && cd aptos-fullnode
    ```
3.  执行下列脚本，准备配置和开发网络的数据文件夹

    ```
    mkdir data && \\
    curl -O <https://raw.githubusercontent.com/aptos-labs/aptos-core/devnet/config/src/config/test_data/public_full_node.yaml> && \\
    curl -O <https://devnet.aptoslabs.com/waypoint.txt> && \\
    curl -O <https://devnet.aptoslabs.com/genesis.blob>
    ```
4.  最终，通过Docker开启全节点：

    ```
    mkdir data && \\
    curl -O <https://raw.githubusercontent.com/aptos-labs/aptos-core/devnet/config/src/config/test_data/public_full_node.yaml> && \\
    curl -O <https://devnet.aptoslabs.com/waypoint.txt> && \\
    curl -O <https://devnet.aptoslabs.com/genesis.blob>
    ```

确保你已经打开了相关的端口：8080, 9101 和 6180，并且可能需要在public\_full\_node.yaml中更新 127.0.0.1为0.0.0.0，作为 listen\_address 和 api\address

## 验证全节点的正确性

### 验证初次同步

在首次同步全节点的过程中，可能有大量数据需要传递。通过请求metrics端口，来查看节点目前的版本，你可以监控整个进度。执行下列代码来查看节点同步的版本。

```
curl 127.0.0.1:9101/metrics 2> /dev/null | grep "aptos_state_sync_version{.*\\"synced\\"}" | awk '{print $2}'
```

这行命令会输出当前你的节点所同步的版本。例如：

```
$ 71000
```

将这个版本（例如`71000`）和在[Aptos status page](https://status.devnet.aptos.dev/)中显示的当前最新版本`Current Version`进行比较。 如果你的节点和当前版本一致，说明同步正确。

{% hint style="info" %}
💡 提示

状态页面的版本和本地版本有一定差异也属于正常情况，因为状态页面并不会自动刷新。
{% endhint %}

### （可选）验证外部网络连接

作为一个可选项，你可以检查外部网络连接。与外部网络连接的数量，需要大于`0`，执行下列代码：

```
curl 127.0.0.1:9101/metrics 2> /dev/null | grep "aptos_connections{direction=\\"outbound\\""
```

命令将输出节点与外界网络连接的数量，例如：

```
$ curl 127.0.0.1:9101/metrics 2> /dev/null | grep "aptos_connections{direction=\\"outbound\\""
aptos_connections{direction="outbound",network_id="Public",peer_id="aabd651f",role_type="full_node"} 3
```

如果与外部网络连接数量为 `0`, 说明你的节点没有连接到Aptos区块链。执行下列步骤来解决这个问题：

1. 按照升级指南，把节点更新至最新版本。
2. 删掉可能添加在`public_full_node.yaml`配置文档中的任意`seed` peers，这些种子可能阻碍网络连接。Seed peers 在[Add upstream seed peers](https://aptos.dev/nodes/full-node/fullnode-source-code-or-docker#add-upstream-seed-peers) 章节中会详细讨论。

### （可选）检查Docker的账本大小

可以通过输入Docker的容器ID，来监控和检查Aptos开发网络的区块链账本大小。这样也可以了解目前区块链账本消耗了多少存储空间。

* 首先，在终端执行`docker container ls`，并且复制所输出的NAME字段，一个类似`public_full_node_fullnode_1`的字符串。
* 接着，执行下列命令来检查账本占用的存储空间大小，在`public_full_node_fullnode_1`使用复制的NAME字段。

```
# Obtain the container ID:
id=$(docker container ls | grep public_full_node_fullnode_1 | grep -oE "^[0-9a-zA-Z]+")
# Enter the container:
docker exec -it $id /bin/bash
# Observe the volume (ledger) size:
du -cs -BM /opt/aptos/data
```

### 增加上游种子peer

{% hint style="info" %}
&#x20;💡 TIP&#x20;

你可能在节点的错误信息中看到`NoAvailablePeers`，如果节点是第一次启动，那么这属于正常情况。等待节点运行几分钟后，看是否连接到peers，如果没有，按下列操作执行：
{% endhint %}

开发网络验证全节点，有一个最大连接数的限制。如果Aptos开发网络经历了大容量的网络连接，全节点有可能连接不上，并在节点错误信息中持续提示 `NoAvailablePeers`。如果遇到这个情况，可以从全节点配置文档 `public_full_node.yaml`中的`seeds`key手动增加peer地址，来使得你的全节点连接到特定的seed peer。

在下方查看可以在`public_full_node.yaml`中连接的seed peer地址。

{% hint style="info" %}
💡 TIP&#x20;

你也可以使用Aptos社区提供的全节点地址。任何已经跑通的全节点都可以提供自己的地址以供连接。查看Aptos Discord中的`#advertise-full-nodes`来获取更多信息
{% endhint %}

```
...
full_node_networks:
    - discovery_method: "onchain"
      # The network must have a listen address to specify protocols. This runs it locally to
      # prevent remote, incoming connections.
      listen_address: ...
      seeds:
        bb14af025d226288a3488b4433cf5cb54d6a710365a2d95ac6ffbd9b9198a86a:
            addresses:
            - "/dns4/pfn0.node.devnet.aptoslabs.com/tcp/6182/noise-ik/bb14af025d226288a3488b4433cf5cb54d6a710365a2d95ac6ffbd9b9198a86a/handshake/0"
            role: "Upstream"
        7fe8523388084607cdf78ff40e3e717652173b436ae1809df4a5fcfc67f8fc61:
            addresses:
            - "/dns4/pfn1.node.devnet.aptoslabs.com/tcp/6182/noise-ik/7fe8523388084607cdf78ff40e3e717652173b436ae1809df4a5fcfc67f8fc61/handshake/0"
            role: "Upstream"
        f6b135a59591677afc98168791551a0a476222516fdc55869d2b649c614d965b:
            addresses:
            - "/dns4/pfn2.node.devnet.aptoslabs.com/tcp/6182/noise-ik/f6b135a59591677afc98168791551a0a476222516fdc55869d2b649c614d965b/handshake/0"
            role: "Upstream"
...
```
