@libp2p/kad-dht 13.1.1 → 13.1.2-35b48025c

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/kad-dht",
3
- "version": "13.1.1",
3
+ "version": "13.1.2-35b48025c",
4
4
  "description": "JavaScript implementation of the Kad-DHT for libp2p",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/kad-dht#readme",
@@ -57,13 +57,13 @@
57
57
  "doc-check": "aegir doc-check"
58
58
  },
59
59
  "dependencies": {
60
- "@libp2p/crypto": "^5.0.4",
61
- "@libp2p/interface": "^2.1.2",
62
- "@libp2p/interface-internal": "^2.0.6",
63
- "@libp2p/peer-collections": "^6.0.6",
64
- "@libp2p/peer-id": "^5.0.4",
65
- "@libp2p/record": "^4.0.4",
66
- "@libp2p/utils": "^6.0.6",
60
+ "@libp2p/crypto": "5.0.4-35b48025c",
61
+ "@libp2p/interface": "2.1.2-35b48025c",
62
+ "@libp2p/interface-internal": "2.0.6-35b48025c",
63
+ "@libp2p/peer-collections": "6.0.6-35b48025c",
64
+ "@libp2p/peer-id": "5.0.4-35b48025c",
65
+ "@libp2p/record": "4.0.4-35b48025c",
66
+ "@libp2p/utils": "6.0.6-35b48025c",
67
67
  "@multiformats/multiaddr": "^12.2.3",
68
68
  "any-signal": "^4.1.1",
69
69
  "hashlru": "^2.3.0",
@@ -89,9 +89,9 @@
89
89
  "uint8arrays": "^5.1.0"
90
90
  },
91
91
  "devDependencies": {
92
- "@libp2p/interface-compliance-tests": "^6.1.4",
93
- "@libp2p/logger": "^5.1.0",
94
- "@libp2p/peer-store": "^11.0.6",
92
+ "@libp2p/interface-compliance-tests": "6.1.4-35b48025c",
93
+ "@libp2p/logger": "5.1.0-35b48025c",
94
+ "@libp2p/peer-store": "11.0.6-35b48025c",
95
95
  "@types/lodash.random": "^3.2.9",
96
96
  "@types/lodash.range": "^3.2.9",
97
97
  "@types/sinon": "^17.0.3",
package/src/index.ts CHANGED
@@ -397,12 +397,10 @@ export interface KadDHTInit {
397
397
  logPrefix?: string
398
398
 
399
399
  /**
400
- * How long to wait in ms when pinging DHT peers to decide if they
401
- * should be evicted from the routing table or not.
402
- *
403
- * @default 10000
400
+ * Settings for how long to wait in ms when pinging DHT peers to decide if
401
+ * they should be evicted from the routing table or not.
404
402
  */
405
- pingTimeout?: number
403
+ pingTimeout?: Omit<AdaptiveTimeoutInit, 'metricsName' | 'metrics'>
406
404
 
407
405
  /**
408
406
  * How many peers to ping in parallel when deciding if they should
package/src/kad-dht.ts CHANGED
@@ -161,7 +161,9 @@ export class KadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implements Ka
161
161
  pingTimeout,
162
162
  pingConcurrency,
163
163
  protocol: this.protocol,
164
- logPrefix: loggingPrefix
164
+ logPrefix: loggingPrefix,
165
+ prefixLength: init.prefixLength,
166
+ splitThreshold: init.kBucketSplitThreshold
165
167
  })
166
168
 
167
169
  this.providers = new Providers(components, providersInit ?? {})
package/src/network.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  queryErrorEvent
12
12
  } from './query/events.js'
13
13
  import type { KadDHTComponents, QueryEvent } from './index.js'
14
- import type { AbortOptions, Logger, Stream, PeerId, PeerInfo, Startable, RoutingOptions } from '@libp2p/interface'
14
+ import type { AbortOptions, Logger, Stream, PeerId, PeerInfo, Startable, RoutingOptions, CounterGroup } from '@libp2p/interface'
15
15
 
16
16
  export interface NetworkInit {
17
17
  protocol: string
@@ -32,6 +32,10 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
32
32
  private running: boolean
33
33
  private readonly components: KadDHTComponents
34
34
  private readonly timeout: AdaptiveTimeout
35
+ private readonly metrics: {
36
+ operations?: CounterGroup
37
+ errors?: CounterGroup
38
+ }
35
39
 
36
40
  /**
37
41
  * Create a new network
@@ -49,6 +53,10 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
49
53
  metrics: components.metrics,
50
54
  metricName: `${init.logPrefix.replaceAll(':', '_')}_network_message_send_times_milliseconds`
51
55
  })
56
+ this.metrics = {
57
+ operations: components.metrics?.registerCounterGroup(`${init.logPrefix.replaceAll(':', '_')}_outbound_rpc_requests_total`),
58
+ errors: components.metrics?.registerCounterGroup(`${init.logPrefix.replaceAll(':', '_')}_outbound_rpc_errors_total`)
59
+ }
52
60
  }
53
61
 
54
62
  /**
@@ -103,6 +111,8 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
103
111
  }
104
112
 
105
113
  try {
114
+ this.metrics.operations?.increment({ [type]: true })
115
+
106
116
  const connection = await this.components.connectionManager.openConnection(to, options)
107
117
  stream = await connection.newStream(this.protocol, options)
108
118
  const response = await this._writeReadMessage(stream, msg, options)
@@ -121,6 +131,8 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
121
131
  record: response.record == null ? undefined : Libp2pRecord.deserialize(response.record)
122
132
  }, options)
123
133
  } catch (err: any) {
134
+ this.metrics.errors?.increment({ [type]: true })
135
+
124
136
  stream?.abort(err)
125
137
 
126
138
  // only log if the incoming signal was not aborted - this means we were
@@ -162,6 +174,8 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
162
174
  }
163
175
 
164
176
  try {
177
+ this.metrics.operations?.increment({ [type]: true })
178
+
165
179
  const connection = await this.components.connectionManager.openConnection(to, options)
166
180
  stream = await connection.newStream(this.protocol, options)
167
181
 
@@ -175,6 +189,8 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
175
189
 
176
190
  yield peerResponseEvent({ from: to, messageType: type }, options)
177
191
  } catch (err: any) {
192
+ this.metrics.errors?.increment({ [type]: true })
193
+
178
194
  stream?.abort(err)
179
195
  yield queryErrorEvent({ from: to, error: err }, options)
180
196
  } finally {
@@ -12,7 +12,7 @@ import { queryPath } from './query-path.js'
12
12
  import type { QueryFunc } from './types.js'
13
13
  import type { QueryEvent } from '../index.js'
14
14
  import type { RoutingTable } from '../routing-table/index.js'
15
- import type { ComponentLogger, Metric, Metrics, PeerId, RoutingOptions, Startable } from '@libp2p/interface'
15
+ import type { ComponentLogger, Counter, Metric, Metrics, PeerId, RoutingOptions, Startable } from '@libp2p/interface'
16
16
  import type { ConnectionManager } from '@libp2p/interface-internal'
17
17
  import type { DeferredPromise } from 'p-defer'
18
18
 
@@ -52,16 +52,16 @@ export class QueryManager implements Startable {
52
52
  private readonly alpha: number
53
53
  private shutDownController: AbortController
54
54
  private running: boolean
55
- private queries: number
56
55
  private readonly logger: ComponentLogger
57
56
  private readonly peerId: PeerId
58
57
  private readonly connectionManager: ConnectionManager
59
58
  private readonly routingTable: RoutingTable
60
59
  private initialQuerySelfHasRun?: DeferredPromise<void>
61
60
  private readonly logPrefix: string
62
- private readonly metrics?: {
63
- runningQueries: Metric
64
- queryTime: Metric
61
+ private readonly metrics: {
62
+ queries?: Counter
63
+ errors?: Counter
64
+ queryTime?: Metric
65
65
  }
66
66
 
67
67
  constructor (components: QueryManagerComponents, init: QueryManagerInit) {
@@ -71,18 +71,16 @@ export class QueryManager implements Startable {
71
71
  this.disjointPaths = disjointPaths ?? K
72
72
  this.running = false
73
73
  this.alpha = alpha ?? ALPHA
74
- this.queries = 0
75
74
  this.initialQuerySelfHasRun = init.initialQuerySelfHasRun
76
75
  this.routingTable = init.routingTable
77
76
  this.logger = components.logger
78
77
  this.peerId = components.peerId
79
78
  this.connectionManager = components.connectionManager
80
79
 
81
- if (components.metrics != null) {
82
- this.metrics = {
83
- runningQueries: components.metrics.registerMetric(`${logPrefix.replaceAll(':', '_')}_running_queries`),
84
- queryTime: components.metrics.registerMetric(`${logPrefix.replaceAll(':', '_')}_query_time_seconds`)
85
- }
80
+ this.metrics = {
81
+ queries: components.metrics?.registerCounter(`${logPrefix.replaceAll(':', '_')}_queries_total`),
82
+ errors: components.metrics?.registerCounter(`${logPrefix.replaceAll(':', '_')}_query_errors_total`),
83
+ queryTime: components.metrics?.registerMetric(`${logPrefix.replaceAll(':', '_')}_query_time_seconds`)
86
84
  }
87
85
 
88
86
  // allow us to stop queries on shut down
@@ -121,7 +119,7 @@ export class QueryManager implements Startable {
121
119
  throw new Error('QueryManager not started')
122
120
  }
123
121
 
124
- const stopQueryTimer = this.metrics?.queryTime.timer()
122
+ const stopQueryTimer = this.metrics.queryTime?.timer()
125
123
 
126
124
  if (options.signal == null) {
127
125
  // don't let queries run forever
@@ -167,8 +165,7 @@ export class QueryManager implements Startable {
167
165
  }
168
166
 
169
167
  log('query:start')
170
- this.queries++
171
- this.metrics?.runningQueries.update(this.queries)
168
+ this.metrics?.queries?.increment()
172
169
 
173
170
  const id = await convertBuffer(key)
174
171
  const peers = this.routingTable.closestPeers(id)
@@ -223,6 +220,10 @@ export class QueryManager implements Startable {
223
220
 
224
221
  queryFinished = true
225
222
  } catch (err: any) {
223
+ if (!queryFinished) {
224
+ this.metrics?.errors?.increment()
225
+ }
226
+
226
227
  if (!this.running && err.name === 'QueryAbortedError') {
227
228
  // ignore query aborted errors that were thrown during query manager shutdown
228
229
  } else {
@@ -236,13 +237,7 @@ export class QueryManager implements Startable {
236
237
 
237
238
  signal.clear()
238
239
 
239
- this.queries--
240
- this.metrics?.runningQueries.update(this.queries)
241
-
242
- if (stopQueryTimer != null) {
243
- stopQueryTimer()
244
- }
245
-
240
+ stopQueryTimer?.()
246
241
  log('query:done in %dms', Date.now() - startTime)
247
242
  }
248
243
  }
@@ -1,19 +1,21 @@
1
- import { InvalidMessageError, TypedEventEmitter } from '@libp2p/interface'
1
+ import { InvalidMessageError, KEEP_ALIVE, TypedEventEmitter } from '@libp2p/interface'
2
2
  import { PeerSet } from '@libp2p/peer-collections'
3
+ import { AdaptiveTimeout } from '@libp2p/utils/adaptive-timeout'
3
4
  import { PeerQueue } from '@libp2p/utils/peer-queue'
4
5
  import { pbStream } from 'it-protobuf-stream'
5
6
  import { Message, MessageType } from '../message/dht.js'
6
7
  import * as utils from '../utils.js'
7
8
  import { KBucket, isLeafBucket, type Bucket, type PingEventDetails } from './k-bucket.js'
8
- import type { ComponentLogger, Logger, Metric, Metrics, PeerId, PeerStore, Startable, Stream } from '@libp2p/interface'
9
+ import type { ComponentLogger, CounterGroup, Logger, Metric, Metrics, PeerId, PeerStore, Startable, Stream } from '@libp2p/interface'
9
10
  import type { ConnectionManager } from '@libp2p/interface-internal'
11
+ import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
10
12
 
11
13
  export const KAD_CLOSE_TAG_NAME = 'kad-close'
12
14
  export const KAD_CLOSE_TAG_VALUE = 50
13
15
  export const KBUCKET_SIZE = 20
14
16
  export const PREFIX_LENGTH = 32
15
- export const PING_TIMEOUT = 10000
16
- export const PING_CONCURRENCY = 10
17
+ export const PING_TIMEOUT = 2000
18
+ export const PING_CONCURRENCY = 20
17
19
 
18
20
  export interface RoutingTableInit {
19
21
  logPrefix: string
@@ -21,7 +23,7 @@ export interface RoutingTableInit {
21
23
  prefixLength?: number
22
24
  splitThreshold?: number
23
25
  kBucketSize?: number
24
- pingTimeout?: number
26
+ pingTimeout?: AdaptiveTimeoutInit
25
27
  pingConcurrency?: number
26
28
  tagName?: string
27
29
  tagValue?: number
@@ -53,7 +55,7 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
53
55
  private readonly components: RoutingTableComponents
54
56
  private readonly prefixLength: number
55
57
  private readonly splitThreshold: number
56
- private readonly pingTimeout: number
58
+ private readonly pingTimeout: AdaptiveTimeout
57
59
  private readonly pingConcurrency: number
58
60
  private running: boolean
59
61
  private readonly protocol: string
@@ -64,6 +66,7 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
64
66
  routingTableKadBucketTotal: Metric
65
67
  routingTableKadBucketAverageOccupancy: Metric
66
68
  routingTableKadBucketMaxDepth: Metric
69
+ kadBucketEvents: CounterGroup<'ping' | 'ping_error' | 'peer_added' | 'peer_removed'>
67
70
  }
68
71
 
69
72
  constructor (components: RoutingTableComponents, init: RoutingTableInit) {
@@ -72,7 +75,6 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
72
75
  this.components = components
73
76
  this.log = components.logger.forComponent(`${init.logPrefix}:routing-table`)
74
77
  this.kBucketSize = init.kBucketSize ?? KBUCKET_SIZE
75
- this.pingTimeout = init.pingTimeout ?? PING_TIMEOUT
76
78
  this.pingConcurrency = init.pingConcurrency ?? PING_CONCURRENCY
77
79
  this.running = false
78
80
  this.protocol = init.protocol
@@ -89,13 +91,19 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
89
91
  this.pingQueue.addEventListener('error', evt => {
90
92
  this.log.error('error pinging peer', evt.detail)
91
93
  })
94
+ this.pingTimeout = new AdaptiveTimeout({
95
+ ...(init.pingTimeout ?? {}),
96
+ metrics: this.components.metrics,
97
+ metricName: `${init.logPrefix.replaceAll(':', '_')}_routing_table_ping_time_milliseconds`
98
+ })
92
99
 
93
100
  if (this.components.metrics != null) {
94
101
  this.metrics = {
95
102
  routingTableSize: this.components.metrics.registerMetric(`${init.logPrefix.replaceAll(':', '_')}_routing_table_size`),
96
103
  routingTableKadBucketTotal: this.components.metrics.registerMetric(`${init.logPrefix.replaceAll(':', '_')}_routing_table_kad_bucket_total`),
97
104
  routingTableKadBucketAverageOccupancy: this.components.metrics.registerMetric(`${init.logPrefix.replaceAll(':', '_')}_routing_table_kad_bucket_average_occupancy`),
98
- routingTableKadBucketMaxDepth: this.components.metrics.registerMetric(`${init.logPrefix.replaceAll(':', '_')}_routing_table_kad_bucket_max_depth`)
105
+ routingTableKadBucketMaxDepth: this.components.metrics.registerMetric(`${init.logPrefix.replaceAll(':', '_')}_routing_table_kad_bucket_max_depth`),
106
+ kadBucketEvents: this.components.metrics.registerCounterGroup(`${init.logPrefix.replaceAll(':', '_')}_kad_bucket_events_total`)
99
107
  }
100
108
  }
101
109
  }
@@ -121,7 +129,10 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
121
129
 
122
130
  // test whether to evict peers
123
131
  kBuck.addEventListener('ping', (evt) => {
132
+ this.metrics?.kadBucketEvents.increment({ ping: true })
133
+
124
134
  this._onPing(evt).catch(err => {
135
+ this.metrics?.kadBucketEvents.increment({ ping_error: true })
125
136
  this.log.error('could not process k-bucket ping event', err)
126
137
  })
127
138
  })
@@ -172,6 +183,9 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
172
183
  tags: {
173
184
  [this.tagName]: {
174
185
  value: this.tagValue
186
+ },
187
+ [KEEP_ALIVE]: {
188
+ value: 1
175
189
  }
176
190
  }
177
191
  })
@@ -180,7 +194,8 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
180
194
  for (const peer of removedPeers) {
181
195
  await this.components.peerStore.merge(peer, {
182
196
  tags: {
183
- [this.tagName]: undefined
197
+ [this.tagName]: undefined,
198
+ [KEEP_ALIVE]: undefined
184
199
  }
185
200
  })
186
201
  }
@@ -195,11 +210,13 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
195
210
  kBuck.addEventListener('added', (evt) => {
196
211
  updatePeerTags()
197
212
 
213
+ this.metrics?.kadBucketEvents.increment({ peer_added: true })
198
214
  this.safeDispatchEvent('peer:add', { detail: evt.detail.peerId })
199
215
  })
200
216
  kBuck.addEventListener('removed', (evt) => {
201
217
  updatePeerTags()
202
218
 
219
+ this.metrics?.kadBucketEvents.increment({ peer_removed: true })
203
220
  this.safeDispatchEvent('peer:remove', { detail: evt.detail.peerId })
204
221
  })
205
222
  }
@@ -235,43 +252,48 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
235
252
 
236
253
  return this.pingQueue.add(async () => {
237
254
  let stream: Stream | undefined
255
+ const signal = this.pingTimeout.getTimeoutSignal()
238
256
 
239
257
  try {
240
258
  const options = {
241
- signal: AbortSignal.timeout(this.pingTimeout)
259
+ signal
242
260
  }
243
261
 
244
262
  this.log('pinging old contact %p', oldContact.peerId)
245
263
  const connection = await this.components.connectionManager.openConnection(oldContact.peerId, options)
246
264
  stream = await connection.newStream(this.protocol, options)
247
265
 
248
- const pb = pbStream(stream)
266
+ const pb = pbStream(stream).pb(Message)
249
267
  await pb.write({
250
- type: MessageType.PING
251
- }, Message, options)
252
- const response = await pb.read(Message, options)
268
+ type: MessageType.PING,
269
+ closer: [],
270
+ providers: []
271
+ }, options)
272
+ const response = await pb.read(options)
253
273
 
254
- await pb.unwrap().close()
274
+ await pb.unwrap().unwrap().close(options)
255
275
 
256
276
  if (response.type !== MessageType.PING) {
257
277
  throw new InvalidMessageError(`Incorrect message type received, expected PING got ${response.type}`)
258
278
  }
259
279
 
280
+ this.log('old contact %p ping ok', oldContact.peerId)
260
281
  return true
261
282
  } catch (err: any) {
262
- if (this.running && this.kb != null) {
283
+ if (this.running) {
263
284
  // only evict peers if we are still running, otherwise we evict
264
285
  // when dialing is cancelled due to shutdown in progress
265
- this.log.error('could not ping peer %p', oldContact.peerId, err)
286
+ this.log.error('could not ping peer %p - %e', oldContact.peerId, err)
266
287
  this.log('evicting old contact after ping failed %p', oldContact.peerId)
267
- this.kb.remove(oldContact.kadId)
288
+ this.kb?.remove(oldContact.kadId)
268
289
  }
269
290
 
270
291
  stream?.abort(err)
271
292
 
272
293
  return false
273
294
  } finally {
274
- this.metrics?.routingTableSize.update(this.size)
295
+ this.pingTimeout.cleanUp(signal)
296
+ this.updateMetrics()
275
297
  }
276
298
  }, {
277
299
  peerId: oldContact.peerId
@@ -1,56 +0,0 @@
1
- {
2
- "codec": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.MessageType.codec.html",
3
- "EventTypes": "https://libp2p.github.io/js-libp2p/enums/_libp2p_kad_dht.EventTypes.html",
4
- ".:EventTypes": "https://libp2p.github.io/js-libp2p/enums/_libp2p_kad_dht.EventTypes.html",
5
- "MessageType": "https://libp2p.github.io/js-libp2p/enums/_libp2p_kad_dht.MessageType-1.html",
6
- "AddPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.AddPeerEvent.html",
7
- ".:AddPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.AddPeerEvent.html",
8
- "DHTRecord": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.DHTRecord.html",
9
- ".:DHTRecord": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.DHTRecord.html",
10
- "DialPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.DialPeerEvent.html",
11
- ".:DialPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.DialPeerEvent.html",
12
- "FinalPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.FinalPeerEvent.html",
13
- ".:FinalPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.FinalPeerEvent.html",
14
- "KadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHT.html",
15
- ".:KadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHT.html",
16
- "KadDHTComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHTComponents.html",
17
- ".:KadDHTComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHTComponents.html",
18
- "KadDHTInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHTInit.html",
19
- ".:KadDHTInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.KadDHTInit.html",
20
- "PeerInfoMapper": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.PeerInfoMapper.html",
21
- ".:PeerInfoMapper": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.PeerInfoMapper.html",
22
- "PeerResponseEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.PeerResponseEvent.html",
23
- ".:PeerResponseEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.PeerResponseEvent.html",
24
- "ProviderEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ProviderEvent.html",
25
- ".:ProviderEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ProviderEvent.html",
26
- "ProvidersInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ProvidersInit.html",
27
- "QueryErrorEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.QueryErrorEvent.html",
28
- ".:QueryErrorEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.QueryErrorEvent.html",
29
- "RoutingTable": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.RoutingTable.html",
30
- ".:RoutingTable": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.RoutingTable.html",
31
- "SelectFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SelectFn.html",
32
- ".:SelectFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SelectFn.html",
33
- "SendQueryEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SendQueryEvent.html",
34
- ".:SendQueryEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SendQueryEvent.html",
35
- "SingleKadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SingleKadDHT.html",
36
- ".:SingleKadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.SingleKadDHT.html",
37
- "ValidateFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ValidateFn.html",
38
- ".:ValidateFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ValidateFn.html",
39
- "ValueEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ValueEvent.html",
40
- ".:ValueEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad_dht.ValueEvent.html",
41
- "DHTProgressEvents": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.DHTProgressEvents.html",
42
- ".:DHTProgressEvents": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.DHTProgressEvents.html",
43
- "MessageName": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.MessageName.html",
44
- ".:MessageName": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.MessageName.html",
45
- "QueryEvent": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.QueryEvent.html",
46
- ".:QueryEvent": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.QueryEvent.html",
47
- "Selectors": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.Selectors.html",
48
- ".:Selectors": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.Selectors.html",
49
- "Validators": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.Validators.html",
50
- ".:Validators": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad_dht.Validators.html",
51
- "kadDHT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.kadDHT-1.html",
52
- ".:kadDHT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.kadDHT-1.html",
53
- "passthroughMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.passthroughMapper.html",
54
- "removePrivateAddressesMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.removePrivateAddressesMapper.html",
55
- "removePublicAddressesMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad_dht.removePublicAddressesMapper.html"
56
- }