@libp2p/kad-dht 12.1.5 → 13.0.0-18dd3cb26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/index.min.js +3 -4
  2. package/dist/src/content-fetching/index.d.ts.map +1 -1
  3. package/dist/src/content-fetching/index.js +6 -5
  4. package/dist/src/content-fetching/index.js.map +1 -1
  5. package/dist/src/content-routing/index.js +1 -1
  6. package/dist/src/errors.d.ts +25 -0
  7. package/dist/src/errors.d.ts.map +1 -0
  8. package/dist/src/errors.js +37 -0
  9. package/dist/src/errors.js.map +1 -0
  10. package/dist/src/index.d.ts +2 -1
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/kad-dht.d.ts.map +1 -1
  14. package/dist/src/kad-dht.js +3 -3
  15. package/dist/src/kad-dht.js.map +1 -1
  16. package/dist/src/message/dht.d.ts +4 -4
  17. package/dist/src/message/dht.d.ts.map +1 -1
  18. package/dist/src/message/dht.js +25 -12
  19. package/dist/src/message/dht.js.map +1 -1
  20. package/dist/src/message/utils.d.ts.map +1 -1
  21. package/dist/src/message/utils.js +5 -3
  22. package/dist/src/message/utils.js.map +1 -1
  23. package/dist/src/network.d.ts.map +1 -1
  24. package/dist/src/network.js +3 -4
  25. package/dist/src/network.js.map +1 -1
  26. package/dist/src/peer-routing/index.d.ts.map +1 -1
  27. package/dist/src/peer-routing/index.js +21 -16
  28. package/dist/src/peer-routing/index.js.map +1 -1
  29. package/dist/src/query/events.d.ts.map +1 -1
  30. package/dist/src/query/events.js +0 -1
  31. package/dist/src/query/events.js.map +1 -1
  32. package/dist/src/query/manager.js +1 -1
  33. package/dist/src/query/query-path.d.ts.map +1 -1
  34. package/dist/src/query/query-path.js +3 -2
  35. package/dist/src/query/query-path.js.map +1 -1
  36. package/dist/src/query-self.js +1 -1
  37. package/dist/src/query-self.js.map +1 -1
  38. package/dist/src/record/selectors.d.ts.map +1 -1
  39. package/dist/src/record/selectors.js +5 -7
  40. package/dist/src/record/selectors.js.map +1 -1
  41. package/dist/src/record/validators.d.ts.map +1 -1
  42. package/dist/src/record/validators.js +9 -10
  43. package/dist/src/record/validators.js.map +1 -1
  44. package/dist/src/routing-table/index.d.ts.map +1 -1
  45. package/dist/src/routing-table/index.js +2 -2
  46. package/dist/src/routing-table/index.js.map +1 -1
  47. package/dist/src/routing-table/refresh.d.ts.map +1 -1
  48. package/dist/src/routing-table/refresh.js +5 -3
  49. package/dist/src/routing-table/refresh.js.map +1 -1
  50. package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -1
  51. package/dist/src/rpc/handlers/add-provider.js +7 -5
  52. package/dist/src/rpc/handlers/add-provider.js.map +1 -1
  53. package/dist/src/rpc/handlers/find-node.js +4 -4
  54. package/dist/src/rpc/handlers/find-node.js.map +1 -1
  55. package/dist/src/rpc/handlers/get-providers.js +6 -6
  56. package/dist/src/rpc/handlers/get-providers.js.map +1 -1
  57. package/dist/src/rpc/handlers/get-value.d.ts.map +1 -1
  58. package/dist/src/rpc/handlers/get-value.js +8 -10
  59. package/dist/src/rpc/handlers/get-value.js.map +1 -1
  60. package/dist/src/rpc/handlers/put-value.js +2 -2
  61. package/dist/src/rpc/handlers/put-value.js.map +1 -1
  62. package/dist/src/topology-listener.d.ts.map +1 -1
  63. package/dist/src/topology-listener.js +1 -1
  64. package/dist/src/topology-listener.js.map +1 -1
  65. package/dist/src/utils.d.ts +1 -1
  66. package/dist/src/utils.d.ts.map +1 -1
  67. package/dist/src/utils.js +7 -5
  68. package/dist/src/utils.js.map +1 -1
  69. package/package.json +14 -15
  70. package/src/content-fetching/index.ts +6 -5
  71. package/src/content-routing/index.ts +1 -1
  72. package/src/errors.ts +39 -0
  73. package/src/index.ts +2 -1
  74. package/src/kad-dht.ts +3 -3
  75. package/src/message/dht.ts +28 -12
  76. package/src/message/utils.ts +6 -3
  77. package/src/network.ts +3 -4
  78. package/src/peer-routing/index.ts +21 -16
  79. package/src/query/events.ts +0 -1
  80. package/src/query/manager.ts +1 -1
  81. package/src/query/query-path.ts +3 -2
  82. package/src/query-self.ts +1 -1
  83. package/src/record/selectors.ts +5 -10
  84. package/src/record/validators.ts +9 -12
  85. package/src/routing-table/index.ts +2 -2
  86. package/src/routing-table/refresh.ts +5 -3
  87. package/src/rpc/handlers/add-provider.ts +8 -5
  88. package/src/rpc/handlers/find-node.ts +4 -4
  89. package/src/rpc/handlers/get-providers.ts +6 -6
  90. package/src/rpc/handlers/get-value.ts +8 -11
  91. package/src/rpc/handlers/put-value.ts +2 -2
  92. package/src/topology-listener.ts +1 -1
  93. package/src/utils.ts +7 -5
  94. package/dist/typedoc-urls.json +0 -55
