@helia/bitswap 1.0.0 → 1.0.1-52dbcf2

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 (46) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/src/constants.d.ts +2 -0
  3. package/dist/src/constants.d.ts.map +1 -1
  4. package/dist/src/constants.js +2 -0
  5. package/dist/src/constants.js.map +1 -1
  6. package/dist/src/index.d.ts +20 -7
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/network.d.ts +5 -3
  10. package/dist/src/network.d.ts.map +1 -1
  11. package/dist/src/network.js +52 -128
  12. package/dist/src/network.js.map +1 -1
  13. package/dist/src/pb/message.d.ts +6 -6
  14. package/dist/src/pb/message.d.ts.map +1 -1
  15. package/dist/src/pb/message.js +37 -20
  16. package/dist/src/pb/message.js.map +1 -1
  17. package/dist/src/peer-want-lists/index.d.ts +1 -0
  18. package/dist/src/peer-want-lists/index.d.ts.map +1 -1
  19. package/dist/src/peer-want-lists/index.js +5 -1
  20. package/dist/src/peer-want-lists/index.js.map +1 -1
  21. package/dist/src/peer-want-lists/ledger.d.ts +3 -1
  22. package/dist/src/peer-want-lists/ledger.d.ts.map +1 -1
  23. package/dist/src/peer-want-lists/ledger.js +8 -0
  24. package/dist/src/peer-want-lists/ledger.js.map +1 -1
  25. package/dist/src/utils/merge-messages.d.ts +3 -0
  26. package/dist/src/utils/merge-messages.d.ts.map +1 -0
  27. package/dist/src/utils/merge-messages.js +51 -0
  28. package/dist/src/utils/merge-messages.js.map +1 -0
  29. package/dist/src/utils/split-message.d.ts +18 -0
  30. package/dist/src/utils/split-message.d.ts.map +1 -0
  31. package/dist/src/utils/split-message.js +101 -0
  32. package/dist/src/utils/split-message.js.map +1 -0
  33. package/dist/src/want-list.d.ts.map +1 -1
  34. package/dist/src/want-list.js +6 -3
  35. package/dist/src/want-list.js.map +1 -1
  36. package/package.json +4 -4
  37. package/src/constants.ts +2 -0
  38. package/src/index.ts +22 -8
  39. package/src/network.ts +60 -150
  40. package/src/pb/message.ts +40 -20
  41. package/src/peer-want-lists/index.ts +5 -1
  42. package/src/peer-want-lists/ledger.ts +11 -1
  43. package/src/utils/merge-messages.ts +70 -0
  44. package/src/utils/split-message.ts +133 -0
  45. package/src/want-list.ts +8 -3
  46. package/dist/typedoc-urls.json +0 -20
@@ -0,0 +1,133 @@
1
+ /* eslint-disable complexity */
2
+ import { CodeError } from '@libp2p/interface'
3
+ import { encodingLength } from 'uint8-varint'
4
+ import { BitswapMessage, Block, BlockPresence, WantlistEntry } from '../pb/message.js'
5
+
6
+ /**
7
+ * https://github.com/ipfs/kubo/issues/4473#issuecomment-350390693
8
+ */
9
+ export const MAX_BLOCK_SIZE = 4193648
10
+ const MAX_ENCODED_BLOCK_SIZE = MAX_BLOCK_SIZE + 16
11
+
12
+ /**
13
+ * Split the passed Bitswap message into multiple smaller messages that when
14
+ * serialized will be under the maximum message size.
15
+ *
16
+ * Since blocks are the largest thing to send, we first try to fit as many
17
+ * blocks as possible into the message, then add (smaller) block presences and
18
+ * wants until the max size is reached.
19
+ *
20
+ * If a block is encountered that is larger than the max message size an error
21
+ * will be thrown.
22
+ */
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
27
+
28
+ let wantListIndex = 0
29
+ let blockPresencesIndex = 0
30
+ let blocksIndex = 0
31
+ let doneSending = false
32
+
33
+ while (true) {
34
+ const subMessage: Required<BitswapMessage> = {
35
+ wantlist: {
36
+ full: message.wantlist?.full ?? false,
37
+ entries: []
38
+ },
39
+ blockPresences: [],
40
+ blocks: [],
41
+ pendingBytes: 0
42
+ }
43
+
44
+ let size = BitswapMessage.encode(subMessage).byteLength
45
+
46
+ let { added, hasMore, newSize } = addToMessage(blocks, subMessage.blocks, blocksIndex, maxSize, size, calculateEncodedBlockSize)
47
+
48
+ blocksIndex += added
49
+ size = newSize
50
+ const haveMoreBlocks = hasMore
51
+
52
+ ;({ added, hasMore, newSize } = addToMessage(blockPresences, subMessage.blockPresences, blockPresencesIndex, maxSize, size, calculateEncodedBlockPresenceSize))
53
+
54
+ blockPresencesIndex += added
55
+ size = newSize
56
+ const haveMorePresences = hasMore
57
+
58
+ ;({ added, hasMore, newSize } = addToMessage(wantListEntries, subMessage.wantlist.entries, wantListIndex, maxSize, size, calculateEncodedWantlistEntrySize))
59
+
60
+ wantListIndex += added
61
+ size = newSize
62
+ const haveMoreWantlistEntries = hasMore
63
+
64
+ doneSending = !haveMoreBlocks && !haveMorePresences && !haveMoreWantlistEntries
65
+
66
+ // if we're sending multiple messages this is no longer the full wantlist
67
+ if (!doneSending) {
68
+ subMessage.wantlist.full = false
69
+ }
70
+
71
+ yield BitswapMessage.encode(subMessage)
72
+
73
+ if (doneSending) {
74
+ break
75
+ }
76
+ }
77
+ }
78
+
79
+ interface AddResult {
80
+ hasMore: boolean
81
+ added: number
82
+ newSize: number
83
+ }
84
+
85
+ function addToMessage <T> (input: T[], output: T[], start: number, maxSize: number, size: number, calculateSize: (arg: T) => number): AddResult {
86
+ let added = 0
87
+ let hasMore = false
88
+
89
+ // try to send as many blocks as possible
90
+ for (let i = start; i < input.length; i++) {
91
+ const item = input[i]
92
+ const itemSize = calculateSize(item)
93
+
94
+ if (itemSize > MAX_ENCODED_BLOCK_SIZE) {
95
+ throw new CodeError('Cannot send block as after encoding it is over the max message size', 'ERR_BLOCK_TOO_LARGE')
96
+ }
97
+
98
+ const newSize = size + itemSize
99
+
100
+ if (newSize > maxSize) {
101
+ hasMore = true
102
+ break
103
+ }
104
+
105
+ output.push(item)
106
+ added++
107
+ size = newSize
108
+ }
109
+
110
+ return { hasMore, added, newSize: size }
111
+ }
112
+
113
+ function calculateEncodedBlockSize (block: Block): number {
114
+ // 3 is the "blocks" field number in message.proto
115
+ return calculateLength(3, Block.encode(block))
116
+ }
117
+
118
+ function calculateEncodedBlockPresenceSize (blockPresence: BlockPresence): number {
119
+ // 4 is the "blockPresences" field number in message.proto
120
+ return calculateLength(4, BlockPresence.encode(blockPresence))
121
+ }
122
+
123
+ function calculateEncodedWantlistEntrySize (entry: WantlistEntry): number {
124
+ // 1 is the "entries" field number in message.proto
125
+ return calculateLength(1, WantlistEntry.encode(entry))
126
+ }
127
+
128
+ function calculateLength (fieldNumber: number, data: Uint8Array): number {
129
+ const fieldNumberLength = encodingLength(fieldNumber)
130
+ const dataLengthLength = encodingLength(data.byteLength)
131
+
132
+ return fieldNumberLength + dataLengthLength + data.byteLength
133
+ }
package/src/want-list.ts CHANGED
@@ -375,7 +375,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
375
375
  * Invoked when a message is received from a bitswap peer
376
376
  */
377
377
  private async receiveMessage (sender: PeerId, message: BitswapMessage): Promise<void> {
378
- this.log('received message from %p', sender)
378
+ this.log('received message %d from %p with %d blocks', sender, message.blocks.length)
379
379
  let blocksCancelled = false
380
380
 
381
381
  // process blocks
@@ -397,7 +397,12 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
397
397
  continue
398
398
  }
399
399
 
400
- const hash = await hasher.digest(block.data)
400
+ let hash: any = hasher.digest(block.data)
401
+
402
+ if (hash.then != null) {
403
+ hash = await hash
404
+ }
405
+
401
406
  const cid = CID.create(cidVersion === 0 ? 0 : 1, multicodec, hash)
402
407
 
403
408
  this.log('received block from %p for %c', sender, cid)
@@ -423,7 +428,7 @@ export class WantList extends TypedEventEmitter<WantListEvents> implements Start
423
428
  const entry = this.wants.get(cidStr)
424
429
 
425
430
  if (entry == null) {
426
- return
431
+ continue
427
432
  }
428
433
 
429
434
  // since we received the block, flip the cancel flag to send cancels to
@@ -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
- }