Skip to content

Piece deletion is expensive and non-atomic — consider a bundled replace #467

@frrist

Description

@frrist

Problem

The current piece model forces an uncomfortable trade-off between onboarding cost and deletion cost.

Aggregation is required for any meaningful onboarding

Each piece add costs ~120–300K gas across both contracts: PDPVerifier writes 2 cold SSTOREs in addOnePiece (service_contracts/lib/pdp/src/PDPVerifier.sol:467) plus a sumtree update, and FWSS piecesAdded (service_contracts/src/FilecoinWarmStorageService.sol:841) layers on a nonce SSTORE, ECDSA verify, per-key metadata SSTOREs, and a payment-rate update.

At 100 GB total: ~48M gas as 256 MiB pieces (≈2 txs) vs. ~12B gas as 1 MiB pieces (≈400 txs). Allowing "any data to be a piece" sounds simpler, but is uneconomic for typical workloads. Aggregation isn't an optimization — it's the only way the numbers work.

Aggregation makes deletion painful

Because the piece is the indivisible unit of removal and proving, deleting one user's data out of an aggregated piece means re-aggregating the survivors off-chain and submitting two on-chain messages: schedulePieceDeletions (PDPVerifier.sol:487) for the stale aggregated piece, then addPieces for the replacement.

Each message pays its own base tx gas, ECDSA verify, FWSS nonce SSTORE, and updatePaymentRates external call to the Payments contract — most of which is duplication of what is logically one operation. The two messages are also not atomic: a failure between them leaves the dataset inconsistent and the operator has to recover by hand.

This will get worse as deletion volume grows (compliance-driven deletes, churn-heavy workloads, dataset migrations).

Direction

A bundled replacePieces-style entrypoint that schedules the old piece for removal and adds the new one in a single transaction would address both pains:

  • Removes the orphaned-state failure mode entirely.
  • Saves the duplicated per-tx overhead — most notably the second updatePaymentRates call, which can be computed once against the net leaf delta.
  • Keeps the existing proving-period semantics intact (both halves settle at the next nextProvingPeriod).

The exact shape — listener interface change, signature scheme, batch behavior, fallback for unaware listeners — is open for whoever picks this up.

This issue/analysis was produced using Claude Code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    🐱 Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions