Tijdreizen

De Surfpool-runtime biedt drie tijdreishelpers. Elk verplaatst de lokale klok naar een absoluut doelwit (geen relatieve verschuiving) en geeft de bijgewerkte EpochInfo terug, zodat tests kunnen controleren of de runtime daadwerkelijk de gevraagde tijd heeft bereikt.

HelperDoelwitGeeft terug
time_travel_to_slot / timeTravelToSlotAbsoluut slot-nummerEpochInfo met het nieuwe absolute_slot
time_travel_to_epoch / timeTravelToEpochAbsoluut epoch-nummerEpochInfo met het nieuwe epoch
time_travel_to_timestamp / timeTravelToTimestampUnix-tijdstempel in millisecondenEpochInfo dat het impliciete slot weerspiegelt

Alleen vooruit

Tijdreizen kan de klok alleen vooruitzetten. Een doel in het verleden wordt geweigerd in plaats van genegeerd — de Rust-helpers retourneren een Err en de JS-helpers gooien een fout. Het bericht benoemt welke eenheid terugwaarts ging, bijvoorbeeld Cannot travel to past slot: target=1000, current=2000.

Spring Naar Een 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);

Spring Naar Een Epoch

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

Spring Naar Een Unix-tijdstempel

Geef de tijdstempel op in milliseconden sinds de Unix-epoch — dezelfde eenheid als JavaScript's Date.now() — niet seconden. De runtime berekent het dichtstbijzijnde slot op dat tijdstempel.

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

De klok rapporteert seconden, niet milliseconden

Elke tijdstempel die je terugleest vanuit de runtime is in seconden — de on-chain Clock-sysvar's unix_timestamp, en de ClockValue die wordt meegedragen door het systemClockUpdated-event. Als je een van die waarden rechtstreeks teruggeeft aan een tijdreishelper, wordt dat omgezet naar een moment in het begin van 1970, waardoor de aanroep wordt geweigerd als een verleden doel. Vermenigvuldig eerst met 1000.

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

De Klok Pauzeren en Hervatten

Tijdreizen springt naar een doel; pauzeren stopt de klok volledig. surfnet_pauseClock stopt de slotproductie en tijdvoortgang totdat surfnet_resumeClock wordt uitgevoerd — gebruik dit wanneer een test het slot en de tijdstempel gedurende meerdere asserties constant wil houden.

Noch de Rust SDK noch de Surfnet-klasse in @solana/surfpool omhult deze twee cheatcodes. Roep ze aan via de Kit-plugin, of rechtstreeks via 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();

Beide cheatcodes retourneren een EpochInfo — de klokstatus op het moment van de pauze, en na het hervatten. Let op de twee dingen die die structuur niet bevat:

  • Geen tijdstempel. EpochInfo heeft geen tijdveld. Lees de gesimuleerde Unix-tijd uit de Clock-sysvar: gebruik getAccountInfo op SysvarC1ock11111111111111111111111111111111 met jsonParsed-codering — opnieuw in seconden.
  • Geen pauzemarkering. Geen enkele RPC-methode rapporteert of de klok momenteel gepauzeerd is. Bekijk via de SDK's het clockUpdate-event, dat afgaat met een clockCommand wanneer een pauze, hervatting of intervalwijziging wordt uitgevoerd. Houd anders de toestand bij in je test.

Veelvoorkomende Patronen

Test Een Vergrendeling Of Vestingvenster

Het onderstaande voorbeeld is een schets — assertWithdrawFails en assertWithdrawSucceeds zijn tijdelijke aanduidingen voor de client-side helpers die uw testsuite gebruikt om RPC-gedrag te controleren.

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

Stuur Een Multi-Epoch Scenario Aan

Tussenliggende slots worden overgeslagen

Tijdreizen springt direct naar het doel — van epoch 1 naar epoch 5 gaan slaat de slots daartussenin over. Als uw programma elke tussenliggende epoch grens nodig heeft om te activeren (bijvoorbeeld om per-epoch beloningen te crediteren), roep dan time_travel_to_epoch eenmaal per epoch aan met eventuele vereiste transacties daartussen.

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

EpochInfo Structuur

Beide SDK's geven een EpochInfo-vormig object terug met de volgende velden:

VeldRustJS
Absolute slotabsolute_slot: u64absoluteSlot: number
Slot binnen epochslot_index: u64slotIndex: number
Slots per epochslots_in_epoch: u64slotsInEpoch: number
Epoch nummerepoch: u64epoch: number
Blokhoogteblock_height: u64blockHeight: number
Transactieaantaltransaction_count: Option<u64>transactionCount?: number

Is this page helpful?

Inhoudsopgave

Pagina Bewerken
© 2026 Solana Foundation. Alle rechten voorbehouden.