xrplto/xrpld-rust
GitHub: xrplto/xrpld-rust
用纯 Rust 从零重新实现的 XRP Ledger 区块链节点守护进程,追求与 C++ 参考实现 rippled 的比特级精确对等。
Stars: 0 | Forks: 0
# xrpld-rust
## 什么是 XRP Ledger?
[XRP Ledger](https://xrpl.org) 是一个去中心化的公共区块链,它使用 Byzantine-fault-tolerant 共识协议(无需 proof-of-work,无需挖矿)在 3-5 秒内完成交易结算。**XRP** 是其原生的、无交易对手风险的资产(供应量上限为 1000 亿,且只会因销毁手续费而减少)。该账本内置了去中心化交易所和 AMM、托管、支票、支付通道、NFT 等功能——所有这些都由运行节点软件的 peer-to-peer 服务器网络执行并强制实施。
## 什么是 xrpld-rust?
`rippled` —— XRP Ledger 的参考服务器 —— 包含约 34 万行 C++ 代码。**xrpld-rust 是用安全的纯 Rust 对其进行的从零开始的重新实现**,**没有 C++,没有 FFI,也没有 `rippled` 链接**(已验证:依赖树中不包含任何 `ring`/`aws-lc-rs`/`openssl`/`secp256k1-sys`)。每一层都是从零开始编写的:secp256k1/ed25519 加密 + RFC 6979,二进制编解码器 + `STAmount`/`Number`,SHAMap,交易引擎,元数据,TLS peer 覆盖层,共识,基于磁盘的 content-addressed 存储,以及 JSON-RPC/WebSocket。
目标是实现 **mainnet 的比特级精确**:它独立验证每个账本的三个 Merkle 根(`ledger_hash`、`account_hash`、`transaction_hash`),逐字节复现交易元数据,遵循并提供完整的账本状态,并在每一轮共识中签署并广播提案和验证。
```
cargo build --release -p xrpld # -> target/release/xrpld
```
## 状态
**在 live-mainnet 功能集上达到了与 `rippled` 3.2.0-b7 的功能对等**,并在 mainnet 上进行了实际运行测试:
- **Validator。** 对每个账本进行独立的三重 Merkle 验证,然后在每一轮签署并广播 `TMProposeSet` / `TMValidation`(manifest / `[validator_token]` 模型)。测得在最新高度达到 **100% 的验证覆盖率**。领先验证器路径(独立在磁盘上构建达成一致的账本 + 自我验证 + 主动验证)已构建完成,但需等待压力测试通过后才会开放。
- **Consensus。** `LedgerTrie`/`Validations` 分叉安全性,trusted-UNL + negative-UNL quorum,`ManifestCache`,动态 UNL(HTTPS + 磁盘缓存),完整的治理 `doVoting` 三件套(amendment / fee / nUNL)+ flag-ledger pseudo-tx 生成,以及 position-convergence avalanche 核心。
- **Transaction engine。** 为 mainnet 激活集合**派发并实现了所有 73 种交易类型的比特级精确**,并通过差分重放验证了元数据的字节级精确;**所有 103 项 amendments**(由 codegen 生成,与 `features.macro` 字节完全一致),包括现代的 `fix*` apply/metadata 行为;**28/28 项账本不变量**;通用的 Flow 支付引擎;以及 AMM, NFToken, Escrow, Check, PaymentChannel, Credentials, DID, Oracle, PermissionedDEX 和(由 amendment 控制的)Vault / Lending / XChain / Batch。
- **Overlay。** TLS 1.3 peer 传输(通过修补后的 rustls 解决了握手的 Finished 移交问题),入站 peer 服务(账本/对象/重放请求),reduce-relay/squelch(发送方 + 接收方 + 多 peer),cluster 模式,peer 预留,`Resource::Charge` 负载管理,动态 validator 列表,以及 PeerFinder endpoint 交换。
- **Full state sync。** 将完整的约 1870 万个对象的 mainnet 状态后台获取到基于磁盘的 content-addressed 存储中,其 RAM 占用是**平坦的,与 tree 大小无关**(参见 [全状态 / 查询模式](#full-state--query-mode-separate-role))。
- **APIs。** 约 63 种 rippled 形态的 JSON-RPC 方法 + 9 种 WebSocket 流(包括 `books` 快照、有状态的 `path_find` 和 `account_history_tx_stream`),以及一个 `xrpld ` CLI 客户端。
**诚恳的说明。** 主动共识参与(从临时的开放账本中驱动共识轮次)已实现,但在进行端到端压力测试验证之前一直被**限制使用**。受 amendment 控制的套件(Vault / Lending / XChain)在其 amendments 接近 mainnet 激活之前,仅限于 XRP-public。一些现代构建路径是正确性参考 + 经过回归测试,但仍在等待最终的实时端到端确认。请参阅 [`docs/RIPPLED-PARITY.md`](docs/RIPPLED-PARITY.md) 以获取详尽的、文件引用的对等审计。
## 架构
一个由专注的、分层的 crate 组成的 Cargo workspace(其中没有任何 FFI):
| Crate | 职责 |
|---|---|
| `xrpl-types` | 核心值类型 —— `Hash256`,`Number`(Small/Large 尾数)算术,`AccountId`。 |
| `xrpl-crypto` | secp256k1 + ed25519 密钥,RFC 6979 确定性签名,base58,12 个 hash 前缀,RFC 1751。 |
| `xrpl-protocol` | 二进制编解码器(字段排序 / VL / 签名过滤器),`STAmount`,keylets,amendment 注册表。 |
| `xrpl-codegen` | 根据内置的 rippled `.macro` 文件在构建时代理生成 SField / TxFormats / LedgerFormats / amendments 表(字节完全一致)。 |
| `xrpl-shamap` | SHAMap —— 每个账本根背后的 Merkle 基数树,支持磁盘缺页读取。 |
| `xrpl-ledger` | 交易引擎应用的 `View` / 账本状态抽象。 |
| `xrpl-tx` | 交易引擎 —— 73 个 transactor,字节精确的元数据,28 个不变量,Flow 支付引擎,AMM。 |
| `xrpl-consensus` | `LedgerTrie`/`Validations` 分叉安全性,`ManifestCache`,治理 `doVoting`,`LoadFeeTrack`。 |
| `xrpl-overlay` | Peer 协议消息,握手,reduce-relay/squelch,cluster,预留,`Resource::Charge`,PeerFinder。 |
| `xrpl-tls` | TLS 1.3 peer 传输 —— 通过修补后的内置 rustls 实现握手 Finished 移交。 |
| `xrpl-nodestore` | 磁盘上的 content-addressed 节点存储 + `online_delete` 修剪 + `TaggedCache`。 |
| `xrpl-rdb` | 持久化交易历史存储(按账户索引,`account_tx` 分页)。 |
| `xrpl-rpc` | 约 63 个 JSON-RPC 方法处理器 + WebSocket 流形态。 |
| `xrpl-server` | HTTP / WebSocket 服务器 + 管理员角色权限控制。 |
| `xrpl-app` | daemon —— 跟随循环,共识连线,状态同步,入站服务,诊断。 |
| `xrpld` | `xrpld` 二进制文件:daemon 入口点 + CLI 客户端。 |
完整的内置 `rippled` 3.2.0-b7 源代码位于 `rippled/` 下,作为比特级精确性参考;`docs/RIPPLED-PARITY.md` 记录了逐行的对等审计。
## 作为 Validator 运行
在 validator 模式下,节点保持与网络的连接,在最新高度跟随已验证的账本,**独立验证每个账本**,并在每一轮中签署并广播 `TMProposeSet`(提案)和 `TMValidation`(验证),通过将主密钥绑定到临时签名密钥的 manifest(rippled 的 `[validator_token]` 模型)进行身份验证。
一个 validator 可以**精简**运行:它跟随最新高度并进行签名,而无需获取完整的账本状态(状态服务是一个单独的、可选择的模式,见下文)。它的工作集是一个滑动的账本历史窗口加上一个有上限的交易树节点存储,因此内存保持有界,而不会随着账本数量增加而增长。
### 硬件规格
要求取决于您运行的**角色**,该角色由几个环境变量选择。
默认情况是一个精简的 **validator**:完整的账户状态驻留在磁盘上(一个由 OS 页面缓存提供的内容寻址存储),因此进程 heap 保持小而平稳(jemalloc 会对其进行限制并将释放的页面返还给 OS),并且繁重的可选索引是关闭的。您开启的每个设置都会增加特定的、已知的成本。
| 角色 | 开启的设置 | CPU | RAM | 磁盘 |
|---|---|---|---|---|
| **Validator(精简)** —— *默认* | *(无)* | 1–2 vCPU | 1–2 GB | 5–10 GB SSD |
| **Validator + 完整状态** | `XRPLD_STATE_SYNC=1` | 2 vCPU | 4 GB | 20 GB SSD |
| **查询 / RPC 节点** | `XRPLD_STATE_SYNC=1` + `XRPLD_PATHFINDER=1`(+ `XRPLD_TX_HISTORY=1`) | 2–4 vCPU | 6–8 GB | 30+ GB SSD |
| | |
|---|---|
| **网络** | 稳定的宽带,出站 TCP **51235**(建议使用可达主机 / 静态 IP) |
| **操作系统** | Linux x86-64 |
各项设置的成本:
- **Validator(精简,默认)。** 占用空间是每个账本瞬时的 SHAMap 工作,而不是存储的状态 —— 无论运行时间多长,RAM 占用都是平坦的,并且没有庞大的磁盘存储。每隔约 4 秒验证一个账本,没有间隙。1 GB 就非常充裕。
- **`XRPLD_STATE_SYNC=1`** 将完整的 mainnet 账户状态保留在磁盘上(约 7–8 GB,缓慢增长,受 `ledger_history` 修剪限制)。读取通过 OS 页面缓存进行,因此需为热工作集增加几 GB 的 RAM 余量 —— 但*进程 heap*保持在约 1–2 GB(jemalloc)。
- **`XRPLD_PATHFINDER=1`**(需要完整状态)会定期遍历*整个*状态以重建 `ripple_path_find` 流动性图表 —— 每个周期都需要实际的 CPU 开销,外加通过页面缓存拉取整个树。请为其提供 CPU + RAM 余量;在 validator 上将其保持**关闭**。
- **`XRPLD_TX_HISTORY=1`** 保留可查询的 `tx`/`account_tx` 历史(redb,ACID),它会随着您索引的账本而增长 —— 请根据您想要的深度预留额外的磁盘空间。
注意事项:
- 一个**可达的**主机(开放/转发出站到 peer 端口 51235,最好是静态 IP)可以改善传播和注册表的可见性,但这并非网络接受和转发您的验证的必要条件。
- **将查询 / RPC 节点与 validator 分开运行**:state-sync + pathfinder 会将 1–2 GB 的 validator 变成 6–8 GB 的设备,并增加您不希望与验证竞争的 CPU 峰值。参见 [全状态 / 查询模式](#full-state--query-mode-separate-role)。
- **低资源强化**(默认设置,无需操作):daemon 使用 **jemalloc** 并带有后台页面清除功能,因此稳态下的 RSS 保持有界(glibc malloc 会向上爬升并产生内存碎片);**pathfinder 索引器默认关闭**(`XRPLD_PATHFINDER`);账户状态通过 OS 页面缓存在磁盘上支持,因此进程 heap 小而平稳。对于无人值守的操作,请为该单元配备一个简单的**停顿看门狗**(如果 xrpld 声称处于 `proposing` 状态,但 `validated_ledger` 在几分钟内停止推进,该计时器将重启 xrpld)—— systemd 的 `Restart=` 仅能捕获崩溃,而不能捕获逻辑死锁。
### 配置(环境变量)
| 变量 | 必需 | 用途 |
|---|---|---|
| `XRPLD_VALIDATION_SEED` | **是**(用于 validator 模式) | Validator 的永久**主** seed(base58,`s…`)。它的存在启用了 validator 模式。临时签名密钥和 manifest 是从中派生出来的。**机密**,请作为私钥对待。 |
| `XRPLD_VALIDATION_DOMAIN` | 否 Manifest 的域名(`xrp-ledger.toml` 品牌标识),例如 `validator.example.com`。 |
| `XRPLD_PEERS` | 否 | 除了内置的公共 hubs 之外,以逗号分隔的 `host:port` 种子 peer。 |
| `XRPLD_STATE_SYNC` | 否 | `1`/`true` 启用后台 full-state 同步。**默认关闭**,仅适用于高 RAM 查询节点。 |
| `XRPLD_PATHFINDER` | 否 | `1` 启用 `ripple_path_find`/`path_find` 所需的后台 pathfinder 索引器。**默认关闭**:它每隔几分钟就会遍历整个已验证状态,这对于 validator 来说是纯粹不需要的 CPU + 页面缓存开销。仅在 RPC/寻路节点上启用(最好有足够的 RAM 余量)。 |
| `XRPLD_RPC` | 否 | CLI 客户端针对的 endpoint(默认为 `127.0.0.1:5005`)。 |
| `XRPLD_CONF` | 否 | `rippled.cfg` 风格配置文件的路径(否则为 `/etc/opt/ripple/rippled.cfg`)。 |
| `XRPLD_PERF` | 否 | 用于瓶颈诊断的性能跟踪(默认关闭)。`warn` 仅记录慢于其阈值的操作(`⧖ perf `);`all` 记录所有已监测的 span。未设置时为零成本。 |
| `XRPLD_VALIDATION_DIAG` | 否 | 每个账本的详细验证生命周期日志(覆盖率 / quorum / acquire+verify+validate 耗时)。默认关闭;无论是否开启该标志,都会始终提供简明的**错失/延迟验证 WARN**。 |
### Validator 密钥
您需要一个唯一的 validator seed(切勿共享;切勿在两台主机上运行相同的 seed)。使用任何 XRPL 密钥对工具(例如 rippled 的 `validation_create`)生成一个,使用 `chmod 600` 存储,并通过 `XRPLD_VALIDATION_SEED` 提供给程序。
### 运行
前台运行(快速测试):
```
XRPLD_VALIDATION_SEED=s••••• target/release/xrpld validate s1.ripple.com:51235
```
作为持久服务运行(`systemd`):
```
# /etc/systemd/system/xrpld.service
[Unit]
Description=xrpld-rust pure-Rust XRPL node
After=network-online.target
Wants=network-online.target
# 永不放弃重启 validator(无 start-rate-limit 锁定)。
StartLimitIntervalSec=0
[Service]
Type=simple
ExecStart=/usr/local/bin/xrpld daemon
Restart=always
RestartSec=3
TimeoutStopSec=15
WorkingDirectory=/var/lib/xrpld
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
```
```
# /etc/systemd/system/xrpld.service.d/validator.conf(chmod 600,包含 seed)
[Service]
Environment=XRPLD_VALIDATION_SEED=s•••••
# Environment=XRPLD_VALIDATION_DOMAIN=validator.example.com
```
```
sudo install -m755 target/release/xrpld /usr/local/bin/xrpld
sudo systemctl daemon-reload
sudo systemctl enable --now xrpld
```
### 操作
```
journalctl -u xrpld -f # live log; look for "consensus ✓ ledger N"
xrpld server_info # rippled-style status (RPC client over :5005)
xrpld ledger validated # latest validated ledger
```
一个健康的 validator 会为每个账本(约 15 次/分钟)记录连续的 `consensus ✓ ledger N`,没有间隙,且 RSS 保持平稳。
### 诊断与性能
可观测性**在关闭时是受限且零成本的**,因此在正常操作中它永远不会给共识热路径增加负担:
- **`XRPLD_PERF=warn`** —— 如果任何已监测的操作超过其缓慢阈值(瓶颈检测器),则记录 `⧖ perf `。每个子系统中有意义的函数 —— tx apply / metadata、SHAMap、编解码器、view/state 读取、磁盘节点存储、共识、overlay、RPC 处理程序、sync/serve —— 都已被监测。`XRPLD_PERF=all` 跟踪每一个 span。
- **`XRPLD_VALIDATION_DIAG`** —— 每个账本的验证生命周期(覆盖率、quorum 以及 acquire→verify→validate 阶段的耗时)。简明的 **`⚠ MISSED VALIDATION` / `LATE OUR-VALIDATION`** 警告始终开启(即使没有该标志),因此错失的验证永远不会悄无声息。
- 跟随循环还会在账本关闭超出其预算时发出常开的 **`⚠ SLOW CLOSE`** 警告,并指出主要耗时阶段。
```
XRPLD_PERF=warn journalctl -u xrpld -f | grep '⧖ perf' # surface slow operations
```
## 全状态 / 查询模式(独立角色)
设置 `XRPLD_STATE_SYNC=1` 将使 daemon 额外将**完整的 mainnet 状态**(约 1870 万个对象)获取到本地存储中,以便它能够从磁盘响应繁重的状态查询(`account_lines`、`book_offers`、`account_objects`、任意 `ledger_entry`)。Validator 不需要它:`account_info` 已经通过经过验证的 Merkle proof-path peer 查询正常工作,而无需此功能。
这是一个具有不同规格的不同角色。状态驻留在**磁盘上的 content-addressed 节点存储**中(hash 到 offset 的索引位于磁盘上,而不是 RAM 中),并且同步获取器遍历**无锁的磁盘快照**,而不是内存中的镜像。关键结果是:完整的约 1870 万个对象的状态位于磁盘上,因此进程 RAM **不会**随着状态大小而增加,并且完整状态可以容纳在一台小型机器上,而内存中的索引则无法做到。
**实测结果**(此构建版本,在 **7.6 GB** 的机器上同步完整状态):
| 指标 | 数值 | 说明 |
|---|---|---|
| 进程 RAM(常驻) | **~2.2 GB** | 节点的工作集:同步结构、live-tip overlay、最近的账本历史窗口和缓存。**不**包括位于磁盘上的 1870 万个对象的状态。 |
| 磁盘上的状态存储 | ~6.8 GB | 5.5 GB 数据加上 1.3 GB 索引(约 2400 万个节点,包括写时复制历史)。 |
| 机器余量 | 适合 7.6 GB | 约 2.2 GB 常驻内存加上可通过数据库文件回收的 OS 页面缓存;机器的其余部分是空闲/缓存。 |
因此,**完整的当前状态**(约 1870 万个对象)在 **7.6 GB 机器上使用约 2.2 GB 的 RAM** 运行,而内存中的状态树则需要约 8 GB。早期“需要更多 RAM”的上限是旧版的内存中 hash 到 offset 的索引(在全状态下约为 1.2 GB)加上内存中的获取器镜像;这两者现在都位于磁盘上。
| | 全状态 / 查询节点 |
|---|---|
| RAM | **最低 4 GB**,**建议 8 GB**(实测常驻约 2.2 GB 加上可回收的页面缓存;余量可保持缓存热度) |
| 磁盘 | 50 GB+ SSD(当前状态数据库约 7 GB 加上增长 / 历史窗口) |
注意事项:
- RAM 不会随状态树的大小而增加:1870 万个对象的状态是从磁盘分页读取的,而不是保存在内存中。这约 2.2 GB 是节点的工作集(overlay + 历史窗口 + 缓存),而不是账本状态。
- 冷同步永远不会发生 OOM 崩溃(有界限的获取通道会应用背压),并且能够在内存受限的机器上达到**完整**状态。
- 最佳实践(与 rippled 一样):在一台主机上**精简**运行一个 validator(约 1 GB RAM),并**单独**运行一个完整/查询节点(常驻约 2.2 GB,机器配备 4 到 8 GB 内存)。查询节点不再需要高内存的机器。
## JSON-RPC / WebSocket / CLI
Daemon 在 `:5005` 上提供 rippled 形态的 **JSON-RPC 和 WebSocket** endpoint,`xrpld ` 是一个通过它进行交互的 CLI 客户端(`XRPLD_RPC`,默认为 `127.0.0.1:5005`)。
约 63 种方法(完整的 `rippled` 处理程序集 + `api_version` v1/v2 协商),在节点自身验证的最新高度上进行响应:
- **Server / ledger:** `server_info`、`server_state`、`ledger`、`ledger_current`、`ledger_closed`、`ledger_data`、`ledger_entry`(约 25 种类型化的子查询)、`fee`、`feature`、`amendments`、`server_definitions`、`ping`。
- **Account:** `account_info`、`account_lines`、`account_objects`、`account_currencies`、`account_tx`(forward/binary + 磁盘上的 head 索引)、`account_nfts`、`account_offers`、`account_channels`、`noripple_check`、`deposit_authorized`、`gateway_balances`。
- **Order books / paths / AMM / oracle:** `book_offers`(`owner_funds`)、`book_changes`、`ripple_path_find`(动态的链上多桥接寻路)、`nft_buy_offers`、`nft_sell_offers`、`vault_info`、`amm_info`、`get_aggregate_price`。
- **Transactions:** `tx`、`transaction_entry`、`submit`、`submit_multisigned`、`simulate`、`sign`、`sign_for`。
- **Overlay / admin / ops:** `peers`、`peer_reservations_*`、`connect`、`validators`、`manifest`、`validation_create`、`wallet_propose`、`log_level`、`stop` 等等(受 loopback / CIDR 管理员权限控制)。
- **WebSocket 流(9):** 用于 `ledger`、`transactions`、`validations`、`manifests`、`book_changes`、`consensus`、`peer_status`、`server`、特定 `accounts`、`books`(带有初始快照)、有状态的 `path_find` 以及 `account_history_tx_stream`(纯 `std` RFC 6455)的 `subscribe` / `unsubscribe`。
示例:
```
xrpld server_info
xrpld ledger validated
xrpld account_info rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh
xrpld tx
```
## 文档
- [`docs/RIPPLED-PARITY.md`](docs/RIPPLED-PARITY.md) —— 针对内置 `rippled` 3.2.0-b7 的详尽的、文件引用的对等审计(已完成的内容、剩余的内容、每一次提交)。
- [`docs/CONSENSUS-GO-LIVE-RUNBOOK.md`](docs/CONSENSUS-GO-LIVE-RUNBOOK.md) —— 从被动 validator 到主动参与者的分阶段推出。
- `rippled/` —— 完整的内置 `rippled` 3.2.0-b7 源代码,即比特级精确性参考。
## 另请参阅
- [XRP Ledger 文档](https://xrpl.org)
- [`XRPLF/rippled`](https://github.com/XRPLF/rippled) —— 本项目重新实现的参考 C++ 服务器。
xrpld-rust 是对 XRP Ledger 协议进行的独立的、净室设计的**纯 Rust** 重新实现 —— 没有任何 `rippled` 代码被链接或内置到构建中(`rippled/` 树仅作为只读的比特级精确性参考)。它通过逐字节实现相同的通信协议、共识和账本规则,与 mainnet 实现互操作。
标签:Rust, XRP, 共识协议, 加密货币, 区块链, 可视化界面, 网络流量审计, 节点软件, 通知系统