Eksekusi Program

Ringkasan

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

Kompilasi

Solana menggunakan LLVM untuk mengompilasi program menjadi biner ELF yang berisi Solana Bytecode Format (sBPF). Biner ELF disimpan secara onchain dalam sebuah executable account.

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

Tulis program

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

Lihat Cross-Program Invocations untuk konsep dan contoh CPI yang berlaku di semua pendekatan ini.

Model eksekusi program

Saat sebuah 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, serta mengonfigurasi TransactionContext.

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

  3. Melakukan push stack frame. (Langkah 3-6 terjadi di dalam InvokeContext::process_instruction() dan process_executable_chain(), dipanggil dari process_message().) Memanggil push() pada InvokeContext, yang menaikkan tinggi stack instruksi dan memberlakukan aturan reentrancy: sebuah program hanya dapat masuk kembali ke dirinya sendiri jika pemanggil langsung (program di puncak stack instruksi saat ini) adalah program yang sama. Rekursi-diri mendalam (A -> A -> A) diizinkan, tunduk 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 adalah builtin dan fungsi entrypointnya dicari langsung dari ProgramCacheForTxBatch. Jika pemiliknya adalah salah satu BPF loader (bpf_loader_deprecated, bpf_loader, bpf_loader_upgradeable, atau loader_v4), entrypoint builtin milik loader itu sendiri yang akan dipanggil.

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

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

  7. Mengakumulasi compute unit. Compute unit yang dikonsumsi oleh instruksi ditambahkan ke total transaksi melalui saturating_add.

Cache program

Runtime mempertahankan ProgramCache global yang menyimpan program yang telah diverifikasi dan dikompilasi. Cache ini mengetahui fork-graph dan menangani aturan visibilitas deployment, eviction, dan rekompilasi batas epoch.

Tipe entri cache

Setiap program yang di-cache memiliki ProgramCacheEntryType yang menentukan perilaku runtimenya:

TipeDeskripsi
LoadedProgram yang telah diverifikasi dan dikompilasi, siap untuk dieksekusi.
BuiltinProgram native yang dikompilasi ke dalam biner validator (System, Stake, Vote, dll.). Tidak disimpan onchain.
UnloadedProgram yang sebelumnya telah diverifikasi namun executable yang telah dikompilasi di-evict dari memori untuk membebaskan 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 buffer account) yang dimiliki oleh 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 ada di masa depan). Tidak pernah disimpan langsung di cache.

Penundaan visibilitas

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

Kebijakan eviction

Cache menampung hingga MAX_LOADED_ENTRY_COUNT (512) entri program yang telah dikompilasi. Ketika batas tercapai, program yang paling jarang digunakan di-evict ke state Unloaded. Penggunaan dilacak oleh tx_usage_counter (dinaikkan 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 dikompilasi ulang terhadap environment baru.

Data kembalian

Program dapat mengatur data kembalian melalui syscall sol_set_return_data. Data disimpan dalam struktur TransactionReturnData di 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
© 2026 Yayasan Solana. Semua hak dilindungi.