常见问题 - Geyser gRPC 流

问:你们的节点位于哪些区域?

我们目前在以下区域运营节点:
  • 法兰克福(FRA)
  • 阿姆斯特丹(AMS)
  • 伦敦(LON)
  • 纽约(NY)
  • 东京(TY)
  • 新加坡(SGP)
  • 悉尼(SYD)
ERPC 基于实际路由路径测量网络延迟,自动选择延迟最低的区域,而不是依赖直线距离。这种方法不仅能改善单个用户的延迟,还能提高整体网络效率,并增强 ERPC 对潜在攻击的全球抵御能力。
如果您的环境未能自动选择最优区域,请通过 ERPC Web Dashboard 联系我们。

问:延迟显示 9999ms 且选择了非最优区域。该怎么办?

在选择 gRPC 区域时,ERPC 会从下列代理主机向您已注册的 IP 发送 ICMP 延迟探测。请允许来自所有列出的源 IP 的入站 ICMP 回显请求。如果这些请求被防火墙(ufw、云防火墙、安全组等)阻止,测量结果可能变为 9999ms,并可能选择非最优区域。同一区域中的多个 IP 分别属于不同的探测主机,必须全部允许。
区域ICMP 源 IP
🇳🇱 Amsterdam82.21.43.34, 151.244.92.36
🇺🇸 New York151.243.244.5
🇩🇪 Frankfurt151.241.178.20, 151.241.178.34, 151.241.178.21
🇬🇧 London151.241.65.4
🇯🇵 Tokyo143.20.238.66
🇸🇬 Singapore151.245.186.2
🛰️ Far Point143.20.238.73

问:我已经将 IP 加入白名单,但仍然无法连接。应该检查什么?

请使用仪表盘中选择的加密 HTTPS 端点。HTTPS 使用 443 端口;使用 80 端口的 HTTP 仍是未加密的低延迟选项。
两种传输方式使用相同的已注册 IP 白名单。请使用仪表盘中选择的端点:HTTPS 使用 443,HTTP 使用 80。
  • HTTPS 端点:使用仪表盘中选择的端点和 443 端口。
  • HTTP 端点:使用仪表盘中选择的端点和 80 端口。
  • 使用仪表盘中显示的 URL,并采用 https:// 或 http:// 格式。
认证基于您已注册的 IP 地址。除非特定产品页面明确要求,否则不要添加 x-token、token 或 Authorization header。

问:我以前只用过 WebSocket。我可以使用 gRPC 吗?有示例吗?

可以。您可以使用 SLV 快速测试并开始 gRPC 开发。
如果是无需 token 即可测试的共享端点,可以运行:
bash
slv check grpc --endpoint <YOUR_ENDPOINT> --token none
请查看我们的 gRPC 快速入门指南了解详情。

问:我可以注册两个 IP 地址吗?

每个订阅可以使用一个端点。如果您希望使用两个 IP 地址,则需要两个独立的订阅。

问:过滤器有限制吗?

Shared Geyser gRPC 设有公平使用保护,避免一条流占用其他 ERPC 客户所需的资源。按当前的 Shared 规则,任何非空的 blocks map 都会被拒绝,即使是已缩小范围的区块请求也一样。每个账户过滤器都必须包含 account、owner 或受支持的 cuckoo 过滤器;仅有 memcmp 或 dataSize 并不够。
请去掉被拒绝的订阅形式,只订阅应用真正需要的数据。交易订阅或区块元数据也许无需传输完整区块就能满足需求。当正当的工作负载超出 Shared 允许的订阅形式或资源额度时,适合使用 Dedicated Geyser gRPC;但它不会让无效的参数变为有效,也无法修复缓慢的客户端。

问:重新连接前应如何收集 gRPC 错误?

请在重连循环覆盖第一条错误之前将其保留下来。记录初始元数据和 trailer 中的 gRPC 状态与消息,以及 x-erpc-error-code、x-erpc-error-reason 和 x-erpc-doc-url。如果 ERPC 给出了暂停,还要记录 x-erpc-retry-after-seconds 和 x-erpc-retry-at(Unix 秒)。
错误可能显示为 ERPC [STREAM_GUARD_SLOW_READER]: ...。请将显示的错误或其错误码粘贴到 FAQ 搜索中。标准说明请参阅 ERPC gRPC FAQ。连接提前结束时,不要假定 trailer 一定会送达。
也可以按症状搜索:慢速接收端、断开连接、带宽、投递滞后、积压、暂停、重试、无效参数、资源耗尽、权限被拒绝、IP 注册、流过多、完整区块或全部账户。

