From 23be7264987eb9a7046db44d1bcb35a3b5f045b0 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Wed, 2 Jun 2021 09:58:39 +0100 Subject: [PATCH 1/4] chore: update to new multiformats Replaces cids and multibase with the new multiformats module. BREAKING CHANGE: uses the CID class from the new multiformats module --- package.json | 3 +-- src/convert.js | 24 +++++++++++++++++++----- src/index.js | 4 ++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 8784aebf..b7bbf1ad 100644 --- a/package.json +++ b/package.json @@ -34,11 +34,10 @@ "./src/resolvers/dns.js": "./src/resolvers/dns.browser.js" }, "dependencies": { - "cids": "^1.0.0", "dns-over-http-resolver": "^1.0.0", "err-code": "^3.0.1", "is-ip": "^3.1.0", - "multibase": "^4.0.2", + "multiformats": "^9.0.2", "uint8arrays": "^2.1.3", "varint": "^6.0.0" }, diff --git a/src/convert.js b/src/convert.js index 4ffa0b10..8d98c99c 100644 --- a/src/convert.js +++ b/src/convert.js @@ -2,8 +2,8 @@ const ip = require('./ip') const protocols = require('./protocols-table') -const CID = require('cids') -const multibase = require('multibase') +const { CID } = require('multiformats/cid') +const { base32 } = require('multiformats/bases/base32') const varint = require('varint') const uint8ArrayToString = require('uint8arrays/to-string') const uint8ArrayFromString = require('uint8arrays/from-string') @@ -163,8 +163,22 @@ function bytes2str (buf) { * @param {string | Uint8Array | CID} hash */ function mh2bytes (hash) { + let cid + + if (typeof hash === 'string') { + cid = CID.parse(hash) + } else if (hash instanceof Uint8Array) { + cid = CID.decode(hash) + } else { + cid = CID.asCID(cid) + } + + if (!cid) { + throw new Error('Invalid CID') + } + // the address is a varint prefixed multihash string representation - const mh = new CID(hash).multihash + const mh = cid.multihash.bytes const size = Uint8Array.from(varint.encode(mh.length)) return uint8ArrayConcat([size, mh], size.length + mh.length) } @@ -199,7 +213,7 @@ function onion2bytes (str) { } // onion addresses do not include the multibase prefix, add it before decoding - const buf = multibase.decode('b' + addr[0]) + const buf = base32.decode('b' + addr[0]) // onion port number const port = parseInt(addr[1], 10) @@ -222,7 +236,7 @@ function onion32bytes (str) { throw new Error('failed to parse onion addr: ' + addr[0] + ' not a Tor onion3 address.') } // onion addresses do not include the multibase prefix, add it before decoding - const buf = multibase.decode('b' + addr[0]) + const buf = base32.decode('b' + addr[0]) // onion port number const port = parseInt(addr[1], 10) diff --git a/src/index.js b/src/index.js index 50d328b6..90d0a0a2 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ const codec = require('./codec') const protocols = require('./protocols-table') const varint = require('varint') -const CID = require('cids') +const { CID } = require('multiformats/cid') const errCode = require('err-code') const inspect = Symbol.for('nodejs.util.inspect.custom') const uint8ArrayToString = require('uint8arrays/to-string') @@ -314,7 +314,7 @@ class Multiaddr { const tuple = tuples.pop() if (tuple && tuple[1]) { // Get multihash, unwrap from CID if needed - return uint8ArrayToString(new CID(tuple[1]).multihash, 'base58btc') + return uint8ArrayToString(CID.parse(tuple[1]).multihash.bytes, 'base58btc') } else { return null } From 530e70b30c8e33479114fa2d437c33dd4c854c70 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Wed, 2 Jun 2021 12:46:24 +0100 Subject: [PATCH 2/4] chore: use prepare for build to enable depending on branchs of this repo --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7bbf1ad..3e3c2d31 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "test": "npm run test:node && npm run test:browser", "test:node": "aegir test --ts -t node", "test:browser": "aegir test -t browser", - "build": "aegir build", + "prepare": "aegir build", "release": "aegir release", "release-minor": "aegir release --type minor", "release-major": "aegir release --type major", From 790694449e6d4458db931d1b52a71384713c29ec Mon Sep 17 00:00:00 2001 From: achingbrain Date: Wed, 2 Jun 2021 17:29:36 +0100 Subject: [PATCH 3/4] chore: simplify input type for mh2bytes --- src/convert.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/convert.js b/src/convert.js index 8d98c99c..3f5cbdd4 100644 --- a/src/convert.js +++ b/src/convert.js @@ -4,6 +4,8 @@ const ip = require('./ip') const protocols = require('./protocols-table') const { CID } = require('multiformats/cid') const { base32 } = require('multiformats/bases/base32') +const { base58btc } = require('multiformats/bases/base58') +const Digest = require('multiformats/hashes/digest') const varint = require('varint') const uint8ArrayToString = require('uint8arrays/to-string') const uint8ArrayFromString = require('uint8arrays/from-string') @@ -160,25 +162,18 @@ function bytes2str (buf) { } /** - * @param {string | Uint8Array | CID} hash + * @param {string} hash - base58btc string */ function mh2bytes (hash) { - let cid + let mh - if (typeof hash === 'string') { - cid = CID.parse(hash) - } else if (hash instanceof Uint8Array) { - cid = CID.decode(hash) + if (hash[0] === 'Q' || hash[0] === '1') { + mh = Digest.decode(base58btc.decode(`z${hash}`)).bytes } else { - cid = CID.asCID(cid) - } - - if (!cid) { - throw new Error('Invalid CID') + mh = CID.parse(hash).multihash.bytes } // the address is a varint prefixed multihash string representation - const mh = cid.multihash.bytes const size = Uint8Array.from(varint.encode(mh.length)) return uint8ArrayConcat([size, mh], size.length + mh.length) } @@ -187,7 +182,7 @@ function mh2bytes (hash) { * Converts bytes to bas58btc string * * @param {Uint8Array} buf - * @returns {string} bas58btc string + * @returns {string} base58btc string */ function bytes2mh (buf) { const size = varint.decode(buf) From fba52019c66284df1b74a119711d789a2cd69a26 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Mon, 21 Jun 2021 09:46:09 +0100 Subject: [PATCH 4/4] chore: handle identity peer ids properly --- src/index.js | 17 +++++++++++++---- src/ip.js | 2 +- test/index.spec.js | 5 +++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index 90d0a0a2..d7c2d891 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ const codec = require('./codec') const protocols = require('./protocols-table') const varint = require('varint') const { CID } = require('multiformats/cid') +const { base58btc } = require('multiformats/bases/base58') const errCode = require('err-code') const inspect = Symbol.for('nodejs.util.inspect.custom') const uint8ArrayToString = require('uint8arrays/to-string') @@ -313,11 +314,19 @@ class Multiaddr { // Get the last ipfs tuple ['ipfs', 'peerid string'] const tuple = tuples.pop() if (tuple && tuple[1]) { - // Get multihash, unwrap from CID if needed - return uint8ArrayToString(CID.parse(tuple[1]).multihash.bytes, 'base58btc') - } else { - return null + const peerIdStr = tuple[1] + + // peer id is base58btc encoded string but not multibase encoded so add the `z` + // prefix so we can validate that it is correctly encoded + if (peerIdStr[0] === 'Q' || peerIdStr[0] === '1') { + return uint8ArrayToString(base58btc.decode(`z${peerIdStr}`), 'base58btc') + } + + // try to parse peer id as CID + return uint8ArrayToString(CID.parse(peerIdStr).multihash.bytes, 'base58btc') } + + return null } catch (e) { return null } diff --git a/src/ip.js b/src/ip.js index 958423ba..8b312f99 100644 --- a/src/ip.js +++ b/src/ip.js @@ -27,7 +27,7 @@ const toBytes = function (ip, buff, offset) { let i for (i = 0; i < sections.length; i++) { const isv4 = isV4(sections[i]) - var v4Buffer + let v4Buffer if (isv4) { v4Buffer = toBytes(sections[i]) diff --git a/test/index.spec.js b/test/index.spec.js index 09999111..5e02170e 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -826,6 +826,11 @@ describe('helpers', () => { new Multiaddr('/p2p-circuit/p2p/bafzbeidt255unskpefjmqb2rc27vjuyxopkxgaylxij6pw35hhys4vnyp4').getPeerId() ).to.equal('QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t') }) + it('extracts the peer Id from a multiaddr, p2p and base58btc encoded identity multihash', () => { + expect( + new Multiaddr('/p2p-circuit/p2p/12D3KooWNvSZnPi3RrhrTwEY4LuuBeB6K6facKUCJcyWG1aoDd2p').getPeerId() + ).to.equal('12D3KooWNvSZnPi3RrhrTwEY4LuuBeB6K6facKUCJcyWG1aoDd2p') + }) }) describe('.getPeerId should return null on missing peer id in multiaddr', () => {