Minh họa cách sử dụng warpToSlot để kiểm thử logic chương trình phụ thuộc thời gian.
Thao Tác Đồng Hồ Cơ Bản
import { createClient, generateKeyPairSigner } from "@solana/kit";import { litesvm } from "@solana/kit-plugin-litesvm";import { signer } from "@solana/kit-plugin-signer";const mySigner = await generateKeyPairSigner();const client = createClient().use(signer(mySigner)).use(litesvm());// Enable sysvars for clock accessclient.svm.withSysvars();// Check initial clockconst initialClock = client.svm.getClock();console.log("Initial state:");console.log(" Slot:", initialClock.slot);console.log(" Epoch:", initialClock.epoch);console.log(" Unix timestamp:", initialClock.unixTimestamp);// Warp to slot 1000client.svm.warpToSlot(1000n);const afterWarp = client.svm.getClock();console.log("\nAfter warpToSlot(1000):");console.log(" Slot:", afterWarp.slot);console.log(" Epoch:", afterWarp.epoch);// Warp furtherclient.svm.warpToSlot(100000n);const afterWarp2 = client.svm.getClock();console.log("\nAfter warpToSlot(100000):");console.log(" Slot:", afterWarp2.slot);console.log(" Epoch:", afterWarp2.epoch);
Kiểm Thử Logic Khóa Thời Gian
Mẫu ví dụ để kiểm thử chức năng khóa thời gian:
import {createClient,address,generateKeyPairSigner,lamports} from "@solana/kit";import { litesvm } from "@solana/kit-plugin-litesvm";import { signer } from "@solana/kit-plugin-signer";const mySigner = await generateKeyPairSigner();const client = createClient().use(signer(mySigner)).use(litesvm());client.svm.withSigverify(false).withBlockhashCheck(false).withSysvars();// Fund payerclient.svm.airdrop(client.payer.address, lamports(10_000_000_000n));// Set up a time-locked vault account// Structure: [u8 discriminator, u64 unlock_slot, u64 amount]const unlockSlot = 10000n;const lockedAmount = 5_000_000_000n;const vaultData = new Uint8Array(1 + 8 + 8);const view = new DataView(vaultData.buffer);vaultData[0] = 0x01; // discriminatorview.setBigUint64(1, unlockSlot, true); // unlock_slotview.setBigUint64(9, lockedAmount, true); // amountconst programId = address("TimeLockedVault11111111111111111111111"); // replace or generateKeyPairSigner()const vaultAddress = address("Vault111111111111111111111111111"); // replace or generateKeyPairSigner()const minBalance = client.svm.minimumBalanceForRentExemption(BigInt(vaultData.length));client.svm.setAccount({address: vaultAddress,data: vaultData,executable: false,lamports: lamports(minBalance + lockedAmount),programAddress: programId,space: BigInt(vaultData.length)});console.log("Vault created with unlock slot:", unlockSlot);console.log("Locked amount:", Number(lockedAmount) / 1e9, "SOL");// Test 1: Try to withdraw before unlock (should fail)console.log("\n--- Test 1: Before unlock ---");const currentClock = client.svm.getClock();console.log("Current slot:", currentClock.slot);// In a real test, you would:// 1. Build a withdraw instruction// 2. Send it and expect it to failconsole.log("Withdrawal attempt: EXPECTED TO FAIL (too early)");// Test 2: Warp to after unlock slotconsole.log("\n--- Test 2: After unlock ---");client.svm.warpToSlot(unlockSlot + 100n);const newClock = client.svm.getClock();console.log("Current slot:", newClock.slot);// In a real test:// 1. Build a withdraw instruction// 2. Send it and expect it to succeedconsole.log("Withdrawal attempt: EXPECTED TO SUCCEED (after unlock)");// Verify vault stateconst updatedVault = client.svm.getAccount(vaultAddress);if (updatedVault.exists) {console.log("\nVault balance:", updatedVault.lamports);}
Đọc Lịch Epoch
Bạn có thể đọc lịch epoch để hiểu mối quan hệ slot/epoch trên cluster:
import { createClient, generateKeyPairSigner } from "@solana/kit";import { litesvm } from "@solana/kit-plugin-litesvm";import { signer } from "@solana/kit-plugin-signer";const mySigner = await generateKeyPairSigner();const client = createClient().use(signer(mySigner)).use(litesvm());client.svm.withSysvars();const epochSchedule = client.svm.getEpochSchedule();console.log("Slots per epoch:", epochSchedule.slotsPerEpoch);console.log("First normal epoch:", epochSchedule.firstNormalEpoch);console.log("First normal slot:", epochSchedule.firstNormalSlot);
warpToSlot chỉ tiến trường slot của đồng hồ nhưng không tự động
cập nhật epoch hay unixTimestamp. Sử dụng setClock để kiểm soát toàn bộ các
trường đồng hồ.
Thao Tác Đồng Hồ Thủ Công
Khi chương trình của bạn đọc epoch hoặc unix_timestamp từ Clock sysvar, hãy dùng
setClock để đặt trực tiếp các trường đó:
import { createClient, generateKeyPairSigner } from "@solana/kit";import { litesvm } from "@solana/kit-plugin-litesvm";import { signer } from "@solana/kit-plugin-signer";const mySigner = await generateKeyPairSigner();const client = createClient().use(signer(mySigner)).use(litesvm());client.svm.withSysvars();// Get clock, mutate, write backconst clock = client.svm.getClock();clock.slot = 50000n;clock.epoch = 5n;clock.unixTimestamp = 1700000000n;client.svm.setClock(clock);const after = client.svm.getClock();console.log("Slot:", after.slot); // 50000nconsole.log("Epoch:", after.epoch); // 5nconsole.log("Timestamp:", after.unixTimestamp); // 1700000000n
Cách này phản ánh mẫu set_sysvar(&clock) trong Rust. Sử dụng warpToSlot để tiến
slot đơn giản, dùng setClock khi bạn cần kiểm soát epoch hoặc timestamp.
Các Trường Hợp Sử Dụng
Thao tác thời gian hữu ích để kiểm thử:
| Tình huống | Cách tiếp cận |
|---|---|
| Vesting token | Warp qua mốc/ngưỡng vesting |
| Kết thúc đấu giá | Warp qua slot kết thúc đấu giá |
| Phần thưởng staking | Dùng setClock để đặt epoch |
| Rút tiền khóa thời gian | Warp qua slot mở khóa |
| Giới hạn tốc độ | Warp giữa các khoảng thời gian được phép |
| Lệnh hết hạn | Warp qua thời điểm hết hạn lệnh |
Lưu ý rằng warpToSlot chỉ thay đổi slot. Unix timestamp có thể không
cập nhật theo tỷ lệ tương ứng tùy thuộc vào cách triển khai SVM.
Điểm Chính
- Bật Sysvar: Gọi
withSysvars()trước khi sử dụng các phương thức đồng hồ - Tiến Về Phía Trước: Dùng
warpToSlot(slot)để tiến slot - Kiểm Soát Toàn Bộ: Dùng
setClockkhi bạn cần đặtepoch,unixTimestamp, hoặc các trường đồng hồ khác - Đọc Đồng Hồ: Dùng
getClock()để đọc slot, epoch, timestamp hiện tại - Mẫu Kiểm Thử: Kiểm thử trước và sau các mốc thời gian
Is this page helpful?