Skip to content

feat(e2e): support running tests against legacy noir contract artifacts#22388

Open
benesjan wants to merge 11 commits intobackport-to-v4-next-stagingfrom
jb/e2e-legacy-contract-artifacts
Open

feat(e2e): support running tests against legacy noir contract artifacts#22388
benesjan wants to merge 11 commits intobackport-to-v4-next-stagingfrom
jb/e2e-legacy-contract-artifacts

Conversation

@benesjan
Copy link
Copy Markdown
Contributor

@benesjan benesjan commented Apr 8, 2026

We need to ensure that it never happens that an already deployed contract stops working on a new release of our stack (new Wallet/PXE). To ensure this is the case we want to run e2e tests with older contract artifacts (contract artifacts compiled with older [Aztec.nr, nargo, bb]).

Now how do we achieve this?

Nico originally proposed that we would be committing the artifacts when a new release is performed. After chatting with AI I decided against this and I instead went with pulling the contract artifacts from npmjs.com where they get automatically pushed on new releases as @aztec/noir-contracts.js and @aztec/noir-test-contracts.js packages.

This has the following advantages:

  1. Less repo bloat,
  2. it's more flexible as it does not depend on the artifacts being committed.

The approach:

  • Set CONTRACT_ARTIFACTS_VERSION=<x.y.z> to run any e2e test against a published legacy version of @aztec/noir-contracts.js / @aztec/noir-test-contracts.js.
  • On-demand npm install into yarn-project/end-to-end/.legacy-contracts/<version>/ (cached across runs).
  • Custom Jest resolver redirects imports and logs a banner (twhen an older artifact is resolved it gets logged into stderr)

I think this approach turned out to be nice because it's very isolated - it's just a few files and it's jest specific.

Note on what actually gets resolved to old version

The resolver hijacks only json files in the artifacts/ dirst of @aztec/noir-contracts.js and @aztec/noir-test-contracts.js packages so this PR results in us using the old json artifacts but new Typescript classes (e.g. we will use new AMM.ts class but old amm_contract-AMM.json artifact).

I set it up like this because that's how it's done on Ethereum as well - the json artifacts are distributed but the helper TypeScript classes are not. Hence we don't want to test backwards compatibility of the class - only of the artifacts.

How to protect against regressions?

The only thing I am worried about is that the resolver breaks with some future changes which results in the current artifacts getting resolved instead of the versioned ones and then everything happily passing in CI without us noticing. For this reason I propose that we add a build step to the contract compilation pipeline that injects the [Aztec.nr, nargo, bb] version in the JSON contract artifact and then in the e2e test setup we add a check that asserts that CONTRACT_ARTIFACTS_VERSION env var actually matches the version in the loaded JSON artifact (if the env var is set). This way we protect against this.

WDYT?

Future work

  • Actually run all the e2e in CI on new releases (here we will need to figure out how to resolve the versions of CONTRACT_ARTIFACTS_VERSIONs we want to test),
  • test the other dimension of the NxN matrix -> running the current contract artifacts (contract artifacts currently getting released) with older versions of the stack.

Why pointed at backport-to-v4-next-staging?

I pointed this PR at backport-to-v4-next-staging because v4 is where we currently need this and hence where I wanted to test this. Once this gets merged I will forward-port this to v5 (our merge 🚂 branch).

How do I know this actually works?

Test fails successfully when run with a version that used older oracles:

image

benesjan and others added 4 commits April 8, 2026 05:28
Set CONTRACT_ARTIFACTS_VERSION=<x.y.z> to transparently redirect
@aztec/noir-contracts.js and @aztec/noir-test-contracts.js imports to a
published version installed on demand under
yarn-project/end-to-end/.legacy-contracts/<version>/. Enables verifying
that contracts deployed from previous releases still work against the
current stack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The jest resolver handles redirection; the Node loader hook was dead code
for our actual use case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously required running scripts/ensure_legacy_contracts.mjs before
jest. Moving the install into the resolver itself makes
CONTRACT_ARTIFACTS_VERSION work with any entrypoint (e.g. yarn test:e2e).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@benesjan benesjan changed the title feat(e2e): run tests against legacy noir-contracts.js artifacts feat(e2e): support running tests against legacy noir contract artifacts Apr 8, 2026
@benesjan benesjan force-pushed the jb/e2e-legacy-contract-artifacts branch from ebe0705 to 4a37ed1 Compare April 8, 2026 07:04
benesjan and others added 3 commits April 8, 2026 07:14
The previous resolver redirected the entire @aztec/noir-contracts.js
package, which dragged the legacy @aztec/aztec.js along with it. That
coupled the test to a moving runtime API surface and would fail at
import time on unrelated breaking changes.

Now the resolver lets defaultResolver run first and only swaps JSON
files under .../noir-contracts.js/artifacts/ (and noir-test-contracts.js)
to the legacy cache equivalents. TS wrapper classes load from the
current workspace and use current aztec.js, so the test exercises only
the deployed-contract artifact compatibility surface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@benesjan benesjan marked this pull request as ready for review April 8, 2026 09:17
Copy link
Copy Markdown
Contributor

@mverzilli mverzilli left a comment

Choose a reason for hiding this comment

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

This is a great approach 🙌

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.

2 participants