Eksekusi program

Ringkasan

Program dikompilasi ke sBPF melalui LLVM dan berjalan dalam VM sandbox dengan anggaran 1,4 juta CU per transaksi. Runtime menyimpan cache hingga 512 program yang dikompilasi, menyediakan syscall untuk logging, CPI, kripto, dan memori, serta menunda deployment baru sebanyak 1 slot.

Kompilasi

Solana menggunakan LLVM untuk mengompilasi program ke dalam binari ELF yang berisi Solana Bytecode Format (sBPF). Binari ELF disimpan on-chain dalam akun yang dapat dieksekusi.

sBPF adalah varian khusus Solana dari bytecode eBPF, yang disesuaikan untuk runtime Solana. Ini bukan eBPF standar dan memiliki modifikasi khusus Solana.

Program Solana terutama ditulis dalam Rust menggunakan salah satu dari dua pendekatan:

Model eksekusi program

Ketika transaksi diproses, runtime mengeksekusi setiap instruksi secara berurutan melalui process_message(). Untuk setiap instruksi, runtime:

  1. Menyiapkan konteks instruksi. Memanggil prepare_next_top_level_instruction() untuk memetakan indeks akun instruksi, mengatur flag signer dan writable, dan mengonfigurasi TransactionContext.

  2. Memeriksa precompile. Jika program adalah precompile, runtime memanggil process_precompile(), yang masih melakukan push dan pop stack frame (melalui push() dan pop()) tetapi melewati sBPF VM dan pencarian cache program, mengeksekusi kode native secara langsung.

  3. Mendorong stack frame. (Langkah 3-6 terjadi di dalam InvokeContext::process_instruction() dan process_executable_chain(), dipanggil dari process_message().) Memanggil push() pada InvokeContext, yang menambah tinggi stack instruksi dan menerapkan aturan reentrancy: sebuah program hanya dapat masuk kembali ke dirinya sendiri jika pemanggil langsung (program di posisi teratas stack instruksi saat ini) adalah program yang sama. Rekursi diri yang dalam (A -> A -> A) diperbolehkan, tergantung pada batas kedalaman stack. Pola reentrancy lainnya (misalnya, A memanggil B memanggil A) mengembalikan InstructionError::ReentrancyNotAllowed.

  4. Menyelesaikan program. Runtime memanggil process_executable_chain() yang menentukan loader. Jika pemilik program account adalah native loader, program tersebut adalah builtin dan fungsi entrypoint-nya dicari langsung dari ProgramCacheForTxBatch. Jika pemiliknya adalah salah satu BPF loader (bpf_loader_deprecated, bpf_loader, bpf_loader_upgradeable, atau loader_v4), entrypoint builtin loader itu sendiri yang dipanggil.

  5. Mengeksekusi program BPF. Untuk program BPF, entrypoint loader mencari executable yang telah dikompilasi dari cache program. execute() kemudian:

    • Menserialisasi data account ke dalam buffer parameter datar
    • Membuat VM sBPF dengan stack, heap, dan region memori
    • Menjalankan kode yang telah dikompilasi, mengonsumsi unit komputasi selama eksekusi. Mengembalikan ComputationalBudgetExceeded jika anggaran terlampaui.
    • Mendeserialisasi data account dari buffer kembali ke state account
  6. Mengeluarkan stack frame. Memanggil pop() yang memverifikasi bahwa instruksi tidak melanggar aturan akuntansi runtime (saldo lamport seimbang, account readonly tidak dimodifikasi, ukuran data account berada dalam batas).

  7. Mengakumulasi unit komputasi. Unit komputasi yang dikonsumsi oleh instruksi ditambahkan ke total transaksi melalui saturating_add.

Cache program

Runtime memelihara ProgramCache global yang menyimpan program yang telah diverifikasi dan dikompilasi. Cache ini menyadari fork-graph dan menangani aturan visibilitas deployment, eviction, dan kompilasi ulang pada batas epoch.

Jenis entri cache

Setiap program yang di-cache memiliki ProgramCacheEntryType yang menentukan perilaku runtime-nya:

JenisDeskripsi
LoadedProgram yang telah diverifikasi dan dikompilasi, siap untuk dieksekusi.
BuiltinProgram native yang dikompilasi ke dalam binary validator (System, Stake, Vote, dll.). Tidak disimpan on-chain.
UnloadedProgram yang sebelumnya telah diverifikasi namun executable yang dikompilasi telah dievict dari memori untuk mengosongkan ruang. Masih melacak statistik penggunaan. Dapat dimuat ulang tanpa verifikasi ulang.
FailedVerificationTombstone untuk program yang tidak lolos verifier sBPF di bawah feature set saat ini. Dapat menjadi Loaded jika aktivasi fitur mengubah aturan verifikasi.
ClosedTombstone untuk program yang secara eksplisit ditutup atau tidak pernah di-deploy. Juga digunakan untuk akun (seperti akun buffer) yang termasuk dalam loader tetapi tidak berisi kode yang dapat dieksekusi.
DelayVisibilityTombstone sintetis yang dikembalikan oleh ProgramCacheForTxBatch::find() ketika entri Loaded ada tetapi belum efektif (effective_slot-nya di masa depan). Tidak pernah disimpan langsung di cache.

Penundaan visibilitas

Program yang baru di-deploy atau di-upgrade tidak langsung efektif. Konstanta DELAY_VISIBILITY_SLOT_OFFSET adalah 1, yang berarti program yang di-deploy di slot N menjadi efektif di slot N+1. Selama slot deployment, setiap upaya untuk memanggil versi baru mengembalikan DelayVisibility, menyebabkan runtime melaporkan "Program is not deployed."

Kebijakan eviksi

Cache menyimpan hingga MAX_LOADED_ENTRY_COUNT (512) entri program yang dikompilasi. Ketika batas tercapai, program yang paling jarang digunakan akan dieviksi ke status Unloaded. Penggunaan dilacak oleh tx_usage_counter (ditambahkan setiap kali transaksi mereferensikan program) dan latest_access_slot.

Rekompilasi batas epoch

Jika aktivasi fitur mengubah ProgramRuntimeEnvironments pada batas epoch, semua program yang di-cache akan dikompilasi ulang terhadap lingkungan yang baru.

Data pengembalian

Program dapat mengatur data pengembalian melalui syscall sol_set_return_data. Data disimpan dalam TransactionReturnData struct tingkat transaksi yang menyimpan byte data dan program_id dari program yang instruksinya memanggil syscall. Ukuran maksimum adalah 1.024 byte (MAX_RETURN_DATA).

Is this page helpful?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung