LiteSVM Docs

Why LiteSVM

Understand how LiteSVM works and why it's different

Overview

Think of LiteSVM as a Solana VM running inside your test function. Not as a separate process, not as a network service - it's just a library call in your code.

Traditional Testing

// Traditional approach - slow and complex
let validator = TestValidator::new().await; // Starts separate process
let client = RpcClient::new(validator.url()); // Network connection

// Every operation is async and goes over network
let balance = client.get_balance(&pubkey).await?;
tokio::time::sleep(Duration::from_secs(1)).await; // Wait for confirmation

LiteSVM Testing

// LiteSVM - fast and simple
let mut svm = LiteSVM::new(); // Just a struct in memory

// Everything is synchronous and immediate
let balance = svm.get_balance(&pubkey).unwrap_or(0);

Key Principles

1. Everything is Synchronous

No async, no await, no delays:

// Send transaction and check result immediately
svm.send_transaction(tx).unwrap();
let balance = svm.get_balance(&account).unwrap(); // Already updated!

2. Direct State Manipulation

// Create any account with any data
svm.set_account(pubkey, Account {
    lamports: 1_000_000_000,
    data: vec![1, 2, 3, 4],
    owner: program_id,
    executable: false,
    rent_epoch: 0,
}).unwrap();

3. Time is Under Your Control

// Jump to any slot instantly
svm.warp_to_slot(1000);

// Expire blockhashes on demand
svm.expire_blockhash();

// Set any sysvar
let mut clock = svm.get_sysvar::<Clock>();
clock.unix_timestamp = 1735689600; // Jan 1, 2025
svm.set_sysvar(&clock);

4. Errors are Immediate and Clear

match svm.send_transaction(tx) {
    Ok(meta) => {
        // Transaction succeeded
        println!("Compute units: {}", meta.compute_units_consumed);
    }
    Err(e) => {
        // Error with full details
        println!("Error: {:?}", e.err);
        println!("Logs: {:?}", e.meta.logs);
    }
}

Next Steps