Skip to content
This repository was archived by the owner on Jul 10, 2026. It is now read-only.

chore: 4.0.0-devnet.1-patch.0 - #111

Closed
wei3erHase wants to merge 18 commits into
devfrom
chore/v4
Closed

chore: 4.0.0-devnet.1-patch.0#111
wei3erHase wants to merge 18 commits into
devfrom
chore/v4

Conversation

@wei3erHase

@wei3erHase wei3erHase commented Feb 4, 2026

Copy link
Copy Markdown
Member

v4 migration notes

v4 upgrade: VERSION=4.0.0-nightly.20260204 bash -i <(curl -sL https://install.aztec.network/4.0.0-nightly.20260204)

  • notice: installation uses curl -sL (previously curl -s)
  • notice: workflow installation needs foundryup (use toolchain)
  • change LSP settings to which nargo (~/.aztec/current/bin/nargo)
  • protocol_types is now protocol
  • rm all .wait() & .deployed()
  • JS deploy is now much simpler
  • remember to clean before re-compiling
  • change pre-commit to nargo fmt

waiting on frozen v4 to merge to dev

  • does the utils script to deploy still make sense?

Summary by CodeRabbit

  • Documentation

    • Removed Docker requirement from setup instructions.
  • Chores

    • Bumped Aztec dependency/version to 4.0.0-devnet.1-patch.0.
    • Switched pre-commit formatting to nargo fmt.
    • Removed several local version-check and sandbox management scripts.
  • CI / Workflows

    • Consolidated and delegated test and baseline workflows to external reusable workflows.
    • Removed in-repo CI composite actions for benchmarks and tests.
  • Tests / Runtime

    • Simplified sandbox startup and test setup/teardown; streamlined deployment and benchmark test flows.

✨ PR Description

Purpose: Upgrade Aztec framework dependencies and CI infrastructure from version 3.0.0-devnet.6-patch.1 to 4.0.0-devnet.1-patch.0 across the entire project.

Main changes:

  • Updated all Aztec package dependencies to 4.0.0-devnet.1-patch.0 including aztec.js, accounts, stdlib, and benchmark packages
  • Refactored CI workflows to use centralized reusable workflows from defi-wonderland repositories for testing and benchmarking
  • Simplified contract deployment by removing explicit .deployed() calls and updating import paths from protocol_types to protocol namespace

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Description using Guidelines Learn how

Comment thread vitest.config.ts
Comment on lines -27 to +29
poolOptions: {
forks: {
singleFork: true,
isolate: false,
execArgv: ["--experimental-vm-modules"],
},
},
singleFork: true,
isolate: false,
execArgv: ["--experimental-vm-modules"],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

i'm not sure what this is about

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 In Vitest v1.0+, poolOptions was deprecated in favor of direct properties. The old format was:

poolOptions: {  forks: {    singleFork: true,    isolate: false  }}

@github-actions

github-actions Bot commented Feb 4, 2026

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 456,805 -15,487 (-3.3%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

Comment thread src/ts/utils.ts

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

does it make sense to keep this file?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Imo yes, I would keep it structure wise to replicate standards. This file is trivial with 1 function, but standards' utils is an example of multiple utilities for tests and benchmarks.

@github-actions

github-actions Bot commented Feb 5, 2026

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 456,805 -15,487 (-3.3%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

Co-authored-by: Weißer Hase <wei3erHase@protonmail.com>
@wei3erHase wei3erHase changed the title chore: 4.0.0-nightly.20260204 chore: 4.0.0-devnet.1-patch.0 Feb 12, 2026
@wei3erHase
wei3erHase marked this pull request as ready for review February 12, 2026 12:23
@github-actions

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 454,517 -17,775 (-3.8%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

@coderabbitai

coderabbitai Bot commented Feb 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR updates Aztec dependencies from 3.0.0-devnet.6-patch.1 to 4.0.0-devnet.1-patch.0 across package and Nargo manifests, adjusts Noir import paths for AztecAddress, and bumps package version. Multiple in-repo GitHub Actions and composite actions were removed and several workflows were replaced with calls to external reusable workflows. scripts/check-aztec-version.ts was deleted. scripts/start-sandbox.ts was simplified to return a minimal stop handle (removing SandboxManager). Tests and deployment helpers were simplified (removing .deployed()/wait chains), vitest config and vitest.setup were adjusted, the pre-commit formatter changed, and one Docker note was removed from the README.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: 4.0.0-devnet.1-patch.0' directly reflects the version upgrade performed across the entire changeset, which is the primary focus of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/v4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 6

🤖 Fix all issues with AI agents
In @.github/actions/benchmark/action.yml:
- Line 51: Update the GitHub Action reference currently set to
"defi-wonderland/aztec-benchmark/action@chore/v4" to a stable ref before
merging: replace the branch ref with a released tag (e.g. "@v4.x" or the
specific semver tag) or with "@main" once aztec-benchmark v4 support is merged;
ensure the change is applied to the uses entry so the workflow pins to a stable
commit instead of the "chore/v4" feature branch.

In @.github/actions/setup-aztec/action.yml:
- Around line 50-51: The install step currently uses `curl -sL $INSTALL_URL >
tmp.sh` then `VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh <<<
yes "yes"`, which unintentionally supplies both stdin and a positional argument;
replace this with an explicit pipe and clean up the temp file: download to
tmp.sh with curl -sL "$INSTALL_URL" -o tmp.sh, run the installer with stdin
piped (e.g., printf "yes\n" | VERSION=${{ steps.aztec-version.outputs.version }}
bash tmp.sh), and then remove tmp.sh (rm -f tmp.sh); reference the
variables/commands INSTALL_URL, VERSION, tmp.sh and the installer invocation
(bash tmp.sh) when making the change.

In `@scripts/start-sandbox.ts`:
- Around line 53-69: In the returned object's stop function (the async stop: ()
=> { ... } block) wrap both process.kill("SIGTERM") and the
process.kill("SIGKILL") inside try/catch to ignore ESRCH errors, and change the
Promise.race handling so the timeout created by setTimeout is cleared when the
process 'exit' event fires (e.g., keep the timeout id in a variable and call
clearTimeout in the process.once("exit"...) handler) to prevent the SIGKILL
timer from firing after the process already exited; use the existing
Promise.race, but ensure the exit listener resolves and clears the timeout and
the SIGKILL call is guarded in try/catch.
- Around line 42-47: The process.on("error") handler in startSandbox currently
types the error as any and throws inside an async event handler (so the throw
becomes an unhandled exception); change the handler to use error: unknown and
propagate the spawn failure by wiring a reject function into a stored promise
(e.g., create a spawnErrorPromise with an external reject or a deferred) and
call that reject from the process.on("error") handler instead of throwing, then
race that promise with waitForSandbox (Promise.race([waitForSandbox(...),
spawnErrorPromise])) so callers can catch the failure; alternatively log the
error and call process.exit(1) if you prefer immediate termination.

In `@src/ts/counter.test.ts`:
- Around line 47-49: The test calls counter.methods.increment().send(...) but
does not wait for inclusion, so add an explicit wait by calling .wait() on the
returned transaction promise (i.e., change usage of
counter.methods.increment().send to await
counter.methods.increment().send(...).wait()); ensure the subsequent call that
reads state (the counter.methods.someReadOr simulate() call) runs only after
.wait() completes so the state reflects the mined transaction.

In `@vitest.config.ts`:
- Around line 22-24: Replace the deprecated pool option property singleFork with
the Vitest v4 equivalent maxWorkers: 1 in the test config; in the configuration
object where singleFork: true, change that key to maxWorkers: 1 and keep isolate
and execArgv at top level (leave isolate: false and execArgv as-is) so the
intended single-worker behavior is preserved under Vitest 4.
🧹 Nitpick comments (6)
.github/actions/setup-aztec/action.yml (1)

57-60: Consider adding a readiness check after starting the local network.

aztec start --local-network & is backgrounded with no health/readiness gate. Subsequent steps (compile, codegen) provide an implicit delay, but the PXE node on Line 79 assumes the network is listening on :8080. A flaky CI environment or fast compile could cause a race. A simple poll loop (e.g., until curl -s http://localhost:8080/status; do sleep 2; done) before the PXE step would make this more robust.

package.json (1)

32-37: @types/node is listed in both dependencies and devDependencies.

Line 32 and line 37 both declare @types/node: "25.0.10". Type definitions are dev-only; remove the entry from dependencies.

Proposed fix
     "@aztec/test-wallet": "4.0.0-devnet.1-patch.0",
     "@defi-wonderland/aztec-benchmark": "https://github.com/defi-wonderland/aztec-benchmark/releases/download/prerelease-3ff00ed/defi-wonderland-aztec-benchmark-4.0.0-devnet.1-patch.0-prerelease.3ff00ed.tgz",
-    "@types/node": "25.0.10"
+    "@types/node": "25.0.10"  
   },

Wait — actually removing it cleanly:

     "@defi-wonderland/aztec-benchmark": "https://github.com/defi-wonderland/aztec-benchmark/releases/download/prerelease-3ff00ed/defi-wonderland-aztec-benchmark-4.0.0-devnet.1-patch.0-prerelease.3ff00ed.tgz",
-    "@types/node": "25.0.10"
   },
scripts/start-sandbox.ts (2)

37-39: Piped stdout/stderr are never consumed — risk of buffer back-pressure stalling the sandbox.

stdio: "pipe" captures output into Node buffers. If the sandbox is verbose, those buffers can fill up and block the child process. Consider using "ignore" or "inherit" if you don't need the output.

-    stdio: "pipe",
+    stdio: "ignore",

1-1: ChildProcess is imported but never used as an explicit type annotation.

process is already inferred from spawn(). You can drop the named import.

-import { spawn, ChildProcess } from "child_process";
+import { spawn } from "child_process";
benchmarks/counter.benchmark.ts (1)

65-67: process.exit(0) in teardown is a heavy-handed shutdown.

This kills the entire Node process, preventing vitest/benchmark runner from performing its own cleanup (flushing results, closing connections). If this is intentional to work around a known hang, a brief comment would help future readers.

src/ts/utils.ts (1)

15-15: Non-null assertion on account access could throw if wallet has no accounts.

Consider a guard or a descriptive error instead of !:

Suggested improvement
-  const deployerAddress = (await deployer.getAccounts())[0]!.item;
+  const accounts = await deployer.getAccounts();
+  if (!accounts.length) throw new Error('Deployer wallet has no registered accounts');
+  const deployerAddress = accounts[0]!.item;

Comment thread .github/actions/benchmark/action.yml Outdated
Comment thread .github/actions/setup-aztec/action.yml Outdated
Comment on lines 50 to 51
curl -sL $INSTALL_URL > tmp.sh
VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh <<< yes "yes"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Confusing here-string / argument syntax in install command.

bash tmp.sh <<< yes "yes" passes the string yes as stdin (here-string) and "yes" as $1 to the script. This is likely unintentional — if the goal is to auto-accept prompts, prefer an explicit pipe:

-        curl -sL $INSTALL_URL > tmp.sh
-        VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh <<< yes "yes"
+        curl -sL $INSTALL_URL > tmp.sh
+        yes | VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh
+        rm -f tmp.sh

Also cleans up the temp file.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -sL $INSTALL_URL > tmp.sh
VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh <<< yes "yes"
curl -sL $INSTALL_URL > tmp.sh
yes | VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh
rm -f tmp.sh
🤖 Prompt for AI Agents
In @.github/actions/setup-aztec/action.yml around lines 50 - 51, The install
step currently uses `curl -sL $INSTALL_URL > tmp.sh` then `VERSION=${{
steps.aztec-version.outputs.version }} bash tmp.sh <<< yes "yes"`, which
unintentionally supplies both stdin and a positional argument; replace this with
an explicit pipe and clean up the temp file: download to tmp.sh with curl -sL
"$INSTALL_URL" -o tmp.sh, run the installer with stdin piped (e.g., printf
"yes\n" | VERSION=${{ steps.aztec-version.outputs.version }} bash tmp.sh), and
then remove tmp.sh (rm -f tmp.sh); reference the variables/commands INSTALL_URL,
VERSION, tmp.sh and the installer invocation (bash tmp.sh) when making the
change.

Comment thread scripts/start-sandbox.ts
Comment on lines +42 to +47
process.on("error", (error: any) => {
if (error.code === "ENOENT") {
throw new Error("Aztec CLI not found. Please install it with aztec-up");
}
throw error;
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Throwing inside an async event handler won't propagate to the caller; use any violates guidelines.

process.on("error", ...) fires asynchronously after startSandbox has already moved on to waitForSandbox. The throw becomes an unhandled exception rather than a rejection the caller can catch. Consider rejecting a stored promise or logging and exiting instead. Also, error: any should be error: unknown per coding guidelines.

Sketch: propagate spawn errors

One approach is to race waitForSandbox against a spawn-error promise:

+ let spawnError: Promise<never> | undefined;
+
  const process = spawn("aztec", ["start", "--sandbox", "--port", "8080"], {
    stdio: "pipe",
  });

- process.on("error", (error: any) => {
-   if (error.code === "ENOENT") {
-     throw new Error("Aztec CLI not found. Please install it with aztec-up");
-   }
-   throw error;
- });
+ spawnError = new Promise<never>((_, reject) => {
+   process.on("error", (error: unknown) => {
+     const code = (error as NodeJS.ErrnoException).code;
+     if (code === "ENOENT") {
+       reject(new Error("Aztec CLI not found. Please install it with aztec-up"));
+     } else {
+       reject(error);
+     }
+   });
+ });

- await waitForSandbox(SANDBOX_URL);
+ await Promise.race([waitForSandbox(SANDBOX_URL), spawnError]);

As per coding guidelines, "Avoid any; use unknown when necessary."

🤖 Prompt for AI Agents
In `@scripts/start-sandbox.ts` around lines 42 - 47, The process.on("error")
handler in startSandbox currently types the error as any and throws inside an
async event handler (so the throw becomes an unhandled exception); change the
handler to use error: unknown and propagate the spawn failure by wiring a reject
function into a stored promise (e.g., create a spawnErrorPromise with an
external reject or a deferred) and call that reject from the process.on("error")
handler instead of throwing, then race that promise with waitForSandbox
(Promise.race([waitForSandbox(...), spawnErrorPromise])) so callers can catch
the failure; alternatively log the error and call process.exit(1) if you prefer
immediate termination.

Comment thread scripts/start-sandbox.ts
Comment on lines +53 to +69
return {
stop: async () => {
console.log("🛑 Stopping Aztec sandbox");
process.kill("SIGTERM");

// Wait for process to exit (with timeout)
await Promise.race([
new Promise<void>((resolve) => {
process.once("exit", () => resolve());
}),
new Promise<void>((resolve) => {
setTimeout(() => {
process.kill("SIGKILL");
resolve();
}, 5000);
}),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

process.kill() can throw ESRCH if the process has already exited.

Both the SIGTERM (line 56) and SIGKILL (line 65) calls will throw if the process is no longer running. Wrap them in try/catch. Also, when the process exits before the 5 s timeout, the SIGKILL timer still fires unnecessarily.

Proposed fix
     stop: async () => {
       console.log("🛑 Stopping Aztec sandbox");
-      process.kill("SIGTERM");
+      try { process.kill("SIGTERM"); } catch { /* already exited */ }

       // Wait for process to exit (with timeout)
       await Promise.race([
         new Promise<void>((resolve) => {
           process.once("exit", () => resolve());
         }),
         new Promise<void>((resolve) => {
           setTimeout(() => {
-            process.kill("SIGKILL");
+            try { process.kill("SIGKILL"); } catch { /* already exited */ }
             resolve();
           }, 5000);
         }),
       ]);
     },
🤖 Prompt for AI Agents
In `@scripts/start-sandbox.ts` around lines 53 - 69, In the returned object's stop
function (the async stop: () => { ... } block) wrap both process.kill("SIGTERM")
and the process.kill("SIGKILL") inside try/catch to ignore ESRCH errors, and
change the Promise.race handling so the timeout created by setTimeout is cleared
when the process 'exit' event fires (e.g., keep the timeout id in a variable and
call clearTimeout in the process.once("exit"...) handler) to prevent the SIGKILL
timer from firing after the process already exited; use the existing
Promise.race, but ensure the exit listener resolves and clears the timeout and
the SIGKILL call is guarded in try/catch.

Comment thread src/ts/counter.test.ts
Comment on lines +47 to +49
await counter.methods.increment().send({
from: alice,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the test file to understand the context
fd counter.test.ts

Repository: defi-wonderland/aztec-boilerplate

Length of output: 99


🏁 Script executed:

# Once we find the file, let's examine lines 45-60 to see the full context
cat -n src/ts/counter.test.ts | sed -n '45,60p'

Repository: defi-wonderland/aztec-boilerplate

Length of output: 450


🏁 Script executed:

# Let's also search for other uses of .send() in the codebase to see the pattern
rg '\.send\(' --type ts -A 2 -B 2

Repository: defi-wonderland/aztec-boilerplate

Length of output: 902


🌐 Web query:

Aztec v4 API send() method documentation transaction inclusion

💡 Result:

In Aztec v4 (Aztec.js), send() does not mean “included in a block” by itself.

  • contract.methods.<fn>(...).send(options) submits the transaction and returns a SentTx handle you can use to track status/receipt/events. It “can be sent to the network to be included in a block,” but inclusion happens later. [1]
  • To wait for transaction inclusion (mined / in a block), you must call .wait() on that returned SentTx:
    • await contract.methods.transfer(...).send({...}).wait(); returns a receipt (including blockNumber). [2]
    • Or “send without waiting”: const sentTx = ...send(...); const txHash = await sentTx.getTxHash(); const receipt = await sentTx.wait(); [2]
  • The API reference for SentTx.wait(opts?: WaitOpts) states it “awaits for a tx to be mined and returns the receipt” (and throws if not mined). [3]

Docs to look at (most directly answering “transaction inclusion”):

  • “Transactions” → send returns SentTx (track status/receipt) [1]
  • “Sending Transactions” → examples using .send().wait() and sentTx.wait() (mined/blockNumber) [2]
  • Aztec.js reference → SentTx.wait() definition (“mined” ⇒ inclusion) [3]

Add .wait() after .send() to ensure transaction inclusion before reading state.

.send() in Aztec v4 submits the transaction but does not wait for block inclusion; you must call .wait() explicitly. Without it, the .simulate() call on line 52 may read stale state before the transaction is mined, causing test flakiness.

    await counter.methods.increment().send({
      from: alice,
    }).wait();
🤖 Prompt for AI Agents
In `@src/ts/counter.test.ts` around lines 47 - 49, The test calls
counter.methods.increment().send(...) but does not wait for inclusion, so add an
explicit wait by calling .wait() on the returned transaction promise (i.e.,
change usage of counter.methods.increment().send to await
counter.methods.increment().send(...).wait()); ensure the subsequent call that
reads state (the counter.methods.someReadOr simulate() call) runs only after
.wait() completes so the state reflects the mined transaction.

Comment thread vitest.config.ts
Comment on lines +22 to +24
singleFork: true,
isolate: false,
execArgv: ["--experimental-vm-modules"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Vitest 4.0 test poolOptions forks singleFork isolate execArgv configuration

💡 Result:

In Vitest v4, test.poolOptions (including poolOptions.forks.singleFork, poolOptions.*.isolate, and poolOptions.*.execArgv) was removed—those settings moved to top-level test options. [1]

v3-style (removed in v4)

export default defineConfig({
  test: {
    pool: 'forks',
    poolOptions: {
      forks: {
        execArgv: ['--expose-gc'],
        isolate: false,
        singleFork: true,
      },
    },
  },
})

v4 equivalent

export default defineConfig({
  test: {
    pool: 'forks',
    execArgv: ['--expose-gc'],
    isolate: false,

    // replaces `singleFork: true` (and `singleThread: true`)
    maxWorkers: 1,
  },
})

What changed (mapping)

  • poolOptions.forks.execArgvtest.execArgv (applies when spawning workers via threads or forks). [2]
  • poolOptions.forks.isolatetest.isolate. [1]
  • poolOptions.forks.singleForkremoved; use maxWorkers: 1 (and usually isolate: false if you previously relied on “single global context” behavior). [1]

Sources: Migration guide + CLI/config docs. [1] [2]


Replace singleFork: true with maxWorkers: 1.

In Vitest 4.x, singleFork was removed and replaced with maxWorkers: 1. The current configuration will silently ignore singleFork: true, breaking the intended behavior. isolate and execArgv are correctly positioned at the top level.

Migration mapping
v3 (removed in v4):
  poolOptions.forks.singleFork: true
  poolOptions.forks.isolate: false
  poolOptions.forks.execArgv: [...]

v4 equivalent:
  maxWorkers: 1
  isolate: false
  execArgv: [...]
🤖 Prompt for AI Agents
In `@vitest.config.ts` around lines 22 - 24, Replace the deprecated pool option
property singleFork with the Vitest v4 equivalent maxWorkers: 1 in the test
config; in the configuration object where singleFork: true, change that key to
maxWorkers: 1 and keep isolate and execArgv at top level (leave isolate: false
and execArgv as-is) so the intended single-worker behavior is preserved under
Vitest 4.

@github-actions

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 454,517 -17,775 (-3.8%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

zkfrov
zkfrov previously approved these changes Feb 12, 2026

@zkfrov zkfrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

@github-actions

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 454,517 -17,775 (-3.8%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

@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: 1

🤖 Fix all issues with AI agents
In `@package.json`:
- Line 32: The package.json currently lists "@types/node" in both "dependencies"
and "devDependencies"; remove the entry from "dependencies" and keep the single
"@types/node": "25.0.10" declaration under "devDependencies" so the type-only
package is not installed at runtime and the version remains consistent across
the file (check the entries near the existing "@types/node" symbols to ensure
only the devDependencies entry remains).
🧹 Nitpick comments (2)
package.json (1)

31-31: Benchmark dependency pinned to a prerelease tarball URL.

This tarball URL is tied to a specific commit (65a679a). Acceptable for a prerelease track, but worth tracking so it gets updated to a proper semver release once the v4 line stabilizes — otherwise it's easy to forget and end up with a stale snapshot.

.github/workflows/pr-checks.yml (1)

11-13: Consider pinning the external reusable workflow to a commit SHA instead of a mutable tag.

@v0 is a mutable Git ref — if the tag is moved (intentionally or via compromise) in defi-wonderland/aztec-ci-actions, the new code runs with all inherited secrets. GitHub recommends pinning reusable workflows from external repositories to a full-length commit SHA for supply-chain safety. This applies equally to main-tests.yml and update-baseline.yml.

Example
-    uses: defi-wonderland/aztec-ci-actions/.github/workflows/run-tests.yml@v0
+    uses: defi-wonderland/aztec-ci-actions/.github/workflows/run-tests.yml@<full-commit-sha>

Comment thread package.json
"@aztec/stdlib": "4.0.0-devnet.1-patch.0",
"@aztec/test-wallet": "4.0.0-devnet.1-patch.0",
"@defi-wonderland/aztec-benchmark": "https://github.com/defi-wonderland/aztec-benchmark/releases/download/prerelease-65a679a/defi-wonderland-aztec-benchmark-4.0.0-devnet.1-patch.0-prerelease.65a679a.tgz",
"@types/node": "25.0.10"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

@types/node is listed in both dependencies and devDependencies.

@types/node at 25.0.10 appears in both sections. It should only be in devDependencies since it's a type-only package not needed at runtime.

Proposed fix
   "dependencies": {
     "@aztec/accounts": "4.0.0-devnet.1-patch.0",
     ...
-    "@defi-wonderland/aztec-benchmark": "...",
-    "@types/node": "25.0.10"
+    "@defi-wonderland/aztec-benchmark": "..."
   },

Also applies to: 37-37

🤖 Prompt for AI Agents
In `@package.json` at line 32, The package.json currently lists "@types/node" in
both "dependencies" and "devDependencies"; remove the entry from "dependencies"
and keep the single "@types/node": "25.0.10" declaration under "devDependencies"
so the type-only package is not installed at runtime and the version remains
consistent across the file (check the entries near the existing "@types/node"
symbols to ensure only the devDependencies entry remains).

Co-authored-by: xorsal <zorzal@wonderland.xyz>
@github-actions

Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: counter

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🔴 increment 472,292 454,517 -17,775 (-3.8%) 2,253 2,048 -205 (-9.1%) 28,872 93,035 +64,163 (+222.2%) N/A N/A

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

🧹 Nitpick comments (1)
.github/workflows/pr-checks.yml (1)

11-13: checks uses a mutable @v0 tag while benchmark is pinned to a specific version.

@v0 is a floating tag that could introduce breaking changes without any change in this repo. Consider pinning to a specific version or commit SHA for reproducibility, consistent with how the benchmark job is pinned to @4.0.0-devnet.1-patch.0.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr-checks.yml around lines 11 - 13, The checks job
currently references a mutable tag in the uses line
("defi-wonderland/aztec-ci-actions/.github/workflows/run-tests.yml@v0"); update
that to a fixed version or commit SHA (matching the approach used for the
benchmark job, e.g., replace "@v0" with a specific release tag or the commit SHA
such as "@4.0.0-devnet.1-patch.0" or a stable SHA) so the checks workflow is
reproducible and won't silently change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@package.json`:
- Around line 23-33: The package.json currently lists the type-only package
"@types/node" in both "dependencies" and "devDependencies"; remove the duplicate
by deleting the "@types/node" entry from the "dependencies" block and keep it
only in "devDependencies" so type definitions are installed for development but
not shipped with production; update the "dependencies" object (the block
containing "@aztec/*" entries) to remove "@types/node" and run your package
manager to refresh the lockfile if necessary.

---

Nitpick comments:
In @.github/workflows/pr-checks.yml:
- Around line 11-13: The checks job currently references a mutable tag in the
uses line
("defi-wonderland/aztec-ci-actions/.github/workflows/run-tests.yml@v0"); update
that to a fixed version or commit SHA (matching the approach used for the
benchmark job, e.g., replace "@v0" with a specific release tag or the commit SHA
such as "@4.0.0-devnet.1-patch.0" or a stable SHA) so the checks workflow is
reproducible and won't silently change.

@linearb linearb 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.

✨ PR Review

The v4 migration simplifies the codebase significantly, particularly in sandbox management and contract deployment patterns. The changes follow the documented v4 migration path.

1 issues detected:

🚀 Performance - Exit event listener registered after process may have already exited, causing 5-second timeout

Details: If the sandbox process exits before stop() is called, the exit event listener registered on line 61 will never fire since the event was already emitted. This causes an unnecessary 5-second timeout delay before proceeding with the SIGKILL fallback.
File: scripts/start-sandbox.ts

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Review using Guidelines Learn how

@ilpepepig

Copy link
Copy Markdown
Contributor

Closing in favor of #119

@ilpepepig ilpepepig closed this Mar 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Development

Successfully merging this pull request may close these issues.

4 participants