Yhteenveto
Ohjelmat käännetään sBPF-muotoon LLVM:n avulla ja suoritetaan hiekkalaatikoidussa virtuaalikoneessa, jossa on 1,4 miljoonan laskentayksikön budjetti per transaktio. Ajoympäristö tallentaa välimuistiin enintään 512 käännettyä ohjelmaa, tarjoaa syscall-kutsut lokitusta, CPI:tä, kryptografiaa ja muistia varten, ja viivästyttää uusia käyttöönotoja 1 slot.
Kääntäminen
Solana käyttää LLVM:ää kääntääkseen ohjelmat ELF-binääreiksi, jotka sisältävät Solana Bytecode Format (sBPF) -muodon. ELF-binääri tallennetaan ketjussa suoritettavaan tiliin.
sBPF on Solanan mukautettu versio eBPF-tavukoodista, räätälöity Solana-ajoympäristöä varten. Se ei ole standardi eBPF ja sisältää Solana-kohtaisia muutoksia.
Kirjoita ohjelmia
Solana-ohjelmat kirjoitetaan pääasiassa Rust-kielellä käyttäen yhtä kolmesta lähestymistavasta:
Anchor
Viitekehys, joka käyttää Rust-makroja vähentämään toistuvaa koodia. Suositellaan useimmille kehittäjille.
Pinocchio
Kevyt, zero-copy Rust-kirjasto, joka on optimoitu laskentakulutuksen ja binäärikoon suhteen. Sisältää ohjelmakohtaiset kirjastot yleisiä CPI-kutsuja varten.
Native Rust
Suora Rust ilman viitekehyksiä. Tarjoaa täyden hallinnan, mutta vaatii enemmän manuaalista toteutusta.
Katso Cross-Program Invocations CPI-konsepteista ja esimerkeistä, jotka pätevät näissä kaikissa lähestymistavoissa.
Ohjelman suoritusmalli
Kun transaktiota käsitellään, ajoympäristö suorittaa jokaisen käskyn
peräkkäin
process_message()-funktion kautta.
Jokaisen käskyn kohdalla ajoympäristö:
-
Valmistelee käskykontekstin. Kutsuu
prepare_next_top_level_instruction()-funktiota kartoittaakseen käskyn tili-indeksit, asettaakseen allekirjoittajan ja kirjoitettavat liput sekä konfiguroidakseenTransactionContext-objektin. -
Tarkistaa esikääntäjät. Jos ohjelma on esikääntäjä, ajoympäristö kutsuu
process_precompile()-funktiota, joka silti työntää ja noutaa pinokehyksen (push()- japop()-kutsujen kautta), mutta ohittaa sBPF-virtuaalikoneen ja ohjelmavälimuistihaun ja suorittaa natiivikoodin suoraan. -
Työntää pinokehyksen. (Vaiheet 3–6 tapahtuvat
InvokeContext::process_instruction()- japrocess_executable_chain()-funktioiden sisällä, joita kutsutaanprocess_message():stä.) Kutsuupush()-funktiotaInvokeContext-objektille, joka kasvattaa käskypinon korkeutta ja valvoo uudelleensyöttösääntöä: ohjelma voi syöttää itsensä uudelleen 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 uudelleensyöttömallit (esim. A kutsuu B:tä, joka kutsuu A:ta) palauttavatInstructionError::ReentrancyNotAllowed. -
Ratkaisee ohjelman. Ajoympäristö kutsuu
process_executable_chain()-funktiota, joka määrittää lataajan. Jos program account -tilin omistaja on native loader, ohjelma on sisäänrakennettu ja sen aloituspisteFunktio haetaan suoraanProgramCacheForTxBatch-objektista. Jos omistaja on jokin BPF-lataajista (bpf_loader_deprecated,bpf_loader,bpf_loader_upgradeabletailoader_v4), lataajan oma sisäänrakennettu aloituspiste käynnistetään sen sijaan. -
Suorittaa BPF-ohjelman. BPF-ohjelmien kohdalla lataajan aloituspiste hakee käännetyn suoritettavan tiedoston ohjelmavälimuistista.
execute()-funktio sen jälkeen:- Sarjallistaa tilitiedot litteään parametripuskuriin
- Luo sBPF-virtuaalikoneen pino-, keko- ja muistialueilla
- Ajaa käännetyn koodin kuluttaen laskentayksiköitä suorituksen aikana. Palauttaa
ComputationalBudgetExceeded, jos budjetti ylittyy. - Sarjanpurkaa tilitiedot puskurista takaisin tilitilaan
-
Noutaa pinokehyksen. Kutsuu
pop()-funktiota, joka tarkistaa, ettei käsky rikkonut ajoympäristön kirjanpitosääntöjä (lamport-saldot ovat tasapainossa, vain luku -tilejä ei muutettu, tilitietojen koot ovat rajojen sisällä). -
Kertää 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-välimuistia,
joka tallentaa varmennetut ja käännetyt ohjelmat. Se on haarautumisgraafitietoinen ja käsittelee
käyttöönoton näkyvyyssäännöt, häätämisen ja epoch-rajalla tapahtuvan uudelleenkääntämisen.
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 suoritukseen. |
Builtin | Natiivi ohjelma, joka on käännetty validator-binääriin (System, Stake, Vote jne.). Ei tallennettu ketjuun. |
Unloaded | Aiemmin varmennettu ohjelma, jonka käännetty suoritettava tiedosto on häätty muistista tilan vapauttamiseksi. Seuraa edelleen käyttötilastoja. Voidaan ladata uudelleen ilman uudelleenvarmennusta. |
FailedVerification | Hautakivi ohjelmille, jotka eivät läpäisseet sBPF-varmistajaa nykyisellä ominaisuusjoukolla. Saattaa muuttua Loaded-tilaan, jos ominaisuuden aktivoinnit muuttavat varmistussääntöjä. |
Closed | Hautakivi ohjelmille, jotka on nimenomaisesti suljettu 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 vielä voimassa (sen effective_slot on tulevaisuudessa). Ei koskaan tallennettu suoraan välimuistiin. |
Näkyvyysviive
Äskettäin käyttöönotetut tai päivitetyt ohjelmat eivät ole heti voimassa.
DELAY_VISIBILITY_SLOT_OFFSET-vakion
arvo on 1, mikä tarkoittaa, että slot N:ssä käyttöönotettu ohjelma tulee voimaan slot
N+1:ssä. Käyttöönottohetkellä mikä tahansa yritys käynnistää uusi versio palauttaa
DelayVisibility-virheen, jolloin ajoympäristö ilmoittaa "Program is not deployed."
Häätöpolitiikka
Välimuisti sisältää enintään
MAX_LOADED_ENTRY_COUNT
(512) käännettyä ohjelmamerkintää. Kun raja saavutetaan, vähiten käytetyt
ohjelmat häätään Unloaded-tilaan. Käyttöä seurataan
tx_usage_counter-laskurilla
(kasvatetaan joka kerta, kun transaktio viittaa ohjelmaan) sekä
latest_access_slot-arvolla.
Epoch-rajalla tapahtuva uudelleenkääntäminen
Jos ominaisuuden aktivointi muuttaa
ProgramRuntimeEnvironments-ympäristöä
epoch-rajalla, kaikki välimuistissa olevat ohjelmat
käännetään uudelleen
uutta ympäristöä vasten.
Palautusdata
Ohjelmat voivat asettaa palautusdatan sol_set_return_data-syscall-kutsun kautta. Data tallennetaan
transaktiotason
TransactionReturnData-rakenteeseen,
joka sisältää datatavut sekä sen ohjelman program_id:n, jonka käsky kutsui syscallia. Enimmäiskoko on 1 024 tavua
(MAX_RETURN_DATA).
Is this page helpful?