-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR updates the `index/add` handler to publish an [index claim](https://github.com/w3s-project/content-claims?tab=readme-ov-file#index-claim) for the added index. Reading an index from the index claim allows freeway and hoverboard to serve blocks from all of the shards without having to request a location claim for each block. refs storacha/blob-fetcher#10
- Loading branch information
Alan Shaw
authored
Jun 7, 2024
1 parent
cf0a1d6
commit 237b0c6
Showing
12 changed files
with
322 additions
and
25 deletions.
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
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,31 @@ | ||
import { | ||
ConnectionView, | ||
DID, | ||
Principal, | ||
Proof, | ||
Signer, | ||
} from '@ucanto/interface' | ||
import { Service } from '@web3-storage/content-claims/server/service/api' | ||
|
||
export type { ConnectionView, DID, Principal, Proof, Signer } | ||
export type { Service } | ||
|
||
export interface ClaimsInvocationConfig { | ||
/** Signing authority issuing the UCAN invocation(s). */ | ||
issuer: Signer | ||
/** The principal delegated to in the current UCAN. */ | ||
audience: Principal | ||
/** The resource the invocation applies to. */ | ||
with: DID | ||
/** Proof(s) the issuer has the capability to perform the action. */ | ||
proofs?: Proof[] | ||
} | ||
|
||
export interface ClaimsClientConfig { | ||
invocationConfig: ClaimsInvocationConfig | ||
connection: ConnectionView<Service> | ||
} | ||
|
||
export interface ClaimsClientContext { | ||
claimsService: ClaimsClientConfig | ||
} |
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
131 changes: 131 additions & 0 deletions
131
packages/upload-api/test/external-service/content-claims.js
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,131 @@ | ||
import * as API from '../../src/types.js' | ||
import { connect } from '@ucanto/client' | ||
import { ed25519 } from '@ucanto/principal' | ||
import { CAR, HTTP } from '@ucanto/transport' | ||
import { Assert } from '@web3-storage/content-claims/capability' | ||
import * as Client from '@web3-storage/content-claims/client' | ||
import * as Server from '@web3-storage/content-claims/server' | ||
import { DigestMap } from '@web3-storage/blob-index' | ||
|
||
/** | ||
* @param {object} params | ||
* @param {API.Signer} params.serviceSigner | ||
* @param {API.Transport.Channel<API.ClaimsService>} params.channel | ||
* @returns {Promise<API.ClaimsClientConfig>} | ||
*/ | ||
export const create = async ({ serviceSigner, channel }) => { | ||
const agent = await ed25519.generate() | ||
const proofs = [ | ||
await Assert.assert.delegate({ | ||
issuer: serviceSigner, | ||
with: serviceSigner.did(), | ||
audience: agent, | ||
}), | ||
] | ||
return { | ||
invocationConfig: { | ||
issuer: agent, | ||
with: serviceSigner.did(), | ||
audience: serviceSigner, | ||
proofs, | ||
}, | ||
connection: connect({ | ||
id: serviceSigner, | ||
codec: CAR.outbound, | ||
channel, | ||
}), | ||
} | ||
} | ||
|
||
/** | ||
* @param {{ http?: import('node:http') }} [options] | ||
* @returns {Promise<API.ClaimsClientConfig & API.ClaimReader & API.Deactivator>} | ||
*/ | ||
export const activate = async ({ http } = {}) => { | ||
const serviceSigner = await ed25519.generate() | ||
|
||
const claimStore = new ClaimStorage() | ||
/** @param {API.MultihashDigest} content */ | ||
const read = async (content) => { | ||
/** @type {import('@web3-storage/content-claims/client/api').Claim[]} */ | ||
const claims = [] | ||
await Server.walkClaims( | ||
{ claimFetcher: claimStore }, | ||
content, | ||
new Set() | ||
).pipeTo( | ||
new WritableStream({ | ||
async write(block) { | ||
const claim = await Client.decode(block.bytes) | ||
claims.push(claim) | ||
}, | ||
}) | ||
) | ||
return { ok: claims } | ||
} | ||
|
||
const server = Server.createServer({ | ||
id: serviceSigner, | ||
codec: CAR.inbound, | ||
claimStore, | ||
validateAuthorization: () => ({ ok: {} }), | ||
}) | ||
|
||
if (!http) { | ||
const conf = await create({ serviceSigner, channel: server }) | ||
return Object.assign(conf, { read, deactivate: async () => {} }) | ||
} | ||
|
||
const httpServer = http.createServer(async (req, res) => { | ||
const chunks = [] | ||
for await (const chunk of req) { | ||
chunks.push(chunk) | ||
} | ||
|
||
const { headers, body } = await server.request({ | ||
// @ts-expect-error | ||
headers: req.headers, | ||
body: new Uint8Array(await new Blob(chunks).arrayBuffer()), | ||
}) | ||
|
||
res.writeHead(200, headers) | ||
res.write(body) | ||
res.end() | ||
}) | ||
await new Promise((resolve) => httpServer.listen(resolve)) | ||
// @ts-expect-error | ||
const { port } = httpServer.address() | ||
const serviceURL = new URL(`http://127.0.0.1:${port}`) | ||
|
||
const channel = HTTP.open({ url: serviceURL, method: 'POST' }) | ||
const conf = await create({ serviceSigner, channel }) | ||
return Object.assign(conf, { | ||
read, | ||
deactivate: () => | ||
new Promise((resolve, reject) => { | ||
httpServer.closeAllConnections() | ||
httpServer.close((err) => { | ||
err ? reject(err) : resolve(undefined) | ||
}) | ||
}), | ||
}) | ||
} | ||
|
||
class ClaimStorage { | ||
constructor() { | ||
/** @type {Map<API.MultihashDigest, import('@web3-storage/content-claims/server/api').Claim[]>} */ | ||
this.data = new DigestMap() | ||
} | ||
|
||
/** @param {import('@web3-storage/content-claims/server/api').Claim} claim */ | ||
async put(claim) { | ||
const claims = this.data.get(claim.content) ?? [] | ||
claims.push(claim) | ||
this.data.set(claim.content, claims) | ||
} | ||
|
||
/** @param {API.MultihashDigest} content */ | ||
async get(content) { | ||
return this.data.get(content) ?? [] | ||
} | ||
} |
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 |
---|---|---|
@@ -1,5 +1,11 @@ | ||
import { IPNIService } from './ipni-service.js' | ||
import { IPNIService } from './ipni.js' | ||
import * as ClaimsService from './content-claims.js' | ||
|
||
export const getExternalServiceImplementations = async () => ({ | ||
/** | ||
* @param {object} [options] | ||
* @param {import('node:http')} [options.http] | ||
*/ | ||
export const getExternalServiceImplementations = async (options) => ({ | ||
ipniService: new IPNIService(), | ||
claimsService: await ClaimsService.activate(options), | ||
}) |
File renamed without changes.
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.