Skip to main content

Übersicht

LaserStream unterstützt komprimierte Kontofilterung über Cuckoo-Filter. Anstatt eine explizite Pubkey-Liste in Ihrer Abonnementanfrage zu senden (32 Bytes pro Konto), senden Sie einen kompakten probabilistischen Filter, der auf der Leitung ungefähr 3–4 Bytes pro Konto kostet. Dies macht es praktikabel, Hunderttausende von Konten in einem Stream zu abonnieren — kein Sharding über Verbindungen, keine übergroßen Abonnementanfragen. Ein Beispiel: Ein Filter, der 500.000 Konten verfolgt, serialisiert sich auf etwa 2,1 MB, im Vergleich zu 16 MB als rohe Pubkey-Liste — ungefähr 7,6x kleiner. Die genauen Einsparungen hängen davon ab, wie voll der Filter ist: Je näher er an der Kapazität ist, desto weniger Bytes pro Konto.

Verfügbarkeit

Wann man Cuckoo-Filter verwendet

Typische Anwendungsfälle: Überwachung jedes Besitzers eines Tokens, Verfolgung aller Positionen in einem Kreditprotokoll oder Beobachtung großer Wallet-Sätze für ein Handels- oder Analysesystem.

So funktioniert es

  1. Erstellen Sie den Filter clientseitig. Fügen Sie jeden verfolgten Pubkey in einen CompressedAccountFilterSet ein. Der Hash-Seed wird pro Filter zufällig erstellt und zusammen mit ihm serialisiert, sodass der Server eingehende Konten mit demselben Seed hasht, den Ihr Client verwendet hat.
  2. Fügen Sie ihn Ihrer Abonnementanfrage hinzu. insert_into_subscribe_request() platziert den serialisierten Filter in den Kontenstream eines Standards SubscribeRequest.
  3. Der Server gleicht probabilistisch ab. Da der Filter probabilistisch ist, kann der Server Updates für Konten liefern, die Sie nicht verfolgt haben — falsch positive Ergebnisse liegen bei unter 1% bei voller Auslastung. Es gibt nie falsch negative: Jede Aktualisierung für ein verfolgtes Konto wird geliefert.
  4. Jedes Update lokal erneut überprüfen — dieser Schritt ist erforderlich. Rufen Sie set.contains(pubkey) für jedes eingehende Konto auf, bevor Sie es verarbeiten. Diese Überprüfung ist exakt (gestützt auf einen internen Hash-Satz), sodass Sie nach der lokalen Filterung keine falsch positiven Ergebnisse sehen.

Schnellstart (Rust)

Fügen Sie das SDK Ihrem Projekt hinzu:
Cargo.toml
Erstellen Sie einen Filter, fügen Sie ihn einem Abonnement hinzu und reinigen Sie falsch positive lokal:
main.rs
Eine komplette ausführbare Version wird mit dem SDK geliefert: rust/examples/cuckoo_account_filter.rs.

Schnellstart (JavaScript/TypeScript)

Installieren Sie das SDK (Cuckoo-Unterstützung erfordert helius-laserstream 0.4.0+):
Erstellen Sie den Filter, fügen Sie ihn hinzu, und überprüfen Sie jedes Update lokal erneut:
Eine komplette ausführbare Version wird mit dem SDK geliefert: javascript/examples/cuckoo-account-sub.ts.

API-Referenz

CompressedAccountFilterSet umhüllt den rohen Cuckoo-Filter zusammen mit einem exakten Hash-Satz, sodass Mutationen und Mitgliedschaftsprüfungen immer sicher und exakt sind: Methodennamen verwenden die Rust-Konventionen. Das JavaScript/TypeScript SDK bietet dieselbe Oberfläche in camelCase — new CompressedAccountFilterSet(capacity) anstelle von with_capacity, insertIntoSubscribeRequest, isDirty, takeDirty, toProto usw. In JavaScript gibt insert einen boolean zurück (true wenn neu hinzugefügt) und wirft TableFullError, wenn der Filter gesättigt ist. Ein Pubkey kann als Base58-String, Roh-32-Bytes oder jedes Objekt mit einer toBytes()-Methode übergeben werden. Verwenden Sie immer CompressedAccountFilterSet anstelle des rohen CuckooFilter, den er umhüllt. Die rohe Filterfunktion remove() kann stillschweigend das falsche Element entfernen — eine dokumentierte Fehlerquelle von Cuckoo-Filtern. Der Wrapper kombiniert den Filter mit einem exakten Hash-Satz, sodass Einfügen, Entfernen und Enthalten immer korrekt sind.

Kapazitätsgrößenbestimmung

  • Bemessen Sie den Filter für die Spitzenanzahl von Konten, die Sie über with_capacity(n) verfolgen möchten.
  • Das Einfügen über die Kapazität hinaus schlägt mit einer TableFullError fehl — der Filter wird nie beschädigt. In der Praxis toleriert die Tabelle eine leichte Überfüllung, bevor sie Einfügungen ablehnt, aber verlassen Sie sich nicht auf diesen Spielraum.
  • Die serialisierte Größe wird durch die Kapazität bestimmt, nicht durch die Anzahl der eingefügten Konten — ein überdimensionaler Filter verschwendet also Bytes auf der Leitung. Wählen Sie eine Kapazität, die nahe an Ihrem tatsächlichen Spitzenwert liegt.

Aktualisierung des verfolgten Sets

Wenn sich Ihr verfolgtes Set ändert (neue Konten zum Folgen, alte zum Entfernen):
  1. Rufen Sie insert() / remove() auf dem CompressedAccountFilterSet auf.
  2. Überprüfen Sie is_dirty() (oder verbrauchen Sie das Flag mit take_dirty()), um zu sehen, ob sich der Filter geändert hat, seit er das letzte Mal gesendet wurde.
  3. Wenn das Flag gesetzt ist, bauen Sie die Anfrage mit insert_into_subscribe_request() neu. In JavaScript können Sie sie im selben Stream mit stream.write(request) erneut senden; in Rust abonnieren Sie mit der neu aufgebauten Anfrage erneut.

FAQ

Nein. Cuckoo-Filter erzeugen falsch positive Ergebnisse (zusätzliche Updates für nicht verfolgte Konten), aber nie falsch negative. Jedes Update für ein verfolgtes Konto wird geliefert.
Unter 1% bei voller Auslastung und typischerweise weniger, wenn der Filter unterhalb der Kapazität liegt. Ein lokaler contains()-Aufruf pro Update filtert sie genau aus.
Das Rust SDK (helius-laserstream 0.2.0+), das JavaScript/TypeScript SDK (helius-laserstream 0.4.0+) und der Yellowstone Rust-Client (yellowstone-grpc-client 13.1.0+). Das Go SDK unterstützt es noch nicht. Siehe die Verfügbarkeitstabelle oben.
Ja. Standard account: [...]-Filter funktionieren unverändert und bleiben die richtige Wahl für kleine Kontosets (bis zu etwa 10.000 Konten). Siehe den Kontofilterungs-Leitfaden.

Verwandt

Kontenabonnements

Standardmäßige Kontofilterung mit Besitzer-, Datengrößen- und Memcmp-Filtern.

Clients & SDKs

TypeScript-, Rust- und Go-SDKs mit automatischer Wiederholung und Wiederverbindung.