Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions .github/workflows/release-testnode-image.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Publish Testnode

# On a version tag (or manual dispatch), publish a testnode image for every
# variant x nitro-contracts-version we support. Each image's chain state is
# current supported variant. Each image's chain state is
# GENERATED inline in CI by running `init` (no pre-built snapshot release
# bundles, nothing to publish out of band). The intended (variant x version)
# matrix and the init flags per combo come from runtime.mjs resolvePublishMatrix.
Expand Down Expand Up @@ -30,15 +30,6 @@ on:
- l3-custom-16
- l3-custom-18
- l3-custom-20
nitro-contracts-version:
description: "Nitro contracts version (or all)"
required: true
default: "all"
type: choice
options:
- all
- v2.1
- v3.2
dockerhub-repository:
description: "Docker Hub repository to publish to (retarget for a dry run)"
required: false
Expand Down Expand Up @@ -88,15 +79,12 @@ jobs:
- name: Build publish matrix
id: matrix
env:
# On tag push: every variant x every supported version. On dispatch:
# the chosen filters. resolvePublishMatrix only emits supported combos
# (e.g. no v2.1 for L2-only variants).
# New releases are built from the current Nitro contracts family.
VARIANT_FILTER: ${{ github.ref_type == 'tag' && 'all' || (github.event_name == 'workflow_dispatch' && inputs.variant || 'all') }}
VERSION_FILTER: ${{ github.ref_type == 'tag' && 'all' || (github.event_name == 'workflow_dispatch' && inputs.nitro-contracts-version || 'all') }}
run: >-
node --input-type=module -e
"import { resolvePublishMatrix } from './packages/testnode/src/runtime.mjs';
const include = resolvePublishMatrix(process.env.VARIANT_FILTER, process.env.VERSION_FILTER);
const include = resolvePublishMatrix(process.env.VARIANT_FILTER, 'v3.2');
if (!include.length) throw new Error('empty publish matrix');
console.error('publish matrix:', JSON.stringify(include));
const { appendFileSync } = await import('node:fs');
Expand All @@ -121,6 +109,8 @@ jobs:
# pin the location and the commit the contract-deployer Dockerfiles use.
TOKEN_BRIDGE_LOCAL_DIR: ${{ github.workspace }}/../token-bridge-contracts
TOKEN_BRIDGE_COMMIT: 5975d8f7360816341be7f94fd333ef240f4aec23
NITRO_CONTRACTS_LOCAL_DIR: ${{ github.workspace }}/../nitro-contracts
NITRO_CONTRACTS_COMMIT: 2695e7b3e3f460531e2b77fed48a60561c54d90e
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -156,6 +146,19 @@ jobs:
test -f node_modules/ts-node/dist/bin.js
test -f scripts/deployment/deployTokenBridgeCreator.ts

- name: Prepare Nitro contracts checkout
run: |
set -euxo pipefail
mkdir -p "$NITRO_CONTRACTS_LOCAL_DIR"
cd "$NITRO_CONTRACTS_LOCAL_DIR"
git init .
git remote add origin https://github.com/OffchainLabs/nitro-contracts.git
git fetch --depth 1 origin "$NITRO_CONTRACTS_COMMIT"
git checkout --detach FETCH_HEAD
git submodule update --init --recursive --depth 1
test "$(node -p 'require("./package.json").name')" = "@arbitrum/nitro-contracts"
test "$(node -p 'require("./package.json").version')" = "3.2.0"

