@libp2p/kad-dht 15.1.10 → 15.1.11-a02cb0461

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 (58) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/constants.d.ts +0 -1
  4. package/dist/src/constants.d.ts.map +1 -1
  5. package/dist/src/constants.js +0 -1
  6. package/dist/src/constants.js.map +1 -1
  7. package/dist/src/content-routing/index.js +3 -3
  8. package/dist/src/content-routing/index.js.map +1 -1
  9. package/dist/src/index.d.ts +1 -1
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/kad-dht.js +1 -1
  12. package/dist/src/kad-dht.js.map +1 -1
  13. package/dist/src/network.d.ts +1 -1
  14. package/dist/src/network.d.ts.map +1 -1
  15. package/dist/src/network.js +3 -6
  16. package/dist/src/network.js.map +1 -1
  17. package/dist/src/peer-routing/index.js +1 -1
  18. package/dist/src/peer-routing/index.js.map +1 -1
  19. package/dist/src/query/manager.js +1 -1
  20. package/dist/src/query/manager.js.map +1 -1
  21. package/dist/src/query/query-path.d.ts +1 -1
  22. package/dist/src/query/query-path.d.ts.map +1 -1
  23. package/dist/src/query/query-path.js +4 -4
  24. package/dist/src/query/query-path.js.map +1 -1
  25. package/dist/src/reprovider.d.ts +6 -2
  26. package/dist/src/reprovider.d.ts.map +1 -1
  27. package/dist/src/reprovider.js +29 -10
  28. package/dist/src/reprovider.js.map +1 -1
  29. package/dist/src/routing-table/index.d.ts +1 -1
  30. package/dist/src/routing-table/index.d.ts.map +1 -1
  31. package/dist/src/routing-table/index.js +3 -2
  32. package/dist/src/routing-table/index.js.map +1 -1
  33. package/dist/src/rpc/handlers/get-value.d.ts +1 -1
  34. package/dist/src/rpc/handlers/get-value.js +3 -3
  35. package/dist/src/rpc/handlers/get-value.js.map +1 -1
  36. package/dist/src/rpc/index.d.ts +2 -2
  37. package/dist/src/rpc/index.d.ts.map +1 -1
  38. package/dist/src/rpc/index.js +42 -47
  39. package/dist/src/rpc/index.js.map +1 -1
  40. package/dist/src/utils.d.ts +0 -1
  41. package/dist/src/utils.d.ts.map +1 -1
  42. package/dist/src/utils.js +1 -8
  43. package/dist/src/utils.js.map +1 -1
  44. package/package.json +32 -35
  45. package/src/constants.ts +0 -2
  46. package/src/content-routing/index.ts +3 -3
  47. package/src/index.ts +1 -1
  48. package/src/kad-dht.ts +1 -1
  49. package/src/network.ts +4 -7
  50. package/src/peer-routing/index.ts +1 -1
  51. package/src/query/manager.ts +1 -1
  52. package/src/query/query-path.ts +5 -5
  53. package/src/reprovider.ts +33 -12
  54. package/src/routing-table/index.ts +5 -3
  55. package/src/rpc/handlers/get-value.ts +3 -3
  56. package/src/rpc/index.ts +47 -51
  57. package/src/utils.ts +1 -10
  58. package/dist/typedoc-urls.json +0 -65
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/kad-dht",
3
- "version": "15.1.10",
3
+ "version": "15.1.11-a02cb0461",
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",
@@ -47,61 +47,58 @@
47
47
  "doc-check": "aegir doc-check"
48
48
  },
49
49
  "dependencies": {
50
- "@libp2p/crypto": "^5.1.7",
51
- "@libp2p/interface": "^2.10.5",
52
- "@libp2p/interface-internal": "^2.3.18",
53
- "@libp2p/peer-collections": "^6.0.34",
54
- "@libp2p/peer-id": "^5.1.8",
55
- "@libp2p/ping": "^2.0.36",
56
- "@libp2p/record": "^4.0.7",
57
- "@libp2p/utils": "^6.7.1",
58
- "@multiformats/multiaddr": "^12.4.4",
50
+ "@libp2p/crypto": "5.1.8-a02cb0461",
51
+ "@libp2p/interface": "2.11.0-a02cb0461",
52
+ "@libp2p/interface-internal": "2.3.19-a02cb0461",
53
+ "@libp2p/peer-collections": "6.0.35-a02cb0461",
54
+ "@libp2p/peer-id": "5.1.9-a02cb0461",
55
+ "@libp2p/ping": "2.0.37-a02cb0461",
56
+ "@libp2p/record": "4.0.7-a02cb0461",
57
+ "@libp2p/utils": "6.7.2-a02cb0461",
58
+ "@multiformats/multiaddr": "^12.5.1",
59
59
  "any-signal": "^4.1.1",
60
- "interface-datastore": "^8.3.1",
61
- "it-all": "^3.0.8",
62
- "it-drain": "^3.0.9",
63
- "it-length": "^3.0.8",
64
- "it-map": "^3.1.3",
65
- "it-merge": "^3.0.11",
66
- "it-parallel": "^3.0.11",
60
+ "interface-datastore": "^8.3.2",
61
+ "it-all": "^3.0.9",
62
+ "it-drain": "^3.0.10",
63
+ "it-length": "^3.0.9",
64
+ "it-map": "^3.1.4",
65
+ "it-merge": "^3.0.12",
66
+ "it-parallel": "^3.0.13",
67
67
  "it-pipe": "^3.0.1",
68
- "it-protobuf-stream": "^2.0.2",
69
68
  "it-pushable": "^3.2.3",
70
- "it-take": "^3.0.8",
69
+ "it-take": "^3.0.9",
71
70
  "main-event": "^1.0.1",
72
- "multiformats": "^13.3.6",
71
+ "multiformats": "^13.4.0",
73
72
  "p-defer": "^4.0.1",
74
73
  "p-event": "^6.0.1",
75
74
  "progress-events": "^1.0.1",
76
- "protons-runtime": "^5.5.0",
77
- "race-signal": "^1.1.3",
75
+ "protons-runtime": "^5.6.0",
76
+ "race-signal": "^2.0.0",
78
77
  "uint8-varint": "^2.0.4",
79
78
  "uint8arraylist": "^2.4.8",
80
79
  "uint8arrays": "^5.1.0"
81
80
  },
82
81
  "devDependencies": {
83
- "@libp2p/interface-compliance-tests": "^6.4.16",
84
- "@libp2p/logger": "^5.1.21",
85
- "@libp2p/peer-store": "^11.2.6",
82
+ "@libp2p/logger": "5.2.0-a02cb0461",
83
+ "@libp2p/peer-store": "11.2.7-a02cb0461",
86
84
  "@types/lodash.random": "^3.2.9",
87
85
  "@types/lodash.range": "^3.2.9",
88
86
  "@types/sinon": "^17.0.4",
89
87
  "@types/which": "^3.0.4",
90
- "aegir": "^47.0.14",
88
+ "aegir": "^47.0.21",
91
89
  "benchmark": "^2.1.4",
92
- "datastore-core": "^10.0.2",
90
+ "datastore-core": "^10.0.4",
93
91
  "delay": "^6.0.0",
94
- "execa": "^9.5.3",
95
- "it-filter": "^3.1.3",
96
- "it-last": "^3.0.8",
92
+ "execa": "^9.6.0",
93
+ "it-filter": "^3.1.4",
94
+ "it-first": "^3.0.9",
95
+ "it-last": "^3.0.9",
97
96
  "it-length-prefixed": "^10.0.1",
98
- "it-pair": "^2.0.6",
99
- "it-stream-types": "^2.0.2",
100
97
  "lodash.random": "^3.2.0",
101
98
  "lodash.range": "^3.2.0",
102
- "p-retry": "^6.2.1",
103
- "protons": "^7.6.1",
104
- "sinon": "^20.0.0",
99
+ "p-retry": "^7.0.0",
100
+ "protons": "^7.7.0",
101
+ "sinon": "^21.0.0",
105
102
  "sinon-ts": "^2.0.0",
106
103
  "which": "^5.0.0"
107
104
  },
package/src/constants.ts CHANGED
@@ -4,8 +4,6 @@ export const second = 1000
4
4
  export const minute = 60 * second
5
5
  export const hour = 60 * minute
6
6
 
7
- export const MAX_RECORD_AGE = 36 * hour
8
-
9
7
  export const PROTOCOL = '/ipfs/kad/1.0.0'
10
8
 
11
9
  /**
@@ -1,5 +1,5 @@
1
1
  import { PeerSet } from '@libp2p/peer-collections'
2
- import { Queue } from '@libp2p/utils/queue'
2
+ import { Queue } from '@libp2p/utils'
3
3
  import { pushable } from 'it-pushable'
4
4
  import { ALPHA } from '../constants.js'
5
5
  import { MessageType } from '../message/dht.js'
@@ -134,8 +134,8 @@ export class ContentRouting {
134
134
  queue.addEventListener('idle', () => {
135
135
  events.end()
136
136
  })
137
- queue.addEventListener('error', (err) => {
138
- this.log.error('error publishing provider record to peer - %e', err)
137
+ queue.addEventListener('failure', (event) => {
138
+ this.log.error('error publishing provider record to peer - %e', event.detail.error)
139
139
  })
140
140
 
141
141
  queue.add(async () => {
package/src/index.ts CHANGED
@@ -138,7 +138,7 @@ import { removePrivateAddressesMapper, removePublicAddressesMapper, passthroughM
138
138
  import type { Libp2pEvents, ComponentLogger, Metrics, PeerId, PeerInfo, PeerStore, RoutingOptions, PrivateKey, AbortOptions } from '@libp2p/interface'
139
139
  import type { AddressManager, ConnectionManager, Registrar } from '@libp2p/interface-internal'
140
140
  import type { Ping } from '@libp2p/ping'
141
- import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
141
+ import type { AdaptiveTimeoutInit } from '@libp2p/utils'
142
142
  import type { Datastore } from 'interface-datastore'
143
143
  import type { TypedEventTarget } from 'main-event'
144
144
  import type { CID } from 'multiformats/cid'
package/src/kad-dht.ts CHANGED
@@ -387,7 +387,7 @@ export class KadDHT extends TypedEventEmitter<PeerDiscoveryEvents> implements Ka
387
387
  }
388
388
 
389
389
  async onPeerConnect (peerData: PeerInfo): Promise<void> {
390
- this.log.trace('peer %p connected', peerData.id)
390
+ this.log.trace('peer %p connected', peerData.id, peerData.multiaddrs)
391
391
 
392
392
  peerData = this.peerInfoMapper(peerData)
393
393
 
package/src/network.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { InvalidParametersError } from '@libp2p/interface'
2
2
  import { Libp2pRecord } from '@libp2p/record'
3
- import { AdaptiveTimeout } from '@libp2p/utils/adaptive-timeout'
4
- import { pbStream } from 'it-protobuf-stream'
3
+ import { AdaptiveTimeout, pbStream } from '@libp2p/utils'
5
4
  import { TypedEventEmitter } from 'main-event'
6
5
  import { Message } from './message/dht.js'
7
6
  import { fromPbPeerInfo } from './message/utils.js'
@@ -13,7 +12,7 @@ import {
13
12
  } from './query/events.js'
14
13
  import type { DisjointPath, KadDHTComponents, QueryEvent } from './index.js'
15
14
  import type { AbortOptions, Logger, Stream, PeerId, PeerInfo, Startable, RoutingOptions, CounterGroup } from '@libp2p/interface'
16
- import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
15
+ import type { AdaptiveTimeoutInit } from '@libp2p/utils'
17
16
 
18
17
  export interface NetworkInit {
19
18
  protocol: string
@@ -178,8 +177,7 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
178
177
  this.log('dialling %p', to)
179
178
  yield dialPeerEvent({ peer: to, path: options.path }, options)
180
179
 
181
- const connection = await this.components.connectionManager.openConnection(to, options)
182
- stream = await connection.newStream(this.protocol, options)
180
+ stream = await this.components.connectionManager.openStream(to, this.protocol, options)
183
181
 
184
182
  this.log('sending %s to %p', msg.type, to)
185
183
  yield sendQueryEvent({ to, type, path: options.path }, options)
@@ -245,8 +243,7 @@ export class Network extends TypedEventEmitter<NetworkEvents> implements Startab
245
243
  this.log('dialling %p', to)
246
244
  yield dialPeerEvent({ peer: to, path: options.path }, options)
247
245
 
248
- const connection = await this.components.connectionManager.openConnection(to, options)
249
- stream = await connection.newStream(this.protocol, options)
246
+ stream = await this.components.connectionManager.openStream(to, this.protocol, options)
250
247
 
251
248
  this.log('sending %s to %p', msg.type, to)
252
249
  yield sendQueryEvent({ to, type, path: options.path }, options)
@@ -367,7 +367,7 @@ export class PeerRouting {
367
367
  }
368
368
 
369
369
  if (output.length > 0) {
370
- this.log('getClosestPeersOffline returning the %d closest peer(s) %b we know', output.length, key)
370
+ this.log('getClosestPeersOffline returning the %d closest peer(s) we know to %b', output.length, key)
371
371
  } else {
372
372
  this.log('getClosestPeersOffline could not any peers close to %b with %d peers in the routing table', key, this.routingTable.size)
373
373
  }
@@ -1,4 +1,4 @@
1
- import { createScalableCuckooFilter } from '@libp2p/utils/filters'
1
+ import { createScalableCuckooFilter } from '@libp2p/utils'
2
2
  import { anySignal } from 'any-signal'
3
3
  import merge from 'it-merge'
4
4
  import { setMaxListeners } from 'main-event'
@@ -1,5 +1,5 @@
1
1
  import { AbortError } from '@libp2p/interface'
2
- import { Queue } from '@libp2p/utils/queue'
2
+ import { Queue } from '@libp2p/utils'
3
3
  import { pushable } from 'it-pushable'
4
4
  import { xor as uint8ArrayXor } from 'uint8arrays/xor'
5
5
  import { xorCompare as uint8ArrayXorCompare } from 'uint8arrays/xor-compare'
@@ -9,7 +9,7 @@ import type { QueryEvent } from '../index.js'
9
9
  import type { QueryFunc } from '../query/types.js'
10
10
  import type { Logger, PeerId, RoutingOptions, AbortOptions, PeerInfo } from '@libp2p/interface'
11
11
  import type { ConnectionManager } from '@libp2p/interface-internal'
12
- import type { Filter } from '@libp2p/utils/filters'
12
+ import type { Filter } from '@libp2p/utils'
13
13
 
14
14
  export interface QueryPathOptions extends RoutingOptions {
15
15
  /**
@@ -100,8 +100,8 @@ export async function * queryPath (options: QueryPathOptions): AsyncGenerator<Qu
100
100
 
101
101
  events.end()
102
102
  })
103
- queue.addEventListener('error', (evt) => {
104
- log.error('error during query - %e', evt.detail)
103
+ queue.addEventListener('failure', (evt) => {
104
+ log.error('error during query - %e', evt.detail.error)
105
105
  })
106
106
 
107
107
  const onAbort = (): void => {
@@ -171,7 +171,7 @@ export async function * queryPath (options: QueryPathOptions): AsyncGenerator<Qu
171
171
 
172
172
  // only continue query if closer peer is actually closer
173
173
  if (uint8ArrayXorCompare(closerPeerXor, peerXor) !== -1) { // eslint-disable-line max-depth
174
- log('skipping %p as they are not closer to %b than %p', closerPeer.id, key, peer)
174
+ log('skipping %p as they are not closer to %b than %p', closerPeer.id, key, peer.id)
175
175
  continue
176
176
  }
177
177
 
package/src/reprovider.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { AdaptiveTimeout } from '@libp2p/utils/adaptive-timeout'
2
- import { Queue } from '@libp2p/utils/queue'
1
+ import { AdaptiveTimeout, Queue } from '@libp2p/utils'
3
2
  import drain from 'it-drain'
4
3
  import { TypedEventEmitter, setMaxListeners } from 'main-event'
5
4
  import { PROVIDERS_VALIDITY, REPROVIDE_CONCURRENCY, REPROVIDE_INTERVAL, REPROVIDE_MAX_QUEUE_SIZE, REPROVIDE_THRESHOLD, REPROVIDE_TIMEOUT } from './constants.js'
@@ -8,7 +7,7 @@ import type { ContentRouting } from './content-routing/index.js'
8
7
  import type { OperationMetrics } from './kad-dht.js'
9
8
  import type { AbortOptions, ComponentLogger, Logger, Metrics, PeerId } from '@libp2p/interface'
10
9
  import type { AddressManager } from '@libp2p/interface-internal'
11
- import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
10
+ import type { AdaptiveTimeoutInit } from '@libp2p/utils'
12
11
  import type { Datastore } from 'interface-datastore'
13
12
  import type { CID } from 'multiformats/cid'
14
13
 
@@ -99,10 +98,10 @@ export class Reprovider extends TypedEventEmitter<ReprovideEvents> {
99
98
  setMaxListeners(Infinity, this.shutdownController.signal)
100
99
 
101
100
  this.timeout = setTimeout(() => {
102
- this.cleanUp({
101
+ this.processRecords({
103
102
  signal: AbortSignal.timeout(REPROVIDE_TIMEOUT)
104
103
  }).catch(err => {
105
- this.log.error('error running reprovide/cleanup - %e', err)
104
+ this.log.error('error running process to reprovide/cleanup - %e', err)
106
105
  })
107
106
  }, this.interval)
108
107
  }
@@ -118,10 +117,10 @@ export class Reprovider extends TypedEventEmitter<ReprovideEvents> {
118
117
  * Check all provider records. Delete them if they have expired, reprovide
119
118
  * them if the provider is us and the expiry is within the reprovide window.
120
119
  */
