Skip to content

[19] Add storage TTL handling analysis and bump-on-touch for all persistent reads #19

Description

@merlik787-droi

Problem Statement

Soroban storage entries have a TTL measured in ledgers. The DataKey::Progress(Address, u32) and DataKey::UserBadges(Address) entries are read repeatedly throughout the lifecycle of the protocol. There is no env.storage().persistent().bump_* call anywhere in the codebase — meaning storage will eventually expire and silently disappear, causing learner badges/progress to vanish.

Why It Matters

  • Storage TTL is invisible to most developers because expiration is ledger-counted, not time-counted.
  • A learner completing a course and receiving their badge could find their badge gone weeks later if no one interacts with their storage entry.
  • Already-emitted events are immutable, but the storage state behind them can be lost.

Technical Context

  • Soroban default MAX_LIVE_UNTIL is approximately 30 days; BUMP_THRESHOLD and other constants exist in the host.
  • Conservation: any function that reads a key should bump its TTL.
  • Conservation: any function that writes should also extend TTL.

Expected Outcome

Acceptance Criteria

  • New audit test: simulate 100,000 ledgers passing with no interactions and assert all badges/progress/courses still readable.
  • TTL bumps confirmed via a CI test instrumented for env.storage().persistent() access patterns.

Implementation Notes

  • Determine an optimal "minimum bump window" (e.g., 1 million ledgers ≈ 1 week).
  • Be mindful of TTL-bump costs — Soroban charges fees per bump.

Files / Modules Affected

All six contracts.

Dependencies

Issue #7 (common crate) precedes.

Difficulty

Medium-Hard.

Estimated Effort

2–3 days.

Suggested Labels

reliability, performance, P1, storage


Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions