Yhteenveto
Transaktiot kulkevat 8 vaiheen läpi: vastaanotto, allekirjoituksen varmennus, puhdistus, budjetin/iän tarkistukset, maksajan validointi, tilin lataus, käskyn suoritus ja vahvistus.
Transaktioiden käsittelyputki
Kun transaktio saapuu validatorille, se kulkee läpi sarjan validointi- ja suoritusvaiheita. Seuraavassa kuvataan täydellinen putki vastaanottamisesta vahvistukseen, sisältäen viittaukset lähdetiedostoihin agave-validator-clientissa.
1. Vastaanotto ja deserialisointi
Validator vastaanottaa transaktiotavut UDP/QUIC-yhteyden kautta. Raakadatan on
mahduttava yksittäiseen pakettiin (PACKET_DATA_SIZE = 1 232 tavua). Tavut
deseralisoidaan VersionedTransaction-muotoon, joka sisältää
allekirjoitustaulukon ja VersionedMessage-viestin (joko legacy tai v0).
2. Allekirjoituksen varmennus (sigverify)
Allekirjoitukset varmennetaan
sigverify-vaiheessa
ennen kuin transaktio siirtyy banking-vaiheeseen. Jokaiselle allekirjoitukselle
indeksissä i varmennin tarkistaa Ed25519(signatures[i], account_keys[i],
message_bytes). Jos jokin allekirjoitus on virheellinen, paketti hylätään.
Varmennus on rinnakkaistettu: validator jakaa pakettierät
VERIFY_PACKET_CHUNK_SIZE-kokoisiin
paloihin (128) ja käsittelee ne rinnakkain.
3. Puhdistus
Deserialisoitu transaktio puhdistetaan tuottamaan SanitizedTransaction
(tai
RuntimeTransaction).
Puhdistus validoi rakenteelliset invariantit:
- Allekirjoitusten määrä vastaa
num_required_signatures-arvoa otsikossa - Kaikki käskyjen
program_id_index- jaaccount_indices-arvot ovat rajojen sisällä - Maksaja (tilin indeksi 0) on kirjoitettava allekirjoittaja
RuntimeTransaction-kääre tallentaa välimuistiin esikäsitellyt metatiedot
TransactionMeta-rakenteesta:
viestin hash, äänestystransaktiolippu, esikäännösten allekirjoitusmäärät
(Ed25519/secp256k1/secp256r1), laskentabudjetin käskytiedot ja käskyjen
kokonaisdatan pituus.
4. Tarkista laskentabudjetti, ikä ja tilavälimuisti
check_transactions-metodi
suorittaa useita tarkistuksia transaktiota kohden:
Laskentabudjetti: Transaktion laskentabudjetti-instruktiot jäsennetään ja
validoidaan ensin. Maksutiedot lasketaan budjettirajoista ja
priorisointimaksusta. Jos laskentabudjetti on virheellinen tai ristiriitainen,
transaktio epäonnistuu laskentabudjetin jäsennysvirheillä, kuten
DuplicateInstruction, InstructionError(..., InvalidInstructionData) tai
InvalidLoadedAccountsDataSizeLimit.
Blockhash-ikä: Transaktion recent_blockhash haetaan
BlockhashQueue-jonosta.
Jos hash löytyy ja sen ikä on MAX_PROCESSING_AGE-arvon sisällä (150
slottia), transaktio jatkaa. Jos sitä ei löydy, validaattori tarkistaa
kelvollisen durable nonce -arvon.
Tilavälimuisti: Transaktion viestihashin tarkistetaan tilavälimuistista. Jos
se löytyy, transaktio hylätään virheellä AlreadyProcessed.
5. Validoi nonce ja maksaja
SVM:n
validate_transaction_nonce_and_fee_payer-metodi
käsittelee kaksi validointia:
Nonce-validointi (jos sovellettavissa): Nonce-transaktioissa validaattori lataa nonce-tilin ja varmistaa:
- Tilin omistaa System Program
- Se jäsentyy muotoon
State::Initialized - Tallennettu durable nonce vastaa transaktion
recent_blockhash-arvoa - Noncea voidaan edistää (sen nykyinen durable nonce eroaa seuraavasta durable noncesta, eli noncea ei ole jo käytetty nykyisessä lohkossa)
- Nonce-auktoriteetti on allekirjoittanut transaktion
Jos kelvollinen, nonce edistetään seuraavaan durable nonce -arvoon. Katso
validate_transaction_nonce.
Maksajan validointi: Maksajatili (aina indeksi 0) ladataan ja tarkistetaan
validate_fee_payer-metodilla:
- Tilin on oltava olemassa (lamports > 0), muuten
AccountNotFound - Tilin on oltava järjestelmätili tai nonce-tili, muuten
InvalidAccountForFee - Lamportien on katettava
min_balance + total_fee, jossamin_balanceon 0 järjestelmätileille tairent.minimum_balance(NonceState::size())nonce-tileille; muutenInsufficientFundsForFee - Maksun vähentämisen jälkeen tilin on pysyttävä rent-exempt-tilassa (ei voi siirtyä rent-exempt-tilasta rent-paying-tilaan)
Maksu vähennetään maksajalta tässä vaiheessa. Tilannekuva maksusta vähennetystä
maksajasta (ja edistetystä noncesta, jos sovellettavissa) tallennetaan nimellä
RollbackAccounts, jotka ovat tilejä, jotka vahvistetaan, vaikka suoritus
epäonnistuisi.
6. Lataa tilit
load_transaction
lataa kaikki tilit, joihin transaktio viittaa.
AccountLoader
käärii ulkoisen tilivaraston ja ylläpitää eräkohtaista välimuistia, jotta saman
erän aiempien transaktioiden muokkaamat tilit ovat näkyvissä myöhemmille
transaktioille.
Jokaiselle ei-maksajatilille lataaja:
- Hakee tilin välimuistista tai accounts-db:stä
- Päivittää vuokravapautuksen tilan tarvittaessa
- Kerää tilin datakoon
loaded_accounts_data_size_limit-rajaan (oletuksena 64 MiB). Jokainen tili aiheuttaa peruskuormanTRANSACTION_ACCOUNT_BASE_SIZE(64 tavua) plus sen datapituuden
Jokaiselle transaktion käskyjen kutsumalle ohjelmalle lataaja varmistaa, että
ohjelmatili on olemassa ja sen omistaa kelvollinen lataaja (NativeLoader tai
jokin PROGRAM_OWNERS). Virheelliset ohjelmat epäonnistuvat virheellä
ProgramAccountNotFound tai InvalidProgramForExecution.
LoaderV3 (päivitettävät) ohjelmat lataavat implisiittisesti niihin liittyvän programdata-tilin, joka myös lasketaan ladatun datan kokorajaan.
Jos tilin lataus epäonnistuu, mutta maksaja validoitiin onnistuneesti,
transaktiosta tulee
FeesOnly
-tulos: maksu peritään silti, mutta käskyjä ei suoriteta.
7. Suorita käskyt
execute_loaded_transaction
luo TransactionContext -olion kaikilla ladatuilla tileillä ja kutsuu
process_message
-funktiota. Käskyt suoritetaan peräkkäin siinä järjestyksessä, jossa ne
esiintyvät viestissä. Jokainen käskyn kutsu luo InvokeContext -olion ja
kutsuu kohdeohjelmaa.
Käskyn käsittelyn yksityiskohdat
Ajoympäristön
process_message
-funktio iteroi jokaisen käskyn läpi ja kutsuu kohdeohjelmaa:
- Jokaiselle ohjeelle runtime kutsuu
prepare_next_top_level_instruction, joka rakentaaInstructionContext. Tämä konteksti sisältää viittaukset ohjeen tileille (ratkaistuna käännetyistä indekseistä), instruction datan ja program account -indeksin. - Runtime tarkistaa, onko ohjelma precompile (Ed25519, Secp256k1, Secp256r1). Precompilet vahvistetaan suoraan ilman BPF VM:n kutsumista.
- Kaikille muille ohjelmille runtime kutsuu
process_instruction, joka lataa ohjelman välimuistista ja suorittaa sen BPF-virtuaalikoneessa. - Ohjeen suorittamisen jälkeen runtime
vahvistaa,
että lamport-saldo kaikkien ohjeen tilien välillä ei ole muuttunut
(
UnbalancedInstruction-tarkistus). - Jos jokin ohje epäonnistuu, koko transaktio peruutetaan. Mitään välitilan muutoksia ei vahvisteta.
Jokainen ohje kasvattaa instruction trace -jälkeä. Jälki sisältää sekä ylätason
ohjeet että kaikki niiden kutsutut CPI:t. Jäljen
kokonaispituus (ylätason ohjeet plus kaikki sisäkkäiset CPI:t) ei voi ylittää
64:ää (MAX_INSTRUCTION_TRACE_LENGTH). Tämän rajan ylittäminen palauttaa
InstructionError::MaxInstructionTraceLengthExceeded.
Suorituksen jälkeen runtime vahvistaa, että:
- Lamport-summa kaikkien tilien välillä ei ole muuttunut
- Mikään tili ei ole siirtynyt rent-exempt-tilasta rent-paying-tilaan
8. Vahvistus tai peruutus
Jos suoritus onnistuu, muokatut tilitilat TransactionContext:sta kirjoitetaan
takaisin AccountLoader:n batch-paikalliseen välimuistiin. Jos suoritus
epäonnistuu, vain RollbackAccounts (maksaja, jolta maksu on vähennetty ja
nonce edistetty) kirjoitetaan takaisin. Maksu peritään silti, mutta kaikki muut
tilimuutokset hylätään.
Pipeline-yhteenveto
Receive packet (UDP/QUIC)--> Deserialize into VersionedTransaction--> Sigverify (parallel Ed25519 verification)--> Sanitize (structural validation, metadata extraction)--> Parse compute budget, calculate fees--> Check blockhash age (or verify nonce account)--> Check status cache (dedup)--> Validate nonce authority and advanceability (if nonce transaction)--> Validate fee payer (load, check balance, deduct fee)--> Load all accounts (with data size limits)--> Load programs (verify loaders)--> Execute instructions sequentially--> Verify post-conditions (lamport balance, rent state)--> Commit account changes (or rollback on failure)
Transaktiovirheiden viite
Seuraava taulukko listaa kaikki
TransactionError
-variantit ja missä pipeline-vaiheessa ne esiintyvät:
| Virhe | Vaihe | Syy |
|---|---|---|
AccountInUse | Ajastus | Tili on jo toisen tapahtuman lukitsema samassa erässä |
AccountLoadedTwice | Ajastus | Pubkey esiintyy kahdesti tapahtuman account_keys-kentässä |
AccountNotFound | Maksajan validointi | Maksajatiliä ei ole olemassa |
ProgramAccountNotFound | Tilin lataus | Kutsuttua ohjelmaa ei ole olemassa |
InsufficientFundsForFee | Maksajan validointi | Maksaja ei voi kattaa maksua + rent-exempt-minimiä |
InvalidAccountForFee | Maksajan validointi | Maksaja ei ole järjestelmä- tai nonce-tili |
AlreadyProcessed | Tilavälimuisti | Tapahtuma oli jo käsitelty |
BlockhashNotFound | Ikätarkistus | Blockhash ei ole jonossa eikä kelvollinen nonce |
InstructionError | Suoritus | Virhe tapahtui käskyä suoritettaessa (sisältää käskyn indeksin ja tietyn InstructionError-virheen) |
CallChainTooDeep | Tilin lataus | Lataajan kutsuketju on liian syvä |
MissingSignatureForFee | Sanitointi | Tapahtuma vaatii maksun, mutta allekirjoitusta ei ole |
InvalidAccountIndex | Sanitointi | Tapahtuma sisältää virheellisen tiliviitteen |
SignatureFailure | Allekirjoituksen varmennus | Ed25519-allekirjoitus ei täsmää (paketti hylätään) |
InvalidProgramForExecution | Tilin lataus | Ohjelman omistaja ei ole kelvollinen lataaja |
SanitizeFailure | Sanitointi | Tapahtuman tilien offsetien sanitointi epäonnistui |
ClusterMaintenance | Ajastus | Tapahtumat ovat tällä hetkellä pois käytöstä klusterin huollon vuoksi |
AccountBorrowOutstanding | Suoritus | Tapahtuman käsittely jätti tilille avoimen lainaviitteen |
WouldExceedMaxBlockCostLimit | Ajastus | Tapahtuma ylittäisi lohkon maksimikustannusrajan |
UnsupportedVersion | Sanitointi | Tapahtuman versio ei ole tuettu |
InvalidWritableAccount | Tilin lataus | Tapahtuma lataa kirjoitettavan tilin, johon ei voi kirjoittaa |
WouldExceedMaxAccountCostLimit | Ajastus | Tapahtuma ylittäisi tilin maksimikustannusrajan lohkossa |
WouldExceedAccountDataBlockLimit | Ajastus | Tapahtuma ylittäisi tilin datarajan lohkossa |
TooManyAccountLocks | Ajastus | Tapahtuma lukitsi liian monta tiliä |
AddressLookupTableNotFound | Tilin lataus | Osoitehakutaulun tiliä ei ole olemassa |
InvalidAddressLookupTableOwner | Tilin lataus | Osoitehakutaulun omistaa väärä ohjelma |
InvalidAddressLookupTableData | Tilin lataus | Osoitehakutaulu sisältää virheellistä dataa |
InvalidAddressLookupTableIndex | Tilin lataus | Osoitetaulun haku käyttää virheellistä indeksiä |
InvalidRentPayingAccount | Suorituksen jälkeinen tarkistus | Tili siirtyi rent-exempt-tilasta rent-paying-tilaan |
WouldExceedMaxVoteCostLimit | Ajastus | Tapahtuma ylittäisi äänestyksen maksimikustannusrajan |
WouldExceedAccountDataTotalLimit | Ajastus | Tapahtuma ylittäisi tilin kokonaisdatarajan |
DuplicateInstruction | Laskentabudjetin jäsennys | Compute budget -käskyn variantti esiintyy kahdesti samassa tapahtumassa |
InsufficientFundsForRent | Suorituksen jälkeinen tarkistus | Tilillä ei ole tarpeeksi lamportteja kattamaan rent-maksua sen datakoolle |
MaxLoadedAccountsDataSizeExceeded | Tilin lataus | Ladattu data ylittää 64 MiB -rajan |
InvalidLoadedAccountsDataSizeLimit | Laskentabudjetin jäsennys | SetLoadedAccountsDataSizeLimit asetettu arvoon 0 |
ResanitizationNeeded | Sanitointi | Tapahtuma erosi ennen/jälkeen ominaisuuden aktivoinnin ja vaatii uudelleensanitoinnin |
ProgramExecutionTemporarilyRestricted | Tilin lataus | Ohjelman suoritus on väliaikaisesti rajoitettu viitatulla tilillä |
UnbalancedTransaction | Suorituksen jälkeinen tarkistus | Lamporttien kokonaissaldo ennen tapahtumaa ei vastaa saldoa sen jälkeen |
ProgramCacheHitMaxLimit | Tilin lataus | Ohjelmavälimuisti saavutti maksimirajan |
CommitCancelled | Commit | Commit peruutettu sisäisesti |
Is this page helpful?