Revision: The Runtime & Programs
This part took the book’s throughline — how do you build a single global state machine that runs at hardware speed without falling apart? — and pointed it at the hardest sub-problem of the whole design: the runtime has to execute code it did not write, submitted by strangers, on thousands of machines at once, and every one of those machines must arrive at the exact same answer. If even one validator computes a different result, consensus fractures. The machine falls apart.
Everything in The Runtime & Programs (SBF) is one answer to that pressure, taken from a different angle. This page walks back through the chain so you can hold it as a single idea before you meet real programs. There is one word under all of it — determinism — and each mechanism is a different guardrail that keeps thousands of independent computers on the same track.
The chain of ideas, start to finish
Section titled “The chain of ideas, start to finish”Here is the whole part as a single pipeline. A program starts as bytecode, gets checked before it can ever run, executes inside a cage, pays for every step, calls other programs under a controlled identity, and reads the world through a fixed, shared window.
your program (Rust) │ compile to a restricted target ▼ SBF bytecode ─────────────────────► /runtime/sbf-bytecode-and-programs/ │ uploaded on-chain ▼ LOADER + VERIFIER ────────────────► /runtime/the-loader-and-verifier/ │ static checks pass? then it may run ▼ SANDBOX (syscalls only) ──────────► /runtime/syscalls-and-the-sandbox/ │ no OS, no clock, no network — just the accounts you declared ▼ COMPUTE-UNIT METER ───────────────► /runtime/compute-units-and-limits/ │ every instruction costs; run out of budget, you're stopped ▼ CPI + signed PDAs ────────────────► /runtime/cross-program-invocation-and-pdas/ │ compose with other programs; sign for addresses you control ▼ SYSVARS (Clock, Rent, …) ─────────► /runtime/sysvars-clock-and-rent/ the environment, delivered as ordinary accounts every validator sharesRead top to bottom, the same requirement shows up at every stage: make sure every validator does the identical thing. Let’s re-tell each link with that lens.
A program is SBF bytecode, not a source file
Section titled “A program is SBF bytecode, not a source file”We started at Programs as SBF Bytecode. A Solana program is not your Rust source and it is not a native binary the operating system runs. It is SBF — Solana Bytecode Format, a register-based instruction set descended from eBPF — a small, fixed vocabulary of operations the runtime interprets (or JIT-compiles) itself.
Why a bytecode at all? Because “run this code the same way on every machine” is impossible if the code is a native executable: it would see the host OS, the wall clock, the filesystem, the network — a thousand sources of divergence. Bytecode is a clean slate. The runtime, not the host, decides what each instruction means, so the same program produces the same effects on a validator in Frankfurt and one in Singapore. The account model from Accounts is the other half of this: the program holds no hidden state, so its behavior is a pure function of the bytecode plus the accounts handed in — exactly the process(accounts, data) shape the companion crate models.
// The whole Solana programming model in one signature. State lives in the// accounts; the program is pure code over them. (See rust/solmini/src/program.rs.)fn process(&self, accounts: &mut [Account], data: &[u8]) -> Result<()>;The loader verifies structure before the code can run
Section titled “The loader verifies structure before the code can run”Bytecode alone isn’t safe — a malformed or malicious program could try to jump to a garbage address, read memory it doesn’t own, or loop forever. So in The Loader and the Verifier, nothing runs until it passes a static verification step at load time: the verifier walks the bytecode and rejects anything with unbounded jumps, out-of-range memory access, bad instruction encodings, or a stack that could overflow.
This is the first place the book’s cross-chain comparison snaps into focus. Bitcoin forbids the dangerous constructs outright — no loops, hard size caps — so a script provably halts and every node can afford it. Ethereum prices them — the EVM allows loops but makes every step cost gas, converting the halting problem from a logic problem into an economic one. Solana does both, split across time: it verifies structure up front (like Bitcoin’s ban, but on shape rather than expressiveness) and then meters compute at runtime (like Ethereum’s gas). Up-front verification means the runtime pays the checking cost once, at deploy, instead of re-proving safety on every single execution.
The sandbox: a program can only touch what it was handed
Section titled “The sandbox: a program can only touch what it was handed”A verified program still must not be trusted with the machine. Syscalls and the Sandbox is the cage. Inside it, a program has no operating system, no threads, no files, no network, and — crucially — no clock of its own. The only way out is a small, fixed set of syscalls the runtime provides: log a message, hash some bytes, invoke another program, read a sysvar.
The reason is determinism again, stated as an absolute. Any capability that could return a different value on two different validators is forbidden. gettimeofday() would return different microseconds on each machine, so it does not exist; the time you’re allowed to see comes from the Clock sysvar, which is the same value for everyone in a slot. The program also cannot reach an account it did not declare — its whole universe is the account slice the transaction named, mirroring the “declare your footprint up front” rule from Sealevel that makes safe parallel execution possible in the first place.
Compute units: metering so no one program can stall the machine
Section titled “Compute units: metering so no one program can stall the machine”Verification proves the shape is safe, but a valid program can still be expensive, and an infinite loop is a perfectly valid shape. Compute Units and Limits is the runtime’s fuel gauge: every instruction and every syscall costs a number of compute units (CU), each transaction runs under a CU budget, and when the meter hits zero the transaction is halted and fails.
This is Solana’s version of gas — the halting problem made economic — but it meters a different currency than Ethereum. Gas is primarily about paying for state and computation; Solana’s CU budget is first about scheduling fairness: a fixed budget per transaction and per block is what lets the runtime pack a block full of work without any single transaction hogging a core. The comparison, one more time, in a line:
Bitcoin : forbid the dangerous constructs (no loops at all) Ethereum : price every step with gas (loops allowed, metered) Solana : verify structure up front, then (static check at load + meter compute at runtime CU budget per run)CPI and signed PDAs: composition without a login
Section titled “CPI and signed PDAs: composition without a login”Programs are only useful if they can call each other — a DEX calling the token program, an escrow calling the system program. Cross-Program Invocation and Signed PDAs is how one program invokes another and proves authority over accounts it owns.
The elegant piece is the Program Derived Address (PDA): an address deliberately derived to fall off the ed25519 curve, so no private key exists for it. A human could never sign for a PDA — but the owning program can, by presenting the seeds, and the runtime treats that as a valid signature during a CPI. That is how a program holds funds and authority with no key to steal: the authority is the code itself, invoked with the right seeds. Composition stays deterministic because a CPI is just another metered, sandboxed call — the callee runs under the same rules, spending from the same CU budget, touching only declared accounts.
Sysvars: the shared environment, delivered as accounts
Section titled “Sysvars: the shared environment, delivered as accounts”Finally, Sysvars: Clock, Rent, and Deterministic Globals closes the loop opened by the sandbox. A program needs to know something about the world — the current slot, the time, the rent rate — but it isn’t allowed to ask the host. So the runtime publishes that world as ordinary read-only sysvar accounts: Clock, Rent, EpochSchedule, and friends. The program reads them exactly the way it reads any account.
The trick is that a sysvar’s value is identical for every validator processing the same slot. Clock.unix_timestamp isn’t each machine’s local time; it’s a single agreed value baked into the slot. By turning “the environment” into shared, versioned accounts, Solana lets programs be time-aware and rent-aware while keeping every execution reproducible. The environment is data, and the data is the same everywhere — so the computation is the same everywhere.
The one requirement under all of it
Section titled “The one requirement under all of it”If you keep only one sentence from this part, keep this: every mechanism above exists so that thousands of validators, running the same code over the same accounts, compute the identical result and converge.
- Bytecode exists so the instructions mean the same thing everywhere.
- The loader/verifier exists so no program can break the machine before it even runs.
- The sandbox exists so a program can’t observe or touch anything that differs between machines.
- Compute metering exists so no program can run forever or starve the others.
- CPI and PDAs exist so composition and authority stay inside those same rules.
- Sysvars exist so the environment is shared data, not a per-machine reading.
Take any one away and determinism breaks somewhere: give a program a real clock and two validators disagree; drop the CU meter and one transaction hangs the chain; skip verification and a malformed jump corrupts a node. Determinism is not a feature bolted on top — it is the constraint that generates every mechanism in the part.
The trade-offs this part surfaced
Section titled “The trade-offs this part surfaced”None of this is free, and the book has been honest about the bill. The same choices that buy speed and safe parallelism ask more of the developer than a more permissive chain would.
- The sandbox is strict. No standard library conveniences, no ambient time, no reaching for an account you didn’t plan for. You program against a small syscall surface and think hard about what your instruction actually needs. That discipline is the price of reproducibility.
- Accounts must be declared up front. Every account a transaction will read or write is named before execution — the footprint rule from Sealevel. This is real friction: you must know your data layout in advance, and getting the account list wrong is a common early bug. In exchange, the scheduler can see which transactions can’t interfere without running them, and run the independent ones in parallel across cores — “shared XOR mutable,” lifted from variables to accounts.
- Verification and metering shift work onto you. Because the runtime checks structure once and meters every step, you own the job of staying inside the CU budget and writing code the verifier accepts. The chain’s throughput is partly your responsibility.
That is the deal Solana offers: accept a stricter, more explicit programming model, and in return get a runtime that can execute untrusted code at hardware speed, in parallel, without falling apart. The strictness is the speed.
Where this points next
Section titled “Where this points next”You now understand the raw runtime — the bare machine and its rules. That is exactly the ground you need to make sense of how real Solana programs are written, because every convenience in the ecosystem is a response to the frictions above.
When you meet Anchor in Programs, you’ll recognize it not as magic but as ergonomics layered directly on top of this part: its account-validation macros are how developers survive the up-front declaration rule; its account discriminators and Borsh (de)serialization are how typed state lives safely in raw account buffers; its CPI helpers wrap the signed-PDA dance you just saw; its errors and constraints are guardrails that keep you inside the sandbox and the CU budget. Anchor programs are shaped the way they are because the runtime is shaped the way it is. Nothing about Anchor will surprise you once you can see the runtime underneath it.
With the machine understood, the rest of the book is about building on it well.