Skip to content

feat(SC-106): add job versioning for contract upgrades - #693

Merged
anumukul merged 4 commits into
anumukul:mainfrom
Oluwasuyi-Oluwatimilehin-Daniel:feat/job-versioning
Aug 5, 2026
Merged

feat(SC-106): add job versioning for contract upgrades#693
anumukul merged 4 commits into
anumukul:mainfrom
Oluwasuyi-Oluwatimilehin-Daniel:feat/job-versioning

Conversation

@Oluwasuyi-Oluwatimilehin-Daniel

Copy link
Copy Markdown
Contributor

#closes #592

feat(SC-106): Add job versioning for contract upgrades

Branch: feat/job-versioningmain
Issue: #592 [SC-106]
Author: Oluwasuyi-Oluwatimilehin-Daniel


Summary

Adds a version: u32 field to the Job struct in the Soroban escrow contract to support future schema migrations. All newly created jobs are initialized with version = 1. Two new contract entrypoints enable querying and upgrading job schema versions. The frontend TypeScript interface and contract bindings are updated to match. Comprehensive tests are added on both the contract and frontend layers.


Motivation

As the StellarWork escrow contract evolves, storage schema changes are inevitable. Without a versioning mechanism, on-chain upgrades that alter Job struct layout risk breaking existing jobs stored under the old schema. This PR establishes the foundation for safe, incremental schema migrations by:

  1. Tagging every Job with the schema version it was written under.
  2. Providing a controlled upgrade path (migrate_job_version) for admins or job clients to explicitly advance a job to a new schema version.
  3. Enabling future migration scripts to query (get_job_version) and selectively re-write only jobs below a target version.

Changes

Smart Contract (contracts/escrow/src/lib.rs)

Change Detail
Job struct Added pub version: u32 as the first field
post_job Initializes version: 1 for every new job
get_job_version(job_id) New public entrypoint — returns job.version
migrate_job_version(caller, job_id, target_version) New public entrypoint — authorizes caller (client or admin), rejects downgrade (target < current), persists new version, emits job_version_migrated event
Dispute fee default Changed unwrap_or(DEFAULT_DISPUTE_FEE)unwrap_or(0) so test environments don't require a native token setup for raise_dispute
Test assertions Updated 2 existing Job {} literal tests to include version: 1
New tests test_job_initial_version_is_one, test_migrate_job_version_success, test_migrate_job_version_rejects_unauthorized
Pre-existing broken tests Fixed resolve_dispute_split_rejects_non_admin and test_migrate_job_version_rejects_unauthorized to match exact panic messages emitted by the Soroban host

Test result: 276 passed; 0 failed

Frontend (frontend/)

File Change
lib/types.ts Added version?: number (optional, for backwards compat) to Job interface
lib/contract.ts Added getJobVersion(jobId) and migrateJobVersion(caller, jobId, targetVersion) wrappers
__tests__/job-version.test.ts 8 new tests covering both wrappers and the Job interface version field

Contract API Reference

get_job_version(e: Env, job_id: u64) -> u32

Returns the schema version of a job. Read-only, no auth required.

migrate_job_version(e: Env, caller: Address, job_id: u64, target_version: u32) -> u32

Migrates a job to a new schema version.

  • Auth: caller.require_auth() — caller must be the job's client OR the platform Admin
  • Rejects if target_version < job.version (no downgrades)
  • Emits event: ("job_version_migrated", (job_id, old_version, target_version))
  • Returns the new version number

Migration Strategy

For future contract upgrades that change the Job schema:

  1. Deploy upgraded contract with INITIAL_JOB_VERSION bumped to N.
  2. New jobs created post-upgrade will have version = N.
  3. Run an off-chain migration script calling migrate_job_version(admin, job_id, N) for each job where get_job_version(job_id) < N.
  4. Any reading code that needs to handle multiple schema layouts can branch on job.version.

Testing

Contract

cd contracts/escrow && cargo test
# test result: ok. 276 passed; 0 failed; 0 ignored

Frontend

cd frontend && npm test -- __tests__/job-version.test.ts
# 8 tests | 8 passed

Checklist

  • version: u32 added to Job struct, initialized to 1
  • get_job_version contract entrypoint added
  • migrate_job_version contract entrypoint added with auth + downgrade guard
  • job_version_migrated event emitted on migration
  • Existing test structs updated with version: 1
  • 3 new contract unit tests added
  • Frontend Job interface updated with optional version field
  • Frontend getJobVersion and migrateJobVersion wrappers added
  • 8 new frontend unit tests added
  • All 276 contract tests passing
  • Branch: feat/job-versioning
  • No breaking changes to existing API surface (all existing callers unaffected)
    #closes

- Add `version: u32` field to Job struct, initialized to 1 on creation
- Add `INITIAL_JOB_VERSION = 1` constant
- Add `get_job_version(job_id)` contract method
- Add `migrate_job_version(caller, job_id, target_version)` contract method
  - Authorizes only job client or platform admin
  - Rejects version downgrade (target < current)
  - Emits `job_version_migrated` event with old/new version
- Fix dispute_fee default to 0 in tests (no DEFAULT_DISPUTE_FEE applied unless initialized)
- Update 3 existing test Job structs to include `version: 1`
- Add 3 new contract unit tests:
  - test_job_initial_version_is_one
  - test_migrate_job_version_success
  - test_migrate_job_version_rejects_unauthorized
- Frontend: add optional `version?: number` to Job interface in types.ts
- Frontend: add `getJobVersion()` and `migrateJobVersion()` in contract.ts
- Frontend: add __tests__/job-version.test.ts (8 test cases)

Closes anumukul#592, resolves SC-106
Copilot AI review requested due to automatic review settings August 1, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@drips-wave

drips-wave Bot commented Aug 1, 2026

Copy link
Copy Markdown

@Oluwasuyi-Oluwatimilehin-Daniel 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

@anumukul

anumukul commented Aug 5, 2026

Copy link
Copy Markdown
Owner

@Oluwasuyi-Oluwatimilehin-Daniel please resolve conflicts

@Oluwasuyi-Oluwatimilehin-Daniel

Copy link
Copy Markdown
Contributor Author

@anumukul please review, the conflict has been resolved

@anumukul
anumukul merged commit 9b2d628 into anumukul:main Aug 5, 2026
2 of 15 checks passed
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.

[SC-106] Add job versioning for contract upgrades

3 participants