-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add @helia/bitswap with sessions #409
Conversation
3e547bb
to
6e789da
Compare
There are no implementations yet but the usage pattern will be something like: ```javascript // unixfs cat command export async function * cat (cid: CID, blockstore: Blocks, options: Partial<CatOptions> = {}): AsyncIterable<Uint8Array> { // create a session for the CID if support is available const blocks = await (blockstore.createSession != null ? blockstore.createSession(cid) : blockstore) const opts: CatOptions = mergeOptions(defaultOptions, options) // resolve and export using the session, if created, otherwise fall back to regular blockstore access const resolved = await resolve(cid, opts.path, blocks, opts) const result = await exporter(resolved.cid, blocks, opts) if (result.type !== 'file' && result.type !== 'raw') { throw new NotAFileError() } if (result.content == null) { throw new NoContentError() } yield * result.content(opts) } ```
b1c5fe9
to
32713ab
Compare
Adds a `@helia/bitswap` module with code ported from `ipfs-bitswap` and greatly simplified. - Supports sessions - Only supports bitswap 1.2.0 - Uses libp2p's metrics system instead of a custom version
6e789da
to
73ab5f9
Compare
…ifferent metadata
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
14/35 files reviewed. I'm going to have to come back to this one, but it may be more valuable for someone like @lidel or @aschmahmann to peek at this.
@@ -0,0 +1,11 @@ | |||
export const BITSWAP_120 = '/ipfs/bitswap/1.2.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export const BITSWAP_120 = '/ipfs/bitswap/1.2.0' | |
export const BITSWAP_PROTOCOL = '/ipfs/bitswap/1.2.0' |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah? It's Bitswap 1.2.0, plain Bitswap might be 1.0.0?
} | ||
|
||
async retrieve (cid: CID, options: BlockRetrievalOptions<BitswapWantBlockProgressEvents> = {}): Promise<Uint8Array> { | ||
return this.bitswap.want(cid, options) | ||
} | ||
|
||
async createSession (root: CID, options?: CreateSessionOptions<BitswapWantBlockProgressEvents>): Promise<BlockBroker<BitswapWantBlockProgressEvents, BitswapNotifyProgressEvents>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this used anywhere yet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been integrating it with helia-http-gateway
, it seems to work!
* JavaScript implementation of the Bitswap 'data exchange' protocol | ||
* used by IPFS. | ||
*/ | ||
export class Bitswap implements BitswapInterface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to support provider filtering, or is that done in the routers?
getWantlist (): WantListEntry[] { | ||
return [...this.wantList.wants.values()] | ||
.filter(entry => !entry.cancel) | ||
.map(entry => ({ | ||
cid: entry.cid, | ||
priority: entry.priority, | ||
wantType: entry.wantType | ||
})) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like knowledge of sessions that wantlists are associated with would be valuable, but this is my first time looking deeply at a bitswap protocol implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, it's something we could add for introspection later if we need it?
return createBitswapSession({ | ||
wantList: this.wantList, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this associating the global wantlist to all sessions? do we want to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, cos we tell the wantlist that a given wants is a session want, the wantlist then keeps track of everything to make sure the right peers are sent the right wants, including upgrading the want from one type to another if the same block is wanted from different contexts (a session, another session, not a session, etc).
// report stats to libp2p metrics | ||
this.stats = new Stats(components) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we have a toggle for stats like libp2p?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If libp2p metrics aren't enabled everything's a no-op. I wouldn't add a toggle here since we could toggle it on for bitswap, but off for libp2p and then people would wonder why they aren't getting stats.
Co-authored-by: Russell Dempsey <[email protected]>
Co-authored-by: Russell Dempsey <[email protected]>
Adds a
@helia/bitswap
module with code ported fromipfs-bitswap
and greatly simplified.