Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

The ipfs.dag.import API #3910

Closed
matheus23 opened this issue Oct 5, 2021 · 4 comments · Fixed by #3911
Closed

The ipfs.dag.import API #3910

matheus23 opened this issue Oct 5, 2021 · 4 comments · Fixed by #3911
Labels
need/triage Needs initial labeling and prioritization

Comments

@matheus23
Copy link
Contributor

A couple of things I noticed from using the API:

  • the docs say it returns AsyncIterable<{ cid: CID, pinErrorMsg?: string }>, but it seems to actually be `AsyncIterable<{ root: { cid: CID, pinErrorMsg?: string } }>
  • the docs don't mention that this only iterates over the roots, not the blocks themselves.
  • it only returns roots when pinRoots: true is set in the options. I find this unexpected. Can't it return the roots even if it doesn't pin them?

I'm happy to provide a PR for that :)

@matheus23 matheus23 added the need/triage Needs initial labeling and prioritization label Oct 5, 2021
@rvagg
Copy link
Member

rvagg commented Oct 5, 2021

{root:{... is correct and should be fixed

Unfortunately you're correct that it will only return roots when pinning; there's additionally a new option that's making its way through the stack, starting with go-ipfs, to add a --stats option that will return additional data: ipfs/kubo#8237

It's possible that --stats could be amended such that if you provide that option that it returns the roots regardless of pin, it'd just need a clear way to differentiate between "was pinned" and "just reporting"

An alternative in JS is to just use the @ipld/car library directly to get this information. There's a few methods you can provide an AsyncIterable to which will give you the roots without forcing you to process the entire CAR. CarBlockIterator and CarCIDIterator will do this, as will CarIndexer. They should all have a getRoots() method on them when you start them with a fromIterable() and you can just discard it after that without it going through the rest of the CAR. Just don't use CarReader which will consume the whole lot.

There also may be scope to add a special inspectHeader() method of some kind in that library just for this case, where you provide it with an AsyncIterable that it'll consume just enough of to get the header for you. If that's going to be helpful for your use case then open an issue over there. It should be straightforward to add I think.

@matheus23
Copy link
Contributor Author

Thanks for the quick response @rvagg :)

I'll open a PR for the { root: { documentation issue & another docs issue with ipfs.block.put.


We were actually migrating away from @ipld/car (we were using it before there was the dag.import API).
The reason we were migrating was that it seemed really hard to use with the new ipfs.block.put API: It doesn't accept a cid parameter anymore (unlike what the docs suggest), and the format parameter has to be a string (it can't be a code number).
Since internally it converts this name into a code anyway, wouldn't it make sense to allow the parameter to be a code in the first place?

Only now I figured out that we could use (await ipfs.codec.getCodec(<code>)).name to go from IPLD name -> IPLD code, but that API isn't documented.

@rvagg
Copy link
Member

rvagg commented Oct 7, 2021

Oh, that's interesting. There's new work on the ipfs.dag.put API in go-ipfs (0.10) that may be of interest when it bubbles up through these JS interfaces that makes working with raw data a bit nicer. The block API is good, and efficient, but there's a lot ore flexibility in the DAG API now.
Using codec codes instead of strings is a good point though, since we de-prioritised those in the JS stack to save on having to have the whole table available. Maybe we should make it possible to use integers or strings where you supply codecs. I might go have that discussion over in go-ipfs as an extension of the DAG API changes.

Also, did you know that every codec in JS now has its code as well as name exposed? Since you'll have the ones you want (likely dag-cbor) then you could just hit them for the string:

> const dagCBOR = require('@ipld/dag-cbor')
undefined
> dagCBOR.code
113
> dagCBOR.name
'dag-cbor'
> dagCBOR
{
  code: 113,
  decode: [Function: decode],
  encode: [Function: encode],
  name: 'dag-cbor'
}

@matheus23
Copy link
Contributor Author

Also, did you know that every codec in JS now has its code as well as name exposed? Since you'll have the ones you want (likely dag-cbor) then you could just hit them for the string:

Yeah, that's true. In my use case the issue is that the only thing I have at hand is a CID, which only gives me the codec code, not the name.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
need/triage Needs initial labeling and prioritization
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants