# OMNX Chain（omnx-1）· 内网 RPC 与 WebSocket 配置

> 适用：公链节点内网开放 **8545（HTTP-RPC）+ 8546（WebSocket 事件订阅）**，
> 开启 `eth_subscribe` 事件订阅；**8545/8546 严禁暴露公网**；chainId 保持 **18888**（omnx-1）。
> 其他功能保持不变，BNB 测试网不受影响。

## 一、端口总览

| 端口 | 协议 | 用途 | 公网 |
|---|---|---|---|
| 8545 | HTTP | JSON-RPC（`POST /rpc`）+ 浏览器页面 + P2P（`/net/*`） | ❌ 禁止（仅运维 IP + VPC 内网） |
| 8546 | WebSocket | 事件订阅（`eth_subscribe` / `subscribe`） | ❌ 禁止（仅运维 IP + VPC 内网） |
| 80 / 443 | HTTP/HTTPS | nginx 网关（对外唯一入口，反代到 127.0.0.1:8545） | ✅ 允许 |
| 8090 | HTTP | 本地开发 Web 服务（serve-web.py，同源代理） | ❌ 仅本机 |

### 补充：P2P 没有独立端口

本链 P2P 是 **HTTP Gossip**，不是 devp2p —— **不存在 30303 之类的独立 P2P 端口**。
对等同步复用 HTTP 端口的 `/net/*` 接口：

| 接口 | 用途 |
|---|---|
| `GET /net/status` | 节点发现 / 存活探测 |
| `GET /net/blocks?from=N` | 区块同步（拉取） |
| `POST /net/blocks` | 区块广播 |
| `POST /net/tx` | 交易广播 |
| `GET /net/peers` | 对等拓扑（仅白名单可见） |

跨主机同步走 `seed.omnxchain.com:443` 的 nginx 网关（vhost 为
`deploy/rpc-gateway/nginx/seed.omnxchain.com.conf`，只放开上表接口，其余一律 404），
**因此无需为 P2P 额外放行任何端口**。

### 补充：安全组口径

`8545` / `8546` 的入站规则为「**运维 IP + VPC 内网**」两类来源，**绝不出现 `0.0.0.0/0`**：

- 同机 nginx 反代走 `127.0.0.1` 回环，本就不依赖安全组；
- 放行运维 IP 是为人在外面直连排障；
- 放行 VPC 内网是为适配器（OMNX-RPC-Adapter）与多节点同步。

`provision-ec2.sh` 在配完规则后会做一次红线复核：一旦发现 8545/8546 对
`0.0.0.0/0` 放行，脚本立即 `die` 中止。

## 二、节点启动参数示例

### 2.1 本地（默认已满足，无需额外参数）

```bash
cd 02-测试网
./scripts/start-local.sh
# 等价于：HOST=127.0.0.1 PORT=8545 OMNX_WS_HOST=127.0.0.1 OMNX_WS_PORT=8546
```

启动后：
```bash
curl http://127.0.0.1:8545/health        # {"ok":true,"chain":"omnx-1"}
# WebSocket 端点：ws://127.0.0.1:8546
```

### 2.2 单节点（内网访问）

```bash
HOST=127.0.0.1 PORT=8545 \
OMNX_WS_HOST=127.0.0.1 OMNX_WS_PORT=8546 \
OMNX_DISABLE_RESET=1 \
python3 node/rpc.py
```

### 2.3 云上多节点 / 适配器跨主机（8545/8546 绑内网 IP）

```bash
HOST=10.0.0.10 PORT=8545 \              # 8545 绑内网 IP（节点间 P2P + 同主机 nginx 反代）
OMNX_WS_HOST=10.0.0.10 OMNX_WS_PORT=8546 \
OMNX_SELF_URL=http://10.0.0.10:8545 \
OMNX_PEERS=10.0.0.11:8545,10.0.0.12:8545 \
OMNX_DISABLE_RESET=1 \
python3 node/rpc.py
```

> 约束：
> - `OMNX_WS_HOST` **不要设为 `0.0.0.0`**；跨主机时显式填内网 IP，靠安全组限定来源。
> - `HOST=0.0.0.0` 仅用于「安全组已严格收紧 + nginx 本机反代」的场景，仍不直接对公网开放 8545。
> - chainId 固定 18888：由 `deploy/genesis.json` 的 `chain_id_num=18888` 与 `chain_id=omnx-1` 固化。

### 2.4 多节点（multi-node.sh）WS 端口错开

`deploy/aws/multi-node.sh` 单机演示默认：HTTP 8545/8546/8547，WS 9545/9546/9547
（WS 端口独立，避免与节点 B 的 HTTP 8546 冲突；`START_WS=xxxx` 可自定义起始端口）。

### 2.5 订阅开启确认

```bash
# 1) 进程监听确认（应看到 8545 与 8546）
lsof -nP -iTCP:8545 -sTCP:LISTEN
lsof -nP -iTCP:8546 -sTCP:LISTEN

# 2) HTTP 端点对订阅方法的提示（订阅仅支持 WS）
curl http://127.0.0.1:8545/rpc -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}'

# 3) WS 冒烟（Node ≥ 22 自带 WebSocket；或浏览器控制台）
node -e '
const ws = new WebSocket("ws://127.0.0.1:8546");
ws.onopen = () => ws.send(JSON.stringify(
  {jsonrpc:"2.0", id:1, method:"eth_subscribe", params:["newHeads"]}));
ws.onmessage = e => { console.log(e.data); process.exit(0); };
setTimeout(() => process.exit(1), 5000);
'
```

## 三、防火墙规则

### 3.1 AWS 安全组（推荐，最小权限）

| 方向 | 端口 | 来源 | 用途 |
|---|---|---|---|
| 入站 | 8545 | VPC 内网 CIDR（如 `10.0.0.0/8`） | 节点间 P2P、适配器 RPC |
| 入站 | 8546 | VPC 内网 CIDR（如 `10.0.0.0/8`） | 适配器 WS 订阅 |
| 入站 | 80 / 443 | `0.0.0.0/0` | nginx 对外网关 |
| 入站 | 22 | 运维白名单 IP | SSH |

> ⚠️ **禁止** `0.0.0.0/0` 放行 8545 / 8546。

### 3.2 ufw（Ubuntu 节点本机）

```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 10.0.0.0/8 to any port 8545 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 8546 proto tcp
# SSH 按需：sudo ufw allow from <你的IP> to any port 22
sudo ufw enable
```

### 3.3 iptables（等价规则）

```bash
iptables -A INPUT -p tcp --dport 8545 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8546 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8545 -j DROP
iptables -A INPUT -p tcp --dport 8546 -j DROP
iptables -A INPUT -p tcp --dport 80  -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
```

## 四、nginx 网关（对外唯一入口）

- 公网只暴露 80/443；nginx 在本机反代 `127.0.0.1:8545` 的 `/rpc`、`/health`、`/net/status|peers`、浏览器页面。
- **不要**为 8545 / 8546 配置公网反代/直连规则（`deploy/aws/nginx-omnx-rpc.conf` 已按此约束）。
- WebSocket（8546）**不经过 nginx**，由安全组限定 VPC 内网来源后直接走内网 IP 访问。

```nginx
# deploy/aws/nginx-omnx-rpc.conf 已内置：
location /rpc     { proxy_pass http://127.0.0.1:8545/rpc; ... }
location /health  { proxy_pass http://127.0.0.1:8545/health; }
location ~ ^/net/(status|peers)$ { proxy_pass http://127.0.0.1:8545; }
```

## 五、环境变量速查

| 变量 | 默认 | 说明 |
|---|---|---|
| `PORT` | 8545 | HTTP-RPC/浏览器端口 |
| `HOST` | 127.0.0.1 | HTTP-RPC 监听地址（云上设内网 IP） |
| `OMNX_WS_PORT` | 8546 | WebSocket 订阅端口 |
| `OMNX_WS_HOST` | 127.0.0.1 | WebSocket 监听地址（**禁止 0.0.0.0**，云上设内网 IP） |
| `START_WS` | 9545 | multi-node.sh 多节点 WS 起始端口（自动错开 HTTP） |
| `OMNX_DISABLE_RESET` | 空 | `1` 时关闭「重置链」管理接口（正式部署必设） |
| `OMNX_PEERS` | 空 | 对端节点列表（逗号分隔，多节点集群） |
| `OMNX_SELF_URL` | 空 | 本节点对端可见地址 |
| `OMNX_GENESIS` | deploy/genesis.json | 创世配置路径（多节点一致） |

## 六、验证清单

1. `lsof -nP -iTCP:8545 -sTCP:LISTEN` 与 `8546` 均在监听；
2. `curl http://127.0.0.1:8545/health` → `{"ok":true,"chain":"omnx-1"}`；
3. `eth_chainId` → `0x49c8`（18888）；
4. WS 订阅 `newHeads`/`logs` 能收到推送；转账后 `Transfer` 消息 `txHash` 与区块交易一致；
5. `bash scripts/check-health.sh` 五项全过（含 WS 8546 握手 + `eth_subscribe` 自检）；
6. `eth_getLogs` 按区块范围返回 Transfer 日志（适配器 RPC 轮询兜底）；
7. 公网 `curl https://<域名>/rpc` 正常走 nginx；`telnet <公网IP> 8546` **应连接失败**（被防火墙拦截）。

## 七、边界

- 仅测试网（omnx-1）环境，严禁主网。
- BNB 测试网不受影响。
- 8545/8546 仅内网；公链对外服务形态不变（后台节点服务，上层应用经标准 RPC 独立接入）。
