Skip to main content

概述

LaserStream 支持通过布谷鸟过滤器的压缩账户过滤。与其在订阅请求中发送显式pubkey列表(每个账户32字节),不如发送一个紧凑的概率过滤器,其在网络上的成本大约为每个账户3–4字节 这样一来,就可以实现在单个流中订阅数十万个账户——无需跨连接分片,也无需过大的订阅请求。 例如,跟踪 500,000 个账户的过滤器序列化后大约为 2.1 MB,而作为原始 pubkey 列表则为 16 MB——大约小 7.6 倍。具体节省取决于过滤器的饱和度:越接近容量,每个账户所需字节越少。

可用性

何时使用布谷鸟过滤器

典型用例:监控每个代币持有者、跟踪借贷协议中的所有头寸,或监视大型钱包集以进行交易或分析。

工作原理

  1. 在客户端构建过滤器。 将每个跟踪的 pubkey 插入 CompressedAccountFilterSet。哈希种子在每个过滤器中随机分配,并与其一起序列化,因此服务器使用您的客户端使用的相同种子哈希传入帐户。
  2. 将其附加到订阅请求中。 insert_into_subscribe_request() 将序列化过滤器放入标准 SubscribeRequest 的账户流中。
  3. 服务器概率匹配。 因为过滤器是概率性的,服务器可能会传递您没有跟踪的账户的更新——错误率在满负荷下低于 1%绝对没有假阴性:所有跟踪账户的更新都会传递。
  4. 在本地重新检查每次更新——此步骤是必须的。 在处理之前对每个传入账户调用 set.contains(pubkey)。此检查是精确的(由内部哈希集合支持),因此在本地过滤后,您将看到零误报。

快速入门(Rust)

将 SDK 添加到您的项目中:
Cargo.toml
构建过滤器,将其附加到订阅并在本地清除误报:
main.rs
SDK 附带完整的可运行版本:rust/examples/cuckoo_account_filter.rs

快速入门(JavaScript/TypeScript)

安装 SDK(布谷鸟支持需要 helius-laserstream 0.4.0+):
构建过滤器,附加它,并在本地重新检查每次更新:
SDK 附带完整的可运行版本:javascript/examples/cuckoo-account-sub.ts

API 参考

CompressedAccountFilterSet 将原始布谷鸟过滤器与精确的哈希集合封装在一起,因此变更和成员检查始终安全且精确: 上述方法名称使用 Rust 约定。JavaScript/TypeScript SDK 以驼峰式命名提供相同的接口——new CompressedAccountFilterSet(capacity) 而不是 with_capacityinsertIntoSubscribeRequestisDirtytakeDirtytoProto 等等。在 JavaScript 中,insert 返回布尔值(如果新添加则为 true),当过滤器饱和时抛出 TableFullError。可以将 pubkey 作为 base58 字符串、原始 32 字节或任何具有 toBytes() 方法的对象传递。 始终使用 CompressedAccountFilterSet 而不是其封装的原始 CuckooFilter。原始过滤器的 remove() 可能会静默移除错误的项目——这是布谷鸟过滤器的一个已知风险。此包装器将过滤器与精确哈希集合配对,因此插入、移除和包含检查始终正确。

容量大小调整

  • 根据您期望通过 with_capacity(n) 跟踪的账户峰值来调整过滤器大小。
  • 超过容量的插入操作会优雅地失败,并产生 TableFullError——过滤器永不损坏。在实际操作中,表在拒绝插入前可容忍轻微的超填充,但不要依赖于这种余量。
  • 序列化大小由容量决定,而不是由您插入的账户数量决定——因此,过大的过滤器会浪费网络字节。选择接近真实峰值的容量。

更新跟踪集合

当您的跟踪集发生变化时(需跟踪的新账户、需移除的旧账户):
  1. CompressedAccountFilterSet 调用 insert() / remove()
  2. 检查 is_dirty()(或使用 take_dirty() 消耗标志)以查看自上次发送以来过滤器是否更改。
  3. 如果已更改,用 insert_into_subscribe_request() 重新构建请求。在 JavaScript 中,您可以使用 stream.write(request) 在同一流上重新发送它;在 Rust 中,使用重新构建的请求重新订阅。

常见问题解答

不会。布谷鸟过滤器会产生误报(未跟踪账户的额外更新)但绝不漏报。所有跟踪账户的更新会被传递。
在满负荷下低于 1%,当过滤器未达到容量时通常更少。每次更新一个本地 contains() 调用能精确过滤掉它们。
Rust SDK (helius-laserstream 0.2.0+)、JavaScript/TypeScript SDK (helius-laserstream 0.4.0+),以及 Yellowstone Rust 客户端 (yellowstone-grpc-client 13.1.0+)。Go SDK 目前尚不支持。请参见上面的可用性表
可以。标准的 account: [...] 过滤器不变,仍然是小型账户集(多达大约10,000个账户)中的最佳选择。请参阅账户订阅指南

相关

账户订阅

使用所有者、数据大小和 memcmp 过滤器的标准账户过滤。

客户和 SDKs

提供自动重放和重连的 TypeScript、Rust 和 Go SDKs。