The TVU: Validating on the Receiving Side
The previous page followed a block out of the leader: split into shreds, fanned across the cluster through Turbine’s tree. This page picks the block up on the other end. Those shreds land at some validator’s network card. What does that validator do with them?
That validator is not the leader. It is doing the other of the two jobs every node alternates between: following. And following is not passive. A follower does not trust the block it received — it re-derives it. It reassembles the shreds into a block, checks the leader’s Proof of History is honest, and then re-executes every transaction against its own copy of the accounts to confirm it reaches the identical resulting state. Only then does it vote. This page builds the pipeline that does all of that: the TVU, the Transaction Validation Unit.
The TVU is the mirror image of the TPU
Section titled “The TVU is the mirror image of the TPU”Hold the TPU in mind — the leader’s producing pipeline: fetch packets, verify signatures, bank (order with PoH + execute with Sealevel), broadcast. The TVU is the same idea run backwards. It is the consuming pipeline, the one a validator runs when it is not the leader, which is almost all the time — one leader serves each ~400 ms slot, so for the overwhelming majority of slots your node is a follower feeding its TVU.
TPU (you are the leader — producing) TVU (you are a follower — validating) ───────────────────────────────────── ────────────────────────────────────── fetch packets shred fetch ◄── from Turbine sigverify retransmit ──► to your children banking: PoH order + Sealevel execute reassemble + verify PoH broadcast (shreds) ──► Turbine replay: re-execute the transactions vote ──► to consensusThe symmetry is exact and worth saying out loud: the leader builds an ordered, executed block and hashes it into PoH; every follower rebuilds that same block and re-runs it to check the leader did honest work. The TPU emits shreds; Turbine carries them; the TVU consumes them. Nothing in the block is taken on faith. The leader’s claim “here is the state after slot N” is a claim every follower independently reproduces or rejects.
Why bother re-doing work the leader already did? Because this is a trustless system. The leader is one staked validator with the temporary, exclusive right to order transactions for its slot — but no right to lie about the result. If followers accepted the leader’s claimed post-state without checking, a dishonest leader could mint itself lamports or ignore a transaction, and the network would have no defense. Replay is the defense: the answer is only accepted because thousands of independent machines re-computed it and agreed.
The stages, one at a time
Section titled “The stages, one at a time”1. Shred fetch — catch the pieces
Section titled “1. Shred fetch — catch the pieces”The front of the TVU is a receiver bound to the validator’s TVU port. Turbine delivers shreds — the small, erasure-coded fragments of the block from the previous page — over UDP, out of order, some possibly missing. The fetch stage pulls them off the socket as fast as the kernel hands them up, exactly as the TPU’s fetch stage pulls transaction packets. This stage exists for the same reason the TPU’s does: the network card must never be the bottleneck, so a dedicated stage does nothing but drain the socket into an internal channel.
Received shreds are written into the blockstore (Solana’s local ledger database, historically built on RocksDB), keyed by slot and index. The blockstore is where partial blocks accumulate until enough shreds have arrived to reconstruct them.
2. Retransmit — pay Turbine forward
Section titled “2. Retransmit — pay Turbine forward”Here is the stage with no TPU counterpart, and it is the reason Turbine works at all. Recall from the Turbine page that the leader does not send the block to everyone — it sends to a small set of nodes, and each of those forwards to its children in the broadcast tree. Your validator is a node in that tree. So the instant you receive a shred, you also retransmit it to the nodes below you.
leader │ (shreds) ┌──────┴──────┐ you peer ◄── layer 1 (retransmit) (retransmit) ┌───┴───┐ ┌───┴───┐ c1 c2 c3 c4 ◄── your / their childrenThis is a cooperative obligation, not an optimization. If followers only consumed shreds and never forwarded them, the tree would collapse into the star topology Turbine was invented to avoid, and the leader’s uplink would melt. Every honest validator’s TVU carries its slice of the propagation load. Retransmit is validated bandwidth being repaid to the cluster.
3. Reassemble and verify against PoH — is this a real block?
Section titled “3. Reassemble and verify against PoH — is this a real block?”Once the blockstore holds enough shreds for a slot — including, thanks to erasure coding, enough to recover a few that never arrived — the block can be reassembled into its sequence of PoH entries: the ordered list of ticks and transaction batches the leader recorded.
Before executing a single transaction, the follower checks the block is structurally honest by replaying its PoH chain. Recall the core PoH asymmetry: the chain is sequential to build but embarrassingly parallel to verify, because each entry pins its own ending hash. The follower recomputes the hashes between entries and confirms each recorded hash matches. This is the same verify your companion runtime implements:
/// Replay a chain of `entries` from `start` and confirm every recorded hash is/// correct. Returns `false` at the first mismatch. (from solmini::poh)pub fn verify(start: Hash, entries: &[Entry]) -> bool { let mut cur = start; for e in entries { match e.mixin { None => { for _ in 0..e.num_hashes { cur = hash_once(&cur); } } Some(mix) => { for _ in 0..e.num_hashes - 1 { cur = hash_once(&cur); } cur = hash_with(&cur, &mix); // fold the transaction batch in } } if cur != e.hash { return false; } // tampering or reordering caught here } true}If PoH verifies, the follower has proof of two things it needs before replay: the transactions are in the order the leader committed to (order is established by construction — you cannot reorder entries without breaking the chain), and no entry was tampered with in flight. A block whose PoH does not verify is discarded before a single transaction runs. Cheap check first, expensive check second.
4. Replay — re-execute and reproduce the exact state
Section titled “4. Replay — re-execute and reproduce the exact state”This is the heart of the TVU, and the whole point of running a validator at all.
Replay means: take the block’s transactions, in the PoH-fixed order, and re-execute them against your own copy of the accounts — the same accounts database, the same programs, the same rules the leader used. If the leader was honest, your resulting state will be byte-for-byte identical to the leader’s. If any account balance, any program’s data, any hash of the whole account set differs, the leader is lying (or you have a bug), and you reject the block.
Concretely, the follower runs each transaction exactly as the leader’s banking stage did, applying every write to its private copy of the accounts and comparing the outcome. In your companion runtime, one transaction against a working set is just:
// Pull the transaction's DECLARED accounts, run the program against them,// and commit the writable ones only on success. (adapted from solmini::runtime)let mut working = self.working_set(tx); // this validator's own copylet result = Self::run_tx(&self.programs, self.compute_per_tx, tx, &mut working);if result.is_ok() { self.commit(tx, &working); // apply writes locally}The follower is doing the same execution the leader did, on its own machine, from its own account state. The leader added transactions to state to produce the block; the follower re-applies them to reproduce it. Same function, opposite intent.
Why replay can go as fast as production: the same determinism
Section titled “Why replay can go as fast as production: the same determinism”Replay would be hopeless if re-executing a block were slower than producing it — the follower would fall permanently behind the leader. It is not, and the reason is the single most important connection in this page.
Recall the account model and Sealevel: every transaction declares up front the accounts it reads and writes. That declaration is what let the leader parallelize — group non-conflicting transactions into batches and run them across cores. But that declaration is stamped into the block. It travels with the transaction. So the follower has the exact same information and can schedule the exact same batches:
The leader saw: The follower sees (same declarations): ───────────────── ────────────────────────────────────── tx footprints → conflict graph tx footprints → SAME conflict graph → conflict-free batches → SAME conflict-free batches → run in parallel, produce state → run in parallel, REPRODUCE stateThis is why Solana’s determinism is load-bearing on both sides of the pipeline. The conflict rule — two transactions conflict when they share an account and at least one writes it — is not a leader-only trick. Because the rule is a pure function of the declared footprints, every validator applying it to the same transactions computes the same batches, runs them in any core assignment, and lands on the same final state. Execution order within a conflict-free batch does not matter; that is the whole guarantee the scheduler buys. So replay parallelizes exactly as production did, and a follower on comparable hardware keeps pace with the leader.
Say the guarantee precisely: the same account declarations that let the leader run transactions in parallel let every follower replay them in parallel and independently agree on the result. Determinism is what makes a distributed state machine possible at all — thousands of machines, no shared memory, all arriving at one answer because they all ran the same inputs through the same rules.
Under the hood — determinism is not automatic
Section titled “Under the hood — determinism is not automatic”For replay to reproduce the leader’s state bit-for-bit, execution must be deterministic to the bit. That is a design constraint threaded through the entire runtime, not a happy accident:
- No wall-clock time, no randomness in programs. A program that read the OS clock or a random number would compute differently on every validator, and replay would never match. Programs get time only through the deterministic
Clocksysvar — the same value for everyone replaying that slot. - Bounded, metered compute. Every transaction runs under a compute-unit budget. A transaction either finishes within budget or is deterministically aborted at the same point on every machine — no “it depends how fast your CPU is” divergence.
- Fixed floating-point and serialization rules. Account data is laid out and hashed by rules identical on every node, so “the same state” is a hash every validator can compute and compare.
Determinism is engineered. Strip any of these guarantees and replay stops being a check, because two honest validators could reach two different answers for the same block.
From successful replay to a vote
Section titled “From successful replay to a vote”If PoH verified and replay reproduced the expected state, the follower has convinced itself the block is valid. Its final TVU stage is to vote for it.
A vote is itself a transaction — the validator signs a message saying “I have replayed slot N and I accept it,” and submits it to be included in a future block. Votes are how independent replays turn into collective agreement: when validators holding a supermajority of stake have voted for a block, the cluster treats it as agreed. The fork-choice rule then follows the branch carrying the most stake-weighted votes.
your TVU: shreds → verify PoH → replay → vote(slot N) ─┐ peer TVU: shreds → verify PoH → replay → vote(slot N) ─┤ peer TVU: shreds → verify PoH → replay → vote(slot N) ─┼─► supermajority ... ─┤ of stake ⇒ peer TVU: shreds → verify PoH → replay → vote(slot N) ─┘ block agreedThis is the seam where the pipeline hands off to consensus, and we will stop right at it — Tower BFT and its exponential lockouts, stake-weighted voting, and optimistic confirmation vs finality are the Consensus part’s job, not this one. The pipeline’s contribution is complete the moment the vote leaves: the TVU has taken shreds off the wire, proven the block is a real, honest, correctly-executed extension of the ledger, and emitted a stake-weighted opinion. Consensus is what aggregates those opinions into a single agreed chain.
The loop closes here. A transaction left a wallet, was forwarded by Gulf Stream to the upcoming leader, ordered and executed in that leader’s TPU, broadcast as shreds through Turbine, and here — in every other validator’s TVU — reassembled, verified, replayed, and voted on. That is the full pipeline: one firehose of transactions in, one agreed-upon block out, at hardware speed.
The architect’s lens
Section titled “The architect’s lens”- Why does it exist? Because a block is a claim — “here is the state after slot N” — and in a trustless system a claim from one staked leader is worth nothing until other machines independently reproduce it. The TVU is the pipeline that turns “the leader says so” into “thousands of us re-ran it and agree.”
- What problem does it solve? It lets every non-leader validator receive, verify, and replay a block fast enough to vote within the ~400 ms slot — catching a dishonest or buggy leader by reproducing the exact resulting state, or rejecting the block if it cannot.
- What are the trade-offs? Replay re-does the leader’s execution on every validator, so the network pays for one block’s compute thousands of times over. Solana accepts that redundancy as the price of trustlessness, and makes it affordable by reusing the leader’s parallelism: the same declared footprints let followers replay in parallel too.
- When should I avoid it? You never remove replay from a validator — it is validation. The only “avoid” is architectural: replay’s per-slot deadline is why Solana refuses features that make execution non-deterministic or unboundedly slow (arbitrary wall-clock reads, unmetered compute); those would break replay’s ability to keep pace and agree.
- What breaks if I remove it? Trustlessness. Without replay, followers would accept the leader’s claimed post-state on faith, and a single dishonest leader could rewrite balances or censor transactions with no one re-checking. Consensus would be voting on unverified claims — the state machine would no longer be verified, just asserted.
Check your understanding
Section titled “Check your understanding”- The TVU is described as the “mirror image” of the TPU. Name the corresponding stage in each pipeline for: receiving from the network, the ordering/execution step, and the network output — and say which direction data flows in each.
- The retransmit stage has no counterpart in the TPU. What does it do, and what would happen to Turbine’s tree if followers skipped it?
- A follower verifies PoH before it replays transactions. Why do the cheap PoH check first? What two things does a passing PoH check prove about the block?
- Explain, using the account model, why a follower can replay a block in parallel rather than as a serial loop — and why that is essential given the slot deadline.
- Successful replay ends in a vote. In one sentence, describe how independent replays across many validators become collective agreement, and name where the pipeline hands off to consensus.
Show answers
- Receiving: the TPU’s fetch stage takes transaction packets in; the TVU’s shred fetch stage takes shreds in — both are ingress. Ordering/execution: the TPU’s banking stage orders (PoH) and executes (Sealevel) to produce state; the TVU’s replay stage re-executes in the fixed order to reproduce state. Network output: the TPU broadcasts shreds out via Turbine; the TVU emits a vote out to consensus. The TPU flows transactions in and a block out; the TVU flows shreds in and a vote out.
- Retransmit forwards each received shred to the node’s children in the Turbine broadcast tree. If followers consumed shreds but never forwarded them, the tree would collapse to a star — the leader alone sending to everyone — and its uplink bandwidth would be overwhelmed, which is exactly the failure Turbine’s tree exists to avoid. Retransmit is a cooperative obligation, not an optimization.
- PoH verification is cheap (recompute hashes, comparable to but far lighter than executing programs) and is embarrassingly parallel because each entry pins its own ending hash, so you do it first and discard bad blocks before paying for execution. A passing PoH check proves (a) the transactions are in the exact order the leader committed to — order is established by construction, so nothing was reordered — and (b) no entry was tampered with in flight.
- Every transaction declares its account footprint up front, and that declaration travels inside the block. So the follower has the same footprints the leader had, applies the same conflict rule (share an account, at least one writes ⇒ conflict), and derives the same conflict-free batches — which it can then run across cores. This is essential because replay must finish inside the ~400 ms slot; a serial loop would fall behind, and a validator that falls behind stops being able to vote in time.
- Each validator that replays a block successfully signs and submits a vote for that slot; when validators holding a supermajority of stake have voted, the cluster treats the block as agreed and fork choice follows the most-voted branch. The pipeline hands off to consensus exactly at the vote — Tower BFT, stake-weighted voting, and finality live in the Consensus part, not the pipeline.