---
title: "Solana Geyser gRPC - 过滤器"
description: "SLV - Solana Geyser gRPC - 过滤器"
canonical: "https://erpc.global/zh/doc/geyser-grpc/filter/"
locale: "zh"
---

# Solana Geyser gRPC - 过滤器

![Solana Stream SDK](https://storage.validators.solutions/SolanaStreamSDK.jpg)

Solana Stream SDK 作为开源软件提供。更多详情请访问以下 GitHub 仓库。

[https://github.com/ValidatorsDAO/solana-stream](https://github.com/ValidatorsDAO/solana-stream)

### gRPC 过滤器概述

Solana Geyser gRPC 使用过滤器高效获取您感兴趣的数据，如特定账户、程序、交易、slot 和区块。

以下是使用 Solana Stream SDK 的 TypeScript 示例，清楚地说明了每个过滤器的具体作用。使用 Rust 时，过滤器的结构和含义完全相同。

## 当前 Shared 的过滤器规则

在当前的 Shared 方案中，任何非空的 `blocks` map 都仅限 Dedicated，包括使用 `accountInclude` 或排除交易来缩小范围的请求。如果交易订阅或 `blocksMeta` 能满足需求，请使用它们；但两者都不等同于完整区块。完整区块需要 Dedicated Geyser gRPC 流。

每个账户过滤器条目都必须包含 `account`、`owner` 或受支持的 cuckoo 过滤器。仅有 `memcmp` 或 `dataSize` 条件，无法选出受支持的账户订阅形式。请使用上述选择器之一缩小请求范围；如需完整的账户流，请使用 Dedicated Geyser gRPC。

## 各过滤器的作用和示例

### 订阅账户

订阅特定账户的实时更新。以下示例以 Confirmed 确认级别订阅 SOL-USDC OpenBook 账户：

```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"` 是客户端自定义的标签。
- 账户、程序、区块和 slot 的多个过滤器可以在单个 JSON 请求中组合使用。

### 使用 `account_data_slice` 订阅账户

此示例演示仅检索账户数据的特定部分。不获取 USDC 代币账户的全部数据（165 字节），而是从偏移量 32 开始检索 40 字节。此范围包含所有者和 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 }],
}
```

### 订阅程序

此示例演示订阅与特定程序关联的账户更新。

以下以 `Processed` 确认级别订阅 Solend 程序拥有的账户更新。

```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"` 是客户端可以自由设置的自定义标签。
- 要订阅多个程序，请参阅下一节"订阅多个程序"。

### 订阅多个程序

此示例演示如何同时订阅与多个程序关联的账户更新。

以下示例订阅 Solend 和 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,
}
```

如果您希望为每个程序分配单独的标签，请使用以下方式：

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

### 订阅所有已最终确认的非投票且未失败的交易

此示例演示以 `Finalized` 确认级别订阅所有交易，排除投票交易和失败交易。

```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` 排除投票交易。
- `failed: false` 排除失败交易。
- 如果字段留空，将检索所有交易。
- 指定多个字段时，它们以 AND 条件运行。

### 订阅涉及特定账户的非投票交易

此示例演示订阅涉及特定账户但排除投票交易的交易。

以下示例订阅涉及 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,
}
```

### 订阅排除特定账户的交易

此示例演示订阅排除涉及特定账户的交易。

以下示例检索排除 Serum 和 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,
}
```

### 订阅涉及特定账户并排除某些账户的交易

此示例演示订阅涉及某些账户的交易，同时明确排除其他指定账户。

以下示例订阅涉及 Serum 账户的交易，但排除指定账户：

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

### 订阅交易签名

此示例演示订阅特定交易签名的实时更新，直到它达到 `Confirmed` 或 `Finalized` 状态。

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

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

### 订阅 slot

此示例演示订阅传入 slot 的通知。除了分配自定义标签名称外，无需其他详细信息：

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

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

### 订阅区块（在当前的 Shared 方案中仅限 Dedicated）

订阅所有生成区块的实时更新。默认情况下，将检索区块内的所有交易：

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

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

#### 排除交易，仅检索更新的账户信息（在当前的 Shared 方案中仅限 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,
}
```

#### 仅检索涉及特定账户的交易/账户（在当前的 Shared 方案中仅限 Dedicated）：

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

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

### 订阅区块元数据

仅订阅区块处理时的区块元数据通知。不包含详细的交易数据。

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

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

## 管理确认级别

Solana Geyser gRPC 流默认使用 `Processed` 确认级别。

您可以指定更高的确认级别，如 `Confirmed` 或 `Finalized`。在这些情况下，Geyser 会缓冲数据并在达到指定的确认级别后发送通知。

为获得最佳性能，建议在客户端管理确认级别。

以下是指定确认级别的方法：

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

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
```

- **`PROCESSED`**：处理后的即时数据。检索速度快，但尚未确认。
- **`CONFIRMED`**：经集群确认的数据，提供更高的确定性。
- **`FINALIZED`**：完全最终确认的数据，没有重组风险。

### 使用 `Processed` 的优势

`Processed` 确认级别的主要优势是即时交易检索，能够快速进行客户端处理。客户端随后可以检测到向 `Confirmed` 或 `Finalized` 的转换，提供快速响应能力。

### 如何管理 `Confirmed` 和 `Finalized`

使用 `Confirmed` 或 `Finalized` 级别时，应按 slot 缓冲事件（交易或账户更新）。

按 slot 缓冲事件，订阅 slot 通知，并在特定 slot 达到所需确认级别（`Confirmed` 或 `Finalized`）后从缓冲区释放事件。

事件最初会在 slot 达到 `Confirmed` 或 `Finalized` 之前接收。

### `Finalized` 的特殊之处

由于 Solana Geyser 规范，并非所有 slot 都会收到明确的最终确认通知。因此，当您收到某个 slot 的最终确认通知时，必须将所有祖先 slot 也视为已最终确认，即使没有收到明确的通知。

具体来说，收到最终确认通知后，追溯地将所有祖先 slot 视为已最终确认。
