Skip to content

fix(freeze): extend instance TTL on every entrypoint - #1458

Open
Ova-Klik wants to merge 9 commits into
CalloraOrg:mainfrom
Ova-Klik:fix/instance-ttl-freeze-checkpoint-errors
Open

Ova-Klik wants to merge 9 commits into
CalloraOrg:mainfrom
Ova-Klik:fix/instance-ttl-freeze-checkpoint-errors

Conversation

@Ova-Klik

Copy link
Copy Markdown

Summary

Closes #1420

Fixes instance TTL management in the freeze, checkpoint, and errors contracts to prevent contract instances from archiving after prolonged inactivity.

Problem

The three contracts extend persistent-entry TTLs but fail to consistently extend their instance TTLs. This can make contract entrypoints unusable after the instance expires, particularly the freeze circuit breaker, which must remain available during emergencies.

The errors registry also contains an unnecessary checked addition in log_error that causes u32::MAX to fail with Error::Overflow.

Changes

  • Freeze: Add a shared bump_instance helper and extend instance TTL in every entrypoint, including views.
  • Checkpoint: Add instance TTL management without changing existing persistent-entry TTL policies.
  • Errors: Add instance TTL management, remove the unnecessary overflow check, and document the RecentErr lifetime.
  • Regression tests: Re-enable and repair the three ignored errors-registry TTL tests, add a 90-day freeze-idle test, and verify instance TTL refresh across relevant entrypoints.
  • Documentation: Add a TTL policy table to docs/INVARIANTS.md.

Each contract uses LEDGERS_PER_DAY-based thresholds and bump amounts corresponding to 30 and 60 days, subject to the network's maximum entry TTL.

Validation

  • cargo test -p callora-freeze -p callora-checkpoint -p errors
  • cargo fmt --all -- --check
  • cargo test --workspace
  • Relevant release/WASM build checks
  • CI passes

CPU impact

Report the measured CPU delta per affected entrypoint. Instance TTL extension should have negligible overhead when the instance remains above the bump threshold.

Scope

Persistent TTL policies for settlement, refund, recipient, hot, and batch-claim contracts are unchanged. No unrelated behavior changes are intended beyond the u32::MAX error-logging fix.

@drips-wave

drips-wave Bot commented Oct 21, 2026

Copy link
Copy Markdown

@Ova-Klik Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

The CalloraOrg#1418 commit turned the crate doc block into outer doc comments placed
before the inner `#![no_std]` attribute and replaced `#[cfg(test)]` with
`#[config(test)]`. Both changes break the crate: rustc rejects an inner
attribute after an outer doc comment, and `config` is not a known attribute.
Revert the two lines so `cargo fmt --all` and `cargo test --workspace`
can run again.
The docs-coverage test expected the typo `ii28`/`ii128` while
docs/ERROR_CODES.md documents `i128`, so the test failed against the
documented text. Align the expectation with the documentation. No contract
behaviour or TTL policy is changed.
Add the measured before/after CPU and memory cost of the per-entrypoint
instance TTL bumps to the TTL policy section, together with the
methodology used to obtain them.
@Ova-Klik
Ova-Klik force-pushed the fix/instance-ttl-freeze-checkpoint-errors branch from b5a8d1f to 198e0f5 Compare October 21, 2026 15:36
The contract entrypoint is `record_deduction(env, amount, request_id)`
(contracts/settlement/src/lib.rs:106): the registered vault is read from
instance storage and must authorize the call, so there is no vault
argument to pass.

Cover the deduction paths in the e2e min-balance test with the current
client API: positive deduction updates the cumulative received total,
non-positive amounts (including a negative signed `i128`) are rejected
with `AmountNotPositive`, a repeated request ID is rejected with
`DuplicateRequestId`, the deduction is accounting-only (developer
balance, global pool and the per-developer minimum balance are
untouched), and the call is rejected without the registered vault's
authorization.
The merge of main into this branch interleaved two copies of the deduction
section and left an unclosed delimiter, so `cargo fmt --all -- --check`
failed on tests/test_min_balance.rs:329.

Rebuild the file from main's version and align every deduction call with
the current generated client API: `record_deduction(env, amount,
request_id)` takes no vault argument, because the contract resolves the
registered vault from instance storage and requires its authorization.

Also correct the request-id expectation: settlement deduplicates every
request ID uniformly and writes a marker for ID 0, whereas the
"no idempotency" sentinel for ID 0 is a vault-contract convention. The
test now asserts the settlement contract's documented behavior (a repeated
ID is rejected with DuplicateRequestId) and keeps the signed negative
amount rejected with AmountNotPositive.
The tests added upstream neither compiled nor matched the code they
exercise:

- `client.settlement()` and `settlement_client.total_received()` do not
  exist; the vault view is `get_settlement()` and the settlement view is
  `get_total_received()`. The `IntoVal` trait also has to be in scope to
  decode event payloads.
- Outside a wasm build the vault's settlement client is a no-op stub
  (`settlement::Client` in `lib.rs`), so the vault never invokes the
  settlement contract and settlement's accounting stays at zero. The
  expectations that settlement received 123/200/350 therefore could not
  hold in a native build.
- The event scan ran after further top-level invocations, and the test
  host resets the event buffer on every invocation, so the buffer was
  already empty. Events are now captured right after the deduct.
- After a prune, the vault's own marker is gone, so the replay is
  accepted; only in a wasm build would settlement still hold a marker for
  that id and reject the forwarded `record_deduction`.

The vault-side guarantees are still asserted: id 0 is never marked, a
non-zero id is, a pruned id can be reused, and the deduct event is
emitted with the deducted amount and the remaining balance.
@Ova-Klik
Ova-Klik force-pushed the fix/instance-ttl-freeze-checkpoint-errors branch from ca97039 to 361f2f0 Compare October 21, 2026 21:11
@Ova-Klik

Copy link
Copy Markdown
Author

@greatest0fallt1me Kindly review and merge, issue resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add instance TTL management to freeze, checkpoint and the errors registry so emergency controls do not archive

1 participant