タイムトラベル

Surfpoolランタイムは3つのタイムトラベルヘルパーを提供します。それぞれのヘルパーはローカルクロックを絶対ターゲット(相対オフセットではなく)に移動させ、更新されたEpochInfoを返すため、テストはランタイムが実際にリクエストされた時刻に到達したことを検証できます。

ヘルパーターゲット返り値
time_travel_to_slot / timeTravelToSlot絶対slot番号新しいabsolute_slotを含むEpochInfo
time_travel_to_epoch / timeTravelToEpoch絶対epoch番号新しいepochを含むEpochInfo
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)?;

よくある使用パターン

ロックアップまたはベスティングウィンドウのテスト

以下の例はスケッチです — assertWithdrawFailsおよびassertWithdrawSucceedsは、テストスイートで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ごとの報酬を付与するなど)、 間に必要なトランザクションを挟みながら、time_travel_to_epochをepochごとに1回呼び出してください。

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?

目次

ページを編集
© 2026 Solana Foundation. 無断転載を禁じます。