121
- private async cleanUp (options?: AbortOptions): Promise<void> {
120
+ private async processRecords (options?: AbortOptions): Promise<void> {
122
121
  try {
123
122
  this.safeDispatchEvent('reprovide:start')
124
-
123
+ this.log('starting reprovide/cleanup')
125
124
  // Get all provider entries from the datastore
126
125
  for await (const entry of this.datastore.query({
127
126
  prefix: this.datastorePrefix
@@ -133,17 +132,20 @@ export class Reprovider extends TypedEventEmitter<ReprovideEvents> {
133
132
  const expires = created + this.validity
134
133
  const now = Date.now()
135
134
  const expired = now > expires
135
+ const isSelf = this.peerId.equals(peerId)
136
136
 
137
- this.log.trace('comparing: %d < %d = %s %s', created, now - this.validity, expired, expired ? '(expired)' : '')
137
+ this.log.trace('comparing: %d (now) < %d (expires) = %s %s', now, expires, expired, expired ? '(expired)' : '(valid)')
138
138
 
139
- // delete the record if it has expired
140
- if (expired) {
139
+ // delete the record if it has expired and isn't us
140
+ // so that if user node is down for a while, we still persist provide intent
141
+ if (expired && !isSelf) {
141
142
  await this.datastore.delete(entry.key, options)
142
143
  }
143
144
 
144
145
  // if the provider is us and we are within the reprovide threshold,
145
146
  // reprovide the record
146
- if (this.peerId.equals(peerId) && (now - expires) < this.reprovideThreshold) {
147
+ if (this.shouldReprovide(isSelf, expires)) {
148
+ this.log('reproviding %c as it is within the reprovide threshold (%d)', cid, this.reprovideThreshold)
147
149
  this.queueReprovide(cid)
148
150
  .catch(err => {
149
151
  this.log.error('could not reprovide %c - %e', cid, err)
@@ -159,8 +161,9 @@ export class Reprovider extends TypedEventEmitter<ReprovideEvents> {
159
161
  this.safeDispatchEvent('reprovide:end')
160
162
 
161
163
  if (this.running) {
164
+ this.log('queuing next re-provide/cleanup run in %d ms', this.interval)
162
165
  this.timeout = setTimeout(() => {
163
- this.cleanUp({
166
+ this.processRecords({
164
167
  signal: AbortSignal.timeout(REPROVIDE_TIMEOUT)
165
168
  }).catch(err => {
166
169
  this.log.error('error running re-provide - %e', err)
@@ -170,6 +173,24 @@ export class Reprovider extends TypedEventEmitter<ReprovideEvents> {
170
173
  }
171
174
  }
172
175
 
176
+ /**
177
+ * Determines if a record should be reprovided
178
+ */
179
+ private shouldReprovide (isSelf: boolean, expires: number): boolean {
180
+ if (!isSelf) {
181
+ return false
182
+ }
183
+ const now = Date.now()
184
+
185
+ if (expires < now) {
186
+ // If the record has already expired, reprovide irrespective of the threshold
187
+ return true
188
+ }
189
+
190
+ // if the record is approaching expiration within the reprovide threshold
191
+ return expires - now < this.reprovideThreshold
192
+ }
193
+
173
194
  private async queueReprovide (cid: CID, options?: AbortOptions): Promise<void> {
174
195
  if (!this.running) {
175
196
  return
@@ -1,6 +1,5 @@
1
1
  import { start, stop } from '@libp2p/interface'
2
- import { AdaptiveTimeout } from '@libp2p/utils/adaptive-timeout'
3
- import { PeerQueue } from '@libp2p/utils/peer-queue'
2
+ import { AdaptiveTimeout, PeerQueue } from '@libp2p/utils'
4
3
  import { anySignal } from 'any-signal'
5
4
  import parallel from 'it-parallel'
6
5
  import { TypedEventEmitter, setMaxListeners } from 'main-event'
@@ -11,7 +10,7 @@ import type { Bucket, GetClosestPeersOptions, LeafBucket, Peer } from './k-bucke
11
10
  import type { Network } from '../network.js'
12
11
  import type { AbortOptions, ComponentLogger, CounterGroup, Logger, Metric, Metrics, PeerId, PeerStore, Startable, Stream } from '@libp2p/interface'
13
12
  import type { Ping } from '@libp2p/ping'
14
- import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout'
13
+ import type { AdaptiveTimeoutInit } from '@libp2p/utils'
15
14
 
16
15
  export const KBUCKET_SIZE = 20
17
16
  export const PREFIX_LENGTH = 6
@@ -118,6 +117,7 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
118
117
  this.populateFromDatastoreOnStart = init.populateFromDatastoreOnStart ?? POPULATE_FROM_DATASTORE_ON_START
119
118
  this.populateFromDatastoreLimit = init.populateFromDatastoreLimit ?? POPULATE_FROM_DATASTORE_LIMIT
120
119
  this.shutdownController = new AbortController()
120
+ setMaxListeners(Infinity, this.shutdownController.signal)
121
121
 
122
122
  this.pingOldContactQueue = new PeerQueue({
123
123
  concurrency: init.pingOldContactConcurrency ?? PING_OLD_CONTACT_CONCURRENCY,
@@ -190,6 +190,8 @@ export class RoutingTable extends TypedEventEmitter<RoutingTableEvents> implemen
190
190
  this.running = true
191
191
 
192
192
  this.shutdownController = new AbortController()
193
+ setMaxListeners(Infinity, this.shutdownController.signal)
194
+
193
195
  await start(this.closestPeerTagger, this.kb)
194
196
  }
195
197
 
@@ -2,7 +2,7 @@ import { publicKeyToProtobuf } from '@libp2p/crypto/keys'
2
2
  import { InvalidMessageError, NotFoundError } from '@libp2p/interface'
3
3
  import { Libp2pRecord } from '@libp2p/record'
4
4
  import {
5
- MAX_RECORD_AGE
5
+ PROVIDERS_VALIDITY
6
6
  } from '../../constants.js'
7
7
  import { MessageType } from '../../message/dht.js'
8
8
  import { bufferToRecordKey, isPublicKeyKey, fromPublicKeyKey } from '../../utils.js'
@@ -107,7 +107,7 @@ export class GetValueHandler implements DHTMessageHandler {
107
107
  * Try to fetch a given record by from the local datastore.
108
108
  * Returns the record if it is still valid, meaning
109
109
  * - it was either authored by this node, or
110
- * - it was received less than `MAX_RECORD_AGE` ago.
110
+ * - it was received less than `PROVIDERS_VALIDITY` ago.
111
111
  */
112
112
  async _checkLocalDatastore (key: Uint8Array): Promise<Libp2pRecord | undefined> {
113
113
  this.log('checkLocalDatastore looking for %b', key)
@@ -129,7 +129,7 @@ export class GetValueHandler implements DHTMessageHandler {
129
129
 
130
130
  // Check validity: compare time received with max record age
131
131
  if (record.timeReceived == null ||
132
- Date.now() - record.timeReceived.getTime() > MAX_RECORD_AGE) {
132
+ Date.now() - record.timeReceived.getTime() > PROVIDERS_VALIDITY) {
133
133
  // If record is bad delete it and return
134
134
  await this.datastore.delete(dsKey)
135
135
  return undefined
package/src/rpc/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { TimeoutError } from '@libp2p/interface'
2
- import { pbStream } from 'it-protobuf-stream'
2
+ import { pbStream } from '@libp2p/utils'
3
3
  import { Message, MessageType } from '../message/dht.js'
4
4
  import { AddProviderHandler } from './handlers/add-provider.js'
5
5
  import { FindNodeHandler } from './handlers/find-node.js'
@@ -15,7 +15,7 @@ import type { GetProvidersHandlerComponents } from './handlers/get-providers.js'
15
15
  import type { GetValueHandlerComponents } from './handlers/get-value.js'
16
16
  import type { PutValueHandlerComponents } from './handlers/put-value.js'
17
17
  import type { RoutingTable } from '../routing-table/index.js'
18
- import type { CounterGroup, Logger, Metrics, PeerId, IncomingStreamData, MetricGroup } from '@libp2p/interface'
18
+ import type { CounterGroup, Logger, Metrics, PeerId, MetricGroup, Connection, Stream } from '@libp2p/interface'
19
19
 
20
20
  export interface DHTMessageHandler {
21
21
  handle(peerId: PeerId, msg: Message): Promise<Message | undefined>
@@ -95,65 +95,61 @@ export class RPC {
95
95
  /**
96
96
  * Handle incoming streams on the dht protocol
97
97
  */
98
- onIncomingStream (data: IncomingStreamData): void {
99
- const message = 'unknown'
98
+ async onIncomingStream (stream: Stream, connection: Connection): Promise<void> {
99
+ const abortListener = (): void => {
100
+ stream.abort(new TimeoutError())
101
+ }
102
+
103
+ let signal = AbortSignal.timeout(this.incomingMessageTimeout)
104
+ signal.addEventListener('abort', abortListener)
105
+
106
+ const messages = pbStream(stream).pb(Message)
100
107
 
101
- Promise.resolve().then(async () => {
102
- const { stream, connection } = data
108
+ while (true) {
109
+ // the remote will not send any more data
110
+ if (stream.readStatus !== 'readable') {
111
+ await stream.close({
112
+ signal
113
+ })
103
114
 
104
- const abortListener = (): void => {
105
- stream.abort(new TimeoutError())
115
+ break
106
116
  }
107
117
 
108
- let signal = AbortSignal.timeout(this.incomingMessageTimeout)
109
- signal.addEventListener('abort', abortListener)
118
+ const message = await messages.read({
119
+ signal
120
+ })
110
121
 
111
- const messages = pbStream(stream).pb(Message)
122
+ const stopSuccessTimer = this.metrics?.rpcTime?.timer(message.type.toString())
123
+ const stopErrorTimer = this.metrics?.rpcTime?.timer(message.type.toString())
124
+ let errored = false
112
125
 
113
126
  try {
114
- while (true) {
115
- const message = await messages.read({
127
+ // handle the message
128
+ this.log('incoming %s from %p', message.type, connection.remotePeer)
129
+ const res = await this.handleMessage(connection.remotePeer, message)
130
+
131
+ // Not all handlers will return a response
132
+ if (res != null) {
133
+ await messages.write(res, {
116
134
  signal
117
135
  })
118
-
119
- const stopSuccessTimer = this.metrics?.rpcTime?.timer(message.type.toString())
120
- const stopErrorTimer = this.metrics?.rpcTime?.timer(message.type.toString())
121
- let errored = false
122
-
123
- try {
124
- // handle the message
125
- this.log('incoming %s from %p', message.type, connection.remotePeer)
126
- const res = await this.handleMessage(connection.remotePeer, message)
127
-
128
- // Not all handlers will return a response
129
- if (res != null) {
130
- await messages.write(res, {
131
- signal
132
- })
133
- }
134
- } catch (err) {
135
- errored = true
136
- stopErrorTimer?.()
137
-
138
- throw err
139
- } finally {
140
- if (!errored) {
141
- stopSuccessTimer?.()
142
- }
143
- }
144
-
145
- // we have received a message so reset the timeout controller to
146
- // allow the remote to send another
147
- signal.removeEventListener('abort', abortListener)
148
- signal = AbortSignal.timeout(this.incomingMessageTimeout)
149
- signal.addEventListener('abort', abortListener)
150
136
  }
151
- } catch (err: any) {
152
- stream.abort(err)
137
+ } catch (err) {
138
+ errored = true
139
+ stopErrorTimer?.()
140
+
141
+ throw err
142
+ } finally {
143
+ if (!errored) {
144
+ stopSuccessTimer?.()
145
+ }
153
146
  }
154
- })
155
- .catch(err => {
156
- this.log.error('error handling %s RPC message from %p - %e', message, data.connection.remotePeer, err)
157
- })
147
+
148
+ // we have received a message so reset the timeout controller to
149
+ // allow the remote to send another
150
+ signal.removeEventListener('abort', abortListener)
151
+ signal = AbortSignal.timeout(this.incomingMessageTimeout)
152
+ signal.addEventListener('abort', abortListener)
153
+ }
158
154
  }
159
155
  }
package/src/utils.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { peerIdFromMultihash, peerIdFromString } from '@libp2p/peer-id'
2
2
  import { Libp2pRecord } from '@libp2p/record'
3
- import { isPrivateIp } from '@libp2p/utils/private-ip'
3
+ import { isPrivateIp } from '@libp2p/utils'
4
4
  import { Key } from 'interface-datastore/key'
5
5
  import { CID } from 'multiformats/cid'
6
6
  import * as raw from 'multiformats/codecs/raw'
@@ -160,15 +160,6 @@ export function createPutRecord (key: Uint8Array, value: Uint8Array): Uint8Array
160
160
  return rec.serialize()
161
161
  }
162
162
 
163
- export function debounce (callback: () => void, wait: number = 100): () => void {
164
- let timeout: ReturnType<typeof setTimeout>
165
-
166
- return (): void => {
167
- clearTimeout(timeout)
168
- timeout = setTimeout(() => { callback() }, wait)
169
- }
170
- }
171
-
172
163
  // see https://github.com/multiformats/multiaddr/blob/master/protocols.csv
173
164
  const P2P_CIRCUIT_CODE = 290
174
165
  const DNS4_CODE = 54
@@ -1,65 +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.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
- "DisjointPath": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.DisjointPath.html",
13
- ".:DisjointPath": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.DisjointPath.html",
14
- "FinalPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.FinalPeerEvent.html",
15
- ".:FinalPeerEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.FinalPeerEvent.html",
16
- "KadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHT.html",
17
- ".:KadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHT.html",
18
- "KadDHTComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHTComponents.html",
19
- ".:KadDHTComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHTComponents.html",
20
- "KadDHTInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHTInit.html",
21
- ".:KadDHTInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.KadDHTInit.html",
22
- "PathEndedEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PathEndedEvent.html",
23
- ".:PathEndedEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PathEndedEvent.html",
24
- "PeerInfoMapper": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PeerInfoMapper.html",
25
- ".:PeerInfoMapper": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PeerInfoMapper.html",
26
- "PeerResponseEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PeerResponseEvent.html",
27
- ".:PeerResponseEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.PeerResponseEvent.html",
28
- "ProviderEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ProviderEvent.html",
29
- ".:ProviderEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ProviderEvent.html",
30
- "ProvidersInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ProvidersInit.html",
31
- ".:ProvidersInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ProvidersInit.html",
32
- "QueryErrorEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.QueryErrorEvent.html",
33
- ".:QueryErrorEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.QueryErrorEvent.html",
34
- "ReProvideInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ReProvideInit.html",
35
- ".:ReProvideInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ReProvideInit.html",
36
- "RoutingTable": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.RoutingTable.html",
37
- ".:RoutingTable": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.RoutingTable.html",
38
- "SelectFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SelectFn.html",
39
- ".:SelectFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SelectFn.html",
40
- "SendQueryEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SendQueryEvent.html",
41
- ".:SendQueryEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SendQueryEvent.html",
42
- "SetModeOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SetModeOptions.html",
43
- ".:SetModeOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SetModeOptions.html",
44
- "SingleKadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SingleKadDHT.html",
45
- ".:SingleKadDHT": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.SingleKadDHT.html",
46
- "ValidateFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ValidateFn.html",
47
- ".:ValidateFn": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ValidateFn.html",
48
- "ValueEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ValueEvent.html",
49
- ".:ValueEvent": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_kad-dht.ValueEvent.html",
50
- "DHTProgressEvents": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.DHTProgressEvents.html",
51
- ".:DHTProgressEvents": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.DHTProgressEvents.html",
52
- "MessageName": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.MessageName.html",
53
- ".:MessageName": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.MessageName.html",
54
- "QueryEvent": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.QueryEvent.html",
55
- ".:QueryEvent": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.QueryEvent.html",
56
- "Selectors": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.Selectors.html",
57
- ".:Selectors": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.Selectors.html",
58
- "Validators": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.Validators.html",
59
- ".:Validators": "https://libp2p.github.io/js-libp2p/types/_libp2p_kad-dht.Validators.html",
60
- "kadDHT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad-dht.kadDHT.html",
61
- ".:kadDHT": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad-dht.kadDHT.html",
62
- "passthroughMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad-dht.passthroughMapper.html",
63
- "removePrivateAddressesMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad-dht.removePrivateAddressesMapper.html",
64
- "removePublicAddressesMapper": "https://libp2p.github.io/js-libp2p/functions/_libp2p_kad-dht.removePublicAddressesMapper.html"
65
- }