Solana Geyser gRPC - Bộ lọc

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 repository GitHub bên dưới.

Tổng quan về bộ lọc gRPC

Solana Geyser gRPC sử dụng bộ lọc để lấy hiệu quả chỉ dữ liệu bạn quan tâm, chẳng hạn như các account, chương trình, giao dịch, slot và block cụ thể.
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 bộ lọc. Cấu trúc và ý nghĩa của các bộ lọc hoàn toàn giống nhau khi sử dụng Rust.

Vai trò và ví dụ của từng bộ lọc

Đăng ký theo dõi một account

Đăng ký cập nhật thời gian thực cho một account cụ thể. Ví dụ sau đăng ký theo dõi account SOL-USDC OpenBook ở 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 bộ lọc cho account, chương trình, block và slot có thể được kết hợp trong một request JSON duy nhất.

Đăng ký theo dõi account với account_data_slice

Ví dụ này minh họa cách 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 token account USDC, nó chỉ 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ư 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 }],
}

Đăng ký theo dõi một chương trình

Ví dụ này minh họa cách đăng ký cập nhật account liên kết với một chương trình cụ thể.
Dưới đây, chúng ta đăng ký cập nhật cho các account thuộc sở hữu của chương trình Solend ở 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 do client tự đặt.
  • Để đăng ký nhiều chương trình, vui lòng tham khảo phần tiếp theo "Đăng ký theo dõi nhiều chương trình."

Đăng ký theo dõi nhiều chương trình

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

Đăng ký tất cả giao dịch finalized không phải vote và không thất bại

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

Đăng ký giao dịch không phải vote đề cập đến một account

Ví dụ này minh họa cách đăng ký giao dịch liên quan đến một account cụ thể nhưng loại trừ giao dịch vote.
Ví dụ dưới đây đăng ký giao dịch không phải vote đề cập đến các account liên kết với chương trình 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,
}

Đăng ký giao dịch loại trừ các account

Ví dụ này minh họa cách đăng ký giao dịch loại trừ các giao dịch liên quan đến các account cụ thể.
Ví dụ dưới đây lấy giao dịch loại trừ mọi account thuộc sở hữu của chương trình Serum và 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,
}

Đăng ký giao dịch đề cập đến account & loại trừ một số account

Ví dụ này minh họa cách đăng ký giao dịch liên quan đến một số account, đồng thời loại trừ rõ ràng các account khác.
Ví dụ dưới đây đăng ký giao dịch đề cập đến 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,
}

Đăng ký theo dõi chữ ký giao dịch

Ví dụ này minh họa cách đăng ký cập nhật thời gian thực cho một chữ ký giao dịch 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,
}

Đăng ký theo dõi slot

Ví dụ này minh họa cách đăng ký thông báo về các slot đến. Không cần thêm chi tiết nào 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,
}

Đăng ký theo dõi block

Đăng ký cập nhật thời gian thực của tất cả block được tạo. Mặc định, tất cả giao dịch 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ừ giao dịch và chỉ lấy thông tin account được cập nhật:

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 giao dịch/account liên quan đến các 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,
}

Đăng ký theo dõi metadata block

Chỉ đăng ký thông báo metadata block khi block được xử lý. Dữ liệu giao dịch 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ý mức commitment

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 mức commitment được chỉ định.
Để đạt hiệu suất tối đa, khuyến nghị xử lý quản lý mức commitment ở phía client.
Cách chỉ định mức commitment:
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 cluster xác nhận, cung cấp độ chắc chắn cao hơn.
  • FINALIZED: Dữ liệu đã hoàn toàn finalize, không có rủi ro tái tổ chức.

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

Ưu điểm chính của mức commitment Processed là lấy giao dịch 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 sự kiện (giao dịch hoặc cập nhật account) nên được đệm theo từng slot.
Đệm sự kiện theo từng slot, đăng ký thông báo slot, và giải phóng sự kiện từ bộ đệm khi một slot cụ thể đạt mức commitment mong muốn (Confirmed hoặc Finalized).
Các sự kiện ban đầu 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 thông báo finalized rõ ràng. Do đó, khi bạn nhận 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 thông báo finalized, hồi tố coi tất cả slot tổ tiên là finalized.