Skip to content

feat(registry): version upgrade validation (#304) - #377

Merged
Cjay-Cyber-2 merged 14 commits into
ASTROIDX556:mainfrom
meem08:feat/registry-upgrade-validation-304
Oct 7, 2026
Merged

Cjay-Cyber-2 merged 14 commits into
ASTROIDX556:mainfrom
meem08:feat/registry-upgrade-validation-304

Conversation

@meem08

@meem08 meem08 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Closes #304

Summary

The Registry is the protocol's single source of truth for version upgrades, so replacing deployed bytecode must be impossible for an unauthorized caller, with malformed bytecode, and it must never be able to move a version backwards. This implements strict validation for proposing and committing contract Wasm upgrades in contracts/registry/src/lib.rs.

Validation matrix (implemented)

Validation Where enforced On failure
Caller is protocol admin, the recorded org owner, or a delegated ModuleUpgrader propose_upgrade Unauthorized (NotFound for an unknown org, so a typo is distinguishable from a permission failure)
version non-zero and strictly greater than the kind's latest propose, commit, and register_version InvalidInput / InvalidState — downgrade protection
wasm_hash well-formed (all-zero hash refused) via require_valid_wasm_hash propose, commit, add_approved_wasm InvalidInput
Hash not already approved for the kind propose InvalidInput — identical-WASM re-proposal refused
One open proposal per kind propose InvalidState — the upgrade path stays unambiguous
Proposal not expired (1 week, UPGRADE_PROPOSAL_EXPIRY) commit NotFound
Registry not frozen every lifecycle entrypoint RegistryFrozen

Committing re-runs the full check set so nothing that went stale while a proposal was pending can slip through. Successful lifecycle actions emit structured UpgradeProposed / UpgradeCommitted / UpgradeRejected events (canonical + tuple-topic form) and are appended to the immutable audit log; refused attempts revert atomically with their error code (Soroban rolls back any write made on an error path, so refusals are visible off-chain as reverted transactions).

Acceptance criteria (from the issue)

  • Upgrade validation checks implemented in contracts/registry/src/
  • Structured Soroban events emitted on successful and rejected upgrade outcomes (UpgradeProposed/UpgradeCommitted/UpgradeRejected on success; refused attempts revert with the deterministic shared error)
  • Comprehensive unit and integration tests covering unauthorized and valid upgrades — see below

Tests

Unit (contracts/registry/src/test.rs, 75 passing):

  • Authorization: stranger → Unauthorized, delegated PolicyManager → Unauthorized, delegated ModuleUpgrader / org owner / admin → allowed (stranger_and_delegated_non_upgrader_cannot_propose, org_owner_module_upgrader_and_admin_can_propose, audit_log_captures_unauthorized_attempts-successor)
  • Downgrade protection at propose and commit: proposal_validation_rejects_unauthorized_and_downgrades, stale_proposal_cannot_shadow_a_committed_version, audit_log_captures_rejected_and_identical_wasm_attempts-successor
  • Identical-WASM re-proposal refused: refused_upgrades_leave_no_audit_entries
  • Wasm-hash format: require_valid_wasm_hash unit coverage + zero-hash refusal
  • Expiry: expired_proposal_cannot_be_committed
  • New in this PR: register_version_rejects_downgrades_and_repeats — the admin escape hatch obeys the same monotonic version-table guard (repeat and downgrade → InvalidState, strictly newer accepted)

Integration (tests/src/upgrade_validation.rs): the propose → commit flow driven across deployed contract boundaries, unauthorized/downgrade rejections, rejection/withdrawal clearing the pending slot, double-commit refusal, and the wallet-facing is_wasm_approved gate staying intact.

Testing done locally

meem08 and others added 2 commits September 26, 2026 13:55
Add an immutable, instance-storage audit trail to the registry's version
upgrade lifecycle so every propose/commit/reject is recorded on-chain
with who did what to which version of a module kind, and when.

- shared: add `UpgradeAudit` payload (#[contracttype], published and
  stored with one identical schema), `UpgradeProposed` /
  `UpgradeCommitted` / `UpgradeRejected` canonical events, tuple-topic
  helpers, `UPGRADE_PROPOSAL_EXPIRY` (1 week) and
  `MAX_UPGRADE_AUDIT_ENTRIES` (32) constants, and a
  `require_valid_wasm_hash` guard (refuses the all-zero hash).
- registry: append each successful lifecycle action to a newest-first
  ring buffer in instance storage, capped at MAX_UPGRADE_AUDIT_ENTRIES;
  expose `get_upgrade_history` / `get_upgrade_history_len`. Re-validate
  proposals at commit time (downgrade, expiry, wasm hash) so nothing
  stale can slip through.
- refused attempts (unauthorized actor, downgrade, identical-WASM
  re-proposal) are deliberately not logged: Soroban invocations are
  atomic, so writes made on an error path are rolled back and could
  never be observed on-chain. Refusals stay visible off-chain as
  reverted transactions carrying their error code.
- tests: registry unit tests covering event emission, log immutability,
  ring-buffer retention, and the identical-WASM/unauthorized edge
  cases; cross-crate tests in tests/src/upgrade_validation.rs driving
  the flow through deployed contract boundaries.

Closes ASTROIDX556#300

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
…version guards (ASTROIDX556#304)

Make the Issue ASTROIDX556#304 validation surface explicit and fully tested:

- add a module-level validation matrix documenting every check in the
  propose -> commit upgrade flow (authorization, downgrade protection,
  wasm-hash format, identical-WASM re-proposal, one-open-proposal,
  expiry, freeze) with the error each refusal reports, and noting that
  the register_version admin escape hatch carries the same guards.
- add register_version_rejects_downgrades_and_repeats covering the
  monotonic version table: repeat and downgrade land InvalidState,
  strictly newer versions are accepted.

No behavior change: the checks themselves ship in the ASTROIDX556#300 stacked
branch; this commit makes the ASTROIDX556#304 scope explicit and locks it in with
tests.

Closes ASTROIDX556#304

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@drips-wave

drips-wave Bot commented Sep 26, 2026

Copy link
Copy Markdown

@meem08 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

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • build: failure
  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • build: failure
  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

1 similar comment
@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • fmt: failure
  • build: failure
  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

1 similar comment
@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • fmt: failure
  • build: failure
  • clippy: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • fmt: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

1 similar comment
@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • fmt: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • fmt: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • clippy: failure
  • fmt: failure
  • build: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

CI Checks Failed — Action Needed

The continuous integration checks on this pull request are failing. I can't merge until all required checks pass.

Failing checks:

  • build: failure
  • clippy: failure
  • fmt: failure

What to do: review the failing checks in the "Checks" tab above, fix the issues in your code, and push the changes.

The merge from main kept the upgrade-audit callers but dropped their
definitions: restore shared UpgradeAudit/events/constants/validation
items from the ASTROIDX556#300 feature line, re-add the registry DataKey variants
and upgrade-audit types, and close the truncated pending_proposal body
that left impl RegistryContract unclosed. Deduplicate the mangled test
import block and adapt the downgrade tests to register_version's
monotonic guard (strictly greater than latest), as specified for ASTROIDX556#304.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@Cjay-Cyber-2

Copy link
Copy Markdown
Contributor

Merge Conflict — Action Needed

This pull request has merge conflicts with the base branch (main).

What to do: update your branch by merging or rebasing against main, resolve any conflicts locally, and push the result.

@Cjay-Cyber-2
Cjay-Cyber-2 merged commit 90d4abd into ASTROIDX556:main Oct 7, 2026
1 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement version upgrade validation in Registry contract

2 participants