Skip to content

Add PS mutation#131

Merged
0xisk merged 12 commits into
OpenZeppelin:mainfrom
andrew-fleming:sim-add-ps-mutation
Jul 24, 2026
Merged

Add PS mutation#131
0xisk merged 12 commits into
OpenZeppelin:mainfrom
andrew-fleming:sim-add-ps-mutation

Conversation

@andrew-fleming

@andrew-fleming andrew-fleming commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #130

This PR proposes to enable private state mutations on the live backend. The breaking change is that setPrivateState needs to be awaited => await this.setPrivateState(...)

Note that this does not support overrideWitness which is a bigger refactor (if wanted). Tests that use overrideWitness (e.g. ShieldedAccessControl in the compact contracts lib) cannot run on the live backend and must be skipped

The proposed changes were tested with ShieldedAccessControl and MultiToken (all tests passed for the latter, only overrideWitness tests failed for the former (they need to be skipped for live runs))

Types of changes

What types of changes does your code introduce to OpenZeppelin Midnight Contracts?
Put an x in the boxes that apply

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update (if none of the other choices apply)

Summary by CodeRabbit

  • New Features

    • Added asynchronous private-state replacement and update APIs.
    • Added support for patch-based and updater-function private-state changes.
    • Live simulations can now persist private-state updates when supported by the configured context.
    • Added clear error reporting when live private-state mutation is unavailable.
  • Bug Fixes

    • Ensured private-state changes are reflected in subsequent simulation calls.
  • Tests

    • Added coverage for replacement, patching, updater functions, persistence, and unsupported mutation scenarios.

@andrew-fleming
andrew-fleming requested review from a team as code owners July 23, 2026 06:15
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3261c59b-e84f-4cfa-92e1-cef604fc5214

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Private-state mutation is now asynchronous across simulator backends. Simulators support partial and functional updates, live contexts can persist state through providers, unsupported mutation is explicitly reported, and integration/unit tests cover replacement, updates, read-after-write behavior, and subsequent circuit calls.

Changes

Private State Mutation

Layer / File(s) Summary
Async mutation contracts and simulator API
packages/simulator/src/backend/Backend.ts, packages/simulator/src/backend/DryBackend.ts, packages/simulator/src/factory/createSimulator.ts, packages/simulator/src/live/LiveContext.ts, packages/simulator/src/index.ts
Backend and simulator mutation methods return promises; updatePrivateState supports shallow patches and updater functions; live-context mutation is optional and the unsupported error is publicly exported.
Live backend and provider mutation
packages/simulator/src/live/LiveBackend.ts, packages/simulator/src/live/createLiveContext.ts
LiveBackend delegates supported mutations to LiveContext, while createLiveContext writes complete state through the configured provider.
Mutation behavior tests and callers
packages/simulator/test/integration/*, packages/simulator/test/unit/*
Tests cover replacement, patching, updater functions, provider round trips, unsupported mutation, and propagation into later circuit calls; injection helpers use the centralized update API.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Simulator
  participant LiveBackend
  participant LiveContext
  participant PrivateStateProvider
  Simulator->>LiveBackend: setPrivateState(state)
  LiveBackend->>LiveContext: setPrivateState(state)
  LiveContext->>PrivateStateProvider: persist state by privateStateId
  PrivateStateProvider-->>LiveContext: write complete
  LiveContext-->>Simulator: Promise<void>
Loading

Possibly related PRs

Suggested reviewers: 0xisk

Poem

I’m a rabbit with state in a neat little sack,
Now async updates can hop forth and back.
Patches preserve what the carrots have grown,
Full writes make the new fields known.
Live providers remember each change in their burrow,
While tests cheer: “No stale state tomorrow!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague to describe the main change; it does not clearly indicate private-state mutation support. Use a specific title such as 'Add private state mutation support'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR adds post-deployment private state mutation support on the live backend and updates tests/docs to cover the new flow.
Out of Scope Changes check ✅ Passed The changes are centered on private-state mutation APIs, live context support, and matching tests, with no clear unrelated scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/simulator/src/factory/createSimulator.ts`:
- Around line 269-277: Serialize the complete read-modify-write operation in
updatePrivateState so concurrent calls on the same simulator cannot overwrite
one another. Add or reuse a per-simulator promise queue/mutex around
getPrivateState, updater execution, and setPrivateState, preserving both
functional and partial updater behavior; alternatively use provider-side
compare-and-set/versioning if that mechanism already exists.

In `@packages/simulator/src/live/LiveContext.ts`:
- Around line 76-78: Fix the TSDoc link in the LiveContext documentation by
referencing the exported PRIVATE_STATE_MUTATION_UNSUPPORTED symbol directly, or
render the symbol as code text instead of linking it through LiveBackend.
Preserve the existing mutation behavior description.

In `@packages/simulator/test/integration/Witness.test.ts`:
- Around line 205-210: Update the replacement-state and patch-state test
fixtures in Witness.test.ts to assign Buffer values to
WitnessPrivateState.secretBytes, replacing the Uint8Array constructions with
Buffer.alloc(...) while preserving the existing length and fill value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d82438d6-97d6-4c7f-88d6-a2f2be75c026

📥 Commits

Reviewing files that changed from the base of the PR and between 60308ab and 7a07f8d.

📒 Files selected for processing (13)
  • packages/simulator/src/backend/Backend.ts
  • packages/simulator/src/backend/DryBackend.ts
  • packages/simulator/src/factory/createSimulator.ts
  • packages/simulator/src/index.ts
  • packages/simulator/src/live/LiveBackend.ts
  • packages/simulator/src/live/LiveContext.ts
  • packages/simulator/src/live/createLiveContext.ts
  • packages/simulator/test/integration/LiveMutation.test.ts
  • packages/simulator/test/integration/SampleZOwnableSimulator.ts
  • packages/simulator/test/integration/Witness.test.ts
  • packages/simulator/test/integration/WitnessSimulator.ts
  • packages/simulator/test/unit/LiveBackendAdapter.test.ts
  • packages/simulator/test/unit/createLiveContext.test.ts

Comment thread packages/simulator/src/factory/createSimulator.ts Outdated
Comment thread packages/simulator/src/live/LiveContext.ts Outdated
Comment thread packages/simulator/test/integration/Witness.test.ts
Comment thread packages/simulator/src/factory/createSimulator.ts Outdated
Comment thread packages/simulator/src/factory/createSimulator.ts Outdated
Comment thread packages/simulator/src/backend/Backend.ts
Comment thread packages/simulator/src/factory/createSimulator.ts
Comment thread packages/simulator/src/factory/createSimulator.ts Outdated
Comment thread packages/simulator/src/factory/createSimulator.ts Outdated

@0xisk 0xisk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@0xisk 0xisk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@0xisk
0xisk merged commit 9e513de into OpenZeppelin:main Jul 24, 2026
6 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.

Add post-deployment private state mutations

2 participants