@helia/bitswap
Version:
JavaScript implementation of the Bitswap data exchange protocol used by Helia
189 lines (162 loc) • 5.53 kB
text/typescript
/**
* @packageDocumentation
*
* This module implements the [Bitswap protocol](https://docs.ipfs.tech/concepts/bitswap/) in TypeScript.
*
* It supersedes the older [ipfs-bitswap](https://www.npmjs.com/package/ipfs-bitswap) module with the aim of being smaller, faster, better integrated with libp2p/helia, having fewer dependencies and using standard JavaScript instead of Node.js APIs.
*/
import { Bitswap as BitswapClass } from './bitswap.js'
import type { BitswapNetworkNotifyProgressEvents, BitswapNetworkWantProgressEvents } from './network.js'
import type { WantType } from './pb/message.js'
import type { BlockBroker, CreateSessionOptions } from '@helia/interface'
import type { Routing } from '@helia/interface/routing'
import type { Libp2p, AbortOptions, Startable, ComponentLogger, Metrics, PeerId } from '@libp2p/interface'
import type { Blockstore } from 'interface-blockstore'
import type { CID } from 'multiformats/cid'
import type { MultihashHasher } from 'multiformats/hashes/interface'
import type { ProgressEvent, ProgressOptions } from 'progress-events'
export type BitswapWantProgressEvents =
BitswapWantBlockProgressEvents
export type BitswapNotifyProgressEvents =
BitswapNetworkNotifyProgressEvents
export type BitswapWantBlockProgressEvents =
ProgressEvent<'bitswap:want-block:unwant', CID> |
ProgressEvent<'bitswap:want-block:block', CID> |
BitswapNetworkWantProgressEvents
export interface WantListEntry {
cid: CID
priority: number
wantType: WantType
}
export interface Bitswap extends Startable {
/**
* Returns the current state of the wantlist
*/
getWantlist(): WantListEntry[]
/**
* Returns the current state of the wantlist for a peer, if it is being
* tracked
*/
getPeerWantlist(peerId: PeerId): WantListEntry[] | undefined
/**
* Notify bitswap that a new block is available
*/
notify(cid: CID, block: Uint8Array, options?: ProgressOptions<BitswapNotifyProgressEvents>): Promise<void>
/**
* Start a session to retrieve a file from the network
*/
want(cid: CID, options?: AbortOptions & ProgressOptions<BitswapWantProgressEvents>): Promise<Uint8Array>
/**
* Start a session to retrieve a file from the network
*/
createSession(options?: CreateSessionOptions<BitswapWantProgressEvents>): Required<Pick<BlockBroker<BitswapWantProgressEvents>, 'retrieve'>>
}
export interface MultihashHasherLoader {
getHasher(codeOrName: number | string): Promise<MultihashHasher>
}
export interface BitswapComponents {
routing: Routing
blockstore: Blockstore
logger: ComponentLogger
libp2p: Libp2p
metrics?: Metrics
}
export interface BitswapOptions {
/**
* This is the maximum number of concurrent inbound bitswap streams that are
* allowed
*
* @default 32
*/
maxInboundStreams?: number
/**
* This is the maximum number of concurrent outbound bitswap streams that are
* allowed
*
* @default 128
*/
maxOutboundStreams?: number
/**
* An incoming stream must resolve within this number of seconds
*
* @default 30000
*/
incomingStreamTimeout?: number
/**
* Whether to run on transient (e.g. time/data limited) connections
*
* @default false
*/
runOnTransientConnections?: boolean
/**
* Enables loading esoteric hash functions
*/
hashLoader?: MultihashHasherLoader
/**
* The protocol that we speak
*
* @default '/ipfs/bitswap/1.2.0'
*/
protocol?: string
/**
* When sending want list updates to peers, how many messages to send at once
*
* @default 50
*/
messageSendConcurrency?: number
/**
* When sending blocks to peers, how many messages to send at once
*
* @default 50
*/
sendBlocksConcurrency?: number
/**
* When sending blocks to peers, timeout after this many milliseconds.
* This is useful for preventing slow/large peer-connections from consuming
* your bandwidth/streams.
*
* @default 10000
*/
sendBlocksTimeout?: number
/**
* When a block is added to the blockstore and we are about to send that block
* to peers who have it in their wantlist, wait this many milliseconds before
* queueing the send job in case more blocks are added that they want
*
* @default 10
*/
sendBlocksDebounce?: number
/**
* If the client sends a want-have, and we have the corresponding block, we
* check the size of the block and if it's small enough we send the block
* itself, rather than sending a HAVE.
*
* This defines the maximum size up to which we replace a HAVE with a block.
*
* @default 1024
*/
maxSizeReplaceHasWithBlock?: number
/**
* The maximum size in bytes of a message that we will send. If a message is
* larger than this (due to lots of blocks or wantlist entries) it will be
* broken up into several smaller messages that are under this size.
*
* @see https://github.com/ipfs/boxo/blob/eeea414587350401b6b804f0574ed8436833331d/bitswap/client/internal/messagequeue/messagequeue.go#L33
*
* @default 2097152
*/
maxOutgoingMessageSize?: number
/**
* The maximum size in bytes of an incoming message that we will process.
*
* Messages larger than this will cause the incoming stream to be reset.
*
* Defaults to `maxOutgoingMessageSize`
*
* @default 2097152
*/
maxIncomingMessageSize?: number
}
export const createBitswap = (components: BitswapComponents, options: BitswapOptions = {}): Bitswap => {
return new BitswapClass(components, options)
}