Per Iniziare
let mut svm = LiteSVM::new();
Questo crea l'istanza di test litesvm di base, che include tutte le funzionalità di runtime abilitate, sysvars predefinite, precompilazioni, programmi spl, sigverify e tutti i programmi integrati come il System Program.
Per interagire con qualsiasi altro programma nei tuoi test, devi distribuire quel programma nel tuo ambiente di test.
-
Compila e distribuisci il programma che vuoi testare
-
Individua tutti i programmi a cui il programma precedente effettua chiamate CPI e distribuisci anche quelli
Esempio: Se il tuo programma utilizza feed di dati di Pyth, dovrai avere il programma Pyth distribuito nella tua istanza di test.
Distribuzione Base dei Programmi
Metodo 1: Distribuzione da Byte
Distribuisci i programmi direttamente da array di byte per un'esecuzione dei test più rapida:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read the program's keypair to get correct IDlet 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 timelet program_bytes = include_bytes!("../target/deploy/my_program.so");// Deploy from bytessvm.add_program(program_id, program_bytes).expect("Failed to deploy program");// Verify deploymentassert!(svm.get_account(&program_id).is_some(), "Program account not created");assert!(svm.get_account(&program_id).unwrap().executable, "Program not executable");
include_bytes! incorpora il binario direttamente nell'eseguibile di test al
momento della compilazione, eliminando le operazioni di I/O durante l'esecuzione
dei test.
✓ Vantaggi
- •Più veloce a runtime (nessuna lettura da disco)
- •Binario di test autonomo
- •Funziona anche se il file .so viene eliminato dopo la compilazione
✗ Svantaggi
- •Dimensione del binario di test maggiore
- •È necessario ricompilare i test quando il file .so cambia
Metodo 2: Deploy da File (.so)
Carica i programmi dal file system quando cambiano frequentemente:
use litesvm::LiteSVM;use solana_sdk::signature::{read_keypair_file, Signer};let mut svm = LiteSVM::new();// Read keypair for correct program IDlet program_keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = program_keypair.pubkey();// Deploy from filesvm.add_program_from_file(program_id, "target/deploy/program.so").expect("Failed to deploy program from file");// Always verifyassert!(svm.get_account(&program_id).unwrap().executable);
✓ Vantaggi
- •Binario di test più leggero
- •Rileva le modifiche ai file .so senza ricompilare i test
- •Maggiore flessibilità per le pipeline CI/CD
✗ Svantaggi
- •Più lento (I/O su disco a runtime)
- •Richiede che il file .so esista al momento dell'esecuzione del test
- •Il percorso del file deve essere corretto rispetto alla directory di esecuzione del test
Recupero di Programmi da Mainnet/Devnet
Quando hai bisogno di un programma di cui non disponi del codice sorgente, utilizza la Solana CLI per esportare i programmi dai cluster attivi e utilizzarli nei test:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Quindi caricalo nei tuoi test:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Best Practice
1. Scegli il Metodo di Deploy Corretto
-
Usa
add_program()quando:- I programmi sono incorporati nel binario di test in fase di compilazione
- Vuoi un'esecuzione dei test più rapida (nessun I/O a runtime)
- I test devono essere autonomi
-
Usa
add_program_from_file()quando:- I programmi vengono compilati separatamente (es. recuperati da devnet)
- Il programma cambia frequentemente durante lo sviluppo (è possibile rieseguire i test senza ricompilare)
- Hai ambienti CI/CD in cui i file .so sono artefatti
Comprendere i keypair dei programmi
Quando compili un programma Solana:
- Anchor crea
target/deploy/program-keypair.json - Le build native creano un file keypair insieme al file
.so - L'indirizzo on-chain del programma è la chiave pubblica di questo keypair, nota anche come ID del programma.
- Per i PDA,
find_program_address()richiede l'ID del programma come seed - Per i CPI, l'ID del programma viene utilizzato per richiamare altri programmi
Problemi comuni e soluzioni
Errori silenziosi durante il deployment
Problema: Il programma sembra essere distribuito ma le transazioni falliscono con "InvalidProgramForExecution".
Causa: L'ID del programma non corrisponde al keypair.
Soluzione:
// Always use the keypair-derived IDlet 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 checkslet 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);
Errore: programma non trovato
Errore: TransactionError::InvalidProgramForExecution
Cause comuni:
- Programma non distribuito
- ID del programma errato utilizzato nell'istruzione
- ID del programma non corrispondente al keypair
Passaggi di debug:
// Step 1: Check if program existsif 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 keypairlet 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 IDprintln!("Instruction program_id: {}", instruction.program_id);assert_eq!(instruction.program_id, program_id, "Instruction uses wrong program ID");
CPI verso programmi non distribuiti
Problema: Il tuo programma effettua una chiamata CPI a un programma non distribuito.
Soluzione: Distribuisci tutti i programmi dipendenti:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Se hai bisogno di recuperare il programma da un cluster, consulta questa sezione.
lamport insufficienti per il deployment
Nota: LiteSVM gestisce automaticamente il saldo esente da rent per i programmi.
// No need to manually fund - LiteSVM handles thissvm.add_program(program_id, &program_bytes).unwrap();// But you can check the rent if neededlet 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);
Checklist di verifica del deployment
Leggi il keypair del programma
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Distribuisci con ID corrispondente
svm.add_program(program_id, &program_bytes).unwrap();
Verifica il deployment
assert!(svm.get_account(&program_id).unwrap().executable);
Distribuisci all'istanza di test litesvm tutti i programmi richiamati dal tuo programma tramite CPI
Passi successivi
Nella prossima sezione, impareremo come eseguire le istruzioni del programma e gestire pattern di transazione complessi.
Is this page helpful?