CPI:n suoritus ja oikeudet

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:

SkenaarioSallittu?ValvontapisteVirhe
Kutsuja välittää tilin kirjoitettavana, kutsuttava merkitsee kirjoitettavaksiKyllä----
Kutsuja välittää tilin vain luku -tilassa, kutsuttava merkitsee kirjoitettavaksiEiprepare_next_instructionPrivilegeEscalation
Kutsuja välittää tilin kirjoitettavana, kutsuttava merkitsee vain luku -tilaanKyllä----
Kutsuja välittää tilin allekirjoittajana, kutsuttava merkitsee allekirjoittajaksiKyllä----
Kutsuja välittää tilin ei-allekirjoittajana, kutsuttava merkitsee allekirjoittajaksi, tili on kutsujan siemenistä johdettu PDAKylläprepare_next_instruction--
Kutsuja välittää tilin ei-allekirjoittajana, kutsuttava merkitsee allekirjoittajaksi, tili EI ole kutsujan PDAEiprepare_next_instructionPrivilegeEscalation
Kutsuja välittää tilin allekirjoittajana, kutsuttava merkitsee ei-allekirjoittajaksiKyllä----
Ohjelma A kutsuu itseään suoraan (A -> A)Kylläpush()--
Ohjelma A kutsuu B:tä, joka kutsuu A:ta (epäsuora uudelleenkutsu)Eipush()ReentrancyNotAllowed
CPI native loaderiin, bpf_loaderiin, bpf_loader_deprecatediin tai precompileihinEicheck_authorized_programProgramNotSupported
Tiliä ei löydy transaktiostaEiprepare_next_instructionMissingAccount

Oikeussäännöt voidaan tiivistää seuraavasti:

  1. Kirjoitusoikeus ei voi laajentua. Jos kutsuja merkitsee tilin vain luku -tilaan, kutsuttava ei voi merkitä sitä kirjoitettavaksi.
  2. 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.
  3. 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:

  1. Tarkistaa allekirjoittaja-seed-joukkojen määrän MAX_SIGNERS-arvoa vasten (16).
  2. Tarkistaa kunkin seed-joukon pituuden MAX_SEEDS-arvoa vasten (16 seedia per joukko).
  3. Kutsuu Pubkey::create_program_address-funktiota sedeillä ja kutsujan ohjelma-ID:llä. Jos seedit eivät tuota kelvollista PDA:ta, CPI epäonnistuu BadSeeds-virheellä.
  4. 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_loader ja bpf_loader_deprecated
  • bpf_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:

  1. Validoi tilitietojen määrän verrattuna MAX_CPI_ACCOUNT_INFOS-arvoon (128 tai 255 SIMD-0339:n kanssa).
  2. Veloittaa tilitietojen käännöskustannuksen (vain SIMD-0339): (num_account_infos * 80) / 250 CU:ta.
  3. 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_unit CU: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:

  1. 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 palauttaa ReentrancyNotAllowed-virheen.
  2. 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.
  3. 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?

Hallinnoi

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