Skip to main content

Aperçu

LaserStream prend en charge le filtrage de comptes compressés via des filtres de coucou. Au lieu d’envoyer une liste explicite de clés publiques dans votre demande d’abonnement (32 octets par compte), vous envoyez un filtre probabiliste compact qui coûte environ 3 à 4 octets par compte sur le réseau. Cela rend possible l’abonnement à des centaines de milliers de comptes dans un seul flux — sans partitionnement sur plusieurs connexions, sans demandes d’abonnement surdimensionnées. Par exemple, un filtre suivant 500 000 comptes se sérialise à environ 2,1 Mo, contre 16 Mo en tant que liste brute de clés publiques — environ 7,6x plus petit. Les économies exactes dépendent de la saturation du filtre : plus il est proche de sa capacité, moins il y a d’octets par compte.

Disponibilité

Quand utiliser des filtres de coucou

Cas d’utilisation typiques : surveiller chaque détenteur d’un token, suivre toutes les positions dans un protocole de prêt, ou observer de grands ensembles de portefeuilles pour un système de trading ou d’analyse.

Comment ça fonctionne

  1. Construisez le filtre côté client. Insérez chaque clé publique suivie dans un CompressedAccountFilterSet. La graine de hachage est randomisée pour chaque filtre et sérialisée à côté, de sorte que le serveur hache les comptes entrants avec la même graine utilisée par votre client.
  2. Attachez-le à votre demande d’abonnement. insert_into_subscribe_request() place le filtre sérialisé dans le flux de comptes d’un standard SubscribeRequest.
  3. Le serveur fait correspondre de manière probabiliste. Étant donné que le filtre est probabiliste, le serveur peut fournir des mises à jour pour des comptes que vous n’avez pas suivis — les faux positifs sont limités à moins de 1 % à pleine charge. Il n’y a jamais de faux négatifs : chaque mise à jour pour un compte suivi est livrée.
  4. Re-vérifiez chaque mise à jour localement — cette étape est requise. Appelez set.contains(pubkey) sur chaque compte entrant avant de le traiter. Cette vérification est exacte (soutenue par un ensemble de hachage interne), donc après le filtrage local, vous ne voyez aucun faux positif.

Démarrage rapide (Rust)

Ajoutez le SDK à votre projet :
Cargo.toml
Construisez un filtre, attachez-le à un abonnement, et éliminez localement les faux positifs :
main.rs
Une version complète exécutable est livrée avec le SDK : rust/examples/cuckoo_account_filter.rs.

Démarrage rapide (JavaScript/TypeScript)

Installez le SDK (le support de coucou nécessite helius-laserstream 0.4.0+):
Construisez le filtre, attachez-le, et re-vérifiez chaque mise à jour localement :
Une version complète exécutable est livrée avec le SDK : javascript/examples/cuckoo-account-sub.ts.

Référence de l’API

CompressedAccountFilterSet enveloppe le filtre de coucou brut avec un ensemble de hachage exact, de sorte que les mutations et vérifications de l’appartenance sont toujours sûres et exactes : Les noms des méthodes ci-dessus suivent les conventions Rust. Le SDK JavaScript/TypeScript expose la même interface en camelCase — new CompressedAccountFilterSet(capacity) au lieu de with_capacity, insertIntoSubscribeRequest, isDirty, takeDirty, toProto, et ainsi de suite. En JavaScript, insert renvoie un booléen (true si nouvellement ajouté) et lance TableFullError lorsque le filtre est saturé. Une clé publique peut être passée en tant que chaîne base58, raw 32 octets, ou tout objet avec une méthode toBytes(). Utilisez toujours CompressedAccountFilterSet plutôt que le raw CuckooFilter qu’il enveloppe. La méthode remove() du filtre brut peut silencieusement supprimer le mauvais élément — une erreur documentée des filtres de coucou. Le wrapper associe le filtre à un ensemble de hachage exact, donc l’insertion, la suppression et la vérification d’appartenance sont toujours correctes.

Dimensionnement de la capacité

  • Dimensionnez le filtre pour le nombre maximal de comptes que vous prévoyez de suivre via with_capacity(n).
  • Insérer au-delà de la capacité échoue gracieusement avec un TableFullError — le filtre n’est jamais corrompu. En pratique, la table tolère un léger sur-remplissage avant de rejeter les insertions, mais ne comptez pas sur cette marge.
  • La taille sérialisée est déterminée par la capacité, et non par le nombre de comptes que vous avez insérés — donc un filtre surdimensionné gaspille des octets réseau. Choisissez une capacité proche de votre véritable pic.

Mise à jour de l’ensemble suivi

Lorsque votre ensemble suivi change (nouveaux comptes à suivre, anciens à supprimer) :
  1. Appelez insert() / remove() sur le CompressedAccountFilterSet.
  2. Vérifiez is_dirty() (ou consommez le drapeau avec take_dirty()) pour voir si le filtre a changé depuis qu’il a été envoyé pour la dernière fois.
  3. Si sale, reconstruisez la demande avec insert_into_subscribe_request(). En JavaScript, vous pouvez le renvoyer sur le même flux avec stream.write(request); en Rust, réabonnez-vous avec la demande reconstruite.

FAQ

Non. Les filtres de coucou produisent des faux positifs (des mises à jour supplémentaires pour des comptes non suivis) mais jamais de faux négatifs. Chaque mise à jour pour un compte suivi est livrée.
Moins de 1 % à pleine charge, et généralement moins lorsque le filtre est en dessous de sa capacité. Un appel local contains() par mise à jour les filtre exactement.
Le SDK Rust (helius-laserstream 0.2.0+), le SDK JavaScript/TypeScript (helius-laserstream 0.4.0+), et le client Rust Yellowstone (yellowstone-grpc-client 13.1.0+). Le SDK Go ne le prend pas encore en charge. Voir le tableau de disponibilité ci-dessus.
Oui. Les filtres standard account: [...] fonctionnent sans changement et restent le bon choix pour les petits ensembles de comptes (jusqu’à environ 10,000 comptes). Voir le guide d’abonnement aux comptes.

Connexe

Abonnements aux comptes

Filtrage standard des comptes avec propriétaire, taille de données et filtres memcmp.

Clients et SDKs

SDKs TypeScript, Rust, et Go avec relecture automatique et reconnexions.