问:哪些 gRPC 错误会让我的连接进入暂停,客户端应在何时停止重新连接?

暂停是 ERPC 在出现某些错误后设定的一段有时限的时间。暂停期间,客户端不得重新连接。
哪些会被计入。 以下错误会被计入,并共用同一组阶段:
  • ERPC 以 ERPC_GRPC_INVALID_ARGUMENT、STREAM_GUARD_SHAPE_BLOCKS 或 STREAM_GUARD_SHAPE_ACCOUNTS_ALL 拒绝的每一个 Subscribe 请求,包括第一个。第一条计入的错误是警告,不会启动暂停。
  • STREAM_GUARD_SLOW_READER,但投递滞后发生在 ERPC 一侧时除外:此时 ERPC 会关闭流但不计入,错误中也不带重试时间。
以下情况不计入:重新连接本身、四个 STREAM_ADMISSION_* 错误码(STREAM_ADMISSION_LIMIT_REACHED、STREAM_ADMISSION_IP_NOT_ADMITTED、STREAM_ADMISSION_SOURCE_UNAVAILABLE 和 STREAM_ADMISSION_SNAPSHOT_UNAVAILABLE),以及暂停期间发生的任何本应计入的错误。暂停期间发生的这类错误不会延长该暂停,也不会进入下一个阶段。
阶段。 每一条计入的错误都会沿以下顺序前进一个阶段,从警告开始:
  • 警告:不暂停。
  • 暂停 60 秒。
  • 暂停 300 秒。
  • 暂停 1800 秒。
  • 暂停 86400 秒(24 小时)。这是最后一个阶段:在此阶段,每一条计入的错误都会再启动一次 86400 秒的暂停。
处于警告阶段时,下一条计入的错误只有在警告后 1 小时内发生,才会进入 60 秒的暂停。在警告 1 小时之后才发生的计入错误是另一次警告,不会暂停,此后的 1 小时窗口从这次新的警告起算。
若计入的错误发生在上一条被计入的错误之后不到 60 秒,它会被视为那条错误的一部分,不推进任何阶段。
阶段何时回到警告。 阶段一旦启动过暂停,只有在从上一次暂停结束起算的 24 小时内既没有计入的错误、也没有暂停,阶段才会回到警告;此后的下一条计入的错误是警告,不会暂停。在此之前,下一条计入的错误会立即启动下一个阶段,不经过警告。
出口流量暂停。 STREAM_GUARD_EGRESS_BUDGET 会启动一个独立的、固定为 600 秒的暂停。它不会推进阶段。
结束时间在哪里。
  • 启动暂停的错误会带有 Retry after N seconds. 以及 header x-erpc-retry-after-seconds 和 x-erpc-retry-at(Unix 秒)。警告不带重试时间。
  • 当启动暂停的正是一条计入的被拒绝请求时,它返回的是 STREAM_GUARD_SHAPE_REJECT_PENALTY 和 ResourceExhausted (8),而不是它自己的错误码。
  • 在慢速读取暂停或出口流量暂停期间,重新连接会收到 STREAM_GUARD_PENALTY_ACTIVE 和剩余时间。
  • 在由被拒绝的请求启动的暂停期间,新的连接会被立即关闭,既没有 gRPC 状态,也没有 ERPC 错误码。在仍处于打开状态的连接上,请求可能在该连接被关闭前再次收到 STREAM_GUARD_SHAPE_REJECT_PENALTY 和剩余时间。客户端可能再也看不到结束时间,因此必须从第一条带有它的错误中保存 x-erpc-retry-at。
