@helia/bitswap 3.1.4 → 3.2.0

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.
package/src/want-list.ts CHANGED
@@ -7,29 +7,35 @@ import pDefer from 'p-defer'
7
7
  import { raceEvent } from 'race-event'
8
8
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
9
9
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
10
- import { DEFAULT_MESSAGE_SEND_DELAY } from './constants.ts'
10
+ import { DEFAULT_WANTLIST_SEND_DEBOUNCE } from './constants.ts'
11
11
  import { BlockPresenceType, WantType } from './pb/message.ts'
12
12
  import { QueuedBitswapMessage } from './utils/bitswap-message.ts'
13
13
  import vd from './utils/varint-decoder.ts'
14
- import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.ts'
14
+ import type { BitswapNotifyProgressEvents } from './index.ts'
15
15
  import type { BitswapNetworkWantProgressEvents, Network } from './network.ts'
16
16
  import type { BitswapMessage } from './pb/message.ts'
17
- import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget, Metrics } from '@libp2p/interface'
17
+ import type { HasherLoader } from '@helia/interface'
18
+ import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget, Metrics, Connection } from '@libp2p/interface'
18
19
  import type { Logger } from '@libp2p/logger'
19
20
  import type { PeerMap } from '@libp2p/peer-collections'
20
21
  import type { DeferredPromise } from 'p-defer'
21
- import type { ProgressOptions } from 'progress-events'
22
+ import type { ProgressEventListener, ProgressOptions } from 'progress-events'
22
23
 
23
24
  export interface WantListComponents {
24
25
  network: Network
25
26
  logger: ComponentLogger
26
27
  libp2p: Libp2p
28
+ getHasher: HasherLoader
27
29
  metrics?: Metrics
28
30
  }
29
31
 
30
32
  export interface WantListInit {
31
- sendMessagesDelay?: number
32
- hashLoader?: MultihashHasherLoader
33
+ sendWantlistDebounce?: number
34
+ }
35
+
36
+ export interface ProgressCallback {
37
+ onProgress: ProgressEventListener<BitswapNetworkWantProgressEvents>
38
+ signal?: AbortSignal
33
39
  }
34
40
 
35
41
  export interface WantListEntry {
@@ -58,6 +64,11 @@ export interface WantListEntry {
58
64
  * Whether the remote should tell us if they have the block or not
59
65
  */
60
66
  sendDontHave: boolean
67
+
68
+ /**
69
+ * Progress event handlers interested in this CID
70
+ */
71
+ onProgress: ProgressCallback[]
61
72
  }
62
73
 
63
74
  export interface WantOptions extends AbortOptions, ProgressOptions<BitswapNetworkWantProgressEvents> {
@@ -68,7 +79,11 @@ export interface WantOptions extends AbortOptions, ProgressOptions<BitswapNetwor
68
79
  }
69
80
 
70
81
  export interface WantBlockResult {
82
+ /**
83
+ * @deprecated access the sender via connection.remotePeer instead
84
+ */
71
85
  sender: PeerId
86
+ connection: Connection
72
87
  cid: CID
73
88
  block: Uint8Array
74
89
  }
@@ -101,9 +116,9 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
101
116
  public readonly wants: Map<string, WantListEntry>
102
117
  private readonly network: Network
103
118
  private readonly log: Logger
104
- private readonly sendMessagesDelay: number
119
+ private readonly sendWantlistDebounce: number
105
120
  private sendMessagesTimeout?: ReturnType<typeof setTimeout>
106
- private readonly hashLoader?: MultihashHasherLoader
121
+ private readonly getHasher: HasherLoader
107
122
  private sendingMessages?: DeferredPromise<void>
108
123
 
109
124
  constructor (components: WantListComponents, init: WantListInit = {}) {
@@ -119,14 +134,14 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
119
134
  metrics: components.metrics
120
135
  })
121
136
  this.network = components.network
122
- this.sendMessagesDelay = init.sendMessagesDelay ?? DEFAULT_MESSAGE_SEND_DELAY
137
+ this.sendWantlistDebounce = init.sendWantlistDebounce ?? DEFAULT_WANTLIST_SEND_DEBOUNCE
123
138
  this.log = components.logger.forComponent('helia:bitswap:wantlist')
124
- this.hashLoader = init.hashLoader
139
+ this.getHasher = components.getHasher
125
140
 
126
141
  this.network.addEventListener('bitswap:message', (evt) => {
127
- this.receiveMessage(evt.detail.peer, evt.detail.message)
142
+ this.receiveMessage(evt.detail.connection, evt.detail.message)
128
143
  .catch(err => {
129
- this.log.error('error receiving bitswap message from %p - %e', evt.detail.peer, err)
144
+ this.log.error('error receiving bitswap message from %p - %e', evt.detail.connection.remotePeer, err)
130
145
  })
131
146
  })
132
147
  this.network.addEventListener('peer:connected', evt => {
@@ -152,12 +167,20 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
152
167
  priority: options.priority ?? 1,
153
168
  wantType: options.wantType ?? WantType.WantBlock,
154
169
  cancel: false,
155
- sendDontHave: true
170
+ sendDontHave: true,
171
+ onProgress: []
156
172
  }
157
173
 
158
174
  this.wants.set(cidStr, entry)
159
175
  }
