pub fn bao_encoded_size(
total_bytes: u64,
chunk_ranges: &RangeSet<[ChunkNum; 2]>,
) -> u64Expand description
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).
This is the byte count that travels on cdn/client/v1: the wire carries the
response-format stream (no 8-byte size header — total_bytes is already the
signed StreamResponse field), so this excludes the header. It is computed
from the same BaoTree + ChunkRanges the serve-side encoder walks, so
it equals the emitted length byte-for-byte. The receiver uses it as the
voucher-cadence / overrun / short-delivery bound, because paid bytes are wire
bytes — content plus proof (ADR 038 §Payment metering) — not content
bytes. chunk_ranges should be the AlignedRange::chunk_ranges both sides
derive from align_range, keeping encoder and decoder in lock-step.
Cost: O(log groups) for the group-aligned contiguous range align_range
produces (a closed-form count over the tree’s shape, see
aligned_wire_size); every other range shape falls back to walking the
encoder’s node set, which is O(groups in range). The closed form is what
keeps a receiver’s wire bound cheap against a peer-claimed or ceiling-sized
total_bytes in the terabytes, where a walk would visit tens of millions of
groups before the first byte arrives.