错误码gRPC 状态是否启动或推进暂停?客户端必须做什么
ERPC_GRPC_INVALID_ARGUMENTInvalidArgument (3)是,在它拒绝 Subscribe 请求时。此时它是按上述阶段计入的错误。停止重连循环,不要重新发送同一个请求。下方该错误码的单独条目列出了需要检查的内容。
STREAM_GUARD_SHAPE_BLOCKSPermissionDenied (7)是。它是按上述阶段计入的错误。停止重连循环,不要重新发送同一个请求。下方该错误码的单独条目列出了需要检查的内容。
STREAM_GUARD_SHAPE_ACCOUNTS_ALLPermissionDenied (7)是。它是按上述阶段计入的错误。停止重连循环,不要重新发送同一个请求。下方该错误码的单独条目列出了需要检查的内容。
STREAM_GUARD_SLOW_READERResourceExhausted (8)是,按上述阶段计入,但投递滞后发生在 ERPC 一侧时除外:此时 ERPC 会关闭流但不计入,错误中也不带重试时间。停止重连循环。下方该错误码的单独条目列出了需要检查的内容。如果它启动了暂停,不要在 x-erpc-retry-at 中的时间之前重新连接。
STREAM_GUARD_EGRESS_BUDGETResourceExhausted (8)是。它会在上述阶段之外启动固定 600 秒的暂停。不要在 x-erpc-retry-at 中的时间之前重新连接。下方该错误码的单独条目列出了需要检查的内容。
STREAM_GUARD_SHAPE_REJECT_PENALTYResourceExhausted (8)是。它就是启动了暂停的那条计入的被拒绝请求。在仍处于打开状态的连接上,它可能带着剩余时间再次返回。不要在 x-erpc-retry-at 中的时间之前重新连接。修正被拒绝的请求,不要原样重新发送。
STREAM_GUARD_PENALTY_ACTIVEResourceExhausted (8)否。它报告的是已在持续中的慢速读取暂停或出口流量暂停。不要在 x-erpc-retry-at 中的时间之前重新连接。
STREAM_ADMISSION_LIMIT_REACHEDResourceExhausted (8)否。它没有限时的暂停。关闭未使用的流,然后重试。
STREAM_ADMISSION_IP_NOT_ADMITTEDPermissionDenied (7)否。它没有限时的暂停。下方该错误码的单独条目列出了需要检查的内容。
STREAM_ADMISSION_SOURCE_UNAVAILABLEUnavailable (14)否。它没有限时的暂停。按常规退避,等待一段时间后再试。
STREAM_ADMISSION_SNAPSHOT_UNAVAILABLEUnavailable (14)否。它没有限时的暂停。按常规退避,等待一段时间后再试。
客户端必须做什么。 遇到计入的错误时,停止重连循环,不要重新发送同一个请求,并修正它。在暂停期间,不要在 x-erpc-retry-at 中的时间之前重新连接。被拒绝的 Subscribe 请求会按上述规则计入,重新连接则不会。

问:慢速接收端被断开时,STREAM_GUARD_SLOW_READER 与 ResourceExhausted (8) 表示什么?

ERPC 观察到该流的写入进度不足或出现投递滞后。仅凭投递滞后无法确定原因。请检查网络丢包、有效带宽、主机硬件,以及应用的消费端是否跟得上。缩小订阅的数据范围,并把处理工作移出接收循环、交给有界队列。有界队列能控制内存使用,却无法解决持续缓慢的消费端。如果 ERPC 给出了重试截止时间,请等到该时间后再重新连接。下方的问题“为什么我的 gRPC 流速度一直停在同一水平,而且越来越落后?”说明了接收窗口,以及如何在客户端的库中调大它。

问:为什么我的 gRPC 流速度一直停在同一水平,而且越来越落后?

客户端或客户端与 ERPC 之间某个环节的接收窗口较小,可能导致 STREAM_GUARD_SLOW_READER 断开以及随后的暂停。本回答说明什么是接收窗口、如何判断它是否限制了您的流,以及如何在各个库中调大它。上方的问题“哪些 gRPC 错误会让我的连接进入暂停,客户端应在何时停止重新连接?”列出了各阶段及其时长。
什么是接收窗口。 在 HTTP/2 中,接收方会告诉发送方:在接收方确认之前,最多可以发送多少数据;这个量就是接收窗口(HTTP/2 流量控制窗口)。一次往返最多只能传输一个窗口的数据,因此速度的上限大约是窗口除以往返时间(到端点再返回所需的时间)。
其他限制。 窗口有两个:每个流一个,每个连接一个(同一连接上的所有流共用),较小的那个决定上限。按照 HTTP/2 规范,两个窗口的初始值都是 65,535 字节。TCP 接收缓冲区(存放传入数据的内存)也以同样的方式限制速度。中间的代理、负载均衡器、网关、VPN 或 sidecar 都有自己的窗口和缓冲区。那里的窗口或缓冲区较小时,即使您自己客户端的窗口很大,流也会被限速。
表现。 无论链上多繁忙,单个流的速度都会稳定在几乎相同的水平,而它的投递滞后会持续增长。ERPC 在一个到法兰克福共享端点往返时间约 6 ms 的位置进行了测量,每次只改变窗口:
  • 16 KiB 的流窗口:稳定在约 2.7 MB/s(16 KiB 除以 6 ms);投递滞后每秒增长约 0.6 秒,45 秒时达到 26 秒。
  • 两个窗口均为 16 MiB:投递滞后最大为 14 ms。
