Programma-uitvoering

Samenvatting

Programma's worden via LLVM gecompileerd naar sBPF en draaien in een sandbox-VM met een budget van 1,4M CU per transactie. De runtime slaat tot 512 gecompileerde programma's op in de cache, biedt syscalls voor logging, CPI, crypto en geheugen, en vertraagt nieuwe implementaties met 1 slot.

Compilatie

Solana gebruikt LLVM om programma's te compileren naar ELF-binaries die het Solana Bytecode Format (sBPF) bevatten. Het ELF-binary wordt onchain opgeslagen in een uitvoerbaar account.

sBPF is Solana's aangepaste variant van eBPF-bytecode, afgestemd op de Solana-runtime. Het is geen standaard eBPF en bevat Solana-specifieke aanpassingen.

Programma's schrijven

Solana-programma's worden voornamelijk geschreven in Rust via een van de drie benaderingen:

Zie Cross-Program Invocations voor CPI-concepten en voorbeelden die van toepassing zijn op al deze benaderingen.

Programma-uitvoeringsmodel

Wanneer een transactie wordt verwerkt, voert de runtime elke instructie sequentieel uit via process_message(). Voor elke instructie doet de runtime het volgende:

  1. Bereidt de instructiecontext voor. Roept prepare_next_top_level_instruction() aan om de accountindices van de instructie te mappen, ondertekenaar- en schrijfbare vlaggen in te stellen, en de TransactionContext te configureren.

  2. Controleert precompiles. Als het programma een precompile is, roept de runtime process_precompile() aan, wat nog steeds een stackframe plaatst en verwijdert (via push() en pop()) maar de sBPF VM en de zoekopdracht in de programma-cache omzeilt en native code direct uitvoert.

  3. Plaatst een stackframe. (Stappen 3-6 vinden plaats binnen InvokeContext::process_instruction() en process_executable_chain(), aangeroepen vanuit process_message().) Roept push() aan op InvokeContext, wat de hoogte van de instructiestack verhoogt en de herintrede-regel handhaaft: een programma mag zichzelf alleen opnieuw betreden als de directe aanroeper (het programma bovenaan de instructiestack) hetzelfde programma is. Diepe zelfrecursie (A -> A -> A) is toegestaan, afhankelijk van de stackdieptelimieten. Andere hrintrede-patronen (bijv. A roept B aan, B roept A aan) retourneren InstructionError::ReentrancyNotAllowed.

  4. Bepaalt het programma. De runtime roept process_executable_chain() aan, wat de loader bepaalt. Als de eigenaar van het program account de native loader is, is het programma een builtin en wordt de entrypoint-functie direct opgezocht in de ProgramCacheForTxBatch. Als de eigenaar een van de BPF-loaders is (bpf_loader_deprecated, bpf_loader, bpf_loader_upgradeable of loader_v4), wordt in plaats daarvan de eigen builtin-entrypoint van de loader aangeroepen.

  5. Voert het BPF-programma uit. Voor BPF-programma's zoekt het loader-entrypoint het gecompileerde uitvoerbare bestand op in de programma-cache. De execute()-functie doet vervolgens het volgende:

    • Serialiseert accountgegevens naar een platte parameterbuffer
    • Maakt de sBPF VM aan met stack, heap en geheugenregio's
    • Voert de gecompileerde code uit en verbruikt daarbij compute units. Retourneert ComputationalBudgetExceeded als het budget wordt overschreden.
    • Deserialiseert accountgegevens van de buffer terug naar de accountstatus
  6. Verwijdert het stackframe. Roept pop() aan, wat verifieert dat de instructie de boekhoudregel van de runtime niet heeft geschonden (lamport-saldi zijn in evenwicht, alleen-lezen accounts zijn niet gewijzigd, de omvang van accountgegevens valt binnen de limieten).

  7. Accumuleert compute units. De door de instructie verbruikte compute units worden via saturating_add opgeteld bij het transactietotaal.

Programma-cache

De runtime onderhoudt een globale ProgramCache die geverifieerde en gecompileerde programma's opslaat. De cache is fork-graph-bewust en verwerkt regels voor implementatiezichtbaarheid, verwijdering en hercompilatie bij epoch-grenzen.

Cachegegevenstypen

Elk gecached programma heeft een ProgramCacheEntryType die het runtimegedrag bepaalt:

TypeBeschrijving
LoadedGeverifieerd en gecompileerd programma, klaar voor uitvoering.
BuiltinNatief programma gecompileerd in het validator-binary (System, Stake, Vote, enz.). Niet onchain opgeslagen.
UnloadedEerder geverifieerd programma waarvan het gecompileerde uitvoerbare bestand uit het geheugen is verwijderd om ruimte vrij te maken. Houdt nog steeds gebruiksstatistieken bij. Kan opnieuw worden geladen zonder herverificatie.
FailedVerificationTombstone voor programma's die de sBPF-verificator niet hebben doorstaan onder de huidige functieset. Kan Loaded worden als feature-activeringen de verificatieregels wijzigen.
ClosedTombstone voor programma's die expliciet zijn gesloten of nooit zijn geïmplementeerd. Ook gebruikt voor accounts (zoals bufferaccounts) die tot een loader behoren maar geen uitvoerbare code bevatten.
DelayVisibilitySynthetische tombstone die wordt geretourneerd door ProgramCacheForTxBatch::find() wanneer een Loaded-vermelding bestaat maar nog niet van kracht is (de effective_slot ligt in de toekomst). Wordt nooit rechtstreeks in de cache opgeslagen.

Zichtbaarheidsvertraging

Nieuw geïmplementeerde of bijgewerkte programma's zijn niet onmiddellijk van kracht. De DELAY_VISIBILITY_SLOT_OFFSET-constante is 1, wat betekent dat een programma dat in slot N wordt geïmplementeerd van kracht wordt in slot N+1. Tijdens de implementatie-slot retourneert elke poging om de nieuwe versie aan te roepen DelayVisibility, waardoor de runtime "Program is not deployed." meldt.

Verwijderingsbeleid

De cache bevat maximaal MAX_LOADED_ENTRY_COUNT (512) gecompileerde programma-items. Wanneer de limiet is bereikt, worden de minst gebruikte programma's verwijderd naar de Unloaded-status. Gebruik wordt bijgehouden via tx_usage_counter (verhoogd telkens wanneer een transactie naar het programma verwijst) en latest_access_slot.

Hercompilatie bij epoch-grens

Als een feature-activering de ProgramRuntimeEnvironments wijzigt bij een epoch-grens, worden alle gecachede programma's hergecompileerd tegen de nieuwe omgeving.

Retourgegevens

Programma's kunnen retourgegevens instellen via de sol_set_return_data-syscall. De gegevens worden opgeslagen in een transactieniveau- TransactionReturnData-struct die de gegevensbytes en de program_id bevat van het programma waarvan de instructie de syscall heeft aangeroepen. De maximale grootte is 1.024 bytes (MAX_RETURN_DATA).

Is this page helpful?

Inhoudsopgave

Pagina Bewerken
© 2026 Solana Foundation. Alle rechten voorbehouden.