Skip to main content

Descripción general

LaserStream admite el filtrado comprimido de cuentas mediante filtros de cuco. En lugar de enviar una lista explícita de claves públicas en tu solicitud de suscripción (32 bytes por cuenta), envías un filtro probabilístico compacto que ocupa aproximadamente 3–4 bytes por cuenta durante la transmisión. Esto permite suscribirte a cientos de miles de cuentas en un solo stream, sin fragmentar entre conexiones ni enviar solicitudes de suscripción demasiado grandes. Por ejemplo, un filtro que sigue 500,000 cuentas se serializa en aproximadamente 2.1 MB, frente a los 16 MB de una lista sin procesar de claves públicas; es decir, es aproximadamente 7.6 veces más pequeño. El ahorro exacto depende de qué tan lleno esté el filtro: cuanto más cerca esté de su capacidad, menos bytes se usarán por cuenta.

Disponibilidad

Cuándo usar filtros de cuco

Casos de uso habituales: supervisar a todos los titulares de un token, seguir todas las posiciones de un protocolo de préstamos o vigilar grandes conjuntos de billeteras para un sistema de trading o análisis.

Cómo funciona

  1. Crea el filtro en el cliente. Inserta cada clave pública seguida en un CompressedAccountFilterSet. La semilla de hash se genera aleatoriamente para cada filtro y se serializa junto con él, por lo que el servidor calcula el hash de las cuentas entrantes con la misma semilla que usó tu cliente.
  2. Adjúntalo a tu solicitud de suscripción. insert_into_subscribe_request() coloca el filtro serializado en el stream de cuentas de un SubscribeRequest estándar.
  3. El servidor busca coincidencias de forma probabilística. Como el filtro es probabilístico, el servidor puede entregar actualizaciones de cuentas que no sigues; los falsos positivos se mantienen por debajo del 1 % con carga completa. Nunca hay falsos negativos: se entrega cada actualización de una cuenta seguida.
  4. Vuelve a comprobar localmente cada actualización; este paso es obligatorio. Llama a set.contains(pubkey) para cada cuenta entrante antes de procesarla. Esta comprobación es exacta (está respaldada por un conjunto hash interno), por lo que después del filtrado local no verás ningún falso positivo.

Inicio rápido (Rust)

Agrega el SDK a tu proyecto:
Cargo.toml
Crea un filtro, adjúntalo a una suscripción y elimina localmente los falsos positivos:
main.rs
El SDK incluye una versión completa y ejecutable: rust/examples/cuckoo_account_filter.rs.

Inicio rápido (JavaScript/TypeScript)

Instala el SDK (la compatibilidad con filtros de cuco requiere helius-laserstream 0.4.0+):
Crea el filtro, adjúntalo y vuelve a comprobar localmente cada actualización:
El SDK incluye una versión completa y ejecutable: javascript/examples/cuckoo-account-sub.ts.

Referencia de la API

CompressedAccountFilterSet encapsula el filtro de cuco sin procesar junto con un conjunto hash exacto, por lo que las mutaciones y las comprobaciones de pertenencia siempre son seguras y exactas: Los nombres de métodos anteriores siguen las convenciones de Rust. El SDK de JavaScript/TypeScript ofrece la misma interfaz en camelCase: new CompressedAccountFilterSet(capacity) en lugar de with_capacity, insertIntoSubscribeRequest, isDirty, takeDirty, toProto, etc. En JavaScript, insert devuelve un valor booleano (true si acaba de agregarse) y genera TableFullError cuando el filtro está saturado. Puedes pasar una clave pública como cadena base58, 32 bytes sin procesar o cualquier objeto con un método toBytes(). Usa siempre CompressedAccountFilterSet en lugar del CuckooFilter sin procesar que encapsula. El método remove() del filtro sin procesar puede eliminar silenciosamente el elemento equivocado, un riesgo conocido y documentado de los filtros de cuco. El contenedor combina el filtro con un conjunto hash exacto, por lo que las operaciones de inserción, eliminación y comprobación de contenido siempre son correctas.

Dimensionamiento de la capacidad

  • Dimensiona el filtro según la cantidad máxima de cuentas que esperas seguir mediante with_capacity(n).
  • Si intentas insertar más elementos de los que admite la capacidad, la operación falla de forma controlada con un TableFullError; el filtro nunca se corrompe. En la práctica, la tabla tolera una ligera sobrecarga antes de rechazar inserciones, pero no dependas de ese margen.
  • El tamaño serializado depende de la capacidad, no de cuántas cuentas hayas insertado. Por lo tanto, un filtro sobredimensionado desperdicia bytes durante la transmisión. Elige una capacidad cercana a tu máximo real.

Actualización del conjunto seguido

Cuando cambie tu conjunto de cuentas seguidas (cuentas nuevas que quieras seguir o antiguas que quieras eliminar):
  1. Llama a insert() / remove() en el CompressedAccountFilterSet.
  2. Comprueba is_dirty() (o consume el indicador con take_dirty()) para saber si el filtro cambió desde la última vez que se envió.
  3. Si tiene cambios pendientes, vuelve a crear la solicitud con insert_into_subscribe_request(). En JavaScript, puedes volver a enviarla por el mismo stream con stream.write(request); en Rust, vuelve a suscribirte con la solicitud recreada.

Preguntas frecuentes

No. Los filtros de cuco generan falsos positivos (actualizaciones adicionales de cuentas no seguidas), pero nunca falsos negativos. Se entrega cada actualización de una cuenta seguida.
Menos del 1 % con carga completa y, normalmente, menos cuando el filtro está por debajo de su capacidad. Una llamada local a contains() por actualización las filtra de manera exacta.
El SDK de Rust (helius-laserstream 0.2.0+), el SDK de JavaScript/TypeScript (helius-laserstream 0.4.0+) y el cliente de Yellowstone para Rust (yellowstone-grpc-client 13.1.0+) admiten filtros de cuco. El SDK de Go aún no los admite. Consulta la tabla de disponibilidad anterior.
Sí. Los filtros account: [...] estándar funcionan sin cambios y siguen siendo la opción adecuada para conjuntos pequeños de cuentas (hasta aproximadamente 10,000 cuentas). Consulta la guía de suscripción a cuentas.
Sí. Cuando se adjunta un filtro comprimido a una suscripción de transacciones y se establece matchMints: true, el servidor también compara con el filtro las direcciones de acuñación de los saldos de tokens anteriores y posteriores a la transacción, además de las claves de sus cuentas. Consulta Filtrado por dirección de acuñación de token.

Contenido relacionado

Account Subscriptions

Filtrado estándar de cuentas con filtros de propietario, tamaño de datos y memcmp.

Clients & SDKs

SDK de TypeScript, Rust y Go con reproducción y reconexión automáticas.

Token Mint Filtering

Busca transacciones por dirección de acuñación de token con matchMints, incluso dentro de filtros comprimidos.