Отправка транзакций
Трейт TransactionHelpers предоставляет удобные методы для отправки инструкций
и анализа результатов.
Отправка одной инструкции
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_send_instruction() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();// Create a transfer instructionlet transfer_ix = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),LAMPORTS_PER_SOL,);// Send and get result (returns Result<TransactionResult, TransactionError>)let result = svm.send_instruction(transfer_ix, &[&alice]).unwrap();// Assert it succeededresult.assert_success();}
Отправка нескольких инструкций
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_send_multiple_instructions() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let carol = svm.create_funded_account(0).unwrap();// Create multiple transfer instructionslet instructions = vec![system_instruction::transfer(&alice.pubkey(), &bob.pubkey(), LAMPORTS_PER_SOL),system_instruction::transfer(&alice.pubkey(), &carol.pubkey(), LAMPORTS_PER_SOL),];// Send all in one transactionlet result = svm.send_instructions(&instructions, &[&alice]).unwrap();result.assert_success();}
TransactionResult
Методы send_instruction и send_instructions возвращают TransactionResult,
который оборачивает метаданные транзакции с полезными утилитами для
тестирования.
Проверка успешного выполнения
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_assert_success() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let ix = system_instruction::transfer(&alice.pubkey(), &bob.pubkey(), LAMPORTS_PER_SOL);let result = svm.send_instruction(ix, &[&alice]).unwrap();// Panics with detailed logs if the transaction failedresult.assert_success();}
assert_success() завершится с паникой и полными логами транзакции, если
транзакция не удалась, что значительно упрощает отладку.
Проверка ошибки
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_assert_failure() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(1 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();// Try to transfer more than Alice haslet ix = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),100 * LAMPORTS_PER_SOL, // Alice only has 1 SOL);let result = svm.send_instruction(ix, &[&alice]).unwrap();// This should failresult.assert_failure();}
Проверка конкретной ошибки
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_assert_error() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(1 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let ix = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),100 * LAMPORTS_PER_SOL,);let result = svm.send_instruction(ix, &[&alice]).unwrap();// Assert a specific error message is presentresult.assert_error("insufficient lamports");}
Проверка кода ошибки
Для пользовательских ошибок программы можно проверить код ошибки:
// Assert a specific custom error coderesult.assert_error_code(6000); // Custom error code from your program
Проверка ошибки Anchor
Для программ Anchor проверяйте по именам ошибок:
// Assert an Anchor-specific errorresult.assert_anchor_error("InsufficientFunds");
Анализ транзакций
Просмотр логов транзакции
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_check_logs() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let ix = system_instruction::transfer(&alice.pubkey(), &bob.pubkey(), LAMPORTS_PER_SOL);let result = svm.send_instruction(ix, &[&alice]).unwrap();// Check if a specific message is in the logsif result.has_log("Transfer") {println!("Found transfer log!");}// Find a log matching a patternif let Some(log) = result.find_log("Program") {println!("Found log: {}", log);}// Get all logslet logs = result.logs();for log in logs {println!("{}", log);}}
Вывод логов для отладки
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_print_logs() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let ix = system_instruction::transfer(&alice.pubkey(), &bob.pubkey(), LAMPORTS_PER_SOL);let result = svm.send_instruction(ix, &[&alice]).unwrap();// Print formatted logs for debuggingresult.print_logs();}
Проверка вычислительных единиц
use litesvm_utils::{LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_compute_units() {let mut svm = LiteSVM::new();let alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();let ix = system_instruction::transfer(&alice.pubkey(), &bob.pubkey(), LAMPORTS_PER_SOL);let result = svm.send_instruction(ix, &[&alice]).unwrap();let compute_units = result.compute_units();println!("Compute units consumed: {}", compute_units);// Assert compute usage is within expected boundsassert!(compute_units < 10_000, "Transaction used too many compute units");}
Мониторинг вычислительных единиц полезен для оптимизации. Solana ограничивает транзакции до 1,4 млн вычислительных единиц, а более высокое потребление увеличивает стоимость.
Полный пример
Ниже представлен подробный пример, демонстрирующий вспомогательные функции для транзакций:
use litesvm_utils::{AssertionHelpers, LiteSVM, Signer, TestHelpers, TransactionHelpers};use solana_sdk::{native_token::LAMPORTS_PER_SOL, system_instruction};#[test]fn test_transaction_workflow() {let mut svm = LiteSVM::new();// Setup accountslet alice = svm.create_funded_account(10 * LAMPORTS_PER_SOL).unwrap();let bob = svm.create_funded_account(0).unwrap();// Test successful transferlet transfer_ix = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),2 * LAMPORTS_PER_SOL,);let result = svm.send_instruction(transfer_ix, &[&alice]).unwrap();// Verify successresult.assert_success();// Check compute usagelet cu = result.compute_units();println!("Transfer used {} compute units", cu);// Verify balancessvm.assert_sol_balance(&bob.pubkey(), 2 * LAMPORTS_PER_SOL);// Test expected failurelet bad_transfer = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),100 * LAMPORTS_PER_SOL, // More than Alice has);let fail_result = svm.send_instruction(bad_transfer, &[&alice]).unwrap();fail_result.assert_failure();// Print logs for debuggingfail_result.print_logs();println!("Transaction workflow test passed!");}
Типы ошибок
Перечисление TransactionError предоставляет структурированную информацию об
ошибках:
| Вариант | Описание |
|---|---|
ExecutionFailed(String) | Выполнение транзакции завершилось с ошибкой и сообщением |
BuildError(String) | Не удалось сформировать транзакцию |
AssertionFailed(String) | Проверка результата завершилась неудачей |
Is this page helpful?