Skip to content

DA Chunk Recovery & Block Reconstruction

Chunk recovery lets nodes reconstruct a full block when they only have the block hash and a subset of erasure-coded chunks. This is distinct from light client data availability sampling (DAS):

  • DAS samples chunks against the header’s data_availability_root.
  • Recovery reconstructs the full BlockEnvelope using a chunk commitment announced by peers.

Chunk recovery is used when a node misses a block body, when a peer needs to rehydrate archived data, or when a validator wants to validate full execution payloads without trusting a single peer.

Ashen uses two related commitments:

  • data_availability_root: stored in the block header and computed from the execution payload during block construction.
  • Chunk recovery commitment: computed from the full block envelope when the application actor erasure-encodes finalized blocks. This commitment is distributed via ChunkAnnounce messages and is used for reconstruction.

Do not assume these commitments are identical. DAS verifies payload availability; recovery verifies full block reconstruction.

  • BlockChunk: a Reed-Solomon shard (ReedSolomon<Blake3>).
  • CheckedBlockChunk: a shard that has passed commitment verification.
  • BlockChunkBundle: { commitment, chunks } produced by BlockChunkProducer::encode_block.
  • CodingConfig: minimum_shards + extra_shards define total shards. Recovery needs at least minimum_shards verified chunks.

Chunks are encoded for transport using encode_chunk and decoded with decode_chunk, which enforces a MAX_SHARD_SIZE bound (64 MB).

Network-level chunk gossip uses:

  • ChunkGossipMessage::Announce: advertises commitment + available indices.
  • ChunkGossipMessage::Request: asks for specific chunk indices.
  • ChunkGossipMessage::Response: returns (index, chunk_bytes) tuples.

Internally, the application actor exposes a control channel:

  • ChunkGossipCommand::Announce { block_hash, response }
  • ChunkGossipCommand::Chunk { block_hash, index, response }

The application actor only serves chunks from its in-memory pending_chunks cache (LRU, PENDING_CHUNKS_MAX_SIZE = 32) populated on finalized blocks. Recovery will fail if the target block has been evicted and no peers can serve the data.

The canonical path is ChunkRecoveryHandle::recover_block:

  1. Fetch announce: request ChunkAnnounce for the block hash.
  2. Validate totals: ensure announce.total_chunks matches minimum_shards + extra_shards.
  3. Fetch chunks: request chunks by index (0..total_chunks), skipping timeouts or invalid proofs.
  4. Verify each chunk: decode bytes and call BlockChunkVerifier::check_chunk.
  5. Reconstruct: once minimum_shards are verified, call BlockChunkVerifier::decode_block to rehydrate the block.

Recommended caller check:

  • Compute the recovered block hash and ensure it matches the requested block_hash.

Common failure cases:

  • Announce mismatch: peer claims a different total shard count than your local CodingConfig.
  • Insufficient chunks: fewer than minimum_shards verified shards were available.
  • Verification failures: chunk proofs do not match the commitment.
  • Timeouts: peers do not respond within the request timeout.
  • The dev/test default is 2-of-4 shards (minimum_shards=2, extra_shards=2).
  • Production target is 64-of-128 shards (minimum_shards=64, extra_shards=64).
  • Recovery requires local config to match the chunk producers. A mismatch guarantees AnnounceMismatch errors.
  • /concepts/data-availability/ for DAS background
  • /internals/flows/finalization/ for block finalization flow
  • src/data_availability.rs for recovery logic (ChunkRecoveryHandle, recover_block)