From bc1a355e37354e277f5fa58261236668179601b4 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Sat, 26 Oct 2019 00:26:28 +0200 Subject: [PATCH 1/3] feat: support CIDs in /ipns/ content paths This adds support for resolving PeerIDs as CIDs in /ipns/ paths. See https://github.com/libp2p/specs/issues/216 for full context. License: MIT Signed-off-by: Marcin Rataj --- src/core/components/name.js | 4 ++-- src/core/ipns/resolver.js | 3 ++- test/core/name.spec.js | 11 +++++++++++ test/http-api/inject/name.js | 27 +++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/core/components/name.js b/src/core/components/name.js index 09dc5dc381..96614eda4d 100644 --- a/src/core/components/name.js +++ b/src/core/components/name.js @@ -6,7 +6,7 @@ const human = require('human-to-milliseconds') const crypto = require('libp2p-crypto') const errcode = require('err-code') const mergeOptions = require('merge-options') -const mh = require('multihashes') +const CID = require('cids') const isDomain = require('is-domain-name') const promisify = require('promisify-es6') @@ -155,7 +155,7 @@ module.exports = function name (self) { const [namespace, hash, ...remainder] = name.slice(1).split('/') try { - mh.fromB58String(hash) + new CID(hash) // eslint-disable-line no-new } catch (err) { // lets check if we have a domain ex. /ipns/ipfs.io and resolve with dns if (isDomain(hash)) { diff --git a/src/core/ipns/resolver.js b/src/core/ipns/resolver.js index 0970eecdfc..d830517a35 100644 --- a/src/core/ipns/resolver.js +++ b/src/core/ipns/resolver.js @@ -4,6 +4,7 @@ const ipns = require('ipns') const crypto = require('libp2p-crypto') const PeerId = require('peer-id') const errcode = require('err-code') +const CID = require('cids') const debug = require('debug') const log = debug('ipfs:ipns:resolver') @@ -74,7 +75,7 @@ class IpnsResolver { // resolve ipns entries from the provided routing async _resolveName (name) { - const peerId = PeerId.createFromB58String(name) + const peerId = PeerId.createFromBytes(new CID(name).multihash) // TODO: change to `PeerId.createFromCID` when https://github.com/libp2p/js-peer-id/pull/105 lands and js-ipfs switched to async peer-id lib const { routingKey } = ipns.getIdKeys(peerId.toBytes()) let record diff --git a/test/core/name.spec.js b/test/core/name.spec.js index edad61d17e..64e143d5e8 100644 --- a/test/core/name.spec.js +++ b/test/core/name.spec.js @@ -13,6 +13,7 @@ const ipnsRouting = require('../../src/core/ipns/routing/config') const OfflineDatastore = require('../../src/core/ipns/routing/offline-datastore') const PubsubDatastore = require('../../src/core/ipns/routing/pubsub-datastore') const { Key, Errors } = require('interface-datastore') +const CID = require('cids') const DaemonFactory = require('ipfsd-ctl') const df = DaemonFactory.create({ @@ -372,6 +373,16 @@ describe('name', function () { expect(value).to.exist() }) + + it('should resolve an ipns path with PeerID as CIDv1 in Base32 correctly', async function () { + const res = await node.add(fixture) + await node.name.publish(`/ipfs/${res[0].hash}`) + let peerCid = new CID(nodeId) + if (peerCid.version === 0) peerCid = peerCid.toV1() // future-proofing + const value = await ipnsPath.resolvePath(node, `/ipns/${peerCid.toString('base32')}`) + + expect(value).to.exist() + }) }) describe('ipns.routing', function () { diff --git a/test/http-api/inject/name.js b/test/http-api/inject/name.js index 3fe7f2564c..db53423a5a 100644 --- a/test/http-api/inject/name.js +++ b/test/http-api/inject/name.js @@ -2,6 +2,7 @@ /* eslint-env mocha */ 'use strict' +const CID = require('cids') const { expect } = require('interface-ipfs-core/src/utils/mocha') const checkAll = (bits) => string => bits.every(bit => string.includes(bit)) @@ -45,5 +46,31 @@ module.exports = (http) => { expect(res).to.exist() expect(res.result.Path).to.satisfy(checkAll([`/ipfs/${cid}`])) }) + + it('should publish and resolve a record with explicit CIDv1 in Base32', async function () { + this.timeout(160 * 1000) + + // ensure PeerID is represented as CIDv1 in Base32 + const { id } = await http.api._ipfs.id() + let cidv1 = new CID(id) + if (cidv1.version === 0) cidv1 = cidv1.toV1() // future-proofing + const peerIdAsCidv1b32 = cidv1.toString('base32') + + let res = await api.inject({ + method: 'GET', + url: `/api/v0/name/publish?arg=${cid}&resolve=false` + }) + + expect(res).to.exist() + expect(res.result.Value).to.equal(`/ipfs/${cid}`) + + res = await api.inject({ + method: 'GET', + url: `/api/v0/name/resolve?arg=${peerIdAsCidv1b32}` + }) + + expect(res).to.exist() + expect(res.result.Path).to.satisfy(checkAll([`/ipfs/${cid}`])) + }) }) } From 71f31a0b0956ff548447e4ef9b02ac9ddf4e4d99 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 6 Nov 2019 09:16:57 +0000 Subject: [PATCH 2/3] chore: update interface-ipfs-core dep License: MIT Signed-off-by: Alan Shaw --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b04b66c7c..d20e0eb11c 100644 --- a/package.json +++ b/package.json @@ -204,7 +204,7 @@ "execa": "^3.0.0", "form-data": "^2.5.1", "hat": "0.0.3", - "interface-ipfs-core": "^0.117.2", + "interface-ipfs-core": "github:ipfs/interface-js-ipfs-core#feat/peerid-as-cid", "ipfs-interop": "^0.1.1", "ipfsd-ctl": "^0.47.2", "libp2p-websocket-star": "~0.10.2", From 7f74ebf4eba64c5aa2805051a1cc13df6a3e9b56 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 6 Nov 2019 12:17:19 +0000 Subject: [PATCH 3/3] chore: update interface-ipfs-core dep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d20e0eb11c..5f347b36a9 100644 --- a/package.json +++ b/package.json @@ -204,7 +204,7 @@ "execa": "^3.0.0", "form-data": "^2.5.1", "hat": "0.0.3", - "interface-ipfs-core": "github:ipfs/interface-js-ipfs-core#feat/peerid-as-cid", + "interface-ipfs-core": "^0.118.0", "ipfs-interop": "^0.1.1", "ipfsd-ctl": "^0.47.2", "libp2p-websocket-star": "~0.10.2",