시간 및 시스템 변수

시간 조작

warp_to_slot

pub fn warp_to_slot(&mut self, slot: u64)

특정 slot으로 이동합니다. 앞으로의 시간 이동만 지원됩니다.

// Get current slot
let clock: Clock = svm.get_sysvar();
let current_slot = clock.slot;
// Jump forward 100 slots
svm.warp_to_slot(current_slot + 100);
// Verify
let new_clock: Clock = svm.get_sysvar();
assert_eq!(new_clock.slot, current_slot + 100);

수동 클록 조작

use solana_sdk::clock::Clock;
// Read clock
let mut clock: Clock = svm.get_sysvar();
// Modify fields
clock.slot = 1000;
clock.epoch = 10;
clock.unix_timestamp = 1735689600;
// Write back
svm.set_sysvar(&clock);

대부분의 시간 조작에는 warp_to_slot()을(를) 사용하세요. 수동 클록 수정은 여러 필드를 정밀하게 제어해야 할 때만 사용하세요.

시스템 변수

get_sysvar

pub fn get_sysvar<T: Sysvar>(&self) -> T

시스템 변수 값을 읽습니다.

use solana_sdk::clock::Clock;
use solana_sdk::rent::Rent;
use solana_sdk::epoch_schedule::EpochSchedule;
let clock: Clock = svm.get_sysvar();
let rent: Rent = svm.get_sysvar();
let epoch_schedule: EpochSchedule = svm.get_sysvar();

set_sysvar

pub fn set_sysvar<T: Sysvar>(&mut self, sysvar: &T)

시스템 변수 값을 씁니다.

use solana_sdk::rent::Rent;
let rent = Rent {
lamports_per_byte_year: 3480,
exemption_threshold: 2.0,
burn_percent: 50,
};
svm.set_sysvar(&rent);

주요 시스템 변수

클록

use solana_sdk::clock::Clock;
let clock: Clock = svm.get_sysvar();
println!("Slot: {}", clock.slot);
println!("Timestamp: {}", clock.unix_timestamp);
println!("Epoch: {}", clock.epoch);

Rent

use solana_sdk::rent::Rent;
let rent: Rent = svm.get_sysvar();
let min_balance = rent.minimum_balance(data_len);

Epoch 일정

use solana_sdk::epoch_schedule::EpochSchedule;
let schedule: EpochSchedule = svm.get_sysvar();
println!("Slots per epoch: {}", schedule.slots_per_epoch);

스테이크 히스토리

use solana_sdk::stake_history::{StakeHistory, StakeHistoryEntry};
let mut stake_history = StakeHistory::default();
stake_history.add(
0, // epoch
StakeHistoryEntry {
effective: 1_000_000,
activating: 0,
deactivating: 0,
},
);
svm.set_sysvar(&stake_history);

시간 기반 테스트 패턴

Slot 기반 기능 테스트

let mut svm = LiteSVM::new();
// Get starting slot
let start_slot = svm.get_sysvar::<Clock>().slot;
// Try action before unlock slot (should fail)
let result = call_locked_program(&mut svm);
assert!(result.is_err());
// Warp to unlock slot
svm.warp_to_slot(start_slot + 1000);
// Now it should succeed
let result = call_locked_program(&mut svm);
assert!(result.is_ok());

타임스탬프 기반 기능 테스트

let mut svm = LiteSVM::new();
// Get current timestamp
let clock: Clock = svm.get_sysvar();
let current_time = clock.unix_timestamp;
// Warp forward 1 hour (3600 seconds)
// Slots roughly correspond to ~0.4 seconds on Solana
let target_slot = clock.slot + (3600.0 / 0.4) as u64;
svm.warp_to_slot(target_slot);
// Verify timestamp increased
let new_clock: Clock = svm.get_sysvar();
assert!(new_clock.unix_timestamp >= current_time + 3600);

베스팅 일정 테스트

// Setup vesting with 100 slot period
let vesting_period = 100;
let start_slot = svm.get_sysvar::<Clock>().slot;
// Test before vesting completes
let result = claim_vested_tokens(&mut svm);
assert!(result.is_err()); // Too early
// Warp past vesting period
svm.warp_to_slot(start_slot + vesting_period + 1);
// Now claim should succeed
let result = claim_vested_tokens(&mut svm);
assert!(result.is_ok());

일반적인 사용 사례

  • 베스팅 일정
  • 시간 잠금 출금
  • 스테이크/언스테이크 쿨다운 기간
  • 경매 종료 시간
  • 임대 기간
  • 에포크 기반 보상

중요 사항

  1. 앞으로만 진행 - 시간을 앞으로만 이동할 수 있으며, 뒤로는 불가능합니다
  2. Slot과 시간 - Slot은 Solana 메인넷에서 대략 ~0.4초에 해당합니다
  3. Clock sysvar - warp_to_slot() 사용 시 항상 업데이트됩니다
  4. 자동 업데이트 없음 - 실제 validator와 달리, 트랜잭션 사이에 시간이 자동으로 진행되지 않습니다

Is this page helpful?