CPI maliyet modeli ve veri senkronizasyonu

Özet

Her CPI, temel olarak ~1.000 CU artı serileştirme maliyetlerine mal olur. Hesap verisi, çağrılan programın yürütülmesinden önce ve sonra senkronize edilir. PDA imzalama, çağıran programın program ID'sini kullanır. Dönüş verisi 1.024 bayt ile sınırlıdır.

CPI maliyet modeli

CPI maliyetleri, aynı işlem hesaplama bütçesinden (paylaşılan sayaç) çekilir. Her invoke / invoke_signed çağrısı için tam maliyet formülü:

total_cpi_cost = invocation_cost
+ instruction_data_cost
+ account_meta_cost (SIMD-0339 only)
+ account_info_cost (SIMD-0339 only)
+ per_account_data_cost (for each non-executable account)
+ callee_execution_cost

Maliyet dağılımı

Maliyet bileşeniFormülKaynak
Çağrı (sabit)invoke_units = 1.000 CU (SIMD-0339 ile 946)CPI girişinde ücretlendirilir
Instruction data serileştirmeinstruction_data_len / cpi_bytes_per_unitcpi_bytes_per_unit = 250. translate_instruction içinde ücretlendirilir.
Hesap meta serileştirme (SIMD-0339)(num_account_metas * 34) / cpi_bytes_per_unitHer AccountMeta 34 bayttır (32 pubkey + 1 is_signer + 1 is_writable). translate_instruction içinde ücretlendirilir.
Hesap bilgisi çevirisi (SIMD-0339)(num_account_infos * 80) / cpi_bytes_per_unitACCOUNT_INFO_BYTE_SIZE = 80 bayt (32 key + 32 owner + 8 lamports + 8 data_len). translate_account_infos içinde ücretlendirilir.
Hesap başına veriaccount_data_len / cpi_bytes_per_unitCallerAccount::from_account_info içinde hesap başına ve çalıştırılabilir hesaplar için ücretlendirilir.
Çağrılan programın yürütülmesiÇağrılan programın tükettiği CU miktarıÇağrılan programın yürütülmesi sırasında paylaşılan sayaçtan düşülür.

Örnek maliyet hesaplaması

100 bayt instruction data, 5 hesap meta, 5 hesap bilgisi (her biri 1.000 bayt veri içeren) ve SIMD-0339 aktif olan bir CPI:

invocation_cost = 946
instruction_data_cost = 100 / 250 = 0 (integer division)
account_meta_cost = (5 * 34) / 250 = 0
account_info_cost = (5 * 80) / 250 = 1
per_account_data_cost = 5 * (1000 / 250) = 20
total (before callee) = 967 CUs

Hesap verisi senkronizasyonu

Hesap durumu, bir CPI sırasında çağıran ve çağrılan arasında iki noktada senkronize edilir. Bu, her iki tarafın da hesap verisinin tutarlı bir görünümünü görmesini sağlar.

CPI öncesi senkronizasyon (çağırandan çağrılana)

Çağrılan çalıştırılmadan önce, update_callee_account çağıranın devam eden değişikliklerini çağrılanın hesap görünümüne kopyalar:

AlanYönNe zaman
LamportsÇağıran -> ÇağrılanDeğer, çağrılanın mevcut görünümünden farklıysa
Veri uzunluğuÇağıran -> ÇağrılanÇağıran hesabı yeniden boyutlandırdıysa. original_data_len + MAX_PERMITTED_DATA_INCREASE (10 KiB) değerini aşmamalıdır.
Veri içeriğiÇağıran -> ÇağrılanHesabın verisi değiştirilebilir durumdaysa (can_data_be_changed geçerse)
SahipÇağıran -> ÇağrılanEn son ayarlanır, böylece veri/lamport değişikliklerine eski sahip altında izin verilir

CPI sonrası senkronizasyon (çağrılandan çağırana)

Çağrılan geri döndükten sonra, update_caller_account çağrılanın değişikliklerini çağıranın görünümüne geri kopyalar. Bu yalnızca yazılabilir olarak işaretlenmiş hesaplar için çalışır:

