> ## 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.

# Phát lại lịch sử LaserStream: Bổ sung dữ liệu còn thiếu

> Khôi phục sau khi mất kết nối và bổ sung dữ liệu blockchain Solana còn thiếu bằng tính năng phát lại lịch sử của LaserStream. Không bao giờ bỏ lỡ giao dịch nào nữa.

<Info>
  **Không bao giờ bỏ lỡ dữ liệu**: Tính năng Phát lại lịch sử của LaserStream đảm bảo bạn có thể khôi phục sau khi mất kết nối và bổ sung dữ liệu còn thiếu trong 48 giờ hoạt động blockchain gần nhất.
</Info>

## Phát lại lịch sử là gì?

Phát lại lịch sử là tính năng của LaserStream cho phép bạn phát lại dữ liệu blockchain gần đây bằng cách thiết lập điểm bắt đầu `fromSlot`. Tính năng này hữu ích để xử lý tình trạng mất kết nối và đảm bảo tính liên tục của dữ liệu trong các ứng dụng thời gian thực.

## Bạn có thể phát lại dữ liệu từ bao lâu trước đây

Bạn có thể phát lại tối đa khoảng 48 giờ lịch sử (khoảng 691.200 slot với thời gian mỗi slot hiện tại của Solana là khoảng 250 mili giây — số lượng slot chính xác sẽ thay đổi khi thời gian slot của mạng thay đổi), bất kể bạn đăng ký ở mức commitment nào. Hãy truyền một `fromSlot` nằm trong khoảng thời gian đó và LaserStream sẽ truyền dữ liệu từ điểm ấy đến hiện tại.

**Các lần phát lại cũ hơn trả về dữ liệu đã hoàn tất.** LaserStream lưu khoảng 20 phút slot gần nhất trong bộ nhớ; mọi dữ liệu cũ hơn được cung cấp từ kho lưu trữ lịch sử chỉ chứa các khối đã hoàn tất. Vì vậy, khi bạn phát lại một `fromSlot` cũ hơn khoảng 20 phút, dữ liệu sẽ phản ánh chuỗi đã hoàn tất — bạn sẽ không thấy các slot thuộc nhánh rẽ, các slot bị loại bỏ hoặc các bản cập nhật tài khoản trong cùng slot ở phạm vi đó, ngay cả khi đăng ký `processed` hoặc `confirmed`. Các slot trong khoảng 20 phút gần nhất vẫn tuân theo ngữ nghĩa commitment thực tế, bao gồm các nhánh rẽ và bản cập nhật tài khoản trong cùng slot.

<Warning>
  **Khoảng thời gian giới hạn**: Tính năng phát lại lịch sử chỉ bao gồm khoảng 48 giờ gần nhất. Bạn không thể phát lại dữ liệu từ các thời điểm tùy ý trong quá khứ.
</Warning>

<CardGroup cols={2}>
  <Card title="Handle Disconnections" icon="clock-rotate-left">
    Khôi phục dữ liệu bị mất trong các lần mất kết nối ngắn (tối đa 48 giờ)
  </Card>

  <Card title="Bootstrap Applications" icon="rocket">
    Khởi động ứng dụng với ngữ cảnh gần đây trong 48 giờ qua
  </Card>

  <Card title="Analyze Recent Events" icon="magnifying-glass">
    Xem lại các giao dịch và thay đổi tài khoản gần đây
  </Card>

  <Card title="Test with Recent Data" icon="flask">
    Sử dụng dữ liệu thực tế gần đây để kiểm thử và phát triển
  </Card>
</CardGroup>

## Kiểm tra khả năng phát lại

Gọi [SubscribeReplayInfo](/docs/vi/api-reference/laserstream/grpc/subscribereplayinfo) để kiểm tra slot sớm nhất hiện có thể phát lại.

Nếu slot đã lưu nằm ngoài khoảng thời gian phát lại, ứng dụng của bạn có thể khôi phục riêng phần lịch sử còn thiếu hoặc tiếp tục từ một slot mới hơn. Hãy bắt đầu một lượt đăng ký mới với `fromSlot` bạn đã chọn. Khả năng cung cấp dữ liệu có thể thay đổi giữa các yêu cầu.

## Cách hoạt động

<Steps>
  <Step title="Specify Starting Point">
    Sử dụng tham số `fromSlot` để đặt điểm bắt đầu phát lại (phải nằm trong khoảng 48 giờ gần nhất, tương đương khoảng 691.200 slot ở tốc độ mạng hiện tại)
  </Step>

  <Step title="Stream Historical Data">
    LaserStream cung cấp tất cả sự kiện kể từ slot bạn chỉ định
  </Step>

  <Step title="Catch Up to Real-Time">
    Dữ liệu lịch sử tiếp tục được truyền cho đến khi bạn bắt kịp slot hiện tại
  </Step>

  <Step title="Continue Live Streaming">
    Chuyển đổi liền mạch sang truyền dữ liệu thời gian thực
  </Step>
</Steps>

<Note>
  **Tự động kết nối lại**: [LaserStream SDK](https://github.com/helius-labs/laserstream-sdk) tự động xử lý việc kết nối lại và phát lại. Không cần mã bổ sung!
</Note>

Quá trình phát lại tuân theo cờ bộ lọc giao dịch `matchMints`, vì vậy một lượt phát lại [được lọc theo mint](/docs/vi/laserstream/mint-filtering) sẽ trả về cùng tập hợp giao dịch mà luồng trực tiếp sẽ cung cấp.

## Bắt đầu nhanh

<Tip>
  Bắt đầu sử dụng LaserStream từ [Bảng điều khiển Helius](https://dashboard.helius.dev/laserstream). Mainnet yêu cầu gói Business hoặc Professional; Devnet khả dụng từ gói Developer trở lên. Xem [Gói dịch vụ và giá](/docs/vi/billing/plans) để biết chi tiết.
</Tip>

<Tabs>
  <Tab title="gRPC">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

    // Pick a slot within the last ~48 h (~691,200 slots at current ~250ms slot time). For a real start
    // value, call `getSlot` first and subtract however far back you want to replay.
    // Note: replays older than ~20 min return finalized data even at processed/confirmed;
    // slots within the last ~20 min carry true commitment semantics.
    const fromSlot = 419_800_000;

    const subscriptionRequest: SubscribeRequest = {
      transactions: {
        "token-filter": { // user-defined label for this filter
          accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
          vote: false,
          failed: false
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {},
      slots: {},
      blocks: {},
      blocksMeta: {},
      entry: {},
      accountsDataSlice: [],
      fromSlot, // u64 slot number; must fall inside the replay window
    };

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

    await subscribe(config, subscriptionRequest, 
      async (data) => {
        console.log('Received data:', data);
      }, 
      async (error) => {
        console.error('Error:', error);
      }
    );
    ```
  </Tab>
</Tabs>

## Tùy chọn cấu hình

<ParamField path="fromSlot" type="number" required>
  Số slot để bắt đầu phát lại, dưới dạng `u64`. Số này phải nằm trong khoảng thời gian phát lại (khoảng 48 giờ gần nhất tính từ slot hiện tại, tương đương khoảng 691.200 slot ở tốc độ mạng hiện tại) ở bất kỳ mức commitment nào.

  **Ví dụ**: `currentSlot - 1000`

  **Quan trọng**: Nếu bạn truyền một slot cũ hơn khoảng thời gian cho phép, LaserStream sẽ từ chối yêu cầu với `Operation was attempted past the valid range`.
</ParamField>

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

<AccordionGroup>
  <Accordion title="Reconnection After Brief Disconnection">
    Khi ứng dụng kết nối lại sau một lần mất kết nối ngắn (dưới 48 giờ), bạn có thể sử dụng tính năng Phát lại lịch sử để đảm bảo không bỏ lỡ dữ liệu. `getCurrentSlot` gọi Helius RPC; `lastProcessedSlot` được lưu trong bộ nhớ bên dưới — hãy lưu trữ lâu dài theo cách phù hợp với ứng dụng của bạn (Redis, Postgres, một tệp, v.v.).

    ```typescript theme={"system"}
    async function getCurrentSlot(): Promise<number> {
      const r = await fetch(`https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getSlot', params: [{ commitment: 'confirmed' }] }),
      });
      const { result } = await r.json();
      return result as number;
    }

    // Load the last slot you processed from wherever you store it.
    let lastProcessedSlot = Number(process.env.LAST_PROCESSED_SLOT ?? 0);

    // Check if it's still within the replay window
    // (~691,200 slots at current ~250ms slot time; recompute if network slot time changes)
    const currentSlot = await getCurrentSlot();
    const maxReplaySlot = currentSlot - 691_200;

    if (lastProcessedSlot < maxReplaySlot) {
      console.warn('Disconnection too long, some data may be lost');
      lastProcessedSlot = maxReplaySlot;
    }

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: lastProcessedSlot, // pass as number, not string
    };

    await subscribe(config, subscriptionRequest,
      async (data) => {
        // your handler here
        if (data.transaction?.slot) {
          lastProcessedSlot = Number(data.transaction.slot);
          // persist `lastProcessedSlot` here so the next reconnect picks up
        }
      }
    );
    ```
  </Accordion>

  <Accordion title="Bootstrap with Recent Context">
    Khởi động ứng dụng với ngữ cảnh gần đây từ vài phút vừa qua:

    ```typescript theme={"system"}
    // Get a slot from 10 minutes ago (within the 48-hour window)
    const currentSlot = await getCurrentSlot();
    const startSlot = currentSlot - 2400; // ~10 minutes ago at current ~250ms slot time

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: startSlot, // u64 number
    };
    ```
  </Accordion>

  <Accordion title="Testing with Recent Data">
    Sử dụng dữ liệu lịch sử gần đây để kiểm thử (giới hạn trong 48 giờ gần nhất):

    ```typescript theme={"system"}
    // Test with data from the last 5 minutes
    const currentSlot = await getCurrentSlot();
    const testStartSlot = currentSlot - 1200; // ~5 minutes ago at current ~250ms slot time
    const testEndSlot = currentSlot - 240;    // ~1 minute ago at current ~250ms slot time

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: testStartSlot, // u64 number
    };

    // Stop processing when reaching the test end slot
    const stream = await subscribe(config, subscriptionRequest,
      async (data) => {
        const slot = Number(data.transaction?.slot ?? data.account?.slot ?? 0);
        if (slot >= testEndSlot) {
          stream.cancel();
          return;
        }
        // your test handler here
      }
    );
    ```
  </Accordion>
</AccordionGroup>

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

<CardGroup cols={2}>
  <Card title="LaserStream gRPC" icon="bolt" href="/docs/vi/laserstream/grpc">
    Tìm hiểu thêm về các tính năng và khả năng truyền dữ liệu qua gRPC
  </Card>

  <Card title="Get Started" icon="rocket" href="https://dashboard.helius.dev/laserstream">
    Bật LaserStream từ Bảng điều khiển Helius và bắt đầu truyền dữ liệu.
  </Card>

  <Card title="SDK Documentation" icon="github" href="https://github.com/helius-labs/laserstream-sdk">
    Xem toàn bộ tài liệu SDK
  </Card>

  <Card title="Contact Support" icon="headset" href="/docs/vi/support">
    Nhận trợ giúp cho quá trình triển khai của bạn
  </Card>
</CardGroup>
