Solana Geyser gRPC - Filter

Solana Stream SDK
Solana Stream SDK được cung cấp dưới dạng phần mềm mã nguồn mở. Để biết thêm chi tiết, vui lòng truy cập GitHub repository bên dưới.

Tổng quan về gRPC Filter

Solana Geyser gRPC sử dụng filter để lấy hiệu quả chỉ những dữ liệu bạn quan tâm, như account cụ thể, program, transaction, slot, và block.
Dưới đây, chúng tôi cung cấp các ví dụ TypeScript sử dụng Solana Stream SDK, giải thích rõ ràng vai trò cụ thể của từng filter. Cấu trúc và ý nghĩa của các filter là giống nhau khi sử dụng Rust.

Vai trò và ví dụ của từng Filter

Subscribe một account

Subscribe cập nhật thời gian thực cho một account cụ thể. Ví dụ sau subscribe account OpenBook SOL-USDC ở mức commitment 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" là nhãn do client tự định nghĩa.
  • Nhiều filter cho account, program, block, và slot có thể được kết hợp trong một JSON request duy nhất.

Subscribe một account với account_data_slice

Ví dụ này minh họa việc lấy chỉ một phần cụ thể của dữ liệu account. Thay vì lấy toàn bộ dữ liệu (165 byte) của một USDC token account, nó lấy 40 byte bắt đầu từ offset 32. Phạm vi này bao gồm thông tin như owner và số dư lamport.
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 }],
}

Subscribe một program

Ví dụ này minh họa việc subscribe cập nhật account liên kết với một program cụ thể.
Bên dưới, chúng ta subscribe cập nhật account cho các account thuộc sở hữu của Solend program ở mức commitment 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" là nhãn tùy chỉnh có thể được đặt tự do bởi client.
  • Để subscribe nhiều program, vui lòng tham khảo phần tiếp theo "Subscribe nhiều program".

Subscribe nhiều program

Ví dụ này minh họa cách subscribe cập nhật account liên kết với nhiều program cùng lúc.
Ví dụ bên dưới subscribe cập nhật cho account thuộc sở hữu của cả Solend và Serum program.
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,
}
Nếu bạn muốn gán nhãn riêng cho từng program, hãy sử dụng cách tiếp cận sau:
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,
}

Subscribe tất cả transaction finalized không phải vote và không thất bại

Ví dụ này minh họa việc subscribe tất cả transaction ở mức commitment Finalized, loại trừ vote transaction và transaction thất bại.
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 loại trừ vote transaction.
  • failed: false loại trừ transaction thất bại.
  • Nếu các trường để trống, tất cả transaction sẽ được lấy.
  • Khi nhiều trường được chỉ định, chúng hoạt động với điều kiện AND.

Subscribe transaction không phải vote đề cập đến một account

Ví dụ này minh họa việc subscribe transaction liên quan đến một account cụ thể nhưng loại trừ vote transaction.
Ví dụ bên dưới subscribe transaction không phải vote đề cập đến account liên kết với Serum program.
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,
}

Subscribe transaction loại trừ account

Ví dụ này minh họa việc subscribe transaction loại trừ những transaction liên quan đến account cụ thể.
Ví dụ bên dưới lấy transaction loại trừ bất kỳ account nào thuộc sở hữu của Serum và Tokenkeg program.
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,
}

Subscribe transaction đề cập account & loại trừ account nhất định

Ví dụ này minh họa việc subscribe transaction liên quan đến một số account, đồng thời loại trừ rõ ràng các account khác đã chỉ định.
Ví dụ bên dưới subscribe transaction đề cập account của Serum nhưng loại trừ một account cụ thể:
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,
}

Subscribe một transaction signature

Ví dụ này minh họa việc subscribe cập nhật thời gian thực cho một transaction signature cụ thể, cho đến khi nó đạt trạng thái Confirmed hoặc Finalized.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Subscribe slot

Ví dụ này minh họa việc subscribe thông báo về các slot đến. Không cần chi tiết bổ sung ngoài việc gán tên tag tùy chỉnh:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Subscribe block

Subscribe cập nhật thời gian thực của tất cả block được tạo. Theo mặc định, tất cả transaction trong block sẽ được lấy:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Để loại trừ transaction và chỉ lấy thông tin cập nhật account:

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

Để chỉ lấy transaction/account liên quan đến account cụ thể:

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

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

Subscribe block metadata

Chỉ subscribe thông báo block metadata khi block được xử lý. Dữ liệu transaction chi tiết không được bao gồm.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

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

Quản lý commitment level

Solana Geyser gRPC stream mặc định sử dụng mức commitment Processed.
Bạn có thể chỉ định mức commitment cao hơn như Confirmed hoặc Finalized. Trong các trường hợp này, Geyser đệm dữ liệu và gửi thông báo khi đạt được mức commitment đã chỉ định.
Để đạt hiệu suất tối đa, chúng tôi khuyến nghị xử lý quản lý commitment-level ở phía client.
Đây là cách chỉ định commitment level:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
  • PROCESSED: Dữ liệu ngay sau khi xử lý. Lấy nhanh, nhưng chưa được xác nhận.
  • CONFIRMED: Dữ liệu được xác nhận bởi cluster, cung cấp mức độ chắc chắn cao hơn.
  • FINALIZED: Dữ liệu đã hoàn tất hoàn toàn, không có rủi ro tổ chức lại.

Lợi ích của việc làm việc ở mức Processed

Ưu điểm chính của mức commitment Processed là lấy transaction ngay lập tức, cho phép xử lý nhanh ở phía client. Client sau đó có thể phát hiện chuyển đổi sang Confirmed hoặc Finalized, mang lại khả năng phản hồi nhanh.

Cách quản lý ConfirmedFinalized

Khi sử dụng mức Confirmed hoặc Finalized, các event (transaction hoặc cập nhật account) nên được đệm theo slot.
Đệm event theo từng slot, subscribe thông báo slot, và giải phóng event từ bộ đệm khi một slot cụ thể đạt commitment mong muốn (Confirmed hoặc Finalized).
Event sẽ được nhận trước khi slot đạt Confirmed hoặc Finalized.

Điều đặc biệt về Finalized

Do đặc tả của Solana Geyser, không phải tất cả slot đều nhận được thông báo finalized rõ ràng. Do đó, khi bạn nhận được thông báo finalized cho một slot, bạn phải coi tất cả slot tổ tiên là đã finalized, ngay cả khi không nhận được thông báo rõ ràng.
Cụ thể, khi nhận được thông báo finalized, hãy coi hồi tố tất cả slot tổ tiên là đã finalized.