WarpToSlot ve SetClock kullanarak zamana bağlı program mantığını test etmeyi gösterir.
Temel Saat Manipülasyonu
package mytestimport ("testing"litesvm "github.com/LiteSVM/litesvm-go")func TestClockWarp(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Read the initial clock.initial, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("initial state:")t.Logf(" slot: %d", initial.Slot)t.Logf(" epoch: %d", initial.Epoch)t.Logf(" unix timestamp: %d", initial.UnixTimestamp)// Warp to slot 1_000.if err := svm.WarpToSlot(1_000); err != nil {t.Fatal(err)}after, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("after warpToSlot(1000):")t.Logf(" slot: %d", after.Slot)t.Logf(" epoch: %d", after.Epoch)// Warp further.if err := svm.WarpToSlot(100_000); err != nil {t.Fatal(err)}after2, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("after warpToSlot(100000):")t.Logf(" slot: %d", after2.Slot)t.Logf(" epoch: %d", after2.Epoch)}
Zaman Kilitli Mantığı Test Etme
package mytestimport ("encoding/binary""testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go")func TestTimeLockedVault(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Setters are infallible in practice; discarding the return keeps the// example readable._ = svm.SetSigverify(false)_ = svm.SetBlockhashCheck(false)_ = svm.SetSysvars()// Fund a payer.priv, err := solana.NewRandomPrivateKey()if err != nil {t.Fatal(err)}payer := priv.PublicKey()if err := svm.Airdrop(payer, 10_000_000_000); err != nil {t.Fatal(err)}// Set up a time-locked vault account.// Layout: [u8 discriminator, u64 unlock_slot, u64 amount]const unlockSlot = uint64(10_000)const lockedAmount = uint64(5_000_000_000)vaultData := make([]byte, 1+8+8)vaultData[0] = 0x01binary.LittleEndian.PutUint64(vaultData[1:9], unlockSlot)binary.LittleEndian.PutUint64(vaultData[9:17], lockedAmount)programID := solana.NewWallet().PublicKey()vaultAddr := solana.NewWallet().PublicKey()minBalance, err := svm.MinimumBalanceForRentExemption(len(vaultData))if err != nil {t.Fatal(err)}acct, err := litesvm.NewAccount(minBalance+lockedAmount, vaultData, programID, false, 0)if err != nil {t.Fatal(err)}defer acct.Close()if err := svm.SetAccount(vaultAddr, acct); err != nil {t.Fatal(err)}t.Logf("vault created: unlock slot=%d, locked=%.3f SOL",unlockSlot, float64(lockedAmount)/1e9)// --- Test 1: Before unlock ---cBefore, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("current slot: %d", cBefore.Slot)// In a real test you would build a withdraw instruction here and assert// it fails because the current slot < unlock_slot.t.Log("withdrawal attempt: EXPECTED TO FAIL (too early)")// --- Test 2: After unlock ---if err := svm.WarpToSlot(unlockSlot + 100); err != nil {t.Fatal(err)}cAfter, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("current slot: %d", cAfter.Slot)// Build and submit the withdraw instruction; assert it succeeds.t.Log("withdrawal attempt: EXPECTED TO SUCCEED (after unlock)")// Verify vault state.updated := svm.GetAccount(vaultAddr)if updated == nil {t.Fatal("vault missing")}defer updated.Close()t.Logf("vault balance: %d lamports", updated.Lamports())_ = payer // payer would be referenced when building the withdraw ix}
Epoch Zamanlamasını Okuma
func TestReadEpochSchedule(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()es, err := svm.EpochSchedule()if err != nil {t.Fatal(err)}t.Logf("slots per epoch: %d", es.SlotsPerEpoch)t.Logf("first normal epoch: %d", es.FirstNormalEpoch)t.Logf("first normal slot: %d", es.FirstNormalSlot)}
WarpToSlot, saatin Slot alanını ilerletir ancak Epoch veya UnixTimestamp alanlarını otomatik olarak güncellemez. Saat alanları üzerinde tam kontrol için SetClock kullanın.
Manuel Saat Manipülasyonu
Programınız Clock sysvar'ından Epoch veya UnixTimestamp okuyorsa, bu alanları SetClock ile doğrudan ayarlayın:
func TestSetClock(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()c, err := svm.Clock()if err != nil {t.Fatal(err)}c.Slot = 50_000c.Epoch = 5c.UnixTimestamp = 1_700_000_000if err := svm.SetClock(c); err != nil {t.Fatal(err)}after, err := svm.Clock()if err != nil {t.Fatal(err)}t.Logf("slot: %d", after.Slot) // 50000t.Logf("epoch: %d", after.Epoch) // 5t.Logf("unix: %d", after.UnixTimestamp) // 1700000000}
Bu, Rust'taki set_sysvar(&clock) kalıbını yansıtır. Basit slot ilerlemesi için WarpToSlot, epoch veya zaman damgası kontrolüne ihtiyaç duyduğunuzda SetClock kullanın.
Kullanım Senaryoları
Zaman manipülasyonu aşağıdakileri test etmek için kullanışlıdır:
| Senaryo | Yaklaşım |
|---|---|
| Token vesting | Vesting eşiğini / kilometre taşlarını geçmek için sar |
| Açık artırma bitişleri | Açık artırma bitiş slot'unu geçmek için sar |
| Staking ödülleri | epoch ayarlamak için SetClock kullanın |
| Zaman kilitli para çekimleri | Kilit açma slot'unu geçmek için sar |
| Hız sınırlama | İzin verilen aralıklar arasında sar |
| Süresi dolan emirler | Emir sona erme tarihini geçmek için sar |
WarpToSlot yalnızca slot'u değiştirir. Unix zaman damgası orantılı olarak güncellenmeyebilir — programınız UnixTimestamp okuyorsa SetClock kullanın.
Önemli Noktalar
- Varsayılan sysvar'lar açık -
litesvm.New(), sysvar'lar başlatılmış bir tanıtıcı döndürür; bunları değiştirdiyseniz varsayılanlara sıfırlamak içinSetSysvars()çağırın. - İleri sar -
WarpToSlot(slot)yalnızca slot alanını ilerletir. - Tam kontrol -
SetClock(Clock{...}),Epoch,UnixTimestampve diğer alanları ayarlamanıza olanak tanır. - Oku -
svm.Clock()mevcut değerleri okur. - Test kalıbı - zaman sınırından önce ve sonra test edin; bir tarafta başarısızlık, diğer tarafta başarı bekleyin.
Is this page helpful?