Hesap çalışma zamanı

Özet

Yürütmeden önce, çalışma zamanı hesapları yükler, ücret ödeyiciyi doğrular, kira muafiyetini kontrol eder ve hesap verilerini programların erişebileceği bir bellek düzenine serileştirir.

Bu sayfa çalışma zamanı iç yapısını kapsar. Çoğu geliştirici program oluşturmak için bu bilgiye ihtiyaç duymaz. Geliştirici odaklı görünüm için Hesap Yapısı sayfasına bakın.

Hesap yükleme

Bir işlem yürütülmeden önce, çalışma zamanı tüm referans verilen hesapları load_transaction_accounts() aracılığıyla yükler. Bu süreç birkaç doğrulama gerçekleştirir:

  1. Ücret ödeyici doğrulaması: Ücret ödeyici (ilk hesap) mevcut olmalı, bir sistem hesabı veya nonce hesabı olmalı ve ücretleri karşılamak için yeterli lamport'a sahip olmalıdır (validate_fee_payer()). Ücretleri ödedikten sonra, hesap ya kira muafiyetini korumalı ya da tam olarak 0 lamport'a düşmelidir. 0 ile kira muafiyeti minimumu arasında kalamaz. Nonce hesapları her zaman kira muafiyetini korumak için yeterli lamport'u tutmalıdır. Ödeyici ne bir sistem hesabı ne de bir nonce hesabı ise, işlem TransactionError::InvalidAccountForFee ile başarısız olur.

  2. Yüklenen veri boyutu sınırı: Yüklenen tüm hesapların toplam boyutu (hesap başına TRANSACTION_ACCOUNT_BASE_SIZE 64 bayt dahil) MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES değerini (64 MiB) aşmamalıdır. Bu sınırın aşılması TransactionError::MaxLoadedAccountsDataSizeExceeded üretir.

  3. Program hesabı doğrulaması: Bir talimat tarafından çağrılan her program mevcut olmalı ve geçerli bir yükleyiciye ait olmalıdır: PROGRAM_OWNERS (BPF Loader Upgradeable, BPF Loader, BPF Loader Deprecated, Loader V4) veya native loader'dan biri. Program hesabı mevcut değilse, işlem TransactionError::ProgramAccountNotFound ile başarısız olur. Mevcut ancak geçersiz bir sahibi varsa, işlem TransactionError::InvalidProgramForExecution ile başarısız olur.

  4. Var olmayan hesaplar: Zincir üzerinde bulunmayan hesaplar, rent_epoch değeri u64::MAX olarak ayarlanmış varsayılan hesaplar (0 lamport, boş veri, sistem programına ait) olarak yüklenir.

BPF serileştirme formatı

Bir program çağrıldığında, çalışma zamanı hesapları bitişik bir bellek arabelleğine serileştirir ve BPF VM'ye iletir. Serileştirme formatı (kullanımdan kaldırılan loader-v1 hariç tüm yükleyiciler tarafından kullanılan standart hizalanmış format için) serialize_parameters_aligned() içinde tanımlanmıştır.

Arabellek, hesap sayısını içeren bir u64 (8 bayt, little-endian) ile başlar. Ardından, talimattaki her hesap için arabellek şunları içerir:

OfsetBoyutAlanTür
01tekrar işaretleyiciu8 (0xFF = benzersiz, indeks = o hesabın kopyası)
11is_signeru8 (0 veya 1)
21is_writableu8 (0 veya 1)
31executableu8 (0 veya 1)
44original_data_len (ayrılmış, her zaman 0)[0u8; 4]
832keyPubkey
4032ownerPubkey
728lamportsu64 (little-endian)
808data_lenu64 (little-endian)
88data_lendata[u8]
88 + data_len10240 + dolgurealloc alanı + hizalamaMAX_PERMITTED_DATA_INCREASE (10 KiB) + BPF_ALIGN_OF_U128 (8 bayt) hizalaması için dolgu ile sıfırlarla doldurulmuş
...8rent_epochu64 (little-endian)

Tüm hesaplardan sonra, tampon şunları ekler:

BoyutAlan
8instruction_data_len (u64, little-endian)
instruction_data_leninstruction_data
32program_id (Pubkey)

Yinelenen hesaplar için, yalnızca 1 bayt (orijinalin indeksini içeren yineleme işaretleyicisi) artı 7 bayt dolgu yazılır.

Hesap tekilleştirme

Aynı hesap genel anahtarı bir talimatın accounts dizisinde birden fazla kez göründüğünde, çalışma zamanı bunları tekilleştirir. Talimatın hesap listesindeki her giriş kendi InstructionAccount yapısına sahiptir, ancak aynı işlem düzeyindeki hesaba atıfta bulunan girişler aynı temel verilere işaret eder.

is_instruction_account_duplicate metodu, belirli bir talimat hesap indeksinin ilk oluşum mu yoksa yineleme mi olduğunu, işlem düzeyindeki hesap indeksini arayarak ve ona eşlenen ilk talimat düzeyindeki indeksi bularak belirler:

  • Mevcut talimat hesap indeksi, ilk eşlenen indekse eşitse, bu bir yineleme değildir (None döndürür).
  • Aksi takdirde, Some(first_index) döndürür; burada first_index, ilk oluşumun indeksidir.

Aynı hesaba yapılan tüm referanslar aynı temel AccountSharedData'i paylaştığından, herhangi bir referans aracılığıyla yapılan değişiklikler diğer tüm referanslar aracılığıyla anında görünür. Ancak, aynı anda yalnızca bir değiştirilebilir ödünç alma tutulabilir. Aynı hesabı iki farklı talimat hesap indeksi aracılığıyla eşzamanlı olarak değiştirilebilir şekilde ödünç almaya çalışmak InstructionError::AccountBorrowFailed döndürür. Programlar, aynı temel hesapta başka bir ödünç alma işlemi yapmadan önce bir ödünç almayı bırakmalıdır.

Program çalıştırıldıktan sonra, çalışma zamanı tamponu geri serileştirir (deserialize_parameters_aligned()) ve lamports, data (uzunluk değişiklikleri dahil, MAX_PERMITTED_DATA_INCREASE'e kadar) ve owner'deki tüm değişiklikleri uygular.

Is this page helpful?

İçindekiler

Sayfayı Düzenle

Yönetici

© 2026 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın