Yhteenveto
CPI:t kulkevat 11 ajonaikaisen vaiheen läpi, mukaan lukien oikeuksien tarkistus, tilin käännös ja datan synkronointi. Maksimi kutsusyvyys: 5 (9 SIMD-0268:n kanssa). Oikeussäännöt estävät kutsuttavaa laajentamasta oikeuksia yli sen, mitä kutsuja myönsi.
Oikeussäännöt
CPI:t laajentavat kutsujan tilioikeudet kutsuttavalle tiukalla valvonnalla.
Ajonaikaympäristö tarkistaa nämä säännöt funktiossa
prepare_next_instruction:
| Skenaario | Sallittu? | Valvontapiste | Virhe |
|---|---|---|---|
| Kutsuja välittää tilin kirjoitettavana, kutsuttava merkitsee kirjoitettavaksi | Kyllä | -- | -- |
| Kutsuja välittää tilin vain luku -tilassa, kutsuttava merkitsee kirjoitettavaksi | Ei | prepare_next_instruction | PrivilegeEscalation |
| Kutsuja välittää tilin kirjoitettavana, kutsuttava merkitsee vain luku -tilaan | Kyllä | -- | -- |
| Kutsuja välittää tilin allekirjoittajana, kutsuttava merkitsee allekirjoittajaksi | Kyllä | -- | -- |
| Kutsuja välittää tilin ei-allekirjoittajana, kutsuttava merkitsee allekirjoittajaksi, tili on kutsujan siemenistä johdettu PDA | Kyllä | prepare_next_instruction | -- |
| Kutsuja välittää tilin ei-allekirjoittajana, kutsuttava merkitsee allekirjoittajaksi, tili EI ole kutsujan PDA | Ei | prepare_next_instruction | PrivilegeEscalation |
| Kutsuja välittää tilin allekirjoittajana, kutsuttava merkitsee ei-allekirjoittajaksi | Kyllä | -- | -- |
| Ohjelma A kutsuu itseään suoraan (A -> A) | Kyllä | push() | -- |
| Ohjelma A kutsuu B:tä, joka kutsuu A:ta (epäsuora uudelleenkutsu) | Ei | push() | ReentrancyNotAllowed |
| CPI native loaderiin, bpf_loaderiin, bpf_loader_deprecatediin tai precompileihin | Ei | check_authorized_program | ProgramNotSupported |
| Tiliä ei löydy transaktiosta | Ei | prepare_next_instruction | MissingAccount |
Oikeussäännöt voidaan tiivistää seuraavasti:
- Kirjoitusoikeus ei voi laajentua. Jos kutsuja merkitsee tilin vain luku -tilaan, kutsuttava ei voi merkitä sitä kirjoitettavaksi.
- Allekirjoittajaoikeus vaatii valtuutuksen. Tili voi olla allekirjoittaja
kutsutussa vain, jos (a) se oli jo allekirjoittaja kutsujassa TAI (b) se on
PDA, joka on johdettu kutsuvan ohjelman siemenistä
invoke_signed-funktion kautta. - Oikeuksien vähentäminen on aina sallittua. Kutsuttu voi käyttää vähemmän oikeuksia kuin kutsuja myönsi.
CPI-suorituskulku
CPI kulkee useiden runtime-kerrosten läpi. Tämä osio dokumentoi koko putkilinjan ohjelman SDK-kutsusta syscall-rajan yli runtimeen ja takaisin. Jokainen vaihe viittaa sen toteuttavaan lähdetiedostoon.
Ohjelman käskyn kutsun maksimikorkeus on nimeltään
max_instruction_stack_depth
ja se on asetettu
MAX_INSTRUCTION_STACK_DEPTH
-vakioon arvoon 5. Kun MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268 on aktiivinen, tämä kasvaa arvoon 9.
Pinosyvyys 1 on alkuperäinen transaktio-ohje. Jokainen CPI kasvattaa syvyyttä yhdellä. Maksimi 5 tarkoittaa, että ohjelma voi tehdä CPI-kutsuja jopa 4 tasoa syvälle (8 tasoa syvälle SIMD-0268:n kanssa).
Vaihe 1: Ohjelma kutsuu invoke- tai invoke_signed-funktiota
Ohjelma kutsuu
invoke
-funktiota tai
invoke_signed
-funktiota. invoke on ohut wrapper, joka kutsuu
invoke_signed-funktiota tyhjällä allekirjoittajan siemen-taulukolla.
SDK-funktio serialisoi Instruction-rakenteen, AccountInfo-taulukon
ja allekirjoittajan siemenet VM-muistiin ja laukaisee sitten syscall-kutsun.
Vaihe 2: Syscall-sisääntulo
SBF VM ohjaa
sol_invoke_signed_rust
-syscall-käsittelijälle, joka kutsuu jaettua sisääntulopistettä:
cpi_common.
Vaihe 3: Kutsukustannuksen kuluttaminen
Ensimmäinen toiminto cpi_common-funktion sisällä on
kiinteän kutsukustannuksen veloittaminen
jaetusta laskentamittarista:
invoke_units
= 1 000 CU:ta (tai 946 CU:ta SIMD-0339:n kanssa).
Vaihe 4: Käskyn kääntäminen VM-muistista
Syscall-käsittelijä kääntää käskyn ohjelman VM-osoiteavaruudesta isäntäpuolen
Rust-tyyppeihin
translate_instruction_rust-funktion
kautta, joka lukee StableInstruction-rakenteen, validoi datan pituuden
MAX_INSTRUCTION_DATA_LEN-arvoa
vasten (10 240 tavua) ja veloittaa sitten
datan serialisointikustannuksen.
Vaihe 5: Allekirjoittaja-seedien kääntäminen ja PDA:iden johdattaminen
Käsittelijä kutsuu
translate_signers_rust-funktiota.
Jokaiselle allekirjoittaja-seedien joukolle runtime:
- Tarkistaa allekirjoittaja-seed-joukkojen määrän
MAX_SIGNERS-arvoa vasten (16). - Tarkistaa kunkin seed-joukon pituuden
MAX_SEEDS-arvoa vasten (16 seedia per joukko). - Kutsuu
Pubkey::create_program_address-funktiota sedeillä ja kutsujan ohjelma-ID:llä. Jos seedit eivät tuota kelvollista PDA:ta, CPI epäonnistuuBadSeeds-virheellä. - Kerää tuloksena saadut PDA-pubkeyit
signers-vektoriin.
Näitä johdettuja PDA:ita käsitellään kelvollisin allekirjoittajina kutsuttavalle käskylle.
Vaihe 6: Valtuutetun ohjelman tarkistus
Ennen jatkamista runtime kutsuu
check_authorized_program-funktiota
varmistaakseen, että kohdeohjelma on sallittu CPI:lle. Seuraavat ohjelmat on
estetty:
- Native loader
bpf_loaderjabpf_loader_deprecatedbpf_loader_upgradeable(paitsi tietyt hallintakäskyt:upgrade,set_authority,set_authority_checked(feature-gated),extend_program_checked(feature-gated),close)- Precompile-ohjelmat (ed25519, secp256k1 jne.)
Rikkomus palauttaa
ProgramNotSupported-virheen.
Vaihe 7: Oikeuksien varmennus (prepare_next_instruction)
Runtime kutsuu
prepare_next_instruction-funktiota,
joka rakentaa kutsuttavan InstructionAccount-listan ja valvoo
oikeussääntöjä. Katso täydellinen päätöstaulukko kohdasta
Oikeussäännöt.
Vaihe 8: Tilitietojen kääntäminen
Käsittelijä kutsuu translate_accounts-funktiota, joka:
- Validoi tilitietojen määrän
verrattuna
MAX_CPI_ACCOUNT_INFOS-arvoon (128 tai 255 SIMD-0339:n kanssa). - Veloittaa tilitietojen käännöskustannuksen
(vain SIMD-0339):
(num_account_infos * 80) / 250CU:ta. - Rakentaa jokaiselle ei-suoritettavalle, ei-duplikaattitilille
CallerAccount-rakenteen kääntämällä osoittimet VM-muistista isäntämuistiin. Tämä sisältää tilikohtaisen datan serialisointikustannuksen veloituksen:account_data_len / cpi_bytes_per_unitCU:ta.
Vaihe 9: CPI:tä edeltävä tilisynkronointi (kutsujalta kutsuttavalle)
Ennen kutsuttavan suorittamista ajonaikaympäristö synkronoi kutsujan
tilimuutokset, jotta kutsuttava voi nähdä ne. Funktio
update_callee_account
kutsutaan jokaiselle käännetylle tilille, kopioimalla lamportit, datan ja
omistajan. Katso
tilidata-synkronointi
yksityiskohtaista kenttien kartoitusta varten.
Vaihe 10: Käskykontekstin lisääminen, kutsuttavan suoritus ja poisto
Ajonaikaympäristö kutsuu
process_instruction-funktiota,
joka:
- Kutsuu
push()-funktiota lisätäkseen uuden kehyksen käskypinoon.push()valvoo uudelleensisääntulosääntöä: ohjelma voi kutsua itseään vain, jos se on suora kutsuja (eli ohjelma A voi kutsua A:ta, mutta A ei voi kutsua B:tä, joka kutsuu A:ta). Rikkomus palauttaaReentrancyNotAllowed-virheen. - Kutsuu
process_executable_chain-funktiota, joka selvittää kutsuttavan ohjelman tulokohtaan ja kutsuu sitä. Kutsuttava suoritetaan samalla jaetulla laskentamittarilla. Kaikki kutsuttavan CU-kulutus vähentää kutsujan jäljellä olevaa budjettia. - Kutsuu
pop()-funktiota poistaakseen kutsuttavan kehyksen ja varmistaakseen, että lamport-saldot ovat muuttumattomat (UnbalancedInstruction, jos eivät ole).
Vaihe 11: CPI:n jälkeinen tilisynkronointi (kutsuttavalta kutsujalle)
Kun process_instruction palaa (mikä sisältää poiston), ajonaikaympäristö
synkronoi muutokset takaisin kutsujalle
update_caller_account-funktion
kautta jokaiselle kirjoitettavalle tilille. Lisäksi
update_caller_account_region
päivittää VM-muistialueiden kartoitukset tileille, joiden data-alueet
muuttuivat. Katso
tilidata-synkronointi
yksityiskohtaista kenttien kartoitusta varten.
CPI-systeemikutsu palauttaa 0 (onnistuminen) kutsuvalle ohjelmalle.
Is this page helpful?