Übersicht
LaserStream unterstützt die komprimierte Account-Filterung über Cuckoo-Filter. Anstatt in deinem subscribe request eine explizite Liste von pubkeys zu senden (32 Byte pro Account), sendest du einen kompakten probabilistischen Filter, der bei der Übertragung nur etwa 3–4 Byte pro Account benötigt. Damit kannst du Hunderttausende Accounts in einem einzigen stream abonnieren – ohne Sharding über mehrere Verbindungen und ohne übergroße subscribe requests. Ein Filter, der 500.000 Accounts verfolgt, wird beispielsweise auf etwa 2,1 MB serialisiert. Eine unkomprimierte Liste von pubkeys benötigt dagegen 16 MB – der Filter ist also ungefähr 7,6-mal kleiner. Die genaue Einsparung hängt vom Füllstand des Filters ab: Je näher er an seiner Kapazitätsgrenze liegt, desto weniger Byte werden pro Account benötigt.Verfügbarkeit
Wann du Cuckoo-Filter verwenden solltest
Typische Anwendungsfälle sind die Überwachung aller Inhaber eines token, die Verfolgung aller Positionen in einem Kreditprotokoll oder die Überwachung großer Wallet-Gruppen für ein Handels- oder Analysesystem.
Funktionsweise
- Erstelle den Filter im Client. Füge jeden verfolgten pubkey in ein
CompressedAccountFilterSetein. Der Hash-Seed wird für jeden Filter zufällig generiert und zusammen mit ihm serialisiert. Dadurch hasht der Server eingehende Accounts mit demselben Seed, den dein Client verwendet hat. - Hänge ihn an deinen subscribe request an.
insert_into_subscribe_request()fügt den serialisierten Filter in den stream für Accounts eines standardmäßigenSubscribeRequestein. - Der Server sucht probabilistisch nach Übereinstimmungen. Da der Filter probabilistisch arbeitet, kann der Server Updates für Accounts liefern, die du nicht verfolgst. Diese False Positives liegen bei voller Auslastung garantiert unter 1 %. Es gibt keine False Negatives: Jedes Update für einen verfolgten Account wird zugestellt.
- Prüfe jedes Update lokal erneut – dieser Schritt ist erforderlich. Rufe
set.contains(pubkey)für jeden eingehenden Account auf, bevor du ihn verarbeitest. Diese Prüfung ist exakt und basiert auf einem internen Hash-Set. Nach der lokalen Filterung gibt es daher keine False Positives.
Schnellstart (Rust)
Füge das SDK deinem Projekt hinzu:Cargo.toml
main.rs
rust/examples/cuckoo_account_filter.rs.
Schnellstart (JavaScript/TypeScript)
Installiere das SDK (die Cuckoo-Unterstützung erforderthelius-laserstream ab Version 0.4.0):
javascript/examples/cuckoo-account-sub.ts.
API-Referenz
CompressedAccountFilterSet umschließt den Cuckoo-Rohfilter zusammen mit einem exakten Hash-Set. Dadurch sind Änderungen und Zugehörigkeitsprüfungen immer sicher und exakt:
Die Methodennamen oben folgen den Rust-Konventionen. Das JavaScript/TypeScript SDK stellt dieselbe Oberfläche in camelCase bereit –
new CompressedAccountFilterSet(capacity) statt with_capacity, insertIntoSubscribeRequest, isDirty, takeDirty, toProto und so weiter. In JavaScript gibt insert einen booleschen Wert zurück (true, wenn der Eintrag neu hinzugefügt wurde) und löst TableFullError aus, wenn der Filter voll ist. Du kannst einen pubkey als base58-String, als 32 Rohbytes oder als beliebiges Objekt mit einer toBytes()-Methode übergeben.
Verwende immer CompressedAccountFilterSet statt des umschlossenen CuckooFilter-Rohfilters. remove() des Rohfilters kann unbemerkt das falsche Element entfernen – eine dokumentierte Fehlerquelle bei Cuckoo-Filtern. Der Wrapper kombiniert den Filter mit einem exakten Hash-Set. Dadurch sind Einfügen, Entfernen und Zugehörigkeitsprüfungen immer korrekt.
Kapazität festlegen
- Lege die Filtergröße über
with_capacity(n)anhand der maximalen Anzahl von Accounts fest, die du voraussichtlich verfolgen wirst. - Einfügen über die Kapazitätsgrenze hinaus schlägt kontrolliert mit
TableFullErrorfehl – der Filter wird nie beschädigt. In der Praxis toleriert die Tabelle eine leichte Überfüllung, bevor sie Einfügungen ablehnt. Verlasse dich aber nicht auf diesen Spielraum. - Die serialisierte Größe hängt von der Kapazität ab, nicht von der Anzahl der bereits eingefügten Accounts. Ein überdimensionierter Filter verschwendet daher Byte bei der Übertragung. Wähle eine Kapazität, die nahe an deinem tatsächlichen Maximum liegt.
Verfolgte Menge aktualisieren
Wenn sich die verfolgte Menge ändert, weil du neuen Accounts folgen oder alte entfernen möchtest:- Rufe
insert()/remove()fürCompressedAccountFilterSetauf. - Prüfe mit
is_dirty(), ob sich der Filter seit dem letzten Senden geändert hat. Alternativ kannst du das Flag mittake_dirty()abrufen und zurücksetzen. - Wenn der Filter geändert wurde, erstelle den request mit
insert_into_subscribe_request()neu. In JavaScript kannst du ihn mitstream.write(request)erneut über denselben stream senden. In Rust abonnierst du mit dem neu erstellten request erneut.
FAQ
Can I miss updates for accounts in my filter?
Can I miss updates for accounts in my filter?
Nein. Cuckoo-Filter erzeugen False Positives, also zusätzliche Updates für nicht verfolgte Accounts, aber keine False Negatives. Jedes Update für einen verfolgten Account wird zugestellt.
How many extra (false-positive) updates will I receive?
How many extra (false-positive) updates will I receive?
Bei voller Auslastung sind es weniger als 1 % und normalerweise noch weniger, wenn der Filter unter seiner Kapazitätsgrenze liegt. Ein lokaler Aufruf von
contains() pro Update filtert sie exakt heraus.Which clients support cuckoo filters?
Which clients support cuckoo filters?
Das Rust SDK (
helius-laserstream ab Version 0.2.0), das JavaScript/TypeScript SDK (helius-laserstream ab Version 0.4.0) und der Yellowstone Rust-Client (yellowstone-grpc-client ab Version 13.1.0). Das Go SDK unterstützt Cuckoo-Filter noch nicht. Weitere Informationen findest du oben in der Verfügbarkeitstabelle.Can I still use explicit pubkey lists?
Can I still use explicit pubkey lists?
Ja. Standardmäßige
account: [...]-Filter funktionieren unverändert und sind für kleine Account-Mengen mit bis zu etwa 10.000 Accounts weiterhin die richtige Wahl. Weitere Informationen findest du im Leitfaden zu Account-Abonnements.Funktionieren komprimierte Filter mit matchMints?
Funktionieren komprimierte Filter mit matchMints?
Ja. Wenn du einen komprimierten Filter an eine Transaktions-Subscription anhängst und
matchMints: true festgelegt ist, prüft der Server neben den Account-Keys auch die Mints der Token-Balances vor und nach der Transaktion anhand des Filters. Siehe Token-Mint-Filterung.Verwandte Themen
Account-Subscriptions
Standardmäßige Account-Filterung mit Filtern für Owner, Datengröße und memcmp.
Clients und SDKs
TypeScript-, Rust- und Go-SDKs mit automatischer Wiederholung und automatischem Neuverbinden.
Token-Mint-Filterung
Gleiche Transaktionen anhand des Token-Mints mit
matchMints ab, auch innerhalb komprimierter Filter.