@helia/bitswap 2.2.0 → 3.0.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/network.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { InvalidParametersError, NotStartedError, TimeoutError, TypedEventEmitter, UnsupportedProtocolError, setMaxListeners } from '@libp2p/interface'
2
- import { PeerQueue } from '@libp2p/utils/peer-queue'
2
+ import { PeerQueue } from '@libp2p/utils'
3
3
  import drain from 'it-drain'
4
4
  import * as lp from 'it-length-prefixed'
5
5
  import map from 'it-map'
6
- import { pipe } from 'it-pipe'
6
+ import { pushable } from 'it-pushable'
7
7
  import take from 'it-take'
8
8
  import { CustomProgressEvent } from 'progress-events'
9
9
  import { raceEvent } from 'race-event'
@@ -16,12 +16,13 @@ import type { MultihashHasherLoader } from './index.js'
16
16
  import type { Block } from './pb/message.js'
17
17
  import type { QueuedBitswapMessage } from './utils/bitswap-message.js'
18
18
  import type { Provider, Routing } from '@helia/interface/routing'
19
- import type { Libp2p, AbortOptions, Connection, PeerId, IncomingStreamData, Topology, ComponentLogger, IdentifyResult, Counter, Metrics } from '@libp2p/interface'
19
+ import type { Libp2p, AbortOptions, Connection, PeerId, Topology, ComponentLogger, IdentifyResult, Counter, Metrics, Stream } from '@libp2p/interface'
20
20
  import type { Logger } from '@libp2p/logger'
21
- import type { PeerQueueJobOptions } from '@libp2p/utils/peer-queue'
21
+ import type { PeerQueueJobOptions } from '@libp2p/utils'
22
22
  import type { Multiaddr } from '@multiformats/multiaddr'
23
23
  import type { CID } from 'multiformats/cid'
24
24
  import type { ProgressEvent, ProgressOptions } from 'progress-events'
25
+ import type { Uint8ArrayList } from 'uint8arraylist'
25
26
 
26
27
  export type BitswapNetworkProgressEvents =
27
28
  ProgressEvent<'bitswap:network:dial', PeerId | Multiaddr | Multiaddr[]>
@@ -114,9 +115,6 @@ export class Network extends TypedEventEmitter<NetworkEvents> {
114
115
  metrics: components.metrics,
115
116
  metricName: 'helia_bitswap_message_send_queue'
116
117
  })
117
- this.sendQueue.addEventListener('error', (evt) => {
118
- this.log.error('error sending wantlist to peer', evt.detail)
119
- })
120
118
  }
121
119
 
