> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# gRPC 调试

> 修复 OrbitFlare 上的 Jetstream 和 Yellowstone gRPC 连接问题：IP Whitelist 与 API Key Only 访问、x-token 错误、TLS 和端口错误、匹配不到任何内容的过滤器以及保活。

OrbitFlare 运行两个 gRPC 服务。大多数问题都源于混淆了它们的主机、端口或身份验证方式，因此请先核对以下内容：

| | Jetstream | Yellowstone |
| - | - | - |
| 主机 | `{region}.jetstream.orbitflare.com` | `{region}.rpc.orbitflare.com` |
| 端口 | `80` | `10000` |
| 传输方式 | 明文（`http://`） | 明文（`http://`） |
| 访问方式 | 白名单 IP，或 `x-token` 密钥 | 白名单 IP，或 `x-token` 密钥 |
| 过滤器 | 仅交易 | 账户、交易、槽、区块、条目 |

如何接入取决于您许可证的[认证模式](/cn/authentication#认证模式)：

* **IP Whitelist：** 连接必须来自许可证白名单中的 IP。无需密钥，而且仅凭密钥无法从其他 IP 接入。要查看服务器连接时使用的 IP，请在该服务器上运行 `curl -s ifconfig.me`。
* **API Key Only：** 在 `x-token` 元数据请求头中发送许可证密钥，可来自任意 IP。gRPC 没有查询字符串，也不接受 `x-api-key`。

在调试其他问题之前，请先在[控制面板](https://orbitflare.com/dashboard)中确认您的许可证处于哪种模式。

## 使用 grpcurl 检查连接

[grpcurl](https://github.com/fullstorydev/grpcurl) 可以在命令行中调用 gRPC 方法，因此无需编写代码即可测试访问权限。将 [SDK 仓库](https://github.com/orbitflare/orbitflare-sdk-ts/tree/main/protos)中的 proto 文件下载到当前文件夹，然后：

```bash Jetstream theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
grpcurl -plaintext -H "x-token: $ORBITFLARE_LICENSE_KEY" -import-path . -proto jetstream_v2.proto \
  -d '{}' fra.jetstream.orbitflare.com:80 jetstream.v2.JetstreamV2/GetVersion
```

```bash Yellowstone theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
grpcurl -plaintext -H "x-token: $ORBITFLARE_LICENSE_KEY" -import-path . -proto geyser.proto \
  -d '{}' fra.rpc.orbitflare.com:10000 geyser.Geyser/GetVersion
```

在 IP Whitelist 模式下可以去掉 `-H` 参数。返回版本字符串表示主机可达且您有访问权限。如果返回其他内容，请在下文中查找。

## 错误及其含义

### 访问被拒绝

两个服务报告此类错误的方式不同，而且同一条消息在不同[认证模式](/cn/authentication#认证模式)下可能含义不同。

| 服务 | 您看到的内容 | IP Whitelist 模式 | API Key Only 模式 |
| - | - | - | - |
| Yellowstone | `Unauthenticated: authentication required: provide x-token header` | 您的 IP 不在白名单中。请将其加入白名单；不需要 x-token | 没有发送 `x-token`。请在其中发送许可证密钥 |
| Yellowstone | `PermissionDenied: IP not whitelisted for this api key` | 密钥有效，但 IP 不在白名单中。此模式下仅有密钥是不够的 | 该区域不在您的许可证范围内 |
| Yellowstone | `Unauthenticated: invalid x-token: api key not found` | x-token 不是有效的密钥 | x-token 不是有效的密钥。请从控制面板重新复制 |
| Jetstream | `Unavailable: error reading from server: EOF` 或 `connection reset by peer` | 您的 IP 不在白名单中 | 没有发送有效的 `x-token` |

Jetstream 会在发送任何 gRPC 状态之前关闭连接，因此 `EOF` 或连接重置是您唯一能看到的迹象。如果某个端点不在您的许可证范围内，无论处于哪种模式，访问它都会出现同样的 `EOF`。请在[控制面板](https://orbitflare.com/dashboard)中查看许可证包含哪些区域。

SDK 会将这些错误连同 gRPC 状态码和端点一起包装，例如 Rust 中的 `grpc error (16): authentication required: provide x-token header`，或 Go 中的 `grpc error (14): [http://ams.jetstream.orbitflare.com] error reading from server: EOF`。状态码 `16` 是 Unauthenticated，`7` 是 PermissionDenied，`14` 是 Unavailable。

如果同样的代码在一台服务器上正常、在另一台上失败，那么几乎可以肯定您处于 IP Whitelist 模式，而第二台服务器的 IP 不在白名单中。如果在 API Key Only 模式下到处都失败，请检查您的客户端是否确实发送了 `x-token` 请求头。

### 传输方式或端口错误

| 您看到的内容 | 原因 | 解决方法 |
| - | - | - |
| `tls: first record does not look like a TLS handshake` | 客户端对明文端口使用了 TLS | 在 URL 中使用 `http://`，或在 grpcurl 中使用 `-plaintext` |
| 连接时出现 `context deadline exceeded` | 端口错误，例如在 `10000` 上连接 Jetstream | Jetstream 使用 `80`，Yellowstone 使用 `10000` |
| DNS 查询失败 | 主机不存在 | 在[全球基础设施](/cn/infrastructure) 中核对区域代码。Jetstream 和 Yellowstone 的区域列表不同 |

### 达到连接上限

`RESOURCE_EXHAUSTED: connection limit exceeded` 表示您的 IP 已经有 50 个打开的 gRPC 连接，这一数量在 Jetstream、Yellowstone 和所有区域之间合并计算。请关闭不再使用的流，并在一个流上放置多个过滤器，而不是为每个过滤器打开一个流。参见[连接限制](/cn/authentication#数据流连接限制)。

## 已连接但收不到任何数据

### Jetstream

Jetstream v2 会告诉您每个过滤器是否被接受。新流上的第一条消息是针对您发送的每个过滤器的 `filterValidation`：

```json theme={"theme":{"light":"github-light","dark":"github-dark-default"}}
{ "filterValidation": { "filterId": "pump", "accepted": true } }
{ "filterValidation": { "filterId": "bad", "rejectionReason": "invalid pubkey" } }
```

被拒绝的过滤器不会关闭流。您会继续收到心跳，因此连接看起来正常，但没有任何内容被匹配。请记录 `filterValidation` 消息，并在认定市场冷清之前先检查 `accepted`。

其他原因：

* **您请求了账户数据。** Jetstream 只推送交易。它不支持账户过滤器，带有 `accounts` 过滤器的 v1 订阅永远不会发送任何内容。如需监控账户状态，请使用 [Yellowstone](/cn/data-streaming/yellowstone-account-monitoring)。
* **`account_required` 过于严格。** `account_include` 匹配提及所列任意一个账户的交易。`account_required` 只匹配提及所有所列账户的交易。请先使用 `account_include`，再逐步收窄范围。
* **您调用了 `SubscribeParsed`。** 该方法尚未实现，会以 `Unavailable: EOF` 关闭。请使用 `Subscribe`（v1）或 `SubscribeTransactions`（v2），并自行解码指令。

### Yellowstone

* **过滤器映射为空。** 不带任何过滤器的 `SubscribeRequest` 是合法的，但不会返回任何内容。每个过滤器都需要一个名称：`{"accounts": {"my-filter": {"account": ["..."]}}}`。
* **账户没有变化。** 账户过滤器只在账户发生变化时才发送更新。请用每个槽都会变化的 `SysvarC1ock11111111111111111111111111111111` 测试。
* **失败的交易被过滤掉了。** `failed: false` 会丢弃所有出错的交易。调试时请不要设置它，这样您就能看到自己的交易是否上链后失败。（`vote` 过滤器已不再重要：自 Alpenglow 起，验证者在链下投票，主网上已没有投票交易。）

## 流中断

空闲的 gRPC 流会在约 10 分钟后被关闭。请每 30 秒在流上发送一次 ping：

* **Jetstream v2：** 在 `SubscribeTransactions` 流上发送 `ping` 消息。服务器会回复携带相同 ID 的 `pong`。
* **Yellowstone：** 发送只设置了 `ping` 的 `SubscribeRequest`。参见 [Yellowstone 快速入门](/cn/data-streaming/yellowstone-quickstart)。

OrbitFlare SDK 会自动发送 ping、检测未收到的 pong、以退避方式重新连接并重新发送您的过滤器。如果使用自己的客户端，请在重新连接后重新发送完整的订阅，因为过滤器属于某个流，会随流一起丢失。

## 仍未解决

请收集主机和端口、您调用的方法、您发送的过滤器、带状态码的确切错误，以及您连接时使用的公网 IP。然后在 [Discord](https://discord.gg/orbitflare) 中提问。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.