@helia/bitswap 1.0.1 → 1.1.0-55b9650

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 (42) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/src/network.d.ts +5 -3
  3. package/dist/src/network.d.ts.map +1 -1
  4. package/dist/src/network.js +8 -18
  5. package/dist/src/network.js.map +1 -1
  6. package/dist/src/peer-want-lists/index.d.ts +2 -1
  7. package/dist/src/peer-want-lists/index.d.ts.map +1 -1
  8. package/dist/src/peer-want-lists/index.js +1 -1
  9. package/dist/src/peer-want-lists/index.js.map +1 -1
  10. package/dist/src/peer-want-lists/ledger.d.ts.map +1 -1
  11. package/dist/src/peer-want-lists/ledger.js +41 -40
  12. package/dist/src/peer-want-lists/ledger.js.map +1 -1
  13. package/dist/src/stats.d.ts +2 -1
  14. package/dist/src/stats.d.ts.map +1 -1
  15. package/dist/src/stats.js +4 -4
  16. package/dist/src/stats.js.map +1 -1
  17. package/dist/src/utils/bitswap-message.d.ts +19 -0
  18. package/dist/src/utils/bitswap-message.d.ts.map +1 -0
  19. package/dist/src/utils/bitswap-message.js +33 -0
  20. package/dist/src/utils/bitswap-message.js.map +1 -0
  21. package/dist/src/utils/merge-messages.d.ts +2 -2
  22. package/dist/src/utils/merge-messages.d.ts.map +1 -1
  23. package/dist/src/utils/merge-messages.js +12 -34
  24. package/dist/src/utils/merge-messages.js.map +1 -1
  25. package/dist/src/utils/split-message.d.ts +2 -2
  26. package/dist/src/utils/split-message.d.ts.map +1 -1
  27. package/dist/src/utils/split-message.js +5 -5
  28. package/dist/src/utils/split-message.js.map +1 -1
  29. package/dist/src/want-list.d.ts +2 -1
  30. package/dist/src/want-list.d.ts.map +1 -1
  31. package/dist/src/want-list.js +51 -67
  32. package/dist/src/want-list.js.map +1 -1
  33. package/package.json +4 -5
  34. package/src/network.ts +12 -21
  35. package/src/peer-want-lists/index.ts +3 -2
  36. package/src/peer-want-lists/ledger.ts +40 -42
  37. package/src/stats.ts +6 -5
  38. package/src/utils/bitswap-message.ts +39 -0
  39. package/src/utils/merge-messages.ts +12 -45
  40. package/src/utils/split-message.ts +6 -5
  41. package/src/want-list.ts +59 -80
  42. package/dist/typedoc-urls.json +0 -20
@@ -2,6 +2,7 @@
2
2
  import { CodeError } from '@libp2p/interface'
3
3
  import { encodingLength } from 'uint8-varint'
4
4
  import { BitswapMessage, Block, BlockPresence, WantlistEntry } from '../pb/message.js'
5
+ import type { QueuedBitswapMessage } from './bitswap-message.js'
5
6
 
6
7
  /**
7
8
  * https://github.com/ipfs/kubo/issues/4473#issuecomment-350390693
@@ -20,10 +21,10 @@ const MAX_ENCODED_BLOCK_SIZE = MAX_BLOCK_SIZE + 16
20
21
  * If a block is encountered that is larger than the max message size an error
21
22
  * will be thrown.
22
23
  */
