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

Extract PieceCID from ContextID #118

Open
bajtos opened this issue Feb 13, 2025 · 1 comment
Open

Extract PieceCID from ContextID #118

bajtos opened this issue Feb 13, 2025 · 1 comment

Comments

@bajtos
Copy link
Member

bajtos commented Feb 13, 2025

To allow Spark to link deals to content advertised to IPNI, SP software like Curio creates ContextID from Piece info. This is provides an alternate way for extracting PieceCID from IPNI advertisements.

We need to enhance piece-indexer to support both options: PieceCID extracted from ContextID, PieceCID extracted from Graphsync metadata.

Spec:
https://github.com/CheckerNetwork/FIPs/blob/frc-retrieval-checking-requirements/FRCs/frc-retrieval-checking-requirements.md#construct-ipni-contextid-from-piececid-piecesize

Optimisation:
ContextID values following the spec above start with the prefix ghsA. If the ContextID value does not start with this prefix, we can skip it (there is no need to try to do base64 and CBOR decoding).

See #117 for an example index provider that uses this new format.

Here is the place where we are extracting PieceCID from Graphsync metadata, we can add the new ContextID-based PieceCID extraction there:

const meta = parseMetadata(advertisement.Metadata['/'].bytes)
const pieceCid = meta.deal?.PieceCID.toString()
if (!pieceCid) {
debug('advertisement %s has no PieceCID in metadata: %j', advertisementCid, meta.deal)
return {
error: /** @type {const} */('MISSING_PIECE_CID'),
previousAdvertisementCid
}
}

@bajtos
Copy link
Member Author

bajtos commented Feb 21, 2025

Example ContextID value in the new format:

ghsAAAAIAAAAANgqWCgAAYHiA5IgIFeksuf2VqNvrrRUxrvA+itvJhrDRju06ThagW6ULKw2

Example Node.js code showing how to parse it:

import { decode as decodeDagCbor } from '@ipld/dag-cbor'

const ContextID = 'ghsAAAAIAAAAANgqWCgAAYHiA5IgIFeksuf2VqNvrrRUxrvA+itvJhrDRju06ThagW6ULKw2'

const bytes = Buffer.from(ContextID, 'base64')
const [pieceSize, pieceCID] = decodeDagCbor(bytes)
console.log('PieceCID:', pieceCID.toString())
// CID(baga6ea4seaqfpjfs473fni3pv22fjrv3yd5cw3zgdlbumo5u5e4fvalosqwkynq)
console.log('PieceSize:', pieceSize)
// 34359738368

Note: we cannot assume that the decoded value will always be a pair of [pieceSize, pieceCID]. We should check that:

  • decodeDagCbor(bytes) returned an array (not an object)
  • the array has exactly two items
  • typeof pieceSize === 'number'
  • the pieceCID item is a CID link (encoded using custom CBOR tag 42) - this can be validated on the JavaScript side as follows:
    typeof pieceCID === 'object' && pieceCID?.constructor?.name === 'CID'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 📥 next
Development

No branches or pull requests

1 participant