如果投递滞后发生在 ERPC 一侧,ERPC 会关闭流但不计入,错误中也不带重试时间。
自行检查。
  1. 将流的速度和投递滞后与上述模式对比。
  2. 测量往返时间。将流的速度乘以往返时间来估算窗口(2.7 MB/s 乘以 6 ms 约为 16 KB)。
  3. 检查客户端的两个窗口是否设置了较小的值,或者是否关闭了自动增长(库自动调大窗口)。
  4. 检查 TCP 接收缓冲区。在 Linux 上运行 sysctl net.ipv4.tcp_rmem net.core.rmem_max,并查看您的应用是否设置了 SO_RCVBUF;设置它会关闭自动调整大小。
  5. 检查中间所有环节的窗口和缓冲区。
  6. 如果速度没有上限、只有滞后在增长,说明接收之后的处理较慢。上方的问题“慢速接收端被断开时,STREAM_GUARD_SLOW_READER 与 ResourceExhausted (8) 表示什么?”说明了如何让接收循环只负责读取,并把繁重的工作移到有界队列。
各库的设置。 示例将两个窗口都设为 16 MiB,与 ERPC 的测量相同。对于未列出的库,请查找 HTTP/2 初始窗口的设置。
Rust,yellowstone-grpc-client。 不设置窗口时,GeyserGrpcClient::build_from_shared 使用每个流 2 MiB、每个连接 5 MiB。在 6 ms 的往返时间下,这些默认值可支持超过 300 MB/s,因此不会限制流。如需自行设置窗口,请使用 builder 的两个方法,并保持 http2_adaptive_window 关闭。如果开启它,窗口会从 65,535 字节开始自动增长到最多 16 MiB,并忽略您设置的值。
rust
// 两个窗口固定为 16 MiB;保持 http2_adaptive_window 关闭。
let client = GeyserGrpcClient::build_from_shared(endpoint)?
    .tls_config(ClientTlsConfig::new().with_native_roots())?
    .initial_stream_window_size(16 * 1024 * 1024)
    .initial_connection_window_size(16 * 1024 * 1024)
    .connect()
    .await?;
TypeScript,@triton-one/yellowstone-grpc 5.0.1 或更高版本。 默认值:每个流 4 MiB,每个连接 8 MiB,自动增长开启。窗口从 64 KiB 开始,最多增长到 16 MiB,因此默认值很少会限制流。如需固定大小,请在第三个参数中传入 grpcHttp2AdaptiveWindow: false。
typescript
// 已关闭自适应窗口,因此使用这些固定大小。
const client = new Client(endpoint, undefined, {
  grpcInitialStreamWindowSize: 16 * 1024 * 1024,
  grpcInitialConnectionWindowSize: 16 * 1024 * 1024,
  grpcHttp2AdaptiveWindow: false,
})
TypeScript,@triton-one/yellowstone-grpc 5.0.0 或更早版本。 这些版本使用 @grpc/grpc-js,其默认窗口为 65,535 字节:6 ms 时约 11 MB/s,100 ms 时约 0.66 MB/s。从 1.14 版本起,@grpc/grpc-js 将 'grpc-node.flow_control_window' 同时应用于两个窗口;1.13 版本只将其应用于流窗口,因此连接窗口仍为 65,535 字节(6 ms 时约 11 MB/s)。如果 @grpc/grpc-js 低于 1.14 版本,升级到 @triton-one/yellowstone-grpc 5.0.1 或更高版本会更快。
typescript
// 需要 @grpc/grpc-js 1.14 或更高版本才能同时调大两个窗口。
const client = new Client(endpoint, undefined, {
  'grpc-node.flow_control_window': 16 * 1024 * 1024,
})
Go,google.golang.org/grpc。 默认情况下,该库会自行调大窗口,最多到 16 MiB。grpc.WithInitialWindowSize 和 grpc.WithInitialConnWindowSize 会固定窗口并关闭自动增长;低于 64 KiB 的值会被忽略。请两个都设置:只设置一个时,另一个会保持在 64 KiB。
go
// 两个都设置;这样也会关闭窗口的自动增长。
conn, err := grpc.NewClient(target,
	grpc.WithTransportCredentials(creds),
	grpc.WithInitialWindowSize(16<<20),
	grpc.WithInitialConnWindowSize(16<<20),
)
Python,grpcio。 grpc.http2.bdp_probe 默认开启,因此窗口会自动增长;如果您的代码传入了 ("grpc.http2.bdp_probe", 0),请将其移除。grpc.http2.lookahead_bytes 设置每个流的预读量(默认 64 KB);往返时间较长时,较大的值可能有帮助。
python
# 如果 options 中包含 ("grpc.http2.bdp_probe", 0),请将其移除。
channel = grpc.secure_channel(target, creds, options=[
    ("grpc.http2.lookahead_bytes", 16 * 1024 * 1024),
])
在更近处接收。 往返时间越短,同样的窗口能传输越多数据;ERPC 的 VPS 服务和裸金属服务器可以把客户端放在端点附近。
谨慎拆分。 每个已注册的来源 IP,Standard 允许 10 个流,Premium 允许 50 个。每个流有自己的流窗口,但同一连接上的流共用一个连接窗口,因此连接窗口较小时仍会限制速度。替换流时,请先关闭旧的:已打开的流会计入上限,超出上限会返回 STREAM_ADMISSION_LIMIT_REACHED(下方有单独的问题)。拆分并不能让缓慢的处理变快。

问:STREAM_GUARD_EGRESS_BUDGET 与 ResourceExhausted (8) 表示什么?

该 IP 的总流量超过了 Shared 额度,因此相关的流可能同时关闭。请减少数据量和不必要的并行流,然后等到返回的截止时间。此出口流量暂停固定为 600 秒,不会推进惩罚阶段;但已有的更长暂停仍可能继续生效。

问:STREAM_GUARD_PENALTY_ACTIVE 与 ResourceExhausted (8) 表示什么?

此前的慢速读取暂停或出口流量暂停仍在持续,此响应带有剩余时间。请保留第一条 ERPC 错误并修正其原因,不要在 x-erpc-retry-at 之前重新连接;也不要为了测试而提前重新连接。重新连接的尝试不会被计入。上方的问题“哪些 gRPC 错误会让我的连接进入暂停,客户端应在何时停止重新连接?”列出了各阶段及其时长。

问:STREAM_GUARD_SHAPE_BLOCKS 与 PermissionDenied (7) 表示什么?

当前的 Shared 规则会拒绝任何非空的 blocks map,即使请求范围很窄。请移除 blocks map。需求允许时可使用交易和/或区块元数据,但两者都不等同于完整区块。需要完整区块时请使用 Dedicated Geyser gRPC;这并不意味着存在可选择部分区块的 Shared 方案。

问:STREAM_GUARD_SHAPE_ACCOUNTS_ALL 与 PermissionDenied (7) 表示什么?

每个账户过滤器条目都必须通过 account、owner 或受支持的 cuckoo 过滤器来选择数据。仅靠 memcmp 和 dataSize 并不够。请将账户请求缩小为这些受支持的形式之一,或在需要完整的账户流时使用 Dedicated Geyser gRPC。

问:STREAM_GUARD_SHAPE_REJECT_PENALTY 与 ResourceExhausted (8) 表示什么?

当启动暂停的正是那条计入的被拒绝请求时,返回的是此错误码,而不是 ERPC_GRPC_INVALID_ARGUMENT、STREAM_GUARD_SHAPE_BLOCKS 或 STREAM_GUARD_SHAPE_ACCOUNTS_ALL;上方的问题“哪些 gRPC 错误会让我的连接进入暂停,客户端应在何时停止重新连接?”说明了何时会发生这种情况。它带有 Retry after N seconds.、x-erpc-retry-after-seconds 和 x-erpc-retry-at。在此暂停期间,新的连接会被立即关闭,既没有 gRPC 状态,也没有 ERPC 错误码,因此客户端可能再也看不到结束时间。请从第一条带有它的错误中保存 x-erpc-retry-at。被拒绝的 Subscribe 请求会按上述规则计入,重新连接则不会。请修正该请求,不要原样重新发送。连接提前中断可能看起来像传输错误,因此请在重连循环把它掩盖之前保留第一条 ERPC 错误。

问:STREAM_ADMISSION_LIMIT_REACHED 与 ResourceExhausted (8) 表示什么?

当前的准入额度已满。请关闭未使用或重复的流,检查该连接的额度,并在有可用容量后重试。此响应本身并不表示限时的惩罚正在生效。

问:STREAM_ADMISSION_IP_NOT_ADMITTED 与 PermissionDenied (7) 表示什么?

ERPC 无法接纳该连接,包括 IP 注册宽限期到期之后的情况。请将实际的出站 IP 与已注册的 IP 进行比较,并确认当前的访问状态。注册变更需要时间生效,请等待其生效,但不要假定固定的生效时间;如果情况持续,请联系支持团队。

问:STREAM_ADMISSION_SOURCE_UNAVAILABLE 与 Unavailable (14) 表示什么?

ERPC 当时无法确定此连接的来源。请退避,稍后再试。如果持续发生,请带上第一条错误及其元数据联系支持团队;该响应并不能证明客户的网络或服务器存在故障。

问:STREAM_ADMISSION_SNAPSHOT_UNAVAILABLE 与 Unavailable (14) 表示什么?

ERPC 当时无法验证访问权限。请退避,稍后再试;如果持续发生,请联系支持团队。反复重新注册、放宽过滤器或购买 Dedicated Geyser gRPC 都无法解决这一可用性响应。

问:ERPC_GRPC_INVALID_ARGUMENT 与 InvalidArgument (3) 表示什么?

请求中含有无效的参数、选项、字段类型、键或过滤器组合。请在重试前修正请求,不要重新发送同一个请求。以此错误码被拒绝的每一个 Subscribe 请求,都是上方问题“哪些 gRPC 错误会让我的连接进入暂停,客户端应在何时停止重新连接?”中的暂停规则所计入的错误,这些规则与 STREAM_GUARD_SHAPE_BLOCKS、STREAM_GUARD_SHAPE_ACCOUNTS_ALL 和 STREAM_GUARD_SLOW_READER 共用。当以此错误码被拒绝的请求启动暂停时,它会以 STREAM_GUARD_SHAPE_REJECT_PENALTY 和 ResourceExhausted (8) 返回。Dedicated Geyser gRPC 不会让无效的参数变为有效。
错误消息会在错误码末尾带上 (reason: <token>),同样的 token 也会通过响应 header x-erpc-error-reason 返回。请在下表中查找该 token,了解需要修改什么。适用限制时,错误消息会写明该限制。
原因含义需要修改的内容
too_many_filters请求中的具名过滤器或数据切片超过了单个请求允许的数量。减少每个请求中此类具名过滤器(或数据切片)的数量。
empty_filter过滤器没有任何地址,而空过滤器表示全部。为每个过滤器至少指定一个地址(accounts:一个 account 或 owner;transactions:一个账户列表)。Shared gRPC 不处理空过滤器。
too_many_addresses一个过滤器字段列出的地址过多。减少单个过滤器字段中的地址数量;可拆分到多个过滤器,或缩小列表。
address_not_allowed过滤器中包含 Shared gRPC 不允许的地址。从过滤器中移除该高流量地址。
filter_name_too_long过滤器名称过长。使用更短的过滤器名称(即 map 的 key)。
invalid_commitmentcommitment 级别无效。使用 processed、confirmed 或 finalized。
invalid_address过滤器中包含无效地址。确保每个地址都是有效的 base58 Solana 地址(不能是空字符串、含空格或长度错误)。
invalid_signature交易签名的值无效。使用有效的 base58 交易签名。
invalid_account_data_filteraccounts 的数据过滤器无效。修正 memcmp、datasize 和 token 账户数据过滤器,并让其数量不超过消息中给出的上限。
invalid_data_slice数据切片无效。按 offset 对数据切片排序,且不要相互重叠。
blocks_include_not_allowedblocks 订阅选项在 Shared gRPC 上不可用。不要指定 blocks,改用交易订阅或 blocks_meta 订阅。
invalid_token_accounts_modetoken accounts 模式无效。使用 ALL (0) 或 BALANCE_CHANGED (1)。
invalid_argument以上原因均不适用。重试前请检查请求的过滤器和参数。

问:当 gRPC 返回其他非零状态时,ERPC_GRPC_REQUEST_FAILED 表示什么?

