fix(cleanup): anchor cleanupPieces gate to last proving activity#279
Merged
Conversation
The permissionless gate was anchored to cleanup-mode entry, so the abandonment path took two INACTIVITY_WINDOWs (~60 days): a third party could delete an abandoned data set after 30 days but had to wait another 30 to clean up and collect the deposit. Both gates now share _withinActivityWindow, making delete and cleanup permissionless at the same moment. Deprecates the now-unused cleanupModeEpoch in place.
There was a problem hiding this comment.
Pull request overview
This PR fixes the cleanup incentive/abandonment flow by aligning the permissionless gate for cleanupPieces() with deleteDataSet(), both anchored to last proving activity rather than cleanup-mode entry. This ensures an abandoned data set can be deleted and cleaned up in the same sequence by the same caller, allowing the cleanup deposit bounty to be claimed immediately when appropriate.
Changes:
- Introduces
_withinActivityWindow(setId)and reuses it for bothdeleteDataSet()andcleanupPieces()permission gating. - Deprecates the old cleanup-mode anchor storage (
cleanupModeEpoch) in-place (renamed todeprecatedCleanupModeEpoch) and clears any legacy residue during finalization. - Expands cleanup-related test coverage to cover abandoned/active/legacy scenarios and storage-residue clearing.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/CleanupPieces.t.sol | Adds targeted tests verifying the new shared activity-anchored permission gate and legacy/residue behavior. |
| src/PDPVerifierLayout.sol | Renames the slot constant to reflect deprecated cleanup-mode epoch storage (same slot preserved). |
| src/PDPVerifierLayout.json | Renames the storage layout label to deprecatedCleanupModeEpoch to match the deprecation. |
| src/PDPVerifier.sol | Implements _withinActivityWindow and applies it to delete/cleanup gating; deprecates and clears the old gate anchor storage. |
| CHANGELOG.md | Documents the behavioral fix and the deprecation of cleanupModeEpoch. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
wjmelements
approved these changes
Jun 5, 2026
… block Assisted-by: Claude:claude-sonnet-4-6
Contributor
|
Nice. Too bad we already deployed the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The permissionless gate was anchored to cleanup-mode entry, so the abandonment path took two INACTIVITY_WINDOWs (~60 days): a third party could delete an abandoned data set after 30 days but had to wait another 30 to clean up and collect the deposit. Both gates now share _withinActivityWindow, making delete and cleanup permissionless at the same moment. Deprecates the now-unused cleanupModeEpoch in place.
deleteDataSetbecomes permissionless afterINACTIVITY_WINDOW(~30 days) without proving activity, but cleanupPieces restarted that clock from the delete itself. The abandonment path therefore took ~60 days, and the cleanup deposit, meant as the bounty for whoever tears down an abandoned data set, was unclaimable by the deleter for a month and then up for grabs by anyone, breaking the incentive to do the (expensive) permissionless delete at all.Fix: both functions now share one gate,
_withinActivityWindow(), anchored to dataSetLastProvenEpoch (legacy fallback toLEGACY_ACTIVITY_EPOCH). That epoch is frozen once a data set enters cleanup mode (provePossession/nextProvingPeriod/addPiecesall revert on deleted data sets), so a data set abandoned enough to delete is immediately cleanable by the same caller, while an actively-proving SP keeps its ~30-day exclusive cleanup window after a voluntary delete. The call ordering (delete, then cleanup) is unchanged: it's enforced by theCLEANUP_MODE_SENTINEL, which never depended on the removed anchor.cleanupModeEpochis deprecated in place;_finalizeCleanupstill clears v3.4.0 residue.