Skip to main content
Storage nodes are the machines that physically hold the network’s data. A node is a staked committee member: it hosts spools of slices, follows the chain, votes in its groups, and proves it still holds its data, epoch after epoch (spool groups, challenges). Storage nodes aren’t public read infrastructure. They serve staked peers, which in practice means gateways, and end users never talk to them directly (gateways). That boundary shapes most of what follows.

A node’s job

  • Store and serve. Hold the slices for every spool assigned to it, and serve them to staked peers.
  • Follow the chain. Ingest Solana blocks and replay the network’s instructions to maintain local state. The same replay bootstraps a brand-new node from snapshot tapes (snapshots).
  • Vote. Sign group certifications, assignment votes, and snapshot votes with its BLS key (spool groups).
  • Prove. Answer challenge rounds, and report data that doesn’t match its on-chain commitments (challenges).
  • Repair. Rebuild lost slices from the group using fragment-based repair (slicing).
  • Sync. When spools change owners at an epoch boundary, transfer and recover them before serving begins, then attest sync on-chain. Rewards for the epoch unlock only after attestation (token economics).
  • Housekeep. Expired data is the nodes’ responsibility: a garbage-collection sweep (on a timer, and again at each epoch boundary) deletes an expired tape’s slices and reclaims the space, no central actor involved (tapes).

How a node accepts and refuses data

Two rules make node access safe to leave open where it matters:
  • Writes are self-authorizing. A node accepts a slice from anyone, because acceptance requires a Merkle proof against the track’s on-chain commitment. Unauthorized bytes can’t pass, so there’s nothing to gate.
  • Reads are stake-gated. Slice reads, index reads, and proofs are served only to mutually authenticated peers whose stake clears the network-voted threshold (why gateways stake).

Inside the node

The node is a single Rust service built on one rule: every capability is a feature, every feature is an isolated, supervised task, and everything between them is bounded.

Features

Each capability (chain ingestion, state management, spool transfer, snapshots, replay, garbage collection, the peer HTTP server) is its own feature: a named, long-lived service with a single job. Features communicate only through bounded channels and the local store, never by reaching into each other. Adding a capability means adding a feature, without touching the ones that already work.

Supervision

A supervisor owns every feature: it spawns them as named tasks on a bounded runtime, watches them, and shuts the node down in order if any feature stops unexpectedly. That’s deliberate. The node prefers a clean exit over limping along degraded, and it can afford to, because restarting is cheap: the node resumes exactly where it left off (see crash-consistent state, below).

Bounded by construction

Queues, fan-out channels, worker pools, and inbound requests all carry fixed caps with backpressure, and retries follow one shared policy. Under overload the node sheds work at the edges instead of accumulating it in the middle, so memory stays flat and behavior stays predictable.

Crash-consistent state

A single writer advances local state, and the sync cursor moves only after everything it covers is safely on disk. Chain forks roll back cleanly, because nothing is kept until finality. A node killed at any instant restarts and replays from its cursor, and bootstrapping a brand-new node uses the same replay path (snapshots).

Built to be tested

The node is generic over its store, its chain API, and its RPC. Production runs an embedded database against Solana; the test suite runs whole multi-node networks in a single process against an in-memory chain, exercising the same feature code end to end.
The node's internals: a supervisor overseeing features, chain ingestion feeding the single-writer store, bounded channels between features, and the peer-facing HTTP server, with external connections to Solana and staked peers.

A supervisor oversees the features. Chain ingestion feeds a single-writer store. Everything between is bounded.

Joining and earning

Membership is enforced by the open protocol: stake and join the committee. Stake changes apply over two epochs, in both directions. Assignment is stake-weighted, so more stake means more spools and more of each epoch’s reward pool. Earnings scale with challenge performance, and rewards unlock only after sync attestation. Failing the epoch’s random audit forfeits the epoch and slashes (token economics, challenges). Ready to run one? Start with storage node setup.