Runtime Surfpool menyediakan tiga helper perjalanan waktu. Masing-masing
memindahkan jam lokal ke target absolut (bukan offset relatif) dan mengembalikan
EpochInfo yang telah diperbarui sehingga pengujian dapat memverifikasi bahwa
runtime benar-benar mencapai waktu yang diminta.
| Helper | Target | Mengembalikan |
|---|---|---|
time_travel_to_slot / timeTravelToSlot | Nomor slot absolut | EpochInfo dengan absolute_slot baru |
time_travel_to_epoch / timeTravelToEpoch | Nomor epoch absolut | EpochInfo dengan epoch baru |
time_travel_to_timestamp / timeTravelToTimestamp | Stempel waktu Unix dalam milidetik | EpochInfo yang mencerminkan slot yang tersirat |
Hanya maju
Time travel hanya dapat memajukan jam ke depan. Target yang berada di masa lalu akan
ditolak, bukan diabaikan — helper Rust mengembalikan Err dan helper JS
akan melempar pengecualian. Pesan kesalahan menyebutkan unit mana yang mundur ke belakang, misalnya
Cannot travel to past slot: target=1000, current=2000.
Lompat Ke Slot
use surfpool_sdk::Surfnet;let surfnet = Surfnet::start().await?;let cheats = surfnet.cheatcodes();let info = cheats.time_travel_to_slot(1_000_000)?;assert!(info.absolute_slot >= 1_000_000);
Lompat Ke Epoch
let info = cheats.time_travel_to_epoch(420)?;assert_eq!(info.epoch, 420);
Lompat Ke Stempel Waktu Unix
Berikan stempel waktu dalam milidetik sejak Unix epoch — satuan yang sama dengan
Date.now() JavaScript — bukan detik. Runtime akan menghitung slot terdekat
pada stempel waktu tersebut.
// 2030-01-01T00:00:00Zlet info = cheats.time_travel_to_timestamp(1_893_456_000_000)?;
Jam melaporkan dalam detik, bukan milidetik
Setiap stempel waktu yang Anda baca kembali dari runtime berada dalam detik — unix_timestamp dari
sysvar Clock on-chain, dan
ClockValue yang dibawa oleh
event systemClockUpdated. Memasukkan salah satu nilai tersebut langsung ke dalam
helper time travel akan mengarah ke momen di awal tahun 1970, sehingga panggilan tersebut
ditolak sebagai target masa lalu. Kalikan dengan 1000 terlebih dahulu.
// WRONG — `unixTimestamp` is in seconds, so this is a past target.surfnet.timeTravelToTimestamp(clock.unixTimestamp + 3600);// RIGHT — convert to milliseconds.surfnet.timeTravelToTimestamp((clock.unixTimestamp + 3600) * 1000);
Jeda dan Lanjutkan Jam
Time travel melompat ke target; menjeda menghentikan jam agar tidak maju sama sekali.
surfnet_pauseClock menghentikan produksi slot dan perkembangan waktu hingga
surfnet_resumeClock dijalankan — gunakan ini ketika pengujian membutuhkan slot dan
stempel waktu tetap diam selama beberapa asersi.
Baik Rust SDK maupun kelas Surfnet di @solana/surfpool tidak membungkus kedua
cheatcode ini. Panggil melalui
plugin Kit, atau langsung melalui JSON-RPC.
const paused = await client.cheatcodes.pauseClock().send();// Nothing advances until the clock is resumed, so this is the only thing that// moves the slot.await client.cheatcodes.timeTravel({ absoluteSlot: paused.absoluteSlot + 1_000n }).send();await client.cheatcodes.resumeClock().send();
Kedua cheatcode mengembalikan EpochInfo — status jam pada saat dijeda, dan setelah dilanjutkan. Perhatikan dua hal yang tidak dibawa oleh bentuk tersebut:
- Tidak ada stempel waktu.
EpochInfotidak memiliki field waktu. Baca waktu Unix yang disimulasikan dari sysvarClock:getAccountInfopadaSysvarC1ock11111111111111111111111111111111dengan encodingjsonParsed— sekali lagi, dalam detik. - Tidak ada flag jeda. Tidak ada metode RPC yang melaporkan apakah jam sedang
dijeda. Dari SDK, pantau
event
clockUpdate, yang dipicu denganclockCommandsetiap kali perintah jeda, lanjutkan, atau perubahan interval dijalankan. Jika tidak, lacak statusnya dalam pengujian Anda.
Pola Umum
Uji Lockup atau Jendela Vesting
Contoh di bawah ini hanyalah sketsa — assertWithdrawFails dan
assertWithdrawSucceeds adalah placeholder untuk helper sisi klien apa pun yang
digunakan layanan pengujian Anda untuk memverifikasi perilaku RPC.
import { Surfnet } from "@solana/surfpool";const surfnet = Surfnet.start();const beneficiary = Surfnet.newKeypair();// 1. Set up a vesting account that unlocks at slot 1,000,000.surfnet.setAccount(/* ...lockup program state... */);// 2. Verify withdrawal fails before unlock.await assertWithdrawFails(surfnet.rpcUrl, beneficiary);// 3. Travel past the unlock slot.surfnet.timeTravelToSlot(1_000_001);// 4. Verify withdrawal succeeds.await assertWithdrawSucceeds(surfnet.rpcUrl, beneficiary);surfnet.stop();
Jalankan Skenario Multi-Epoch
Slot perantara dilewati
Perjalanan waktu langsung melompat ke target — berpindah dari epoch 1 ke epoch
5 akan melewati slot-slot di antaranya. Jika program Anda membutuhkan setiap
batas epoch perantara untuk dieksekusi (misalnya, untuk mengkredit hadiah
per-epoch), panggil time_travel_to_epoch sekali per epoch dengan transaksi
yang diperlukan di antaranya.
for epoch in 2..=5 {cheats.time_travel_to_epoch(epoch)?;surfnet.rpc_client().send_transaction(&claim_rewards_tx)?;}
Bentuk EpochInfo
Kedua SDK mengembalikan objek berbentuk EpochInfo dengan field-field berikut:
| Field | Rust | JS |
|---|---|---|
| Slot absolut | absolute_slot: u64 | absoluteSlot: number |
| Slot dalam epoch | slot_index: u64 | slotIndex: number |
| Slot per epoch | slots_in_epoch: u64 | slotsInEpoch: number |
| Nomor epoch | epoch: u64 | epoch: number |
| Tinggi blok | block_height: u64 | blockHeight: number |
| Jumlah transaksi | transaction_count: Option<u64> | transactionCount?: number |
Is this page helpful?