Yhteenveto
Ohjelmat käännetään sBPF:ksi LLVM:n kautta ja suoritetaan eristetyssä VM:ssä, jossa on 1,4M CU:n budjetti per transaktio. Ajoympäristö tallentaa välimuistiin jopa 512 käännettyä ohjelmaa, tarjoaa järjestelmäkutsuja lokitukseen, CPI:hen, kryptografiaan ja muistiin, ja viivästyttää uusia käyttöönottoja 1 slotin verran.
Kääntäminen
Solana käyttää LLVM:ää ohjelmien kääntämiseen ELF-binääreiksi, jotka sisältävät Solana Bytecode Format (sBPF) -muotoista koodia. ELF-binääri tallennetaan ketjuun suoritettavaan tiliin.
sBPF on Solanan mukautettu versio eBPF-tavukoodista, joka on räätälöity Solanan ajoympäristölle. Se ei ole standardia eBPF:ää ja sisältää Solana-spesifisiä muutoksia.
Ohjelmien kirjoittaminen
Solana-ohjelmat kirjoitetaan pääasiassa Rust-kielellä käyttäen yhtä kahdesta lähestymistavasta:
Anchor
Kehys, joka käyttää Rust-makroja vähentääkseen toistuvaa koodia. Suositeltu useimmille kehittäjille.
Natiivi Rust
Suora Rust ilman kehyksiä. Tarjoaa täyden hallinnan, mutta vaatii enemmän manuaalista toteutusta.
Ohjelman suoritusmalli
Kun transaktio käsitellään, ajoympäristö suorittaa jokaisen käskyn peräkkäin
process_message():n
kautta. Jokaiselle käskylle ajoympäristö:
-
Valmistelee käskyn kontekstin. Kutsuu
prepare_next_top_level_instruction():ia kartoittaakseen käskyn tili-indeksit, asettaakseen allekirjoittaja- ja kirjoitusliput sekä konfiguroimaanTransactionContext:n. -
Tarkistaa esikäännetyt ohjelmat. Jos ohjelma on esikäännetty, ajoympäristö kutsuu
process_precompile():ia, joka silti työntää ja poistaa pinokehyksen (käyttäenpush():ia japop():ia), mutta ohittaa sBPF VM:n ja ohjelmavälimuistin haun suorittaen natiivia koodia suoraan. -
Työntää pinokehyksen. (Vaiheet 3-6 tapahtuvat funktioiden
InvokeContext::process_instruction()japrocess_executable_chain()sisällä, jotka kutsutaan funktiostaprocess_message().) Kutsuupush()-funktiotaInvokeContext-oliolla, mikä kasvattaa käskypinon korkeutta ja valvoo uudelleensisääntulosääntöä: ohjelma voi palata itseensä vain, jos välitön kutsuja (ohjelma käskypinon nykyisessä huipussa) on sama ohjelma. Syvä itserekursio (A -> A -> A) on sallittu pinon syvyysrajojen puitteissa. Muut uudelleensisääntulomallit (esim. A kutsuu B:tä, joka kutsuu A:ta) palauttavatInstructionError::ReentrancyNotAllowed-virheen. -
Selvittää ohjelman. Ajoympäristö kutsuu
process_executable_chain()-funktiota, joka määrittää lataajan. Jos ohjelmatilin omistaja on native loader, ohjelma on sisäänrakennettu ja sen tulopiste haetaan suoraanProgramCacheForTxBatch-rakenteesta. Jos omistaja on jokin BPF-lataajista (bpf_loader_deprecated,bpf_loader,bpf_loader_upgradeabletailoader_v4), kutsutaan sen sijaan lataajan omaa sisäänrakennettua tulopistettä. -
Suorittaa BPF-ohjelman. BPF-ohjelmille lataajan tulopiste hakee käännetyn suoritettavan tiedoston ohjelmavälimuistista.
execute()-funktio:- Serialisoi tilitiedot litteäksi parametripuskuriksi
- Luo sBPF VM:n pinolla, keolla ja muistialueilla
- Suorittaa käännetyn koodin kuluttaen laskentayksiköitä suorituksen aikana.
Palauttaa
ComputationalBudgetExceeded-virheen, jos budjetti ylittyy. - Deserialisoi tilitiedot puskurista takaisin tilitilaan
-
Poistaa pinokehyksen. Kutsuu
pop()-funktiota, joka varmistaa, että käsky ei rikkonut ajoympäristön kirjanpitosääntöjä (lamport-saldot ovat tasapainossa, vain luku -tilejä ei muokattu, tilitietojen koot ovat rajojen sisällä). -
Kerää laskentayksiköt. Käskyn kuluttamat laskentayksiköt lisätään transaktion kokonaismäärään
saturating_add-funktion kautta.
Ohjelmavälimuisti
Ajoympäristö ylläpitää globaalia
ProgramCache
joka tallentaa varmennetut ja käännetyt ohjelmat. Se on
haarautumisgraafitietoinen ja käsittelee käyttöönoton näkyvyyssääntöjä, häätöä
ja epoch-rajojen uudelleenkääntämistä.
Välimuistimerkintätyypit
Jokaisella välimuistissa olevalla ohjelmalla on
ProgramCacheEntryType
joka määrittää sen ajoaikaisen käyttäytymisen:
| Tyyppi | Kuvaus |
|---|---|
Loaded | Varmennettu ja käännetty ohjelma, valmis suoritettavaksi. |
Builtin | Natiivi ohjelma, joka on käännetty validator-binääriin (System, Stake, Vote jne.). Ei tallenneta lohkoketjuun. |
Unloaded | Aiemmin varmennettu ohjelma, jonka käännetty suoritettava tiedosto on häädetty muistista tilan vapauttamiseksi. Seuraa edelleen käyttötilastoja. Voidaan ladata uudelleen ilman uudelleenvarmennusta. |
FailedVerification | Hautakivi ohjelmille, jotka eivät läpäisseet sBPF-varmenninta nykyisellä ominaisuusjoukolla. Voi muuttua Loaded-tyypiksi, jos ominaisuuksien aktivoinnit muuttavat varmennussääntöjä. |
Closed | Hautakivi ohjelmille, jotka on suljettu eksplisiittisesti tai joita ei ole koskaan otettu käyttöön. Käytetään myös tileille (kuten puskuritileille), jotka kuuluvat lataajalle mutta eivät sisällä suoritettavaa koodia. |
DelayVisibility | Synteettinen hautakivi, jonka ProgramCacheForTxBatch::find() palauttaa, kun Loaded-merkintä on olemassa mutta ei ole vielä voimassa (sen effective_slot on tulevaisuudessa). Ei koskaan tallenneta suoraan välimuistiin. |
Näkyvyysviive
Äskettäin käyttöönotetut tai päivitetyt ohjelmat eivät ole voimassa
välittömästi.
DELAY_VISIBILITY_SLOT_OFFSET
-vakio on 1, mikä tarkoittaa, että slotissa N käyttöönotettu ohjelma tulee
voimaan slotissa N+1. Käyttöönoton aikana mikä tahansa yritys kutsua uutta
versiota palauttaa DelayVisibility-arvon, jolloin ajoympäristö ilmoittaa
"Program is not deployed."
Häätökäytäntö
Välimuisti sisältää enintään
MAX_LOADED_ENTRY_COUNT
(512) käännettyä ohjelmamerkintää. Kun raja saavutetaan, vähiten käytetyt
ohjelmat häädetään Unloaded -tilaan. Käyttöä seurataan
tx_usage_counter
-arvolla (kasvaa joka kerta kun transaktio viittaa ohjelmaan) ja
latest_access_slot-arvolla.
Epoch-rajan uudelleenkääntäminen
Jos ominaisuuden aktivointi muuttaa
ProgramRuntimeEnvironments
-arvoa epoch-rajalla, kaikki välimuistissa olevat ohjelmat
käännetään uudelleen
uutta ympäristöä vasten.
Paluudata
Ohjelmat voivat asettaa paluudatan sol_set_return_data-syskutsun kautta. Data
tallennetaan transaktiotason
TransactionReturnData
-rakenteeseen, joka sisältää datatavut ja sen ohjelman program_id-arvon, jonka
instruktio kutsui syskutsua. Maksimikoko on 1 024 tavua (MAX_RETURN_DATA).
Is this page helpful?