Solana Geyser gRPC - Filter

Solana Stream SDK
Solana Stream SDK disediakan sebagai perangkat lunak open source. Untuk detail lebih lanjut, silakan kunjungi repositori GitHub di bawah ini.

Ikhtisar Filter gRPC

Solana Geyser gRPC menggunakan filter untuk secara efisien mengambil hanya data yang menarik bagi Anda, seperti akun, program, transaksi, slot, dan blok tertentu.
Di bawah ini, kami menyajikan contoh TypeScript yang menggunakan Solana Stream SDK dan menjelaskan dengan jelas peran spesifik setiap filter. Struktur dan makna filter tetap sama saat menggunakan Rust.

Peran dan Contoh Setiap Filter

Berlangganan ke akun

Berlangganan pembaruan real-time untuk akun tertentu. Contoh berikut berlangganan ke akun SOL-USDC OpenBook pada tingkat komitmen 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" adalah label yang didefinisikan oleh klien.
  • Beberapa filter untuk akun, program, blok, dan slot dapat dikombinasikan dalam satu permintaan JSON.

Berlangganan ke akun dengan account_data_slice

Contoh ini menunjukkan cara mengambil hanya sebagian tertentu dari data akun. Alih-alih mengambil seluruh data (165 byte) dari akun token USDC, contoh ini mengambil 40 byte mulai dari offset 32. Rentang ini mencakup informasi seperti pemilik dan saldo 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 }],
}

Berlangganan ke program

Contoh ini menunjukkan cara berlangganan pembaruan akun yang terkait dengan program tertentu.
Di bawah ini, kami berlangganan pembaruan akun untuk akun-akun yang dimiliki oleh program Solend pada tingkat komitmen 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" adalah label kustom yang dapat diatur secara bebas oleh klien.
  • Untuk berlangganan ke beberapa program, silakan lihat bagian berikutnya yang berjudul "Berlangganan ke beberapa program".

Berlangganan ke beberapa program

Contoh ini menunjukkan cara berlangganan pembaruan akun yang terkait dengan beberapa program sekaligus.
Contoh di bawah ini berlangganan pembaruan untuk akun yang dimiliki oleh program Solend dan Serum.
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,
}
Jika Anda lebih suka memberikan label tersendiri untuk setiap program, gunakan pendekatan berikut:
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,
}

Berlangganan ke semua transaksi finalized yang bukan vote dan tidak gagal

Contoh ini menunjukkan cara berlangganan ke semua transaksi pada tingkat komitmen Finalized, dengan mengecualikan transaksi vote dan transaksi yang gagal.
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 mengecualikan transaksi vote.
  • failed: false mengecualikan transaksi yang gagal.
  • Jika field dibiarkan kosong, semua transaksi akan diambil.
  • Jika beberapa field ditentukan, semuanya berlaku dengan kondisi AND.

Berlangganan ke transaksi non-vote yang menyebutkan akun

Contoh ini menunjukkan cara berlangganan ke transaksi yang melibatkan akun tertentu tetapi mengecualikan transaksi vote.
Contoh di bawah ini berlangganan ke transaksi non-vote yang menyebutkan akun yang terkait dengan program Serum.
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,
}

Berlangganan ke transaksi dengan mengecualikan akun

Contoh ini menunjukkan cara berlangganan ke transaksi dengan mengecualikan transaksi yang melibatkan akun tertentu.
Contoh di bawah ini mengambil transaksi dengan mengecualikan akun apa pun yang dimiliki oleh program Serum dan Tokenkeg.
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,
}

Berlangganan ke transaksi yang menyebutkan akun & mengecualikan akun tertentu

Contoh ini menunjukkan cara berlangganan ke transaksi yang melibatkan akun tertentu, sekaligus secara eksplisit mengecualikan akun lain yang ditentukan.
Contoh di bawah ini berlangganan ke transaksi yang menyebutkan akun Serum tetapi mengecualikan akun tertentu:
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,
}

Berlangganan ke tanda tangan transaksi

Contoh ini menunjukkan cara berlangganan pembaruan real-time untuk tanda tangan transaksi tertentu, hingga transaksi tersebut mencapai status Confirmed atau Finalized.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Berlangganan ke slot

Contoh ini menunjukkan cara berlangganan notifikasi slot yang masuk. Tidak ada detail tambahan yang diperlukan selain menetapkan nama tag kustom:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Berlangganan ke blok

Berlangganan pembaruan real-time dari semua blok yang dihasilkan. Secara default, semua transaksi dalam blok akan diambil:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Untuk mengecualikan transaksi dan hanya mengambil informasi akun yang diperbarui:

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,
}

Untuk hanya mengambil transaksi/akun yang melibatkan akun tertentu:

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

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

Berlangganan ke metadata blok

Berlangganan hanya ke notifikasi metadata blok saat blok diproses. Data transaksi yang terperinci tidak disertakan.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Mengelola tingkat komitmen

Stream Solana Geyser gRPC secara default menggunakan tingkat komitmen Processed.
Anda dapat menentukan tingkat komitmen yang lebih tinggi seperti Confirmed atau Finalized. Dalam hal ini, Geyser menyimpan data di buffer dan mengirimkan notifikasi setelah tingkat komitmen yang ditentukan tercapai.
Untuk performa maksimal, disarankan untuk menangani pengelolaan tingkat komitmen di sisi klien.
Berikut cara menentukan tingkat komitmen:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
  • PROCESSED: Data langsung setelah diproses. Pengambilannya cepat, tetapi belum dikonfirmasi.
  • CONFIRMED: Data yang telah dikonfirmasi oleh cluster, sehingga memberikan kepastian yang lebih tinggi.
  • FINALIZED: Data yang sepenuhnya final tanpa risiko reorganisasi.

Keuntungan bekerja di Processed

Keuntungan utama tingkat komitmen Processed adalah transaksi dapat diterima seketika, sehingga pemrosesan di sisi klien bisa dilakukan dengan cepat. Setelah itu, klien dapat mendeteksi transisi ke Confirmed atau Finalized, sehingga tetap responsif.

Cara mengelola Confirmed dan Finalized

Saat menggunakan tingkat Confirmed atau Finalized, event (transaksi atau pembaruan akun) sebaiknya di-buffer per slot.
Tampung event di buffer slot demi slot, berlangganan notifikasi slot, lalu lepaskan event dari buffer setelah slot tertentu mencapai komitmen yang diinginkan (Confirmed atau Finalized).
Event pada awalnya akan diterima sebelum slot mencapai Confirmed atau Finalized.

Hal khusus tentang Finalized

Karena spesifikasi Solana Geyser, tidak semua slot menerima notifikasi finalized secara eksplisit. Oleh karena itu, ketika Anda menerima notifikasi finalized untuk suatu slot, Anda harus memperlakukan semua slot leluhurnya sebagai finalized, meskipun tidak ada notifikasi yang diterima secara eksplisit.
Secara spesifik, setelah menerima notifikasi finalized, perlakukan semua slot leluhur sebagai finalized secara retroaktif.