솔라나 문서LiteSVMRust프로그램 테스트

명령어 실행

개요

LiteSVM에 프로그램을 배포한 후, 배포된 프로그램과 상호작용하려면 명령어를 실행해야 합니다.

LiteSVM은 트랜잭션을 생성, 전송 및 시뮬레이션하기 위한 간단한 API를 제공하며, Solana의 트랜잭션 모델과 완전히 호환됩니다.

기본 트랜잭션 흐름

명령어를 실행하는 일반적인 흐름은 다음과 같습니다:

  1. 명령어 생성 - 호출할 프로그램과 전달할 데이터를 정의합니다
  2. 메시지 빌드 - 하나 이상의 명령어를 결합합니다
  3. 트랜잭션 생성 - 필요한 서명자로 메시지에 서명합니다
  4. 전송 또는 시뮬레이션 - 트랜잭션을 실행하고 결과를 처리합니다

명령어 생성

기본 명령어 구조

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)
};

트랜잭션 빌드 및 전송

방법 1: 기본 트랜잭션

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);

new_signed_with_payer의 동작:

  • 명령어로부터 메시지를 자동으로 빌드합니다
  • 제공된 모든 keypair로 트랜잭션에 자동으로 서명합니다
  • 완전히 서명된, 전송 준비가 완료된 트랜잭션을 반환합니다

방법 2: 커스텀 메시지 트랜잭션

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);

다음과 같이 Message를 직접 제어해야 할 때 이 방법을 사용하세요:

  • 버전 트랜잭션 (조회 테이블이 포함된 v0)
  • 부분/다중 서명 워크플로
  • 지속 가능한 논스
  • 서명 전 시뮬레이션 또는 검사
  • 커스텀 수수료 납부자 로직
  • 트랜잭션 크기 최적화

버전 트랜잭션

LiteSVM은 레거시 트랜잭션과 버전 트랜잭션을 모두 지원합니다:

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);

트랜잭션 결과

성공한 트랜잭션

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);
}
}

트랜잭션 메타데이터 필드

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,
}

트랜잭션 시뮬레이션

트랜잭션 시뮬레이션을 사용하면 상태를 변경하지 않고 트랜잭션을 테스트할 수 있습니다:

// 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);
}
}

오류 처리

일반적인 트랜잭션 오류

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(_) => {}
}

프로그램 로그 활용

로그 접근

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());

로그 출력 예시

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

컴퓨트 버짓 설정

글로벌 컴퓨트 버짓 설정

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

트랜잭션별 컴퓨트 버짓

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,
];

System Program 명령어

LiteSVM은 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,
);

요약

LiteSVM에서 명령어 실행은 표준 Solana 트랜잭션 모델을 따릅니다:

  1. 프로그램 ID, 계정, 데이터를 포함한 Instruction 객체 생성
  2. 명령어와 필수 서명자로 Transaction 구성
  3. 실행 시 send_transaction(), 테스트 시 simulate_transaction() 사용
  4. TransactionMetadata 또는 오류 세부 정보를 확인하여 결과 처리

LiteSVM은 상세한 로그와 디버깅 정보를 제공하며 즉각적인 실행이 가능하여 Solana 프로그램을 효율적으로 테스트하기에 최적화되어 있습니다.

Is this page helpful?