# Generate this combo's snapshot inline via init. init is flaky in CI
# (intermittently exits 0 at wait-l1 before capturing, ~50%), so success
# is driven off the manifest existing, with up to 3 attempts and a reset
Expand All @@ -164,7 +167,6 @@ jobs:
- name: Generate snapshot (init, retry until captured)
env:
SNAPSHOT_ID: ${{ matrix.snapshotId }}
NC_VERSION: ${{ matrix.contractsVersion }}
DECIMALS: ${{ matrix.feeTokenDecimals }}
TIMEBOOST: ${{ matrix.timeboostEnabled }}
run: |
Expand Down Expand Up @@ -229,7 +231,6 @@ jobs:
# `docker compose ... down -v` below so a timed-out attempt recovers.
set +e
timeout 1500 pnpm dev init \
--nitro-contracts-version "$NC_VERSION" \
$EXTRA \
--capture-id "$SNAPSHOT_ID" \
--rebuild \
Expand Down Expand Up @@ -262,7 +263,6 @@ jobs:
node scripts/ci/prepare-testnode-context.mjs
--variant "${{ matrix.variant }}"
--snapshot-id "${{ matrix.snapshotId }}"
--nitro-contracts-version "${{ matrix.contractsVersion }}"

# Both refs are derived from one suffix so the registries cannot disagree
# about what a version means. The suffix shape must match
Expand Down
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,21 @@ pnpm dev bake \
--push # optional; docker login is your responsibility
```

New builds use the stable Nitro contracts v3.2.0 release by default. For local
development, point `NITRO_CONTRACTS_LOCAL_DIR` at a Nitro 3.x checkout; a sibling
`../nitro-contracts` checkout is detected automatically:

```bash
NITRO_CONTRACTS_LOCAL_DIR=../nitro-contracts pnpm dev init --rebuild
NITRO_CONTRACTS_LOCAL_DIR=../nitro-contracts pnpm dev bake --rebuild \
--setup-command "./scripts/deploy-and-seed.sh" \
--image-ref ghcr.io/acme/arbitrum-testnode:governance
```

The checkout determines the contracts family; `init` and `bake` no longer expose
separate Nitro version or branch selectors. New builds require Nitro 3.x. Existing
published v2.1 images remain available through `start` and the run action.

To bake straight from an existing snapshot (no setup step), use the à-la-carte
subcommand:

Expand Down Expand Up @@ -285,7 +300,8 @@ job — log in before invoking it:
```

By default the action installs a base snapshot release (via `github-token`) and
restores it; set `rebuild: true` to run a full init instead.
restores it; set `rebuild: true` to run a full init instead. Rebuilds also accept
`nitro-contracts-ref` (default `v3.2.0`) and `fee-token-decimals`.

### Booting a custom image