23
- export async function * splitMessage (message: BitswapMessage, maxSize: number): AsyncGenerator<Uint8Array> {
24
- const wantListEntries = message.wantlist?.entries ?? []
25
- const blockPresences = message.blockPresences
26
- const blocks = message.blocks
24
+ export function * splitMessage (message: QueuedBitswapMessage, maxSize: number): Generator<Uint8Array> {
25
+ const wantListEntries = [...message.wantlist.values()]
26
+ const blockPresences = [...message.blockPresences.values()]
27
+ const blocks = [...message.blocks.values()]
27
28
 
28
29
  let wantListIndex = 0
29
30
  let blockPresencesIndex = 0
@@ -33,7 +34,7 @@ export async function * splitMessage (message: BitswapMessage, maxSize: number):
33
34
  while (true) {
34
35
  const subMessage: Required<BitswapMessage> = {
35
36
  wantlist: {
36
- full: message.wantlist?.full ?? false,
37
+ full: message.full ?? false,
37
38
  entries: []
38
39
  },
39
40
  blockPresences: [],
package/src/want-list.ts CHANGED
@@ -1,10 +1,6 @@
1
1
  import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
2
2
  import { trackedPeerMap } from '@libp2p/peer-collections'
3
3
  import { trackedMap } from '@libp2p/utils/tracked-map'
4
- import all from 'it-all'
5
- import filter from 'it-filter'
6
- import map from 'it-map'
7
- import { pipe } from 'it-pipe'
8
4
  import { CID } from 'multiformats/cid'
9
5
  import { sha256 } from 'multiformats/hashes/sha2'
10
6
  import pDefer from 'p-defer'
@@ -13,11 +9,12 @@ import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
13
9
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
14
10
  import { DEFAULT_MESSAGE_SEND_DELAY } from './constants.js'
15
11
  import { BlockPresenceType, WantType } from './pb/message.js'
12
+ import { QueuedBitswapMessage } from './utils/bitswap-message.js'
16
13
  import vd from './utils/varint-decoder.js'
17
14
  import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.js'
18
15
  import type { BitswapNetworkWantProgressEvents, Network } from './network.js'
19
16
  import type { BitswapMessage } from './pb/message.js'
20
- import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget } from '@libp2p/interface'
17
+ import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget, Metrics } from '@libp2p/interface'
21
18
  import type { Logger } from '@libp2p/logger'
22
19
  import type { PeerMap } from '@libp2p/peer-collections'
23
20
  import type { DeferredPromise } from 'p-defer'
@@ -27,6 +24,7 @@ export interface WantListComponents {
27
24
  network: Network
28
25
  logger: ComponentLogger
29
26
  libp2p: Libp2p
27
+ metrics?: Metrics
30
28
  }
31
29
 
32
30
  export interface WantListInit {
@@ -114,11 +112,11 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
114
112
  setMaxListeners(Infinity, this)
115
113
  this.peers = trackedPeerMap({
116
114
  name: 'helia_bitswap_peers',
117
- metrics: components.libp2p.metrics
115
+ metrics: components.metrics
118
116
  })
119
117
  this.wants = trackedMap({
120
118
  name: 'helia_bitswap_wantlist',
121
- metrics: components.libp2p.metrics
119
+ metrics: components.metrics
122
120
  })
123
121
  this.network = components.network
124
122
  this.sendMessagesDelay = init.sendMessagesDelay ?? DEFAULT_MESSAGE_SEND_DELAY
@@ -218,39 +216,29 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
218
216
  await Promise.all(
219
217
  [...this.peers.entries()].map(async ([peerId, sentWants]) => {
220
218
  const sent = new Set<string>()
221
- const message: Partial<BitswapMessage> = {
222
- wantlist: {
223
- full: false,
224
- entries: pipe(
225
- this.wants.entries(),
226
- (source) => filter(source, ([key, entry]) => {
227
- const sentPreviously = sentWants.has(key)
228
-
229
- // don't cancel if we've not sent it to them before
230
- if (entry.cancel) {
231
- return sentPreviously
232
- }
233
-
234
- // only send if we've not sent it to them before
235
- return !sentPreviously
236
- }),
237
- (source) => map(source, ([key, entry]) => {
238
- sent.add(key)
239
-
240
- return {
241
- cid: entry.cid.bytes,
242
- priority: entry.priority,
243
- wantType: entry.wantType,
244
- cancel: entry.cancel,
245
- sendDontHave: entry.sendDontHave
246
- }
247
- }),
248
- (source) => all(source)
249
- )
219
+ const message = new QueuedBitswapMessage()
220
+
221
+ for (const [key, entry] of this.wants.entries()) {
222
+ const sentPreviously = sentWants.has(key)
223
+
224
+ // only send if either we've not sent it before, or we haven't sent it
225
+ // but we're also cancelling the want.
226
+ if (sentPreviously || entry.cancel) {
227
+ continue
250
228
  }
229
+
230
+ sent.add(key)
231
+
232
+ message.addWantlistEntry(entry.cid, {
233
+ cid: entry.cid.bytes,
234
+ priority: entry.priority,
235
+ wantType: entry.wantType,
236
+ cancel: entry.cancel,
237
+ sendDontHave: entry.sendDontHave
238
+ })
251
239
  }
252
240
 
253
- if (message.wantlist?.entries.length === 0) {
241
+ if (message.wantlist.size === 0) {
254
242
  return
255
243
  }
256
244
 
@@ -294,19 +282,17 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
294
282
  * Add a CID to the wantlist
295
283
  */
296
284
  async wantSessionPresence (cid: CID, peerId: PeerId, options: WantOptions = {}): Promise<WantPresenceResult> {
297
- // sending WantHave directly to peer
298
- await this.network.sendMessage(peerId, {
299
- wantlist: {
300
- full: false,
301
- entries: [{
302
- cid: cid.bytes,
303
- sendDontHave: true,
304
- wantType: WantType.WantHave,
305
- priority: 1
306
- }]
307
- }
285
+ const message = new QueuedBitswapMessage()
286
+ message.addWantlistEntry(cid, {
287
+ cid: cid.bytes,
288
+ sendDontHave: true,
289
+ wantType: WantType.WantHave,
290
+ priority: 1
308
291
  })
309
292
 
293
+ // sending WantHave directly to peer
294
+ await this.network.sendMessage(peerId, message)
295
+
310
296
  // wait for peer response
311
297
  const event = await raceEvent<CustomEvent<WantHaveResult | WantDontHaveResult>>(this, 'presence', options.signal, {
312
298
  filter: (event) => {
@@ -331,19 +317,17 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
331
317
  * Add a CID to the wantlist
332
318
  */
333
319
  async wantSessionBlock (cid: CID, peerId: PeerId, options: WantOptions = {}): Promise<WantPresenceResult> {
334
- // sending WantBlockResult directly to peer
335
- await this.network.sendMessage(peerId, {
336
- wantlist: {
337
- full: false,
338
- entries: [{
339
- cid: cid.bytes,
340
- sendDontHave: true,
341
- wantType: WantType.WantBlock,
342
- priority: 1
343
- }]
344
- }
320
+ const message = new QueuedBitswapMessage()
321
+ message.addWantlistEntry(cid, {
322
+ cid: cid.bytes,
323
+ sendDontHave: true,
324
+ wantType: WantType.WantBlock,
325
+ priority: 1
345
326
  })
346
327
 
328
+ // sending WantBlockResult directly to peer
329
+ await this.network.sendMessage(peerId, message)
330
+
347
331
  // wait for peer response
348
332
  const event = await raceEvent<CustomEvent<WantPresenceResult>>(this, 'presence', options.signal, {
349
333
  filter: (event) => {
@@ -375,7 +359,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
375
359
  * Invoked when a message is received from a bitswap peer
376
360
  */
377
361
  private async receiveMessage (sender: PeerId, message: BitswapMessage): Promise<void> {
378
- this.log('received message %d from %p with %d blocks', sender, message.blocks.length)
362
+ this.log('received message from %p with %d blocks', sender, message.blocks.length)
379
363
  let blocksCancelled = false
380
364
 
381
365
  // process blocks
@@ -463,32 +447,27 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
463
447
  */
464
448
  async peerConnected (peerId: PeerId): Promise<void> {
465
449
  const sentWants = new Set<string>()
450
+ const message = new QueuedBitswapMessage(true)
466
451
 
467
452
  // new peer, give them the full wantlist
468
- const message: Partial<BitswapMessage> = {
469
- wantlist: {
470
- full: true,
471
- entries: pipe(
472
- this.wants.entries(),
473
- (source) => filter(source, ([key, entry]) => !entry.cancel),
474
- (source) => map(source, ([key, entry]) => {
475
- sentWants.add(key)
476
-
477
- return {
478
- cid: entry.cid.bytes,
479
- priority: 1,
480
- wantType: WantType.WantBlock,
481
- cancel: false,
482
- sendDontHave: false
483
- }
484
- }),
485
- (source) => all(source)
486
- )
453
+ for (const [key, entry] of this.wants.entries()) {
454
+ if (entry.cancel) {
455
+ continue
487
456
  }
457
+
458
+ sentWants.add(key)
459
+
460
+ message.addWantlistEntry(entry.cid, {
461
+ cid: entry.cid.bytes,
462
+ priority: 1,
463
+ wantType: WantType.WantBlock,
464
+ cancel: false,
465
+ sendDontHave: false
466
+ })
488
467
  }
489
468
 
490
469
  // only send the wantlist if we have something to send
491
- if (message.wantlist?.entries.length === 0) {
470
+ if (message.wantlist.size === 0) {
492
471
  this.peers.set(peerId, sentWants)
493
472
 
494
473
  return
@@ -1,20 +0,0 @@
1
- {
2
- "Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
3
- ".:Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
4
- "BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
5
- ".:BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
6
- "BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
7
- ".:BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
8
- "MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
9
- ".:MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
10
- "WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
11
- ".:WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
12
- "BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
13
- ".:BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
14
- "BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
15
- ".:BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
16
- "BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
17
- ".:BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
18
- "createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html",
19
- ".:createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html"
20
- }