UKK
Lähetä kysymyksesi StackExchange-palveluun.
Berkeley Packet Filter (BPF)
Solanan lohkoketjuohjelmat käännetään LLVM-kääntäjäinfrastruktuurin avulla Executable and Linkable Format (ELF) -muotoon, joka sisältää muunnelman Berkeley Packet Filter (BPF) -tavukoodista.
Koska Solana käyttää LLVM-kääntäjäinfrastruktuuria, ohjelma voidaan kirjoittaa millä tahansa ohjelmointikielellä, joka voi kohdistua LLVM:n BPF-taustajärjestelmään.
BPF tarjoaa tehokkaan käskyjoukon, jota voidaan suorittaa tulkatussa virtuaalikoneessa tai tehokkaina just-in-time käännettyinä natiivikäskyinä.
Muistikartta
Solana SBF -ohjelmien käyttämä virtuaalinen osoitemuistikartta on kiinteä ja järjestetty seuraavasti
- Ohjelmakoodi alkaa osoitteesta 0x100000000
- Pinodata alkaa osoitteesta 0x200000000
- Kekodata alkaa osoitteesta 0x300000000
- Ohjelman syöteparametrit alkavat osoitteesta 0x400000000
Yllä olevat virtuaaliosoitteet ovat aloitusosoitteita, mutta ohjelmille annetaan
pääsy vain osaan muistikartasta. Ohjelma kaatuu, jos se yrittää lukea tai
kirjoittaa virtuaaliosoitteeseen, johon sille ei ole myönnetty pääsyä, ja
AccessViolation
-virhe palautetaan, joka sisältää osoitteen ja koon yritetystä
rikkomuksesta.
InvalidAccountData
Tämä ohjelmavirhe voi tapahtua monista syistä. Yleensä se johtuu siitä, että ohjelmalle välitetään tili, jota ohjelma ei odota, joko väärässä paikassa ohjeessa tai tili, joka ei ole yhteensopiva suoritettavan ohjeen kanssa.
Ohjelman toteutus voi myös aiheuttaa tämän virheen suorittaessaan ohjelmarajat ylittävän ohjeen ja unohtaessaan antaa tilin ohjelmalle, jota kutsutaan.
InvalidInstructionData
Tämä ohjelmavirhe voi tapahtua yrittäessä purkaa ohjetta, tarkista että
välitetty rakenne vastaa täsmälleen ohjetta. Kenttien välillä saattaa olla
täytettä. Jos ohjelma toteuttaa Rust-kielen Pack
-rajapinnan, kokeile pakata
ja purkaa ohjetyyppi T
määrittääksesi tarkan koodauksen, jota ohjelma odottaa.
MissingRequiredSignature
Jotkin ohjeet vaativat, että tili on allekirjoittaja; tämä virhe palautetaan, jos tilin odotetaan olevan allekirjoitettu, mutta se ei ole.
Ohjelman toteutus voi myös aiheuttaa tämän virheen suorittaessaan
ohjelmien välistä kutsua, joka vaatii allekirjoitetun ohjelma-
osoitteen, mutta invoke_signed
-funktiolle välitetyt allekirjoittajan siemenet
eivät vastaa ohjelma-osoitteen luomiseen käytettyjä allekirjoittajan siemeniä
create_program_address
.
Stack
SBF käyttää pinakehyksiä muuttuvan pinakohdistimen sijaan. Jokaisen pinakehyksen koko on 4 kt.
Jos ohjelma rikkoo pinakehyksen kokoa, kääntäjä ilmoittaa ylityksestä varoituksena.
Esimerkiksi:
Error: Function _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082E Stack offset of -30728 exceeded max offset of -4096 by 26632 bytes, please minimize large stack variables
Viesti kertoo, mikä symboli ylittää pinakehyksensä, mutta nimi saattaa olla vääristynyt.
Rust-symbolin selventämiseen käytä rustfilt-työkalua.
Yllä oleva varoitus tuli Rust-ohjelmasta, joten selvennetty symbolin nimi on:
rustfilt _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082Ecurve25519_dalek::edwards::EdwardsBasepointTable::create
Syy siihen, että ilmoitetaan varoitus eikä virhettä, on se, että jotkin
riippuvuudet saattavat sisältää toiminnallisuutta, joka rikkoo pinakehyksen
rajoituksia, vaikka ohjelma ei käyttäisi kyseistä toiminnallisuutta. Jos ohjelma
rikkoo pina- kokoa ajonaikaisesti, raportoidaan AccessViolation
-virhe.
SBF-pinakehykset käyttävät virtuaalista osoitealuetta alkaen osoitteesta
0x200000000
.
Heap-koko
Ohjelmilla on pääsy ajonaikaiseen heap-muistiin Rust alloc
API:en kautta.
Nopeiden allokointien mahdollistamiseksi käytetään yksinkertaista 32 kilotavun
bump heap -muistia. Heap ei tue free
tai realloc
toimintoja.
Sisäisesti ohjelmilla on pääsy 32 kilotavun muistialueeseen, joka alkaa virtuaaliosoitteesta 0x300000000, ja ne voivat toteuttaa mukautetun heap-muistin ohjelman erityistarpeiden mukaan.
Rust-ohjelmat toteuttavat heap-muistin suoraan määrittelemällä mukautetun
global_allocator
Lataajat
Ohjelmat otetaan käyttöön ja suoritetaan ajonaikaisten lataajien avulla. Tällä hetkellä tuettuja lataajia on kaksi: BPF Loader ja BPF loader deprecated
Lataajat voivat tukea erilaisia sovellusten binäärirajapintoja, joten
kehittäjien on kirjoitettava ohjelmansa tietylle lataajalle ja otettava ne
käyttöön samalla lataajalla. Jos yhdelle lataajalle kirjoitettu ohjelma otetaan
käyttöön toisella lataajalla, tuloksena on yleensä AccessViolation
virhe, joka
johtuu ohjelman syöteparametrien virheellisestä deserialisoinnista.
Käytännössä ohjelmat tulisi aina kirjoittaa kohdistumaan uusimpaan BPF-lataajaan, ja uusin lataaja on oletusarvoisesti käytössä komentorivikäyttöliittymässä ja JavaScript-API:ssa.
Käyttöönotto
SBF-ohjelman käyttöönotto on prosessi, jossa BPF-jaettu objekti ladataan
ohjelmatiliin ja tili merkitään suoritettavaksi. Asiakas pilkkoo SBF-jaetun
objektin pienempiin osiin ja lähettää ne lataajalle
Write
-ohjeiden datana, jolloin lataaja kirjoittaa tiedot ohjelmatilin dataan. Kun
kaikki osat on vastaanotettu, asiakas lähettää
Finalize
-ohjeen lataajalle, joka tarkistaa, että SBF-data on kelvollista ja merkitsee
ohjelmatilin suoritettavaksi. Kun ohjelmatili on merkitty suoritettavaksi,
myöhemmät transaktiot voivat antaa ohjeita kyseisen ohjelman käsiteltäväksi.
Kun ohje ohjataan suoritettavaan SBF-ohjelmaan, lataaja määrittää ohjelman suoritusympäristön, sarjallistaa ohjelman syöttöparametrit, kutsuu ohjelman sisääntulopistettä ja raportoi mahdolliset kohdatut virheet.
Lisätietoja löydät kohdasta ohjelmien käyttöönotto.
Syöttöparametrien sarjallistaminen
SBF-lataajat sarjallistavat ohjelman syöttöparametrit tavutaulukoksi, joka sitten välitetään ohjelman sisääntulokohtaan, jossa ohjelma on vastuussa sen deserialisoinnista lohkoketjussa. Yksi muutoksista vanhentuneen lataajan ja nykyisen lataajan välillä on, että syöttöparametrit sarjallistetaan tavalla, joka johtaa eri parametrien sijoittumiseen kohdistettuihin siirtymiin kohdistetun tavutaulukon sisällä. Tämä mahdollistaa deserialisointitoteutusten viitata suoraan tavutaulukkoon ja tarjota kohdistettuja osoittimia ohjelmalle.
Uusin lataaja sarjallistaa ohjelman syöttöparametrit seuraavasti (kaikki koodaus on little endian):
- 8 tavua etumerkitön tilien lukumäärä
- Jokaiselle tilille
- 1 tavu, joka ilmaisee, onko tämä duplikaattitili, jos ei ole duplikaatti, arvo on 0xff, muuten arvo on sen tilin indeksi, jonka duplikaatti se on.
- Jos duplikaatti: 7 tavua täytettä
- Jos ei duplikaatti:
- 1 tavu boolean, tosi jos tili on allekirjoittaja
- 1 tavu boolean, tosi jos tili on kirjoitettavissa
- 1 tavu boolean, tosi jos tili on suoritettavissa
- 4 tavua täytettä
- 32 tavua tilin julkista avainta
- 32 tavua tilin omistajan julkista avainta
- 8 tavua etumerkitön lamport-määrä, jonka tili omistaa
- 8 tavua etumerkitön tilin data-tavujen määrä
- x tavua tilin dataa
- 10k tavua täytettä, käytetään uudelleenallokointiin
- riittävästi täytettä siirtymän kohdistamiseksi 8 tavuun.
- 8 tavua rent epoch
- 8 tavua etumerkitön instruction data -määrä
- x tavua instruction data
- 32 tavua ohjelmatunnusta
Is this page helpful?