Skip to content
Draft
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
15 changes: 15 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,25 @@ jobs:
test-integration-anvil:
name: Test (Integration Anvil)
runs-on: ubuntu-latest
env:
NITRO_CONTRACTS_IMAGE_REF: v3.2.0-2f747c7
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build nitro contracts image
uses: docker/build-push-action@v6
with:
context: ./nitro-contracts
file: ./nitro-contracts/Dockerfile
tags: chain-sdk-nitro-contracts:${{ env.NITRO_CONTRACTS_IMAGE_REF }}
load: true
cache-from: type=gha,scope=chain-sdk-nitro-contracts-${{ env.NITRO_CONTRACTS_IMAGE_REF }}
cache-to: type=gha,mode=max,scope=chain-sdk-nitro-contracts-${{ env.NITRO_CONTRACTS_IMAGE_REF }}

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
Expand Down
30 changes: 27 additions & 3 deletions nitro-contracts/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
FROM ghcr.io/foundry-rs/foundry:v1.3.1 AS foundry

FROM node:20-bullseye-slim
FROM node:20-bullseye-slim AS builder

ARG NITRO_CONTRACTS_REPO_URL=https://github.com/OffchainLabs/nitro-contracts.git
ARG NITRO_CONTRACTS_GIT_COMMIT=2f747c722d98d5fd662bfda08cd86aa534b22be2

COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

WORKDIR /workspace
COPY . /workspace

RUN git init . \
&& git remote add origin "${NITRO_CONTRACTS_REPO_URL}" \
&& git fetch --depth 1 origin "${NITRO_CONTRACTS_GIT_COMMIT}" \
&& git checkout --detach FETCH_HEAD \
&& git submodule update --init --recursive --depth 1

RUN cp scripts/config.example.ts scripts/config.ts
RUN yarn install
RUN yarn install --frozen-lockfile
RUN yarn build:all

FROM node:20-bullseye-slim

WORKDIR /workspace
COPY --from=builder /workspace/package.json /workspace/package.json
COPY --from=builder /workspace/yarn.lock /workspace/yarn.lock
COPY --from=builder /workspace/hardhat.config.ts /workspace/hardhat.config.ts
COPY --from=builder /workspace/tsconfig.json /workspace/tsconfig.json
COPY --from=builder /workspace/scripts /workspace/scripts
COPY --from=builder /workspace/test/contract /workspace/test/contract
COPY --from=builder /workspace/build /workspace/build
COPY --from=builder /workspace/out /workspace/out
COPY --from=builder /workspace/node_modules /workspace/node_modules

ENTRYPOINT ["yarn"]
15 changes: 8 additions & 7 deletions src/integrationTestHelpers/anvilHarness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import {
cleanupCurrentHarnessResources,
cleanupStaleHarnessContainers,
cleanupStaleHarnessNetworks,
createSourceDockerNetwork,
startSourceL1AnvilContainer,
startSourceL2NitroContainer,
createDockerNetwork,
startL1AnvilContainer,
startL2NitroContainer,
waitForRpc,
} from './dockerHelpers';
import {
Expand Down Expand Up @@ -105,7 +105,7 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
runtimeDir = mkdtempSync(join(tmpdir(), 'chain-sdk-int-test'));
prepareNitroRuntimeDir(runtimeDir);
dockerNetworkName = `chain-sdk-int-test-net-${Date.now()}`;
createSourceDockerNetwork(dockerNetworkName);
createDockerNetwork(dockerNetworkName);

const l2ChainId = testConstants.DEFAULT_L2_CHAIN_ID;
const l1RpcPort = testConstants.DEFAULT_L1_RPC_PORT;
Expand Down Expand Up @@ -143,7 +143,7 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
l1ContainerName = `chain-sdk-int-test-l1-${Date.now()}`;
console.log('Starting L1 Anvil node...');

startSourceL1AnvilContainer({
startL1AnvilContainer({
containerName: l1ContainerName,
networkName: dockerNetworkName,
l1RpcPort,
Expand Down Expand Up @@ -225,16 +225,17 @@ export async function setupAnvilTestStack(): Promise<AnvilTestStack> {
if (l2ChainConfig.arbitrum.DataAvailabilityCommittee) {
delete l2NodeConfig.node?.['data-availability']?.['rpc-aggregator'];
}

l2NodeConfig.node!['batch-poster']!.enable = false;
l2NodeConfig.node!.staker!.enable = false;
const nodeConfigPath = join(runtimeDir, 'source-l2-node-config.json');
const nodeConfigPath = join(runtimeDir, 'l2-node-config.json');
writeFileSync(nodeConfigPath, JSON.stringify(l2NodeConfig, null, 2), { mode: 0o644 });

// Starting L2 node (Nitro)
console.log('Starting L2 Nitro node...');
l2ContainerName = `chain-sdk-int-test-l2-${Date.now()}`;

startSourceL2NitroContainer({
startL2NitroContainer({
containerName: l2ContainerName,
networkName: dockerNetworkName,
l2RpcPort,
Expand Down
5 changes: 4 additions & 1 deletion src/integrationTestHelpers/anvilHarnessHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ function getRollupCreatorDockerArgs(
'-e',
'IGNORE_MAX_DATA_SIZE_WARNING=true',
nitroContractsImage,
'deploy-factory',
'hardhat',
'run',
'--no-compile',
'scripts/deployment.ts',
'--network',
'custom',
];
Expand Down
4 changes: 1 addition & 3 deletions src/integrationTestHelpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { ethers } from 'ethers';
export const testConstants = {
DEFAULT_ANVIL_IMAGE: 'ghcr.io/foundry-rs/foundry:v1.3.1',
DEFAULT_NITRO_IMAGE: 'offchainlabs/nitro-node:v3.9.5-66e42c4',
DEFAULT_NITRO_CONTRACTS_REF: 'v3.2.0',
DEFAULT_NITRO_CONTRACTS_REPO_URL: 'https://github.com/OffchainLabs/nitro-contracts.git',
DEFAULT_NITRO_CONTRACTS_BRANCH: 'feat/add-polling-interval',
DEFAULT_NITRO_CONTRACTS_REF: 'v3.2.0-2f747c7',
DEFAULT_L2_CHAIN_ID: 421_337,
DEFAULT_L1_RPC_PORT: 9645,
DEFAULT_L2_RPC_PORT: 8747,
Expand Down
41 changes: 7 additions & 34 deletions src/integrationTestHelpers/dockerHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { execFile, execFileSync } from 'node:child_process';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { rmSync } from 'node:fs';
import { join } from 'node:path';

import { createPublicClient, http } from 'viem';

import { testConstants } from './constants';

const cachedNitroContractsImageByTag: Record<string, string> = {};

function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Expand Down Expand Up @@ -47,43 +44,19 @@ export function getNitroContractsImage(): string {
const imageTag = `chain-sdk-nitro-contracts:${sanitizeDockerTagPart(
testConstants.DEFAULT_NITRO_CONTRACTS_REF,
)}`;
const cachedImage = cachedNitroContractsImageByTag[imageTag];
if (cachedImage) {
return cachedImage;
}

try {
docker(['image', 'inspect', imageTag]);
} catch {
const tempDir = mkdtempSync(join(tmpdir(), 'chain-sdk-nitro-contracts-'));
const repoDir = join(tempDir, 'repo');
const nitroContractsDir = join(process.cwd(), 'nitro-contracts');
const dockerfilePath = join(process.cwd(), 'nitro-contracts', 'Dockerfile');

try {
runCommand('git', [
'clone',
'--recurse-submodules',
'--shallow-submodules',
'--depth',
'1',
'--branch',
testConstants.DEFAULT_NITRO_CONTRACTS_BRANCH,
'--single-branch',
testConstants.DEFAULT_NITRO_CONTRACTS_REPO_URL,
repoDir,
]);

docker(['build', '-f', dockerfilePath, '-t', imageTag, repoDir]);
} finally {
rmSync(tempDir, { recursive: true, force: true });
}
docker(['build', '-f', dockerfilePath, '-t', imageTag, nitroContractsDir]);
}

cachedNitroContractsImageByTag[imageTag] = imageTag;
return imageTag;
}

export function createSourceDockerNetwork(networkName: string) {
export function createDockerNetwork(networkName: string) {
docker(['network', 'create', networkName]);
}

Expand Down Expand Up @@ -237,7 +210,7 @@ export function cleanupStaleHarnessNetworks() {
}
}

export function startSourceL1AnvilContainer(params: {
export function startL1AnvilContainer(params: {
containerName: string;
networkName: string;
l1RpcPort: number;
Expand Down Expand Up @@ -275,7 +248,7 @@ export function startSourceL1AnvilContainer(params: {
]);
}

export function startSourceL2NitroContainer(params: {
export function startL2NitroContainer(params: {
containerName: string;
networkName: string;
l2RpcPort: number;
Expand All @@ -295,7 +268,7 @@ export function startSourceL2NitroContainer(params: {
`${params.runtimeDir}:/runtime`,
params.nitroImage,
'--conf.file',
'/runtime/source-l2-node-config.json',
'/runtime/l2-node-config.json',
'--persistent.chain',
'/runtime/nitro-data',
'--ensure-rollup-deployment=false',
Expand Down
Loading