Suite pengujian Solana yang menjalankan solana-test-validator membutuhkan waktu beberapa detik per pengujian - Anda menunggu proses startup, koneksi RPC, dan round-trip jaringan. LiteSVM menjalankan pengujian yang sama dalam milidetik. Tidak ada proses eksternal, tidak ada jaringan, semuanya dalam memori di dalam test runner Anda.
litesvm-go adalah binding Go resmi. Tipe inti (PublicKey, Hash, Signature) langsung berasal dari gagliardetto/solana-go, sehingga nilai mengalir secara alami antara litesvm-go dan ekosistem Go Solana lainnya.
Persyaratan: Go 1.24+. Tidak perlu Rust toolchain - arsip statis bawaan sudah disertakan dalam modul dan dipilih secara otomatis oleh GOOS / GOARCH. Platform yang didukung: macOS (amd64, arm64), Linux (amd64, arm64; glibc atau musl), Windows (amd64).
Handle LiteSVM yang baru menyediakan airdrop, transaksi (legacy + v0), simulasi, baca/tulis akun, sysvar, compute budget, feature gate, time travel, program kustom, dan riwayat transaksi - semuanya didukung oleh inti Rust yang sama yang menggerakkan SDK Rust dan TypeScript.
Mulai Cepat
Instal modul
go get menyelesaikan dependensi ke dalam modul Go, jadi inisialisasi terlebih dahulu jika Anda belum memiliki go.mod:
go mod init mytest
Kemudian tambahkan modulnya:
go get github.com/LiteSVM/litesvm-go
Tarik juga solana-go untuk pembuatan keypair, instruksi, dan transaksi:
go get github.com/gagliardetto/solana-go
Pengguna Alpine / musl: tambahkan -tags musl ke perintah go build / go test Anda agar arsip bawaan yang tepat ditautkan.
Buat SVM Anda
package mytestimport ("testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go")func TestSetup(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()// Fund a payerpriv, err := solana.NewRandomPrivateKey()if err != nil {t.Fatal(err)}payer := priv.PublicKey()if err := svm.Airdrop(payer, 5_000_000_000); err != nil {t.Fatal(err)}// Check the balancelamports, ok, err := svm.Balance(payer)if err != nil {t.Fatal(err)}if !ok {t.Fatal("payer account missing")}t.Logf("balance: %d lamports", lamports)}
litesvm.New() mengembalikan *LiteSVM dan sebuah error. Setiap titik masuk di litesvm-go mengikuti bentuk (value, error) yang sama; panik di sisi Rust ditangkap dan dikonversi menjadi error. Selalu gunakan defer svm.Close() agar handle Rust yang mendasarinya dilepaskan - atau andalkan finalizer, meskipun Close eksplisit lebih disarankan untuk pembersihan yang dapat diprediksi.
Memahami Handle
Setelah litesvm.New(), *LiteSVM yang dikembalikan mengekspos kelompok kemampuan berikut:
| Grup | Metode |
|---|---|
| Akun | Airdrop, Balance, GetAccount, SetAccount, MinimumBalanceForRentExemption |
| Transaksi | SendLegacyTransaction, SendVersionedTransaction, SimulateLegacyTransaction, SimulateVersionedTransaction, GetTransaction |
| Blockhash | LatestBlockhash, ExpireBlockhash |
| Program | AddProgram, AddProgramFromFile, AddProgramWithLoader |
| Waktu dan sysvar | WarpToSlot, Clock, SetClock, Rent, SetRent, EpochSchedule, SetEpochSchedule, EpochRewards, ... |
| Konfigurasi | SetSigverify, SetBlockhashCheck, SetTransactionHistory, SetLogBytesLimit, SetSysvars, SetBuiltins, ... |
| Komputasi dan fitur | ComputeBudget, SetComputeBudget, SetFeatureSet |
LiteSVM yang baru sudah dilengkapi dengan program inti Solana (System Program, SPL Token, dll.) yang telah dimuat sebelumnya, sehingga transfer sederhana langsung berfungsi tanpa konfigurasi tambahan.
Mengirim Transaksi
Bangun instruksi dengan solana-go, marshal transaksinya, dan kirimkan byte-nya. litesvm-go menerima byte yang dikodekan dengan bincode yang dihasilkan oleh (*solana.Transaction).MarshalBinary:
package mytestimport ("testing"litesvm "github.com/LiteSVM/litesvm-go"solana "github.com/gagliardetto/solana-go""github.com/gagliardetto/solana-go/programs/system")func TestTransfer(t *testing.T) {svm, err := litesvm.New()if err != nil {t.Fatal(err)}defer svm.Close()priv, err := solana.NewRandomPrivateKey()if err != nil {t.Fatal(err)}payer := priv.PublicKey()recipient := solana.NewWallet().PublicKey()if err := svm.Airdrop(payer, 2_000_000_000); err != nil {t.Fatal(err)}blockhash, err := svm.LatestBlockhash()if err != nil {t.Fatal(err)}ix := system.NewTransferInstruction(1_000_000_000, payer, recipient).Build()tx, err := solana.NewTransaction([]solana.Instruction{ix},blockhash,solana.TransactionPayer(payer),)if err != nil {t.Fatal(err)}if _, err := tx.Sign(func(k solana.PublicKey) *solana.PrivateKey {if k.Equals(payer) {return &priv}return nil}); err != nil {t.Fatal(err)}txBytes, err := tx.MarshalBinary()if err != nil {t.Fatal(err)}out, err := svm.SendLegacyTransaction(txBytes)if err != nil {t.Fatal(err)}defer out.Close()if !out.IsOk() {t.Fatalf("tx failed: %s\nlogs: %v", out.Error(), out.Logs())}lamports, _, err := svm.Balance(recipient)if err != nil {t.Fatal(err)}if lamports != 1_000_000_000 {t.Fatalf("recipient balance = %d, want 1_000_000_000", lamports)}}
SendLegacyTransaction dan SendVersionedTransaction keduanya mengembalikan *TxOutcome baik saat transaksi berhasil maupun gagal. Panggil IsOk() sebelum membaca field yang hanya tersedia saat sukses, dan selalu gunakan defer out.Close() untuk melepaskan handle Rust.
Bekerja dengan TxOutcome
Setiap titik masuk send / simulate mengembalikan *TxOutcome. Handle yang sama membawa metadata untuk keberhasilan maupun kegagalan:
out, err := svm.SendLegacyTransaction(txBytes)if err != nil {t.Fatal(err)}defer out.Close()if !out.IsOk() {t.Fatalf("error: %s", out.Error())}_ = out.Signature() // solana.Signature_ = out.ComputeUnits() // uint64_ = out.Fee() // uint64_ = out.Logs() // []string_ = out.InnerInstructions()// Programs that call set_return_data expose it here.if pid, data, ok := out.ReturnData(); ok {_ = pid_ = data}
Untuk SimulateLegacyTransaction / SimulateVersionedTransaction, *TxOutcome yang sama juga mengekspos PostAccounts() - status akun setelah eksekusi yang akan terjadi:
sim, err := svm.SimulateLegacyTransaction(txBytes)if err != nil {t.Fatal(err)}defer sim.Close()posts, err := sim.PostAccounts()if err != nil {t.Fatal(err)}for _, p := range posts {_ = p.Address_ = p.Account.Lamports()p.Account.Close()}
Konfigurasi
litesvm-go mengekspos switch builder yang sama seperti crate Rust, yang ditampilkan sebagai metode Set*:
// Each setter returns an error. In tests where the values are known good,// the calls are infallible and assigning to _ keeps the example readable;// in production code, check the error or wrap with require.NoError(t, ...)._ = svm.SetSigverify(false) // accept unsigned / badly-signed txs_ = svm.SetBlockhashCheck(false) // skip recent-blockhash enforcement_ = svm.SetTransactionHistory(0) // 0 disables dedup; any N caps history_ = svm.SetLogBytesLimit(-1) // negative = unlimited_ = svm.SetLamports(1 << 40) // default lamports for new accounts_ = svm.SetSysvars() // reset sysvars to defaults_ = svm.SetBuiltins() // reload built-in programs_ = svm.SetDefaultPrograms() // reload SPL Token, Memo, etc._ = svm.SetPrecompiles() // enable ed25519 / secp256k1 precompiles_ = svm.WithNativeMints() // seed wrapped-SOL mint
Catatan
Keamanan thread. Handle *LiteSVM tidak aman untuk digunakan secara bersamaan dari beberapa goroutine (tipe Rust yang mendasarinya bukan Sync, dan sebagian besar metode mengubah status internal). Batasi handle pada satu goroutine, atau lindungi dengan sync.Mutex.
Perilaku panik. Arsip rilis bawaan dibangun dengan immediate-abort: setiap panik di dalam Rust langsung mengakhiri proses host tanpa unwinding. Ini adalah pertukaran yang disengaja demi arsip yang lebih kecil. Jika Anda mengalaminya dalam praktik, silakan buka issue dengan reproducer.
Apa Selanjutnya
Ini mencakup handle inti - membuat akun, mengirim instruksi, dan membaca state. Untuk referensi lengkap metode per metode, lihat dokumentasi API. Untuk contoh yang dapat dijalankan (transfer SOL, pengaturan akun, pengujian program, logika berbasis waktu) lihat Contoh.
Is this page helpful?