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

fix!: update aggregate spec in client and api #824

Merged
merged 2 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion packages/aggregate-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"@ucanto/interface": "^8.0.0",
"@ucanto/server": "^8.0.0",
"@ucanto/transport": "^8.0.0",
"@web3-storage/capabilities": "workspace:^"
"@web3-storage/capabilities": "workspace:^",
"@web3-storage/data-segment": "^1.0.1"
},
"devDependencies": {
"@ipld/car": "^5.1.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/aggregate-api/src/aggregate/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export const provide = (context) =>
* @returns {Promise<API.UcantoInterface.Result<API.AggregateGetSuccess, API.AggregateGetFailure>>}
*/
export const claim = async ({ capability }, { aggregateStore }) => {
const commitmentProof = capability.nb.commitmentProof
const subject = capability.nb.subject

const aggregateArrangedResult = await aggregateStore.get(commitmentProof)
const aggregateArrangedResult = await aggregateStore.get(subject)
if (!aggregateArrangedResult) {
return {
error: new AggregateNotFound(
`aggregate not found for commitment proof: ${commitmentProof}`
`aggregate not found for subject: ${subject}`
),
}
}
Expand Down
43 changes: 11 additions & 32 deletions packages/aggregate-api/src/aggregate/offer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export const claim = async (
) => {
// Get offer block
const offerCid = capability.nb.offer
const commitmentProof = capability.nb.commitmentProof
const offers = getOfferBlock(offerCid, invocation)
const piece = capability.nb.piece
const offers = getOfferBlock(offerCid, invocation.iterateIPLDBlocks())

if (!offers) {
return {
Expand All @@ -52,30 +52,15 @@ export const claim = async (
`offer over size, offered: ${size}, maximum: ${MAX_SIZE}`
),
}
} else if (size !== capability.nb.size) {
} else if (size !== piece.size) {
return {
error: new AggregateOfferInvalidSizeError(
`offer size mismatch, specified: ${capability.nb.size}, actual: ${size}`
`offer size mismatch, specified: ${piece.size}, actual: ${size}`
),
}
}

// Validate URLs in offers src
for (const offer of offers.values()) {
for (const u of offer.src) {
try {
new URL(u)
} catch {
return {
error: new AggregateOfferInvalidUrlError(
`offer has invalid URL: ${u}`
),
}
}
}
}

// TODO: Validate commP
// TODO: Validate commP of commPs

// Create effect for receipt
const fx = await Offer.arrange
Expand All @@ -84,13 +69,13 @@ export const claim = async (
audience: context.id,
with: context.id.did(),
nb: {
commitmentProof,
pieceLink: piece.link,
},
})
.delegate()

// Write offer to store
await offerStore.queue({ commitmentProof, offers })
await offerStore.queue({ piece, offers })

return Server.ok({
status: 'queued',
Expand All @@ -99,13 +84,13 @@ export const claim = async (

/**
* @param {Server.API.Link<unknown, number, number, 0 | 1>} offerCid
* @param {Server.API.Invocation<Server.API.Capability<"aggregate/offer", `did:${string}:${string}` & `did:${string}` & Server.API.Phantom<{ protocol: "did:"; }> & `${string}:${string}` & Server.API.Phantom<{ protocol: `${string}:`; }>, Pick<{ offer: Server.API.Link<unknown, number, number, 0 | 1>; commitmentProof: Server.API.Link<unknown, number, number, 0 | 1>; size: number & Server.API.Phantom<{ typeof: "integer"; }>; }, "offer" | "commitmentProof" | "size"> & Partial<Pick<{ offer: Server.API.Link<unknown, number, number, 0 | 1>; commitmentProof: Server.API.Link<unknown, number, number, 0 | 1>; size: number & Server.API.Phantom<{ typeof: "integer"; }>; }, never>>>>} invocation
* @param {IterableIterator<Server.API.Transport.Block<unknown, number, number, 1>>} blockIterator
*/
function getOfferBlock(offerCid, invocation) {
for (const block of invocation.iterateIPLDBlocks()) {
function getOfferBlock(offerCid, blockIterator) {
for (const block of blockIterator) {
if (block.cid.equals(offerCid)) {
const decoded =
/** @type {import('@web3-storage/aggregate-client/types').Offer[]} */ (
/** @type {import('@web3-storage/aggregate-client/types').Piece[]} */ (
CBOR.decode(block.bytes)
)
return decoded
Expand All @@ -114,12 +99,6 @@ function getOfferBlock(offerCid, invocation) {
}
}

class AggregateOfferInvalidUrlError extends Server.Failure {
get name() {
return /** @type {const} */ ('AggregateOfferInvalidUrl')
}
}

class AggregateOfferInvalidSizeError extends Server.Failure {
get name() {
return /** @type {const} */ ('AggregateOfferInvalidSize')
Expand Down
6 changes: 3 additions & 3 deletions packages/aggregate-api/src/offer/arrange.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export const provide = (context) =>
* @returns {Promise<API.UcantoInterface.Result<API.OfferArrangeSuccess, API.OfferArrangeFailure>>}
*/
export const claim = async ({ capability }, { arrangedOfferStore }) => {
const commitmentProof = capability.nb.commitmentProof
const pieceLink = capability.nb.pieceLink
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not suffix with types? piece: Link is ok? Why is the size not being passed in this instance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size is only needed on the aggregate offer for SP validation. Here is when there was already a resolution and we just want to create the receipt with final result. For searching we do not need the size (and I don't even know if by the state we get from the Oracle we would have access to it easily).

piece is Object with link and size everywhere else. That is the reasoning to name it this way here as we decided in storacha/specs#62

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got to say pieceLink also bothered me, I was not going to say anything but since @alanshaw did how about we rename piece object into something else ? I think few cases we considered pieceInfo ?

Naming is so hard 😭 and it's made harder by the fact that piece CID does not fully identify the piece without the size....


const status = await arrangedOfferStore.get(commitmentProof)
const status = await arrangedOfferStore.get(pieceLink)

if (!status) {
return {
error: new OfferArrangeNotFound(
`arranged offer not found for commitment proof: ${commitmentProof}`
`arranged offer not found for piece: ${pieceLink}`
),
}
}
Expand Down
12 changes: 6 additions & 6 deletions packages/aggregate-api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
} from '@ucanto/interface'
import type { ProviderInput } from '@ucanto/server'

import type { Offer } from '@web3-storage/aggregate-client/types'
import type { Piece } from '@web3-storage/aggregate-client/types'
export * from '@web3-storage/aggregate-client/types'

export * from '@web3-storage/capabilities/types'
Expand All @@ -31,7 +31,7 @@ export interface ServiceContext

export interface ArrangedOfferStore {
get: (
commitmentProof: Link<unknown, number, number, 0 | 1>
pieceLink: Link<unknown, number, number, 0 | 1>
) => Promise<string | undefined>
}

Expand All @@ -40,13 +40,13 @@ export interface OfferStore {
}

export interface OfferToQueue {
commitmentProof: Link<unknown, number, number, 0 | 1>
offers: Offer[]
piece: Piece
offers: Piece[]
}

export interface AggregateStore {
get: (
commitmentProof: Link<unknown, number, number, 0 | 1>
pieceLink: Link<unknown, number, number, 0 | 1>
) => Promise<unknown[] | undefined>
}

Expand Down Expand Up @@ -76,7 +76,7 @@ export interface Assert {

export interface AggregateStoreBackend {
put: (
commitmentProof: Link<unknown, number, number, 0 | 1>,
pieceLink: Link<unknown, number, number, 0 | 1>,
aggregateInfo: unknown
) => Promise<void>
}
Expand Down
Loading