请求以一个有效的 gRPC 状态失败,该状态决定了下一步该怎么做。对于 OutOfRange (11) 等状态(例如历史范围无效时),请修正请求;对于 Unavailable (14) 等可用性状态,请退避。不要把所有非零状态都当作暂时性错误,也不要对每个响应都原样重试。

问:推荐哪个区域?

没有一个永远最好的区域。Solana 是全球网络,leader 角色按照 Leader 调度在验证者之间转移。验证者数量和质押量较多的区域中,leader slot 出现的频率更高,这有助于交易更快上链。但相应地,竞争流量也会同步集中,因此根据您的策略,竞争相对较少的区域有时反而能取得更好的效果。
一个实用的起点是:当稳定的 leader slot 供给最为重要时,选择验证者集中的区域,例如法兰克福或美国东海岸;当最短路径执行是首要目标时,则将基础设施部署在特定目标验证者附近。请使用 Validators Solutions 了解 Solana 网络的公开分布,然后结合 ERPC Leader Slot API 和实际测量判断单区域、双区域或全球部署是否合适。
Solana 主网分布报告

问:我需要约 400ms 或更低的延迟。

要实现约 400ms 以内的延迟,请考虑以下要点:
  • 对 Ping 值的现实理解:Ping 值表示理想条件,不反映流式通信中的实际延迟,后者通常约为 ping 延迟的 5 倍。例如,跨洲 100ms 的 ping 实际上会导致约 500ms 的延迟。因此,必须在同一区域内建立基础设施才能实现约 400ms 的延迟。
    • 典型 Ping 值参考:
      • 同一网络:~0.1ms
      • 私有网络互联(PNI):~0.2ms
      • 同一数据中心:~0.3ms
      • 同一城市:~1ms
      • 邻国:~5–10ms
      • 跨洲:~100–300ms
  • 避免平均延迟的陷阱:Solana 验证者分布在全球各地,且 Leader 调度在每个 epoch 随机变化。依赖平均延迟来实现约 400ms 是不切实际的。相反,您应该精确跟踪特定区域的验证者调度,以识别延迟最低的 slot。要持续实现最小延迟,需要在所有相关区域部署基础设施。在同一区域内,数据获取可以在几十毫秒内完成,传输可以在几毫秒内完成。
  • 跟踪 Leader 调度:借助 ERPC Leader Slot API(getLeaderSlots),监控您所在区域的 Leader 验证者调度。 它会返回即将到来的 Leader 调度、当前 epoch 的质押权重、估算的验证者地理位置以及参考 ping 值,让您能赶在延迟最低的 slot 到来之前识别出它们,并将其作为目标。 公共地图型数据源和原生 RPC API 适合了解网络整体分布,但精度不足以用于判断执行时机。Leader Slot API 补足了路由和交易判断所需的粒度。
Validators Solutions - Solana 网络数据
Solana 网络数据:Validators Solutions

问:如何实现零区块(零 slot)交易?

成功实现零区块(零 slot)交易需要更复杂的策略,如下:
  • 识别机会区域:Solana 验证者分布在全球各地,物理上不可能对每个 slot 都实现最优延迟。因此,监控您基础设施所在区域的验证者 Leader 调度,并识别最有利的机会区域。在多个区域部署基础设施也可能有利。例如,法兰克福是关键区域,因为其验证者密度高,Leader 选择更频繁,交易机会更多。
    借助 ERPC Leader Slot API(getLeaderSlots),查询即将到来的 Leader 调度、当前 epoch 的质押权重、估算的验证者地理位置数据以及参考 ping 值,其精度远高于公共地图型数据源或原生 RPC API。这样,您就能在相应 slot 到来之前预先标出机会区域,并执行接近零延迟的交易。
  • 部署专用节点:如果您难以竞争,请考虑部署专用节点。共享节点由于其他用户的流量会产生延迟,因此不推荐使用。此外,将您的专用节点放置在与应用程序相同的网络中可以显著降低网络延迟并优化性能。

问:我可以使用特定端点吗?

为了维持低延迟环境,我们的系统会自动选择最近的可用节点。如果您希望使用特定端点,我们建议租用距离该端点最近的服务器。

问:我收到了 401 错误。为什么?

为了维护低延迟环境,我们实施了 IP 限制。如果您没有订阅或您的 IP 未注册,您将收到 401 错误。
请仔细检查您注册的 IP 是否与当前访问 IP 匹配。

问:我收到了 429 错误。为什么?

您已达到方案的连接数上限。
如果遇到此错误,请考虑升级您的方案。如果您需要的连接数超过高级方案提供的数量,专用 gRPC 节点会更合适。

问:为什么专用端点更快?

共享端点由多个客户共同使用相同的资源。随着流量增加,延迟往往会出现。服务器资源有物理限制,它们能处理的工作量是有限的。当太多请求同时到达时,必须按顺序处理,这会导致响应时间变慢。
尽管我们采取了各种措施来优化共享端点的性能,但使用专用端点时您是资源的唯一用户。这意味着您完全不受其他用户的影响,确保始终稳定且快速的响应。
此外,专用端点提供无 TLS 的通信选项,如 HTTP。通过跳过 TLS 握手(约 20ms),通信比 HTTPS 更快。

问:签约后价格会被上调吗?

在订阅有效期内,您签约时锁定的价格将保持不变。能够承担 Solana 实时工作负载的运行环境在全球范围内都很稀缺,我们计划随着硬件和网络需求的持续增长,分阶段上调价格。高规格配置和需求集中的区域库存会更快售罄,因此以当前价格锁定订阅是长期控制成本最有利的选择。

问:我想用加密货币支付

当注册账单地址的国家/地区属于欧盟成员国时,即可在 ERPC Web Dashboard 中使用加密货币支付。如果账户中注册的支付卡片全部由欧盟以外发行,则无法使用加密货币支付。您可以使用 SOL、USDC 或 EURC 购买 ERPC Credits。
这些 ERPC Credits 可用于启用或续用 ERPC 方案。打开仪表盘,选择“Crypto 付款”,从您的钱包发起转账,仪表盘会验证这笔交易,并将 Credits 记入您的账户。
支持国家/地区:爱尔兰、爱沙尼亚、奥地利、保加利亚、比利时、波兰、丹麦、德国、法国、芬兰、荷兰、捷克、克罗地亚、拉脱维亚、立陶宛、卢森堡、罗马尼亚、马耳他、葡萄牙、瑞典、塞浦路斯、斯洛伐克、斯洛文尼亚、西班牙、希腊、匈牙利、意大利。
如果您的国家/地区不在列表中,请使用信用卡付款。

问:如何实现尽可能低的延迟?

我们强烈推荐将专用 gRPC 节点与我们的裸金属服务器结合使用。
两者共享同一网络,允许私有的零距离通信,无需穿越互联网。这种设置可实现极低的延迟,通常约 0.1ms ping。
如需了解更多详情,请通过 ERPC Web Dashboard 联系我们。

问:延迟是怎样的?

延迟因测量方法和您的具体使用环境而异。与其关注精确的数值,更重要的是确保延迟满足您的实际运营需求。
我们提供易于使用的 TypeScript 和 Rust 延迟测量工具。

问:这个 RPC(gRPC、Shreds)比其他的快吗?

我们在每个价格档位都以速度为设计目标,欢迎您把我们与任何其他供应商放在同等条件下比较。结果会随区域、使用共享端点或专用端点、所用协议(WebSockets、gRPC 或 Shreds)以及客户端的编程语言而变化。
如果您发现我们的服务更慢,请通过 ERPC Web Dashboard 告诉我们您比较的具体条件和竞争对手。我们将找出原因并进一步提高速度。

问:哪个方案提供最快的性能?

通常,我们最高级别的方案由于更优秀的 CPU、更大的内存容量和强大的硬件配置而提供最快的性能。
如果您需要更强大的服务器,我们还提供定制解决方案,但我们的标准方案旨在提供最佳的性价比。
我们有信心在每个价位都提供世界级的性能。如果您在相同价格范围内找到更快的供应商,请告诉我们,以便我们调查和改进。

问:我遇到了高延迟。我该怎么办?

延迟在很大程度上取决于您与端点的距离。我们建议从靠近提供的端点的服务器访问。最快的连接通过我们的裸金属服务器和 VPS 服务实现。

问:WebSockets、gRPC 和 Shreds 哪个最快?

客户反馈一致认为速度排名如下:
Shreds > gRPC > WebSockets
如果您观察到不同的结果,请告诉我们。

问:延迟不如预期。

性能因使用的编程语言而异。通常,语言速度排名如下:
Rust > Go > TypeScript (JavaScript) > Python
详细比较请参阅:
为了获得最佳性能,我们强烈推荐使用 Rust。