diff --git a/package.json b/package.json index ff292825..9f712c56 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "err-code": "^3.0.0", "hashlru": "^2.3.0", "interface-datastore": "^6.0.2", + "iso-random-stream": "^2.0.1", "it-all": "^1.0.5", "it-drain": "^1.0.4", "it-first": "^1.0.4", @@ -65,7 +66,6 @@ "it-pipe": "^1.1.0", "it-take": "^1.0.2", "k-bucket": "^5.1.0", - "libp2p-crypto": "^0.21.0", "libp2p-interfaces": "^2.0.1", "libp2p-record": "^0.10.4", "multiaddr": "^10.0.0", diff --git a/src/dual-kad-dht.js b/src/dual-kad-dht.js index b92aedde..23df9fe2 100644 --- a/src/dual-kad-dht.js +++ b/src/dual-kad-dht.js @@ -1,7 +1,6 @@ 'use strict' const { EventEmitter } = require('events') -const PeerId = require('peer-id') const utils = require('./utils') const errCode = require('err-code') const merge = require('it-merge') @@ -17,6 +16,7 @@ const log = utils.logger('libp2p:kad-dht') * @typedef {import('libp2p/src/registrar')} Registrar * @typedef {import('multiformats/cid').CID} CID * @typedef {import('multiaddr').Multiaddr} Multiaddr + * @typedef {import('peer-id')} PeerId * @typedef {import('./kad-dht').KadDHT} KadDHT * @typedef {import('./types').DHT} DHT * @typedef {import('./types').QueryEvent} QueryEvent @@ -299,48 +299,6 @@ class DualKadDHT extends EventEmitter { ) } - /** - * Get the public key for the given peer id - * - * @param {PeerId} peer - * @param {object} [options] - * @param {AbortSignal} [options.signal] - */ - async getPublicKey (peer, options = {}) { - log('getPublicKey %p', peer) - - // local check - const peerData = this._libp2p.peerStore.get(peer) - - if (peerData && peerData.id.pubKey) { - log('getPublicKey: found local copy') - return peerData.id.pubKey - } - - // try the node directly - const pks = await Promise.all([ - this._lan.getPublicKey(peer, options), - this._wan.getPublicKey(peer, options) - ]) - - if (pks[0] && pks[1] && !pks[0].equals(pks[1])) { - throw errCode(new Error('Inconsistent public key loaded from wan and lan DHTs'), 'ERR_FAILED_TO_LOAD_KEY') - } - - const pk = pks[0] || pks[1] - - if (!pk) { - throw errCode(new Error('Failed to load public key'), 'ERR_FAILED_TO_LOAD_KEY') - } - - const peerId = new PeerId(peer.id, undefined, pk) - const addrs = ((peerData && peerData.addresses) || []).map((address) => address.multiaddr) - this._libp2p.peerStore.addressBook.add(peerId, addrs) - this._libp2p.peerStore.keyBook.set(peerId, pk) - - return pk - } - async refreshRoutingTable () { await Promise.all([ this._lan.refreshRoutingTable(), diff --git a/src/kad-dht.js b/src/kad-dht.js index 8a9fd263..49566a67 100644 --- a/src/kad-dht.js +++ b/src/kad-dht.js @@ -1,7 +1,6 @@ 'use strict' const { EventEmitter } = require('events') -const crypto = require('libp2p-crypto') const libp2pRecord = require('libp2p-record') const { MemoryDatastore } = require('datastore-core/memory') const { RoutingTable } = require('./routing-table') @@ -463,39 +462,6 @@ class KadDHT extends EventEmitter { yield * this._peerRouting.getClosestPeers(key, options) } - /** - * Get the public key for the given peer id - * - * @param {PeerId} peer - * @param {object} [options] - * @param {AbortSignal} [options.signal] - */ - async getPublicKey (peer, options = {}) { - this._log('getPublicKey %p', peer) - - // try the node directly - let pk - - for await (const event of this._peerRouting.getPublicKeyFromNode(peer, options)) { - if (event.name === 'VALUE') { - pk = crypto.keys.unmarshalPublicKey(event.value) - } - } - - if (!pk) { - // try dht directly - const pkKey = utils.keyForPublicKey(peer) - - for await (const event of this.get(pkKey, options)) { - if (event.name === 'VALUE') { - pk = crypto.keys.unmarshalPublicKey(event.value) - } - } - } - - return pk - } - async refreshRoutingTable () { await this._routingTableRefresh.refreshTable(true) } diff --git a/src/peer-routing/index.js b/src/peer-routing/index.js index 032ec0d9..a0cf7248 100644 --- a/src/peer-routing/index.js +++ b/src/peer-routing/index.js @@ -2,14 +2,12 @@ const errcode = require('err-code') const { validator } = require('libp2p-record') -const PeerId = require('peer-id') const { toString: uint8ArrayToString } = require('uint8arrays/to-string') const { Message } = require('../message') const utils = require('../utils') const { queryErrorEvent, - finalPeerEvent, - valueEvent + finalPeerEvent } = require('../query/events') const PeerDistanceList = require('../peer-list/peer-distance-list') const { Record } = require('libp2p-record') @@ -17,12 +15,13 @@ const { Record } = require('libp2p-record') /** * @typedef {import('multiaddr').Multiaddr} Multiaddr * @typedef {import('../types').PeerData} PeerData + * @typedef {import('peer-id')} PeerId */ class PeerRouting { /** * @param {object} params - * @param {import('peer-id')} params.peerId + * @param {PeerId} params.peerId * @param {import('../routing-table').RoutingTable} params.routingTable * @param {import('../types').PeerStore} params.peerStore * @param {import('../network').Network} params.network @@ -82,34 +81,6 @@ class PeerRouting { yield * this._network.sendRequest(peer, msg, options) } - /** - * Get the public key directly from a node. - * - * @param {PeerId} peer - * @param {object} [options] - * @param {AbortSignal} [options.signal] - */ - async * getPublicKeyFromNode (peer, options) { - const pkKey = utils.keyForPublicKey(peer) - - for await (const event of this._getValueSingle(peer, pkKey, options)) { - yield event - - if (event.name === 'PEER_RESPONSE' && event.record) { - const recPeer = await PeerId.createFromPubKey(event.record.value) - - // compare hashes of the pub key - if (!recPeer.equals(peer)) { - throw errcode(new Error('public key does not match id'), 'ERR_PUBLIC_KEY_DOES_NOT_MATCH_ID') - } - - yield valueEvent({ from: peer, value: recPeer.pubKey.bytes }) - } - } - - throw errcode(new Error(`Node not responding with its public key: ${peer.toB58String()}`), 'ERR_INVALID_RECORD') - } - /** * Search for a peer with the given ID. * diff --git a/src/routing-table/refresh.js b/src/routing-table/refresh.js index c9e2c44f..4650769e 100644 --- a/src/routing-table/refresh.js +++ b/src/routing-table/refresh.js @@ -3,7 +3,7 @@ const { xor: uint8ArrayXor } = require('uint8arrays/xor') const GENERATED_PREFIXES = require('./generated-prefix-list.json') const { sha256 } = require('multiformats/hashes/sha2') -const crypto = require('libp2p-crypto') +const randomBytes = require('iso-random-stream/src/random') const PeerId = require('peer-id') const utils = require('../utils') const length = require('it-length') @@ -170,8 +170,8 @@ class RoutingTableRefresh { * @param {number} targetCommonPrefixLength */ async _generateRandomPeerId (targetCommonPrefixLength) { - const randomBytes = crypto.randomBytes(2) - const randomUint16 = (randomBytes[1] << 8) + randomBytes[0] + const bytes = randomBytes(2) + const randomUint16 = (bytes[1] << 8) + bytes[0] const key = await this._makePeerId(this._routingTable.kb.localNodeId, randomUint16, targetCommonPrefixLength) diff --git a/src/types.ts b/src/types.ts index 7c6248a1..8739aa33 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,7 +3,6 @@ import type { Multiaddr } from 'multiaddr' import type { CID } from 'multiformats/cid' import type { MuxedStream } from 'libp2p/src/upgrader' import type Topology from 'libp2p-interfaces/src/topology' -import type { PublicKey } from 'libp2p-crypto' import type { Message } from './message/dht' export enum EventTypes { @@ -134,7 +133,6 @@ export interface DHT { findProviders: (key: CID, options?: QueryOptions) => AsyncIterable findPeer: (id: PeerId, options?: QueryOptions) => AsyncIterable getClosestPeers: (key: Uint8Array, options?: QueryOptions) => AsyncIterable - getPublicKey: (peer: PeerId, options?: QueryOptions) => Promise // publish/server methods provide: (key: CID, options?: QueryOptions) => AsyncIterable diff --git a/src/utils.js b/src/utils.js index 9b3ddba8..6a1fc28c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,14 +7,9 @@ const { base32 } = require('multiformats/bases/base32') const { Key } = require('interface-datastore/key') const { Record } = require('libp2p-record') const PeerId = require('peer-id') -const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') const { toString: uint8ArrayToString } = require('uint8arrays/to-string') -const { concat: uint8ArrayConcat } = require('uint8arrays/concat') const isPrivateIp = require('private-ip') -// const IPNS_PREFIX = uint8ArrayFromString('/ipns/') -const PK_PREFIX = uint8ArrayFromString('/pk/') - /** * @param {import('./types').PeerData} peer */ @@ -83,19 +78,6 @@ const bufferToKey = (buf) => { return new Key('/' + uint8ArrayToString(buf, 'base32'), false) } -/** - * Generate the key for a public key. - * - * @param {PeerId} peer - * @returns {Uint8Array} - */ -const keyForPublicKey = (peer) => { - return uint8ArrayConcat([ - PK_PREFIX, - peer.id - ]) -} - /** * @param {Uint8Array} key */ @@ -165,7 +147,6 @@ module.exports = { convertBuffer, convertPeerId, bufferToKey, - keyForPublicKey, isPublicKeyKey, isIPNSKey, fromPublicKeyKey, diff --git a/test/kad-dht.spec.js b/test/kad-dht.spec.js index 02897662..1ab7230e 100644 --- a/test/kad-dht.spec.js +++ b/test/kad-dht.spec.js @@ -3,7 +3,6 @@ const { expect } = require('aegir/utils/chai') const sinon = require('sinon') -const { Multiaddr } = require('multiaddr') const { Record } = require('libp2p-record') const errcode = require('err-code') const { equals: uint8ArrayEquals } = require('uint8arrays/equals') @@ -82,7 +81,6 @@ describe('KadDHT', () => { expect(dht).to.have.property('findProviders') expect(dht).to.have.property('findPeer') expect(dht).to.have.property('getClosestPeers') - expect(dht).to.have.property('getPublicKey') expect(dht).to.have.property('enableServerMode') expect(dht).to.have.property('enableClientMode') }) @@ -689,37 +687,6 @@ describe('KadDHT', () => { }) }) - describe('getPublicKey', () => { - it('already known', async function () { - this.timeout(20 * 1000) - - const dhts = await tdht.spawn(2) - - const ids = dhts.map((d) => d._libp2p.peerId) - dhts[0]._libp2p.peerStore.addressBook.add(dhts[1]._libp2p.peerId, [new Multiaddr('/ip4/160.1.1.1/tcp/80')]) - - const key = await dhts[0].getPublicKey(ids[1]) - expect(key).to.eql(dhts[1]._libp2p.peerId.pubKey) - - await delay(100) - }) - - it('connected node', async function () { - this.timeout(30 * 1000) - - const dhts = await tdht.spawn(2) - - const ids = dhts.map((d) => d._libp2p.peerId) - - await tdht.connect(dhts[0], dhts[1]) - - dhts[0]._libp2p.peerStore.addressBook.add(dhts[1]._libp2p.peerId, [new Multiaddr('/ip4/160.1.1.1/tcp/80')]) - - const key = await dhts[0].getPublicKey(ids[1]) - expect(uint8ArrayEquals(key, dhts[1]._libp2p.peerId.pubKey)).to.eql(true) - }) - }) - describe('errors', () => { it('get should fail if only has one peer', async function () { this.timeout(20 * 1000) diff --git a/test/kad-utils.spec.js b/test/kad-utils.spec.js index efa43aad..cce1fa16 100644 --- a/test/kad-utils.spec.js +++ b/test/kad-utils.spec.js @@ -2,9 +2,9 @@ 'use strict' const { expect } = require('aegir/utils/chai') -const { concat: uint8ArrayConcat } = require('uint8arrays/concat') const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') const { toString: uint8ArrayToString } = require('uint8arrays/to-string') +const keyForPublicKey = require('./utils/key-for-public-key') const utils = require('../src/utils') const createPeerId = require('./utils/create-peer-id') @@ -31,22 +31,14 @@ describe('kad utils', () => { }) }) - describe('keyForPublicKey', () => { - it('works', async () => { - const peers = await createPeerId(1) - expect(utils.keyForPublicKey(peers[0])) - .to.eql(uint8ArrayConcat([uint8ArrayFromString('/pk/'), peers[0].id])) - }) - }) - describe('fromPublicKeyKey', () => { it('round trips', async function () { this.timeout(40 * 1000) const peers = await createPeerId(50) peers.forEach((id, i) => { - expect(utils.isPublicKeyKey(utils.keyForPublicKey(id))).to.eql(true) - expect(utils.fromPublicKeyKey(utils.keyForPublicKey(id)).id) + expect(utils.isPublicKeyKey(keyForPublicKey(id))).to.eql(true) + expect(utils.fromPublicKeyKey(keyForPublicKey(id)).id) .to.eql(id.id) }) }) diff --git a/test/rpc/handlers/get-value.spec.js b/test/rpc/handlers/get-value.spec.js index 131c2b0f..f2181311 100644 --- a/test/rpc/handlers/get-value.spec.js +++ b/test/rpc/handlers/get-value.spec.js @@ -4,9 +4,9 @@ const { expect } = require('aegir/utils/chai') const { Message } = require('../../../src/message') const { GetValueHandler } = require('../../../src/rpc/handlers/get-value') -const utils = require('../../../src/utils') const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') const drain = require('it-drain') +const keyForPublicKey = require('../../utils/key-for-public-key') const T = Message.TYPES.GET_VALUE @@ -78,7 +78,7 @@ describe('rpc - handlers - GetValue', () => { describe('public key', () => { it('self', async () => { - const key = utils.keyForPublicKey(dht._libp2p.peerId) + const key = keyForPublicKey(dht._libp2p.peerId) const msg = new Message(T, key, 0) const response = await handler.handle(peerIds[0], msg) @@ -89,7 +89,7 @@ describe('rpc - handlers - GetValue', () => { it('other in peerstore', async () => { const other = peerIds[1] - const key = utils.keyForPublicKey(other) + const key = keyForPublicKey(other) const msg = new Message(T, key, 0) @@ -104,7 +104,7 @@ describe('rpc - handlers - GetValue', () => { it('other unkown', async () => { const other = peerIds[1] - const key = utils.keyForPublicKey(other) + const key = keyForPublicKey(other) const msg = new Message(T, key, 0) const response = await handler.handle(peerIds[0], msg) diff --git a/test/simulation/index.js b/test/simulation/index.js index 81573931..092457d7 100644 --- a/test/simulation/index.js +++ b/test/simulation/index.js @@ -12,7 +12,7 @@ const { convertBuffer } = require('../../src/utils') const { sortClosestPeers } = require('../utils/sort-closest-peers') const DHT = require('../../src') const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') -const crypto = require('libp2p-crypto') +const randomBytes = require('iso-random-stream/src/random') const NUM_PEERS = 10e3 // Peers to create, not including us const LATENCY_DEAD_NODE = 120e3 // How long dead nodes should take before erroring @@ -137,7 +137,7 @@ async function GetClosestPeersSimulation () { function createPeers (num) { const peers = [...new Array(num)].map(() => { return PeerId.createFromB58String( - base58btc.baseEncode(crypto.randomBytes(34)) + base58btc.baseEncode(randomBytes(34)) ) }) diff --git a/test/utils/create-values.js b/test/utils/create-values.js index 1b7dee16..85097145 100644 --- a/test/utils/create-values.js +++ b/test/utils/create-values.js @@ -2,12 +2,12 @@ const { CID } = require('multiformats/cid') const { sha256 } = require('multiformats/hashes/sha2') -const crypto = require('libp2p-crypto') +const randomBytes = require('iso-random-stream/src/random') function createValues (length) { return Promise.all( Array.from({ length }).map(async () => { - const bytes = crypto.randomBytes(32) + const bytes = randomBytes(32) const h = await sha256.digest(bytes) return { cid: CID.createV0(h), diff --git a/test/utils/key-for-public-key.js b/test/utils/key-for-public-key.js new file mode 100644 index 00000000..872ea530 --- /dev/null +++ b/test/utils/key-for-public-key.js @@ -0,0 +1,22 @@ +'use strict' + +const { concat: uint8ArrayConcat } = require('uint8arrays/concat') +const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') + +// const IPNS_PREFIX = uint8ArrayFromString('/ipns/') +const PK_PREFIX = uint8ArrayFromString('/pk/') + +/** + * Generate the key for a public key. + * + * @param {PeerId} peer + * @returns {Uint8Array} + */ +const keyForPublicKey = (peer) => { + return uint8ArrayConcat([ + PK_PREFIX, + peer.id + ]) +} + +module.exports = keyForPublicKey