diff --git a/README.zh.md b/README.zh.md new file mode 100644 index 000000000..5876d05c0 --- /dev/null +++ b/README.zh.md @@ -0,0 +1,91 @@ +
+ + + + Open Mina 节点是一个用 Rust 实现的快速且安全的 Mina 协议实现 + + +![Beta][beta-badge] [![release-badge]][release-link] [![Changelog][changelog-badge]][changelog] [![Apache licensed]][Apache link] + +_**Open Mina 节点**是一个用 **Rust** 实现的快速且安全的 Mina 协议实现。_ +_目前处于**公开测试阶段**,加入我们的 [Discord 社区](https://discord.com/channels/484437221055922177/1290662938734231552)来帮助测试未来的版本。_ + +
+ +--- + +## 入门指南 + +### 从源码构建 + +- [Rust 节点](/docs/building-from-source-guide.md#how-to-build-and-launch-a-node-from-source) 和 [仪表盘](./docs/building-from-source-guide.md#how-to-launch-the-ui) + +### 通过 Docker 在开发网络运行节点 + +- [非出块节点](/docs/alpha-testing-guide.md) 连接到对等节点并在开发网络上同步节点;无需开发网络权益。 +- [出块节点](/docs/block-producer-guide.md) 在开发网络上产生区块;需要足够的开发网络权益。 +- [本地出块演示](/docs/local-demo-guide.md) 在自定义本地链上产生区块,无需开发网络权益。 + +区块生产节点界面 + +--- + +## 发布流程 + +**本项目处于测试阶段**。我们保持每月发布周期,[每月提供更新](https://github.com/openmina/openmina/releases)。 + +## 核心功能 + +- **Mina 网络**:连接对等节点、同步、广播消息 +- **区块生产**:根据 Mina 共识生产、验证和应用区块 +- **SNARK 生成**:为交易生成 SNARK 证明 +- **调试**:使用归档节点数据的区块重放器 + +## 仓库结构 + +- [core/](core) - 提供需要在节点不同组件之间共享的基本类型 +- [ledger/](ledger) - Rust 实现的 Mina 账本 +- [snark/](snark) - Snark/证明验证 +- [p2p/](p2p) - OpenMina 节点的 P2p 实现 +- [node/](node) - 组合节点的所有业务逻辑 + - [native/](node/native) - 节点的操作系统特定部分,用于在本地运行节点(Linux/Mac/Windows) + - [testing/](node/testing) - OpenMina 节点的测试框架 +- [cli/](cli) - OpenMina 命令行工具 +- [frontend/](frontend) - OpenMina 前端 + +## Open Mina 文档 + +### 什么是 Open Mina? + +- [为什么我们要开发 Open Mina](docs/why-openmina.zh.md) + +### 核心组件 + +- [P2P 通信](https://github.com/openmina/openmina/blob/documentation/docs/p2p_service.md) + - [GossipSub](https://github.com/openmina/mina-wiki/blob/3ea9041e52fb2e606918f6c60bd3a32b8652f016/p2p/mina-gossip.md) +- [扫描状态](docs/scan-state.md) +- [SNARKs](docs/snark-work.md) + +### 开发者工具 + +- [前端](./docs/building-from-source-guide.md#how-to-launch-the-ui) + +### Mina 测试框架 + +- [完整测试文档](docs/testing/testing.md) + +### 如何运行 + +- [非出块节点](./docs/alpha-testing-guide.md) +- [出块节点](./docs/block-producer-guide.md) +- [本地出块演示](./docs/local-demo-guide.md) + +[changelog]: ./CHANGELOG.md +[beta-badge]: https://img.shields.io/badge/status-beta-yellow +[changelog-badge]: https://img.shields.io/badge/changelog-Changelog-%23E05735 +[release-badge]: https://img.shields.io/github/v/release/openmina/openmina +[release-link]: https://github.com/openmina/openmina/releases/latest +[Apache licensed]: https://img.shields.io/badge/license-Apache_2.0-blue.svg +[Apache link]: https://github.com/openmina/openmina/blob/master/LICENSE diff --git a/docs/alpha-testing-guide.zh.md b/docs/alpha-testing-guide.zh.md new file mode 100644 index 000000000..c7db0d261 --- /dev/null +++ b/docs/alpha-testing-guide.zh.md @@ -0,0 +1,77 @@ +# 在开发网络上运行非出块节点 + +本指南将指导您使用 Docker 在开发网络上运行 **Alpha Rust 节点**。按照以下步骤设置节点并为这个 Alpha 版本[提供反馈](#4-提供反馈)。 + +## 1. 前置要求 + +确保您已安装 **Docker**: + +- [Linux、macOS 和 Windows 的 Docker 安装指南](./docker-installation.md) + +## 2. 下载并启动节点 + +1. **下载最新版本**: + + - 访问 [Open Mina 发布页面](https://github.com/openmina/openmina/releases) + - 下载最新的 `openmina-vX.Y.Z-docker-compose.zip` + +2. **解压文件**: + + ```bash + unzip openmina-vX.Y.Z-docker-compose.zip + cd openmina-vX.Y.Z-docker-compose + ``` + + 额外的可选参数: + + `OPENMINA_LIBP2P_EXTERNAL_IP` 设置您节点的外部 IP 地址,以帮助其他节点找到它。 + + `OPENMINA_LIBP2P_PORT` 设置 Libp2p 通信的端口。 + +3. **在开发网络上启动节点并保存日志**: + 启动节点并保存日志以供后续分析: + + ```bash + docker compose up --pull always && docker compose logs > openmina-node.log + ``` + +4. **访问仪表板**: + 在浏览器中打开 `http://localhost:8070`。 + + 仪表板将实时显示同步过程。 + image + + > **1. 连接节点:** 节点与其他对等节点建立连接。您将看到已连接、正在连接和断开连接的节点数量增长。 + > + > **2. 获取账本:** 节点下载关键数据:权益账本、下一轮账本和已验证账本。进度条显示下载状态。 + > + > **3. 获取并应用区块:** 节点下载最近的区块以匹配网络的当前状态。仪表板跟踪已获取和应用的区块数量。 + +## 3. 监控和故障排除 + +### 检查保存的日志 + +如果您已将日志保存到文件中,可以使用 tail 或类似工具查看: + +```bash +tail -f openmina-node.log +``` + +### 重启节点: + +如果节点无响应或无法启动,请重启设置: + +```bash +docker compose down +docker compose up --pull always +``` + +## 4. 提供反馈 + +此 Alpha 版本用于测试目的。您的反馈至关重要。按照以下步骤报告任何问题: + +1. **收集日志**:使用[上述命令保存日志](#2-下载并启动节点) +2. **访问 Discord**:[Open Mina Discord 频道](https://discord.com/channels/484437221055922177/1290662938734231552/1290667779317305354) +3. **描述问题**:简要说明问题和重现步骤 +4. **附上日志**:Discord 允许上传最大 25MB 的文件。如果您的日志更大,请使用 Google Drive 或类似服务 +5. **包含截图**:仪表板截图提供了节点状态的详细信息,便于诊断问题 diff --git a/docs/block-producer-guide.zh.md b/docs/block-producer-guide.zh.md new file mode 100644 index 000000000..cae531976 --- /dev/null +++ b/docs/block-producer-guide.zh.md @@ -0,0 +1,62 @@ +# 在开发网络上运行区块生产节点 + +本指南仅适用于在 **Mina 开发网络** 上设置区块生产节点。 +在完成必要的安全审计之前,请勿将本指南用于 Mina 主网。 + +--- + +## 前置要求 + +确保您的系统已安装 Docker 和 Docker Compose - [Docker 安装指南](./docker-installation.zh.md) + +## 下载并启动节点 + +1. **下载最新版本** + +- 访问 [Open Mina 发布页面](https://github.com/openmina/openmina/releases) +- 下载最新的 `openmina-vX.Y.Z-docker-compose.zip` +- 解压文件: + + ```bash + unzip openmina-vX.Y.Z-docker-compose.zip + cd openmina-vX.Y.Z-docker-compose + mkdir openmina-workdir + ``` + +2. **准备密钥** + + [Docker Compose](../docker-compose.block-producer.yml) 引用 `openmina-workdir`。它存储区块生产所需的私钥和日志。 + 将您的区块生产者私钥放入 `openmina-workdir` 目录并命名为 `producer-key`: + + ```bash + cp /path/to/your/private_key openmina-workdir/producer-key + ``` + + 将 `/path/to/your/private_key` 替换为您私钥文件的实际路径。 + +3. **启动区块生产者** + + 使用 `MINA_PRIVKEY_PASS` 设置私钥密码。可选择使用 `COINBASE_RECEIVER` 设置不同的币基接收地址: + + ```bash + env COINBASE_RECEIVER="您的钱包地址" MINA_PRIVKEY_PASS="您的密码" \ + docker compose -f docker-compose.block-producer.yml up -d --pull always + ``` + + 可选参数: + + `OPENMINA_LIBP2P_EXTERNAL_IP` 设置您节点的外部 IP 地址,以帮助其他节点找到它。 + + `OPENMINA_LIBP2P_PORT` 设置 Libp2p 通信的端口。 + +4. **访问仪表盘** + + 访问 [http://localhost:8070](http://localhost:8070) 来[监控同步状态](http://localhost:8070/dashboard)和[区块生产](http://localhost:8070/block-production)。 + +### 访问日志 + +日志存储在 `openmina-workdir` 中,文件名格式如 `openmina.log.2024-10-14`、`openmina.log.2024-10-15` 等。 + +### 提供反馈 + +收集 `openmina-workdir` 中的日志,并在 [rust-node-testing](https://discord.com/channels/484437221055922177/1290662938734231552) Discord 频道报告问题。如果可能,请包含复现步骤。 diff --git a/docs/building-from-source-guide.zh.md b/docs/building-from-source-guide.zh.md new file mode 100644 index 000000000..9ef33a6a5 --- /dev/null +++ b/docs/building-from-source-guide.zh.md @@ -0,0 +1,100 @@ +# 如何从源码构建和启动节点 + +本安装指南已在 Debian 和 Ubuntu 系统上测试过,应该适用于大多数 Linux 发行版。 + +## 前置要求 + +Ubuntu 或基于 Debian 的 Linux 发行版,需要安装以下软件包: + +- `curl` +- `git` +- `libssl-dev` +- `pkg-config` +- `protobuf-compiler` +- `build-essential` + +示例(基于 debian): + +```sh +# 使用 "sudo" 或以 "root" 用户身份运行 +sudo apt install curl git libssl-dev pkg-config protobuf-compiler build-essential +``` + +示例(macOS): + +如果您尚未安装 homebrew: + +```sh +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` + +```sh +brew install curl git openssl pkg-config protobuf gcc make +``` + +## 步骤(适用于基于 Debian 的 Linux 发行版和 macOS): + +打开命令行并输入以下命令: + +```sh +# 安装 rustup 并将默认 Rust 工具链设置为 1.80(更新版本也可以) +curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.80 +# 为当前 shell 配置 rustup +source "$HOME/.cargo/env" +# 克隆 openmina 仓库 +git clone https://github.com/openmina/openmina.git +cd openmina/ +# 构建并运行节点 +cargo run --release -p cli node +``` + +# 如何启动 UI: + +## 前置要求 + +### 1. Node.js v20.11.1 + +#### MacOS + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +brew install node@20.11.1 +``` + +#### Linux + +```bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash +source ~/.bashrc +nvm install 20.11.1 +``` + +#### Windows + +从官方网站下载 [Node.js v20.11.1](https://nodejs.org/),打开安装程序并按照提示完成安装。 + +### 2. Angular CLI v16.2.0 + +```bash +npm install -g @angular/cli@16.2.0 +``` + +### 3. 安装 + +打开终端并导航到项目根目录 + +```bash +cd PROJECT_LOCATION/openmina/frontend +``` + +安装依赖 + +```bash +npm install +``` + +## 运行应用 + +```bash +npm start +``` diff --git a/docs/docker-installation.zh.md b/docs/docker-installation.zh.md new file mode 100644 index 000000000..74b943564 --- /dev/null +++ b/docs/docker-installation.zh.md @@ -0,0 +1,65 @@ +# Docker 安装指南 + +## 适用于以下系统的安装指南 + +- [基于 Debian 的 Linux 系统](#基于-debian-的-linux-系统安装-docker) +- [Windows 系统](#windows-系统安装-docker) +- [macOS 系统](#macos-系统安装-docker) + +## 基于 Debian 的 Linux 系统安装 Docker + +1. 设置 Docker 的 apt 仓库: + + ```bash + # 添加 Docker 的官方 GPG 密钥: + sudo apt-get update + sudo apt-get install ca-certificates curl + sudo install -m 0755 -d /etc/apt/keyrings + sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + sudo chmod a+r /etc/apt/keyrings/docker.asc + + # 将仓库添加到 Apt 源: + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt-get update + ``` + +2. 安装 Docker 软件包: + + ```bash + sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + ``` + +3. 将当前用户添加到 `docker` 用户组: + + ```bash + sudo usermod -aG docker $USER + newgrp docker + ``` + +4. 验证安装: + + ```bash + docker run hello-world + ``` + +--- + +## Windows 系统安装 Docker + +1. 下载并安装 [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop/)。 + +2. 确保 Docker Desktop 正在运行(检查系统托盘图标)。 + +--- + +## macOS 系统安装 Docker + +1. 下载并安装 [Docker Desktop for Mac](https://www.docker.com/products/docker-desktop/)。 +2. 在终端中验证安装: + + ```bash + docker --version + ``` diff --git a/docs/local-demo-guide.zh.md b/docs/local-demo-guide.zh.md new file mode 100644 index 000000000..f05d1d720 --- /dev/null +++ b/docs/local-demo-guide.zh.md @@ -0,0 +1,56 @@ +# 在本地网络上运行区块生产者 + +在完成您操作系统的[前置要求](./docs/docker-installation.zh.md)后,请按照以下步骤操作: + +## 设置选项 1:从发布版本下载 Docker Compose 文件 + +1. **下载 Docker Compose 文件:** + + - 访问本仓库的[发布页面](https://github.com/openmina/openmina/releases) + - 下载最新的 `openmina-vX.Y.Z-docker-compose.zip`(或 `.tar.gz`)文件,对应发布版本(从 v0.8.0 版本开始提供) + +2. **解压文件:** + + - 解压下载的文件: + ```bash + unzip openmina-vX.Y.Z-docker-compose.zip + ``` + 或 + ```bash + tar -xzvf openmina-vX.Y.Z-docker-compose.tar.gz + ``` + - 将 `vX.Y.Z` 替换为您下载的实际发布版本号 + +3. **进入解压后的目录:** + ```bash + cd openmina-vX.Y.Z-docker-compose + ``` + +## 设置选项 2:克隆仓库 + +1. **克隆此仓库:** + + ```bash + git clone https://github.com/openmina/openmina.git + ``` + +2. **进入仓库目录:** + ```bash + cd openmina + ``` + +## 启动 + +**运行以下命令启动演示:** + +```bash +docker compose -f docker-compose.local.producers.yml up --pull always --force-recreate +``` + +最后: + +**在浏览器中访问 [http://localhost:8070](http://localhost:8070)** + +您应该能看到以下界面: + +![区块生产者演示](https://github.com/user-attachments/assets/f0ccc36e-0ee8-4284-a8d7-de0f9a3397d6) diff --git a/docs/scan-state.zh.md b/docs/scan-state.zh.md new file mode 100644 index 000000000..b22436a55 --- /dev/null +++ b/docs/scan-state.zh.md @@ -0,0 +1,229 @@ +# 扫描状态 + +这是一个数据结构,用于对需要交易 SNARK 证明的交易进行排队,并允许 SNARK 工作者并行处理这些交易 SNARK。 + +它被称为"扫描状态"是因为它将扫描类操作与 Mina 区块链状态的更新相结合。在函数式编程中,扫描会对元素序列应用特定操作,在每一步都跟踪中间结果并生成这些累积值的序列。 + +在这种情况下,元素序列是传入的交易区块流。 + +扫描状态表示一堆二叉树(每个节点有两个子节点的数据结构),其中树中的每个节点都是由 SNARK 工作者完成的 SNARK 任务。扫描状态会定期从树顶返回单个证明,证明树底所有交易的正确性。扫描状态定义了一个区块中的交易数量。 + +目前,Mina 允许每个区块包含 128 笔交易。区块生产者不必自己完成工作,可以从 SNARK 池中的可用出价购买任何 SNARK 工作者完成的工作。 + +**可能的状态:** + +**todo** - SNARK 已请求但尚未完成。 + +**pending** - 此交易的 SNARK 已完成,但尚未包含在区块中 + +**done** - 已完成并包含在区块中 + +在二叉树底部有 128 个 SNARK 任务,可能附加到以下条目之一: + +**支付** - Mina 资金转账(非 ZK 应用程序交易)和权益委托 + +**Zk 应用程序** - 由 zk-SNARKs 驱动的 Mina 协议智能合约(ZK 应用程序交易)。 + +**铸币** - 创建(或发行)之前不存在的新代币的交易。这些新代币用于支付区块生产者奖励。 + +**费用转账** - 用于支付 SNARK 工作。 + +**合并** - 将两个现有 SNARK 任务合并为一个(将两个 SNARK 任务 SNARK 化) + +**空** - SNARK 任务的空槽位 + +在扫描状态中,两个基本常量定义了其行为: + +**transaction_capacity_log_2** - 可以包含在区块中的最大交易数量 + +**work_delay** - 一定的延迟(以区块为单位),确保 SNARK 工作者有足够的时间完成 SNARK 工作。 + +**扫描状态中的树的数量受这些常量影响:** + + +## 最大交易数量 + + +## TxnsMax=2^(TCL) + +**TxnsMax** - 最大交易数量, + +**TCL** - transaction_capacity_log_2 + +交易构成二叉树的无子叶节点。虽然这决定了可能的最大交易数量,但它将包含其他需要证明的操作,如 ZK 应用程序、费用转账和铸币。 + + +## 最大树数量 + + +## TreesMax=(TCL+1)*WD, + +TreesMax = 最大树数量, + +TCL = transaction_capacity_log_2, + +WD = work_delay + + +## 最大证明数量(每个区块) + + +## MNP = 2^(TN/TCL+1)-1 + +MNP = 最大证明数量, + +TN = 交易数量, + +TCL = transaction_capacity_log_2 + +每堆二叉树代表 Mina 区块链的一个"状态"。扫描状态的二叉树从叶子到根填充 SNARK 任务。 + +### 扫描状态的工作原理 + +这里我们有一个说明扫描状态如何工作的示例。 + +**重要提示:注意这是一个非常简化的版本,我们仅使用支付作为待处理的 SNARK 任务的概念,尽管其他操作也可能请求 SNARK 工作。** + +目前,Mina 的扫描状态允许一个区块中最多包含 128 笔交易,这意味着二叉树末端可能有多达 128 个叶节点。但是,为了解释这个概念,我们仅使用一个 `max_no_of_transactions` = 8(意味着一个区块中最多可以包含 8 笔交易或其他操作)和 `work_delay` = 1 的二叉树。 + +另外,请注意截图是从去中心化 Snark 工作者 UI 的浅色模式拍摄的,但默认情况下浏览器会以深色模式打开。 + +可能的状态: + +**Todo** - SNARK 已请求但尚未完成。 + +**ongoing** - 有生成 SNARK 的承诺,但 SNARK 尚未完成 + +**pending** - 此交易的 SNARK 已完成(在 SNARK 池中就绪),但尚未包含在区块中 + +**done** - 已完成并包含在区块中 + +**available jobs** - 当新区块到来时,扫描状态会更新新的可用任务 + + + +1. 空扫描状态 + +在创世时,扫描状态为空,如下所示: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/28fe2b45-fffa-4e36-8ad3-ef257a509c58) + +2. 树 0 填充了 8 笔交易的待办 SNARK 任务 + +我们添加 8 个待办 SNARK 任务(SNARK 任务请求): + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/99eb76eb-355e-4aed-a601-bc73837d2d6a) + +在底行中,颜色方案描述了我们已请求 SNARK 证明的各种类型的交易。在此示例中,有 5 笔支付(浅色模式下为深灰色,深色模式下为白色)、2 笔费用转账(紫色)和 1 笔铸币(浅色模式下为青色,深色模式下为浅蓝色)。 + +上面是 8 个黄色块,代表待办 SNARK 任务,即已请求但尚未完成的 SNARK 任务。 + +3. 树 1 填充了 8 笔交易的待办 SNARK 任务 + +现在添加了另一个包含 8 个待办 SNARK 任务的区块,填充了二叉树 2 的叶子。由于 `work_delay` 为 1,此阶段不需要 SNARK 工作。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/3615e6d4-f053-4bf6-901e-49064af639f8) + +在两个二叉树的底部,我们再次看到已请求 SNARK 证明的各种类型的交易。在新树中,有 2 笔支付、2 笔费用转账和 4 笔铸币。 + +上面我们看到在树 1 中,一些待办 SNARK 任务现在处于待处理状态(深紫色)。这意味着该交易的 SNARK 任务已完成,但尚未包含在区块中。 + +4. 树 2 填充了 8 个待办 SNARK 任务,树 0 获得前 4 个待处理合并任务 + +形成了另一个 SNARK 任务二叉树(树 3),树 1 中的交易获得了 SNARK 证明。此外,在树 1 中,为合并现有的 8 个已 SNARK 化交易创建了四个待处理 SNARK 任务。树 1 和树 2 的大多数 SNARK 任务已完成,但尚未添加到区块中: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/fe19b898-6dc0-4266-90a5-01035223453e) + +5. 树 3 为其交易填充了 8 个待办 SNARK 任务,树 0 和树 1 有待处理的合并任务 + +第四个 SNARK 任务二叉树填充了 8 个新交易,树 2 的所有待处理 SNARK 任务都已完成,但尚未添加到区块中。在树 0 和树 1 中,现有交易获得了 SNARK 证明,另外为合并这些交易创建了四个待处理 SNARK 任务。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/1c13c745-8841-4bab-9acb-c31d53a23576) + +6. 树 4 为其交易填充了待办 SNARK 任务,树 0 和树 1 有待处理的合并任务 + +树 4 为其交易填充了 8 个待办 SNARK 任务。由于 work_delay 为 1,这意味着在执行下一阶段的 SNARK 工作或合并之前有两个前置树的"延迟"。 + +实际上,这意味着树 2 现在将有 4 个待办 SNARK 任务来合并其交易,而树 0 将有 2 个待办 SNARK 任务来合并 4 个已经合并过一次的 SNARK 任务。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/d17c8b53-978e-4712-8d6e-6fd848896a79) + +7. 树 5 为其交易填充了待办 SNARK 任务,树 0 几乎完成了所有 SNARK 的合并 + +这个过程重复进行,直到达到最大树数量(在本例中为 6)。随着每个额外的树的添加,由于 work_delay 为 1,在第 n-2 个前置树上执行合并 SNARK 工作。如果时间延迟更大,则这个数字会增加(例如,如果 work_delay 为 2,那么就会是第 n-3 个前置树)。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/7c048c08-31cb-4eae-89fa-8a15f59b25d4) + +8. 达到最大树数量,在 n-2 个前置树上执行 SNARK 工作 + +一旦达到最大树数量,就会在剩余的树上执行合并 SNARK 工作: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/8a70e56f-6a7c-4d55-882e-aeec771bfe0f) + +在下图中,树 0 和树 1 的 SNARK 已经合并了最大次数,因此这些树中的 SNARK 工作已完成。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/2768f8b7-4714-406d-b10e-c11300b50e63) + +执行现有 SNARK 的合并任务,直到整个扫描状态都由 SNARK 组成,这意味着所有二叉树的交易都已经 SNARK 化,并且 SNARK 已经合并了 3 次。 + +在这种情况下,合并发生 3 次 = 添加 8 笔交易,然后进行 SNARK 化,然后合并成 4 个 SNARK,再合并成 2 个,最后合并成 1 个: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/da09bca8-2955-454f-85a7-d9acb53e679c) + +当扫描状态如上图所示时,这意味着所有二叉树都已填充交易,这些交易已经 SNARK 化,并且 SNARK 证明已经合并到最大次数。 + +通过使用 SNARK 证明及其合并,我们最终得到了 Mina 区块链的一个非常压缩和轻量级的表示。 + +## 延迟问题 + +在交易被包含在区块中和该交易的证明被包含之间存在显著的延迟(以区块为单位)。 + +假设一笔交易被包含在第 1 个区块中(尚未证明): + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/ccd45621-abbc-4c9b-9bc7-4ac34e07802d) + +这将在扫描状态的二叉树中填充一个代表交易的槽位: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/afff4f74-435f-474d-9c27-4b3ad6a95187) + +在某个时刻,SNARK 工作者会接取这个任务并开始完成证明。 + +工作者完成证明后将其广播给其他节点,因此,完成的任务可能会被添加到它们的 SNARK 池中: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/d88cd86e-2788-4b68-92a6-154fcde36609) + +在扫描状态中,二叉树更新以显示该交易的 SNARK 已完成(紫色),但尚未添加到区块中(绿色)。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/fb7767e1-b8cc-4734-b33f-85553819dafd) + +最终,区块生产者会从其池中获取这个 SNARK 并将其包含在区块中。 + +区块生产者生成第 5 个区块,并包含为第 1 个区块中的交易创建的证明: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/a9b5ab38-0226-436a-bb39-d133799a73d5) + +这仅意味着完成的任务已被添加到扫描状态中的树(在底部),现在需要通过与其他证明合并将这个证明冒泡到顶部: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/bdb23b8e-3f16-4b89-a2bd-7f2eb8f7d88d) + +一旦这个完成的任务被添加到树的底部,就会创建一个新的合并任务(将这个证明与另一个底部证明合并): + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/bc53fb64-a9df-437a-ab98-ba103497379c) + +最终,某个 SNARK 工作者会接取它,完成它,广播它,然后某个生产者会将其包含在另一个区块中。这将创建另一个合并任务,并且需要重复这个过程: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/1c2b704a-828b-444b-b7e7-122a9d49da9c) + +最终,生产者生成一个区块,其中将包含树顶部的合并证明,该证明包含了我们在第一步中包含的交易的证明。 + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/772b567d-067e-4fd9-b374-84e2126a855f) + +此时,已验证账本哈希被更新,现在该交易(以及其他交易)成为已验证账本的一部分。 + +如果不使用这些树,对于我们需要生成的每个交易证明,我们都需要等待前一个交易被证明后才能证明下一个。这将导致网络一直停滞等待证明就绪。此外,证明将无法并行解决(在当前设置中,我们可以让许多 SNARK 工作者解决最终会合并的不同证明)。 + +## 吞吐量 + +延迟问题导致吞吐量出现瓶颈。在某个时点,增加吞吐量会导致延迟急剧上升,因为将有太多 SNARK 任务等待合并并添加到已验证账本中: + +![image](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/ef75ebc9-e1e4-4ba4-b6a2-50324e559567) diff --git a/docs/snark-work.zh.md b/docs/snark-work.zh.md new file mode 100644 index 000000000..74b5199a5 --- /dev/null +++ b/docs/snark-work.zh.md @@ -0,0 +1,111 @@ +## 提交和生成新的 SNARK + +SNARK 证明是 Mina 区块链的核心,用于验证交易、区块和其他 SNARK 的有效性。我们希望优化 SNARK 的生产过程,以确保 Mina 区块链能够持续运行和扩展。 + +**这是 SNARK 工作流程的概述。点击图片查看高分辨率版本:** + +[![图片](https://github.com/openmina/openmina/assets/60480123/f32f8d6c-c20a-4984-9cab-0dbdc5eec5b1)](https://raw.githubusercontent.com/openmina/openmina/docs/cleanup/docs/OpenMina%20%2B%20ZK%20Diagrams.png) + +### 接收区块以更新可用任务 + +由于区块同时包含交易和 SNARK,每个新区块不仅会更新暂存账本,还会更新扫描状态(包含 SNARK 证明)。 + +图片 + +通过 GossipSub(P2P),节点接收包含交易和 SNARK 证明的新区块。 + +![图片](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/02f74256-6ac4-420e-8762-bfb39c72d073) + +工作池(作为修改后的 SNARK 池的一部分,包含暂存账本和扫描状态)会被更新。暂存账本包含新区块,扫描状态则用新任务更新。 + +![图片](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/ebb3446c-8a26-4c20-9dca-e395e75470e8) + +### 接收来自 Rust 节点的承诺 + +我们希望避免在 SNARK 生成过程中浪费时间和资源,特别是要防止 SNARK 生成者在同一个待处理的 SNARK 任务上重复工作。为此,我们引入了"承诺"的概念,即 SNARK 工作者承诺为待处理的 SNARK 任务生成证明。 + +这是 SNARK 工作者发出的消息,通知网络中的其他节点他们正在承诺为待处理的 SNARK 任务生成证明,这样其他 SNARK 工作者就不会执行相同的任务,而是可以承诺其他 SNARK 任务。 + +承诺通过专门为此创建的额外 P2P 层进行。 + +![图片](https://github.com/openmina/openmina/assets/60480123/8966f501-c989-47dc-93e3-3477fbbdf5a3) + +承诺通过 WebRTC 发送,这使得节点之间可以通过 P2P 网络直接通信。 + +![图片](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/9fa32591-0e63-40c1-91ab-c77a74c0e8b4) + +有效的承诺会被添加到"承诺池"中。 + +要添加承诺,必须满足以下条件: + +1. 承诺的 SNARK 任务在扫描状态中仍标记为未完成 +2. 该任务没有其他先前的承诺。或者,如果有其他承诺,则只添加费用最低的承诺。 + +图片 + +工作池(作为修改后的 SNARK 池的一部分)会用特定待处理 SNARK 任务的承诺(包括其费用)进行更新。 + +![图片](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/5951772d-f0c0-4ad8-bb0b-089c5f42659e"> + +承诺一旦添加到承诺池中,节点就会通过直接的 WebRTC P2P 通信将其广播给网络中的其他节点。 + +图片 + +### 接收来自 OCaml 节点的 SNARK + +Rust 节点从 OCaml 节点(OCaml SNARK 工作者)接收 SNARK 证明。 + +![图片](https://github.com/openmina/openmina/assets/60480123/fbde0660-df6d-4184-8d8c-b2f8832b711b) + +SNARK 会被验证。 + +图片 + +如果它是特定待处理 SNARK 任务的最低费用 SNARK,则会被添加到 SNARK 池中,区块生产者可以从这里获取 SNARK 并将其添加到区块中。 + +图片 + +之后,更新后的 SNARK 池(包含已完成但尚未包含在区块中的 SNARK)会通过 `mina/snark-work/1.0.0`(SNARK 池差异)主题在 PubSub P2P 网络上广播,并通过 WebRTC 直接发送给其他节点。 + +![图片](https://github.com/JanSlobodnik/pre-publishing/assets/60480123/f02fc1f4-e30e-4296-9a20-b7b57e2cf4a1) + +图片 + +### 接收来自 Rust 节点的 SNARK + +Rust 节点通过 P2P 发送 SNARK。 + +图片 + +SNARK 会被验证。 + +图片 + +如果是最低费用,它将被添加到 SNARK 池中。 + +### 提交和生成 SNARK + +一旦承诺了待处理的 SNARK 任务,SNARK 工作者就会生成 SNARK。 + +图片 + +如果承诺的 SNARK 任务在扫描状态中标记为未完成,且没有该任务的先前承诺(或者如果有其他承诺,则它是该 SNARK 工作的最低费用承诺),它就会被添加到 SNARK 池中。 + +从 SNARK 池中,它可以被提交给以下之一: + +图片 + +1. 尚未完成或包含在区块中的可用任务 +2. 已经执行但新承诺具有更低费用的任务 + +如果承诺是可用的最低费用,那么 SNARK 工作者就会开始在 OCaml 中生成 SNARK 证明。完成后,生成的 SNARK 会被发送回 SNARK 工作者(Rust)。 + +图片 + +SNARK 工作者开始处理已承诺的任务。生成的 SNARK 证明会由 OCaml 中的证明者检查,然后发送回 SNARK 工作者。 + +SNARK 证明随后被发送到 SNARK 池。 + +图片 + +从这里,它会通过 WebRTC P2P 直接广播给 Rust 节点,并通过 PubSub P2P 网络的 `mina/snark-work/1.0.0`(SNARK 池差异)主题间接广播给 OCaml 节点。 diff --git a/docs/testing/README.zh.md b/docs/testing/README.zh.md new file mode 100644 index 000000000..29fd77261 --- /dev/null +++ b/docs/testing/README.zh.md @@ -0,0 +1,161 @@ +# 测试 + +## 目录 + +- [P2P 测试](#p2p-测试) + - [RPC](#rpc) + - [Kademlia](#kademlia) + - [Identify](#identify) + - [Connection](#connection) +- [场景](#场景) + - [连接发现](#连接发现) + - [P2P 连接](#p2p-连接) + - [Kademlia](#p2p-kademlia) + - [Pubsub](#p2p-pubsub) + - [P2P 入站](#p2p-入站) + - [P2P 出站](#p2p-出站) + - [单节点](#单节点) + - [多节点](#多节点) + - [记录/重放](#记录重放) + +## P2P 测试 + +### [RPC](../../p2p/tests/rpc.rs) + +* `rust_to_rust`: 测试 Rust 节点是否可以接收和发送响应到另一个 Rust 节点 +* `rust_to_many_rust_query`: 测试 Rust 节点是否可以响应多个 Rust 节点 +* `rust_to_many_rust`: 测试 Rust 节点是否可以向多个 Rust 节点发送请求 +* RPC 测试,这些测试检查节点是否可以通过 RPC 正确通信: +* `initial_peers`: 检查初始节点是否正确发送和接收 +* `best_tip_with_proof`: 检查最佳提示是否正确发送和接收 +* `ledger_query`: 检查账本查询是否正确发送和接收 +* `staged_ledger_aux_and_pending_coinbases_at_block`: 在 yamux 中失败,错误为 `attempt to subtract with overflow` +* `block`: 在 yamux 中失败,错误为 `attempt to subtract with overflow` + +### [Kademlia](../../p2p/tests/kademlia.rs) + +* `kademlia_routing_table`: 测试节点是否通过 Kademlia 接收节点 +* `kademlia_incoming_routing_table`: 测试 Kademlia 是否通过传入节点更新 +* `bootstrap_no_peers`: 测试即使没有节点传递,Kademlia 引导是否完成 +* `discovery_seed_single_peer`: 测试节点通过 Kademlia 发现 +* `discovery_seed_multiple_peers`: 测试节点发现和识别集成 +* `test_bad_node`: 测试如果节点提供无效节点,我们是否能处理 + +### [Identify](../../p2p/tests/identify.rs) + +* `rust_node_to_rust_node`: 测试 Rust 节点是否可以识别另一个 Rust 节点 + +### [Connection](../../p2p/tests/connection.rs) + +* `rust_to_rust`: 测试 Rust 节点是否可以连接到 Rust 节点 +* `rust_to_libp2p`: 测试我们的节点是否可以连接到 Rust libp2p +* `libp2p_to_rust`: 测试 libp2p 节点是否可以连接到 Rust 节点 +* `mutual_rust_to_rust`: 测试一个 Rust 节点是否可以连接到第二个 Rust 节点,同时第二个节点尝试连接到第一个节点 +* `mutual_rust_to_rust_many`: 测试多个 Rust 节点是否可以同时相互连接 +* `mutual_rust_to_libp2p`: 测试 Rust 节点是否可以连接到 libp2p 节点,同时 libp2p 节点尝试连接到 Rust 节点 +* `mutual_rust_to_libp2p_port_reuse`: 测试 Rust 节点是否可以解决自身与 libp2p 节点之间的相互连接,目前由于 [Issue #399](https://github.com/openmina/openmina/issues/399) 失败 + +## 场景 + +### [连接发现](../../node/testing/src/scenarios/multi_node/connection_discovery.rs) + +我们想测试 Rust 节点是否可以连接并从 Ocaml 节点发现节点,反之亦然 + +* `RustToOCaml`: +此测试确保在 Rust 节点连接到具有已知地址的 OCaml 节点后,它将其地址添加到其 Kademlia 状态中。它还检查 OCaml 节点是否具有与 Rust 节点对应的正确 peer_id 和端口的节点。 + +* `OCamlToRust`: +此测试确保在 OCaml 节点连接到 Rust 节点后,其地址变得在 Rust 节点的 Kademlia 状态中可用。它还检查 OCaml 节点是否具有与 Rust 节点对应的正确 peer_id 和端口的节点。 + +* `RustToOCamlViaSeed`: +此测试确保 Rust 节点可以连接到 OCaml 节点,其地址只能从 OCaml 种子节点发现,并且 Rust 节点将其地址添加到其 Kademlia 状态中。它还检查 OCaml 节点是否具有与 Rust 节点对应的正确 peer_id 和端口的节点。最初,OCaml 种子节点在其节点列表中有其他两个节点,而 OCaml 节点和 Rust 节点只有种子节点。这两个(OCaml 和 Rust)非种子节点连接到 OCaml 种子节点。一旦连接,它们从种子节点获取彼此的信息。然后它们在彼此之间建立连接。如果测试成功,那么在此过程结束时,每个节点在其节点列表中都有彼此。 + +* `OCamlToRustViaSeed`: 此测试确保 OCaml 节点可以连接到 Rust 节点,其地址只能从 OCaml 种子节点发现,并且其地址变得在 Rust 节点的 Kademlia 状态中可用。它还检查 OCaml 节点是否具有与 Rust 节点对应的正确 peer_id 和端口的节点。 + +* `RustNodeAsSeed`: 此测试确保 Rust 节点可以作为种子节点运行,通过运行两个仅知道 Rust 节点地址的 OCaml 节点。在这些节点连接到 Rust 节点后,测试确保它们也有彼此的地址作为其节点。 + +### [P2P 连接](../../node/testing/tests/p2p_basic_connections.rs) + +* `SimultaneousConnections`: +测试如果两个节点同时连接到彼此,它们应该连接,因此每个节点只有一个连接。 + +* `AllNodesConnectionsAreSymmetric` +所有节点之间的连接是对称的,即如果 node1 在其活动节点中有 node2,那么 node2 应该在其活动节点中有 node1。 + +* `SeedConnectionsAreSymmetric` +种子节点与其他节点的连接是对称的,即如果一个节点是种子的节点,那么它在其节点中有种子。 + +* `MaxNumberOfPeersIncoming`: +测试 Rust 节点的传入连接是否有限制。 + +* `MaxNumberOfPeersIs1` +两个最大节点数为 1 的节点可以相互连接。 + +### [P2P Kademlia](../../node/testing/tests/p2p_kad.rs) + +与 Kademlia 层相关的测试。 + +* `KademliaBootstrap`: +测试节点是否发现另一个 Rust 节点并能够引导 + +### [P2P Pubsub](../../node/testing/tests/p2p_pubsub.rs) + +与 pubsub 层相关的测试。 + +* `P2pReceiveBlock` +测试节点是否通过 meshsub 从节点接收区块 + +### [P2P 入站](../../node/testing/tests/p2p_basic_incoming.rs) + +与处理传入连接相关的测试。 + +* `AcceptIncomingConnection`: 节点应该接受传入连接。 +* `AcceptMultipleIncomingConnections`: 节点应该接受多个传入连接。 + +### [P2P 出站](../../node/testing/tests/p2p_basic_outgoing.rs) + +与出站连接相关的测试 + +* `MakeOutgoingConnection`: 节点应该能够与监听节点建立出站连接。 + +* `MakeMultipleOutgoingConnections`: 节点应该能够创建多个出站连接。 + +* `DontConnectToNodeWithSameId`: 节点不应与具有相同 peer_id 的节点建立连接。 + +* `DontConnectToInitialPeerWithSameId`: 节点不应与具有相同 peer_id 的节点建立连接,即使其地址在初始节点中指定。 + +* `DontConnectToSelfInitialPeer`: 节点不应与自身建立连接,即使其地址在初始节点中指定。 + +* `ConnectToInitialPeers`: 节点应该能够连接到所有初始节点。 + +* `ConnectToUnavailableInitialPeers`: 节点应该重复连接到不可用的初始节点。 + +* `ConnectToInitialPeersBecomeReady`: 节点应该能够在初始节点准备好后连接到所有初始节点。 + +### [单节点](../../node/testing/tests/single_node.rs): + +我们想测试 Rust 节点是否与 OCaml 节点兼容。我们通过尝试将 Openmina 节点连接到现有的 OCaml 测试网来实现这一点。 + +为此,我们使用 _solo node_,这是一个连接到 OCaml 节点网络的单个 Open Mina 节点。目前,我们使用公共测试网,但以后我们希望使用我们自己在集群上的 OCaml 节点网络。 + +* `SoloNodeBasicConnectivityAcceptIncoming`: 本地测试以确保 Openmina 节点可以接受来自现有 OCaml 节点的连接。 + +* `SoloNodeBasicConnectivityInitialJoining`: 本地测试以确保 Openmina 节点可以连接到现有 OCaml 测试网。 + +* `SoloNodeSyncRootSnarkedLedger`: 设置单个 Rust 节点并同步根 snarked 账本。 + +* `SoloNodeBootstrap`: 设置单个 Rust 节点并引导 snarked 账本、引导账本和区块。 + +### [多节点](../../node/testing/tests/multi_node.rs): + +我们还想测试一个仅由 Openmina 节点组成的网络场景。如果 Openmina 节点使用的功能仅在 OCaml 节点中实现,并且它没有正确执行,那么我们将无法通过单节点测试看到它。为此,我们利用多节点测试,这涉及我们的节点网络,没有任何第三方,因此测试完全是本地的并且在我们的控制之下。 + +* `MultiNodeBasicConnectivityPeerDiscovery`: 测试我们的节点是否能够通过 Ocaml 种子节点发现 Ocaml 节点。 + +* `MultiNodeBasicConnectivityInitialJoining`: 测试节点是否在允许的最小和最大节点数之间保持节点数量。 + +### [记录/重放](../../node/testing/tests/record_replay.rs) + +* `RecordReplayBootstrap`: 在启用状态和输入操作记录器的情况下引导一个 Rust 节点,并确保我们可以成功重放它。 + +* `RecordReplayBlockProduction`: 确保我们可以成功记录和重放集群中的多个节点 + 区块生产。 \ No newline at end of file diff --git a/docs/testing/testing.zh.md b/docs/testing/testing.zh.md new file mode 100644 index 000000000..9e0306f97 --- /dev/null +++ b/docs/testing/testing.zh.md @@ -0,0 +1,355 @@ +# Mina的测试框架 + +### 目录 +- [介绍](#介绍) +- [我们在测试什么](#我们在测试什么) +- [1. 网络连接和节点管理](#1-网络连接和节点管理) + - [网络连接](#网络连接) + - [单节点](#单节点) + - [节点发现测试](#节点发现测试) + - [Rust接受OCaml的入站连接](#rust接受ocaml的入站连接) + - [OCaml连接到广告的Rust节点](#ocaml连接到广告的rust节点) + - [通过OCaml种子节点发现Rust和OCaml节点](#通过ocaml种子节点发现rust和ocaml节点) + - [OCaml节点发现测试](#ocaml节点发现测试) + - [OCaml到Rust](#ocaml到rust) + - [Rust到OCaml](#rust到ocaml) + - [通过种子节点从Rust到OCaml](#通过种子节点从rust到ocaml) + - [Rust作为种子节点](#rust作为种子节点) + - [测试条件](#测试条件) + - [多节点](#多节点) + - [自适应节点管理](#自适应节点管理) +- [2. 网络抗性](#2-网络抗性) + - [抗DDoS攻击](#抗ddos攻击) + - [抗Eclipse攻击](#抗eclipse攻击) + - [抗Sybil攻击](#抗sybil攻击) + - [抗审查](#抗审查) +- [3. 节点引导和数据可用性](#3-节点引导和数据可用性) + - [节点引导](#节点引导) + - [数据可用性](#数据可用性) +- [4. 账本一致性和传播](#4-账本一致性和传播) + - [账本一致视图](#账本一致视图) + - [区块传播](#区块传播) + - [交易/零知识证明传播](#交易零知识证明传播) +- [5. 区块链进展和公平性](#5-区块链进展和公平性) + - [链进展](#链进展) + - [交易处理的公平性](#交易处理的公平性) +- [6. 可扩展性和可升级性](#6-可扩展性和可升级性) + - [网络可扩展性](#网络可扩展性) + - [可升级性](#可升级性) +- [7. 如何运行测试](#7-如何运行测试) + +### 介绍 + +处理重要信息的复杂系统,如区块链网络,必须经过彻底和持续的测试,以确保最高程度的安全性、稳定性和性能。 + +为此,我们需要开发一个能够部署各种测试的综合测试框架。 + +这样的框架在评估区块链对各种恶意攻击的抵抗力方面起着关键作用。通过模拟这些攻击场景和漏洞,该框架有助于识别区块链安全措施中的弱点,使开发人员能够加强系统的防御。这种主动的方法对于维护区块链生态系统内的信任和完整性至关重要,因为它最大限度地减少了漏洞的风险,并增强了用户和利益相关者的信心。 + +其次,一个强大的测试框架对于评估区块链的可扩展性、速度和稳定性同样重要。随着区块链网络的规模和采用率的增长,它们必须在保持高性能和稳定性的同时,能够处理越来越多的交易和用户。可扩展性测试确保系统能够在不降低速度或可靠性的情况下处理更大的工作负载,有助于避免可能阻碍交易和整体网络性能的瓶颈和拥堵。 + +此外,稳定性测试评估区块链在各种条件下(即使在协议升级期间)的一致运行能力。我们希望在潜在问题或崩溃有机会在主网上发生之前识别它们。 + +### 我们在测试什么 + +以下是测试类别的有限概述。目前的测试主要集中在网络和P2P层,下一步将是共识、账本和其他部分。 + +我们需要假设系统中超过三分之一的节点可能是拜占庭节点。 + +## 1. 网络连接和节点管理 + +### 网络连接 + +断开连接的节点应最终能够重新连接并与网络同步。 + +_此测试评估区块链节点保持一致网络连接的能力。它评估节点是否能够优雅地处理与网络的临时断开连接,并随后重新建立连接。_ + +我们希望确保新节点能够加入网络并处理被连接或数据请求淹没的情况,包括各种弹性和稳定性条件(例如,处理重新连接、延迟、间歇性连接和动态IP处理)。 + +这对于确保没有节点被永久隔离并且始终可以参与区块链的共识过程至关重要。 + +我们正在测试两个版本的节点: + +### 单节点 + +我们希望测试Rust节点是否与OCaml节点兼容。我们通过尝试将Openmina节点连接到现有的OCaml测试网来实现这一点。 + +为此,我们使用了一个_单节点_,这是一个连接到OCaml节点网络的单个Open Mina节点。目前,我们使用的是公共测试网,但以后我们希望使用我们自己集群上的OCaml节点网络。 + +此测试通过启动一个Openmina节点并将其连接到公共(或私有)OCaml测试网的种子节点来执行。 + +_此测试的源代码可以在此仓库中找到:_ + +[https://github.com/openmina/openmina/blob/develop/node/testing/src/scenarios/solo_node/basic_connectivity_initial_joining.rs](https://github.com/openmina/openmina/blob/develop/node/testing/src/scenarios/solo_node/basic_connectivity_initial_joining.rs) + +**我们正在测试以下场景:** + +#### 节点发现测试 + +#### Rust节点接受OCaml的入站连接 + +Openmina(Rust)节点是否可以接受来自本地Mina(OCaml)节点的入站连接。此测试将证明我们的Rust节点正在监听入站连接并可以接受它们。 + +**测试** +- [p2p_basic_incoming(accept_connection)](../node/testing/src/scenarios/p2p/basic_incoming_connections.rs#L16) +- [p2p_basic_incoming(accept_multiple_connections)](../node/testing/src/scenarios/p2p/basic_incoming_connections.rs#L62) +- [solo_node_accept_incoming](../node/testing/src/scenarios/solo_node/basic_connectivity_accept_incoming.rs) + +#### OCaml连接到广告的Rust节点 + +OCaml节点是否可以发现并连接到一个广告的Rust节点。这是通过广告Rust节点,使OCaml节点可以发现它并连接到该节点来完成的。 + +在此测试中,我们不会明确告知OCaml节点连接到它,它应该自动找到并通过对等发现(通过Kademlia执行)连接到节点。此测试将确保Rust节点以与OCaml节点兼容的方式使用Kademlia。 + +**测试** + +- [solo_node_accept_incoming](../node/testing/src/scenarios/solo_node/basic_connectivity_accept_incoming.rs) + +#### 通过OCaml种子节点发现Rust和OCaml节点 + +此测试的主要目标是确保Rust节点可以在网络中发现对等节点,并且也可以被其他对等节点发现。 + +1. 在此测试中,启动三个节点: + +* 具有已知地址和对等ID的OCaml种子节点 +* 设置种子节点为初始对等节点的OCaml节点 +* 设置种子节点为初始对等节点的Rust节点 + +最初,OCaml种子节点在其对等列表中有其他两个节点,而OCaml节点和Rust节点只有种子节点。 + +![peer1](https://github.com/openmina/openmina/assets/60480123/bb2c8428-7e89-4748-949a-4b8aa5954205) + +2. 两个(OCaml和Rust)非种子节点连接到OCaml种子节点 + +![peer2](https://github.com/openmina/openmina/assets/60480123/480ffeb0-e7c7-4f16-bed3-76281a19e2bf) + +3. 一旦连接,它们从种子节点获取彼此的信息。 + +然后它们之间建立连接。如果测试成功,那么在此过程结束时,每个节点在其对等列表中都有彼此。 + +![peer3](https://github.com/openmina/openmina/assets/60480123/3ee75cd4-68cf-453c-aa7d-40c09b11d83b) + +**实现细节** + +用于部署网络的Helm图表还包含执行检查的脚本。 + +#### OCaml节点发现测试 + +我们必须确保Rust节点可以利用Kademlia协议(KAD)发现并连接到OCaml节点,反之亦然。 + +为此,我们开发了一系列基本测试,以检查当Rust节点连接到OCaml对等节点时,通过KAD进行的正确对等发现。 + +#### OCaml到Rust + +此测试确保在OCaml节点连接到Rust节点后,其地址变为Rust节点Kademlia状态的一部分。它还检查OCaml节点是否具有正确的`peer_id`和对应于Rust节点的端口的对等节点。 + +**步骤** + +1. 配置并启动Rust节点 +2. 启动一个OCaml节点,并将Rust节点作为唯一对等节点 +3. 运行Rust节点,直到它收到一个事件,表明OCaml节点已连接 +4. 等待一个用于识别远程对等节点地址和端口的Identify事件 +5. 检查Rust节点在其Kademlia状态部分中是否有OCaml节点的地址 + +#### Rust到OCaml + +此测试确保在Rust节点连接到具有已知地址的OCaml节点后,它将其地址添加到其Kademlia状态中。它还检查OCaml节点是否具有正确的`peer_id`和对应于Rust节点的端口的对等节点。 + +**步骤** + +1. 启动一个OCaml节点,并等待其p2p准备就绪 +2. 启动一个Rust节点,并启动其与OCaml节点的连接 +3. 运行Rust节点,直到它收到一个事件,表明连接已建立 +4. 运行Rust节点,直到它收到一个Kademlia事件,表明OCaml节点的地址已添加 +5. 检查Rust节点在其Kademlia状态部分中是否有OCaml节点的地址 + +#### 通过种子节点从OCaml到Rust + +此测试确保OCaml节点可以连接到Rust节点,其地址只能从OCaml种子节点发现,并且其地址变为Rust节点Kademlia状态的一部分。它还检查OCaml节点是否具有正确的`peer_id`和对应于Rust节点的端口的对等节点。 + +**步骤** + +1. 启动一个作为种子节点的OCaml节点,并等待其P2P准备就绪 +2. 启动一个Rust节点,并启动其与种子节点的连接 +3. 运行Rust节点,直到它收到一个事件,表明连接已建立 +4. 启动一个OCaml节点,并将种子节点作为其对等节点 +5. 运行Rust节点,直到它收到一个事件,表明与OCaml节点的连接已建立 +6. 检查Rust节点在其Kademlia状态部分中是否有OCaml节点的地址 + +#### 通过种子节点从Rust到OCaml + +此测试确保Rust节点可以连接到OCaml对等节点,其地址只能从OCaml种子节点发现,并且Rust节点将其地址添加到其Kademlia状态中。它还检查OCaml节点是否具有正确的`peer_id`和对应于Rust节点的端口的对等节点。 + +**步骤** + +1. 启动一个作为种子节点的OCaml节点 +2. 启动一个OCaml节点,并将种子节点作为其对等节点,并等待其p2p准备就绪 +3. 启动一个Rust节点,并启动其与种子节点的连接 +4. 运行Rust节点,直到它收到一个事件,表明与种子节点的连接已建立 +5. 运行Rust节点,直到它收到一个事件,表明与非种子OCaml节点的连接已建立 +6. 检查Rust节点在其Kademlia状态部分中是否有OCaml节点的地址 + +#### Rust作为种子节点 + +此测试确保Rust节点可以作为种子节点运行,通过运行两个仅知道Rust节点地址的OCaml节点。在这些节点连接到Rust节点后,测试确保它们也有彼此的地址作为对等节点。 + +**步骤** + +1. 启动一个Rust节点 +2. 启动两个OCaml节点,指定Rust节点地址作为其对等节点 +3. 等待事件,表明与两个OCaml节点的连接已建立 +4. 检查两个OCaml节点是否有彼此的地址作为对等节点 +5. 检查Rust节点在其Kademlia状态中是否有两个OCaml节点的地址 + +#### 测试条件 + +我们运行这些测试,直到: + +* 已知对等节点的数量大于或等于最大对等节点数量。 +* 连接的对等节点数量大于或等于某个阈值。 +* 如果指定的步骤数量发生但条件未满足,则测试失败。 + +### 多节点 + +我们还希望测试一个仅由Openmina节点组成的网络场景。如果Openmina节点使用的功能仅在OCaml节点中实现,并且它未正确执行,那么我们将无法通过单节点测试看到它。 + +为此,我们使用多节点测试,该测试涉及我们的节点网络,没有任何第三方,因此测试完全是本地的并且在我们的控制之下。 + +#### Rust连接到所有初始可用节点 + +此测试检查Rust节点是否连接到其初始对等列表中的所有对等节点。 + +**测试** + +- [multi_node_initial_joining](../node/testing/src/scenarios/multi_node/basic_connectivity_initial_joining.rs)(部分?) + +#### Rust节点连接到广告的Rust节点 + +此测试检查Rust节点是否连接到广告的Rust节点。在此测试中,我们不会明确告知OCaml节点连接到它,它应该自动找到并通过对等发现(通过Kademlia执行)连接到节点。 + +**测试** +- [multi_node_connection_discovery/OCamlToRustViaSeed](../node/testing/src/scenarios/multi_node/connection_discovery.rs#L267) + +_此测试的源代码可以在此仓库中找到:_ + +[https://github.com/openmina/openmina/blob/develop/node/testing/src/scenarios/multi_node/basic_connectivity_initial_joining.rs#L9](https://github.com/openmina/openmina/blob/develop/node/testing/src/scenarios/multi_node/basic_connectivity_initial_joining.rs#L9) + +### 自适应节点管理 + +节点应能够发现并连接到新的对等节点,如果其当前的对等节点变得无响应或恶意。 + +_此测试评估区块链节点适应变化的网络条件的能力。它检查节点是否可以自主识别无响应或恶意的对等节点并将其替换为可信的对等节点。自适应节点管理增强了网络对潜在攻击或不可靠参与者的弹性。_ + +## 2. 网络抗性 + +### 抗DDoS攻击 + +即使在特定节点或基础设施上受到有针对性的拒绝服务攻击,网络也应保持运行。 + +_此测试重点评估节点抵御分布式拒绝服务(DDoS)攻击的能力,这些攻击可能会压倒节点的资源并使其无法访问。它评估节点在遭受故意和持续攻击时是否能够继续运行并为网络服务,以及在保持运行的情况下可以承受多少攻击。_ + +### 抗Eclipse攻击 + +诚实节点不应被恶意节点隔离,以至于它们只能从这些恶意实体接收信息。 + +_此测试检查区块链节点抵御Eclipse攻击的能力,在这种攻击中,恶意节点包围并隔离诚实节点,限制其获取准确信息的能力。它确保诚实节点始终可以访问多样化的对等节点,不会被恶意行为者主导。_ + +### 抗Sybil攻击 + +即使对手创建大量假名身份,网络也应正常运行。诚实节点仍应能够连接到其他诚实节点。 + +_此测试评估网络减轻Sybil攻击的能力,在这种攻击中,对手创建大量假身份以控制网络的很大一部分。它验证网络在存在这些假名攻击者的情况下能否保持完整性并继续有效运行。_ + +### 抗审查 + +网络应抵御任何子集节点持续审查或阻止某些交易或区块的尝试。 + +_此测试评估节点抵御子集节点审查尝试的能力。它验证网络的设计是否防止任何小团体审查特定交易或区块,维护区块链的开放性和去中心化。_ + +## 3. 节点引导和数据可用性 + +### 节点引导 + +新加入网络的节点应最终发现并连接到诚实的对等节点,并同步最新的区块链状态。 + +_此测试评估节点成功引导到网络的能力。它确保新加入的节点可以找到可信的对等节点,启动同步,并赶上区块链的当前状态,增强网络的可扩展性。_ + +此测试的重点是确保最新的Openmina构建能够对Berkeleynet进行引导。它每天执行一次。 + +节点的HTTP端口可访问为[http://1.k8.openmina.com:31001](http://1.k8.openmina.com:31001/)。 + +这些是主要步骤和检查。 + +首先,它对先前部署的实例执行一些检查: + +* 节点处于同步状态 +* 节点的最佳提示是Berkeleynet的提示 + +然后它部署新的Openmina实例,并等待其引导完成(超时时间为10分钟)。之后,它执行以下检查: + +* 节点的最佳提示是Berkeleynet的提示 +* openmina容器没有重启 + +有关详细信息,请参阅[Openmina Daily](https://github.com/openmina/openmina/blob/develop/.github/workflows/daily.yaml)工作流文件。 + +### 数据可用性 + +区块链中的任何数据(如区块或交易)应对任何请求它的节点可用。 + +_此测试确认区块链节点能够始终如一地向网络中的其他节点提供请求的数据。它保证数据可用性得到维护,促进区块链历史的透明性和信任。_ + +## 4. 账本一致性和传播 + +### 账本一致视图 + +网络中的所有诚实节点最终应对账本有一致的视图,达成对区块顺序和内容的共识。 + +_此测试确保所有诚实节点在账本视图上达成一致。它验证节点是否在区块顺序和内容上达成共识,防止分叉并确保区块链的单一、一致版本。_ + +### 区块传播 + +每个新挖掘或创建的区块最终应被网络中的每个诚实节点接收。 + +_此测试检查区块链节点在网络中传播新创建区块的效率。它验证没有节点被排除在接收关键区块更新之外,维护区块链的完整性。_ + +### 交易/零知识证明传播 + +用户广播的每笔交易/零知识证明最终应被网络中的矿工或验证者接收和处理。 + +_此测试检查节点及时向网络传播用户生成的交易和零知识证明的能力。它确保这些交易被矿工或验证者可靠地处理,促进高效的交易处理。_ + +## 5. 区块链进展和公平性 + +### 链进展 + +新区块应定期添加到区块链中,确保系统继续处理交易。 + +_此测试评估区块链节点是否能够定期向链中添加新区块。它保证区块链保持运行并能够容纳持续涌入的交易。_ + +### 交易处理的公平性 + +网络不应永久忽略或降低某些交易的优先级。诚实交易最终应得到处理。 + +_此测试评估节点在处理交易方面的公平性。我们希望确保没有有效交易被不公正地忽略或延迟,维护公平和高效的交易处理系统。_ + +## 6. 可扩展性和可升级性 + +### 网络可扩展性 + +随着参与者数量或交易速率的增加,网络仍应保持其活性属性。 + +_此测试检查区块链网络在不影响其活性属性的情况下处理增加的流量和参与的能力,确保其在扩展时保持强大和响应。_ + +### 可升级性 + +网络应能够在不停止或分裂的情况下升级或更改协议,确保连续运行。 + +_此测试确保区块链网络能够无缝地进行协议升级或更改,而不会导致中断或分裂网络。它支持网络的适应性和长期性。_ + +这些扩展描述提供了评估区块链节点功能和安全性的关键测试的全面理解。每个测试都为区块链网络的整体稳健性和可靠性做出了贡献。 + +## 7. 如何运行测试 + +cargo test --release --features scenario-generators + + diff --git a/docs/why-openmina.zh.md b/docs/why-openmina.zh.md new file mode 100644 index 000000000..9909782d1 --- /dev/null +++ b/docs/why-openmina.zh.md @@ -0,0 +1,17 @@ +# 为什么我们要开发 Open Mina 节点和 Mina Web 节点? + +## 多样化 Mina 生态系统 + +与任何区块链一样,Mina 也受益于节点的多样性增长。这有助于提升网络安全性,改善协议的清晰度,并确保区块链的透明度。此外,它还能营造有利于创新的环境,同时保护所有网络参与者的利益。 + +## 选择 Rust 语言以确保安全性和稳定性 + +对于 Mina 这样负责保护金融数据的系统来说,安全性和稳定性至关重要。因此,我们选择了 Rust 作为首选语言,因为它具有卓越的安全性、内存安全性,以及防止并发问题(如竞态条件)的能力。 + +## 提高网络韧性 + +随着多个开发团队积极参与创建各种节点实现,bug的识别和解决过程变得更加顺畅,降低了对生态系统产生负面影响的可能性。由于链验证的负担不会集中在单一实现上,任何出现的bug都会被有效地隔离在有限的节点子集中,最大限度地减少对整个区块链的潜在影响。 + +## 为 Mina 社区提供更多节点选择 + +最后,用户始终能从拥有更多运行 Mina 节点的选择中受益。人们在节点实现方面可能有不同的偏好。每种编程语言都能带来其独特的功能特性。多样化的节点使用户能够根据自己的具体偏好和需求做出选择。