Build Your Own Solana Runtime in Rust
Earlier parts took a chain apart to see how it holds together: Bitcoin’s blocks are a hash chain that makes history expensive to rewrite, and the accounts-vs-UTXO split is really a question of where state lives. This part turns those ideas into working code. We are going to build a small Solana runtime — from an empty Rust crate — and let the throughline of the whole book drive every design choice: how do you build one global state machine that runs at hardware speed without falling apart?
The honest answer is that most chains don’t run at hardware speed. They run one transaction at a time. This part is about the handful of design bets Solana made to escape that ceiling, and the only way to really understand a bet is to make it yourself. So we build solmini: a self-contained crate that models the three ideas Solana’s throughput rests on, and nothing else.
Why build a runtime at all
Section titled “Why build a runtime at all”You can read that Solana “executes transactions in parallel” and nod along. But the moment you try to implement it, the hard question appears immediately: to run two transactions on two cores at once, you must know — before either runs — that they don’t touch the same state. Where does that knowledge come from? It cannot come from the code, because the code is what you are trying to run. It has to come from the transaction itself.
That single constraint — every transaction declares the state it will touch, up front — is the seed the entire runtime grows from. It forces the account model (state must live in named, external accounts so a transaction can point at them). It rewards Proof of History (a clock the whole network agrees on without waiting for messages). And it makes a parallel scheduler possible (declared footprints are exactly what a scheduler needs to spot conflicts). Building the runtime is how you feel that one constraint radiate outward into every component.
We build it the way the rest of these books build things: the simplest version that is still correct, with every simplification called out honestly, and a sequential baseline the fast path must match exactly.
What solmini is (and is not)
Section titled “What solmini is (and is not)”solmini lives at rust/solmini in this repo. It is a normal Rust library crate with a tiny demo binary. Its whole job is to make three ideas concrete and testable:
Transaction { program, accounts: [meta…], data } │ schedule() ── conflict-free batches ──► run each batch in parallel (rayon) │ │ accounts: HashMap<Pubkey, Account> ◄── commit writable accounts (on success)- Proof of History — a verifiable clock built from a sequential SHA-256 chain. Ordered by construction, cheap to verify, impossible to fake.
- Typed accounts + stateless programs — accounts are byte buffers with a balance and an owner; programs are pure code that mutates the accounts a transaction hands them. State lives outside the code.
- A Sealevel-style parallel scheduler — transactions declare their account footprint, and the scheduler runs non-conflicting ones across threads while serializing the rest.
Just as important is what solmini leaves out, so you always know where the map ends:
- No networking. There is one process, one in-memory account database. Nothing is gossiped, sent, or received.
- No consensus. We build the clock (PoH) but not the voting (Tower BFT) that turns one node’s clock into a network’s agreement. solmini is a single validator that never disagrees with itself.
- No real cryptographic signatures. Keys are SHA-256 of a label (
Pubkey::from_seed("alice")), not ed25519 keypairs. We model where signature checks would sit, not the ed25519 math. - No fees, rent, or compute metering beyond a knob that burns hashes to simulate per-transaction CPU cost so you can see the parallel speedup on a wall clock.
That is a lot of “no,” and it is deliberate. Strip away networking, consensus, and cryptography and what remains is the pure architectural core: an ordered clock, external state, and safe parallelism. Those three are the answer to the book’s question. Everything else a real validator does is defense of that core against an adversarial network — important, but a different part.
The minimal dependency surface
Section titled “The minimal dependency surface”A runtime you cannot read is a runtime you cannot learn from, so solmini’s dependency list is short enough to hold in your head:
[dependencies]sha2 = "0.10" # SHA-256, the single hash behind PoH and every Pubkeyserde = { version = "1", features = ["derive"] }serde_json = "1" # so accounts/entries can be inspected and snapshottedthiserror = "2" # ergonomic, typed runtime errors (SolError)rayon = "1" # the data-parallel engine the scheduler runs batches onFive crates. sha2 is the entire cryptographic story. rayon is the entire concurrency story — we never spawn a raw thread or reach for a lock, because, as you will see, a conflict-free batch is already safe to run in parallel and the type system proves it. Everything else in solmini is plain std.
The roadmap
Section titled “The roadmap”Read the pages in order. Each one adds exactly one component to the crate and is forced into existence by one idea. By the last page the pieces fit together into a runtime whose parallel output is identical to its sequential output — the proof that we smashed the throughput ceiling without breaking correctness.
| # | Page | Component it builds | Idea it forces |
|---|---|---|---|
| 2 | The Throughput Problem | (motivation — no code yet) | Serialized execution is a hard ceiling: one CPU, one transaction at a time |
| 3 | Proof of History | poh — Poh, Entry, verify | A clock everyone agrees on without exchanging messages, built from a hash chain |
| 4 | Accounts and Stateless Programs | account, program — Account, Pubkey, Program | State must live outside code so a transaction can name what it touches |
| 5 | The Account-Locks Scheduler | runtime::schedule, conflicts | Declared footprints let you batch non-conflicting transactions safely |
| 6 | Assembling the Runtime | Runtime — parallel run, commit, rollback | Parallel execution must produce the same state as sequential, or it is worthless |
| 900 | Part Revision | (recap) | The whole runtime, retold as one chain of consequences |
The thread
Section titled “The thread”The throughline of this book is a single question — how do you build one global state machine that runs at hardware speed without falling apart? — and this part answers it as a chain of forced moves, not a list of features.
To run at hardware speed you must use every core, which means running transactions in parallel. To run them in parallel safely you must know their state footprints in advance, which means state must live in named external accounts and programs must be stateless. To keep a global ordering without stopping to take a network-wide vote on timestamps, you need a clock that is a proof of elapsed time — Proof of History. And to make sure the fast parallel path never diverges from the truth, you keep an obvious sequential baseline and prove they agree. Each page is one link in that chain. Bitcoin’s hash chain reappears as PoH; the accounts-vs-UTXO distinction reappears as the account model; the throughput problem is what makes all of it necessary.
Check your understanding
Section titled “Check your understanding”- What single constraint does solmini place on every transaction, and why does the ability to run transactions in parallel depend on it?
- Name the three ideas solmini models and, for each, the crate module that implements it.
- solmini has “no consensus.” What does it build that lives in consensus’s neighborhood, and what is the difference between the two?
- Why does the crate keep a
run_sequentialpath when the whole point is parallel execution? - Restate the part’s driving question in your own words, and give the one-line chain of forced moves that connects “run at hardware speed” to “stateless programs + Proof of History.”
Show answers
- Every transaction must declare, up front, the accounts it will read and write (its footprint). Parallel execution needs to know before running two transactions whether they touch the same state; that knowledge can’t come from the code being run, so it must come from the declaration. No declared footprint, no safe scheduling.
- Proof of History → the
pohmodule (Poh,Entry,verify). Typed accounts + stateless programs → theaccountandprogrammodules (Account,Pubkey,Program). Parallel scheduling → theruntimemodule (schedule,conflicts,Runtime). - It builds Proof of History — a clock (a verifiable proof that time/work elapsed and events were ordered). Consensus is the voting (Tower BFT) that makes a whole network agree on which chain is canonical. solmini is a single validator that never disagrees with itself, so it needs the clock but not the vote.
- Because a parallel result is only trustworthy if it matches the obvious, one-at-a-time result. The sequential path is the correctness oracle: the integration tests run both and assert the final account state is identical, so any scheduling bug shows up as a divergence.
- How do you build one global state machine that runs at hardware speed without falling apart? The chain: hardware speed → use all cores → run transactions in parallel → need footprints known in advance → state must live in named external accounts (so programs are stateless), and global ordering without a network vote needs a clock you can prove elapsed → Proof of History.