DataKey::Delegation and DataKey::Nonce entries were stored in instance
storage, which has a single shared TTL for the entire contract instance.
Neither key type had its TTL extended individually. If a Nonce entry expired
and was archived, it would restore to 0, breaking the monotonic nonce
guarantee and enabling replay attacks against long-lived management delegations.
nonce.rs
- Added TTL constants:
LEDGER_BUMP_BUFFER = 17_280(~1 day),MIN_NONCE_TTL = 518_400(~30 days),MAX_TTL = 3_110_400(~6 months). - Added
bump_delegation_ttl(env, key, expires_at)— bumps aDelegationkey's TTL to(expires_at − now) / 5s + LEDGER_BUMP_BUFFER, capped atMAX_TTL. - Added
bump_nonce_ttl(env, key, expires_at)— bumps aNoncekey's TTL to at leastMIN_NONCE_TTL, extended further if a delegation'sexpires_atexceeds that floor. - Both helpers guard with
has()before callingextend_ttlto avoidMissingValueerrors on first write. - Migrated all
Noncereads/writes frominstance()topersistent()storage.
lib.rs
- Migrated all
Delegationreads/writes frominstance()topersistent()storage. store_delegation: callsbump_delegation_ttlafter write; callsbump_nonce_ttlto ensure the nonce entry's TTL covers the delegation's lifetime.mark_delegation_revoked: callsbump_delegation_ttlafter write.get_delegation,is_valid_delegate,get_attestation_status: callbump_delegation_ttlon every read.
test_delegation_ttl.rs (new file, 8 tests)
- TTL set on write (
delegate) - TTL refreshed on
get_delegation - TTL refreshed on
is_valid_delegate - Nonce TTL set on
consume_nonce - Nonce TTL covers delegation lifetime
- Nonce TTL refreshed on
get_nonce - TTL bumped on
revoke_delegation - TTL capped at
MAX_TTLfor far-future expiries
After this change, a Nonce entry for any owner who has ever issued a
delegation will remain in persistent storage for at least MIN_NONCE_TTL
ledgers (~30 days) beyond the last interaction, and for at least as long as
the longest active delegation. Archival of a nonce entry while a delegation
is still valid is no longer possible under normal operation.
cargo test -p credence_delegation
All 55 tests pass (27 pre-existing + 8 new TTL tests + existing domain/pausable suites).