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
| Kustannuskomponentti | Kaava | Lähde |
|---|---|---|
| Kutsu (kiinteä) | invoke_units = 1 000 CU:ta (946 SIMD-0339:n kanssa) | Veloitetaan CPI-sisäänkäynnissä |
| Instruction datan serialisointi | instruction_data_len / cpi_bytes_per_unit | cpi_bytes_per_unit = 250. Veloitetaan translate_instruction -funktiossa. |
| Tilimetatietojen serialisointi (SIMD-0339) | (num_account_metas * 34) / cpi_bytes_per_unit | Jokainen 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_unit | ACCOUNT_INFO_BYTE_SIZE = 80 tavua (32 key + 32 owner + 8 lamports + 8 data_len). Veloitetaan translate_account_infos -funktiossa. |
| Tilikohtainen data | account_data_len / cpi_bytes_per_unit | Veloitetaan tilikohtaisesti CallerAccount::from_account_info -funktiossa ja suoritettaville tileille. |
| Kutsuttavan suoritus | Mitä tahansa CU:ita kutsuttava ohjelma kuluttaa | Vä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 = 946instruction_data_cost = 100 / 250 = 0 (integer division)account_meta_cost = (5 * 34) / 250 = 0account_info_cost = (5 * 80) / 250 = 1per_account_data_cost = 5 * (1000 / 250) = 20total (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ä | Suunta | Milloin |
|---|---|---|
| Lamportit | Kutsuja -> Kutsuttava | Jos arvo eroaa kutsuttavan nykyisestä näkymästä |
| Datan pituus | Kutsuja -> Kutsuttava | Jos kutsuja on muuttanut tilin kokoa. Ei saa ylittää original_data_len + MAX_PERMITTED_DATA_INCREASE (10 KiB). |
| Datan sisältö | Kutsuja -> Kutsuttava | Jos tilin data on muokattavissa (can_data_be_changed hyväksyy) |
| Omistaja | Kutsuja -> Kutsuttava | Asetetaan 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ä | Suunta | Milloin |
|---|---|---|
| Lamportit | Kutsuttava -> Kutsuja | Kopioidaan aina takaisin |
| Omistaja | Kutsuttava -> Kutsuja | Kopioidaan aina takaisin |
| Datan pituus | Kutsuttava -> Kutsuja | Jos 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 -> Kutsuja | Kopioidaan 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:
- Allekirjoittajan seed-taulukko validoidaan: enintään
MAX_SIGNERS(16) allekirjoittajan seed-joukkoa. - Jokainen seed-joukko validoidaan: enintään
MAX_SEEDS(16) seed-arvoa joukkoa kohden, jokainen seed enintäänMAX_SEED_LEN(32) tavua. Pubkey::create_program_addresskutsutaan seed-arvoilla ja kutsijan ohjelman ID:llä (ei kutsuttavan).- Jos seed-arvot eivät tuota kelvollista PDA:ta (eli tuloksena oleva piste on
ed25519-käyrällä), CPI epäonnistuu virheellä
BadSeeds. - Johdetut PDA-pubkey-arvot kerätään ja välitetään
prepare_next_instructionkelvollisina 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äänMAX_RETURN_DATA(1 024) tavua paluudataa nykyiselle instruktiolle. Kustannus ondata_len / cpi_bytes_per_unit + syscall_base_costCU: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_costCU: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?