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
- 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. - Attachez-le à votre demande d’abonnement.
insert_into_subscribe_request()place le filtre sérialisé dans le flux de comptes d’un standardSubscribeRequest. - 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.
- 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
main.rs
rust/examples/cuckoo_account_filter.rs.
Démarrage rapide (JavaScript/TypeScript)
Installez le SDK (le support de coucou nécessitehelius-laserstream 0.4.0+):
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) :- Appelez
insert()/remove()sur leCompressedAccountFilterSet. - Vérifiez
is_dirty()(ou consommez le drapeau avectake_dirty()) pour voir si le filtre a changé depuis qu’il a été envoyé pour la dernière fois. - Si sale, reconstruisez la demande avec
insert_into_subscribe_request(). En JavaScript, vous pouvez le renvoyer sur le même flux avecstream.write(request); en Rust, réabonnez-vous avec la demande reconstruite.
FAQ
Puis-je manquer des mises à jour pour les comptes dans mon filtre ?
Puis-je manquer des mises à jour pour les comptes dans mon filtre ?
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.
Combien de mises à jour (faux positifs) supplémentaires vais-je recevoir ?
Combien de mises à jour (faux positifs) supplémentaires vais-je recevoir ?
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.Quels clients prennent en charge les filtres de coucou ?
Quels clients prennent en charge les filtres de coucou ?
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.Puis-je encore utiliser des listes de clés publiques explicites ?
Puis-je encore utiliser des listes de clés publiques explicites ?
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.