Documentación de SolanaLiteSVMRustProbando tu programa

Ejecución de instrucciones

Descripción general

Después de desplegar un programa en LiteSVM, necesitarás ejecutar instrucciones para interactuar con el programa desplegado.

LiteSVM proporciona una API sencilla para crear, enviar y simular transacciones que es totalmente compatible con el modelo de transacciones de Solana.

Flujo básico de transacciones

El flujo típico para ejecutar una instrucción es:

  1. Crear una instrucción - Define qué programa llamar y con qué datos
  2. Construir un mensaje - Combina una o más instrucciones
  3. Crear una transacción - Firma el mensaje con los firmantes requeridos
  4. Enviar o simular - Ejecuta la transacción y gestiona los resultados

Creación de instrucciones

Estructura básica de una instrucción

use solana_instruction::{Instruction, AccountMeta};
use solana_pubkey::Pubkey;
let instruction = Instruction {
program_id: Pubkey::new_unique(), // The program to call
accounts: vec![ // Accounts the program needs
AccountMeta::new(account_pubkey, false), // Writable, not signer
AccountMeta::new_readonly(readonly_pubkey, false), // Read-only, not signer
AccountMeta::new(signer_pubkey, true), // Writable, signer
],
data: vec![0, 1, 2, 3], // Instruction data (program-specific)
};

Construcción y envío de transacciones

Método 1: Transacción básica

use litesvm::LiteSVM;
use solana_keypair::Keypair;
use solana_message::Message;
use solana_transaction::Transaction;
use solana_signer::Signer;
let mut svm = LiteSVM::new();
let payer = Keypair::new();
// Airdrop SOL for fees
svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();
// Create instruction
let instruction = /* your instruction */;
// Build message with payer
let message = Message::new(&[instruction], Some(&payer.pubkey()));
// Create and sign transaction
let tx = Transaction::new_signed_with_payer(
&[instruction], // Your instructions
Some(&payer.pubkey()), // Who pays transaction fees
&[&payer], // All required signers
svm.latest_blockhash(), // Recent blockhash
);
// Send transaction
let result = svm.send_transaction(tx);

Qué hace new_signed_with_payer:

  • Construye automáticamente un Message a partir de tus instrucciones
  • Firma automáticamente la transacción con todos los keypairs proporcionados

  • Devuelve una transacción completamente firmada y lista para enviar

Método 2: Transacción con mensaje personalizado

let payer = Keypair::new();
// Manually construct message
let message = Message::new(&[instruction], Some(&payer.pubkey()));
// Create transaction with signers, message, and blockhash
let tx = Transaction::new(
&[&payer],
message,
svm.latest_blockhash(),
);
let result = svm.send_transaction(tx);

Usa este método cuando necesites control sobre Message, como:

  • Transacciones versionadas (v0 con tablas de búsqueda)
  • Flujos de trabajo con firma parcial/múltiple
  • Nonces duraderos
  • Simulación o inspección previa a la firma
  • Lógica personalizada del pagador de comisiones
  • Optimización del tamaño de la transacción

Transacciones versionadas

LiteSVM admite tanto transacciones heredadas como versionadas:

use solana_transaction::versioned::VersionedTransaction;
use solana_message::VersionedMessage;
// Legacy transaction (most common)
let legacy_msg = Message::new(&[instruction], Some(&payer.pubkey()));
let versioned_tx = VersionedTransaction::try_new(
VersionedMessage::Legacy(legacy_msg),
&[&payer]
).unwrap();
// Send versioned transaction
let result = svm.send_transaction(versioned_tx);

Resultados de las transacciones

Transacción exitosa

match svm.send_transaction(tx) {
Ok(meta) => {
println!("Signature: {}", meta.signature);
println!("Compute units: {}", meta.compute_units_consumed);
println!("Logs:");
for log in &meta.logs {
println!(" {}", log);
}
}
Err(err) => {
println!("Transaction failed: {:?}", err.err);
// Logs are still available on failure
println!("Failure logs: {:?}", err.meta.logs);
}
}

Campos de metadatos de la transacción

pub struct TransactionMetadata {
pub signature: Signature,
pub logs: Vec<String>,
pub inner_instructions: InnerInstructionsList,
pub compute_units_consumed: u64,
pub return_data: TransactionReturnData,
pub fee: u64,
}

Simulación de Transacciones

La simulación de transacciones te permite probar transacciones sin modificar el estado:

// Simulate instead of sending
match svm.simulate_transaction(tx) {
Ok(sim_result) => {
println!("Simulation successful!");
println!("Logs: {:?}", sim_result.meta.logs);
println!("Compute units: {}", sim_result.meta.compute_units_consumed);
}
Err(err) => {
println!("Simulation failed: {:?}", err.err);
}
}

Manejo de Errores

Errores Comunes en Transacciones

use solana_transaction_error::TransactionError;
use solana_instruction::error::InstructionError;
match svm.send_transaction(tx) {
Err(failed_tx) => {
match failed_tx.err {
TransactionError::InsufficientFundsForFee => {
println!("Not enough SOL for fees");
}
TransactionError::InvalidProgramForExecution => {
println!("Program doesn't exist or isn't executable");
}
TransactionError::InstructionError(index, err) => {
println!("Instruction {} failed: {:?}", index, err);
match err {
InstructionError::Custom(code) => {
println!("Custom error code: {}", code);
}
InstructionError::AccountNotFound => {
println!("An account doesn't exist");
}
_ => {}
}
}
TransactionError::BlockhashNotFound => {
println!("Blockhash expired or invalid");
}
_ => println!("Other error: {:?}", failed_tx.err),
}
}
Ok(_) => {}
}

Trabajo con Registros de Programa

Acceso a los Registros

let result = svm.send_transaction(tx).unwrap();
// All logs (including system logs)
for log in &result.logs {
println!("{}", log);
}
// Pretty-printed logs (formatted)
println!("{}", result.pretty_logs());

Ejemplo de Salida de Registros

Program 11111111111111111111111111111111 invoke [1]
Program log: Processing instruction
Program 11111111111111111111111111111111 consumed 2000 compute units
Program 11111111111111111111111111111111 success

Configuración del Presupuesto de Cómputo

Configuración Global del Presupuesto de Cómputo

use solana_compute_budget::compute_budget::ComputeBudget;
let mut svm = LiteSVM::new()
.with_compute_budget(ComputeBudget {
compute_unit_limit: 200_000,
..Default::default()
});

Presupuesto de Cómputo por Transacción

use solana_compute_budget_interface::ComputeBudgetInstruction;
let instructions = vec![
// Set compute budget for this transaction
ComputeBudgetInstruction::set_compute_unit_limit(400_000),
ComputeBudgetInstruction::set_compute_unit_price(1),
// Your actual instruction
your_instruction,
];

Instrucciones del System Program

LiteSVM incluye soporte para el System Program:

use solana_keypair::Keypair;
use solana_signer::Signer;
use solana_system_interface::instruction as system_instruction;
use solana_transaction::Transaction;
// Transfer SOL
let transfer_ix = system_instruction::transfer(
&alice.pubkey(),
&bob.pubkey(),
1_000_000_000, // 1 SOL
);
// Create new account
let create_ix = system_instruction::create_account(
&payer_pubkey,
&new_account_pubkey,
lamports,
space as u64,
&owner_program_id,
);

Resumen

La ejecución de instrucciones en LiteSVM sigue el modelo estándar de transacciones de Solana:

  1. Crear objetos Instruction con el ID del programa, las cuentas y los datos
  2. Construir un Transaction con la instrucción y los firmantes requeridos
  3. Usar send_transaction() para ejecutar o simulate_transaction() para probar
  4. Gestionar los resultados verificando el TransactionMetadata o los detalles del error

LiteSVM ofrece ejecución instantánea con registros detallados e información de depuración, lo que lo hace ideal para probar programas de Solana de manera eficiente.

Is this page helpful?