@@ -4,7 +4,7 @@
4
4
  /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
5
5
  /* eslint-disable @typescript-eslint/no-empty-interface */
6
6
 
7
- import { type Codec, decodeMessage, encodeMessage, enumeration, message } from 'protons-runtime'
7
+ import { type Codec, decodeMessage, type DecodeOptions, encodeMessage, enumeration, MaxLengthError, message } from 'protons-runtime'
8
8
  import { alloc as uint8ArrayAlloc } from 'uint8arrays/alloc'
9
9
  import type { Uint8ArrayList } from 'uint8arraylist'
10
10
 
@@ -54,7 +54,7 @@ export namespace Record {
54
54
  if (opts.lengthDelimited !== false) {
55
55
  w.ldelim()
56
56
  }
57
- }, (reader, length) => {
57
+ }, (reader, length, opts = {}) => {
58
58
  const obj: any = {}
59
59
 
60
60
  const end = length == null ? reader.len : reader.pos + length
@@ -101,8 +101,8 @@ export namespace Record {
101
101
  return encodeMessage(obj, Record.codec())
102
102
  }
103
103
 
104
- export const decode = (buf: Uint8Array | Uint8ArrayList): Record => {
105
- return decodeMessage(buf, Record.codec())
104
+ export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<Record>): Record => {
105
+ return decodeMessage(buf, Record.codec(), opts)
106
106
  }
107
107
  }
108
108
 
