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

Length Limit for CID/Multihash? #4918

Closed
kevina opened this issue Apr 3, 2018 · 23 comments
Closed

Length Limit for CID/Multihash? #4918

kevina opened this issue Apr 3, 2018 · 23 comments

Comments

@kevina
Copy link
Contributor

kevina commented Apr 3, 2018

Right now (and to my surprise) there doesn't seam to be any length limit. When identity hashes are used (see #4910) , an 18k file with hashed with the identity hash just works. I am even able to add that file to a directory entry with the files API and retrieve it.

$ ipfs add t0250-files-api.sh --hash=id -q > hash
$ ipfs cat `cat hash` > thefile
$ diff t0250-files-api.sh thefile 
$ ipfs files cp /ipfs/`cat hash` /tmp2
$ ipfs files ls
tmp
tmp2
$ ipfs files ls -l
tmp	z45btRgLsWtUjnxUC6eCo1EWfquee6nzwdLPDGyM7YAjiZHn6iArvVr546aaCXwsinDV7pLuzx3CfM7KiAXqf9CcqjjfVU9g4toFd9VE7VMASTrxDYWCzohasmJy1CbGhoArqQp5PyNPC6SBMYMqPQsGuUNXAtEBphybn9xRw3q9U7uyw77gMz3RzRSCo5D7nd6F3KcoQYuxD6NoGuqFuYoE2PHhZLksDd5StdH2a69WEWF2Y9RP1ZMZ5igg8XZH6DREV3h3	188
tmp2	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 and cat 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	19028
$ ipfs files read /tmp2 > thefile
$ diff  t0250-files-api.sh thefile # files the same
@kevina
Copy link
Contributor Author

kevina commented Apr 5, 2018

For now the wrapper blockstore enforces a limit of 64 bytes.

@ivan386
Copy link
Contributor

ivan386 commented Apr 5, 2018

Why need a limit?

@kevina
Copy link
Contributor Author

kevina commented Apr 5, 2018

Very large keys are likely to create a problem somewhere.

Right now the biggest problem is displaying them. I am not against allowing identity hashes of a few kbytes in directory entries as long as we do something about displaying them, one idea is to replace the key with something like <inlined>. This means the only way to access the context is via the directory entry as for all intents and purposes it doesn't have a hash.

@Stebalien
Copy link
Member

Yeah, the issue is for people.

@kevina
Copy link
Contributor Author

kevina commented Apr 6, 2018

BTW: the 64 byte (or 512 bits) limits comes from the fact that is the largest output size of modern cryptographic hash functions.

@kevina
Copy link
Contributor Author

kevina commented Apr 6, 2018

Another idea is to impose a length limit on the display of hashes that limit will be the size required to display a CID of a hash of of 64 bytes (which will vary depending on the multibase used) after that the length will be truncated with the a ... displayed at the end.

@ivan386
Copy link
Contributor

ivan386 commented Apr 7, 2018

We can use link index in block for display or get data/link.

[block cid]:1

We already have limits of block size. No need limits for it parts. If link not fit to this block limit then move it to sub block. If link not fit to block limit then error.

It can be used for micro tar files in dir block:
Tar header is 512 bytes + Tar Padding max 1535 bytes + link to file data 512 bits max.

@Stebalien
Copy link
Member

The issue here is that people need to use CIDs. That is, /ipfs/QmId... should always be reasonably short and the user shouldn't care if the CID is inline or not.

For unixfs2, we may want to consider inline files but that changes some of the semantics of ipfs (e.g., not all files will be directly addressable without indirecting through a directory).

@kevina
Copy link
Contributor Author

kevina commented Apr 10, 2018

@Stebalien if will allow long id-hashes we effectively allow inline files, you could access it via an a very long hash string, but no sane person will want to do that, so you effectively have to access via the directory entry. If we allow this the only issue is with display. I can think of two possibilities, we replace the hash with something like <inline>:

QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn 4    l/
<inline>                                       2048 afile

or we truncate long hashes

QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn 4    l/
z45fakeidhashvLxQVkXqqLX5R1X345qqfHbsf67hvA... 2048 afile

Where we determine some metric for the maxim length.

@mib-kd743naq
Copy link
Contributor

@ivan386 We already have limits of block size. No need limits for it parts.

1MB is way too large. See below.

you could access it via an a very long hash string, but no sane person will want to do that

They might want to in a pinch ( i.e. useful when the IPFS network is unavailable for some reason ). What we need to design for is ensuring that it is always possible.to do so.

The easiest hard limitation that comes to mind is: the URL length. GIven there is desire to move over to base32 encoding in the future, this translates to a max of:

2000 =
  ( maximum_data_length + 3_bytes_of_CID_prefix + 2_bytes_of_varint_size_under_16k)
    *
  log(256) / log(32)
   +
  ~25_bytes_to_hold_the _url_prefix_https://ipfs.io/ipfs/

2000 = ( maximum_data_length + 5 ) * 8/5 + 25

maximum_data_length = 1229

To allow larger leading URLs we should probably cap this at 1200

There is one more consideration: bookmarks could be capped at 260 characters on some browsers. If we take that as the basis ( should we? ) we get a maximum_data_length of only 141 bytes

@ivan386
Copy link
Contributor

ivan386 commented Apr 11, 2018

@mib-kd743naq

They might want to in a pinch ( i.e. useful when the IPFS network is unavailable for some reason ). What we need to design for is ensuring that it is always possible.to do so.

Pin underline block. Index of link in block migth be used to limit pin.

Data URI scheme is analog of identity hash in web.

Data protocol URL size limitations

@Stebalien
Copy link
Member

