FilOzone / FilOzone/synapse-sdk

getPdpDataSets throws when any client data set is on a provider with an inactive PDP product

Open
#966 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.