LiteSVM
LiteSVM 0.6.x executa uma VM Solana in-process para testes de programa em sub-segundo sem solana-test-validator. Use para testes unitários, casos negativos de segurança e loops de feedback Rust apertados.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
use litesvm::LiteSVM;
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
signature::Keypair,
signer::Signer,
transaction::Transaction,
};
let mut svm = LiteSVM::new();
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();
svm.add_program(program_id, include_bytes!("../target/deploy/my_program.so"));Quando usar:
- Testar handlers de instrução em
#[test]Rust puro. - Fuzzing adversarial de account meta rapidamente.
- Camada de teste unitário CI antes de
anchor testmais lento. - Depurar erros de programa sem ruído RPC.
Exemplo prático
use litesvm::LiteSVM;
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
signature::Keypair,
signer::Signer,
system_program,
transaction::Transaction,
};
#[test]
fn withdraw_requires_signer() {
let program_id = Pubkey::new_unique();
let mut svm = LiteSVM::new();
svm.add_program(program_id, include_bytes!("../target/deploy/my_program.so"));
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 2_000_000_000).unwrap();
let vault = Pubkey::new_unique();
let ix = Instruction {
program_id,
accounts: vec![
AccountMeta::new(vault, false),
AccountMeta::new_readonly(payer.pubkey(), false), // missing signer
],
data: vec![1, 0, 0, 0], // withdraw discriminator stub
};
let tx = Transaction::new_signed_with_payer(
&[ix],
Some(&payer.pubkey()),
&[&payer],
svm.latest_blockhash(),
);
let result = svm.send_transaction(tx);
assert!(result.is_err());
}O que isso demonstra:
- Carregue
.socompilado diretamente no LiteSVM. - Construa transações com account metas explícitos para casos de ataque.
- Asserte falha sem iniciar validador ou harness TypeScript.
Mergulho profundo
Como funciona
- LiteSVM embute execução SVM no processo de teste.
- Sysvars, rent e comportamento do BPF loader aproximam semântica Agave 4.1.1.
- Blockhash e clock podem ser avançados manualmente para testes dependentes de tempo.
- Sem RPC - testes rodam inteiramente em memória.
LiteSVM vs outros harnesses
| Ferramenta | Velocidade | Fidelidade | Linguagem |
|---|---|---|---|
| LiteSVM 0.6.x | Mais rápido | Alta para lógica ix | Rust |
| Mollusk | Rápido | Focado em instrução | Rust |
| Bankrun | Rápido | Ergonomia TS | TypeScript |
| test-validator | Lento | RPC completo | Qualquer |
Notas Rust
// Avance clock para testes de obsolescência
svm.set_sysvar(&solana_sdk::clock::Clock {
unix_timestamp: 1_700_000_000,
..Default::default()
});Erros comuns
- Artefato .so obsoleto - Teste executa binário antigo após mudança de código. Correção:
anchor buildno CI antes decargo test. - Programas ausentes no svm - CPI para SPL Token falha sem carregar token program. Correção:
svm.add_programpara dependências. - Setup de dados de conta - Contas não inicializadas precisam packing manual de dados. Correção: Helper para escrever layouts Borsh/Anchor em contas svm.
- Blockhash expirado - Sequências longas precisam
svm.expire_blockhash()ou refresh. Correção: Busquelatest_blockhash()por tx. - Mismatch de features - Features de build diferem do deploy. Correção: Mesmas features
Cargo.tomlque build de release. - Não é RPC completo - Quirks específicos de RPC precisam testes de validador. Correção: Camada E2E separada.
Alternativas
| Alternativa | Use quando | Não use quando |
|---|---|---|
| Mollusk | Apenas Rust em nível de instrução | Quer ergonomia completa de simulação de tx |
| Bankrun | Equipe TypeScript | Fluxo Rust puro |
| anchor test | Integração completa | Velocidade inner-loop |
FAQs
Qual versão LiteSVM combina com Agave 4.1.1?
Fixe LiteSVM 0.6.x no manifest; verifique release notes para compatibilidade de syscall.
LiteSVM testa CPIs?
Sim - carregue programas callee (Token, seu vault) e forneça grafo de contas correto.
Como financiar contas?
svm.airdrop para SOL; defina dados de conta token manualmente para saldos SPL.
Anchor funciona com LiteSVM?
Use .so bruto + dados de instrução, ou helpers da comunidade para construir discriminators Anchor.
Integração CI?
cargo test após anchor build - sem serviço validador exigido para camada LiteSVM.
Como testar signers PDA?
Inclua conta PDA correta com is_signer: false; programa invoca CPI assinado internamente.
Logs disponíveis?
Txs falhas retornam logs no erro - asserte substrings de log para debug msg! customizado.
Testes paralelos?
Cada teste deve possuir LiteSVM::new() - evite svm mutável compartilhado entre threads.
Program IDs devnet?
Use mesmos program IDs do cluster alvo ao testar allowlists CPI.
Quando graduar para testes de validador?
Ao depender de métodos RPC, ALTs ou comportamento de landing multi-tx.
Relacionados
- Noções básicas de testes - contexto da pirâmide
- Mollusk - harness Rust alternativo
- Testando CPIs e PDAs - padrões de teste CPI
- Melhores práticas de segurança - testes negativos
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.