> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Giám sát slot & khối bằng LaserStream

> Giám sát cơ chế đồng thuận của mạng Solana, quá trình tạo khối và các thay đổi trạng thái mạng bằng LaserStream — thời gian slot, siêu dữ liệu khối và các khối đầy đủ đã lọc.

Tính năng giám sát slot và khối giúp bạn quan sát cơ chế đồng thuận, thời gian tạo khối và tình trạng tổng thể của mạng Solana. Với LaserStream, bạn có thể theo dõi tiến trình slot, quá trình hoàn tất khối và các chỉ số hiệu suất mạng theo thời gian thực bằng SDK [`helius-laserstream`](/docs/vi/laserstream/clients).

<Info>
  **Điều kiện tiên quyết:** Hướng dẫn này giả định rằng bạn đã hoàn thành [Hướng dẫn bắt đầu nhanh với LaserStream gRPC](/docs/vi/laserstream/grpc) và có khóa API.
</Info>

***

## Các loại giám sát

<Tabs>
  <Tab title="Slot Updates">
    **Theo dõi tiến trình đồng thuận của mạng**

    Giám sát tiến trình slot trên các mức cam kết:

    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

    const subscriptionRequest: SubscribeRequest = {
      slots: {
        slotSubscribe: {
          filterByCommitment: false // Receive all commitment levels
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Dữ liệu slot bao gồm:** số slot, slot cha, trạng thái cam kết (`processed` / `confirmed` / `finalized`) và thông tin leader.

    <Note>
      **Phù hợp nhất cho:** Giám sát tình trạng mạng, phân tích thời gian slot, theo dõi đồng thuận.
    </Note>
  </Tab>

  <Tab title="Block Data">
    **Giám sát đầy đủ thông tin khối**

    Truyền phát các khối đầy đủ cùng giao dịch và nội dung cập nhật tài khoản:

    ```typescript theme={"system"}
    const subscriptionRequest: SubscribeRequest = {
      blocks: {
        blockSubscribe: {
          accountInclude: [], // All accounts
          includeTransactions: true,
          includeAccounts: true,
          includeEntries: false
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      slots: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Dữ liệu khối bao gồm:** siêu dữ liệu khối, giao dịch, nội dung cập nhật tài khoản, thời gian khối.

    <Warning>
      **Lưu lượng lớn:** Các luồng khối đầy đủ tạo ra lượng dữ liệu đáng kể. Sử dụng bộ lọc `accountInclude` để giảm lưu lượng.
    </Warning>
  </Tab>

  <Tab title="Block Metadata">
    **Thông tin khối gọn nhẹ**

    Lấy siêu dữ liệu khối mà không cần chi tiết giao dịch:

    ```typescript theme={"system"}
    const subscriptionRequest: SubscribeRequest = {
      blocksMeta: {
        blockMetaSubscribe: {}
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, transactions: {}, transactionsStatus: {},
      slots: {}, blocks: {}, entry: {}, accountsDataSlice: [],
    };
    ```

    **Siêu dữ liệu bao gồm:** hàm băm khối, hàm băm khối cha, slot, chiều cao, số lượng giao dịch, phần thưởng.

    <Tip>
      **Hiệu quả:** Giải pháp thay thế sử dụng ít băng thông hơn so với truyền phát khối đầy đủ.
    </Tip>
  </Tab>
</Tabs>

***

## Ví dụ thực tế

### Ví dụ 1: Trình giám sát tình trạng mạng

Theo dõi tiến trình slot và xác định các sự cố mạng:

```typescript [expandable] theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

let lastSlot = 0;
let lastTimestamp = Date.now();
const slotTimes: number[] = [];

// CommitmentLevel only ships the forward (name → number) mapping, so we keep
// a small reverse lookup for the numeric status the SDK returns on slot updates.
const STATUS_NAMES = ['PROCESSED', 'CONFIRMED', 'FINALIZED'] as const;

async function monitorNetworkHealth() {
  const subscriptionRequest: SubscribeRequest = {
    slots: {
      slotSubscribe: {
        filterByCommitment: true // Track processed commitment levels
      }
    },
    commitment: CommitmentLevel.PROCESSED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.slot) return;
    const slot = data.slot;
    // The SDK returns u64 fields as strings to preserve precision.
    const currentSlot = Number(slot.slot);
    const currentTime = Date.now();

    console.log(`\n📊 Slot Update:`);
    console.log(`  Slot: ${currentSlot}`);
    console.log(`  Parent: ${slot.parent}`);
    // slot.status is a numeric enum (0=processed, 1=confirmed, 2=finalized).
    console.log(`  Status: ${STATUS_NAMES[slot.status] ?? slot.status}`);

    if (lastSlot > 0) {
      const slotDiff = currentSlot - lastSlot;
      const timeDiff = currentTime - lastTimestamp;

      if (slotDiff === 1) {
        slotTimes.push(timeDiff);
        if (slotTimes.length > 100) slotTimes.shift();

        const avg = slotTimes.reduce((a, b) => a + b, 0) / slotTimes.length;
        console.log(`  Slot Time: ${timeDiff}ms`);
        console.log(`  Avg Slot Time: ${avg.toFixed(1)}ms`);

        if (timeDiff > 800) {
          console.log(`  ⚠️  SLOW SLOT: ${timeDiff}ms (normal ~400ms)`);
        }
      } else if (slotDiff > 1) {
        console.log(`  ⚠️  SKIPPED ${slotDiff - 1} SLOTS`);
      }
    }

    lastSlot = currentSlot;
    lastTimestamp = currentTime;
  }, async (error) => {
    console.error('Stream error:', error);
  });
}

monitorNetworkHealth().catch(console.error);
```

### Ví dụ 2: Trình giám sát quá trình tạo khối

Theo dõi quá trình tạo khối và khối lượng giao dịch:

```typescript [expandable] theme={"system"}
async function monitorBlockProduction() {
  const subscriptionRequest: SubscribeRequest = {
    blocksMeta: {
      blockMetaSubscribe: {}
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    slots: {}, blocks: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.blockMeta) return;
    const blockMeta = data.blockMeta;

    console.log(`\n🧱 Block Produced:`);
    console.log(`  Slot: ${blockMeta.slot}`);
    // blockHeight is a wrapper object: { blockHeight: '397657352' }
    console.log(`  Block Height: ${blockMeta.blockHeight?.blockHeight}`);
    console.log(`  Block Hash: ${blockMeta.blockhash}`);
    console.log(`  Parent Slot: ${blockMeta.parentSlot}`);
    console.log(`  Parent Hash: ${blockMeta.parentBlockhash}`);
    console.log(`  Transactions: ${blockMeta.executedTransactionCount}`);
    console.log(`  Entries: ${blockMeta.entriesCount}`);
    if (blockMeta.blockTime?.timestamp) {
      // blockTime.timestamp is a u64 as a string (Unix seconds).
      console.log(`  Block Time: ${new Date(Number(blockMeta.blockTime.timestamp) * 1000).toISOString()}`);
    }

    // rewards is a wrapper object: { rewards: [...], numPartitions: number | null }
    if (blockMeta.rewards?.rewards?.length > 0) {
      console.log(`  Rewards:`);
      blockMeta.rewards.rewards.forEach((r: any) => {
        console.log(`    ${r.pubkey}: ${r.lamports} lamports (${r.rewardType})`);
      });
    }

    if (Number(blockMeta.executedTransactionCount) > 3000) {
      console.log(`  🔥 HIGH ACTIVITY: ${blockMeta.executedTransactionCount} transactions`);
    }
  }, async (error) => {
    console.error('Stream error:', error);
  });
}
```

### Ví dụ 3: Trình giám sát khối đã lọc

Giám sát các khối chứa hoạt động của chương trình cụ thể:

```typescript [expandable] theme={"system"}
async function monitorDEXBlocks() {
  const subscriptionRequest: SubscribeRequest = {
    blocks: {
      blockSubscribe: {
        accountInclude: [
          "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium
          "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK", // Raydium CLMM
          "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"   // Jupiter
        ],
        includeTransactions: true,
        includeAccounts: false,
        includeEntries: false
      }
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {}, transactions: {}, transactionsStatus: {},
    slots: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
  };

  const config: LaserstreamConfig = {
    apiKey: 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  };

  await subscribe(config, subscriptionRequest, async (data) => {
    if (!data.block) return;
    const block = data.block;

    let successfulDexTx = 0;
    let totalFees = 0; // lamports
    block.transactions?.forEach((tx: any) => {
      if (tx.meta && !tx.meta.err) {
        successfulDexTx++;
        // tx.meta.fee is a u64 string — coerce before adding.
        totalFees += Number(tx.meta.fee ?? 0);
      }
    });

    console.log(`\n🔄 DEX Activity Block:`);
    console.log(`  Slot: ${block.slot}`);
    console.log(`  Block Height: ${block.blockHeight?.blockHeight}`);
    console.log(`  Block Hash: ${block.blockhash}`);
    console.log(`  Total transactions in block: ${block.executedTransactionCount}`);
    console.log(`  Matched DEX transactions: ${block.transactions?.length ?? 0}`);
    console.log(`  Successful DEX transactions: ${successfulDexTx}`);
    if (successfulDexTx > 0) {
      console.log(`  Total Fees: ${(totalFees / 1e9).toFixed(4)} SOL`);
      console.log(`  Avg Fee: ${(totalFees / successfulDexTx / 1e9).toFixed(6)} SOL`);
    }
  }, async (error) => {
    console.error('Stream error:', error);
  });
}
```

***

## Cấu trúc dữ liệu

<Accordion title="Slot Data Structure">
  ```typescript theme={"system"}
  {
    slot: string;     // Current slot number (u64 as string)
    parent: string;   // Parent slot number (u64 as string)
    status: number;   // CommitmentLevel enum: 0 = processed, 1 = confirmed, 2 = finalized
  }
  ```

  Mỗi slot đại diện cho khoảng 400 mili giây thời gian mạng. Ba mức cam kết phản ánh mức đảm bảo tăng dần: `processed` (ban đầu), `confirmed` (được đa số áp đảo bỏ phiếu), `finalized` (không thể đảo ngược).

  <Tip>
    Các trường u64 (slot, parent) được trả về dưới dạng chuỗi để duy trì độ chính xác vượt quá `Number.MAX_SAFE_INTEGER`. Chuyển đổi bằng `Number(slot.slot)` khi cần thực hiện phép toán. `status` là một enum dạng số — sử dụng `CommitmentLevel[slot.status]` để lấy tên mà con người có thể đọc được.
  </Tip>
</Accordion>

<Accordion title="Block Metadata Structure">
  ```typescript theme={"system"}
  {
    slot: string;                                  // u64 as string
    blockhash: string;
    rewards: {
      rewards: Array<{
        pubkey: string;
        lamports: string;                          // u64 as string
        rewardType: string;                        // "fee" | "rent" | "voting" | "staking"
      }>;
      numPartitions: number | null;
    };
    blockTime: { timestamp: string };              // Unix seconds as a u64 string
    blockHeight: { blockHeight: string };          // u64 as string, wrapped
    parentSlot: string;                            // u64 as string
    parentBlockhash: string;
    executedTransactionCount: string;              // u64 as string
    entriesCount: string;                          // u64 as string
  }
  ```

  <Tip>
    Các trường số (slot, parentSlot, executedTransactionCount, entriesCount, các giá trị bên trong `blockHeight` và `blockTime`) được xuất dưới dạng chuỗi vì chúng là u64 trong proto cơ sở. Bao chúng bằng `Number(...)` để thực hiện phép toán hoặc so sánh.
  </Tip>
</Accordion>

<Accordion title="Full Block Structure">
  ```typescript theme={"system"}
  {
    slot: string;                                  // u64 as string
    blockhash: string;
    rewards: {
      rewards: Array<{
        pubkey: string;
        lamports: string;                          // u64 as string
        rewardType: string;
      }>;
      numPartitions: number | null;
    };
    blockTime: { timestamp: string };              // Unix seconds (u64 string)
    blockHeight: { blockHeight: string };          // u64 as string, wrapped
    parentSlot: string;                            // u64 as string
    parentBlockhash: string;
    executedTransactionCount: string;              // total executed tx in the block (u64 as string)
    updatedAccountCount: string;                   // total account updates in the block (u64 as string)
    entriesCount: string;                          // u64 as string
    transactions: Array<{
      signature: Buffer;                           // base58-encode for display
      isVote: boolean;
      transaction: TransactionMessage;             // full transaction payload
      meta: TransactionMeta;                       // execution metadata (fee, err, balances, …)
      index: string;                               // u64 as string
    }>;
    accounts: AccountUpdate[];                     // populated when includeAccounts: true
    entries: Entry[];                              // populated when includeEntries: true
  }
  ```

  Các khối đầy đủ có thể có kích thước vài MB khi chứa toàn bộ giao dịch và tài khoản. Quy ước biểu diễn u64 dưới dạng chuỗi cũng được áp dụng — bao các trường số bằng `Number(...)` để thực hiện phép toán. Bên trong mỗi giao dịch, `meta.fee`, `meta.preBalances`, `meta.postBalances`, v.v. cũng là các chuỗi.
</Accordion>

***

## Các yếu tố cần cân nhắc về hiệu suất

<CardGroup cols={2}>
  <Card title="Slot Monitoring" icon="clock">
    Gọn nhẹ: băng thông rất thấp, chi phí xử lý tối thiểu. Phù hợp cho các bảng điều khiển giám sát.
  </Card>

  <Card title="Block Metadata" icon="info">
    Cân bằng: băng thông vừa phải, cung cấp thông tin chuyên sâu ở cấp khối mà không cần toàn bộ dữ liệu. Phù hợp cho hoạt động phân tích.
  </Card>

  <Card title="Full Blocks" icon="database">
    Lưu lượng lớn: dữ liệu giao dịch đầy đủ, yêu cầu khả năng xử lý mạnh mẽ. Luôn kết hợp với các bộ lọc.
  </Card>

  <Card title="Filtered Blocks" icon="filter">
    Được tối ưu hóa: sử dụng `accountInclude`, tắt `includeAccounts`/`includeEntries` nếu không cần.
  </Card>
</CardGroup>

***

## Trường hợp sử dụng

<Tabs>
  <Tab title="Network Monitoring">
    Theo dõi tình trạng và hiệu suất mạng — thời gian slot, tắc nghẽn, đồng thuận.

    ```typescript theme={"system"}
    const targetSlotTime = 400; // ms
    const tolerance = 200; // ms
    if (Math.abs(slotTime - targetSlotTime) > tolerance) {
      console.log(`Network performance issue detected`);
    }
    ```
  </Tab>

  <Tab title="Analytics & Metrics">
    Thu thập dữ liệu phân tích blockchain — khối lượng giao dịch, phân tích phí, kích thước khối, mô hình hoạt động.

    ```typescript theme={"system"}
    const dailyStats = {
      date: new Date().toDateString(),
      totalTransactions: 0,
      totalFees: 0,
      blockCount: 0
    };
    ```
  </Tab>

  <Tab title="Application Synchronization">
    Duy trì đồng bộ ứng dụng với mạng — cập nhật dựa trên slot, xác nhận khối.

    ```typescript theme={"system"}
    if (data.slot && data.slot.status === 'finalized') {
      updateApplicationState(data.slot.slot);
    }
    ```
  </Tab>
</Tabs>

***

## Xử lý lỗi

<Accordion title="Missing Slots">
  **Triệu chứng:** Có khoảng trống trong tiến trình slot.

  **Nguyên nhân:** Sự cố kết nối mạng, validator ngừng hoạt động, độ trễ xử lý phía máy khách.

  **Giải pháp:** Theo dõi và cảnh báo khoảng trống slot; triển khai logic bắt kịp thông qua [phát lại dữ liệu lịch sử](/docs/vi/laserstream/historical-replay); giám sát tình trạng kết nối.
</Accordion>

<Accordion title="High Volume">
  **Triệu chứng:** Có quá nhiều dữ liệu khối.

  **Giải pháp:** Sử dụng siêu dữ liệu khối thay cho khối đầy đủ; áp dụng bộ lọc tài khoản; tắt các nội dung không cần thiết (mục nhập, tài khoản); xử lý bất đồng bộ.
</Accordion>

<Accordion title="Timing Issues">
  **Triệu chứng:** Thời gian slot không nhất quán.

  **Phân tích:** Tính trung bình động; theo dõi độ lệch; giám sát các chỉ số tình trạng mạng; đối chiếu với hiệu suất của validator.
</Accordion>

***

## Các phương pháp hay nhất

<Note>
  **Hướng dẫn cho môi trường production:**

  * **Bắt đầu với siêu dữ liệu** — sử dụng siêu dữ liệu khối trước khi đăng ký nhận các khối đầy đủ
  * **Áp dụng bộ lọc** — sử dụng `accountInclude` để loại bỏ dữ liệu không liên quan
  * **Giám sát thời gian** — theo dõi tiến trình slot như một chỉ báo cảnh báo sớm về tình trạng mạng
  * **Xử lý khoảng trống** — kết hợp với [phát lại dữ liệu lịch sử](/docs/vi/laserstream/historical-replay) để các slot bị thiếu được tự động bổ sung khi kết nối lại
  * **Xử lý bất đồng bộ** — không chặn quá trình xử lý luồng bằng các phép tính nặng
  * **Chọn mức cam kết phù hợp với nhu cầu** — `processed` cho giao diện người dùng có độ trễ thấp, `confirmed`/`finalized` cho thao tác ghi trạng thái
</Note>

***

## Các bước tiếp theo

<CardGroup cols={2}>
  <Card title="Transaction Monitoring" icon="receipt" href="/docs/vi/laserstream/guides/transaction-monitoring">
    Lọc giao dịch theo chương trình, tài khoản, phiếu bầu hoặc trạng thái lỗi.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/vi/laserstream/guides/stream-pump-amm-data">
    Ví dụ thực tế: giám sát các giao dịch Pump AMM.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/vi/laserstream/guides/decoding-transaction-data">
    Phân tích các payload nhị phân `transactionUpdate` thành các giao dịch Solana có thể đọc được.
  </Card>

  <Card title="Yellowstone protocol reference" icon="book" href="/docs/vi/grpc/slot-and-block-monitoring">
    Quy trình tương tự khi làm việc trực tiếp với giao thức Yellowstone gRPC thô.
  </Card>
</CardGroup>
