Context. Blob removal (#30) retires a root on-chain only when every sub-piece is pending removal: PDPVerifier removes whole pieces, and proving reads sub-piece bytes, so removed blobs' bytes stay while their root is live. Worst case, one live 1KB blob pins a ~256MB aggregate — with no time bound (reclamation waits for the root's last live blob). Under S3 billing the client stops paying at the delete request, so these zombie bytes are proven storage fil.one pays the SP for; the SP's exposure is disk occupancy.
What pdp-sim says (fil.one workload analysis): the delete-SLA ÷ proving-period ratio is the dominant cost lever (1d→2d ≈ 110× SP gas); eager per-delete compaction is the worst regime; the compaction threshold is second-order; rewrites double-prove survivors during the proving lag; fil.one margin is healthiest at an SLA of ~2–5 proving periods.
Proposal: a batched compaction task driven by a configurable delete SLA (target 2–3 proving periods):
- Candidate selection by SLA deadline, not space threshold: roots holding pending-removal sub-pieces whose removal requests are approaching the SLA.
- Batch the candidates' live sub-pieces into fresh aggregates through the existing pipeline (bytes and commp are on hand) and submit via the existing addPieces path — batching amortizes the per-transaction base cost.
- On confirmation, mark migrated sub-pieces superseded per (data_set, piece_id, sub_piece) — the same digest is briefly live in two roots and
blobHasClaims is digest-scoped, so a digest-level mark can't express this.
- The existing sweep condition (every sub-piece pending or superseded) retires the old roots and finalizes byte release.
Non-goals: eager per-delete compaction; space-threshold-driven "defrag" (inert knob per the sim). The old root must remain provable until its removal confirms (invariant #30 already maintains).
Open product input: the delete SLA value itself — it sets the fil.one/SP cost split and is the study's biggest lever.
Origin: PR #30 review discussion — #30 (comment)
Context. Blob removal (#30) retires a root on-chain only when every sub-piece is pending removal: PDPVerifier removes whole pieces, and proving reads sub-piece bytes, so removed blobs' bytes stay while their root is live. Worst case, one live 1KB blob pins a ~256MB aggregate — with no time bound (reclamation waits for the root's last live blob). Under S3 billing the client stops paying at the delete request, so these zombie bytes are proven storage fil.one pays the SP for; the SP's exposure is disk occupancy.
What pdp-sim says (fil.one workload analysis): the delete-SLA ÷ proving-period ratio is the dominant cost lever (1d→2d ≈ 110× SP gas); eager per-delete compaction is the worst regime; the compaction threshold is second-order; rewrites double-prove survivors during the proving lag; fil.one margin is healthiest at an SLA of ~2–5 proving periods.
Proposal: a batched compaction task driven by a configurable delete SLA (target 2–3 proving periods):
blobHasClaimsis digest-scoped, so a digest-level mark can't express this.Non-goals: eager per-delete compaction; space-threshold-driven "defrag" (inert knob per the sim). The old root must remain provable until its removal confirms (invariant #30 already maintains).
Open product input: the delete SLA value itself — it sets the fil.one/SP cost split and is the study's biggest lever.
Origin: PR #30 review discussion — #30 (comment)