Account runtime

Samenvatting

Vóór uitvoering laadt de runtime accounts, valideert de betaler van de kosten, controleert huurvrijstelling en serialiseert accountgegevens naar een geheugenindeling die programma's kunnen benaderen.

Deze pagina behandelt runtime-interne werking. De meeste ontwikkelaars hebben deze informatie niet nodig voor het bouwen van programma's. Zie accountstructuur voor het ontwikkelaarsperspectief.

Account laden

Voordat een transactie wordt uitgevoerd, laadt de runtime alle gerefereerde accounts via load_transaction_accounts(). Dit proces voert verschillende validaties uit:

  1. Validatie van de betaler: De betaler van de kosten (eerste account) moet bestaan, een systeemaccount of nonce-account zijn en voldoende lamports hebben om de kosten te dekken (validate_fee_payer()). Na het betalen van de kosten moet het account ofwel huurvrij blijven of precies naar 0 lamports gaan. Het kan niet eindigen tussen 0 en het huurvrije minimum. Nonce-accounts moeten altijd voldoende lamports behouden om huurvrij te blijven. Als de betaler geen systeemaccount of nonce-account is, mislukt de transactie met TransactionError::InvalidAccountForFee.

  2. Limiet voor geladen gegevensgrootte: De totale grootte van alle geladen accounts (inclusief een TRANSACTION_ACCOUNT_BASE_SIZE van 64 bytes per account) mag niet groter zijn dan MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES (64 MiB). Het overschrijden van deze limiet levert TransactionError::MaxLoadedAccountsDataSizeExceeded op.

  3. Validatie van programma-account: Elk programma dat door een instructie wordt aangeroepen moet bestaan en eigendom zijn van een geldige loader: een van de PROGRAM_OWNERS (BPF Loader Upgradeable, BPF Loader, BPF Loader Deprecated, Loader V4) of de native loader. Als het programma-account niet bestaat, mislukt de transactie met TransactionError::ProgramAccountNotFound. Als het wel bestaat maar een ongeldige eigenaar heeft, mislukt de transactie met TransactionError::InvalidProgramForExecution.

  4. Niet-bestaande accounts: Accounts die niet on-chain bestaan worden geladen als standaard accounts (0 lamports, lege data, eigendom van system program) met rent_epoch ingesteld op u64::MAX.

BPF-serialisatieformaat

Wanneer een programma wordt aangeroepen, serialiseert de runtime accounts naar een aaneengesloten geheugenbuffer en geeft deze door aan de BPF VM. Het serialisatieformaat (voor het standaard uitgelijnde formaat dat wordt gebruikt door alle loaders behalve de verouderde loader-v1) is gedefinieerd in serialize_parameters_aligned().

De buffer begint met een u64 (8 bytes, little-endian) die het aantal accounts bevat. Vervolgens bevat de buffer voor elk account in de instructie:

OffsetGrootteVeldType
01duplicaatmarkeringu8 (0xFF = uniek, index = duplicaat van dat account)
11is_signeru8 (0 of 1)
21is_writableu8 (0 of 1)
31executableu8 (0 of 1)
44original_data_len (gereserveerd, altijd 0)[0u8; 4]
832keyPubkey
4032ownerPubkey
728lamportsu64 (little-endian)
808data_lenu64 (little-endian)
88data_lendata[u8]
88 + data_len10240 + paddingrealloc-ruimte + uitlijningOpgevuld met nullen tot MAX_PERMITTED_DATA_INCREASE (10 KiB) + padding om uit te lijnen op BPF_ALIGN_OF_U128 (8 bytes)
...8rent_epochu64 (little-endian)

Na alle accounts voegt de buffer het volgende toe:

GrootteVeld
8instruction_data_len (u64, little-endian)
instruction_data_leninstruction_data
32program_id (Pubkey)

Voor dubbele accounts wordt slechts 1 byte (de duplicaatmarkering met de index van het origineel) plus 7 bytes padding geschreven.

Deduplicatie van accounts

Wanneer dezelfde publieke accountsleutel meerdere keren voorkomt in de accounts-array van een instructie, dedupliceert de runtime deze. Elk item in de accountlijst van de instructie krijgt zijn eigen InstructionAccount-struct, maar items die verwijzen naar hetzelfde account op transactieniveau wijzen naar dezelfde onderliggende data.

De is_instruction_account_duplicate-methode bepaalt of een gegeven instructie-accountindex het eerste voorkomen of een duplicaat is door de accountindex op transactieniveau op te zoeken en de eerste index op instructieniveau te vinden die ernaar verwijst:

  • Als de huidige instructie-accountindex gelijk is aan de eerste toegewezen index, is het geen duplicaat (retourneert None).
  • Anders retourneert het Some(first_index), waarbij first_index de index is van het eerste voorkomen.

Omdat alle verwijzingen naar hetzelfde account dezelfde onderliggende AccountSharedData delen, zijn wijzigingen via elke verwijzing onmiddellijk zichtbaar via alle andere verwijzingen. Er kan echter slechts één muteerbare borrow tegelijk worden vastgehouden. Een poging om hetzelfde account muteerbaar te lenen via twee verschillende instructie-accountindexen tegelijkertijd retourneert InstructionError::AccountBorrowFailed. Programma's moeten één borrow loslaten voordat ze een andere op hetzelfde onderliggende account verkrijgen.

Nadat het programma is uitgevoerd, deserialiseert de runtime de buffer terug (deserialize_parameters_aligned()) en past eventuele wijzigingen toe op lamports, data (inclusief lengtewijzigingen tot MAX_PERMITTED_DATA_INCREASE), en owner.

Is this page helpful?

Inhoudsopgave

Pagina Bewerken

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden