1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Filesystem-origin layout contract and outboard seeding.
//!
//! A filesystem cache origin stores each blob as a sharded data object
//! `{base}/{hex[0..2]}/{hex}` with a sibling pre-order bao outboard
//! `{base}/{hex[0..2]}/{hex}.obao4`
//! ([ADR 037 §Origin-tier pull-through](../../../adr/037-regional-proxy-warming.md)).
//! The reader side lives in `decdn-cache` (`origin::fs` / `origin::s3`); the
//! writer side is `decdn origin import`. Both derive the sibling key and the
//! outboard bytes from this module, so a blob written here is one the daemon
//! reads back verbatim.
//!
//! The outboard is a `bao-tree` pre-order outboard at [`crate::IROH_BLOCK_SIZE`]
//! (16 KiB chunk groups). A stock `bao encode --outboard` uses a different chunk
//! group size and produces a file the daemon rejects, so the outboard **cannot**
//! be produced by generic shell tooling — it must come from this shared encoder.
use Read;
use PreOrderOutboard;
use CreateOutboard;
use crateIROH_BLOCK_SIZE;
/// Sibling-key suffix for the published pre-order bao outboard (`{H}.obao4`),
/// per [ADR 037 §Origin-tier pull-through](../../../adr/037-regional-proxy-warming.md).
/// Shared across the filesystem / S3 reader adapters and the `origin import`
/// writer so an operator `aws s3 sync`-ing between backends keeps the same
/// object names.
pub const OBAO4_SUFFIX: &str = ".obao4";
/// The two-character shard prefix for a blob's lowercase-hex address:
/// `{base}/{hex[0..2]}/{hex}`. The first two hex chars shard the directory so a
/// content set with millions of entries doesn't land in a single dirent list.
///
/// Panic-free: a `hex` shorter than two chars (never produced by a real BLAKE3
/// address, but the workspace's anti-indexing lint forbids `&hex[..2]`) yields
/// the empty prefix rather than panicking.
/// A blob's content address plus its pre-order bao outboard, ready to write to a
/// filesystem origin as the sharded data object and its `{hex}.obao4` sibling.
/// Stream `reader` (exactly `size` bytes) once, computing the BLAKE3 root hash
/// and the pre-order bao outboard at [`crate::IROH_BLOCK_SIZE`] in a single
/// pass. `size` must equal the number of bytes `reader` yields — it frames the
/// bao tree, and a wrong value produces an outboard the reader rejects.
///
/// The source bytes are **not** buffered in memory; only the outboard (roughly
/// `1/256` of the blob at 16 KiB groups) is retained, so a multi-gigabyte blob
/// costs a few megabytes of RAM here rather than its whole length.
// tests