Skip to content

Commit e9ee0ff

Browse files
rvaggSgtPooki
authored andcommitted
feat!: use activePieceCount for accurate piece tracking (#517)
BREAKING: EnhancedDataSetInfo.nextPieceId removed, s/currentPieceCount/activePieceCount This exposes getActivePieceCount from PDPVerifier, replaces the inaccurate nextPieceId-based counting with actual active piece count, and removes nextPieceId from the data set details struct to avoid extra eth_call for a low- value piece of information.
1 parent 6987925 commit e9ee0ff

File tree

12 files changed

+54
-27
lines changed

12 files changed

+54
-27
lines changed

docs/src/content/docs/developer-guides/storage/storage-operations.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ for (const ds of dataSets) {
115115
console.log(`Dataset ${ds.pdpVerifierDataSetId}:`, {
116116
live: ds.isLive,
117117
cdn: ds.withCDN,
118-
pieces: ds.currentPieceCount,
118+
pieces: ds.activePieceCount,
119119
metadata: ds.metadata
120120
});
121121
}

packages/synapse-core/src/mocks/jsonrpc/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ export const presets = {
475475
dataSetLive: () => [true],
476476
getDataSetListener: () => [ADDRESSES.calibration.warmStorage],
477477
getNextPieceId: () => [2n],
478+
getActivePieceCount: () => [2n],
478479
getActivePieces: () => [[], [], false],
479480
getDataSetStorageProvider: () => [ADDRESSES.serviceProvider1, ADDRESSES.zero],
480481
getDataSetLeafCount: () => [0n],

packages/synapse-core/src/mocks/jsonrpc/pdp.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as Abis from '../../abis/index.ts'
66
import type { AbiToType, JSONRPCOptions } from './types.ts'
77

88
export type getNextPieceId = ExtractAbiFunction<typeof Abis.pdp, 'getNextPieceId'>
9+
export type getActivePieceCount = ExtractAbiFunction<typeof Abis.pdp, 'getActivePieceCount'>
910
export type dataSetLive = ExtractAbiFunction<typeof Abis.pdp, 'dataSetLive'>
1011
export type getDataSetListener = ExtractAbiFunction<typeof Abis.pdp, 'getDataSetListener'>
1112
export type getActivePieces = ExtractAbiFunction<typeof Abis.pdp, 'getActivePieces'>
@@ -17,6 +18,7 @@ export interface PDPVerifierOptions {
1718
dataSetLive?: (args: AbiToType<dataSetLive['inputs']>) => AbiToType<dataSetLive['outputs']>
1819
getDataSetListener?: (args: AbiToType<getDataSetListener['inputs']>) => AbiToType<getDataSetListener['outputs']>
1920
getNextPieceId?: (args: AbiToType<getNextPieceId['inputs']>) => AbiToType<getNextPieceId['outputs']>
21+
getActivePieceCount?: (args: AbiToType<getActivePieceCount['inputs']>) => AbiToType<getActivePieceCount['outputs']>
2022
getActivePieces?: (args: AbiToType<getActivePieces['inputs']>) => AbiToType<getActivePieces['outputs']>
2123
getDataSetStorageProvider?: (
2224
args: AbiToType<getDataSetStorageProvider['inputs']>
@@ -65,6 +67,14 @@ export function pdpVerifierCallHandler(data: Hex, options: JSONRPCOptions): Hex
6567
Abis.pdp.find((abi) => abi.type === 'function' && abi.name === 'getNextPieceId')!.outputs,
6668
options.pdpVerifier.getNextPieceId(args)
6769
)
70+
case 'getActivePieceCount':
71+
if (!options.pdpVerifier?.getActivePieceCount) {
72+
throw new Error('PDP Verifier: getActivePieceCount is not defined')
73+
}
74+
return encodeAbiParameters(
75+
Abis.pdp.find((abi) => abi.type === 'function' && abi.name === 'getActivePieceCount')!.outputs,
76+
options.pdpVerifier.getActivePieceCount(args)
77+
)
6878
case 'getActivePieces': {
6979
if (!options.pdpVerifier?.getActivePieces) {
7080
throw new Error('PDP Verifier: getActivePieces is not defined')

packages/synapse-sdk/src/pdp/verifier.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,23 @@ export class PDPVerifier {
4646
/**
4747
* Get the next piece ID for a data set
4848
* @param dataSetId - The PDPVerifier data set ID
49-
* @returns The next piece ID (which equals the current piece count)
49+
* @returns The next piece ID to assign (total pieces ever added; does not decrease when pieces are removed)
5050
*/
5151
async getNextPieceId(dataSetId: number): Promise<number> {
5252
const nextPieceId = await this._contract.getNextPieceId(dataSetId)
5353
return Number(nextPieceId)
5454
}
5555

56+
/**
57+
* Get the count of active pieces (non-zero leaf count) for a data set
58+
* @param dataSetId - The PDPVerifier data set ID
59+
* @returns The number of active pieces in the data set
60+
*/
61+
async getActivePieceCount(dataSetId: number): Promise<number> {
62+
const count = await this._contract.getActivePieceCount(dataSetId)
63+
return Number(count)
64+
}
65+
5666
/**
5767
* Get the data set listener (record keeper)
5868
* @param dataSetId - The PDPVerifier data set ID

packages/synapse-sdk/src/retriever/chain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export class ChainRetriever implements PieceRetriever {
4444
const dataSets = await this.warmStorageService.getClientDataSetsWithDetails(client)
4545

4646
// Filter for live data sets with pieces
47-
const validDataSets = dataSets.filter((ds) => ds.isLive && ds.currentPieceCount > 0)
47+
const validDataSets = dataSets.filter((ds) => ds.isLive && ds.activePieceCount > 0)
4848

4949
if (validDataSets.length === 0) {
5050
throw createError('ChainRetriever', 'findProviders', `No active data sets with data found for client ${client}`)

packages/synapse-sdk/src/storage/context.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ export class StorageContext {
539539
type EvaluatedDataSet = {
540540
dataSetId: number
541541
dataSetMetadata: Record<string, string>
542-
currentPieceCount: number
542+
activePieceCount: number
543543
}
544544

545545
// Sort ascending by ID (oldest first) for deterministic selection
@@ -558,9 +558,9 @@ export class StorageContext {
558558
sortedDataSets.slice(i, i + BATCH_SIZE).map(async (dataSet) => {
559559
const dataSetId = Number(dataSet.dataSetId)
560560
try {
561-
const [dataSetMetadata, currentPieceCount] = await Promise.all([
561+
const [dataSetMetadata, activePieceCount] = await Promise.all([
562562
warmStorageService.getDataSetMetadata(dataSetId),
563-
warmStorageService.getNextPieceId(dataSetId),
563+
warmStorageService.getActivePieceCount(dataSetId),
564564
warmStorageService.validateDataSet(dataSetId),
565565
])
566566

@@ -571,7 +571,7 @@ export class StorageContext {
571571
return {
572572
dataSetId,
573573
dataSetMetadata,
574-
currentPieceCount,
574+
activePieceCount,
575575
}
576576
} catch (error) {
577577
console.warn(
@@ -587,7 +587,7 @@ export class StorageContext {
587587
if (result == null) continue
588588

589589
// select the first dataset with pieces and break out of the inner loop
590-
if (result.currentPieceCount > 0) {
590+
if (result.activePieceCount > 0) {
591591
selectedDataSet = result
592592
break
593593
}
@@ -599,7 +599,7 @@ export class StorageContext {
599599
}
600600

601601
// early exit if we found a dataset with pieces; break out of the outer loop
602-
if (selectedDataSet != null && selectedDataSet.currentPieceCount > 0) {
602+
if (selectedDataSet != null && selectedDataSet.activePieceCount > 0) {
603603
break
604604
}
605605
}
@@ -689,8 +689,8 @@ export class StorageContext {
689689
if (managedDataSets.length > 0 && !forceCreateDataSet) {
690690
// Prefer data sets with pieces, sort by ID (older first)
691691
const sorted = managedDataSets.sort((a, b) => {
692-
if (a.currentPieceCount > 0 && b.currentPieceCount === 0) return -1
693-
if (b.currentPieceCount > 0 && a.currentPieceCount === 0) return 1
692+
if (a.activePieceCount > 0 && b.activePieceCount === 0) return -1
693+
if (b.activePieceCount > 0 && a.activePieceCount === 0) return 1
694694
return a.pdpVerifierDataSetId - b.pdpVerifierDataSetId
695695
})
696696

packages/synapse-sdk/src/test/retriever-chain.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ describe('ChainRetriever', () => {
572572
return [dataSetId !== 1n] // Data set 1 not live
573573
},
574574
getDataSetListener: () => [Mocks.ADDRESSES.calibration.warmStorage],
575-
getNextPieceId: (args) => {
575+
getActivePieceCount: (args) => {
576576
const [dataSetId] = args
577577
return [dataSetId === 2n ? 0n : 1n] // Data set 2 has no pieces
578578
},

packages/synapse-sdk/src/test/storage.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ describe('StorageService', () => {
429429
...Mocks.presets.basic,
430430
pdpVerifier: {
431431
...Mocks.presets.basic.pdpVerifier,
432-
getNextPieceId: (args) => {
432+
getActivePieceCount: (args) => {
433433
const [dataSetId] = args
434434
if (dataSetId === 2n) {
435435
return [2n]

packages/synapse-sdk/src/test/warm-storage-service.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,7 @@ describe('WarmStorageService', () => {
255255
assert.lengthOf(detailedDataSets, 1)
256256
assert.equal(detailedDataSets[0].pdpRailId, 48)
257257
assert.equal(detailedDataSets[0].pdpVerifierDataSetId, 242)
258-
assert.equal(detailedDataSets[0].nextPieceId, 2)
259-
assert.equal(detailedDataSets[0].currentPieceCount, 2)
258+
assert.equal(detailedDataSets[0].activePieceCount, 2)
260259
assert.isTrue(detailedDataSets[0].isLive)
261260
assert.isTrue(detailedDataSets[0].isManaged)
262261
})

packages/synapse-sdk/src/types.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,8 @@ export interface DataSetInfo {
229229
export interface EnhancedDataSetInfo extends DataSetInfo {
230230
/** PDPVerifier global data set ID */
231231
pdpVerifierDataSetId: number
232-
/** Next piece ID to use when adding pieces */
233-
nextPieceId: number
234-
/** Current number of pieces in the data set */
235-
currentPieceCount: number
232+
/** Number of active pieces in the data set (excludes removed pieces) */
233+
activePieceCount: number
236234
/** Whether the data set is live on-chain */
237235
isLive: boolean
238236
/** Whether this data set is managed by the current Warm Storage contract */

0 commit comments

Comments
 (0)