-
Notifications
You must be signed in to change notification settings - Fork 115
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: helia supports additional byteProviders #276
Closed
SgtPooki
wants to merge
10
commits into
main
from
274-update-helia-to-fallback-to-trustless-http-gateways
+345
−10
Closed
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
df1d562
feat: helia supports additional blockProviders
SgtPooki 2e9bc2c
fix: aborted gatewayReqs dont emit uncaughtErrors
SgtPooki dfa5dcf
fix: remove additional bitswap started check
SgtPooki c754efd
chore: fix lint errors
SgtPooki 1c7730d
chore: fix build error after fixing lint errors
SgtPooki 89f85e3
chore: byte<->block provider naming and tests
SgtPooki e5dfb93
chore: lint fix
SgtPooki ef9b3c7
test: test-helper does not use default gateway providers
SgtPooki f9b51b6
test: empty default byteProviders unless explicitly needed
SgtPooki 15cb72d
Merge branch 'main' into 274-update-helia-to-fallback-to-trustless-ht…
SgtPooki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { logger } from '@libp2p/logger' | ||
import forEach from 'it-foreach' | ||
import type { Pair, GetOfflineOptions, ByteProvider } from '@helia/interface/blocks' | ||
import type { AbortOptions } from '@libp2p/interface' | ||
import type { Blockstore } from 'interface-blockstore' | ||
import type { AwaitIterable } from 'interface-store' | ||
import type { CID } from 'multiformats/cid' | ||
|
||
const log = logger('helia:block-provider') | ||
|
||
export interface GetOptions extends AbortOptions { | ||
progress?: (evt: Event) => void | ||
} | ||
|
||
/** | ||
* BlockProvider is a partial implementation of the Blocks interface that only handles block retrieval. | ||
* | ||
* This takes a {@link ByteProvider} and {@link Blockstore}. When a block is requested, it will first | ||
* check the blockstore for the block. If it is not found, it will then call the provider to get the bytes. Once the | ||
* bytes are retrieved, they are validated as a "block" and then that block is stored in the blockstore. | ||
* | ||
*/ | ||
export class BlockProvider { | ||
private readonly blockstore: Blockstore | ||
readonly #provider: ByteProvider | ||
|
||
/** | ||
* Create a new BlockProvider | ||
*/ | ||
constructor (blockstore: Blockstore, provider: ByteProvider) { | ||
this.blockstore = blockstore | ||
this.#provider = provider | ||
} | ||
|
||
/** | ||
* Get a block by cid, using the given ByteProvider | ||
*/ | ||
async get (cid: CID, options: GetOfflineOptions & AbortOptions): Promise<Uint8Array> { | ||
if (options.offline !== true && !(await this.blockstore.has(cid))) { | ||
try { | ||
const block = await this.#provider.get(cid, options) | ||
|
||
await this.blockstore.put(cid, block, options) | ||
|
||
return block | ||
} catch (err) { | ||
log.error('failed to get block for %s', cid.toString(), err) | ||
} | ||
} | ||
|
||
return this.blockstore.get(cid, options) | ||
} | ||
|
||
/** | ||
* Get multiple blocks back from an (async) iterable of cids | ||
*/ | ||
async * getMany (cids: AwaitIterable<CID>, options: GetOfflineOptions & AbortOptions): AsyncIterable<Pair> { | ||
yield * this.blockstore.getMany(forEach(cids, async (cid): Promise<void> => { | ||
if (options.offline !== true && !(await this.blockstore.has(cid))) { | ||
const block = await this.#provider.get(cid, options) | ||
|
||
await this.blockstore.put(cid, block, options) | ||
} | ||
})) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { getGatewayBlockProvider } from './byte-provider-gateway.js' | ||
import type { ByteProvider } from '@helia/interface/blocks' | ||
|
||
export function getDefaultByteProviders (): ByteProvider[] { | ||
return [ | ||
getGatewayBlockProvider('https://dweb.link'), // 2023-10-03: IPNS, Origin, and Block/CAR support from https://ipfs-public-gateway-checker.on.fleek.co/ | ||
getGatewayBlockProvider('https://cf-ipfs.com'), // 2023-10-03: IPNS, Origin, and Block/CAR support from https://ipfs-public-gateway-checker.on.fleek.co/ | ||
getGatewayBlockProvider('https://4everland.io'), // 2023-10-03: IPNS, Origin, and Block/CAR support from https://ipfs-public-gateway-checker.on.fleek.co/ | ||
getGatewayBlockProvider('https://w3s.link'), // 2023-10-03: IPNS, Origin, and Block/CAR support from https://ipfs-public-gateway-checker.on.fleek.co/ | ||
getGatewayBlockProvider('https://cloudflare-ipfs.com') // 2023-10-03: IPNS, and Block/CAR support from https://ipfs-public-gateway-checker.on.fleek.co/ | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { logger } from '@libp2p/logger' | ||
import { getRawBlockFromGateway } from './get-raw-block-from-gateway.js' | ||
import type { ByteProvider } from '@helia/interface/blocks' | ||
import type { CID } from 'multiformats/cid' | ||
|
||
const log = logger('helia:gateway-block-provider') | ||
|
||
export function getGatewayBlockProvider (url: URL | string): ByteProvider { | ||
const byteProvider: ByteProvider = { | ||
get: async (cid: CID, options = {}) => { | ||
log('getting block for %s from %s', cid.toString(), url.toString()) | ||
try { | ||
const block = await getRawBlockFromGateway(url, cid, options.signal) | ||
log('got block for %s from %s', cid.toString(), url.toString()) | ||
|
||
return block | ||
} catch (err) { | ||
log.error('failed to get block for %s from %s', cid.toString(), url.toString(), err) | ||
|
||
throw err | ||
} | ||
} | ||
} | ||
|
||
return byteProvider | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { CID } from 'multiformats/cid' | ||
|
||
export async function getRawBlockFromGateway (url: string | URL, cid: CID, signal?: AbortSignal): Promise<Uint8Array> { | ||
const gwUrl = new URL(url) | ||
|
||
gwUrl.pathname = `/ipfs/${cid.toString()}` | ||
gwUrl.search = '?format=raw' // necessary as not every gateway supports dag-cbor, but every should support sending raw block as-is | ||
if (signal?.aborted === true) { | ||
throw new Error(`Signal to fetch raw block for CID ${cid} from gateway ${gwUrl.toString()} was aborted prior to fetch`) | ||
} | ||
try { | ||
const res = await fetch(gwUrl.toString(), { | ||
signal, | ||
headers: { | ||
// also set header, just in case ?format= is filtered out by some reverse proxy | ||
Accept: 'application/vnd.ipld.raw' | ||
}, | ||
cache: 'force-cache' | ||
}) | ||
if (!res.ok) { | ||
throw new Error(`unable to fetch raw block for CID ${cid} from gateway ${gwUrl.toString()}`) | ||
} | ||
return new Uint8Array(await res.arrayBuffer()) | ||
} catch (cause) { | ||
// @ts-expect-error - TS thinks signal?.aborted can only be false now because it was checked for true above. | ||
if (signal?.aborted === true) { | ||
throw new Error(`fetching raw block for CID ${cid} from gateway ${gwUrl.toString()} was aborted`) | ||
} | ||
throw new Error(`unable to fetch raw block for CID ${cid}`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
we could wrap the blockstore on put that re-hashes it to verify.
we don't need to parse the data.. we just need to verify that when we hash the block with the cid.multihash.code is the same.
add method to this class for verifying bytes. might be able to use util methods in blockstore classes/package