Skip to content

Commit

Permalink
fix: rename blob and index client capabilities (#1478)
Browse files Browse the repository at this point in the history
Rename capabilities to minimize issues on migration for clients based on
storacha/RFC#12
  • Loading branch information
vasco-santos authored May 30, 2024
1 parent 2998a93 commit 17e3a31
Show file tree
Hide file tree
Showing 23 changed files with 519 additions and 466 deletions.
12 changes: 6 additions & 6 deletions packages/capabilities/src/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import { equalBlob, equalWith, SpaceDID } from './utils.js'

/**
* Capability can only be delegated (but not invoked) allowing audience to
* derived any `blob/` prefixed capability for the (memory) space identified
* derived any `space/blob/` prefixed capability for the (memory) space identified
* by DID in the `with` field.
*/
export const blob = capability({
can: 'blob/*',
can: 'space/blob/*',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
Expand All @@ -50,13 +50,13 @@ export const content = Schema.struct({
})

/**
* `blob/add` capability allows agent to store a Blob into a (memory) space
* `space/blob/add` capability allows agent to store a Blob into a (memory) space
* identified by did:key in the `with` field. Agent should compute blob multihash
* and size and provide it under `nb.blob` field, allowing a service to provision
* a write location for the agent to PUT desired Blob into.
*/
export const add = capability({
can: 'blob/add',
can: 'space/blob/add',
/**
* DID of the (memory) space where Blob is intended to
* be stored.
Expand All @@ -76,7 +76,7 @@ export const add = capability({
* space identified by `with` field.
*/
export const remove = capability({
can: 'blob/remove',
can: 'space/blob/remove',
/**
* DID of the (memory) space where Blob is stored.
*/
Expand Down Expand Up @@ -111,7 +111,7 @@ export const remove = capability({
* (memory) space identified by `with` field.
*/
export const list = capability({
can: 'blob/list',
can: 'space/blob/list',
/**
* DID of the (memory) space where Blobs to be listed are stored.
*/
Expand Down
8 changes: 4 additions & 4 deletions packages/capabilities/src/index/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ import { equalWith, SpaceDID, and, equal } from '../utils.js'

/**
* Capability can only be delegated (but not invoked) allowing audience to
* derive any `index/` prefixed capability for the space identified by the DID
* derive any `space/index/` prefixed capability for the space identified by the DID
* in the `with` field.
*/
export const index = capability({
can: 'index/*',
can: 'space/index/*',
/** DID of the space where indexed data is stored. */
with: SpaceDID,
derives: equalWith,
})

/**
* `index/add` capability allows an agent to submit verifiable claims
* `space/index/add` capability allows an agent to submit verifiable claims
* about content-addressed data to be published on the InterPlanetary Network
* Indexer (IPNI), making it publicly queryable.
*/
export const add = capability({
can: 'index/add',
can: 'space/index/add',
/** DID of the space where indexed data is stored. */
with: SpaceDID,
nb: Schema.struct({
Expand Down
2 changes: 1 addition & 1 deletion packages/capabilities/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const equalLink = (claimed, delegated) => {
}

/**
* @template {Types.ParsedCapability<"blob/add"|"blob/remove"|"web3.storage/blob/allocate"|"web3.storage/blob/accept", Types.URI<'did:'>, {blob: { digest: Uint8Array, size: number }}>} T
* @template {Types.ParsedCapability<"space/blob/add"|"space/blob/remove"|"web3.storage/blob/allocate"|"web3.storage/blob/accept", Types.URI<'did:'>, {blob: { digest: Uint8Array, size: number }}>} T
* @param {T} claimed
* @param {T} delegated
* @returns {Types.Result<{}, Types.Failure>}
Expand Down
14 changes: 7 additions & 7 deletions packages/capabilities/test/capabilities/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const index = async () =>
})

describe('index capabilities', function () {
it('index/add can be derived from *', async () => {
it('space/index/add can be derived from *', async () => {
const add = Index.add.invoke({
issuer: alice,
audience: w3,
Expand All @@ -50,13 +50,13 @@ describe('index capabilities', function () {
}

assert.deepEqual(result.ok.audience.did(), w3.did())
assert.equal(result.ok.capability.can, 'index/add')
assert.equal(result.ok.capability.can, 'space/index/add')
assert.deepEqual(result.ok.capability.nb, {
index: await createCarCid('test'),
})
})

it('index/add can be derived from index/*', async () => {
it('space/index/add can be derived from index/*', async () => {
const add = Index.add.invoke({
issuer: alice,
audience: w3,
Expand All @@ -79,13 +79,13 @@ describe('index capabilities', function () {
}

assert.deepEqual(result.ok.audience.did(), w3.did())
assert.equal(result.ok.capability.can, 'index/add')
assert.equal(result.ok.capability.can, 'space/index/add')
assert.deepEqual(result.ok.capability.nb, {
index: await createCarCid('test'),
})
})

it('index/add can be derived from index/* derived from *', async () => {
it('space/index/add can be derived from index/* derived from *', async () => {
const index = await Index.index.delegate({
issuer: alice,
audience: bob,
Expand Down Expand Up @@ -115,13 +115,13 @@ describe('index capabilities', function () {
}

assert.deepEqual(result.ok.audience.did(), w3.did())
assert.equal(result.ok.capability.can, 'index/add')
assert.equal(result.ok.capability.can, 'space/index/add')
assert.deepEqual(result.ok.capability.nb, {
index: await createCarCid('test'),
})
})

it('index/add should fail when escalating index constraint', async () => {
it('space/index/add should fail when escalating index constraint', async () => {
const delegation = await Index.add.delegate({
issuer: alice,
audience: bob,
Expand Down
4 changes: 3 additions & 1 deletion packages/filecoin-api/src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ export class UnexpectedPiece extends Error {
}
}

export const UnsupportedCapabilityErrorName = /** @type {const} */ ('UnsupportedCapability')
export const UnsupportedCapabilityErrorName = /** @type {const} */ (
'UnsupportedCapability'
)
export class UnsupportedCapability extends Server.Failure {
/**
* @param {object} source
Expand Down
5 changes: 3 additions & 2 deletions packages/filecoin-api/test/context/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ export function getMockService() {
return Server.ok({
piece: invCap.nb.piece,
aggregates: [],
deals: []
deals: [],
})
}})
},
}),
},
deal: {
info: Server.provideAdvanced({
Expand Down
12 changes: 6 additions & 6 deletions packages/filecoin-api/test/context/store-implementations.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ export const getStoreImplementations = (
return undefined
}
return new ReadableStream({
start(controller) {
// Push the data into the stream
controller.enqueue(item)
// Close the stream
controller.close()
}
start(controller) {
// Push the data into the stream
controller.enqueue(item)
// Close the stream
controller.close()
},
})
},
}),
Expand Down
5 changes: 1 addition & 4 deletions packages/filecoin-api/test/services/aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,7 @@ export const test = {
pieceQueue: new FailingQueue(),
})
),
'piece/accept must be invoked on service did': async (
assert,
context
) => {
'piece/accept must be invoked on service did': async (assert, context) => {
const { agent, storefront } = await getServiceContext(context.id)
const connection = connect({
id: context.id,
Expand Down
95 changes: 48 additions & 47 deletions packages/filecoin-api/test/services/storefront.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { createServer, connect } from '../../src/storefront/service.js'
import {
QueueOperationErrorName,
StoreOperationErrorName,
UnsupportedCapabilityErrorName
UnsupportedCapabilityErrorName,
} from '../../src/errors.js'
import { randomCargo, randomAggregate } from '../utils.js'
import { createInvocationsAndReceiptsForDealDataProofChain } from '../context/receipts.js'
Expand Down Expand Up @@ -242,30 +242,29 @@ export const test = {
pieceStore: getStoreImplementations(FailingStore).storefront.pieceStore,
})
),
'filecoin/submit must be invoked on service did':
async (assert, context) => {
const { agent } = await getServiceContext(context.id)
const connection = connect({
id: context.id,
channel: createServer(context),
})
'filecoin/submit must be invoked on service did': async (assert, context) => {
const { agent } = await getServiceContext(context.id)
const connection = connect({
id: context.id,
channel: createServer(context),
})

// Generate piece for test
const [cargo] = await randomCargo(1, 128)
const filecoinSubmitInv = Filecoin.submit.invoke({
issuer: agent,
audience: connection.id,
with: agent.did(),
nb: {
piece: cargo.link.link(),
content: cargo.content.link(),
},
})
// Generate piece for test
const [cargo] = await randomCargo(1, 128)
const filecoinSubmitInv = Filecoin.submit.invoke({
issuer: agent,
audience: connection.id,
with: agent.did(),
nb: {
piece: cargo.link.link(),
content: cargo.content.link(),
},
})

const response = await filecoinSubmitInv.execute(connection)
assert.ok(response.out.error)
assert.equal(response.out.error?.name, UnsupportedCapabilityErrorName)
},
const response = await filecoinSubmitInv.execute(connection)
assert.ok(response.out.error)
assert.equal(response.out.error?.name, UnsupportedCapabilityErrorName)
},
'filecoin/submit inserts piece into piece offer queue and returns effect':
async (assert, context) => {
const { storefront } = await getServiceContext(context.id)
Expand Down Expand Up @@ -344,7 +343,9 @@ export const test = {
assert,
context
) => {
const { storefront, aggregator, dealer } = await getServiceContext(context.id)
const { storefront, aggregator, dealer } = await getServiceContext(
context.id
)
const group = context.id.did()
const connection = connect({
id: context.id,
Expand Down Expand Up @@ -452,30 +453,29 @@ export const test = {
BigInt(dealMetadata.dataSource.dealID)
)
},
'filecoin/accept must be invoked on service did':
async (assert, context) => {
const { agent } = await getServiceContext(context.id)
const connection = connect({
id: context.id,
channel: createServer(context),
})
'filecoin/accept must be invoked on service did': async (assert, context) => {
const { agent } = await getServiceContext(context.id)
const connection = connect({
id: context.id,
channel: createServer(context),
})

// Generate piece for test
const [cargo] = await randomCargo(1, 128)
const filecoinSubmitInv = Filecoin.accept.invoke({
issuer: agent,
audience: connection.id,
with: agent.did(),
nb: {
piece: cargo.link.link(),
content: cargo.content.link(),
},
})
// Generate piece for test
const [cargo] = await randomCargo(1, 128)
const filecoinSubmitInv = Filecoin.accept.invoke({
issuer: agent,
audience: connection.id,
with: agent.did(),
nb: {
piece: cargo.link.link(),
content: cargo.content.link(),
},
})

const response = await filecoinSubmitInv.execute(connection)
assert.ok(response.out.error)
assert.equal(response.out.error?.name, UnsupportedCapabilityErrorName)
},
const response = await filecoinSubmitInv.execute(connection)
assert.ok(response.out.error)
assert.equal(response.out.error?.name, UnsupportedCapabilityErrorName)
},
'filecoin/accept fails if fails to read from piece store':
wichMockableContext(
async (assert, context) => {
Expand Down Expand Up @@ -509,7 +509,8 @@ export const test = {
'filecoin/info gets aggregate where piece was included together with deals and inclusion proof':
wichMockableContext(
async (assert, context) => {
const { agent, storefront, aggregator, dealer } = await getServiceContext(context.id)
const { agent, storefront, aggregator, dealer } =
await getServiceContext(context.id)
const group = context.id.did()
const connection = connect({
id: context.id,
Expand Down
12 changes: 4 additions & 8 deletions packages/filecoin-api/test/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import type {
Signer,
Result,
Unit,
UnknownLink
} from '@ucanto/interface'
import type { Signer, Result, Unit, UnknownLink } from '@ucanto/interface'
import * as AggregatorInterface from '../src/aggregator/api.js'
import * as DealerInterface from '../src/dealer/api.js'
import * as StorefrontInterface from '../src/storefront/api.js'
Expand Down Expand Up @@ -61,9 +56,10 @@ export interface StorefrontTestEventsContext
}>
}

export interface TestContentStore<RecKey, Rec> extends StorefrontInterface.ContentStore<RecKey, Rec> {
export interface TestContentStore<RecKey, Rec>
extends StorefrontInterface.ContentStore<RecKey, Rec> {
/**
* Puts a record in the store.
*/
put: (record: Rec) => Promise<Result<Unit, StorePutError>>
}
}
4 changes: 0 additions & 4 deletions packages/upload-api/src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import * as Types from './types.js'
import * as Legacy from '@ucanto/transport/legacy'
import * as CAR from '@ucanto/transport/car'
import { create as createRevocationChecker } from './utils/revocation.js'
import { createService as createBlobService } from './blob.js'
import { createService as createStoreService } from './store.js'
import { createService as createUploadService } from './upload.js'
import { createService as createConsoleService } from './console.js'
import { createService as createAccessService } from './access.js'
import { createService as createConsumerService } from './consumer.js'
import { createService as createCustomerService } from './customer.js'
import { createService as createSpaceService } from './space.js'
import { createService as createIndexService } from './index.js'
import { createService as createProviderService } from './provider.js'
import { createService as createSubscriptionService } from './subscription.js'
import { createService as createAdminService } from './admin.js'
Expand Down Expand Up @@ -177,11 +175,9 @@ export const run = async (agent, invocation) => {
*/
export const createService = (context) => ({
access: createAccessService(context),
blob: createBlobService(context),
console: createConsoleService(context),
consumer: createConsumerService(context),
customer: createCustomerService(context),
index: createIndexService(context),
provider: createProviderService(context),
'rate-limit': createRateLimitService(context),
admin: createAdminService(context),
Expand Down
Loading

0 comments on commit 17e3a31

Please sign in to comment.