Viaggio nel Tempo

Il runtime di Surfpool espone tre helper per il viaggio nel tempo. Ognuno sposta il clock locale verso un obiettivo assoluto (non un offset relativo) e restituisce il valore aggiornato EpochInfo così i test possono verificare che il runtime abbia effettivamente raggiunto il tempo richiesto.

HelperObiettivoRestituisce
time_travel_to_slot / timeTravelToSlotNumero di slot assolutoEpochInfo con il nuovo absolute_slot
time_travel_to_epoch / timeTravelToEpochNumero di epoch assolutoEpochInfo con il nuovo epoch
time_travel_to_timestamp / timeTravelToTimestampTimestamp Unix in millisecondiEpochInfo che riflette lo slot implicito

Solo in avanti

Il viaggio nel tempo può spostare il clock solo in avanti. Chiamare questi metodi con un obiettivo nel passato non produce alcun effetto — l'helper restituisce il EpochInfo corrente invariato.

Salta a uno 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);

Salta a un Epoch

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

Salta a un Timestamp Unix

Passa il timestamp in millisecondi, non in secondi. Il runtime calcola lo slot più vicino a quel timestamp.

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

Pattern Comuni

Testa un Blocco o una Finestra di Vesting

L'esempio seguente è uno schema — assertWithdrawFails e assertWithdrawSucceeds sono segnaposto per gli helper lato client che la tua suite di test utilizza per verificare il comportamento 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();

Gestire uno Scenario Multi-Epoch

Gli slot intermedi vengono saltati

Il salto temporale va direttamente alla destinazione — spostandosi dall'epoch 1 all'epoch 5 vengono saltati gli slot intermedi. Se il tuo programma necessita che ogni confine di epoch intermedio venga attivato (ad esempio, per accreditare le ricompense per epoch), chiama time_travel_to_epoch una volta per epoch con le eventuali transazioni necessarie nel mezzo.

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

Struttura di EpochInfo

Entrambi gli SDK restituiscono un oggetto di tipo EpochInfo con questi campi:

CampoRustJS
Slot assolutoabsolute_slot: u64absoluteSlot: number
Slot nell'epochslot_index: u64slotIndex: number
Slot per epochslots_in_epoch: u64slotsInEpoch: number
Numero epochepoch: u64epoch: number
Altezza bloccoblock_height: u64blockHeight: number
Conteggio transazionitransaction_count: Option<u64>transactionCount?: number

Is this page helpful?

Indice dei contenuti

Modifica pagina
© 2026 Solana Foundation. Tutti i diritti riservati.