Primeros Pasos
let mut svm = LiteSVM::new();
Esto crea la instancia de prueba básica de litesvm, que incluye todas las funciones de tiempo de ejecución habilitadas, sysvars predeterminados, precompilaciones, programas spl, verificación de firmas y todos los programas integrados como el System Program.
Para interactuar con cualquier otro programa en tus pruebas, debes implementar ese programa en tu entorno de pruebas.
-
Compila e implementa el programa que deseas probar
-
Encuentra todos los programas a los que el programa anterior realiza llamadas CPI e impleméntalos
Ejemplo: Si tu programa utiliza feeds de datos de Pyth, necesitarás tener el programa de Pyth implementado en tu instancia de prueba.
Implementación Básica de Programas
Método 1: Implementar desde Bytes
Implementa programas directamente desde arreglos de bytes para una ejecución de pruebas más rápida:
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! incrusta el binario directamente en el ejecutable de prueba en
tiempo de compilación, eliminando operaciones de E/S durante la ejecución de las
pruebas.
✓ Ventajas
- •Más rápido en tiempo de ejecución (sin lecturas de disco)
- •Binario de prueba autocontenido
- •Funciona incluso si el archivo .so se elimina después de la compilación
✗ Desventajas
- •Mayor tamaño del binario de prueba
- •Se deben recompilar las pruebas cuando el archivo .so cambia
Método 2: Desplegar desde un archivo (.so)
Carga programas desde el sistema de archivos cuando cambian con frecuencia:
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);
✓ Ventajas
- •Binario de prueba más pequeño
- •Permite detectar cambios en el .so sin recompilar las pruebas
- •Mayor flexibilidad para pipelines de CI/CD
✗ Desventajas
- •Más lento (E/S de disco en tiempo de ejecución)
- •Requiere que el archivo .so exista en el momento de ejecutar las pruebas
- •La ruta del archivo debe ser correcta relativa al directorio de ejecución de las pruebas
Obtener programas desde Mainnet/Devnet
Cuando necesitas un programa del que no tienes el código fuente, usa la CLI de Solana para extraer programas de clústeres en producción y utilizarlos en las pruebas:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Luego cárgalo en tus pruebas:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Mejores prácticas
1. Elige el método de despliegue adecuado
-
Use
add_program()cuando:- Los programas están integrados en el binario de prueba en tiempo de compilación
- Quieres una ejecución de pruebas más rápida (sin E/S en tiempo de ejecución)
- Las pruebas son autocontenidas
-
Usa
add_program_from_file()cuando:- Los programas se compilan por separado (es decir, se obtienen desde devnet)
- Los programas cambian con frecuencia durante el desarrollo (se pueden volver a ejecutar las pruebas sin recompilar)
- Tienes entornos de CI/CD donde los archivos .so son artefactos
Entendiendo los keypair de programas
Cuando compilas un programa de Solana:
- Anchor crea
target/deploy/program-keypair.json - Las compilaciones nativas crean un archivo keypair junto al archivo
.so - La dirección on-chain del programa es la clave pública de este keypair, que también se conoce como el ID del programa.
- Para las PDAs,
find_program_address()requiere el ID del programa como seed - Para los CPIs, el ID del programa se usa para llamar a otros programas
Problemas comunes y soluciones
Fallos silenciosos en el despliegue
Problema: El programa parece desplegarse correctamente, pero las transacciones fallan con "InvalidProgramForExecution".
Causa: El ID del programa no coincide con el keypair.
Solución:
// 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);
Error de programa no encontrado
Error: TransactionError::InvalidProgramForExecution
Causas comunes:
- El programa no está desplegado
- Se usó un ID de programa incorrecto en la instrucción
- El ID del programa no coincide con el keypair
Pasos para depurar:
// 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 a programas no desplegados
Problema: Tu programa realiza una llamada CPI a un programa que no está desplegado.
Solución: Despliega todos los programas de los que depende:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Si necesitas obtener el programa desde un clúster, revisa esta sección.
lamport insuficientes para el despliegue
Nota: LiteSVM gestiona automáticamente el balance exento de renta para los programas.
// 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);
Lista de verificación del despliegue
Lee el keypair del programa
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Despliega con el ID coincidente
svm.add_program(program_id, &program_bytes).unwrap();
Verifica el despliegue
assert!(svm.get_account(&program_id).unwrap().executable);
Despliega cualquier programa que tu programa llame mediante CPI en la instancia de prueba de litesvm
Próximos pasos
En la siguiente sección, aprenderemos cómo ejecutar instrucciones de programas y manejar patrones de transacciones complejos.
Is this page helpful?