160
176
 
177
+ if (options.onProgress != null) {
178
+ entry.onProgress.push({
179
+ onProgress: options.onProgress,
180
+ signal: options.signal
181
+ })
182
+ }
183
+
161
184
  // upgrade want-have to want-block if the new want is a WantBlock but the
162
185
  // previous want was a WantHave
163
186
  if (entry.wantType === WantType.WantHave && options.wantType === WantType.WantBlock) {
@@ -207,7 +230,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
207
230
  .catch(err => {
208
231
  this.log('error sending messages to peers - %e', err)
209
232
  })
210
- }, this.sendMessagesDelay)
233
+ }, this.sendWantlistDebounce)
211
234
  }
212
235
 
213
236
  private async sendMessages (): Promise<void> {
@@ -244,7 +267,15 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
244
267
 
245
268
  // add message to send queue
246
269
  try {
247
- await this.network.sendMessage(peerId, message)
270
+ await this.network.sendMessage(peerId, message, {
271
+ onProgress: evt => {
272
+ this.wants.forEach(({ onProgress }) => {
273
+ onProgress.forEach(({ onProgress }) => {
274
+ onProgress(evt)
275
+ })
276
+ })
277
+ }
278
+ })
248
279
 
249
280
  // update list of messages sent to remote
250
281
  for (const key of sent) {
@@ -291,7 +322,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
291
322
  })
292
323
 
293
324
  // sending WantHave directly to peer
294
- await this.network.sendMessage(peerId, message)
325
+ await this.network.sendMessage(peerId, message, options)
295
326
 
296
327
  // wait for peer response
297
328
  const event = await raceEvent<CustomEvent<WantHaveResult | WantDoNotHaveResult>>(this, 'presence', options.signal, {
@@ -326,7 +357,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
326
357
  })
327
358
 
328
359
  // sending WantBlockResult directly to peer
329
- await this.network.sendMessage(peerId, message)
360
+ await this.network.sendMessage(peerId, message, options)
330
361
 
331
362
  // wait for peer response
332
363
  const event = await raceEvent<CustomEvent<WantPresenceResult>>(this, 'presence', options.signal, {
@@ -358,8 +389,8 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
358
389
  /**
359
390
  * Invoked when a message is received from a bitswap peer
360
391
  */
361
- private async receiveMessage (sender: PeerId, message: BitswapMessage): Promise<void> {
362
- this.log('received message from %p with %d blocks', sender, message.blocks.length)
392
+ private async receiveMessage (connection: Connection, message: BitswapMessage): Promise<void> {
393
+ this.log('received message from %p with %d blocks', connection.remotePeer, message.blocks.length)
363
394
  let blocksCancelled = false
364
395
 
365
396
  // process blocks
@@ -374,7 +405,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
374
405
  const hashAlg = values[2]
375
406
  const hashLen = values[3]
376
407
 
377
- const hasher = hashAlg === sha256.code ? sha256 : await this.hashLoader?.getHasher(hashAlg)
408
+ const hasher = hashAlg === sha256.code ? sha256 : await this.getHasher(hashAlg)
378
409
 
379
410
  if (hasher == null) {
380
411
  this.log.error('unknown hash algorithm', hashAlg)
@@ -391,19 +422,20 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
391
422
 
392
423
  const cid = CID.create(cidVersion === 0 ? 0 : 1, multicodec, hash)
393
424
 
394
- this.log('received block from %p for %c', sender, cid)
425
+ this.log('received block from %p for %c', connection.remotePeer, cid)
395
426
 
396
427
  this.safeDispatchEvent<WantBlockResult>('block', {
397
428
  detail: {
398
- sender,
429
+ sender: connection.remotePeer,
399
430
  cid,
400
- block: block.data
431
+ block: block.data,
432
+ connection
401
433
  }
402
434
  })
403
435
 
404
436
  this.safeDispatchEvent<WantHaveResult | WantDoNotHaveResult>('presence', {
405
437
  detail: {
406
- sender,
438
+ sender: connection.remotePeer,
407
439
  cid,
408
440
  has: true,
409
441
  block: block.data
@@ -428,11 +460,11 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
428
460
  for (const { cid: cidBytes, type } of message.blockPresences) {
429
461
  const cid = CID.decode(cidBytes)
430
462
 
431
- this.log('received %s from %p for %c', type, sender, cid)
463
+ this.log('received %s from %p for %c', type, connection.remotePeer, cid)
432
464
 
433
465
  this.safeDispatchEvent<WantHaveResult | WantDoNotHaveResult>('presence', {
434
466
  detail: {
435
- sender,
467
+ sender: connection.remotePeer,
436
468
  cid,
437
469
  has: type === BlockPresenceType.HaveBlock
438
470
  }
@@ -476,7 +508,15 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
476
508
  }
477
509
 
478
510
  try {
479
- await this.network.sendMessage(peerId, message)
511
+ await this.network.sendMessage(peerId, message, {
512
+ onProgress: evt => {
513
+ this.wants.forEach(({ onProgress }) => {
514
+ onProgress.forEach(({ onProgress }) => {
515
+ onProgress(evt)
516
+ })
517
+ })
518
+ }
519
+ })
480
520
 
481
521
  this.peers.set(peerId, sentWants)
482
522
  } catch (err) {