@@ -184,7 +184,7 @@ export namespace PeerInfo {
184
184
  if (opts.lengthDelimited !== false) {
185
185
  w.ldelim()
186
186
  }
187
- }, (reader, length) => {
187
+ }, (reader, length, opts = {}) => {
188
188
  const obj: any = {
189
189
  id: uint8ArrayAlloc(0),
190
190
  multiaddrs: []
@@ -201,6 +201,10 @@ export namespace PeerInfo {
201
201
  break
202
202
  }
203
203
  case 2: {
204
+ if (opts.limits?.multiaddrs != null && obj.multiaddrs.length === opts.limits.multiaddrs) {
205
+ throw new MaxLengthError('Decode error - map field "multiaddrs" had too many elements')
206
+ }
207
+
204
208
  obj.multiaddrs.push(reader.bytes())
205
209
  break
206
210
  }
@@ -226,8 +230,8 @@ export namespace PeerInfo {
226
230
  return encodeMessage(obj, PeerInfo.codec())
227
231
  }
228
232
 
229
- export const decode = (buf: Uint8Array | Uint8ArrayList): PeerInfo => {
230
- return decodeMessage(buf, PeerInfo.codec())
233
+ export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<PeerInfo>): PeerInfo => {
234
+ return decodeMessage(buf, PeerInfo.codec(), opts)
231
235
  }
232
236
  }
233
237
 
@@ -287,7 +291,7 @@ export namespace Message {
287
291
  if (opts.lengthDelimited !== false) {
288
292
  w.ldelim()
289
293
  }
290
- }, (reader, length) => {
294
+ }, (reader, length, opts = {}) => {
291
295
  const obj: any = {
292
296
  type: MessageType.PUT_VALUE,
293
297
  closer: [],
@@ -317,11 +321,23 @@ export namespace Message {
317
321
  break
318
322
  }
319
323
  case 8: {
320
- obj.closer.push(PeerInfo.codec().decode(reader, reader.uint32()))
324
+ if (opts.limits?.closer != null && obj.closer.length === opts.limits.closer) {
325
+ throw new MaxLengthError('Decode error - map field "closer" had too many elements')
326
+ }
327
+
328
+ obj.closer.push(PeerInfo.codec().decode(reader, reader.uint32(), {
329
+ limits: opts.limits?.closer$
330
+ }))
321
331
  break
322
332
  }
323
333
  case 9: {
324
- obj.providers.push(PeerInfo.codec().decode(reader, reader.uint32()))
334
+ if (opts.limits?.providers != null && obj.providers.length === opts.limits.providers) {
335
+ throw new MaxLengthError('Decode error - map field "providers" had too many elements')
336
+ }
337
+
338
+ obj.providers.push(PeerInfo.codec().decode(reader, reader.uint32(), {
339
+ limits: opts.limits?.providers$
340
+ }))
325
341
  break
326
342
  }
327
343
  default: {
@@ -342,7 +358,7 @@ export namespace Message {
342
358
  return encodeMessage(obj, Message.codec())
343
359
  }
344
360
 
345
- export const decode = (buf: Uint8Array | Uint8ArrayList): Message => {
346
- return decodeMessage(buf, Message.codec())
361
+ export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<Message>): Message => {
362
+ return decodeMessage(buf, Message.codec(), opts)
347
363
  }
348
364
  }
@@ -1,11 +1,12 @@
1
- import { peerIdFromBytes } from '@libp2p/peer-id'
1
+ import { peerIdFromMultihash } from '@libp2p/peer-id'
2
2
  import { multiaddr } from '@multiformats/multiaddr'
3
+ import * as Digest from 'multiformats/hashes/digest'
3
4
  import type { PeerInfo as PBPeerInfo, ConnectionType } from './dht.js'
4
5
  import type { PeerInfo } from '@libp2p/interface'
5
6
 
6
7
  export function toPbPeerInfo (peer: PeerInfo, connection?: ConnectionType): PBPeerInfo {
7
8
  const output: PBPeerInfo = {
8
- id: peer.id.toBytes(),
9
+ id: peer.id.toMultihash().bytes,
9
10
  multiaddrs: (peer.multiaddrs ?? []).map((m) => m.bytes),
10
11
  connection
11
12
  }
@@ -18,8 +19,10 @@ export function fromPbPeerInfo (peer: PBPeerInfo): PeerInfo {
18
19
  throw new Error('Invalid peer in message')
19
20
  }
20
21
 
22
+ const multihash = Digest.decode(peer.id)
23
+
21
24
  return {
22
- id: peerIdFromBytes(peer.id),
25
+ id: peerIdFromMultihash(multihash),
23
26
  multiaddrs: (peer.multiaddrs ?? []).map((a) => multiaddr(a))
24
27
  }
25
28
  }
package/src/network.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { TypedEventEmitter } from '@libp2p/interface'
1
+ import { InvalidParametersError, TypedEventEmitter } from '@libp2p/interface'
2
2
  import { Libp2pRecord } from '@libp2p/record'
3
3
  import { AdaptiveTimeout, type AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
4
4
  import { pbStream } from 'it-protobuf-stream'
5
- import { CodeError } from 'protons-runtime'
6
5
  import { Message } from './message/dht.js'
7
6
  import { fromPbPeerInfo } from './message/utils.js'
8
7
  import {
@@ -88,7 +87,7 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
88
87
  const type = msg.type
89
88
 
90
89
  if (type == null) {
91
- throw new CodeError('Message type was missing', 'ERR_INVALID_PARAMETERS')
90
+ throw new InvalidParametersError('Message type was missing')
92
91
  }
93
92
 
94
93
  this.log('sending %s to %p', msg.type, to)
@@ -141,7 +140,7 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
141
140
  const type = msg.type
142
141
 
143
142
  if (type == null) {
144
- throw new CodeError('Message type was missing', 'ERR_INVALID_PARAMETERS')
143
+ throw new InvalidParametersError('Message type was missing')
145
144
  }
146
145
 
147
146
  this.log('sending %s to %p', msg.type, to)
@@ -1,8 +1,9 @@
1
- import { keys } from '@libp2p/crypto'
2
- import { CodeError } from '@libp2p/interface'
3
- import { peerIdFromKeys } from '@libp2p/peer-id'
1
+ import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
2
+ import { InvalidPublicKeyError, NotFoundError } from '@libp2p/interface'
3
+ import { peerIdFromPublicKey } from '@libp2p/peer-id'
4
4
  import { Libp2pRecord } from '@libp2p/record'
5
5
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
6
+ import { QueryError, InvalidRecordError } from '../errors.js'
6
7
  import { MessageType } from '../message/dht.js'
7
8
  import { PeerDistanceList } from '../peer-list/peer-distance-list.js'
8
9
  import {
@@ -63,7 +64,7 @@ export class PeerRouting {
63
64
  try {
64
65
  peerData = await this.peerStore.get(p)
65
66
  } catch (err: any) {
66
- if (err.code !== 'ERR_NOT_FOUND') {
67
+ if (err.name !== 'NotFoundError') {
67
68
  throw err
68
69
  }
69
70
  }
@@ -73,7 +74,7 @@ export class PeerRouting {
73
74
  try {
74
75
  peerData = await this.peerStore.get(peer)
75
76
  } catch (err: any) {
76
- if (err.code !== 'ERR_NOT_FOUND') {
77
+ if (err.name !== 'NotFoundError') {
77
78
  throw err
78
79
  }
79
80
  }
@@ -113,22 +114,26 @@ export class PeerRouting {
113
114
  yield event
114
115
 
115
116
  if (event.name === 'PEER_RESPONSE' && event.record != null) {
116
- const recPeer = await peerIdFromKeys(keys.marshalPublicKey({ bytes: event.record.value }))
117
+ const publicKey = publicKeyFromProtobuf(event.record.value)
118
+ const recPeer = peerIdFromPublicKey(publicKey)
117
119
 
118
120
  // compare hashes of the pub key
119
121
  if (!recPeer.equals(peer)) {
120
- throw new CodeError('public key does not match id', 'ERR_PUBLIC_KEY_DOES_NOT_MATCH_ID')
122
+ throw new InvalidPublicKeyError('public key does not match id')
121
123
  }
122
124
 
123
125
  if (recPeer.publicKey == null) {
124
- throw new CodeError('public key missing', 'ERR_PUBLIC_KEY_MISSING')
126
+ throw new InvalidPublicKeyError('public key missing')
125
127
  }
126
128
 
127
- yield valueEvent({ from: peer, value: recPeer.publicKey }, options)
129
+ yield valueEvent({
130
+ from: peer,
131
+ value: event.record.value
132
+ }, options)
128
133
  }
129
134
  }
130
135
 
131
- throw new CodeError(`Node not responding with its public key: ${peer.toString()}`, 'ERR_INVALID_RECORD')
136
+ throw new QueryError(`Node not responding with its public key: ${peer.toString()}`)
132
137
  }
133
138
 
134
139
  /**
@@ -160,7 +165,7 @@ export class PeerRouting {
160
165
  const findPeerQuery: QueryFunc = async function * ({ peer, signal }) {
161
166
  const request: Partial<Message> = {
162
167
  type: MessageType.FIND_NODE,
163
- key: id.toBytes()
168
+ key: id.toMultihash().bytes
164
169
  }
165
170
 
166
171
  for await (const event of self.network.sendRequest(peer, request, {
@@ -180,7 +185,7 @@ export class PeerRouting {
180
185
  }
181
186
  }
182
187
 
183
- for await (const event of this.queryManager.run(id.toBytes(), findPeerQuery, options)) {
188
+ for await (const event of this.queryManager.run(id.toMultihash().bytes, findPeerQuery, options)) {
184
189
  if (event.name === 'FINAL_PEER') {
185
190
  foundPeer = true
186
191
  }
@@ -190,7 +195,7 @@ export class PeerRouting {
190
195
  }
191
196
 
192
197
  if (!foundPeer) {
193
- yield queryErrorEvent({ from: this.peerId, error: new CodeError('Not found', 'ERR_NOT_FOUND') }, options)
198
+ yield queryErrorEvent({ from: this.peerId, error: new NotFoundError('Not found') }, options)
194
199
  }
195
200
  }
196
201
 
@@ -257,7 +262,7 @@ export class PeerRouting {
257
262
  const errMsg = 'invalid record received, discarded'
258
263
  this.log(errMsg)
259
264
 
260
- yield queryErrorEvent({ from: event.from, error: new CodeError(errMsg, 'ERR_INVALID_RECORD') }, options)
265
+ yield queryErrorEvent({ from: event.from, error: new QueryError(errMsg) }, options)
261
266
  continue
262
267
  }
263
268
  }
@@ -273,7 +278,7 @@ export class PeerRouting {
273
278
  */
274
279
  async _verifyRecordOnline (record: DHTRecord): Promise<void> {
275
280
  if (record.timeReceived == null) {
276
- throw new CodeError('invalid record received', 'ERR_INVALID_RECORD')
281
+ throw new InvalidRecordError('invalid record received')
277
282
  }
278
283
 
279
284
  await verifyRecord(this.validators, new Libp2pRecord(record.key, record.value, record.timeReceived))
@@ -301,7 +306,7 @@ export class PeerRouting {
301
306
  multiaddrs: peer.addresses.map(({ multiaddr }) => multiaddr)
302
307
  })
303
308
  } catch (err: any) {
304
- if (err.code !== 'ERR_NOT_FOUND') {
309
+ if (err.name !== 'NotFoundError') {
305
310
  throw err
306
311
  }
307
312
  }
@@ -1,4 +1,3 @@
1
- import { CustomEvent } from '@libp2p/interface'
2
1
  import type { MessageType, SendQueryEvent, PeerResponseEvent, DialPeerEvent, AddPeerEvent, ValueEvent, ProviderEvent, QueryErrorEvent, FinalPeerEvent } from '../index.js'
3
2
  import type { PeerId, PeerInfo } from '@libp2p/interface'
4
3
  import type { Libp2pRecord } from '@libp2p/record'
@@ -223,7 +223,7 @@ export class QueryManager implements Startable {
223
223
 
224
224
  queryFinished = true
225
225
  } catch (err: any) {
226
- if (!this.running && err.code === 'ERR_QUERY_ABORTED') {
226
+ if (!this.running && err.name === 'QueryAbortedError') {
227
227
  // ignore query aborted errors that were thrown during query manager shutdown
228
228
  } else {
229
229
  throw err
@@ -1,8 +1,9 @@
1
- import { CodeError, setMaxListeners } from '@libp2p/interface'
1
+ import { setMaxListeners } from '@libp2p/interface'
2
2
  import { Queue } from '@libp2p/utils/queue'
3
3
  import { anySignal } from 'any-signal'
4
4
  import { xor as uint8ArrayXor } from 'uint8arrays/xor'
5
5
  import { xorCompare as uint8ArrayXorCompare } from 'uint8arrays/xor-compare'
6
+ import { QueryAbortedError } from '../errors.js'
6
7
  import { convertPeerId, convertBuffer } from '../utils.js'
7
8
  import { queryErrorEvent } from './events.js'
8
9
  import type { QueryEvent } from '../index.js'
@@ -195,7 +196,7 @@ export async function * queryPath (options: QueryPathOptions): AsyncGenerator<Qu
195
196
  }
196
197
  } catch (err) {
197
198
  if (signal.aborted) {
198
- throw new CodeError('Query aborted', 'ERR_QUERY_ABORTED')
199
+ throw new QueryAbortedError('Query aborted')
199
200
  }
200
201
 
201
202
  throw err
package/src/query-self.ts CHANGED
@@ -125,7 +125,7 @@ export class QuerySelf implements Startable {
125
125
  const start = Date.now()
126
126
 
127
127
  const found = await pipe(
128
- this.peerRouting.getClosestPeers(this.peerId.toBytes(), {
128
+ this.peerRouting.getClosestPeers(this.peerId.toMultihash().bytes, {
129
129
  signal,
130
130
  isSelfQuery: true
131
131
  }),
@@ -1,5 +1,6 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { InvalidParametersError } from '@libp2p/interface'
2
2
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
3
+ import { MissingSelectorError } from '../errors.js'
3
4
  import type { Selectors } from '../index.js'
4
5
 
5
6
  /**
@@ -7,26 +8,20 @@ import type { Selectors } from '../index.js'
7
8
  */
8
9
  export function bestRecord (selectors: Selectors, k: Uint8Array, records: Uint8Array[]): number {
9
10
  if (records.length === 0) {
10
- const errMsg = 'No records given'
11
-
12
- throw new CodeError(errMsg, 'ERR_NO_RECORDS_RECEIVED')
11
+ throw new InvalidParametersError('No records given')
13
12
  }
14
13
 
15
14
  const kStr = uint8ArrayToString(k)
16
15
  const parts = kStr.split('/')
17
16
 
18
17
  if (parts.length < 3) {
19
- const errMsg = 'Record key does not have a selector function'
20
-
21
- throw new CodeError(errMsg, 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY')
18
+ throw new InvalidParametersError('Record key does not have a selector function')
22
19
  }
23
20
 
24
21
  const selector = selectors[parts[1].toString()]
25
22
 
26
23
  if (selector == null) {
27
- const errMsg = `No selector function configured for key type "${parts[1]}"`
28
-
29
- throw new CodeError(errMsg, 'ERR_UNRECOGNIZED_KEY_PREFIX')
24
+ throw new MissingSelectorError(`No selector function configured for key type "${parts[1]}"`)
30
25
  }
31
26
 
32
27
  if (records.length === 1) {
@@ -1,5 +1,5 @@
1
- import { CodeError } from '@libp2p/interface'
2
- import { sha256 } from 'multiformats/hashes/sha2'
1
+ import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
2
+ import { InvalidParametersError } from '@libp2p/interface'
3
3
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
4
4
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
5
5
  import type { Validators } from '../index.js'
@@ -23,9 +23,7 @@ export async function verifyRecord (validators: Validators, record: Libp2pRecord
23
23
  const validator = validators[parts[1].toString()]
24
24
 
25
25
  if (validator == null) {
26
- const errMsg = `No validator available for key type "${parts[1]}"`
27
-
28
- throw new CodeError(errMsg, 'ERR_INVALID_RECORD_KEY_TYPE')
26
+ throw new InvalidParametersError(`No validator available for key type "${parts[1]}"`)
29
27
  }
30
28
 
31
29
  await validator(key, record.value)
@@ -42,25 +40,24 @@ export async function verifyRecord (validators: Validators, record: Libp2pRecord
42
40
  */
43
41
  const validatePublicKeyRecord = async (key: Uint8Array, publicKey: Uint8Array): Promise<void> => {
44
42
  if (!(key instanceof Uint8Array)) {
45
- throw new CodeError('"key" must be a Uint8Array', 'ERR_INVALID_RECORD_KEY_NOT_BUFFER')
43
+ throw new InvalidParametersError('"key" must be a Uint8Array')
46
44
  }
47
45
 
48
46
  if (key.byteLength < 5) {
49
- throw new CodeError('invalid public key record', 'ERR_INVALID_RECORD_KEY_TOO_SHORT')
47
+ throw new InvalidParametersError('Invalid public key record')
50
48
  }
51
49
 
52
50
  const prefix = uint8ArrayToString(key.subarray(0, 4))
53
51
 
54
52
  if (prefix !== '/pk/') {
55
- throw new CodeError('key was not prefixed with /pk/', 'ERR_INVALID_RECORD_KEY_BAD_PREFIX')
53
+ throw new InvalidParametersError('key was not prefixed with /pk/')
56
54
  }
57
55
 
56
+ const pubKey = publicKeyFromProtobuf(publicKey)
58
57
  const keyhash = key.slice(4)
59
58
 
60
- const publicKeyHash = await sha256.digest(publicKey)
61
-
62
- if (!uint8ArrayEquals(keyhash, publicKeyHash.bytes)) {
63
- throw new CodeError('public key does not match passed in key', 'ERR_INVALID_RECORD_HASH_MISMATCH')
59
+ if (!uint8ArrayEquals(keyhash, pubKey.toMultihash().bytes)) {
60
+ throw new InvalidParametersError('public key does not match passed in key')
64
61
  }
65
62
  }
66
63
 
@@ -1,4 +1,4 @@
1
- import { CodeError, TypedEventEmitter } from '@libp2p/interface'
1
+ import { InvalidMessageError, TypedEventEmitter } from '@libp2p/interface'
2
2
  import { PeerSet } from '@libp2p/peer-collections'
3
3
  import { PeerQueue } from '@libp2p/utils/peer-queue'
4
4
  import { pbStream } from 'it-protobuf-stream'
@@ -254,7 +254,7 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
254
254
  await pb.unwrap().close()
255
255
 
256
256
  if (response.type !== MessageType.PING) {
257
- throw new CodeError(`Incorrect message type received, expected PING got ${response.type}`, 'ERR_BAD_PING_RESPONSE')
257
+ throw new InvalidMessageError(`Incorrect message type received, expected PING got ${response.type}`)
258
258
  }
259
259
 
260
260
  return true
@@ -1,7 +1,8 @@
1
1
  import { randomBytes } from '@libp2p/crypto'
2
2
  import { setMaxListeners } from '@libp2p/interface'
3
- import { peerIdFromBytes } from '@libp2p/peer-id'
3
+ import { peerIdFromMultihash } from '@libp2p/peer-id'
4
4
  import length from 'it-length'
5
+ import * as Digest from 'multiformats/hashes/digest'
5
6
  import { sha256 } from 'multiformats/hashes/sha2'
6
7
  import { xor as uint8ArrayXor } from 'uint8arrays/xor'
7
8
  import { TABLE_REFRESH_INTERVAL, TABLE_REFRESH_QUERY_TIMEOUT } from '../constants.js'
@@ -140,7 +141,7 @@ export class RoutingTableRefresh {
140
141
  const signal = AbortSignal.timeout(this.refreshQueryTimeout)
141
142
  setMaxListeners(Infinity, signal)
142
143
 
143
- const peers = await length(this.peerRouting.getClosestPeers(peerId.toBytes(), {
144
+ const peers = await length(this.peerRouting.getClosestPeers(peerId.toMultihash().bytes, {
144
145
  signal
145
146
  }))
146
147
 
@@ -172,8 +173,9 @@ export class RoutingTableRefresh {
172
173
  const randomUint16 = (randomData[1] << 8) + randomData[0]
173
174
 
174
175
  const key = await this._makePeerId(this.routingTable.kb.localPeer.kadId, randomUint16, targetCommonPrefixLength)
176
+ const multihash = Digest.decode(key)
175
177
 
176
- return peerIdFromBytes(key)
178
+ return peerIdFromMultihash(multihash)
177
179
  }
178
180
 
179
181
  async _makePeerId (localKadId: Uint8Array, randomPrefix: number, targetCommonPrefixLength: number): Promise<Uint8Array> {
@@ -1,7 +1,8 @@
1
- import { CodeError } from '@libp2p/interface'
2
- import { peerIdFromBytes } from '@libp2p/peer-id'
1
+ import { InvalidMessageError } from '@libp2p/interface'
2
+ import { peerIdFromMultihash } from '@libp2p/peer-id'
3
3
  import { multiaddr } from '@multiformats/multiaddr'
4
4
  import { CID } from 'multiformats/cid'
5
+ import * as Digest from 'multiformats/hashes/digest'
5
6
  import type { Message } from '../../message/dht.js'
6
7
  import type { Providers } from '../../providers'
7
8
  import type { DHTMessageHandler } from '../index.js'
@@ -29,7 +30,7 @@ export class AddProviderHandler implements DHTMessageHandler {
29
30
  this.log('start')
30
31
 
31
32
  if (msg.key == null || msg.key.length === 0) {
32
- throw new CodeError('Missing key', 'ERR_MISSING_KEY')
33
+ throw new InvalidMessageError('Missing key')
33
34
  }
34
35
 
35
36
  let cid: CID
@@ -37,7 +38,7 @@ export class AddProviderHandler implements DHTMessageHandler {
37
38
  // this is actually just the multihash, not the whole CID
38
39
  cid = CID.decode(msg.key)
39
40
  } catch (err: any) {
40
- throw new CodeError('Invalid CID', 'ERR_INVALID_CID')
41
+ throw new InvalidMessageError('Invalid CID')
41
42
  }
42
43
 
43
44
  if (msg.providers == null || msg.providers.length === 0) {
@@ -59,7 +60,9 @@ export class AddProviderHandler implements DHTMessageHandler {
59
60
 
60
61
  this.log('received provider %p for %s (addrs %s)', peerId, cid, pi.multiaddrs.map((m) => multiaddr(m).toString()))
61
62
 
62
- await this.providers.addProvider(cid, peerIdFromBytes(pi.id))
63
+ const multihash = Digest.decode(pi.id)
64
+
65
+ await this.providers.addProvider(cid, peerIdFromMultihash(multihash))
63
66
  })
64
67
  )
65
68
 
@@ -1,4 +1,4 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { InvalidMessageError } from '@libp2p/interface'
2
2
  import { protocols } from '@multiformats/multiaddr'
3
3
  import { equals as uint8ArrayEquals } from 'uint8arrays'
4
4
  import { MessageType } from '../../message/dht.js'
@@ -45,12 +45,12 @@ export class FindNodeHandler implements DHTMessageHandler {
45
45
  this.log('incoming request from %p for peers closer to %b', peerId, msg.key)
46
46
 
47
47
  if (msg.key == null) {
48
- throw new CodeError('Invalid FIND_NODE message received - key was missing', 'ERR_INVALID_MESSAGE')
48
+ throw new InvalidMessageError('Invalid FIND_NODE message received - key was missing')
49
49
  }
50
50
 
51
51
  const closer: PeerInfo[] = await this.peerRouting.getCloserPeersOffline(msg.key, peerId)
52
52
 
53
- if (uint8ArrayEquals(this.peerId.toBytes(), msg.key)) {
53
+ if (uint8ArrayEquals(this.peerId.toMultihash().bytes, msg.key)) {
54
54
  closer.push({
55
55
  id: this.peerId,
56
56
  multiaddrs: this.addressManager.getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code))
@@ -64,7 +64,7 @@ export class FindNodeHandler implements DHTMessageHandler {
64
64
  .map(this.peerInfoMapper)
65
65
  .filter(({ multiaddrs }) => multiaddrs.length)
66
66
  .map(peerInfo => ({
67
- id: peerInfo.id.toBytes(),
67
+ id: peerInfo.id.toMultihash().bytes,
68
68
  multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
69
69
  })),
70
70
  providers: []
@@ -1,4 +1,4 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { InvalidMessageError } from '@libp2p/interface'
2
2
  import { CID } from 'multiformats/cid'
3
3
  import { MessageType } from '../../message/dht.js'
4
4
  import type { PeerInfoMapper } from '../../index.js'
@@ -40,14 +40,14 @@ export class GetProvidersHandler implements DHTMessageHandler {
40
40
 
41
41
  async handle (peerId: PeerId, msg: Message): Promise<Message> {
42
42
  if (msg.key == null) {
43
- throw new CodeError('Invalid GET_PROVIDERS message received - key was missing', 'ERR_INVALID_MESSAGE')
43
+ throw new InvalidMessageError('Invalid GET_PROVIDERS message received - key was missing')
44
44
  }
45
45
 
46
46
  let cid
47
47
  try {
48
48
  cid = CID.decode(msg.key)
49
49
  } catch (err: any) {
50
- throw new CodeError('Invalid CID', 'ERR_INVALID_CID')
50
+ throw new InvalidMessageError('Invalid CID')
51
51
  }
52
52
 
53
53
  this.log('%p asking for providers for %s', peerId, cid)
@@ -67,14 +67,14 @@ export class GetProvidersHandler implements DHTMessageHandler {
67
67
  .map(this.peerInfoMapper)
68
68
  .filter(({ multiaddrs }) => multiaddrs.length)
69
69
  .map(peerInfo => ({
70
- id: peerInfo.id.toBytes(),
70
+ id: peerInfo.id.toMultihash().bytes,
71
71
  multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
72
72
  })),
73
73
  providers: providerPeers
74
74
  .map(this.peerInfoMapper)
75
75
  .filter(({ multiaddrs }) => multiaddrs.length)
76
76
  .map(peerInfo => ({
77
- id: peerInfo.id.toBytes(),
77
+ id: peerInfo.id.toMultihash().bytes,
78
78
  multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
79
79
  }))
80
80
  }
@@ -104,7 +104,7 @@ export class GetProvidersHandler implements DHTMessageHandler {
104
104
  output.push(peerAfterFilter)
105
105
  }
106
106
  } catch (err: any) {
107
- if (err.code !== 'ERR_NOT_FOUND') {
107
+ if (err.name !== 'NotFoundError') {
108
108
  throw err
109
109
  }
110
110
  }
@@ -1,4 +1,5 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { publicKeyToProtobuf } from '@libp2p/crypto/keys'
2
+ import { InvalidMessageError, NotFoundError } from '@libp2p/interface'
2
3
  import { Libp2pRecord } from '@libp2p/record'
3
4
  import {
4
5
  MAX_RECORD_AGE
@@ -41,7 +42,7 @@ export class GetValueHandler implements DHTMessageHandler {
41
42
  this.log('%p asked for key %b', peerId, key)
42
43
 
43
44
  if (key == null || key.length === 0) {
44
- throw new CodeError('Invalid key', 'ERR_INVALID_KEY')
45
+ throw new InvalidMessageError('Invalid key')
45
46
  }
46
47
 
47
48
  const response: Message = {
@@ -61,12 +62,12 @@ export class GetValueHandler implements DHTMessageHandler {
61
62
  const peer = await this.peerStore.get(idFromKey)
62
63
 
63
64
  if (peer.id.publicKey == null) {
64
- throw new CodeError('No public key found in key book', 'ERR_NOT_FOUND')
65
+ throw new NotFoundError('No public key found in key book')
65
66
  }
66
67
 
67
- pubKey = peer.id.publicKey
68
+ pubKey = publicKeyToProtobuf(peer.id.publicKey)
68
69
  } catch (err: any) {
69
- if (err.code !== 'ERR_NOT_FOUND') {
70
+ if (err.name !== 'NotFoundError') {
70
71
  throw err
71
72
  }
72
73
  }
@@ -91,7 +92,7 @@ export class GetValueHandler implements DHTMessageHandler {
91
92
  if (closer.length > 0) {
92
93
  this.log('had %s closer peers in routing table', closer.length)
93
94
  response.closer = closer.map(peerInfo => ({
94
- id: peerInfo.id.toBytes(),
95
+ id: peerInfo.id.toMultihash().bytes,
95
96
  multiaddrs: peerInfo.multiaddrs.map(ma => ma.bytes)
96
97
  }))
97
98
  }
@@ -114,7 +115,7 @@ export class GetValueHandler implements DHTMessageHandler {
114
115
  try {
115
116
  rawRecord = await this.datastore.get(dsKey)
116
117
  } catch (err: any) {
117
- if (err.code === 'ERR_NOT_FOUND') {
118
+ if (err.name === 'NotFoundError') {
118
119
  return undefined
119
120
  }
120
121
  throw err
@@ -123,10 +124,6 @@ export class GetValueHandler implements DHTMessageHandler {
123
124
  // Create record from the returned bytes
124
125
  const record = Libp2pRecord.deserialize(rawRecord)
125
126
 
126
- if (record == null) {
127
- throw new CodeError('Invalid record', 'ERR_INVALID_RECORD')
128
- }
129
-
130
127
  // Check validity: compare time received with max record age
131
128
  if (record.timeReceived == null ||
132
129
  Date.now() - record.timeReceived.getTime() > MAX_RECORD_AGE) {
@@ -1,4 +1,4 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { InvalidMessageError } from '@libp2p/interface'
2
2
  import { Libp2pRecord } from '@libp2p/record'
3
3
  import { verifyRecord } from '../../record/validators.js'
4
4
  import { bufferToRecordKey } from '../../utils.js'
@@ -39,7 +39,7 @@ export class PutValueHandler implements DHTMessageHandler {
39
39
  const errMsg = `Empty record from: ${peerId.toString()}`
40
40
 
41
41
  this.log.error(errMsg)
42
- throw new CodeError(errMsg, 'ERR_EMPTY_RECORD')
42
+ throw new InvalidMessageError(errMsg)
43
43
  }
44
44
 
45
45
  try {
@@ -1,4 +1,4 @@
1
- import { CustomEvent, TypedEventEmitter } from '@libp2p/interface'
1
+ import { TypedEventEmitter } from '@libp2p/interface'
2
2
  import type { KadDHTComponents } from '.'
3
3
  import type { Logger, PeerId, Startable } from '@libp2p/interface'
4
4