@helia/bitswap 1.0.0 → 1.0.1-0ecb529
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/dist/index.min.js +1 -1
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +20 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/network.d.ts +5 -3
- package/dist/src/network.d.ts.map +1 -1
- package/dist/src/network.js +52 -128
- package/dist/src/network.js.map +1 -1
- package/dist/src/pb/message.d.ts +6 -6
- package/dist/src/pb/message.d.ts.map +1 -1
- package/dist/src/pb/message.js +37 -20
- package/dist/src/pb/message.js.map +1 -1
- package/dist/src/peer-want-lists/index.d.ts +1 -0
- package/dist/src/peer-want-lists/index.d.ts.map +1 -1
- package/dist/src/peer-want-lists/index.js +5 -1
- package/dist/src/peer-want-lists/index.js.map +1 -1
- package/dist/src/peer-want-lists/ledger.d.ts +3 -1
- package/dist/src/peer-want-lists/ledger.d.ts.map +1 -1
- package/dist/src/peer-want-lists/ledger.js +8 -0
- package/dist/src/peer-want-lists/ledger.js.map +1 -1
- package/dist/src/utils/merge-messages.d.ts +3 -0
- package/dist/src/utils/merge-messages.d.ts.map +1 -0
- package/dist/src/utils/merge-messages.js +51 -0
- package/dist/src/utils/merge-messages.js.map +1 -0
- package/dist/src/utils/split-message.d.ts +18 -0
- package/dist/src/utils/split-message.d.ts.map +1 -0
- package/dist/src/utils/split-message.js +101 -0
- package/dist/src/utils/split-message.js.map +1 -0
- package/dist/src/want-list.d.ts.map +1 -1
- package/dist/src/want-list.js +6 -3
- package/dist/src/want-list.js.map +1 -1
- package/package.json +4 -4
- package/src/constants.ts +2 -0
- package/src/index.ts +22 -8
- package/src/network.ts +60 -150
- package/src/pb/message.ts +40 -20
- package/src/peer-want-lists/index.ts +5 -1
- package/src/peer-want-lists/ledger.ts +11 -1
- package/src/utils/merge-messages.ts +70 -0
- package/src/utils/split-message.ts +133 -0
- package/src/want-list.ts +8 -3
- 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
|
-
|
|
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
|
-
|
|
431
|
+
continue
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
// since we received the block, flip the cancel flag to send cancels to
|
package/dist/typedoc-urls.json
DELETED
|
@@ -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
|
-
}
|