AlanYönNe zaman
LamportsÇağrılan -> ÇağıranHer zaman geri kopyalanır
SahipÇağrılan -> ÇağıranHer zaman geri kopyalanır
Veri uzunluğuÇağrılan -> ÇağıranDeğiştiyse. VM veri dilimi işaretçisi ve serileştirilmiş uzunluk alanı güncellenir. Hesap küçültüldüyse, serbest bırakılan bellek sıfırlanır. Yeni uzunluk original_data_len + MAX_PERMITTED_DATA_INCREASE değerini aşarsa, InvalidRealloc döndürür.
Veri içeriğiÇağrılan -> ÇağıranÇağrılanın veri tamponundan çağıranın serileştirilmiş veri bölgesine kopyalanır

Realloc sınırları

Hesap verileri, CPI sırasında mevcut üst düzey talimatın başlangıcındaki hesap veri uzunluğunun MAX_PERMITTED_DATA_INCREASE = 10.240 bayt (10 KiB) ötesine kadar yeniden boyutlandırılabilir. Bu sınır hem update_callee_account (CPI öncesi) hem de update_caller_account (CPI sonrası) içinde uygulanır. Bu sınırın aşılması InvalidRealloc döndürür.

PDA imzalama

invoke_signed çağrıldığında, çalışma zamanı sağlanan seed'lerden ve çağıranın program ID'sinden PDA adreslerini türetir. Bu işlem translate_signers_rust içinde gerçekleşir:

  1. İmzalayan seed dizisi doğrulanır: en fazla MAX_SIGNERS (16) imzalayan seed seti.
  2. Her seed seti doğrulanır: set başına en fazla MAX_SEEDS (16) seed, her seed en fazla MAX_SEED_LEN (32) bayt.
  3. Pubkey::create_program_address seed'ler ve çağıranın program ID'si (çağrılanın değil) ile çağrılır.
  4. Eğer seed'ler geçerli bir PDA üretmezse (yani, ortaya çıkan nokta ed25519 eğrisi üzerindeyse), CPI BadSeeds ile başarısız olur.
  5. Türetilen PDA pubkey'leri toplanır ve geçerli imzalayanlar olarak prepare_next_instruction'e aktarılır. Yetki kontrolü sırasında, bir çağrılan hesap imzalayan olarak işaretlenmişse ve pubkey'i bu türetilmiş PDA'lardan biriyle eşleşiyorsa, imzalayan kontrolü geçer.

PDA, çağıranın program ID'si kullanılarak türetilir, çağrılanın değil. Bu, yalnızca PDA'ya sahip olan programın (türetmek için ID'si kullanılan programın) onun adına imzalayabileceği anlamına gelir. Bir program, diğer programlardan türetilen PDA'lar için imzalayamaz.

Dönüş verisi

Programlar, dönüş verisi mekanizmasını kullanarak çağıranlara veri geri gönderebilir. Bu işlem iki syscall kullanır:

  • sol_set_return_data: Mevcut talimat için MAX_RETURN_DATA (1.024) bayta kadar dönüş verisi ayarlar. Maliyet data_len / cpi_bytes_per_unit + syscall_base_cost CU'dur.
  • sol_get_return_data: En son yürütülen talimat tarafından ayarlanan dönüş verisini okur. Veriyi, onu ayarlayan program ID'si ile birlikte döndürür. Maliyet (data_len + 32) / cpi_bytes_per_unit + syscall_base_cost CU'dur (program ID'si için 32 bayt).

Dönüş verisi işlem başına saklanır ve sol_set_return_data çağrısı yapan her talimat tarafından üzerine yazılır. Her program çağrısının başlangıcında, çalışma zamanı dönüş verisini sıfırlar ve boş hale getirir. Bir CPI döndükten sonra, çağıran taraf, çağrılanın (veya çağrılanın çağırdığı herhangi bir programın) en son ayarladığı dönüş verisini okuyabilir.

Dönüş verisi 1.024 bayt ile sınırlıdır. Çağrı zincirinde sol_set_return_data çağrısı yapan son program, çağıranın ne göreceğini belirler. Eğer çağrılan taraf, dönüş verisi ayarlayan başka CPI'lar yaparsa, çağrılanın kendi dönüş verisi üzerine yazılır.

Is this page helpful?

İçindekiler

Sayfayı Düzenle

Yönetici

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