Solana-DokumentationLiteSVMRustIhr Programm testen

Programme deployen

Erste Schritte

let mut svm = LiteSVM::new();

Dies erstellt die grundlegende LiteSVM-Testinstanz, die alle aktivierten Laufzeitfunktionen, Standard-Sysvars, Precompiles, SPL-Programme, Sigverify und alle integrierten Programme wie das System Program umfasst.

Um in Ihren Tests mit einem anderen Programm zu interagieren, müssen Sie dieses Programm in Ihrer Testumgebung deployen.

  1. Erstellen und deployen Sie das Programm, das Sie testen möchten

  2. Ermitteln Sie alle Programme, an die das obige Programm CPI-Aufrufe sendet, und deployen Sie diese Programme

Beispiel: Wenn Ihr Programm Daten-Feeds von Pyth verwendet, müssen Sie das Pyth-Programm in Ihrer Testinstanz deployen.

Grundlegendes Programm-Deployment

Methode 1: Deployment aus Bytes

Deployen Sie Programme direkt aus Byte-Arrays für eine schnellstmögliche Testausführung:

use litesvm::LiteSVM;
use solana_sdk::signature::{read_keypair_file, Signer};
let mut svm = LiteSVM::new();
// Read the program's keypair to get correct ID
let program_keypair = read_keypair_file("target/deploy/my_program-keypair.json")
.expect("Program keypair file not found");
let program_id = program_keypair.pubkey();
// Include bytes at compile time
let program_bytes = include_bytes!("../target/deploy/my_program.so");
// Deploy from bytes
svm.add_program(program_id, program_bytes)
.expect("Failed to deploy program");
// Verify deployment
assert!(svm.get_account(&program_id).is_some(), "Program account not created");
assert!(svm.get_account(&program_id).unwrap().executable, "Program not executable");

include_bytes! bettet die Binärdatei zur Kompilierzeit direkt in die ausführbare Testdatei ein und eliminiert so E/A-Operationen während der Testausführung.

Vorteile

  • Schneller zur Laufzeit (keine Festplattenzugriffe)
  • In sich geschlossene Test-Binärdatei
  • Funktioniert auch, wenn die .so-Datei nach der Kompilierung gelöscht wird

Nachteile

  • Größere Test-Binärdatei
  • Tests müssen neu kompiliert werden, wenn sich die .so-Datei ändert

Methode 2: Deployment aus Datei (.so)

Programme aus dem Dateisystem laden, wenn sie sich häufig ändern:

use litesvm::LiteSVM;
use solana_sdk::signature::{read_keypair_file, Signer};
let mut svm = LiteSVM::new();
// Read keypair for correct program ID
let program_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();
let program_id = program_keypair.pubkey();
// Deploy from file
svm.add_program_from_file(program_id, "target/deploy/program.so")
.expect("Failed to deploy program from file");
// Always verify
assert!(svm.get_account(&program_id).unwrap().executable);

Vorteile

  • Kleinere Test-Binärdatei
  • Kann .so-Änderungen übernehmen, ohne Tests neu zu kompilieren
  • Flexibler für CI/CD-Pipelines

Nachteile

  • Langsamer (Datenträger-E/A zur Laufzeit)
  • Erfordert, dass die .so-Datei zum Zeitpunkt der Testausführung vorhanden ist
  • Dateipfad muss relativ zum Testausführungsverzeichnis korrekt sein

Programme von Mainnet/Devnet abrufen

Wenn Sie ein Programm benötigen, für das Sie keinen Quellcode haben, verwenden Sie die Solana CLI, um Programme aus Live-Clustern zu exportieren und in Tests zu verwenden:

# Dump a program from mainnet
solana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta
# Dump from devnet
solana program dump YourProgramID program.so --url devnet

Dann laden Sie es in Ihren Tests:

svm.add_program_from_file(
pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),
"pyth.so"
).unwrap();

Best Practices

1. Die richtige Deployment-Methode wählen

  • Use add_program() wenn:

    • Programme zum Zeitpunkt der Kompilierung in Ihre Test-Binärdatei eingebettet sind
    • Sie eine schnellere Testausführung wünschen (kein Laufzeit-E/A)
    • In sich geschlossene Tests
  • Verwende add_program_from_file() wenn:

    • Programme separat gebaut werden (d.h. von devnet bezogen werden)
    • Programme sich während der Entwicklung häufig ändern (Tests können ohne Neukompilierung erneut ausgeführt werden)
    • Du CI/CD-Umgebungen hast, in denen .so-Dateien Artefakte sind

Das program keypair verstehen

Wenn du ein Solana-Programm baust:

  1. Anchor erstellt target/deploy/program-keypair.json
  2. Native Builds erstellen eine keypair-Datei zusammen mit der .so-Datei
  3. Die On-Chain-Adresse des Programms ist der öffentliche Schlüssel dieses keypair, der auch als Programm-ID bekannt ist.
  4. Bei PDAs erfordert find_program_address() die Programm-ID als seed
  5. Bei CPIs wird die Programm-ID verwendet, um andere Programme aufzurufen

Häufige Probleme und Lösungen

Stille Deployment-Fehler

Problem: Das Programm scheint erfolgreich deployed zu sein, aber Transaktionen schlagen mit "InvalidProgramForExecution" fehl.

Ursache: Die Programm-ID stimmt nicht mit dem keypair überein.

Lösung:

// Always use the keypair-derived ID
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();
let program_id = keypair.pubkey();
svm.add_program(program_id, &program_bytes).unwrap();
// Verify with detailed checks
let account = svm.get_account(&program_id)
.expect("Program account doesn't exist");
assert!(account.executable, "Program not executable");
assert_eq!(account.owner, solana_sdk::bpf_loader::id(), "Wrong owner");
assert!(!account.data.is_empty(), "Program data is empty");
println!("✅ Program verified at {}", program_id);

Fehler: Programm nicht gefunden

Fehler: TransactionError::InvalidProgramForExecution

Häufige Ursachen:

  1. Programm nicht deployed
  2. Falsche Programm-ID in der Anweisung verwendet
  3. Programm-ID stimmt nicht mit dem keypair überein

Debugging-Schritte:

// Step 1: Check if program exists
if let Some(account) = svm.get_account(&program_id) {
println!("Program exists");
println!(" Executable: {}", account.executable);
println!(" Owner: {}", account.owner);
println!(" Data length: {}", account.data.len());
} else {
println!("Program does not exist at {}", program_id);
}
// Step 2: Verify the ID matches keypair
let expected_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();
let expected_id = expected_keypair.pubkey();
if program_id != expected_id {
println!(" ID mismatch!");
println!(" Used: {}", program_id);
println!(" Expected: {}", expected_id);
}
// Step 3: Check instruction program ID
println!("Instruction program_id: {}", instruction.program_id);
assert_eq!(instruction.program_id, program_id, "Instruction uses wrong program ID");

CPI zu nicht deployten Programmen

Problem: Dein Programm führt einen CPI-Aufruf an ein Programm durch, das nicht deployed ist.

Lösung: Alle Abhängigkeitsprogramme deployen:

// Find all dependency programs and make sure they are deployed
svm.add_program_from_file(
pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),
"pyth.so"
).unwrap();

Wenn du das Programm aus einem Cluster beziehen musst, lies diesen Abschnitt.

Unzureichende lamports für das Deployment

Hinweis: LiteSVM verwaltet automatisch den rent-exempt-Saldo für Programme.

// No need to manually fund - LiteSVM handles this
svm.add_program(program_id, &program_bytes).unwrap();
// But you can check the rent if needed
let program_len = program_bytes.len();
let required_lamports = svm.minimum_balance_for_rent_exemption(program_len);
println!("Program requires {} lamports for rent exemption", required_lamports);

Deployment Verifikations-Checkliste

Programm-keypair lesen

let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();
let program_id = keypair.pubkey();

Mit passender ID deployen

svm.add_program(program_id, &program_bytes).unwrap();

Deployment überprüfen

assert!(svm.get_account(&program_id).unwrap().executable);

Deployen Sie alle Programme, die Ihr Programm per CPI aufruft, in die litesvm-Testinstanz

Nächste Schritte

Im nächsten Abschnitt lernen wir, wie man Programm Anweisungen ausführt und komplexe Transaktionsmuster verarbeitet.

Is this page helpful?

© 2026 Solana Foundation. Alle Rechte vorbehalten.