122
120
  async start (): Promise<void> {
@@ -179,13 +177,11 @@ export class Network extends TypedEventEmitter<NetworkEvents> {
179
177
  /**
180
178
  * Handles incoming bitswap messages
181
179
  */
182
- _onStream (info: IncomingStreamData): void {
180
+ _onStream (stream: Stream, connection: Connection): void {
183
181
  if (!this.running) {
184
182
  return
185
183
  }
186
184
 
187
- const { stream, connection } = info
188
-
189
185
  Promise.resolve().then(async () => {
190
186
  this.log('incoming new bitswap %s stream from %p', stream.protocol, connection.remotePeer)
191
187
  const abortListener = (): void => {
@@ -200,39 +196,49 @@ export class Network extends TypedEventEmitter<NetworkEvents> {
200
196
  setMaxListeners(Infinity, signal)
201
197
  signal.addEventListener('abort', abortListener)
202
198
 
203
- await stream.closeWrite()
204
-
205
- await pipe(
206
- stream,
207
- (source) => lp.decode(source, {
208
- maxDataLength: this.maxIncomingMessageSize
209
- }),
210
- async (source) => {
211
- for await (const data of source) {
212
- try {
213
- const message = BitswapMessage.decode(data)
214
- this.log('incoming new bitswap %s message from %p on stream', stream.protocol, connection.remotePeer, stream.id)
215
-
216
- this.safeDispatchEvent('bitswap:message', {
217
- detail: {
218
- peer: connection.remotePeer,
219
- message
220
- }
221
- })
222
-
223
- // we have received some data so reset the timeout controller
224
- signal.removeEventListener('abort', abortListener)
225
- signal = AbortSignal.timeout(this.messageReceiveTimeout)
226
- setMaxListeners(Infinity, signal)
227
- signal.addEventListener('abort', abortListener)
228
- } catch (err: any) {
229
- this.log.error('error reading incoming bitswap message from %p on stream', connection.remotePeer, stream.id, err)
230
- stream.abort(err)
231
- break
199
+ await stream.close({
200
+ signal
201
+ })
202
+
203
+ const input = pushable<Uint8Array | Uint8ArrayList>()
204
+
205
+ stream.addEventListener('message', (evt) => {
206
+ input.push(evt.data)
207
+ })
208
+ stream.addEventListener('remoteCloseWrite', () => {
209
+ input.end()
210
+ })
211
+ stream.addEventListener('close', (evt) => {
212
+ if (evt.error != null) {
213
+ input.end(evt.error)
214
+ }
215
+ })
216
+
217
+ for await (const data of lp.decode(input, {
218
+ maxDataLength: this.maxIncomingMessageSize
219
+ })) {
220
+ try {
221
+ const message = BitswapMessage.decode(data)
222
+ this.log('incoming new bitswap %s message from %p on stream', stream.protocol, connection.remotePeer, stream.id)
223
+
224
+ this.safeDispatchEvent('bitswap:message', {
225
+ detail: {
226
+ peer: connection.remotePeer,
227
+ message
232
228
  }
233
- }
229
+ })
230
+
231
+ // we have received some data so reset the timeout controller
232
+ signal.removeEventListener('abort', abortListener)
233
+ signal = AbortSignal.timeout(this.messageReceiveTimeout)
234
+ setMaxListeners(Infinity, signal)
235
+ signal.addEventListener('abort', abortListener)
236
+ } catch (err: any) {
237
+ this.log.error('error reading incoming bitswap message from %p on stream', connection.remotePeer, stream.id, err)
238
+ stream.abort(err)
239
+ break
234
240
  }
235
- )
241
+ }
236
242
  })
237
243
  .catch(err => {
238
244
  this.log.error('error handling incoming stream from %p', connection.remotePeer, err)
@@ -324,11 +330,11 @@ export class Network extends TypedEventEmitter<NetworkEvents> {
324
330
  await stream.closeRead()
325
331
 
326
332
  try {
327
- await pipe(
328
- splitMessage(message, this.maxOutgoingMessageSize),
329
- (source) => lp.encode(source),
330
- stream
331
- )
333
+ for (const buf of splitMessage(message, this.maxOutgoingMessageSize)) {
334
+ if (!stream.send(lp.encode.single(buf))) {
335
+ await stream.onDrain(options)
336
+ }
337
+ }
332
338
 
333
339
  await stream.close(options)
334
340
  } catch (err: any) {
@@ -1,3 +1,4 @@
1
+ import toBuffer from 'it-to-buffer'
1
2
  import { DEFAULT_MAX_SIZE_REPLACE_HAS_WITH_BLOCK } from '../constants.js'
2
3
  import { BlockPresenceType, WantType } from '../pb/message.js'
3
4
  import { QueuedBitswapMessage } from '../utils/bitswap-message.js'
@@ -93,7 +94,7 @@ export class Ledger {
93
94
 
94
95
  for (const [key, entry] of this.wants.entries()) {
95
96
  try {
96
- const block = await this.blockstore.get(entry.cid, options)
97
+ const block = await toBuffer(this.blockstore.get(entry.cid, options))
97
98
 
98
99
  // do they want the block or just us to tell them we have the block
99
100
  if (entry.wantType === WantType.WantHave) {
package/src/want-list.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
2
2
  import { trackedPeerMap } from '@libp2p/peer-collections'
3
- import { trackedMap } from '@libp2p/utils/tracked-map'
3
+ import { trackedMap } from '@libp2p/utils'
4
4
  import { CID } from 'multiformats/cid'
5
5
  import { sha256 } from 'multiformats/hashes/sha2'
6
6
  import pDefer from 'p-defer'