if will allow long id-hashes we effectively allow inline files, you could access it via an a very long hash string, but no sane person will want to do that, so you effectively have to access via the directory entry. If we allow this the only issue is with display.

So, for unixfs2, we actually don't need to use CIDs for this. Instead, we can just allow inline files:

{
    "file1": {
        ... // metadata
        data: Cid(...),
    },
    "file2": {
        ... // metadata,
       data: [bytes...],
    },
}

The primary motivation for inline CIDs is that it allows us to concisely point to inlined objects. If we can't do that (e.g., have a large, unwieldily CID), then there isn't much of a point in using CIDs.

@ivan386
Copy link
Contributor

ivan386 commented Apr 19, 2018

@Stebalien what about inline data in files in any place?

@kevina
Copy link
Contributor Author

kevina commented Apr 19, 2018

@Stebalien unixfs2 is not defined yet, and there is no clear consensus on what to include (that is unless I am missing something).

@kevina
Copy link
Contributor Author

kevina commented Apr 19, 2018

In particular I am not sure allowing inline files is such a good idea, at very least it requires careful though.

I am more included to allow larger identity hashes.

@Stebalien
Copy link
Member

CIDs need to remain usable in paths. I agree that we'd need to be careful about inline files (and I'm not even sure if should support them) but CIDs must remain usable by humans.

We need to focus on the motivations:

  • CIDs shouldn't be more than ~50% of the size of the file (max): Inline CIDs.
  • Transferring lots of small blocks is inefficient: Make it efficient (e.g., batch transfer).
  • Storing lots of small blocks is inefficient: Use a better datastore.

@mib-kd743naq
Copy link
Contributor

CIDs must remain usable by humans.

@Stebalien do you have thoughts on the ~140byte figure I derived in #4918 (comment) ?

@kevina
Copy link
Contributor Author

kevina commented Jun 2, 2018

This needs to be decided on, changing it later will create comparability problems. I would prefer to use a nice power of two size. Right now I am trying to decide between 64 and 128 bytes for the length of the hash component. If we continue to use 256 bit (=32 bytes) hashes than 64 satisfies the requirement "CIDs shouldn't be more than ~50% of the size of the file (max): Inline CIDs.". 128 bytes will be a bit more flexible, while it will create annoying long hashes they are still manageable, for example when part of the URL as described above.

@Stebalien @whyrusleeping @Kubuxu (others?) thoughts?

@Stebalien
Copy link
Member

One thing to remember is that we're talking about a cutoff, not a maximum. That is, we're not forbidding users from creating larger CIDs, we're saying that all files smaller than X will be embedded directly in the CID.

So, if we say 140 or even 128, we will generate a ton of 140/128 byte CIDs automatically. 128 looks like:

/ipfs/zDL1jdad4g2Dzzabm1PboDzAd9Xh5HBpk4B6vccGziRVW7KHXSZifGEjtNbB4DxmZnciQiyxrqGx3AoRgaKkVM7PsuKWMbrSHPQ21ARmPouAypAG2PYxdFWAMhrrSax3nKvz3aLxbmUAQWHYGWxtkTHLhVGqQZkX8Yxq2UBTzveQaczj

On the other hand, a 64 byte (base58 encoded) CID looks like:

/ipfs/z3QhWPA3C2ZgtVBGRP8SwU1eEu4on2fuPxv8y1WonNNqMr6kjQnLw78e311KBwqznkxJqwgFKRob3oq779Q5uXzZ5

Currently, a V1 CID looks like:

/ipfs/zb2rhgb5oHpycXA39nhQSknjAWW59r5TvcmLh8QAAd3mQAXgD


Honestly, even the 64 byte CID is a bit long. We may even want to consider 52 bytes as the resulting path (including the prefix) will fit in 78 bytes (under 80 characters):

/ipfs/zVvDErb6sZbLuCww5AxA4dy4a7Mro6ZGcvXxnAD8NiARgFWgQZnyxSP5tkrXRUqiCZUHFFgT

However, that doesn't give us much room to work with.

So, I'd say that 64 is a max, at the very least.

@kevina
Copy link
Contributor Author

kevina commented Jun 3, 2018

That is, we're not forbidding users from creating larger CIDs

Actually that was part of the plan, unless we create a special rule that says id hashes can not be longer then XX, but other CIDs could, which doesn't make sense to me.

We could just allow longer CIDs and just not use them by default as I don't think that will break anything, and now that I think about it might be the best way forward.

Also I want to be clear when I say 64 bytes, I mean a 64 byte digest length, the complete Cid with the prefix (including the multihash one) will likely be a bit longer.

If we do set a hard limit then 64 should be a absolute minimum in case someday we want to the the full 512 bits of some crypto. hashes.

Also note, if we really want to consider things such as display width (which I don't think is such a good idea), consider that we may switch to base 32, which is slightly longer.

I now see three options

  1. Don't set a hard limit on CID digest size, but by default id hashes will have a maxium digest length (and thus content length) of 64 bytes
  2. Set a hard limit of 128 bytes on digest length (to keep things from getting to out of hand, but also to not artificially limit our options) but limit id hashes to 64 bytes by default.
  3. Set a hard limit of 64 bytes on digest length and thus limit id hashes to this length

I am now leaning towards (1), and possible going with (2). (3) is an option but I don't see a technical reason to force CID length to this.

@ivan386
Copy link
Contributor

ivan386 commented Jun 3, 2018

It is important for me that the program can understand the identifier of any size. And don't discards blocks with them.

@Stebalien
Copy link
Member

I've moved this to the CID repo as it's a spec issue and we need to involve people out side of go.

@Stebalien
Copy link
Member

New issue: multiformats/cid#21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants