Skip to content

stellar-contracts: TTL policy, access-grant index invariants, canonical medical-record hashing, event timestamp validation - #1270

Merged
llinsss merged 5 commits into
DogStark:mainfrom
laddyr141-ui:petchain-1154-1174-fixes
Aug 31, 2026
Merged

stellar-contracts: TTL policy, access-grant index invariants, canonical medical-record hashing, event timestamp validation#1270
llinsss merged 5 commits into
DogStark:mainfrom
laddyr141-ui:petchain-1154-1174-fixes

Conversation

@laddyr141-ui

Copy link
Copy Markdown
Contributor

Title

stellar-contracts: TTL policy, access-grant index invariants, canonical medical-record hashing, event timestamp validation

Body

This PR addresses four narrowly-scoped [stellar-contracts] issues in stellar-contracts/src/lib.rs, each as its own commit.

Add TTL extension policy for persistent storage (#1154) — Persistent-storage entries (access logs, emergency access/audit logs, activity streaks, breeding records and their indexes) were written via persistent().set() but never had their TTL extended, so they could be archived/expire out from under the contract even while still logically active. Adds a bump_persistent_ttl helper driven by new PERSISTENT_TTL_THRESHOLD / PERSISTENT_TTL_EXTEND_TO policy constants (~30/~60 days), called after every persistent write (and on the access-log read path) in the affected modules. Tests assert a freshly written breeding record's TTL is actually extended to the policy target.

Add invariant tests for access-grant indexes (#1158)grant_access / revoke_access / compact_storage maintain AccessGrant, AccessGrantCount, and AccessGrantIndex together. Adds tests proving the index stays unique/reachable and consistent with the count across multiple grants and a re-grant, that a revoked or expired grant can never authorize access via check_access (even before compaction runs), and that compact_storage fully removes stale grant records/index slots while leaving the remaining index contiguous and active grantees still authorized.

Define canonical medical-record hashing (#1169) — Adds get_medical_record_hash (and the underlying canonical_medical_record_preimage encoder) so off-chain clients can reproduce a deterministic, versioned commitment (petchain:medical-record:v1) over a record's clinical fields — pet_id, vet_address, diagnosis, treatment, medications, notes, date — in a fixed field order using XDR encoding, documented on the function. Storage/audit metadata (id, updated_at, attachment_hashes, deleted_at) is intentionally excluded so the commitment is stable across non-clinical mutations. Tests cover determinism, sensitivity to clinical-content changes, and stability across delete_medical_record.

Validate medical event timestamps against ledger time (#1174)add_vaccination previously accepted an arbitrary caller-supplied administered_at / next_due_date / expires_at with no validation. Adds a new InvalidTimestamp error and rejects administered_at more than MAX_EVENT_FUTURE_SKEW (~100 years) past ledger time, plus a next_due_date/expires_at (when set) that precedes administered_at or sits beyond MAX_EVENT_HORIZON (~50 years) past it. The windows are deliberately generous so legitimate historical records and existing synthetic test timestamps are unaffected — only clearly out-of-domain values are rejected. Tests cover the accepted boundary, the first rejected value past it, and the ordering checks.

Notes

Closes #1154
Closes #1158
Closes #1169
Closes #1174

Persistent-storage entries (access/emergency/audit logs, activity
streaks, breeding records and their indexes) were never having their
TTL extended, so they could be archived/expire out from under the
contract even while still logically active. Add a bump_persistent_ttl
helper backed by PERSISTENT_TTL_THRESHOLD/PERSISTENT_TTL_EXTEND_TO
policy constants and call it after every persistent().set() (and on
reads of the access-log record) in the affected modules, plus tests
asserting a freshly written persistent entry's TTL is actually
extended to the policy's target.

Refs DogStark#1154
Grant, revoke, and cleanup (compact_storage) maintain three related
keys per pet: AccessGrant, AccessGrantCount, and AccessGrantIndex.
Add tests proving the index stays unique/reachable and consistent
with the count across multiple grants and a re-grant, that a revoked
or expired grant can never authorize access via check_access even
before compaction runs, and that compact_storage fully removes stale
grant records and index slots while leaving the remaining index
contiguous and active grantees authorized.

Refs DogStark#1158
Add PetChainContract::get_medical_record_hash / the underlying
canonical_medical_record_preimage encoder, giving off-chain clients a
deterministic, versioned commitment ("petchain:medical-record:v1")
over a record's clinical fields (pet_id, vet_address, diagnosis,
treatment, medications, notes, date) using the fixed field order and
XDR encoding documented on the function. Storage/audit metadata
(id, updated_at, attachment_hashes, deleted_at) is intentionally
excluded so the commitment is stable across non-clinical mutations
like a soft-delete. Tests cover determinism, sensitivity to clinical
content changes, and stability across delete_medical_record.

Refs DogStark#1169
add_vaccination previously accepted an arbitrary caller-supplied
administered_at/next_due_date/expires_at with no validation, letting
a nonsensical or maliciously far-future timestamp corrupt reminder
scheduling and medical history ordering. Reject administered_at that
is further in the future than MAX_EVENT_FUTURE_SKEW relative to
ledger time, and reject a next_due_date/expires_at (when set) that
precedes administered_at or sits beyond MAX_EVENT_HORIZON past it,
via the new InvalidTimestamp error. The skew/horizon windows are
deliberately generous (decades) so legitimate historical records and
existing synthetic test timestamps are unaffected; only clearly
corrupt/out-of-domain values are rejected. Tests cover the accepted
boundary, the first rejected value past it, and the ordering checks.

Refs DogStark#1174
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@laddyr141-ui 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

@llinsss
llinsss merged commit f847302 into DogStark:main Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants