Ξεκινώντας
let mut svm = LiteSVM::new();
Αυτό δημιουργεί τη βασική δοκιμαστική παρουσία litesvm, η οποία περιλαμβάνει όλες τις ενεργοποιημένες λειτουργίες χρόνου εκτέλεσης, προεπιλεγμένες sysvars, precompiles, προγράμματα spl, sigverify, και όλα τα ενσωματωμένα προγράμματα όπως το System Program.
Για να αλληλεπιδράσετε με οποιοδήποτε άλλο πρόγραμμα στις δοκιμές σας, πρέπει να αναπτύξετε αυτό το πρόγραμμα στο περιβάλλον δοκιμών σας.
-
Δημιουργήστε και αναπτύξτε το πρόγραμμα που θέλετε να δοκιμάσετε
-
Βρείτε όλα τα προγράμματα στα οποία το παραπάνω πρόγραμμα πραγματοποιεί κλήσεις CPI και αναπτύξτε αυτά τα προγράμματα
Παράδειγμα: Εάν το πρόγραμμά σας χρησιμοποιεί ροές δεδομένων από το Pyth, θα χρειαστεί να έχετε το πρόγραμμα Pyth αναπτυγμένο στη δοκιμαστική παρουσία σας.
Βασική Ανάπτυξη Προγράμματος
Μέθοδος 1: Ανάπτυξη από Bytes
Αναπτύξτε προγράμματα απευθείας από πίνακες bytes για την ταχύτερη εκτέλεση δοκιμών:
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! ενσωματώνει το δυαδικό αρχείο απευθείας στο εκτελέσιμο δοκιμής
κατά τη στιγμή της μεταγλώττισης, εξαλείφοντας τις λειτουργίες I/O κατά την
εκτέλεση των δοκιμών.
✓ Πλεονεκτήματα
- •Ταχύτερο κατά την εκτέλεση (χωρίς ανάγνωση από δίσκο)
- •Αυτόνομο δυαδικό αρχείο δοκιμής
- •Λειτουργεί ακόμα και αν το αρχείο .so διαγραφεί μετά τη μεταγλώττιση
✗ Μειονεκτήματα
- •Μεγαλύτερο μέγεθος δυαδικού αρχείου δοκιμής
- •Απαιτείται επαναμεταγλώττιση των δοκιμών όταν αλλάζει το .so
Μέθοδος 2: Ανάπτυξη από Αρχείο (.so)
Φορτώστε προγράμματα από το σύστημα αρχείων όταν αλλάζουν συχνά:
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);
✓ Πλεονεκτήματα
- •Μικρότερο δυαδικό αρχείο δοκιμών
- •Δυνατότητα ανίχνευσης αλλαγών .so χωρίς επαναμεταγλώττιση δοκιμών
- •Μεγαλύτερη ευελιξία για αγωγούς CI/CD
✗ Μειονεκτήματα
- •Πιο αργό (I/O δίσκου κατά το χρόνο εκτέλεσης)
- •Απαιτεί ύπαρξη του αρχείου .so κατά τον χρόνο εκτέλεσης δοκιμών
- •Η διαδρομή αρχείου πρέπει να είναι σωστή σχετικά με τον κατάλογο εκτέλεσης δοκιμών
Λήψη Προγραμμάτων από το Mainnet/Devnet
Όταν χρειάζεστε ένα πρόγραμμα για το οποίο δεν έχετε τον κώδικα, χρησιμοποιήστε το Solana CLI για εξαγωγή προγραμμάτων από ενεργά clusters και χρησιμοποιήστε τα σε δοκιμές:
# Dump a program from mainnetsolana program dump gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s pyth.so --url mainnet-beta# Dump from devnetsolana program dump YourProgramID program.so --url devnet
Στη συνέχεια φορτώστε το στις δοκιμές σας:
svm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Βέλτιστες Πρακτικές
1. Επιλέξτε τη Σωστή Μέθοδο Ανάπτυξης
-
Χρησιμοποιήστε
add_program()όταν:- Τα προγράμματα είναι ενσωματωμένα στο δυαδικό αρχείο δοκιμών κατά τη μεταγλώττιση
- Θέλετε ταχύτερη εκτέλεση δοκιμών (χωρίς I/O κατά το χρόνο εκτέλεσης)
- Αυτόνομες δοκιμές
-
Χρησιμοποιήστε το
add_program_from_file()όταν:- Τα προγράμματα δημιουργούνται ξεχωριστά (δηλ. ανάκτηση από το devnet)
- Το πρόγραμμα αλλάζει συχνά κατά την ανάπτυξη (δυνατότητα επανεκτέλεσης δοκιμών χωρίς επαναμεταγλώττιση)
- Διαθέτετε περιβάλλοντα CI/CD όπου τα αρχεία .so είναι artifacts
Κατανόηση των keypair Προγραμμάτων
Όταν δημιουργείτε ένα πρόγραμμα Solana:
- Το Anchor δημιουργεί
target/deploy/program-keypair.json - Οι Native builds δημιουργούν ένα αρχείο keypair δίπλα στο αρχείο
.so - Η διεύθυνση on-chain του προγράμματος είναι το public key αυτού του keypair, γνωστό επίσης ως program ID.
- Για PDAs, το
find_program_address()απαιτεί το program ID ως seed - Για CPIs, το program ID χρησιμοποιείται για την κλήση άλλων προγραμμάτων
Συνηθισμένα Προβλήματα και Λύσεις
Αθόρυβες Αποτυχίες Ανάπτυξης
Πρόβλημα: Το πρόγραμμα φαίνεται να αναπτύσσεται αλλά οι συναλλαγές αποτυγχάνουν με το μήνυμα "InvalidProgramForExecution".
Αιτία: Το program ID δεν ταιριάζει με το keypair.
Λύση:
// 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);
Σφάλμα: Το Πρόγραμμα Δεν Βρέθηκε
Σφάλμα: TransactionError::InvalidProgramForExecution
Συνηθισμένες Αιτίες:
- Το πρόγραμμα δεν έχει αναπτυχθεί
- Χρησιμοποιήθηκε λάθος program ID στην εντολή
- Αναντιστοιχία program ID με keypair
Βήματα Εντοπισμού Σφαλμάτων:
// 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 σε Μη Αναπτυγμένα Προγράμματα
Πρόβλημα: Το πρόγραμμά σας πραγματοποιεί μια κλήση CPI σε ένα πρόγραμμα που δεν έχει αναπτυχθεί.
Λύση: Αναπτύξτε όλα τα προγράμματα εξαρτήσεων:
// Find all dependency programs and make sure they are deployedsvm.add_program_from_file(pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s"),"pyth.so").unwrap();
Αν χρειάζεται να ανακτήσετε το πρόγραμμα από ένα cluster, ανατρέξτε στην ενότητα αυτή.
Ανεπαρκή lamport για Ανάπτυξη
Σημείωση: Το LiteSVM χειρίζεται αυτόματα το rent-exempt υπόλοιπο για τα προγράμματα.
// 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);
Λίστα Ελέγχου Επαλήθευσης Ανάπτυξης
Διαβάστε το keypair του προγράμματος
let keypair = read_keypair_file("target/deploy/program-keypair.json").unwrap();let program_id = keypair.pubkey();
Αναπτύξτε με αντίστοιχο ID
svm.add_program(program_id, &program_bytes).unwrap();
Επαληθεύστε την ανάπτυξη
assert!(svm.get_account(&program_id).unwrap().executable);
Αναπτύξτε τυχόν προγράμματα που καλεί το πρόγραμμά σας μέσω CPI στην περίπτωση δοκιμής litesvm
Επόμενα Βήματα
Στην επόμενη ενότητα, θα μάθουμε πώς να εκτελούμε εντολές προγράμματος και να χειριζόμαστε σύνθετα μοτίβα συναλλαγών.
Is this page helpful?