feat(v2): implement TTL policy for all v2 record types - #119
Merged
Conversation
collinsezedike
force-pushed
the
feat/v2-ttl-policy
branch
2 times, most recently
from
August 28, 2026 00:25
21f39d7 to
c072dfc
Compare
collinsezedike
force-pushed
the
feat/v2-ttl-policy
branch
from
August 28, 2026 09:40
c072dfc to
8d4eb84
Compare
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 #72
Summary
Implements TTL policy for all four of v2's long-lived record types (
AssertionV2,Resolution,Position,Credit), per #72's scope.Every write already re-extended TTL via a flat 30-day bump (
INSTANCE_BUMP_AMOUNT), matching v1's constant. That's a hardcoded margin, not one sized from the deployment's actual policy:anti_snipe_hard_max_secsisn't capped today (that's #114/#116, still in review), and even once bounded at 29 days,anti_snipe_hard_max_secs + reveal_duration_secscan exceed 30 days on its own for a deployment configured with a long anti-snipe window and a long reveal window. A record whose TTL is sized independently of the round it belongs to can expire mid-round.What changed
record_bump(policy)helper computes the TTL bump(threshold, amount)in ledgers from that specific assertion's own pinnedPolicySnapshotV2:anti_snipe_hard_max_secs + reveal_duration_secs + SETTLEMENT_GRACE_SECS(a fixed 7-day settlement/withdrawal grace period), floored atINSTANCE_BUMP_AMOUNTso this never shrinks the existing margin, only ever matches or exceeds it.set_assertion,set_resolution,set_position, andadd_creditall now compute their bump from this instead of the flat constant.bump_ttl(id, address).Position/Creditkeys aren't enumerable on-chain (the design deliberately avoids an unbounded voter vector), so a record nobody happens to touch again before its own next write, a registered voter who never reveals, or unclaimed credit sitting past settlement, previously only got its TTL renewed if that address's own owner calledreveal/settle/withdraw. Anyone who knows the(id, address)key can now renew it directly. A no-op (not an error) for any of the four entries that don't exist for a givenid/address; fails only withAssertionNotFoundifiditself doesn't exist.On the issue's other requirements
RestoreFootprintOp) is transaction-level, not something contract code can trigger internally. Nothing insettle/withdraw/get_*assumes non-restorability, so a restored entry works normally once the client includes it in a transaction's footprint.bump_ttlreduces how often restoration is even needed by making proactive renewal permissionless.Position/Creditkey is already derivable without on-chain enumeration: fixed positions' keys come fromAsserted+Disputed(both carry the address), external positions' fromPositionFunded, and credit's fromSettled/DustCredited(both carry the address). No new event needed for this requirement.Test plan
cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings, andcargo test --workspacepass locally (104 tests intholos-v2, all 100 pre-existing ones unchanged and passing, confirming the floor keeps default-policy behavior identical to before)CONTRACT_V2.mdupdated: the TTL section now describes the sized calculation, andbump_ttlhas its own function reference entryscripts/testnet-smoke.shcovers v1 onlytest_dispute_sizes_resolution_and_position_ttl_from_policy_when_larger_than_instance_bump(confirms a largeanti_snipe_hard_max_secsproduces a TTL bump exceeding the flat floor, with the exact expected ledger count),test_bump_ttl_extends_assertion_resolution_position_and_credit(full flow to all four record types populated, confirmsbump_ttlrestores every one to a full bump after partial decay),test_bump_ttl_on_nonexistent_assertion_fails,test_bump_ttl_is_noop_when_position_and_credit_do_not_exist_for_address