# 环境准备

> 代码仓库固定的工具链、仓库中的两个工作空间、证明所需的仪式文件，以及每一步对机器的要求。

远地虚拟机 v1.0.0 是一个 Rust 代码仓库。除了 `rustup` 之外无需安装任何东西：仓库固定了自己的工具链，工具链自带客户程序（guest）的编译目标。编写、构建、运行客户程序以及分析其性能，都不再需要别的东西。证明则额外需要一个大文件，以及一台内存相应充足的机器。

## 工具链

仓库根目录下的 `rust-toolchain.toml` 固定了 stable 版 Rust **1.96.1**，连同 `rustfmt`、`clippy` 和 `llvm-tools`，以及目标 **`riscv32imac-unknown-none-elf`**，该目标的 `core` 和 `alloc` 以预编译形式提供。rustup 会在根目录以下的每个目录中应用它，并在首次使用时安装。

```sh
cd apogee-vm
rustup show active-toolchain     # 1.96.1, overridden by rust-toolchain.toml
cargo --version
```

仓库中任何地方都不使用 nightly，也不使用任何不稳定特性。`llvm-tools` 提供与编译器的 LLVM 相匹配的 `llvm-objdump` 和 `llvm-nm`：仓库用它们生成已提交的反汇编清单，你也可以用它们阅读客户程序的代码。

## 两个工作空间

检出的代码中有两个 Cargo 工作空间，这一划分很重要：

| 工作空间 | 根 | 构建目标 | 包含 |
| --- | --- | --- | --- |
| 根工作空间 | `Cargo.toml` | 你的宿主机（host） | 证明者、验证者、宿主程序 SDK、各种工具，即 `crates/` 和 `tools/` 中的一切 |
| 客户程序工作空间 | `guests/Cargo.toml` | `riscv32imac-unknown-none-elf` | 所有客户程序，以及它自己的 `guests/target` 目录 |

客户程序之所以单独存放，是因为每个成员都为客户程序目标编译，并链接一个 `#[panic_handler]`；在根目录运行的 `cargo test --workspace` 绝不能触及它们。客户程序工作空间还带有正确构建客户程序所需的设置，所以你永远不必手动输入：

- `guests/.cargo/config.toml` 设定目标，并向链接器传入 `-T crates/guest-sdk/link.ld`（即内存布局）和 `--no-relax`，因为链接器松弛（relaxation）会移动程序身份所绑定的地址。
- `guests/Cargo.toml` 把两个构建 profile 固定为相同的语义，溢出检查也包括在内（[构建与检查](https://apogee.gweb3networks.com/docs/launch/build#profiles)）。
- 它的 `[patch.crates-io]` 把 `k256`、`ark-ff` 和 `revm-precompile` 指向仓库内的 vendored 副本，这些副本会调用远地虚拟机的委托（[委托](https://apogee.gweb3networks.com/docs/launch/delegations#vendored)）。

> [!TIP]
> 在编辑器中把 `guests/` 作为单独的文件夹打开。这样 rust-analyzer 会读取该工作空间的 `.cargo/config.toml`，按客户程序目标而不是你的宿主机来检查客户程序代码。

## 仪式文件

远地虚拟机做出的每个承诺，都基于一场公开仪式所产生的秘密 `τ` 的各次幂：**PSE 的 perpetual powers of tau，第 80 次贡献**。一个文件满足所有用途：

```text
assets/ptau/ppot_0080_24.ptau        19.3 GB, 2^24 powers; assets/ptau/ is gitignored
```

计算程序身份、构建真实密钥和执行证明都需要它。构建、运行客户程序和分析其性能，或者运行工作空间测试，都不需要它；这些测试在各自的玩具设置上做证明。

PSE 仪式的各个文件截取自同一份 transcript，所以任何幂次不低于 24 的文件都可以用。Hermez 的 `powersOfTau28_hez_final_*.ptau` 是另一场仪式，`τ` 也不同：读取器同样能顺利读入它，但基于它得到的每个承诺、密钥和程序身份都会不同。为确认你持有的是正确的仪式文件，可以核对它的 `[τ]_1`，其规范编码 `x ‖ y` 的十六进制表示为：

```text
9bbb31bedc304e081e2aada4b56c2217e0e94ee16874e3517d14bef5dcec3a16
317ff1589e53513fa333591b318e8f1e55ef7c37d92beb6d9a61d770a2f39506
```

规范中的 [SRS 页面](https://apogee.gweb3networks.com/docs/auditors/spec/srs)准确说明了读取器检查哪些内容、又默认信任哪些内容。

## 机器

构建和运行在笔记本电脑上就能完成。证明受内存限制，其内存占用取决于同时证明的分片，而不是运行的长度。

| 步骤 | 需要 |
| --- | --- |
| 构建、运行客户程序并分析其性能，导出并检查其映像 | 任何一台较新的笔记本电脑；数秒 |
| 计算程序身份（`artifact-dump tables --ptau`） | 仪式文件；在默认高度下，18 核笔记本电脑上约 25 s |
| 以 `2^20` 的高度证明一个小型客户程序 | 数十 GiB。最宽的指令电路族的一个 `2^20` 分片，在前向过程中约占用 8.4 GiB 的域元素，每个同时处理中的分片各自占用一份 |
| 证明一个完整的以太坊区块 | 实测区块在一台 32 vCPU、247.7 GiB 内存的机器上，峰值为 174 GiB |

证明页面解释了高度和同时处理的分片数如何在内存与时间之间权衡：[证明与验证](https://apogee.gweb3networks.com/docs/launch/prove#heights)。

## 检查你检出的代码

CI 运行的内容如下，全部不需要仪式文件：

```sh
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo run -p kat-gen && git diff --exit-code      # committed fixtures regenerate identically
(cd guests && cargo clippy --bins -- -D warnings)
```

证明真实分片的测试套件都标记了 `#[ignore]`，因为每个都需要数十 GiB 内存。想在自己的机器上亲眼看到证明的生成与拒绝时，按名称运行其中一个：

```sh
cargo test --release -p prover --test acceptance -- --include-ignored --test-threads=1
```

下一步：[编写客户程序](https://apogee.gweb3networks.com/docs/launch/write)，或者在[快速上手](https://apogee.gweb3networks.com/docs/launch/quickstart)中把整个流程走一遍。