Expand Down Expand Up @@ -386,11 +402,11 @@ Publish one variant image from GitHub Actions:
workflow: Publish Testnode
version: v0.2.3
variant: l3-eth
nitro-contracts-version: v3.2
snapshot-version: v0.1.6
```

Publish every catalog entry by setting `variant` to `all`. Publish every supported Nitro contracts tag by setting `nitro-contracts-version` to `all`.
Publish every current catalog entry by setting `variant` to `all`. Existing v2.1
images remain resolvable but are not rebuilt by new releases.

The default Timeboost publish target is `l2-timeboost`, which expects the `l2-timeboost` snapshot ID in the selected snapshot release. It can be published directly with `variant: l2-timeboost` or through the `name: timeboost` entry in `config/testnodes.json`.

Expand Down
32 changes: 13 additions & 19 deletions apps/cli/src/commands/bake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,25 @@ const bakeOptions = z.object({
.string()
.optional()
.describe("Base snapshot to restore when not rebuilding (default: default)"),
nitroContractsVersion: z
.string()
.optional()
.describe("Nitro contracts version for a rebuild init (e.g. v2.1, v3.2)"),
feeTokenDecimals: z
.number()
.optional()
.describe("Custom fee token decimals (6, 16, 18, or 20) for a rebuild init"),
timeboostEnabled: z.boolean().optional().describe("Enable Timeboost for a rebuild init"),
});

function rebuildInitOptions(options: z.infer<typeof bakeOptions>) {
return {
rebuild: true,
...(options.feeTokenDecimals !== undefined
? { feeTokenDecimals: options.feeTokenDecimals }
: {}),
...(options.timeboostEnabled !== undefined
? { timeboostEnabled: options.timeboostEnabled }
: {}),
};
}

/**
* Boot the base stack the customization runs against. `--rebuild` runs a full
* init; otherwise the installed base snapshot is restored and started, mirroring
Expand All @@ -75,21 +83,7 @@ async function ensureBaseStack(
options: z.infer<typeof bakeOptions>,
): Promise<void> {
if (options.rebuild) {
await runInitCommand(
{
rebuild: true,
...(options.nitroContractsVersion
? { nitroContractsVersion: options.nitroContractsVersion }
: {}),
...(options.feeTokenDecimals !== undefined
? { feeTokenDecimals: options.feeTokenDecimals }
: {}),
...(options.timeboostEnabled !== undefined
? { timeboostEnabled: options.timeboostEnabled }
: {}),
},
createInitContext(root),
);
await runInitCommand(rebuildInitOptions(options), createInitContext(root));
return;
}

Expand Down
4 changes: 0 additions & 4 deletions apps/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ export const initCli = Cli.create("init", {
.optional()
.describe("Deploy a custom fee token ERC20 on L2 with this many decimals (6, 16, 18, or 20)"),
foreground: z.boolean().optional().describe("Internal worker mode for detached init runs"),
nitroContractsVersion: z
.string()
.optional()
.describe("Nitro contracts version for the L3 rollup (e.g. v2.1, v3.2). Default v3.2."),
rebuild: z
.boolean()
.optional()
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/test/no-docker-rollup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("init chain steps deploy rollups through a local RollupCreator", () =>

it("uses Docker only to provision the RollupCreator contracts", () => {
expect(initSource).toContain("deployRollupCreatorViaDocker");
expect(initSource).toContain("CONTRACT_DEPLOYER_IMAGE");
expect(initSource).toContain("resolveDeployerImageSpec");
expect(initSource).not.toContain("ROLLUPCREATOR_IMAGE");
});

Expand Down
37 changes: 31 additions & 6 deletions bake/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,17 @@ inputs:
required: false
default: ""
description: "Base snapshot release tag to install (defaults to latest) when not rebuilding"
nitro-contracts-version:
nitro-contracts-ref:
required: false
default: "v3.2"
description: "Nitro contracts version passed through to a rebuild init"
default: "v3.2.0"
description: >-
Nitro contracts release, branch, or commit used during a rebuild init.
fee-token-decimals:
required: false
default: ""
description: >-
Custom L3 fee-token decimals (6, 16, 18, or 20) for a rebuild init.
Empty = ETH-fee (no custom fee token).
github-token:
required: false
default: ""
Expand Down Expand Up @@ -93,12 +100,29 @@ runs:
working-directory: ${{ github.action_path }}/..
env:
BASE_SNAPSHOT_ID_INPUT: ${{ inputs.base-snapshot-id }}
NITRO_CONTRACTS_VERSION_INPUT: ${{ inputs.nitro-contracts-version }}
FEE_TOKEN_DECIMALS_INPUT: ${{ inputs.fee-token-decimals }}
NITRO_CONTRACTS_REF_INPUT: ${{ inputs.nitro-contracts-ref }}
NITRO_CONTRACTS_DEFAULT_COMMIT: 2695e7b3e3f460531e2b77fed48a60561c54d90e
NITRO_CONTRACTS_LOCAL_DIR: ${{ runner.temp }}/nitro-contracts
TOKEN_BRIDGE_COMMIT: 5975d8f7360816341be7f94fd333ef240f4aec23
TOKEN_BRIDGE_LOCAL_DIR: ${{ runner.temp }}/token-bridge-contracts
run: |
set -euxo pipefail
npm install -g yarn@1.22.22
if [ ! -f "$NITRO_CONTRACTS_LOCAL_DIR/package.json" ]; then
mkdir -p "$NITRO_CONTRACTS_LOCAL_DIR"
(
cd "$NITRO_CONTRACTS_LOCAL_DIR"
git init .
git remote add origin https://github.com/OffchainLabs/nitro-contracts.git
git fetch --depth 1 origin "$NITRO_CONTRACTS_REF_INPUT"
git checkout --detach FETCH_HEAD
git submodule update --init --recursive --depth 1
if [ "$NITRO_CONTRACTS_REF_INPUT" = "v3.2.0" ]; then
test "$(git rev-parse HEAD)" = "$NITRO_CONTRACTS_DEFAULT_COMMIT"
fi
)
fi
if [ ! -f "$TOKEN_BRIDGE_LOCAL_DIR/node_modules/ts-node/dist/bin.js" ]; then
mkdir -p "$TOKEN_BRIDGE_LOCAL_DIR"
(
Expand All @@ -113,7 +137,9 @@ runs:
fi
base="$BASE_SNAPSHOT_ID_INPUT"
init_args=(--rebuild --capture-id "$base" --skip-post-capture-verify)
init_args+=(--nitro-contracts-version "$NITRO_CONTRACTS_VERSION_INPUT")
if [ -n "$FEE_TOKEN_DECIMALS_INPUT" ]; then
init_args+=(--fee-token-decimals "$FEE_TOKEN_DECIMALS_INPUT")
fi
for attempt in 1 2 3; do
if node apps/cli/dist/index.js init "${init_args[@]}" \
&& test -f "config/snapshots/$base/manifest.json"; then
Expand Down Expand Up @@ -143,5 +169,4 @@ runs:
--image-ref "${{ inputs.image-ref }}" \
--snapshot-id "${{ inputs.snapshot-id }}" \
--base-snapshot-id "${{ inputs.base-snapshot-id }}" \
--nitro-contracts-version "${{ inputs.nitro-contracts-version }}" \
${{ inputs.push == 'true' && '--push' || '' }}
38 changes: 0 additions & 38 deletions docker/contract-deployer-v2.1.Dockerfile

This file was deleted.

10 changes: 5 additions & 5 deletions docker/contract-deployer.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
FROM ghcr.io/foundry-rs/foundry:v1.3.1 AS foundry

# The caller must override this stage with
# `--build-context nitrocontracts=<local path or pinned Git context>`.
FROM scratch AS nitrocontracts

FROM node:20-trixie-slim AS nitro-builder

COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge
Expand All @@ -8,11 +12,7 @@ RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

WORKDIR /workspace/nitro-contracts

RUN git init . \
&& git remote add origin https://github.com/OffchainLabs/nitro-contracts.git \
&& git fetch --depth 1 origin cd4eb69e3c4cb87161b1433ad238902ea5c32ebd \
&& git checkout --detach FETCH_HEAD \
&& git submodule update --init --recursive --depth 1
COPY --from=nitrocontracts . /workspace/nitro-contracts

RUN cp scripts/config.example.ts scripts/config.ts
RUN yarn install --frozen-lockfile
Expand Down
14 changes: 6 additions & 8 deletions packages/action/test/action.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,12 @@ describe("bake action metadata", () => {
expect(action).not.toContain("OffchainLabs/arbitrum-testnode");
});

it("passes the selected Nitro contracts version to every rebuild init attempt", () => {
expect(action).toContain('default: "v3.2"');
expect(action).toContain(
"NITRO_CONTRACTS_VERSION_INPUT: ${{ inputs.nitro-contracts-version }}",
);
expect(action).toContain(
'init_args+=(--nitro-contracts-version "$NITRO_CONTRACTS_VERSION_INPUT")',
);
it("prepares the selected Nitro source without passing a version selector to init", () => {
expect(action).toContain('default: "v3.2.0"');
expect(action).toContain("NITRO_CONTRACTS_REF_INPUT: ${{ inputs.nitro-contracts-ref }}");
expect(action).toContain("NITRO_CONTRACTS_LOCAL_DIR: ${{ runner.temp }}/nitro-contracts");
expect(action).not.toContain("--nitro-contracts-version");
expect(action).not.toContain("--nitro-contracts-branch");
expect(action).toContain('node apps/cli/dist/index.js init "${init_args[@]}"');
});
});
Expand Down
Loading
Loading