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

feat: support Peer ID represented as CID #105

Merged
merged 4 commits into from
Nov 4, 2019
Merged

Conversation

lidel
Copy link
Member

@lidel lidel commented Oct 25, 2019

Motivation

This PR implements Stage 1: Parse CIDs as peer ID from libp2p/specs#216.

TL;DR This PR does not change the default text representation of Peer IDs, all we do in Stage 1 is adding support for creating PeerId objects from CIDs.

For a wider context see libp2p/specs/RFC/0001-text-peerid-cid.md, short story is that CID support will enable IPFS project to support /ipns/{cid} in Base32 (https://github.com/ipfs/ipfs/issues/337), enabling things like http://{libp2p-key-as-cidv1b32}.ipns.dweb.link

Changes

This PR adds two functions:

  • createFromCID accepts CID as String|CID|Buffer and creates PeerId from the multihash value inside of it
  • toCIDString serializes PeerId multihash into a CIDv1 in Base32 (libp2p RFC 0001)

Next

cc https://github.com/ipfs/ipfs/issues/337, libp2p/specs#216, libp2p/specs#209, ipfs/kubo#5287

This change adds two functions:

- createFromCID accepts CID as String|CID|Buffer
  and creates PeerId from the multihash value inside of it
- toCIDString serializes PeerId multihash into a CIDv1 in Base32,
  as agreed in libp2p/specs#209

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
src/index.js Outdated Show resolved Hide resolved
src/index.js Outdated Show resolved Hide resolved
CIDv1 is self describing, and toString was not defined.
Makes sense to use generic toString in this case.

This change also:
- remembers string with CID, so it is lazily generated only once
- switches createFromB58String to createFromCID (b58 is CIDv0),
  making it easier to migrate existing codebases.

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
Copy link
Contributor

@jacobheun jacobheun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a minor request in the tests, but otherwise this looks good!

test/peer-id.spec.js Show resolved Hide resolved
Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of toJSON should change to encode the peer ID as a CID - right?

@@ -197,9 +207,18 @@ Returns the Peer ID's `id` as a buffer.
<Buffer 12 20 d6 24 39 98 f2 fc 56 34 3a d7 ed 03 42 ab 78 86 a4 eb 18 d7 36 f1 b6 7d 44 b3 7f cc 81 e0 f3 9f>
```


### `toString()`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I would add toCID and have toString as () => this.toCID().toString().

This creates a symmetric API createFromCID/toCID (although "create" is superfluous IMHO, but meh, maybe a refactor for another day) and a nice sensible representation as a string that also enables ${peerId} or peerID + '' without having to explicitly call toString.

Copy link
Member Author

@lidel lidel Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning: there is no toCID because there was not toMultihash :)
We want to keep API surface small, liberal in inputs (accept CID object), but strict in outputs (just basic types: PeerID, String and Buffer)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in keeping this in the context of this PR. We can iterate on this in a new PR if it justifies

@@ -122,6 +123,16 @@ class PeerId {
return this._idB58String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will now become rarely used. Should we generate on demand instead of in the constructor?

Copy link
Member Author

@lidel lidel Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in isPeerId and changing this triggers a bigger refactor.
I'd like to keep it as-is in this PR (to keep it small) and change it in Stage 2 of libp2p/specs#216
(when we "Format peer IDs as CIDs by default.")

toString () {
if (!this._idCIDString) {
const cid = new CID(1, 'libp2p-key', this.id, 'base32')
this._idCIDString = cid.toBaseEncodedString('base32')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you cache the CID instance you could use it in a toCID also. Note that CID's cache their string representation so calling toString on it won't re-encode.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above, we don't want to expose CID types in outputs, just Strings.

src/index.js Outdated Show resolved Hide resolved
src/index.js Outdated Show resolved Hide resolved
src/index.js Show resolved Hide resolved
src/index.js Outdated
} else {
// provide more meaningful error than the one in CID.validateCID
throw new Error('Supplied cid value is neither String|CID|Buffer')
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: validate the codec is libp2p-key or that it's a v0?

Copy link
Member Author

@lidel lidel Oct 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tricky.
We want people to be able to convert CIDv0→CIDv1 and be able to use it.

See scenario below:

  • Execute ipfs id
  • How to convert PeerID to CIDv1?
  • Caveat: conversion produces a valid CIDv1 with (now explicit) dag-pb multicodec
    • the multihash inside of CIDv1 still represents a valid PeerID, and this library does not care about the rest od CID anyway

I think the only way is to handle it gracefully is to check for both libp2p-key and dag-pb. Updated this PR to do just that + tests.

lidel added 2 commits October 28, 2019 18:43
License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
- require CID with 'libp2p-key' (CIDv1) or 'dag-pb' (CIDv0 converted to CIDv1)
- delegate CID validation to CID constructor

License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
Copy link
Member Author

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanshaw no, the implementation of toJSON should NOT change in Stage 1 (see libp2p/specs#216). In this PR we only add support for parsing CID here, but don't change current default representation (remains CIDv0).

I simplified createFromCID and applied some of your suggestions in 2b11192

@lidel lidel requested a review from alanshaw October 28, 2019 19:20
@lidel
Copy link
Member Author

lidel commented Nov 4, 2019

ping @vasco-santos

Copy link
Member

@vasco-santos vasco-santos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

@@ -197,9 +207,18 @@ Returns the Peer ID's `id` as a buffer.
<Buffer 12 20 d6 24 39 98 f2 fc 56 34 3a d7 ed 03 42 ab 78 86 a4 eb 18 d7 36 f1 b6 7d 44 b3 7f cc 81 e0 f3 9f>
```


### `toString()`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in keeping this in the context of this PR. We can iterate on this in a new PR if it justifies

@vasco-santos
Copy link
Member

@alanshaw any other feedback that you want to provide here? I think we can go with this

@vasco-santos vasco-santos merged commit 544ca7d into master Nov 4, 2019
@daviddias daviddias deleted the feat/cid-support branch November 4, 2019 18:50
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

Successfully merging this pull request may close these issues.

5 participants