Τεκμηρίωση SolanaLiteSVMTypeScriptΠαραδείγματα

Δοκιμές Βασισμένες στον Χρόνο

Επιδεικνύει τη χρήση του warpToSlot για δοκιμή λογικής προγράμματος που εξαρτάται από τον χρόνο.

Βασικός Χειρισμός Ρολογιού

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 access
client.svm.withSysvars();
// Check initial clock
const 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 1000
client.svm.warpToSlot(1000n);
const afterWarp = client.svm.getClock();
console.log("\nAfter warpToSlot(1000):");
console.log(" Slot:", afterWarp.slot);
console.log(" Epoch:", afterWarp.epoch);
// Warp further
client.svm.warpToSlot(100000n);
const afterWarp2 = client.svm.getClock();
console.log("\nAfter warpToSlot(100000):");
console.log(" Slot:", afterWarp2.slot);
console.log(" Epoch:", afterWarp2.epoch);

Δοκιμή Λογικής Κλειδωμένης στον Χρόνο

Παράδειγμα προτύπου για δοκιμή λειτουργικότητας κλειδωμένης στον χρόνο:

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 payer
client.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; // discriminator
view.setBigUint64(1, unlockSlot, true); // unlock_slot
view.setBigUint64(9, lockedAmount, true); // amount
const 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 fail
console.log("Withdrawal attempt: EXPECTED TO FAIL (too early)");
// Test 2: Warp to after unlock slot
console.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 succeed
console.log("Withdrawal attempt: EXPECTED TO SUCCEED (after unlock)");
// Verify vault state
const updatedVault = client.svm.getAccount(vaultAddress);
if (updatedVault.exists) {
console.log("\nVault balance:", updatedVault.lamports);
}

Ανάγνωση του Προγράμματος Epoch

Μπορείτε να διαβάσετε το πρόγραμμα epoch για να κατανοήσετε τη σχέση slot/epoch στο 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 προωθεί το πεδίο slot του ρολογιού αλλά δεν ενημερώνει αυτόματα το epoch ή το unixTimestamp. Χρησιμοποιήστε το setClock για πλήρη έλεγχο των πεδίων ρολογιού.

Χειροκίνητος Χειρισμός Ρολογιού

Όταν το πρόγραμμά σας διαβάζει epoch ή unix_timestamp από το Clock sysvar, χρησιμοποιήστε το setClock για να ορίσετε αυτά τα πεδία απευθείας:

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 back
const 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); // 50000n
console.log("Epoch:", after.epoch); // 5n
console.log("Timestamp:", after.unixTimestamp); // 1700000000n

Αυτό αντικατοπτρίζει το πρότυπο Rust set_sysvar(&clock). Χρησιμοποιήστε το warpToSlot για απλή προώθηση slot, και το setClock όταν χρειάζεστε έλεγχο epoch ή χρονικής σφραγίδας.

Περιπτώσεις Χρήσης

Ο χειρισμός χρόνου είναι χρήσιμος για δοκιμές:

ΣενάριοΠροσέγγιση
Vesting tokenΜεταφορά πέρα από το όριο/ορόσημα vesting
Λήξη δημοπρασιώνΜεταφορά πέρα από το τελικό slot δημοπρασίας
Ανταμοιβές stakingΧρησιμοποιήστε το setClock για ορισμό epoch
Αναλήψεις κλειδωμένες στον χρόνοΜεταφορά πέρα από το slot ξεκλειδώματος
Περιορισμός ρυθμούΜεταφορά μεταξύ επιτρεπόμενων διαστημάτων
Λήξη εντολώνΜεταφορά πέρα από τη λήξη εντολής

Να θυμάστε ότι το warpToSlot αλλάζει μόνο το slot. Η χρονική σφραγίδα unix ενδέχεται να μην ενημερώνεται αναλογικά ανάλογα με την υλοποίηση SVM.

Βασικά Σημεία

  1. Ενεργοποίηση Sysvars: Καλέστε το withSysvars() πριν χρησιμοποιήσετε μεθόδους ρολογιού
  2. Προώθηση: Χρησιμοποιήστε το warpToSlot(slot) για να προωθήσετε το slot
  3. Πλήρης Έλεγχος: Χρησιμοποιήστε το setClock όταν χρειάζεστε να ορίσετε το epoch, το unixTimestamp ή άλλα πεδία ρολογιού
  4. Ανάγνωση Ρολογιού: Χρησιμοποιήστε το getClock() για ανάγνωση τρέχοντος slot, epoch, χρονικής σφραγίδας
  5. Πρότυπο Δοκιμής: Δοκιμάστε πριν και μετά τα χρονικά όρια

Is this page helpful?

© 2026 Ίδρυμα Solana. Με επιφύλαξη παντός δικαιώματος.