Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CARv1 "roots" array ambiguity #287

Open
Dodo-alone opened this issue Jun 28, 2023 · 1 comment
Open

CARv1 "roots" array ambiguity #287

Dodo-alone opened this issue Jun 28, 2023 · 1 comment
Assignees
Labels

Comments

@Dodo-alone
Copy link

Dodo-alone commented Jun 28, 2023

The CARv1 specification is ambiguous as to whether the roots array should be allowed to be empty

#### Constraints
* The `version` is always a value of `1`. Future iterations of this specification may make use of `version` to introduce variations of the format.
* The `roots` array must contain **one or more** CIDs, each of which should be present somewhere in the remainder of the CAR.

conflicts with

Regarding the `roots` property of the Header block:
* The current Go implementation assumes at least one CID when creating a CAR
* The current Go implementation requires at least one CID when reading a CAR
* The current JavaScript implementation allows for zero or more roots
* Current usage of the CAR format in Filecoin requires exactly one CID
It is unresolved how the `roots` array should be constrained. **It is recommended that only a single root CID be used in this version of the CAR format.**

Which definition on the spec is correct, and how should new CARv1 implementations handle decoding headers with empty roots arrays?

@rvagg
Copy link
Member

rvagg commented Jun 29, 2023

If you're developing a new implementation then allow empty roots. The spec needs to be updated and I plan on doing that in conjunction with an overhaul of the way go-car deals with this. The current situation is even more nuanced now than the second section mentions! Various uses of go-car/v2, which are now quite common (blockstore and storage in particular) are fine with empty roots and even produce empty root CARs themselves. I have an initial draft of a go-car/v3 that's a kind of unification of v0 and v2 codebases (i.e. trying to make a single codebase that does the whole lot, the v2 codebase was very specifically focused on CARv2 usage but I want something that's easy to work across both CARv1 and CARv2).

With a go-car/v3, I'll bring it up to compatibility with js-car, with empty roots being fine in all cases.

I don't think we'll go as far as making the roots field entirely optional, although that is a possibility (Edit: we probably won't do this, it would be a hard break for all existing code, but I was tempted with the idea!). For now, my approach is something like this:

  1. Read the header object, where version is mandatory
  2. Check version, if it's 2 then proceed to process the remainder as CARv2 (i.e. CARv2 has just length-prefixed {"version":2} CBOR at the front as a pragma).
  3. If it's anything other than 1, report that the version is unsupported.
  4. If it's version 1 then check whether the roots field is defined and error if it's not.
  5. Proceed parsing CARv1, with or without an empty roots array.

I'll work on getting this more explicitly into the spec as I work toward go-car/v3; my local code already does this very explicitly, and you can see it in the js-car implementation in the schema it uses to validate the header (the notes in there outline this strategy): https://github.com/ipld/js-car/blob/master/src/header.ipldsch, and you can see it play out here: https://github.com/ipld/js-car/blob/af655e05137facba8ecfa9ca728e35a47594fafe/src/decoder.js#L27-L50

@rvagg rvagg self-assigned this Jun 29, 2023
@rvagg rvagg added the P2 label Jun 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: 🥞 Todo
Development

No branches or pull requests

2 participants