an atproto pds written in F# (.NET 9) 馃
pds fsharp giraffe dotnet atproto
1# CAR Format Implementation Notes 2 3The **Content Addressable aRchives (CAR)** format is used to store content-addressable objects (IPLD blocks) as a sequence of bytes. 4It is the standard format for repository export (`sync.getRepo`) and block transfer (`sync.getBlocks`) in the AT Protocol. 5 6## 1. Format Overview (v1) 7 8A CAR file consists of a **Header** followed by a sequence of **Data** sections. 9 10```text 11|--------- Header --------| |--------------- Data Section 1 ---------------| |--------------- Data Section 2 ---------------| ... 12[ varint | DAG-CBOR block ] [ varint | CID bytes | Block Data bytes ] [ varint | CID bytes | Block Data bytes ] ... 13``` 14 15### LEB128 Varints 16 17All length prefixes in CAR are encoded as **unsigned LEB128 (UVarint)** integers. 18 19- Used to prefix the Header block. 20- Used to prefix each Data section. 21 22## 2. Header 23 24The header is a single DAG-CBOR encoded block describing the archive. 25 26**Encoding:** 27 281. Construct the CBOR map: `{ "version": 1, "roots": [<cid>, ...] }`. 292. Encode as DAG-CBOR bytes. 303. Prefix with the length of those bytes (as UVarint). 31 32## 3. Data Sections 33 34Following the header, the file contains a concatenated sequence of data sections. Each section represents one IPLD block. 35 36```text 37[ Section Length (UVarint) ] [ CID (raw bytes) ] [ Binary Data ] 38``` 39 40- **Section Length**: The total length of the *CID bytes* + *Binary Data*. 41- **CID**: The raw binary representation of the block's CID (usually CIDv1 + DAG-CBOR + SHA2-256). 42- **Binary Data**: The actual content of the block. 43 44The Section Length *includes* the length of the CID. 45 46This is slightly different from some other framing formats where length might only cover the payload. 47 48## 4. References 49 50- [IPLD CARv1 Specification](https://ipld.io/specs/transport/car/carv1/)