LiteSVM Docs
Additional Crateslitesvm-loader

Quick Start

Learn how to use the litesvm-loader crate for testing upgradeable program deployment

Installation

Make sure you have all the needed dependencies:

cargo add --dev litesvm litesvm-loader solana-keypair solana-signer

If your test invokes the deployed program directly, also add the Solana instruction and transaction crates used by your test:

cargo add --dev solana-instruction solana-message solana-transaction

What is litesvm-loader?

The litesvm-loader crate provides helpers for deploying programs through the BPF upgradeable loader inside LiteSVM. Use it when your test needs loader-owned program accounts, program data accounts, or upgrade authority behavior instead of directly inserting a program with svm.add_program(...).

Upgradeable Deployment

  • Creates the loader buffer account
  • Writes program bytes in chunks
  • Deploys the final program account with the BPF upgradeable loader
  • Uses the provided program keypair as the program ID

Upgrade Authority Management

  • Changes the upgrade authority for an already deployed program
  • Supports assigning a new authority
  • Supports passing None to make the program immutable

Real Loader State

  • Exercises the same loader account model your program sees on-chain
  • Lets tests inspect program and program data accounts
  • Helps catch mistakes hidden by direct program insertion

For most tests, svm.add_program(program_id, program_bytes) is still the fastest and simplest way to load a program. Use litesvm-loader when the loader account layout or upgrade authority is part of what you need to test.

Quick Example

Here's a complete example that deploys a program through the upgradeable loader and then rotates its authority:

use litesvm::LiteSVM;
use litesvm_loader::{deploy_upgradeable_program, set_upgrade_authority};
use solana_keypair::Keypair;
use solana_signer::Signer;

#[test]
fn test_upgradeable_deployment() {
    let mut svm = LiteSVM::new();

    let payer = Keypair::new();
    svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();

    // Use the keypair that should own the program ID.
    // For Anchor programs, this is usually target/deploy/<program>-keypair.json.
    let program = Keypair::new();
    let program_bytes = include_bytes!("../target/deploy/my_program.so");

    deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();

    let program_account = svm.get_account(&program.pubkey()).unwrap();
    assert!(program_account.executable);

    let new_authority = Keypair::new();
    set_upgrade_authority(
        &mut svm,
        &payer,
        &program.pubkey(),
        &payer,
        Some(&new_authority.pubkey()),
    )
    .unwrap();
}

Choosing the Program Keypair

deploy_upgradeable_program uses the program_kp argument as the program address. If your program declares a fixed ID, load the generated deploy keypair instead of creating a random keypair:

use solana_keypair::read_keypair_file;

let program = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();

Invoking the Deployed Program

After deployment, call the program the same way you would call any LiteSVM-loaded program. Build an instruction for your program, sign the transaction, and send it through the same LiteSVM instance:

use solana_instruction::Instruction;
use solana_message::Message;
use solana_transaction::Transaction;

let instruction = Instruction::new_with_bytes(
    program.pubkey(),
    &[],  // instruction data for your program
    vec![], // account metas for your program
);

let message = Message::new(&[instruction], Some(&payer.pubkey()));
let tx = Transaction::new(&[&payer], message, svm.latest_blockhash());

svm.send_transaction(tx).unwrap();

Key Components

deploy_upgradeable_program

ArgumentDescription
svmMutable LiteSVM instance that receives the deployed program
payer_kpFee payer and initial upgrade authority
program_kpKeypair whose public key becomes the program ID
program_bytesCompiled SBF program bytes, usually from target/deploy/*.so

deploy_upgradeable_program creates a loader buffer, writes the program bytes in 512-byte chunks, and deploys the program with room for future upgrades.

set_upgrade_authority

ArgumentDescription
svmMutable LiteSVM instance containing the deployed program
from_keypairFee payer and signing authority for the transaction
program_addressProgram ID whose authority should change
current_authority_keypairCurrent upgrade authority keypair
new_authority_addressNew authority address, or None to make the program immutable

In the current helper implementation, the generated transaction is signed by from_keypair. Pass the current authority as from_keypair, or keep the payer and current authority the same, when changing upgrade authority.

Common Workflows

Deploy with the declared program ID

use solana_keypair::read_keypair_file;

let program = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
let program_bytes = include_bytes!("../target/deploy/my_program.so");

deploy_upgradeable_program(&mut svm, &payer, &program, program_bytes).unwrap();

Make a program immutable

set_upgrade_authority(
    &mut svm,
    &payer,
    &program.pubkey(),
    &payer,
    None,
)
.unwrap();

Troubleshooting

Common Errors

ErrorCauseSolution
ProgramAccountNotFound or instruction failures against the wrong IDThe deployment used a random Keypair while the program expects a declared IDRead target/deploy/<program>-keypair.json and pass that keypair to deploy_upgradeable_program
InsufficientFundsThe payer does not have enough lamports for loader buffer and program accountsAirdrop more lamports before deployment
MissingRequiredSignature when changing authorityThe current authority did not sign the transactionPass the current authority as from_keypair, or keep payer and current authority as the same keypair
Program deployment is slower than expectedLoader deployment writes bytes through real loader instructionsUse svm.add_program(...) when you do not need loader state or upgrade authority behavior