Overview
The Ledger subsystem in Agave provides persistent, verifiable storage for the blockchain. It consists of the Blockstore (RocksDB-based storage) and the Shred system (data fragmentation and Reed-Solomon erasure coding). Together, they enable parallel verification of Proof of History, efficient disk storage, and network transmission of blockchain data.Architecture
Core Components
Blockstore (blockstore.rs:1-200): RocksDB-backed persistent storage for shreds, entries, transactions, and metadata.
Shred: Fundamental unit of ledger data transmission, designed to fit in network MTU (~1280 bytes).
ShredData (shred_data.rs): Contains actual ledger entries.
ShredCode (shred_code.rs): Erasure-coded redundancy for data recovery.
Shredder: Converts entries into shreds with FEC (Forward Error Correction).
Data Flow
Blockstore Structure
RocksDB Column Families
Fromblockstore.rs:1-105, Blockstore uses multiple column families:
- ShredData: Data shreds indexed by
(slot, shred_index) - ShredCode: Coding shreds for erasure coding
- SlotMeta: Metadata about slot completion and connectivity
- TransactionStatus: Transaction execution results
- Rewards: Reward distribution information
- TransactionMemos: Optional transaction memos
- TransactionStatusIndex: Index for transaction lookups
- AddressSignatures: Index of signatures by address
- ProgramCosts: Compute unit costs per program
- OptimisticSlots: Slots optimistically confirmed
Slot Metadata
Fromblockstore_meta.rs, SlotMeta tracks slot state:
consumed == last_index + 1- All shreds from 0 to
last_indexreceived DATA_COMPLETE_SHREDflag set on final shred
Persistent Storage Path
Blockstore is stored at configurable path:Shred Format
Data Shred Structure
Fromshred.rs:1-50, data shreds have three parts:
SIZE_OF_COMMON_SHRED_HEADER):
- Signature (64 bytes)
- Shred type (data vs coding)
- Slot number
- Shred index
- Version
- Parent offset
- Flags (DATA_COMPLETE_SHRED, LAST_SHRED_IN_SLOT)
- Size
SIZE_OF_DATA_SHRED_HEADERS)
Coding Shred Structure
Fromshred.rs:24-42:
num_data_shreds: Number of data shreds in FEC batchnum_coding_shreds: Number of coding shreds in batchposition: This coding shred’s position in batch
SIZE_OF_CODING_SHRED_HEADERS)
Shred Constraints
Fromshred.rs:104-127:
- 32:32 erasure coding: 32 data shreds + 32 coding shreds per batch
- Can recover from loss of any 32 shreds in a 64-shred batch
- Provides 50% redundancy for network resilience
Shred Flags
Fromshred.rs:144-150:
- SHRED_TICK_REFERENCE_MASK: Lower 6 bits for tick reference
- DATA_COMPLETE_SHRED: Marks shred completing an entry sequence
- LAST_SHRED_IN_SLOT: Final shred in slot (implies DATA_COMPLETE)
Shred Creation and Recovery
Shredder
TheShredder converts entries to shreds:
- Serialize Entries: Convert entries to byte stream
- Fragment: Split into shred-sized chunks (respecting MTU)
- Add Headers: Attach common and data headers
- FEC Encode: Generate coding shreds using Reed-Solomon
- Sign: Leader signs all shreds
Reed-Solomon Erasure Coding
Fromshredder.rs, erasure coding provides:
- Recovery: Reconstruct lost data shreds from coding shreds
- Efficiency: 50% overhead for 50% packet loss tolerance
- Parallel: Can verify shreds in parallel across slots
Deshredding
Recovering entries from shreds:- Collect Shreds: Gather shreds for slot from blockstore
- Verify Signatures: Check leader signature on each shred
- Check Completeness: Verify all shreds 0..last_index received
- Recover Missing: Use coding shreds to recover lost data shreds
- Deserialize: Extract entries from shred payloads
Blockstore Operations
Writing Shreds
Inserting shreds into blockstore:- Verify: Check signatures if not trusted
- Detect Duplicates: Check for conflicting shreds (possible slashing)
- Update Metadata: Update SlotMeta with new shred info
- Store: Write shred to ShredData or ShredCode column
- Check Completion: Determine if slot is now complete
- Signal: Notify replay stage if slot completed
Reading Shreds
Retrieving shreds for replay or repair:- By Slot: Get all shreds for a slot
- By Range: Get shreds in index range for a slot
- With Metadata: Include SlotMeta information
Slot Completion
Fromblockstore_meta.rs, a slot is complete when:
- Replay stage processes the slot
- Turbine retransmit stops for this slot
- Repair service adjusts strategy
Duplicate Detection
Fromblockstore.rs:138-161, duplicate shreds indicate Byzantine behavior:
Ledger Cleanup
BlockstoreCleanupService
Fromblockstore_cleanup_service.rs:1-150, automated cleanup:
- Count Live Shreds: Query RocksDB metadata for ShredData entries
- Check Threshold: If shred count exceeds
max_ledger_shreds - Calculate Target: Determine oldest slot to keep
- Purge FIFO: Delete oldest slots first
- Update Lowest Slot: Update blockstore’s lowest_slot marker
blockstore_cleanup_service.rs:25-36:
Purge Types
Fromblockstore_purge.rs, different purge strategies:
- PurgeType::Exact: Remove exact slot range
- PurgeType::CompactionFilter: Use RocksDB compaction for cleanup
Cleanup Timing
Fromblockstore_cleanup_service.rs:40-48:
- Latest root advanced by at least
DEFAULT_CLEANUP_SLOT_INTERVAL(512 slots) - Shred count exceeds threshold
Transaction Storage
TransactionStatus
Blockstore stores transaction execution results:- Status: Success or error details
- Fee: Transaction fee charged
- PreBalances/PostBalances: Account balances before/after
- Logs: Program log messages
- ComputeUnitsConsumed: CU usage
(Slot, Signature) for efficient lookup.
Address Signatures
Secondary index enabling queries like “show all transactions for address X”:- Column:
AddressSignatures - Key:
(Address, Slot, Signature) - Enables historical transaction lookup per address
Snapshot Integration
Snapshot Storage
Blockstore coordinates with snapshots:- Stores snapshot metadata in columns
- Tracks available snapshots via gossip (
SnapshotHashes) - Provides slot ranges for snapshot generation
Bank Forks Utilities
Frombank_forks_utils.rs, blockstore provides:
- Load bank from snapshots
- Replay slots on top of snapshot
- Verify continuity from snapshot to current root
Performance Optimizations
Parallel Verification
Fromblockstore.rs:1-4, design goal:
- Parallel signature verification across shreds
- Parallel FEC decoding across erasure batches
- Parallel slot replay (with dependencies)
RocksDB Configuration
Fromblockstore_options.rs:
- Compaction: Background compaction for space reclamation
- Compression: LZ4 compression for older data
- Block Cache: Configurable cache size for hot data
- Thread Pools: Separate flush and compaction threads
Shred Batching
Fromshred.rs:132-140, typical batch size:
Key Files
blockstore.rs:1-200- Main blockstore implementationshred.rs:1-200- Shred format and typesshredder.rs- Entry to shred conversionblockstore_cleanup_service.rs:1-150- Automated disk cleanupblockstore_meta.rs- SlotMeta and metadata structuresblockstore_db.rs- RocksDB wrapper and column definitions
Related Components
- Turbine: Receives shreds from network, writes to blockstore
- Replay Stage: Reads complete slots from blockstore for execution
- Repair Service: Requests missing shreds using blockstore gaps
- Snapshot Service: Generates snapshots from blockstore state