Fix #54: Add storage TTL lifecycle management (read-bumps, keeper refresh, migration) - #127
Merged
Muyideen-js merged 3 commits intoAug 20, 2026
Conversation
… permissionless keeper, and a migration path. Claim/resolve/cancel now refresh market/bet/payout keys; anyone can call refresh_market_ttl / refresh_markets / get_market_ttl. Referral counters and leaderboard stats get write-time bumps plus matching keeper entrypoints so idle entries cannot silently vanish. Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Closes #54
Summary
This PR introduces a complete TTL lifecycle for every prediction-market storage entry required to recover user funds.
Markets, bettor indexes, bets, payouts, refund records, and related user liabilities are refreshed as one logical lifecycle rather than independently.
The design includes automatic touch-based refresh, permissionless maintenance, expiry visibility, and an upgrade migration path for existing state.
Storage Lifecycle Invariant
For every market that still has a possible user claim or refund, all storage required to execute that claim/refund must remain alive together:
Market(market_id)Bet(market_id, user)Payout(market_id, user)It must never be possible for the market metadata to remain available while the user's financial entitlement silently expires.
Shared TTL Helper
Introduce an internal lifecycle helper that refreshes all keys touched by a market operation using the same TTL policy.
Every write or financially relevant read calls the helper.
Automatic Refresh Paths
TTL is refreshed on:
create_marketplace_betresolve_marketcancel_marketclaimcancel_refundFor claim/refund operations, the required keys are refreshed before further processing whenever they are still available.
Permissionless Keeper
refresh_market_ttl(market_id)refreshes the complete market lifecycle, not just theMarketkey.Using the bounded bettor index, it refreshes all required per-user entries for that market.
If one transaction cannot safely refresh the entire bounded set, expose paginated maintenance:
with deterministic progress.
Anyone may call it and pay the storage-extension cost.
TTL Visibility
Expose lifecycle information sufficient for operators/indexers to know when maintenance is needed:
A keeper should not have to guess which dependent key is closest to expiry.
Migration
After upgrade, provide a bounded migration/refresh function over all existing known markets:
For each market it also schedules/executes refresh of its associated bettor/bet/payout/refund keys.
Migration progress is persistent and resumable.
Already unavailable state is explicitly detected and reported rather than silently treated as healthy.
Where the platform supports restoration of archived entries, document and provide the required restoration workflow before TTL refresh.
Lifecycle Policy
Document who is responsible for keeping unresolved liabilities alive:
Storage may be allowed to expire only after every financial liability for that market has been settled.
Tests
Cover:
claimrefreshes required state;cancel_refundrefreshes required state;Acceptance Criteria
cancel_refundis covered.Result
User funds no longer depend on independently expiring storage keys with no maintenance policy. Every outstanding market liability has an explicit, observable, and maintainable storage lifecycle until settlement.