Επιδεικνύει τη χρήση του 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 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);
Δοκιμή Λογικής Κλειδωμένης στον Χρόνο
Παράδειγμα προτύπου για δοκιμή λειτουργικότητας κλειδωμένης στον χρόνο:
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);}
Ανάγνωση του Προγράμματος 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 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
Αυτό αντικατοπτρίζει το πρότυπο Rust set_sysvar(&clock). Χρησιμοποιήστε το warpToSlot για απλή
προώθηση slot, και το setClock όταν χρειάζεστε έλεγχο epoch ή χρονικής σφραγίδας.
Περιπτώσεις Χρήσης
Ο χειρισμός χρόνου είναι χρήσιμος για δοκιμές:
| Σενάριο | Προσέγγιση |
|---|---|
| Vesting token | Μεταφορά πέρα από το όριο/ορόσημα vesting |
| Λήξη δημοπρασιών | Μεταφορά πέρα από το τελικό slot δημοπρασίας |
| Ανταμοιβές staking | Χρησιμοποιήστε το setClock για ορισμό epoch |
| Αναλήψεις κλειδωμένες στον χρόνο | Μεταφορά πέρα από το slot ξεκλειδώματος |
| Περιορισμός ρυθμού | Μεταφορά μεταξύ επιτρεπόμενων διαστημάτων |
| Λήξη εντολών | Μεταφορά πέρα από τη λήξη εντολής |
Να θυμάστε ότι το warpToSlot αλλάζει μόνο το slot. Η χρονική σφραγίδα unix ενδέχεται να μην
ενημερώνεται αναλογικά ανάλογα με την υλοποίηση SVM.
Βασικά Σημεία
- Ενεργοποίηση Sysvars: Καλέστε το
withSysvars()πριν χρησιμοποιήσετε μεθόδους ρολογιού - Προώθηση: Χρησιμοποιήστε το
warpToSlot(slot)για να προωθήσετε το slot - Πλήρης Έλεγχος: Χρησιμοποιήστε το
setClockόταν χρειάζεστε να ορίσετε τοepoch, τοunixTimestampή άλλα πεδία ρολογιού - Ανάγνωση Ρολογιού: Χρησιμοποιήστε το
getClock()για ανάγνωση τρέχοντος slot, epoch, χρονικής σφραγίδας - Πρότυπο Δοκιμής: Δοκιμάστε πριν και μετά τα χρονικά όρια
Is this page helpful?