Ü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
- Erstellen Sie den Filter clientseitig. Fügen Sie jeden verfolgten Pubkey in einen
CompressedAccountFilterSetein. 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. - Fügen Sie ihn Ihrer Abonnementanfrage hinzu.
insert_into_subscribe_request()platziert den serialisierten Filter in den Kontenstream eines StandardsSubscribeRequest. - 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.
- 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
main.rs
rust/examples/cuckoo_account_filter.rs.
Schnellstart (JavaScript/TypeScript)
Installieren Sie das SDK (Cuckoo-Unterstützung erforderthelius-laserstream 0.4.0+):
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
TableFullErrorfehl — 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):- Rufen Sie
insert()/remove()auf demCompressedAccountFilterSetauf. - Überprüfen Sie
is_dirty()(oder verbrauchen Sie das Flag mittake_dirty()), um zu sehen, ob sich der Filter geändert hat, seit er das letzte Mal gesendet wurde. - Wenn das Flag gesetzt ist, bauen Sie die Anfrage mit
insert_into_subscribe_request()neu. In JavaScript können Sie sie im selben Stream mitstream.write(request)erneut senden; in Rust abonnieren Sie mit der neu aufgebauten Anfrage erneut.
FAQ
Kann ich Updates für Konten in meinem Filter verpassen?
Kann ich Updates für Konten in meinem Filter verpassen?
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.
Wie viele zusätzliche (falsch-positive) Updates werde ich erhalten?
Wie viele zusätzliche (falsch-positive) Updates werde ich erhalten?
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.Welche Clients unterstützen Cuckoo-Filter?
Welche Clients unterstützen Cuckoo-Filter?
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.Kann ich immer noch explizite Pubkey-Listen verwenden?
Kann ich immer noch explizite Pubkey-Listen verwenden?
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.