时间旅行

Surfpool 运行时提供了三个时间旅行辅助函数。每个函数均将本地时钟移动至绝对目标时间(而非相对偏移量),并返回更新后的 EpochInfo,以便测试用例验证运行时是否确实到达了请求的时间。

辅助函数目标返回值
time_travel_to_slot / timeTravelToSlot绝对 slot 编号包含新 absolute_slotEpochInfo
time_travel_to_epoch / timeTravelToEpoch绝对 epoch 编号包含新 epochEpochInfo
time_travel_to_timestamp / timeTravelToTimestamp毫秒级 Unix 时间戳反映对应 slot 的 EpochInfo

仅支持向前跳转

时间旅行只能将时钟向前移动。若目标时间早于当前时间,该方法将不执行任何操作——辅助函数将返回当前 EpochInfo,保持不变。

跳转至指定 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);

跳转至指定 Epoch

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

跳转至指定 Unix 时间戳

请以毫秒为单位传入时间戳,而非秒。运行时将计算该时间戳所对应的最近 slot。

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

常见使用模式

测试锁定期或归属窗口

以下示例仅为示意——assertWithdrawFailsassertWithdrawSucceeds 是占位符,代表您的测试套件中用于断言 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();

驱动多 epoch 场景

中间 slot 将被跳过

时间旅行会直接跳转到目标位置 —— 从 epoch 1 跳转到 epoch 5 会跳过中间的所有 slot。如果您的程序需要触发每个中间 epoch 的边界事件(例如,用于计算每 epoch 的奖励),请在每个 epoch 之间 携带所需交易调用一次 time_travel_to_epoch

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

EpochInfo 结构

两个 SDK 均返回一个 EpochInfo 结构的对象,包含以下字段:

字段RustJS
绝对 slotabsolute_slot: u64absoluteSlot: number
epoch 内的 slotslot_index: u64slotIndex: number
每 epoch 的 slot 数slots_in_epoch: u64slotsInEpoch: number
epoch 编号epoch: u64epoch: number
区块高度block_height: u64blockHeight: number
交易数量transaction_count: Option<u64>transactionCount?: number

Is this page helpful?

Table of Contents

Edit Page
©️ 2026 Solana 基金会版权所有