Aikamatka

Surfpool-ajoympäristö tarjoaa kolme aikamatka-apufunktiota. Jokainen siirtää paikallisen kellon absoluuttiseen kohteeseen (ei suhteelliseen siirtymään) ja palauttaa päivitetyn EpochInfo, jotta testit voivat varmistaa, että ajoympäristö todella saavutti pyydetyn ajan.

HelperKohdePalauttaa
time_travel_to_slot / timeTravelToSlotAbsoluuttinen slot-numeroEpochInfo uudella absolute_slot
time_travel_to_epoch / timeTravelToEpochAbsoluuttinen epoch-numeroEpochInfo uudella epoch
time_travel_to_timestamp / timeTravelToTimestampUnix-aikaleima millisekunteinaEpochInfo vastaa laskettua slotia

Vain eteenpäin

Aikamatka voi siirtää kelloa vain eteenpäin. Menneisyyteen osoittava kohde hylätään eikä jätetä huomiotta — Rust-apufunktiot palauttavat Err-arvon ja JS- apufunktiot heittävät poikkeuksen. Viesti nimeää yksikön, joka meni taaksepäin, esimerkiksi Cannot travel to past slot: target=1000, current=2000.

Hyppää slotiin

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);

Hyppää epochiin

let info = cheats.time_travel_to_epoch(420)?;
assert_eq!(info.epoch, 420);

Hyppää Unix-aikaleimaan

Anna aikaleima millisekunneissa Unix-epochista lähtien — sama yksikkö kuin JavaScriptin Date.now() — ei sekunteina. Ajonaikainen ympäristö laskee lähimmän slotin kyseisellä aikaleimalla.

// 2030-01-01T00:00:00Z
let info = cheats.time_travel_to_timestamp(1_893_456_000_000)?;

Kello ilmoittaa sekunteja, ei millisekunteja

Jokainen aikaleima, jonka luet takaisin ajonaikaisesta ympäristöstä, on sekunteina — ketjussa olevan Clock-syscarin unix_timestamp sekä ClockValue, jonka systemClockUpdated-tapahtuma välittää. Jos syötät jonkin näistä arvoista suoraan aikamatka-apufunktioon, se ratkaisee hetken vuoden 1970 alkuun, joten kutsu hylätään menneisyyden kohteena. Kerro ensin tuhannella.

// 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);

Pysäytä ja jatka kelloa

Aikamatka hyppää kohteeseen; pysäyttäminen estää kelloa etenemästä lainkaan. surfnet_pauseClock keskeyttää slotien tuotannon ja ajan etenemisen, kunnes surfnet_resumeClock suoritetaan — käytä sitä, kun testin täytyy pitää slotti ja aikaleima muuttumattomina useiden väittämien ajan.

Rust SDK eikä Surfnet-luokka @solana/surfpool-paketissa kääri näitä kahta huijaukoodikutsua. Kutsu niitä Kit-laajennuksen kautta tai suoraan JSON-RPC:n välityksellä.

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();

Molemmat huijaukoodikutsut palauttavat EpochInfo-arvon — kellotilan pysäytyshetkellä ja jatkamisen jälkeen. Huomaa kaksi asiaa, joita tuo rakenne ei sisällä:

  • Ei aikaleimaa. EpochInfo-rakenteessa ei ole aikakenttää. Lue simuloitu Unix-aika Clock-syscarista: kutsu getAccountInfo osoitteelle SysvarC1ock11111111111111111111111111111111 käyttäen jsonParsed-enkoodausta — jälleen sekunteina.
  • Ei pysäytystilalippua. Mikään RPC-metodi ei ilmoita, onko kello tällä hetkellä pysäytettynä. SDK:ista voit seurata clockUpdate-tapahtumaa, joka laukeaa clockCommand-komennolla aina, kun pysäytys, jatkaminen tai intervallin muutos suoritetaan. Muussa tapauksessa seuraa tilaa itse testissäsi.

Yleisiä käyttötapoja

Testaa lukitusaika tai vesting-ikkuna

Alla oleva esimerkki on luonnos — assertWithdrawFails ja assertWithdrawSucceeds ovat paikkamerkkejä niille asiakaspuolen apufunktioille, joita testipakettisi käyttää RPC-toiminnan varmistamiseen.

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();

Aja Moni-Epoch-Skenaario

Väliset slot-yksiköt ohitetaan

Aikamatka hyppää suoraan kohteeseen — siirtyminen epoch 1:stä epoch 5:een ohittaa välissä olevat slot-yksiköt. Jos ohjelmasi tarvitsee jokaisen välissä olevan epoch- rajan laukaistavan (esimerkiksi epoch-kohtaisten palkintojen hyvittämiseksi), kutsu time_travel_to_epoch kerran per epoch tarvittavien transaktioiden kanssa välissä.

for epoch in 2..=5 {
cheats.time_travel_to_epoch(epoch)?;
surfnet.rpc_client().send_transaction(&claim_rewards_tx)?;
}

EpochInfo-rakenne

Molemmat SDK:t palauttavat EpochInfo-muotoisen objektin seuraavilla kentillä:

KenttäRustJS
Absoluuttinen slotabsolute_slot: u64absoluteSlot: number
Slot epochin sisälläslot_index: u64slotIndex: number
Sloteja per epochslots_in_epoch: u64slotsInEpoch: number
Epoch-numeroepoch: u64epoch: number
Lohkokorkeusblock_height: u64blockHeight: number
Transaktioiden määrätransaction_count: Option<u64>transactionCount?: number

Is this page helpful?

Sisällysluettelo

Muokkaa sivua
© 2026 Solana Foundation. Kaikki oikeudet pidätetään.