Skip to content
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
9 changes: 6 additions & 3 deletions docs/src/content/docs/developer-guides/components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,12 @@ interface WarmStorageServiceAPI {
getApprovedProviderIds(): Promise<number[]>
isProviderIdApproved(providerId: number): Promise<boolean>

// Proving Period
getMaxProvingPeriod(): Promise<number>
getChallengeWindow(): Promise<number>
getPDPConfig(): Promise<{
maxProvingPeriod: number
challengeWindowSize: number
challengesPerProof: number
initChallengeWindowStart: number
}>
}
```

Expand Down
7 changes: 2 additions & 5 deletions packages/synapse-core/src/mocks/jsonrpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,8 @@ export const presets = {
clientNonces: () => {
return [BigInt(0)]
},
getMaxProvingPeriod: () => {
return [BigInt(2880)]
},
challengeWindow: () => {
return [BigInt(60)]
getPDPConfig: () => {
return [BigInt(2880), BigInt(60), BigInt(1), BigInt(0)]
},
},
pdpVerifier: {
Expand Down
25 changes: 7 additions & 18 deletions packages/synapse-core/src/mocks/jsonrpc/warm-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export type getDataSetMetadata = ExtractAbiFunction<typeof Abis.storageView, 'ge
export type getAllPieceMetadata = ExtractAbiFunction<typeof Abis.storageView, 'getAllPieceMetadata'>
export type getPieceMetadata = ExtractAbiFunction<typeof Abis.storageView, 'getPieceMetadata'>
export type clientNonces = ExtractAbiFunction<typeof Abis.storageView, 'clientNonces'>
export type getMaxProvingPeriod = ExtractAbiFunction<typeof Abis.storageView, 'getMaxProvingPeriod'>
export type challengeWindow = ExtractAbiFunction<typeof Abis.storageView, 'challengeWindow'>
export type getPDPConfig = ExtractAbiFunction<typeof Abis.storageView, 'getPDPConfig'>

export interface WarmStorageViewOptions {
isProviderApproved?: (args: AbiToType<isProviderApproved['inputs']>) => AbiToType<isProviderApproved['outputs']>
Expand All @@ -36,8 +35,7 @@ export interface WarmStorageViewOptions {
getAllPieceMetadata?: (args: AbiToType<getAllPieceMetadata['inputs']>) => AbiToType<getAllPieceMetadata['outputs']>
getPieceMetadata?: (args: AbiToType<getPieceMetadata['inputs']>) => AbiToType<getPieceMetadata['outputs']>
clientNonces?: (args: AbiToType<clientNonces['inputs']>) => AbiToType<clientNonces['outputs']>
getMaxProvingPeriod?: (args: AbiToType<getMaxProvingPeriod['inputs']>) => AbiToType<getMaxProvingPeriod['outputs']>
challengeWindow?: (args: AbiToType<challengeWindow['inputs']>) => AbiToType<challengeWindow['outputs']>
getPDPConfig?: (args: AbiToType<getPDPConfig['inputs']>) => AbiToType<getPDPConfig['outputs']>
}

/**
Expand Down Expand Up @@ -293,22 +291,13 @@ export function warmStorageViewCallHandler(data: Hex, options: JSONRPCOptions):
options.warmStorageView.clientNonces(args)
)
}
case 'getMaxProvingPeriod': {
if (!options.warmStorageView?.getMaxProvingPeriod) {
throw new Error('Warm Storage View: getMaxProvingPeriod is not defined')
case 'getPDPConfig': {
if (!options.warmStorageView?.getPDPConfig) {
throw new Error('Warm Storage View: getPDPConfig is not defined')
}
return encodeAbiParameters(
Abis.storageView.find((abi) => abi.type === 'function' && abi.name === 'getMaxProvingPeriod')!.outputs,
options.warmStorageView.getMaxProvingPeriod(args)
)
}
case 'challengeWindow': {
if (!options.warmStorageView?.challengeWindow) {
throw new Error('Warm Storage View: challengeWindow is not defined')
}
return encodeAbiParameters(
Abis.storageView.find((abi) => abi.type === 'function' && abi.name === 'challengeWindow')!.outputs,
options.warmStorageView.challengeWindow(args)
Abis.storageView.find((abi) => abi.type === 'function' && abi.name === 'getPDPConfig')!.outputs,
options.warmStorageView.getPDPConfig(args)
)
}

Expand Down
23 changes: 10 additions & 13 deletions packages/synapse-sdk/src/storage/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1370,17 +1370,14 @@ export class StorageContext {

// If piece exists, get provider info for retrieval URL and proving params in parallel
if (exists) {
const [providerInfo, provingParams] = await Promise.all([
const [providerInfo, pdpConfig] = await Promise.all([
// Get provider info for retrieval URL
this.getProviderInfo().catch(() => null),
// Get proving period configuration (only if we have data set data)
dataSetData != null
? Promise.all([this._warmStorageService.getMaxProvingPeriod(), this._warmStorageService.getChallengeWindow()])
.then(([maxProvingPeriod, challengeWindow]) => ({
maxProvingPeriod,
challengeWindow,
}))
.catch(() => null)
? this._warmStorageService.getPDPConfig().catch((error) => {
console.debug('Failed to get PDP config:', error)
return null
})
: Promise.resolve(null),
])

Expand All @@ -1396,8 +1393,8 @@ export class StorageContext {
)}/piece/${parsedPieceCID.toString()}`
}

// Process proof timing data if we have data set data and proving params
if (dataSetData != null && provingParams != null) {
// Process proof timing data if we have data set data and PDP config
if (dataSetData != null && pdpConfig != null) {
// Check if this PieceCID is in the data set
const pieceData = dataSetData.pieces.find((piece) => piece.pieceCid.toString() === parsedPieceCID.toString())

Expand All @@ -1407,17 +1404,17 @@ export class StorageContext {
// Calculate timing based on nextChallengeEpoch
if (dataSetData.nextChallengeEpoch > 0) {
// nextChallengeEpoch is when the challenge window STARTS, not ends!
// The proving deadline is nextChallengeEpoch + challengeWindow
// The proving deadline is nextChallengeEpoch + challengeWindowSize
const challengeWindowStart = dataSetData.nextChallengeEpoch
const provingDeadline = challengeWindowStart + provingParams.challengeWindow
const provingDeadline = challengeWindowStart + pdpConfig.challengeWindowSize

// Calculate when the next proof is due (end of challenge window)
nextProofDue = epochToDate(provingDeadline, network)

// Calculate last proven date (one proving period before next challenge)
const lastProvenDate = calculateLastProofDate(
dataSetData.nextChallengeEpoch,
provingParams.maxProvingPeriod,
pdpConfig.maxProvingPeriod,
network
)
if (lastProvenDate != null) {
Expand Down
16 changes: 9 additions & 7 deletions packages/synapse-sdk/src/test/warm-storage-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1449,19 +1449,20 @@ describe('WarmStorageService', () => {
})
})

describe('getMaxProvingPeriod() and getChallengeWindow()', () => {
describe('getPDPConfig().maxProvingPeriod and getPDPConfig().challengeWindowSize', () => {
it('should return max proving period from WarmStorage contract', async () => {
server.use(
Mocks.JSONRPC({
...Mocks.presets.basic,
warmStorageView: {
...Mocks.presets.basic.warmStorageView,
getMaxProvingPeriod: () => [BigInt(2880)],
getPDPConfig: () => [BigInt(2880), BigInt(60), BigInt(1), BigInt(0)],
},
})
)
const warmStorageService = await createWarmStorageService()
const result = await warmStorageService.getMaxProvingPeriod()
const pdpConfig = await warmStorageService.getPDPConfig()
const result = pdpConfig.maxProvingPeriod
assert.equal(result, 2880)
})

Expand All @@ -1471,12 +1472,13 @@ describe('WarmStorageService', () => {
...Mocks.presets.basic,
warmStorageView: {
...Mocks.presets.basic.warmStorageView,
challengeWindow: () => [BigInt(60)],
getPDPConfig: () => [BigInt(2880), BigInt(60), BigInt(1), BigInt(0)],
},
})
)
const warmStorageService = await createWarmStorageService()
const result = await warmStorageService.getChallengeWindow()
const pdpConfig = await warmStorageService.getPDPConfig()
const result = pdpConfig.challengeWindowSize
assert.equal(result, 60)
})

Expand All @@ -1486,7 +1488,7 @@ describe('WarmStorageService', () => {
...Mocks.presets.basic,
warmStorageView: {
...Mocks.presets.basic.warmStorageView,
getMaxProvingPeriod: () => {
getPDPConfig: () => {
throw new Error('Contract call failed')
},
},
Expand All @@ -1495,7 +1497,7 @@ describe('WarmStorageService', () => {
const warmStorageService = await createWarmStorageService()

try {
await warmStorageService.getMaxProvingPeriod()
await warmStorageService.getPDPConfig()
assert.fail('Should have thrown error')
} catch (error: any) {
assert.include(error.message, 'Contract call failed')
Expand Down
32 changes: 16 additions & 16 deletions packages/synapse-sdk/src/warm-storage/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1072,26 +1072,26 @@ export class WarmStorageService {
return signerAddress.toLowerCase() === ownerAddress.toLowerCase()
}

// ========== Proving Period Operations ==========

/**
* Get the maximum proving period from the WarmStorage contract
* @returns Maximum proving period in epochs
* Get the PDP config from the WarmStorage contract.
* Returns maxProvingPeriod, challengeWindowSize, challengesPerProof, initChallengeWindowStart
*/
async getMaxProvingPeriod(): Promise<number> {
async getPDPConfig(): Promise<{
maxProvingPeriod: number
challengeWindowSize: number
challengesPerProof: number
initChallengeWindowStart: number
}> {
const viewContract = this._getWarmStorageViewContract()
const maxPeriod = await viewContract.getMaxProvingPeriod()
return Number(maxPeriod)
}
const [maxProvingPeriod, challengeWindowSize, challengesPerProof, initChallengeWindowStart] =
await viewContract.getPDPConfig()

/**
* Get the challenge window size from the WarmStorage contract
* @returns Challenge window size in epochs
*/
async getChallengeWindow(): Promise<number> {
const viewContract = this._getWarmStorageViewContract()
const window = await viewContract.challengeWindow()
return Number(window)
return {
maxProvingPeriod: Number(maxProvingPeriod),
challengeWindowSize: Number(challengeWindowSize),
challengesPerProof: Number(challengesPerProof),
initChallengeWindowStart: Number(initChallengeWindowStart),
}
}
/**
* Increments the fixed locked-up amounts for CDN payment rails.
Expand Down