FilOzone / FilOzone/synapse-sdk
getPdpDataSets throws when any client data set is on a provider with an inactive PDP product
- Dominant language
- TypeScript
- Stars
- 25
- Forks
- 32
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 22
Description
`getPdpDataSets` (and therefore `synapse.storage.download` in read-only mode) throws as soon as any of the client's data sets is on a provider whose PDP product is inactive. One dead provider anywhere in an account's history makes every piece unretrievable through the SDK, including pieces held by healthy providers.
**Observed** (Calibration, `@filoz/synapse-sdk` 2.0.0 / `@filoz/synapse-core` 0.9.0, 2026-09-15)
Client `0x44f08D1beFe61255b3C3A349C392C560FA333759` has 13 data sets. Five are on provider 6 (`beck-calib`), which now reports `providerInfo.isActive=false`, `product.isActive=false`, `capabilityKeys=[]`. The demo data is on provider 4 (`infrafolio-calib`), active and proving.
```
const sets = await getPdpDataSets(readClient, { address: client })
// SynapseError: Validation failed.
// Invalid hex value -> at serviceURL
// Invalid hex value -> at minPieceSizeInBytes
// ... (every PDPOffering field)
```
and so
```
await synapse.storage.download({ pieceCid })
// StorageManager download failed: All provider retrieval attempts failed and no additional retriever method was configured
```
while `curl -I https://caliberation-pdp.infrafolio.com/piece/` returns 200 and `context.pieceStatus()` returns that URL.
**Cause**
`packages/synapse-core/src/warm-storage/get-pdp-data-sets.ts` line 152 (`main`): `providers.set(providerId, parsePDPProvider(result))` runs for every provider id in the batch with no active check. `parsePDPProvider` calls `decodePDPOffering`, whose zod schema requires the seven mandatory capability keys, so an empty capability list fails validation and the exception aborts the whole listing. The single-provider path `getPDPProvider` already guards this with `hasActivePDPProduct(data)` and returns `null`; the batch path skipped the guard.
**Suggested fix**
In `enrichDataSetBatch`, when `!hasActivePDPProduct(result)`, store `null` (or a provider record with `pdp: undefined`) instead of parsing, and let `chainResolver` skip data sets whose provider is null. Data sets on a deregistered provider are still worth returning to callers; they just have no retrievable offering.
**Workaround** we shipped: on `download` failure, call `pieceStatus` on the piece's own data set context and fetch `retrievalUrl` directly, validating the piece CID of what comes back. https://github.com/SgtPooki/Avalanche-IPFS-Filecoin-RWA-reference-Architecture/commit/5cbe673
Contributor guide
Research direction
Start in packages/synapse-core/src/warm-storage/get-pdp-data-sets.ts at line 152 and compare the batch path with getPDPProvider, which already checks hasActivePDPProduct(data). Update the batch handling so inactive providers do not abort listing, then verify getPdpDataSets still returns data sets on healthy providers and that synapse.storage.download can retrieve their pieces.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100