Yhteenveto
Ennen suoritusta suoritusympäristö lataa tilit, validoi maksajan, tarkistaa vuokravapautuksen ja sarjallistaa tilin datan muistiasetteluun, johon ohjelmat voivat päästä käsiksi.
Tämä sivu käsittelee suoritusympäristön sisäisiä toimintoja. Useimmat kehittäjät eivät tarvitse näitä tietoja ohjelmien rakentamiseen. Katso tilin rakenne kehittäjille suunnatusta näkökulmasta.
Tilin lataaminen
Ennen kuin transaktio suoritetaan, suoritusympäristö lataa kaikki viitatut tilit
load_transaction_accounts()-funktion
kautta. Tämä prosessi suorittaa useita validointeja:
-
Maksajan validointi: Maksajan (ensimmäinen tili) on oltava olemassa, sen on oltava järjestelmätili tai nonce-tili, ja sillä on oltava tarpeeksi lamportteja maksujen kattamiseen (
validate_fee_payer()). Maksujen maksamisen jälkeen tilin on joko pysyttävä vuokravapautettuna tai sen on mentävä täsmälleen 0 lamporttiin. Se ei voi päätyä 0:n ja vuokravapautusminimin väliin. Nonce-tilien on aina säilytettävä tarpeeksi lamportteja pysyäkseen vuokravapautettuina. Jos maksaja ei ole järjestelmätili eikä nonce-tili, transaktio epäonnistuu virheelläTransactionError::InvalidAccountForFee. -
Ladatun datan kokoraja: Kaikkien ladattujen tilien yhteenlaskettu koko (sisältäen
TRANSACTION_ACCOUNT_BASE_SIZE64 tavua per tili) ei saa ylittääMAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES(64 MiB). Tämän rajan ylittäminen tuottaa virheenTransactionError::MaxLoadedAccountsDataSizeExceeded. -
Ohjelmatilien validointi: Jokaisen instruktion kutsuman ohjelman on oltava olemassa ja sen on oltava kelvollisen lataajan omistuksessa: jonkin
PROGRAM_OWNERS(BPF Loader Upgradeable, BPF Loader, BPF Loader Deprecated, Loader V4) tai natiivin lataajan. Jos ohjelmatiliä ei ole olemassa, transaktio epäonnistuu virheelläTransactionError::ProgramAccountNotFound. Jos se on olemassa mutta sillä on virheellinen omistaja, transaktio epäonnistuu virheelläTransactionError::InvalidProgramForExecution. -
Olemattomat tilit: Tilit, joita ei ole olemassa ketjussa, ladataan oletustileinä (0 lamportia, tyhjä data, System Programin omistuksessa)
rent_epochasetettuna arvoonu64::MAX.
BPF-sarjallistamismuoto
Kun ohjelma kutsutaan, ajonaikaympäristö sarjallistaa tilit yhtenäiseen
muistipuskuriin ja välittää sen BPF VM:lle. Sarjallistamismuoto (standardille
tasatulle muodolle, jota käyttävät kaikki lataajat paitsi vanhentunut loader-v1)
on määritelty tiedostossa
serialize_parameters_aligned().
Puskuri alkaa u64-arvolla (8 tavua, little-endian), joka sisältää tilien
määrän. Sitten jokaiselle käskyn tilille puskuri sisältää:
| Siirtymä | Koko | Kenttä | Tyyppi |
|---|---|---|---|
| 0 | 1 | duplicate marker | u8 (0xFF = uniikki, indeksi = kyseisen tilin duplikaatti) |
| 1 | 1 | is_signer | u8 (0 tai 1) |
| 2 | 1 | is_writable | u8 (0 tai 1) |
| 3 | 1 | executable | u8 (0 tai 1) |
| 4 | 4 | original_data_len (varattu, aina 0) | [0u8; 4] |
| 8 | 32 | key | Pubkey |
| 40 | 32 | owner | Pubkey |
| 72 | 8 | lamports | u64 (little-endian) |
| 80 | 8 | data_len | u64 (little-endian) |
| 88 | data_len | data | [u8] |
| 88 + data_len | 10240 + padding | realloc-tila + tasaus | Nollatäytetty MAX_PERMITTED_DATA_INCREASE-kokoon (10 KiB) + padding tasaukseen BPF_ALIGN_OF_U128-rajalle (8 tavua) |
| ... | 8 | rent_epoch | u64 (little-endian) |
Kaikkien tilien jälkeen puskuri lisää:
| Koko | Kenttä |
|---|---|
| 8 | instruction_data_len (u64, little-endian) |
| instruction_data_len | instruction_data |
| 32 | program_id (Pubkey) |
Duplikaattitileille kirjoitetaan vain 1 tavu (duplikaattimarkkeri alkuperäisen indeksillä) plus 7 tavua täytettä.
Tilien deduplikointi
Kun sama tilin julkinen avain esiintyy useita kertoja instruktion
accounts-taulukossa, ajonaikainen ympäristö
deduplikoi
ne. Jokainen instruktion tililuettelon merkintä saa oman
InstructionAccount-rakenteensa,
mutta merkinnät, jotka viittaavat samaan transaktiotason tiliin, osoittavat
samaan taustalla olevaan dataan.
is_instruction_account_duplicate-metodi
määrittää, onko tietty instruktiotiliindeksi ensimmäinen esiintymä vai
duplikaatti etsimällä transaktiotason tiliindeksin ja löytämällä ensimmäisen
instruktiotason indeksin, joka kartoittuu siihen:
- Jos nykyinen instruktiotiliindeksi on yhtä suuri kuin ensimmäinen kartoitettu
indeksi, se ei ole duplikaatti (palauttaa
None). - Muussa tapauksessa se palauttaa
Some(first_index), jossafirst_indexon ensimmäisen esiintymän indeksi.
Koska kaikki viittaukset samaan tiliin jakavat saman taustalla olevan
AccountSharedData:n, muutokset minkä tahansa viittauksen kautta ovat
välittömästi näkyvissä kaikkien muiden viittausten kautta. Kuitenkin vain yksi
muokattava laina voi olla voimassa kerrallaan. Yritys lainata samaa tiliä
muokattavasti kahden eri instruktiotiliindeksin kautta samanaikaisesti palauttaa
InstructionError::AccountBorrowFailed. Ohjelmien on vapautettava yksi
laina ennen toisen hankkimista samalle taustalla olevalle tilille.
Ohjelman suorituksen jälkeen ajonaikainen ympäristö deserialisoi puskurin
takaisin
(deserialize_parameters_aligned())
ja soveltaa kaikki muutokset lamports:iin, data:iin (mukaan lukien
pituusmuutokset MAX_PERMITTED_DATA_INCREASE:iin asti) ja owner:iin.
Is this page helpful?