Skip to content
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!: upgrade to helia 5 #107

Merged
merged 4 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions packages/verified-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,52 +57,52 @@
"release": "aegir release"
},
"dependencies": {
"@helia/block-brokers": "^3.0.1",
"@helia/car": "^3.1.5",
"@helia/http": "^1.0.8",
"@helia/interface": "^4.3.0",
"@helia/ipns": "^7.2.2",
"@helia/routers": "^1.1.0",
"@ipld/dag-cbor": "^9.2.0",
"@ipld/dag-json": "^10.2.0",
"@ipld/dag-pb": "^4.1.0",
"@libp2p/interface": "^1.4.0",
"@libp2p/kad-dht": "^12.0.17",
"@libp2p/peer-id": "^4.1.2",
"@helia/block-brokers": "^4.0.0",
"@helia/car": "^4.0.0",
"@helia/http": "^2.0.0",
"@helia/interface": "^5.0.0",
"@helia/ipns": "^8.0.0",
"@helia/routers": "^2.0.0",
"@ipld/dag-cbor": "^9.2.1",
"@ipld/dag-json": "^10.2.2",
"@ipld/dag-pb": "^4.1.2",
"@libp2p/interface": "^2.1.3",
"@libp2p/kad-dht": "^14.0.1",
"@libp2p/peer-id": "^5.0.5",
"@multiformats/dns": "^1.0.6",
"cborg": "^4.2.0",
"cborg": "^4.2.4",
"hashlru": "^2.3.0",
"interface-blockstore": "^5.2.10",
"interface-datastore": "^8.2.11",
"ipfs-unixfs-exporter": "^13.5.0",
"it-map": "^3.1.0",
"interface-blockstore": "^5.3.1",
"interface-datastore": "^8.3.1",
"ipfs-unixfs-exporter": "^13.6.1",
"it-map": "^3.1.1",
"it-pipe": "^3.0.1",
"it-tar": "^6.0.5",
"it-to-browser-readablestream": "^2.0.9",
"lru-cache": "^10.2.2",
"multiformats": "^13.1.0",
"progress-events": "^1.0.0",
"multiformats": "^13.3.0",
"progress-events": "^1.0.1",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
"@helia/dag-cbor": "^3.0.4",
"@helia/dag-json": "^3.0.4",
"@helia/json": "^3.0.4",
"@helia/unixfs": "^3.0.6",
"@helia/utils": "^0.3.1",
"@ipld/car": "^5.3.0",
"@libp2p/interface-compliance-tests": "^5.4.5",
"@libp2p/logger": "^4.0.13",
"@libp2p/peer-id-factory": "^4.1.2",
"@helia/dag-cbor": "^4.0.0",
"@helia/dag-json": "^4.0.0",
"@helia/json": "^4.0.0",
"@helia/unixfs": "^4.0.0",
"@helia/utils": "^1.0.0",
"@ipld/car": "^5.3.2",
"@libp2p/interface-compliance-tests": "^6.1.6",
"@libp2p/logger": "^5.1.1",
"@libp2p/peer-id-factory": "^4.2.4",
"@sgtpooki/file-type": "^1.0.1",
"@types/sinon": "^17.0.3",
"aegir": "^42.2.11",
"blockstore-core": "^4.4.1",
"blockstore-core": "^5.0.2",
"browser-readablestream-to-it": "^2.0.7",
"datastore-core": "^9.2.9",
"helia": "^4.2.2",
"ipfs-unixfs-importer": "^15.2.5",
"ipns": "^9.1.0",
"datastore-core": "^10.0.2",
"helia": "^5.0.0",
"ipfs-unixfs-importer": "^15.3.1",
"ipns": "^10.0.0",
"it-all": "^3.0.6",
"it-drain": "^3.0.7",
"it-last": "^3.0.6",
Expand Down
5 changes: 2 additions & 3 deletions packages/verified-fetch/src/utils/get-tar-stream.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { CodeError } from '@libp2p/interface'
import { exporter, recursive, type UnixFSEntry } from 'ipfs-unixfs-exporter'
import map from 'it-map'
import { pipe } from 'it-pipe'
Expand Down Expand Up @@ -28,7 +27,7 @@ function toHeader (file: UnixFSEntry): Partial<TarEntryHeader> & { name: string

function toTarImportCandidate (entry: UnixFSEntry): TarImportCandidate {
if (!EXPORTABLE.includes(entry.type)) {
throw new CodeError('Not a UnixFS node', 'ERR_NOT_UNIXFS')
throw new Error('Not a UnixFS node')
}
2color marked this conversation as resolved.
Show resolved Hide resolved

const candidate: TarImportCandidate = {
Expand Down Expand Up @@ -64,5 +63,5 @@ export async function * tarStream (ipfsPath: string, blockstore: Blockstore, opt
return
}

throw new CodeError('Not a UnixFS node', 'ERR_NOT_UNIXFS')
throw new Error('Not a UnixFS node')
}
9 changes: 6 additions & 3 deletions packages/verified-fetch/src/utils/parse-url-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CID } from 'multiformats/cid'
import { TLRU } from './tlru.js'
import type { RequestFormatShorthand } from '../types.js'
import type { DNSLinkResolveResult, IPNS, IPNSResolveResult, IPNSRoutingEvents, ResolveDNSLinkProgressEvents, ResolveProgressEvents, ResolveResult } from '@helia/ipns'
import type { AbortOptions, ComponentLogger } from '@libp2p/interface'
import type { AbortOptions, ComponentLogger, PeerId } from '@libp2p/interface'
import type { ProgressOptions } from 'progress-events'

const ipnsCache = new TLRU<DNSLinkResolveResult | IPNSResolveResult>(1000)
Expand Down Expand Up @@ -174,11 +174,14 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin
log.trace('resolved %s to %c from cache', cidOrPeerIdOrDnsLink, cid)
} else {
log.trace('Attempting to resolve PeerId for %s', cidOrPeerIdOrDnsLink)
let peerId = null
let peerId: PeerId | undefined
try {
// try resolving as an IPNS name
peerId = peerIdFromString(cidOrPeerIdOrDnsLink)
resolveResult = await ipns.resolve(peerId, options)
if (peerId.publicKey == null) {
throw new Error('cidOrPeerIdOrDnsLink contains no public key')
}
resolveResult = await ipns.resolve(peerId.publicKey, options)
cid = resolveResult?.cid
resolvedPath = resolveResult?.path
log.trace('resolved %s to %c', cidOrPeerIdOrDnsLink, cid)
Expand Down
4 changes: 2 additions & 2 deletions packages/verified-fetch/src/utils/walk-path.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CodeError, type Logger } from '@libp2p/interface'
import { type Logger } from '@libp2p/interface'
import { type Blockstore } from 'interface-blockstore'
import { walkPath as exporterWalk, type ExporterOptions, type ReadableStorage, type ObjectNode, type UnixFSEntry } from 'ipfs-unixfs-exporter'
import { type FetchHandlerFunctionArg } from '../types.js'
Expand Down Expand Up @@ -28,7 +28,7 @@ export async function walkPath (blockstore: ReadableStorage, path: string, optio
}

if (terminalElement == null) {
throw new CodeError('No terminal element found', 'ERR_NO_TERMINAL_ELEMENT')
throw new Error('No terminal element found')
}

return {
Expand Down
9 changes: 4 additions & 5 deletions packages/verified-fetch/src/verified-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { setCacheControlHeader, setIpfsRoots } from './utils/response-headers.js
import { badRequestResponse, movedPermanentlyResponse, notAcceptableResponse, notSupportedResponse, okResponse, badRangeResponse, okRangeResponse, badGatewayResponse, notFoundResponse } from './utils/responses.js'
import { selectOutputType } from './utils/select-output-type.js'
import { handlePathWalking, isObjectNode } from './utils/walk-path.js'
import type { CIDDetail, ContentTypeParser, CreateVerifiedFetchOptions, Resource, VerifiedFetchInit as VerifiedFetchOptions } from './index.js'
import type { CIDDetail, ContentTypeParser, CreateVerifiedFetchOptions, Resource, ResourceDetail, VerifiedFetchInit as VerifiedFetchOptions } from './index.js'
import type { FetchHandlerFunctionArg, RequestFormatShorthand } from './types.js'
import type { Helia, SessionBlockstore } from '@helia/interface'
import type { Blockstore } from 'interface-blockstore'
Expand Down Expand Up @@ -167,7 +167,7 @@ export class VerifiedFetch {
// just read it out..
const routingKey = uint8ArrayConcat([
uint8ArrayFromString('/ipns/'),
peerId.toBytes()
peerId.toMultihash().bytes
])
const datastoreKey = new Key('/dht/record/' + uint8ArrayToString(routingKey, 'base32'), false)
const buf = await this.helia.datastore.get(datastoreKey, options)
Expand All @@ -185,7 +185,7 @@ export class VerifiedFetch {
*/
private async handleCar ({ resource, cid, session, options }: FetchHandlerFunctionArg): Promise<Response> {
const blockstore = this.getBlockstore(cid, resource, session, options)
const c = car({ blockstore, dagWalkers: this.helia.dagWalkers })
const c = car({ blockstore, getCodec: this.helia.getCodec })
const stream = toBrowserReadableStream(c.stream(cid, options))

const response = okResponse(resource, stream)
Expand Down Expand Up @@ -481,8 +481,7 @@ export class VerifiedFetch {

const options = convertOptions(opts)

options?.onProgress?.(new CustomProgressEvent<CIDDetail>('verified-fetch:request:start', { resource }))

options?.onProgress?.(new CustomProgressEvent<ResourceDetail>('verified-fetch:request:start', { resource }))
// resolve the CID/path from the requested resource
let cid: ParsedUrlStringResults['cid']
let path: ParsedUrlStringResults['path']
Expand Down
10 changes: 6 additions & 4 deletions packages/verified-fetch/test/abort-handling.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { dagCbor } from '@helia/dag-cbor'
import { type DNSLinkResolveResult, type IPNS, type IPNSResolveResult } from '@helia/ipns'
import { unixfs } from '@helia/unixfs'
import { generateKeyPair } from '@libp2p/crypto/keys'
import { stop, type ComponentLogger, type Logger } from '@libp2p/interface'
import { prefixLogger, logger as libp2pLogger } from '@libp2p/logger'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import browserReadableStreamToIt from 'browser-readablestream-to-it'
import { fixedSize } from 'ipfs-unixfs-importer/chunker'
Expand Down Expand Up @@ -102,11 +103,12 @@ describe('abort-handling', function () {
hello: 'world'
})

const peerId = await createEd25519PeerId()
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)

await name.publish(peerId, cid, { lifetime: 1000 * 60 * 60 })
await name.publish(key, cid, { lifetime: 1000 * 60 * 60 })

await expect(makeAbortedRequest(verifiedFetch, [`ipns://${peerId}`], peerIdResolverCalled.promise)).to.eventually.be.rejectedWith('aborted')
await expect(makeAbortedRequest(verifiedFetch, [`ipns://${peerId.toString()}`], peerIdResolverCalled.promise)).to.eventually.be.rejectedWith('aborted')
expect(peerIdResolver.callCount).to.equal(1)
expect(dnsLinkResolver.callCount).to.equal(0) // not called because signal abort was detected
expect(blockRetriever.retrieve.callCount).to.equal(0) // not called because we never got the cid
Expand Down
13 changes: 8 additions & 5 deletions packages/verified-fetch/test/accept-header.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { dagJson } from '@helia/dag-json'
import { ipns } from '@helia/ipns'
import * as ipldDagCbor from '@ipld/dag-cbor'
import * as ipldDagJson from '@ipld/dag-json'
import { generateKeyPair } from '@libp2p/crypto/keys'
import { stop } from '@libp2p/interface'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import * as cborg from 'cborg'
import { marshal } from 'ipns'
import { marshalIPNSRecord } from 'ipns'
import { CID } from 'multiformats/cid'
import * as raw from 'multiformats/codecs/raw'
import { sha256 } from 'multiformats/hashes/sha2'
Expand Down Expand Up @@ -269,15 +270,17 @@ describe('accept header', () => {
})

it('should support fetching IPNS records', async () => {
const peerId = await createEd25519PeerId()
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)

const obj = {
hello: 'world'
}
const c = dagCbor(helia)
const cid = await c.add(obj)

const i = ipns(helia)
const record = await i.publish(peerId, cid)
const record = await i.publish(key, cid)

const resp = await verifiedFetch.fetch(`ipns://${peerId}`, {
headers: {
Expand All @@ -288,7 +291,7 @@ describe('accept header', () => {
expect(resp.headers.get('content-type')).to.equal('application/vnd.ipfs.ipns-record')
const buf = await resp.arrayBuffer()

expect(new Uint8Array(buf)).to.equalBytes(marshal(record))
expect(new Uint8Array(buf)).to.equalBytes(marshalIPNSRecord(record))
})

shouldNotAcceptCborWith({
Expand Down
13 changes: 8 additions & 5 deletions packages/verified-fetch/test/cache-control-header.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { dagCbor } from '@helia/dag-cbor'
import { ipns } from '@helia/ipns'
import { generateKeyPair } from '@libp2p/crypto/keys'
import { stop } from '@libp2p/interface'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { dns } from '@multiformats/dns'
import { expect } from 'aegir/chai'
import Sinon from 'sinon'
Expand Down Expand Up @@ -59,10 +60,11 @@ describe('cache-control header', () => {
const cid = await c.add(obj)

const oneHourInMs = 1000 * 60 * 60
const peerId = await createEd25519PeerId()
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)

// ipns currently only allows customising the lifetime which is also used as the TTL
await name.publish(peerId, cid, { lifetime: oneHourInMs })
await name.publish(key, cid, { lifetime: oneHourInMs })

const resp = await verifiedFetch.fetch(`ipns://${peerId}`)
expect(resp).to.be.ok()
Expand All @@ -82,7 +84,8 @@ describe('cache-control header', () => {
const cid = await c.add(obj)

const oneHourInSeconds = 60 * 60
const peerId = await createEd25519PeerId()
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)

/**
* ipns currently only allows customising the lifetime which is also used as the TTL
Expand All @@ -92,7 +95,7 @@ describe('cache-control header', () => {
* @see https://github.com/ipfs/js-ipns/blob/16e0e10682fa9a663e0bb493a44d3e99a5200944/src/index.ts#L200
* @see https://github.com/ipfs/js-ipns/pull/308
*/
await name.publish(peerId, cid, { lifetime: oneHourInSeconds * 1000 }) // pass to ipns as milliseconds
await name.publish(key, cid, { lifetime: oneHourInSeconds * 1000 }) // pass to ipns as milliseconds

const resp = await verifiedFetch.fetch(`ipns://${peerId}`)
expect(resp).to.be.ok()
Expand Down
19 changes: 11 additions & 8 deletions packages/verified-fetch/test/ipns-record.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { dagCbor } from '@helia/dag-cbor'
import { ipns } from '@helia/ipns'
import { generateKeyPair } from '@libp2p/crypto/keys'
import { stop } from '@libp2p/interface'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import { marshal, unmarshal } from 'ipns'
import { marshalIPNSRecord, unmarshalIPNSRecord } from 'ipns'
import { VerifiedFetch } from '../src/verified-fetch.js'
import { createHelia } from './fixtures/create-offline-helia.js'
import type { Helia } from '@helia/interface'
Expand Down Expand Up @@ -33,8 +34,9 @@ describe('ipns records', () => {
const c = dagCbor(helia)
const cid = await c.add(obj)

const peerId = await createEd25519PeerId()
const record = await name.publish(peerId, cid)
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)
const record = await name.publish(key, cid)

const resp = await verifiedFetch.fetch(`ipns://${peerId}`, {
headers: {
Expand All @@ -45,9 +47,9 @@ describe('ipns records', () => {
expect(resp.headers.get('content-type')).to.equal('application/vnd.ipfs.ipns-record')

const buf = new Uint8Array(await resp.arrayBuffer())
expect(marshal(record)).to.equalBytes(buf)
expect(marshalIPNSRecord(record)).to.equalBytes(buf)

const output = unmarshal(buf)
const output = unmarshalIPNSRecord(buf)
expect(output.value).to.deep.equal(`/ipfs/${cid}`)
})

Expand Down Expand Up @@ -76,8 +78,9 @@ describe('ipns records', () => {
const c = dagCbor(helia)
const cid = await c.add(obj)

const peerId = await createEd25519PeerId()
await name.publish(peerId, cid)
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)
await name.publish(key, cid)

const resp = await verifiedFetch.fetch(`ipns://${peerId}/hello`, {
headers: {
Expand Down
6 changes: 4 additions & 2 deletions packages/verified-fetch/test/parse-resource.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { generateKeyPair } from '@libp2p/crypto/keys'
import { defaultLogger } from '@libp2p/logger'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import { CID } from 'multiformats/cid'
import sinon from 'sinon'
Expand All @@ -8,7 +9,8 @@ import { parseResource } from '../src/utils/parse-resource.js'
import type { IPNS } from '@helia/ipns'

const testCID = CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr')
const peerId = await createEd25519PeerId()
const key = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(key)

describe('parseResource', () => {
it('does not call @helia/ipns for CID', async () => {
Expand Down
Loading
Loading