Pierwsze kroki
let mut svm = LiteSVM::new();
Tworzy to podstawową instancję testową litesvm, która zawiera wszystkie włączone funkcje środowiska uruchomieniowego, domyślne sysvary, prekompilacje, programy spl, sigverify oraz wszystkie wbudowane programy, takie jak System Program.
Aby w testach korzystać z innych programów, należy wdrożyć je do środowiska testowego.
-
Zbuduj i wdróż program, który chcesz przetestować
-
Znajdź wszystkie programy, do których powyższy program wykonuje wywołania CPI, i wdróż je
Przykład: Jeśli Twój program korzysta z danych rynkowych Pyth, musisz mieć wdrożony program Pyth w swojej instancji testowej.
Podstawowe wdrażanie programów
Metoda 1: Wdrożenie z tablicy bajtów
Wdrażaj programy bezpośrednio z tablic bajtów, aby uzyskać najszybsze wykonanie testów:
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! osadza plik binarny bezpośrednio w wykonywalnym pliku testowym
podczas kompilacji, eliminując operacje wejścia/wyjścia podczas wykonywania
testów.
✓ Zalety
- •Szybsze działanie w czasie wykonywania (brak odczytów z dysku)
- •Samodzielny plik binarny testów
- •Działa nawet po usunięciu pliku .so po kompilacji
✗ Wady
- •Większy rozmiar pliku binarnego testów
- •Konieczność ponownej kompilacji testów przy zmianie pliku .so
Metoda 2: Wdrożenie z pliku (.so)
Ładuj programy z systemu plików, gdy często się zmieniają:
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);
✓ Zalety
- •Mniejszy plik binarny testów
- •Możliwość pobierania zmian .so bez ponownej kompilacji testów
- •Większa elastyczność w potokach CI/CD
✗ Wady
- •Wolniejsze działanie (operacje I/O na dysku w czasie wykonania)
- •Wymaga obecności pliku .so w momencie wykonania testów
- •Ścieżka do pliku musi być poprawna względem katalogu wykonania testów
Pobieranie programów z Mainnet/Devnet
Jeśli potrzebujesz programu, do którego nie masz kodu źródłowego, użyj Solana CLI, aby pobrać programy z działających klastrów i wykorzystać je w testach:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Następnie załaduj go w testach:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Najlepsze praktyki
1. Wybierz właściwą metodę wdrożenia
-
Użyj
add_program()gdy:- Programy są osadzone w binarnym pliku testów w czasie kompilacji
- Zależy Ci na szybszym wykonaniu testów (brak operacji I/O w czasie wykonania)
- Testy mają być samowystarczalne
-
Użyj
add_program_from_file()gdy:- Programy są budowane osobno (tzn. pobierane z devnet)
- Programy często się zmieniają podczas programowania (można ponownie uruchomić testy bez rekompilacji)
- Masz środowiska CI/CD, w których pliki .so są artefaktami
Zrozumienie keypair programu
Kiedy budujesz program Solana:
- Anchor tworzy
target/deploy/program-keypair.json - Kompilacje natywne tworzą plik keypair obok pliku
.so - Adres on-chain programu to klucz publiczny tego keypair, znany również jako ID programu.
- W przypadku PDA,
find_program_address()wymaga ID programu jako seed - W przypadku CPI, ID programu służy do wywoływania innych programów
Typowe problemy i rozwiązania
Ciche błędy wdrożenia
Problem: Program wydaje się być wdrożony, ale transakcje kończą się błędem "InvalidProgramForExecution".
Przyczyna: ID programu nie pasuje do keypair.
Rozwiązanie:
// 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);
Błąd: nie znaleziono programu
Błąd: TransactionError::InvalidProgramForExecution
Częste przyczyny:
- Program nie został wdrożony
- Użyto nieprawidłowego ID programu w instrukcji
- Niezgodność ID programu z keypair
Kroki diagnostyczne:
// 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 do niewdrożonych programów
Problem: Twój program wykonuje wywołanie CPI do programu, który nie jest wdrożony.
Rozwiązanie: Wdróż wszystkie programy zależne:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Jeśli chcesz pobrać program z klastra, zapoznaj się z tą sekcją.
Niewystarczająca liczba lamport do wdrożenia
Uwaga: LiteSVM automatycznie obsługuje saldo zwolnione z czynszu dla programów.
// 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 kontrolna weryfikacji wdrożenia
Odczytaj keypair programu
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Wdróż z pasującym ID
svm.add_program(program_id, &program_bytes).unwrap();
Zweryfikuj wdrożenie
assert!(svm.get_account(&program_id).unwrap().executable);
Wdróż wszystkie programy, które Twój program wywołuje przez CPI, do instancji testowej litesvm
Następne kroki
W następnej sekcji nauczymy się, jak wykonywać instrukcje programu i obsługiwać złożone wzorce transakcji.
Is this page helpful?