Skip to main content

Crate decdn_bao_range

Crate decdn_bao_range 

Source
Expand description

Bao verified-range helpers for deCDN: align a byte range to bao chunk groups, encode a verified range for the wire, and size that encoding.

deCDN streams every blob as bao’s interleaved verified encoding, so a receiver checks each chunk group against the blob’s BLAKE3 root as it lands (ADR 038 § Wire format). This crate holds the range arithmetic both sides share. It depends on bao-tree and not on iroh-blobs, so the client SDK and the decdn CLI link no blob store.

§Entry points

You want toUse
Snap a [offset, +len) request to whole chunk groupsalign_range, align_range_clamped, AlignedRange
Encode a verified range from raw bytes and an untrusted outboardencode_verified_range
Know how many wire bytes a range costs, proof includedbao_encoded_size, AlignedRange::wire_len
Encode a whole blob as a stream, without buffering itstreaming
Implement a range-aware blob backendRangedStore
Write or find a blob’s outboard in a filesystem originencode_outboard, OBAO4_SUFFIX, shard_prefix

§Verifying an origin range

An origin backend (S3, R2, B2, HTTP, or a filesystem) serves raw bytes by hash, with no bao tree. When the origin also stores the blob’s pre-order bao outboard at the sibling key {H}.obao4, a node fetches only the range [a, b) it wants and verifies it against the root H with that outboard (ADR 037 § Origin-tier pull-through). The result is the bao interleaved encoding, which the node imports as a verified partial blob.

The outboard needs no trust. Every leaf must hash to its parent, and the spine must combine to the root H the node asked for. A tampered range, a tampered outboard, or a wrong root fails with RangeVerifyError. The origin stays a plain byte store.

Re-exports§

pub use origin_seed::EncodedOutboard;
pub use origin_seed::OBAO4_SUFFIX;
pub use origin_seed::encode_outboard;
pub use origin_seed::shard_prefix;
pub use ranged_store::RangedFuture;
pub use ranged_store::RangedStore;
pub use ranged_store::RangedStoreError;

Modules§

origin_seed
Filesystem-origin layout contract and outboard seeding.
ranged_store
The (hash, total_bytes) blob view every range-aware backend implements.
streaming
Streaming, header-less whole-blob bao encoder (issue #1130’s stream-while- store seam): produces the same interleaved proof+data bytes as crate::encode_verified_range over ChunkRanges::all(), but reads a sequential std::io::Read source instead of requiring the whole blob already buffered in memory, and omits the 8-byte LE size header that helper prepends (the tee this feeds already carries the size out-of-band, in the signed StreamResponse).

Structs§

AlignedRange
The chunk-group-aligned byte span a node must fetch from origin to serve a requested [byte_offset, byte_offset + byte_len), plus the chunk ranges to import. A bao proof covers whole 16 KiB groups, so the fetch widens to the enclosing group boundaries (the extra bytes are paid origin egress but never re-served as client bytes — the request is still scoped, not whole-blob). Fields are private and the only constructor is align_range, so holding an AlignedRange guarantees its invariants: fetch_start <= fetch_end, both group-aligned (or fetch_end == blob_size for the final partial group), and chunk_ranges exactly covers [fetch_start, fetch_end).

Enums§

RangeVerifyError
Errors from preparing a verified origin range pull.

Constants§

CHUNK_GROUP_BYTES
Bytes per chunk group, derived from IROH_BLOCK_SIZE (2^chunk_log 1 KiB chunks) — the granularity an origin range must snap to, because a bao proof anchors whole chunk groups to the root.
IROH_BLOCK_SIZE
iroh-blobs’ canonical on-disk block size (16 KiB chunk groups, from_chunk_log(4)). Declared from the bao-tree primitive rather than re-exported from iroh-blobs, because this crate must stay iroh-blobs-free so the CLI’s pull path can link it. The value is identical by construction to iroh_blobs::store::IROH_BLOCK_SIZE (which is also BlockSize::from_chunk_log(4)); decdn-cache carries a lock-step test asserting the two stay equal, so a divergence across an iroh-blobs bump — which ADR 038 treats as a protocol-contract change — fails the build there.

Functions§

align_range
Compute the chunk-group-aligned fetch span for a [byte_offset, +byte_len) request against a blob_size-byte blob. byte_len == 0 means “to end”.
align_range_clamped
align_range, but an end past the blob clamps to the blob’s end instead of being refused: a claimed size is a hint, and the planner’s bound can overshoot it. Only byte_offset >= blob_size (for a non-empty blob) is refused, with RangeVerifyError::RangeOutOfBounds: a start past the end has no chunk group to anchor, clamped or not. (0, 0) means the whole blob, and the empty blob is addressable only as (0, 0), exactly as in align_range.
bao_encoded_size
Exact byte length of the header-less bao interleaved encoding a serving node emits for chunk_ranges of a total_bytes-byte blob — the sum of every proof node (64 bytes each) and data leaf (≤ chunk-group bytes) in response (pre-order) order (ADR 038 §Wire format).
encode_verified_range
Verify range_data (covering aligned.fetch_start..aligned.fetch_end) and the supplied pre-order outboard against the wanted root root, returning the bao interleaved encoding for aligned.chunk_ranges — ready for Blobs::import_bao_bytes(root, aligned.chunk_ranges, _).