PetChain is a decentralized pet health record platform built on Stellar Soroban smart contracts.
Large workflows can stay logically correct while silently exceeding Soroban instruction, memory, or storage budgets after a feature addition. To catch this early, the contract test suite measures representative worst-case calls and compares them against documented budget snapshots.
| Workflow | Representative worst-case call | Budgeted resources |
|---|---|---|
| Registration | Register a pet with the maximum allowed metadata fields | instructions, memory, storage |
| Record | Append a health record to a pet at the maximum record count | instructions, memory, storage |
| Consent | Grant consent to the maximum number of authorized parties | instructions, memory, storage |
| Claim | Submit and settle a claim with the largest allowed payload | instructions, memory, storage |
| Pagination | Page through the largest supported result set | instructions, memory |
Each workflow has a committed budget snapshot under contracts/test/budgets/. A snapshot
records the measured instructions, memory, and storage values for that workflow.
CI runs the budget tests on every pull request. When a workflow exceeds its snapshot, the job fails and reports the specific resource that regressed, for example:
[budget] record: instructions regressed (measured 1_240_000 > budget 1_100_000)
The failure names the workflow and the resource (instructions, memory, or storage)
so the regression can be attributed without re-running the suite locally.
Budgets are intentional baselines, not auto-generated values. To update a snapshot after a reviewed change:
- Run the budget tests with the baseline-update flag enabled.
- Review the diff in
contracts/test/budgets/to confirm the increase is expected. - Commit the updated snapshot together with the change that caused it.
Snapshots must only be raised deliberately; an unexplained increase should be treated as a regression and investigated before merging.
Budget tests use bounded, realistic fixtures: the largest inputs the contracts are expected to accept (maximum metadata fields, record counts, consent parties, claim payloads, and page sizes). Fixtures are capped so the tests stay deterministic and fast while still exercising the worst case for each workflow.
Public contract errors are documented in a deterministic registry so clients can
map a numeric discriminant to its meaning and recovery semantics without parsing
error text. The registry is generated from the contract source (the #[contracterror]
enums) rather than hand-maintained, so it stays in sync with the contracts.
Each entry records:
- code — the stable numeric discriminant returned on-chain.
- meaning — a human-readable description of the failure.
- retryability — whether a client may safely retry, and under what conditions.
See Error Codes for the full registry and recovery guidance. Discriminants are treated as a stable public interface: existing codes must not change silently, duplicate codes fail CI, and any intentional change requires updating the generated snapshot and the accompanying intentional-change test.
Soroban batch operations in this repository follow a single, documented atomicity model: all-or-nothing. A batch either applies every item or applies none of them. There is no partial-success mode.
- Atomicity model. Each batch is executed as one atomic unit. If any item fails validation or execution, the entire batch is rolled back and no state change from that batch is committed. Ownership, consent, and custody records therefore never expose a partially applied batch.
- Rollback / error behavior. On the first failing item the batch aborts and returns an error identifying the failing item index and reason. Because the whole batch is rolled back, no partial ownership or consent state is observable after a failed batch.
- Per-item results. Per-item results are only exposed when they are safe: on full success (each item's committed result) or as a non-mutating preview that performs no writes. Failed batches do not return per-item success results, since none of the items were committed.
- Item limits. Batch size is bounded by a documented maximum. Batches that exceed the limit are rejected before any state is touched, so oversized batches cannot partially apply.
All Stellar paginated read endpoints (pet, record, vet, consent, custody, and activity reads) share a single bounded page-size policy. The policy is centralized in the contracts crate so every endpoint validates page sizes the same way and returns identical cursor semantics.
| Parameter | Value |
|---|---|
| Minimum page size | 1 |
| Default page size | 20 |
| Maximum page size | 100 |
Rules:
- A page size of
0(or any value below the minimum) is rejected with a deterministic error. - A page size above the maximum is rejected with a deterministic error.
- Omitting the page size uses the documented default of
20. - Every paginated endpoint returns the same cursor semantics: the cursor is an opaque token identifying the next page, and an empty/absent cursor starts at the first page.
- Existing callers that pass a page size within
[1, 100]remain compatible.
MIT
- #1305: [Contracts] Add Stellar storage-key namespace collision tests
- #1307: [Contracts] Add cursor invalidation tests after deletion and state transitions
- #1311: [Contracts] Add emergency-contact priority and duplicate invariant tests
- #1312: [Contracts] Add insurance claim evidence lifecycle and expiry tests
- #1313: [Contracts] Add Soroban persistent-storage TTL extension failure handling
- #1188: [pet-transfer-adoption] Prevent adoption of nonexistent or inactive pets
- #1197: [stellar-contracts] Add emergency-override least-privilege scopes
- #1200: [stellar-contracts] Minimize public emergency-profile data
- #1212: [stellar-contracts] Add governance timelock and cancellation policy
- #1213: [stellar-contracts] Secure contract-upgrade authorization and hash binding
- #1223: [backend-2fa] Version encrypted TOTP secret envelopes
- #1224: [backend-2fa] Add online key rotation for encrypted TOTP secrets
- #1227: [backend-2fa] Enforce TOTP replay protection atomically
- #1261: [backend-2fa] Add webhook signature key versioning
- #1304: [Contracts] Add Celo invariant tests for registry pause and recovery behavior
- #1320: [Contracts] Add Celo event indexing compatibility fixtures
- #1331: [Contracts] Add Soroban event privacy regression tests
- #1332: [Contracts] Add Soroban upgrade proposal expiry semantics
- #1340: [Contracts] Add Soroban insurance reserve accounting audit view