Solana Geyser gRPC - Filter

Solana Stream SDK
Das Solana Stream SDK wird als Open-Source-Software bereitgestellt. Weitere Informationen finden Sie im GitHub-Repository unten.

Überblick über die gRPC-Filter

Solana Geyser gRPC verwendet Filter, um effizient nur die Daten abzurufen, die Sie interessieren, etwa bestimmte Konten, Programme, Transaktionen, Slots und Blöcke.
Im Folgenden finden Sie TypeScript-Beispiele mit dem Solana Stream SDK, in denen die konkrete Rolle jedes Filters verständlich erklärt wird. Aufbau und Bedeutung der Filter sind bei der Verwendung von Rust identisch.

Aktuelle Filterregeln für Shared

Im aktuellen Shared-Plan ist jede nicht leere blocks-Map nur mit Dedicated verfügbar, auch wenn die Anfrage mit accountInclude oder durch den Ausschluss von Transaktionen eingegrenzt ist. Verwenden Sie ein Transaktionsabonnement oder blocksMeta, wenn das Ihre Anforderungen erfüllt; keines von beiden ist gleichwertig mit vollständigen Blöcken. Für vollständige Blöcke ist ein Dedicated Geyser gRPC-Stream erforderlich.
Jeder Eintrag eines Kontofilters muss account, owner oder einen unterstützten Cuckoo-Filter enthalten. Eine Bedingung mit memcmp oder dataSize allein wählt keine unterstützte Kontoform aus. Grenzen Sie die Anfrage auf einen dieser Selektoren ein, oder verwenden Sie Dedicated Geyser gRPC, wenn ein vollständiger Konto-Stream erforderlich ist.

Rollen und Beispiele der einzelnen Filter

Ein Konto abonnieren

Abonnieren Sie Echtzeit-Updates für ein bestimmtes Konto. Das folgende Beispiel abonniert das OpenBook-Konto für SOL-USDC auf der Commitment-Stufe Confirmed:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: { slots: {} },
  accounts: {
    'wsol/usdc': {
      account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
}
  • "wsol/usdc" ist ein vom Client festgelegtes Label.
  • Mehrere Filter für Konten, Programme, Blöcke und Slots lassen sich in einer einzigen JSON-Anfrage kombinieren.

Ein Konto mit account_data_slice abonnieren

Dieses Beispiel zeigt, wie Sie nur einen bestimmten Teil der Kontodaten abrufen. Statt die gesamten Daten (165 Bytes) eines USDC-Token-Kontos abzurufen, werden 40 Bytes ab Offset 32 abgerufen. Dieser Bereich enthält Informationen wie den Eigentümer und das Guthaben in Lamports.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {
    usdc: {
      owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
      filters: [
        {
          tokenAccountState: true,
        },
        {
          memcmp: {
            offset: 0,
            data: {
              base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
            },
          },
        },
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  commitment: CommitmentLevel.CONFIRMED,
  accountsDataSlice: [{ offset: 32, length: 40 }],
}

Ein Programm abonnieren

Dieses Beispiel zeigt, wie Sie Konto-Updates abonnieren, die zu einem bestimmten Programm gehören.
Im Folgenden abonnieren wir Konto-Updates für Konten, die dem Programm Solend gehören, auf der Commitment-Stufe Processed.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
  • "solend" ist ein benutzerdefiniertes Label, das der Client frei festlegen kann.
  • Wenn Sie mehrere Programme abonnieren möchten, lesen Sie bitte den nächsten Abschnitt „Mehrere Programme abonnieren“.

Mehrere Programme abonnieren

Dieses Beispiel zeigt, wie Sie Konto-Updates, die zu mehreren Programmen gehören, auf einmal abonnieren.
Das folgende Beispiel abonniert Updates für Konten, die den Programmen Solend und Serum gehören.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    programs: {
      owner: [
        'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo',
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
Wenn Sie jedem Programm lieber ein eigenes Label zuweisen möchten, gehen Sie wie folgt vor:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
    serum: {
      owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Alle finalisierten Transaktionen außer Vote- und fehlgeschlagenen Transaktionen abonnieren

Dieses Beispiel zeigt, wie Sie alle Transaktionen auf der Commitment-Stufe Finalized abonnieren, ausgenommen Vote-Transaktionen und fehlgeschlagene Transaktionen.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    alltxs: {
      vote: false,
      failed: false,
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.FINALIZED,
}
  • vote: false schließt Vote-Transaktionen aus.
  • failed: false schließt fehlgeschlagene Transaktionen aus.
  • Wenn Felder leer gelassen werden, werden alle Transaktionen abgerufen.
  • Wenn mehrere Felder angegeben sind, werden sie mit einer UND-Bedingung verknüpft.

Nicht-Vote-Transaktionen abonnieren, die ein Konto referenzieren

Dieses Beispiel zeigt, wie Sie Transaktionen abonnieren, an denen ein bestimmtes Konto beteiligt ist, Vote-Transaktionen jedoch ausschließen.
Das folgende Beispiel abonniert Nicht-Vote-Transaktionen, die Konten referenzieren, die mit dem Programm Serum verknüpft sind.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      vote: false,
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Transaktionen unter Ausschluss von Konten abonnieren

Dieses Beispiel zeigt, wie Sie Transaktionen abonnieren und dabei Transaktionen ausschließen, an denen bestimmte Konten beteiligt sind.
Das folgende Beispiel ruft Transaktionen ab und schließt dabei alle Konten aus, die den Programmen Serum und Tokenkeg gehören.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountExclude: [
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
      ],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Transaktionen abonnieren, die Konten referenzieren und bestimmte Konten ausschließen

Dieses Beispiel zeigt, wie Sie Transaktionen abonnieren, an denen bestimmte Konten beteiligt sind, und dabei andere angegebene Konten ausdrücklich ausschließen.
Das folgende Beispiel abonniert Transaktionen, die das Konto von Serum referenzieren, schließt aber ein angegebenes Konto aus:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
      accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Eine Transaktionssignatur abonnieren

Dieses Beispiel zeigt, wie Sie Echtzeit-Updates für eine bestimmte Transaktionssignatur abonnieren, bis sie den Status Confirmed oder Finalized erreicht.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {
    sign: {
      signature:
        '5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Slots abonnieren

Dieses Beispiel zeigt, wie Sie Benachrichtigungen über eingehende Slots abonnieren. Außer der Vergabe eines benutzerdefinierten Tag-Namens sind keine weiteren Angaben erforderlich:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    incoming_slots: {},
  },
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Blöcke abonnieren (im aktuellen Shared-Plan nur mit Dedicated)

Abonnieren Sie Echtzeit-Updates aller erzeugten Blöcke. Standardmäßig werden alle Transaktionen innerhalb eines Blocks abgerufen:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {},
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Um Transaktionen auszuschließen und nur aktualisierte Kontoinformationen abzurufen (im aktuellen Shared-Plan nur mit Dedicated):

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      includeTransactions: false,
      includeAccounts: true,
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Um nur Transaktionen/Konten abzurufen, an denen bestimmte Konten beteiligt sind (im aktuellen Shared-Plan nur mit Dedicated):

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Block-Metadaten abonnieren

Abonnieren Sie nur Benachrichtigungen über Block-Metadaten, wenn Blöcke verarbeitet werden. Detaillierte Transaktionsdaten sind nicht enthalten.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {
    blockmetadata: {},
  },
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

Commitment-Stufen verwalten

Der Solana Geyser gRPC-Stream verwendet standardmäßig die Commitment-Stufe Processed.
Sie können höhere Commitment-Stufen wie Confirmed oder Finalized angeben. In diesen Fällen puffert Geyser die Daten und sendet Benachrichtigungen, sobald die angegebene Commitment-Stufe erreicht ist.
Für maximale Leistung wird empfohlen, die Verwaltung der Commitment-Stufen auf der Client-Seite zu übernehmen.
So geben Sie die Commitment-Stufen an:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
  • PROCESSED: Daten unmittelbar nach der Verarbeitung. Schneller Abruf, aber noch nicht bestätigt.
  • CONFIRMED: Vom Cluster bestätigte Daten, die eine höhere Sicherheit bieten.
  • FINALIZED: Vollständig finalisierte Daten ohne Risiko einer Reorganisation.

Vorteile der Arbeit mit Processed

Der Hauptvorteil der Commitment-Stufe Processed ist der sofortige Abruf von Transaktionen, der eine schnelle Verarbeitung auf der Client-Seite ermöglicht. Clients können anschließend die Übergänge zu Confirmed oder Finalized erkennen, was eine schnelle Reaktionsfähigkeit ermöglicht.

So verwalten Sie Confirmed und Finalized

Bei Verwendung der Stufen Confirmed oder Finalized sollten Ereignisse (Transaktionen oder Konto-Updates) pro Slot gepuffert werden.
Puffern Sie Ereignisse Slot für Slot, abonnieren Sie Slot-Benachrichtigungen und geben Sie die Ereignisse aus dem Puffer frei, sobald ein bestimmter Slot das gewünschte Commitment (Confirmed oder Finalized) erreicht.
Ereignisse werden zunächst empfangen, bevor ein Slot Confirmed oder Finalized erreicht.

Die Besonderheit von Finalized

Aufgrund der Spezifikation von Solana Geyser erhalten nicht alle Slots eine explizite Benachrichtigung über die Finalisierung. Wenn Sie also für einen Slot eine Benachrichtigung über die Finalisierung erhalten, müssen Sie alle Vorgänger-Slots als finalisiert behandeln, auch wenn für sie keine Benachrichtigung explizit empfangen wurde.
Konkret gilt: Behandeln Sie nach dem Empfang einer Benachrichtigung über die Finalisierung alle Vorgänger-Slots rückwirkend als finalisiert.