Skip to content

The Runtime & Programs (SBF)

The book keeps asking one question: how do you build a single global state machine that runs at hardware speed without falling apart? Earlier parts answered pieces of it. The account model pulled state out of programs so a transaction’s footprint is knowable before it runs. Sealevel used that footprint to run non-conflicting transactions across cores. Proof of History gave every validator the same ordering without a round of messages. Each of those took something for granted: that there is a program, and that running it is safe.

This part is where that assumption gets paid for. A global state machine has to run untrusted code — programs written by strangers, deployed by anyone, invoked by anyone — and it has to run that code fast, deterministically, and without any single program being able to crash, hang, or corrupt the validator it runs on. That is not a property you get for free from “let people upload code.” It is a property you build: a specific bytecode, a loader that verifies before it trusts, a sandbox that denies everything by default, a meter that bounds every instruction, and a small set of deterministic globals. This part builds each piece from first principles.

What this part is about (and what it is not)

Section titled “What this part is about (and what it is not)”

The scope here is narrow on purpose: the on-chain execution environment. Given an ordered, scheduled transaction that names a program and a list of accounts, what actually happens when the validator runs that program’s code? That splits into a handful of concrete mechanisms:

  • The bytecode the program compiles to (SBF), and why it is a register machine and not native x86.
  • The loader and verifier that check a program before it is allowed to run, so malformed or malicious bytecode never executes.
  • The sandbox and syscalls — the wall around the program, and the tiny, audited doorways through it back to the runtime.
  • Compute units — the meter that guarantees every program halts, so no one can hang the chain with an infinite loop.
  • Cross-program invocation and PDAs — how one program safely calls another, and how a program signs for accounts it owns without a private key.
  • Sysvars — the deterministic view of “now” (clock, rent, fees) that every validator must compute identically.

This part is deliberately not about ordering, consensus, or networking. When a transaction runs, whether the resulting state is canonical, and how the transaction reached the leader are all answered elsewhere — Proof of History, Consensus, and the validator pipeline own those. Here we assume the transaction has already arrived, already been ordered, and already been scheduled. The only question is: how does the validator turn this program’s code into new state, safely?

already handled THIS PART already handled
─────────────── ───────── ───────────────
PoH orders it ─► Sealevel ─► load · verify · sandbox ─► Consensus agrees
pipeline routes it schedules it meter · invoke · sysvars the new state is
──────────────────────── canonical
"run untrusted code fast,
deterministically, safely"

Three ideas from earlier parts are load-bearing here; if any is fuzzy, follow the link before you go on.

  • Programs are stateless. From Stateless Programs Act on Accounts: a program is pure code with no storage of its own. It receives an ordered list of accounts and an opaque data blob, mutates the accounts, and returns. Everything in this part — the sandbox, the syscalls, the metering — is about running that function safely. There is no hidden per-program memory to protect, only the accounts handed in.
  • Accounts are external and declared. From Everything Is an Account and the Sealevel part: all mutable state lives in named accounts, and a transaction declares which ones it touches (and how) before it runs. The sandbox enforces that declaration — a program physically cannot reach an account it did not name.
  • Execution is parallel. From Sealevel: the same program runs on many cores at once, over disjoint working sets. That is why determinism and metering matter so much here: thousands of independent executions, on thousands of different machines, must all reach the identical result or the chain forks.

The one thing to keep separate: earlier parts gave us the ordering and the scheduling. This part gives us the execution environment those two feed into. Ordering is about time; this part is about the sandbox.

Read the pages in order. Each one forces exactly one idea, and each grounds where it can in the book’s companion runtime, solmini — the same stateless Program trait and three-field Account you already know — and points to the real Solana mechanism it stands in for.

#PageThe idea it forcesGrounded in
2Programs as SBF Bytecodesource compiles to a portable register bytecode (SBF), not native code, so any validator can run it identicallythe stateless Program as compiled artifact
3The Loader and the Verifierbytecode is statically verified before first execution — no jumps out of bounds, no forbidden instructionsverify-then-trust; the program account holds the bytes
4Syscalls and the Sandboxthe program runs in a deny-by-default sandbox; the only way back to the runtime is a small set of audited syscallsthe account slice is the only reachable state
5Compute Units and Limitsevery instruction costs metered compute units, so every program provably haltsthe compute budget, Amdahl’s hot-account floor
6Cross-Program Invocation and Signed PDAsone program calls another under the same sandbox rules, and signs for owned accounts via PDAsCPI depth limits; PDAs
7Sysvars: Clock, Rent, and Deterministic Globals”now” must be a value every validator computes identically, so it is exposed as read-only accountsdeterminism; the clock as data
900Revision: The Runtime & Programsthe part compressed to what you must retainthe whole thread in one page

