CPI-kustannusmalli ja tietojen synkronointi

Yhteenveto

Jokainen CPI maksaa ~1 000 CU:ta peruskustannuksena plus serialisointikustannukset. Tilidata synkronoidaan ennen kutsuttavan suoritusta ja sen jälkeen. PDA-allekirjoitus käyttää kutsijan ohjelmatunnusta. Paluudata on rajoitettu 1 024 tavuun.

CPI-kustannusmalli

CPI-kustannukset vähennetään samasta transaktiolaskentabudjetista (jaettu mittari). Täydellinen kustannuskaava jokaiselle invoke / invoke_signed -kutsulle:

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

Kustannusten erittely

KustannuskomponenttiKaavaLähde
Kutsu (kiinteä)invoke_units = 1 000 CU:ta (946 SIMD-0339:n kanssa)Veloitetaan CPI-sisäänkäynnissä
Instruction datan serialisointiinstruction_data_len / cpi_bytes_per_unitcpi_bytes_per_unit = 250. Veloitetaan translate_instruction -funktiossa.
Tilimetatietojen serialisointi (SIMD-0339)(num_account_metas * 34) / cpi_bytes_per_unitJokainen AccountMeta on 34 tavua (32 pubkey + 1 is_signer + 1 is_writable). Veloitetaan translate_instruction -funktiossa.
Tilitietojen käännös (SIMD-0339)(num_account_infos * 80) / cpi_bytes_per_unitACCOUNT_INFO_BYTE_SIZE = 80 tavua (32 key + 32 owner + 8 lamports + 8 data_len). Veloitetaan translate_account_infos -funktiossa.
Tilikohtainen dataaccount_data_len / cpi_bytes_per_unitVeloitetaan tilikohtaisesti CallerAccount::from_account_info -funktiossa ja suoritettaville tileille.
Kutsuttavan suoritusMitä tahansa CU:ita kutsuttava ohjelma kuluttaaVähennetään jaetusta mittarista kutsuttavan suorituksen aikana.

Esimerkki kustannuslaskelmasta

CPI, jossa on 100 tavua instruction dataa, 5 tilimetatietoa, 5 tilitietoa (jokainen 1 000 tavun datalla), SIMD-0339 aktiivisena:

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

Tilitietojen synkronointi

Tilin tila synkronoidaan kutsijan ja kutsuttavan välillä kahdessa kohdassa CPI:n aikana. Tämä varmistaa, että molemmat osapuolet näkevät yhtenäisen näkymän tilitiedoista.

Synkronointi ennen CPI:tä (kutsujalta kutsuttavalle)

Ennen kuin kutsuttava suoritetaan, update_callee_account kopioi kutsijan käynnissä olevat muutokset kutsuttavan tilinäkymään:

KenttäSuuntaMilloin
LamportitKutsuja -> KutsuttavaJos arvo eroaa kutsuttavan nykyisestä näkymästä
Datan pituusKutsuja -> KutsuttavaJos kutsuja on muuttanut tilin kokoa. Ei saa ylittää original_data_len + MAX_PERMITTED_DATA_INCREASE (10 KiB).
Datan sisältöKutsuja -> KutsuttavaJos tilin data on muokattavissa (can_data_be_changed hyväksyy)
OmistajaKutsuja -> KutsuttavaAsetetaan viimeisenä, jotta data- ja lamport-muutokset ovat sallittuja vanhan omistajan alaisuudessa

Synkronointi CPI:n jälkeen (kutsuttavalta kutsujalle)

Kun kutsuttava palaa, update_caller_account kopioi kutsuttavan muutokset takaisin kutsijan näkymään. Tämä suoritetaan vain tileille, jotka on merkitty kirjoitettaviksi:

KenttäSuuntaMilloin
LamportitKutsuttava -> KutsujaKopioidaan aina takaisin
OmistajaKutsuttava -> KutsujaKopioidaan aina takaisin
Datan pituusKutsuttava -> KutsujaJos muuttunut. VM:n data-osoitin ja sarjallistettu pituuskenttä päivitetään. Jos tiliä kutistettiin, vapautettu muisti nollataan. Jos uusi pituus ylittää original_data_len + MAX_PERMITTED_DATA_INCREASE, palauttaa InvalidRealloc.
Datan sisältöKutsuttava -> KutsujaKopioidaan kutsuttavan datapuskurista kutsijan sarjallistettuun data-alueeseen

Realloc-rajoitukset

Tilin dataa voidaan muuttaa CPI:n aikana enintään MAX_PERMITTED_DATA_INCREASE = 10 240 tavua (10 KiB) tilin datan pituuden yli nykyisen ylätason instruktion alussa. Tämä rajoitus valvotaan sekä update_callee_account (ennen CPI:tä) että update_caller_account (CPI:n jälkeen). Sen ylittäminen palauttaa InvalidRealloc.

PDA-allekirjoitus

Kun invoke_signed kutsutaan, runtime johtaa PDA-osoitteet annetuista seed-arvoista ja kutsijan ohjelman ID:stä. Tämä tapahtuu translate_signers_rust:

  1. Allekirjoittajan seed-taulukko validoidaan: enintään MAX_SIGNERS (16) allekirjoittajan seed-joukkoa.
  2. Jokainen seed-joukko validoidaan: enintään MAX_SEEDS (16) seed-arvoa joukkoa kohden, jokainen seed enintään MAX_SEED_LEN (32) tavua.
  3. Pubkey::create_program_address kutsutaan seed-arvoilla ja kutsijan ohjelman ID:llä (ei kutsuttavan).
  4. Jos seed-arvot eivät tuota kelvollista PDA:ta (eli tuloksena oleva piste on ed25519-käyrällä), CPI epäonnistuu virheellä BadSeeds.
  5. Johdetut PDA-pubkey-arvot kerätään ja välitetään prepare_next_instruction kelvollisina allekirjoittajina. Oikeuksien tarkistuksen aikana, jos kutsuttavan tili on merkitty allekirjoittajaksi ja sen pubkey vastaa yhtä näistä johdetuista PDA:ista, allekirjoitustarkistus läpäisee.

PDA johdetaan kutsijan ohjelman ID:llä, ei kutsuttavan. Tämä tarkoittaa, että vain PDA:n omistava ohjelma (se, jonka ID:tä käytettiin sen johtamiseen) voi allekirjoittaa sen puolesta. Ohjelma ei voi allekirjoittaa muista ohjelmista johdettujen PDA:iden puolesta.

Paluudata

Ohjelmat voivat välittää dataa takaisin kutsujille paluudatamekanismilla. Tämä käyttää kahta syscall-kutsua:

  • sol_set_return_data: Asettaa enintään MAX_RETURN_DATA (1 024) tavua paluudataa nykyiselle instruktiolle. Kustannus on data_len / cpi_bytes_per_unit + syscall_base_cost CU:ta.
  • sol_get_return_data: Lukee viimeksi suoritetun instruktion asettaman paluudatan. Palauttaa datan yhdessä sen asettaneen ohjelman ID:n kanssa. Kustannus on (data_len + 32) / cpi_bytes_per_unit + syscall_base_cost CU:ta (32 tavua ohjelman ID:lle).

Palautusdata tallennetaan transaktiota kohden, ja jokainen sol_set_return_data-komentoa kutsuva ohje ylikirjoittaa sen. Jokaisen ohjelman kutsun alussa ajonaikaympäristö nollaa palautusdatan tyhjäksi. CPI:n palautuksen jälkeen kutsuja voi lukea palautusdatan, jonka kutsuttu ohjelma (tai mikä tahansa sen kutsuma ohjelma) on viimeksi asettanut.

Palautusdata on rajoitettu 1 024 tavuun. Vain viimeinen ohjelma, joka kutsuu sol_set_return_data-komentoa kutsuketjussa, määrittää mitä kutsuja näkee. Jos kutsuttu ohjelma tekee lisää CPI-kutsuja, jotka asettavat palautusdataa, sen oma palautusdata ylikirjoitetaan.

Is this page helpful?

Sisällysluettelo

Muokkaa sivua

Hallinnoi

© 2026 Solana Foundation.
Kaikki oikeudet pidätetään.
Yhdistä