By the end you will be able to take any deployed Solana program and explain, mechanism by mechanism, exactly what stands between “a stranger uploaded these bytes” and “every validator on Earth ran them and agreed on the result.”

What does building this execution environment force you to understand? That “run untrusted code fast” is not one problem but three, and they only compose because each is solved separately. Sandboxing answers can this code hurt the validator or reach state it wasn’t given? — no, because it runs behind a wall with audited doorways. Determinism answers will two honest validators running the same bytecode over the same accounts get the same answer? — yes, because the bytecode is portable, the inputs are the declared accounts plus deterministic sysvars, and nothing non-deterministic (wall-clock time, randomness, the network) is reachable. Metering answers is this program guaranteed to finish? — yes, because every instruction costs compute units and the budget is finite, so the halting problem is sidestepped by fiat.

Stack those three and you get the property the whole chain rests on: thousands of strangers’ machines can run the same stranger’s program and agree on the result. That agreement is what “a single global state machine” actually means — not one computer, but many computers that are provably running the same computation. This part is where that “provably” is manufactured.

The first job is to see what the program even is once it leaves the developer’s editor — why it becomes portable register bytecode instead of native machine code: Programs as SBF Bytecode.

  1. This part narrows the throughline to a specific problem. State it in one sentence, and name the three distinct properties the execution environment must provide.
  2. Three ideas from earlier parts are load-bearing here: stateless programs, external/declared accounts, and parallel execution. Pick any two and explain what the runtime would be unable to guarantee without them.
  3. The part explicitly excludes ordering, consensus, and networking. For each, name the earlier part that owns it, and say what this part assumes has already happened by the time a program runs.
  4. Why does “run the same program on thousands of machines and agree on the result” require determinism specifically, and what kinds of inputs must the sandbox therefore make unreachable?
  5. Metering (compute units) is described as sidestepping the halting problem “by fiat.” What does that mean, and what would break on the chain if a program could run for unbounded time?
Show answers
  1. The problem: a single global state machine must run untrusted code fast, deterministically, and without any one program being able to crash or hang the validator. The three properties are sandboxing (a program cannot harm the validator or reach state it was not given), determinism (every honest validator computes the identical result from the identical inputs), and metering (every program provably halts within a bounded compute budget).
  2. Any two of: stateless programs — without them a program could carry hidden state between calls, so its footprint would not be knowable and the sandbox could not confine it to the accounts it was handed. External/declared accounts — without the up-front declaration, the runtime could not tell which accounts a program will touch, so it could neither schedule in parallel nor stop the program reaching undeclared state. Parallel execution — it is why determinism and metering matter at all: the same code runs on many cores and many machines at once, and every one of those runs must reach the same result or the chain forks.
  3. Ordering is owned by Proof of History; this part assumes the transaction’s position in the sequence is already fixed. Consensus is owned by Consensus; this part assumes it produces state and lets consensus decide later whether that state is canonical. Networking is owned by the validator pipeline; this part assumes the transaction has already reached the leader and been scheduled. In short: the transaction has already arrived, already been ordered, and already been scheduled.
  4. If two validators running the same bytecode over the same accounts could get different answers, they would compute different state and the chain would fork — so the result must be a pure function of the declared inputs. The sandbox therefore has to make every non-deterministic input unreachable: wall-clock time, randomness, network or filesystem access, and any host-machine detail that could differ between validators. The only inputs a program sees are its declared accounts, its instruction data, and read-only sysvars every validator computes identically.
  5. Deciding in general whether an arbitrary program halts is undecidable (the halting problem), so Solana does not try — instead it charges every executed instruction a fixed number of compute units and caps the total budget, so execution must stop when the budget is exhausted, whether the program finished or not. Without this, a single program with an infinite loop (or merely a very long one) could occupy a validator indefinitely, stalling block production and denying the chain to everyone — the metering is what guarantees every transaction terminates.