diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e92712a6..cb74a23a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - master - develop - release - # run this job on the default branch daily + # run this job on the default branch (release) daily # the docker compose file contains some images with tags like 'latest' and 'stable' # we nightly run here just to double check no bugs have been merged into those tags and are now on release schedule: @@ -20,6 +20,7 @@ jobs: build_and_run: runs-on: ubuntu-8 strategy: + fail-fast: false matrix: pos: [pos, no-pos] l3node: [l3node, l3node-token-6, no-l3node] @@ -46,20 +47,3 @@ jobs: - name: Startup Nitro testnode run: ${{ github.workspace }}/.github/workflows/testnode.bash --init-force ${{ (matrix.l3node == 'l3node' && '--l3node') || (matrix.l3node == 'l3node-token-6' && '--l3node --l3-fee-token --l3-token-bridge --l3-fee-token-decimals 6') || '' }} ${{ matrix.tokenbridge == 'tokenbridge' && '--tokenbridge' || '--no-tokenbridge' }} --detach ${{ matrix.pos == 'pos' && '--pos' || '' }} --simple ${{ (matrix.simple == 'simple' && '--simple') || (matrix.simple == 'no-simple' && '--no-simple') || '' }} - - bold_upgrade: - runs-on: ubuntu-8 - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host - - - name: Startup Nitro testnode - run: ${{ github.workspace }}/.github/workflows/testnode.bash --init-force --bold-upgrade --simple --detach diff --git a/boldupgrader/Dockerfile b/boldupgrader/Dockerfile deleted file mode 100644 index 72bab80a..00000000 --- a/boldupgrader/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:20-bookworm-slim -RUN apt-get update && \ - apt-get install -y git docker.io python3 make gcc g++ curl jq -ARG BOLD_CONTRACTS_BRANCH=bold-merge-script -WORKDIR /workspace -RUN git clone --no-checkout https://github.com/OffchainLabs/nitro-contracts.git ./ -RUN git checkout ${BOLD_CONTRACTS_BRANCH} -RUN yarn install && yarn cache clean -RUN curl -L https://foundry.paradigm.xyz | bash -ENV PATH="${PATH}:/root/.foundry/bin" -RUN foundryup --install 1.0.0 -RUN touch scripts/config.ts -RUN yarn build:all -ENTRYPOINT ["yarn"] \ No newline at end of file diff --git a/docker-compose-ci-cache.json b/docker-compose-ci-cache.json index 8a9dacb6..0fee603d 100644 --- a/docker-compose-ci-cache.json +++ b/docker-compose-ci-cache.json @@ -22,17 +22,6 @@ "type=docker" ] }, - "boldupgrader": { - "cache-from": [ - "type=local,src=/tmp/.buildx-cache" - ], - "cache-to": [ - "type=local,dest=/tmp/.buildx-cache,mode=max" - ], - "output": [ - "type=docker" - ] - }, "tokenbridge": { "cache-from": [ "type=local,src=/tmp/.buildx-cache" diff --git a/docker-compose.yaml b/docker-compose.yaml index 2ec63237..7584f141 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -47,7 +47,7 @@ services: - "127.0.0.1:6379:6379" geth: - image: ethereum/client-go:stable + image: ethereum/client-go:v1.14.13 ports: - "127.0.0.1:8545:8545" - "127.0.0.1:8551:8551" @@ -370,26 +370,6 @@ services: - "tokenbridge-data:/workspace" - /var/run/docker.sock:/var/run/docker.sock - boldupgrader: - depends_on: - - geth - - sequencer - pid: host - build: - context: boldupgrader/ - args: - BOLD_CONTRACTS_BRANCH: ${BOLD_CONTRACTS_BRANCH:-} - environment: - - L1_RPC_URL=http://geth:8545 - - L1_PRIV_KEY=0xdc04c5399f82306ec4b4d654a342f40e2e0620fe39950d967e1e574b32d4dd36 - - CONFIG_NETWORK_NAME=local - - DEPLOYED_CONTRACTS_DIR=./scripts/files/ - - DISABLE_VERIFICATION=true - volumes: - - "config:/config" - - "boldupgrader-data:/workspace" - - /var/run/docker.sock:/var/run/docker.sock - rollupcreator: depends_on: - geth @@ -502,4 +482,3 @@ volumes: das-committee-b-data: das-mirror-data: timeboost-auctioneer-data: - boldupgrader-data: diff --git a/rollupcreator/Dockerfile b/rollupcreator/Dockerfile index 59d56a5a..8e93229d 100644 --- a/rollupcreator/Dockerfile +++ b/rollupcreator/Dockerfile @@ -5,6 +5,7 @@ ARG NITRO_CONTRACTS_BRANCH=main WORKDIR /workspace RUN git clone --no-checkout https://github.com/OffchainLabs/nitro-contracts.git ./ RUN git checkout ${NITRO_CONTRACTS_BRANCH} +RUN git submodule update --init --recursive RUN yarn install && yarn cache clean RUN curl -L https://foundry.paradigm.xyz | bash ENV PATH="${PATH}:/root/.foundry/bin" diff --git a/scripts/config.ts b/scripts/config.ts index 33cde21a..097c8234 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -198,6 +198,11 @@ function writeConfigs(argv: any) { "info-files": [chainInfoFile], }, "node": { + "bold": { + "rpc-block-number": "latest", + "strategy": "makeNodes", + "assertion-posting-interval": "10s" + }, "staker": { "dangerous": { "without-block-validator": false @@ -292,7 +297,7 @@ function writeConfigs(argv: any) { if (argv.simple) { let simpleConfig = JSON.parse(baseConfJSON) simpleConfig.node.staker.enable = true - simpleConfig.node.staker["use-smart-contract-wallet"] = true + simpleConfig.node.staker["use-smart-contract-wallet"] = false // TODO: set to true when fixed simpleConfig.node.staker.dangerous["without-block-validator"] = true simpleConfig.node.sequencer = true simpleConfig.node.dangerous["no-sequencer-coordinator"] = true @@ -307,7 +312,7 @@ function writeConfigs(argv: any) { } else { let validatorConfig = JSON.parse(baseConfJSON) validatorConfig.node.staker.enable = true - validatorConfig.node.staker["use-smart-contract-wallet"] = true + validatorConfig.node.staker["use-smart-contract-wallet"] = false // TODO: set to true when fixed let validconfJSON = JSON.stringify(validatorConfig) fs.writeFileSync(path.join(consts.configpath, "validator_config.json"), validconfJSON) @@ -340,13 +345,14 @@ function writeConfigs(argv: any) { let l3Config = JSON.parse(baseConfJSON) l3Config["parent-chain"].connection.url = argv.l2url - l3Config.node.staker["parent-chain-wallet"].account = namedAddress("l3owner") + // use the same account for l2 and l3 staker + // l3Config.node.staker["parent-chain-wallet"].account = namedAddress("l3owner") l3Config.node["batch-poster"]["parent-chain-wallet"].account = namedAddress("l3sequencer") l3Config.chain.id = 333333 const l3ChainInfoFile = path.join(consts.configpath, "l3_chain_info.json") l3Config.chain["info-files"] = [l3ChainInfoFile] l3Config.node.staker.enable = true - l3Config.node.staker["use-smart-contract-wallet"] = true + l3Config.node.staker["use-smart-contract-wallet"] = false // TODO: set to true when fixed l3Config.node.sequencer = true l3Config.execution["sequencer"].enable = true l3Config.node["dangerous"]["no-sequencer-coordinator"] = true @@ -436,7 +442,7 @@ function writeL3ChainConfig(argv: any) { "EnableArbOS": true, "AllowDebugPrecompiles": true, "DataAvailabilityCommittee": false, - "InitialArbOSVersion": 31, + "InitialArbOSVersion": 32, "InitialChainOwner": argv.l2owner, "GenesisBlockNum": 0 } diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index 27984cb5..bf54d384 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -10,6 +10,8 @@ import * as fs from "fs"; import { ARB_OWNER } from "./consts"; import * as TransparentUpgradeableProxy from "@openzeppelin/contracts/build/contracts/TransparentUpgradeableProxy.json" import * as ExpressLaneAuctionContract from "@arbitrum/nitro-contracts/build/contracts/src/express-lane-auction/ExpressLaneAuction.sol/ExpressLaneAuction.json" +import * as StylusDeployerContract from "@arbitrum/nitro-contracts/build/contracts/src/stylus/StylusDeployer.sol/StylusDeployer.json" + const path = require("path"); async function sendTransaction(argv: any, threadId: number) { @@ -185,6 +187,36 @@ async function deployWETHContract(deployerWallet: Wallet): Promise { return weth.address; } +async function createStylusDeployer(deployerWallet: Wallet): Promise { + // this factory should be deployed by the rollupcreator when deploy helper is used + const create2factory = '0x4e59b44847b379578588920ca78fbf26c0b4956c' + if (await deployerWallet.provider.getCode(create2factory) === '0x') { + // wait for 30 seconds, check again before throwing an error + await new Promise(resolve => setTimeout(resolve, 30000)); + if (await deployerWallet.provider.getCode(create2factory) === '0x') { + throw new Error('Create2 factory not yet deployed') + } + } + + const salt = ethers.constants.HashZero + const stylusDeployerBytecode = StylusDeployerContract.bytecode + const stylusDeployerAddress = ethers.utils.getCreate2Address(create2factory, salt, ethers.utils.keccak256(stylusDeployerBytecode)) + + // check if the address is already deployed + const code = await deployerWallet.provider.getCode(stylusDeployerAddress) + if (code !== '0x') { + console.log("Stylus deployer already deployed") + } else { + const stylusDeployerTx = await deployerWallet.sendTransaction({ + to: create2factory, + data: ethers.utils.concat([salt, stylusDeployerBytecode]) + }) + await stylusDeployerTx.wait() + } + + return stylusDeployerAddress +} + export const bridgeFundsCommand = { command: "bridge-funds", describe: "sends funds from l1 to l2", @@ -593,6 +625,30 @@ export const createWETHCommand = { }, }; +export const createStylusDeployerCommand = { + command: "create-stylus-deployer", + describe: "deploys the stylus deployer contract", + builder: { + deployer: { string: true, describe: "account (see general help)" }, + l3: { boolean: false, describe: "deploy on L3, otherwise deploy on L2" }, + }, + handler: async (argv: any) => { + console.log("create-stylus-deployer"); + + const provider = new ethers.providers.WebSocketProvider(argv.l3 ? argv.l3url : argv.l2url); + const deployerWallet = namedAccount(argv.deployer).connect(provider); + + const stylusDeployerAddress = await createStylusDeployer(deployerWallet); + if (argv.l3) { + console.log("Stylus deployer deployed at L3 address:", stylusDeployerAddress); + } else { + console.log("Stylus deployer deployed at L2 address:", stylusDeployerAddress); + } + + provider.destroy(); + } +}; + export const sendL1Command = { command: "send-l1", describe: "sends funds between l1 accounts", diff --git a/scripts/index.ts b/scripts/index.ts index 55a85b7b..a16b7e15 100644 --- a/scripts/index.ts +++ b/scripts/index.ts @@ -26,6 +26,7 @@ import { createERC20Command, deployExpressLaneAuctionContractCommand, createWETHCommand, + createStylusDeployerCommand, transferERC20Command, sendL1Command, sendL2Command, @@ -56,6 +57,7 @@ async function main() { .command(createFeeTokenPricerCommand) .command(deployExpressLaneAuctionContractCommand) .command(createWETHCommand) + .command(createStylusDeployerCommand) .command(transferERC20Command) .command(sendL1Command) .command(sendL2Command) diff --git a/scripts/package.json b/scripts/package.json index c2dc9db9..9a5885d9 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -6,7 +6,7 @@ "author": "Offchain Labs, Inc.", "license": "Apache-2.0", "dependencies": { - "@arbitrum/nitro-contracts": "^2.1.1", + "@arbitrum/nitro-contracts": "^3.1.1", "@arbitrum/token-bridge-contracts": "1.2.0", "@node-redis/client": "^1.0.4", "@openzeppelin/contracts": "^4.9.3", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 26f86656..5ec812cc 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -19,6 +19,17 @@ optionalDependencies: sol2uml "2.2.0" +"@arbitrum/nitro-contracts@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@arbitrum/nitro-contracts/-/nitro-contracts-3.1.1.tgz#f2efac5329e3f187ade998bbbbad93070e2e90a3" + integrity sha512-30s5ocUZbDx22MybngvO7WZtCgYoPYmkHnnBl07FZnN3gOv+oy4WQB0Ln2QG4aBzPp6hCg76Yw9mQJDN/+OkCg== + dependencies: + "@offchainlabs/upgrade-executor" "1.1.0-beta.0" + "@openzeppelin/contracts" "4.7.3" + "@openzeppelin/contracts-upgradeable" "4.7.3" + patch-package "^6.5.1" + solady "0.0.182" + "@arbitrum/token-bridge-contracts@1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@arbitrum/token-bridge-contracts/-/token-bridge-contracts-1.2.0.tgz#b1dc02e123393848d0d8e5c167028bafa0ac8229" @@ -2198,7 +2209,7 @@ parse5@^7.0.0: dependencies: entities "^4.4.0" -patch-package@^6.4.7: +patch-package@^6.4.7, patch-package@^6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621" integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA== @@ -2522,6 +2533,11 @@ sol2uml@2.2.0: js-graph-algorithms "^1.0.18" klaw "^4.0.1" +solady@0.0.182: + version "0.0.182" + resolved "https://registry.yarnpkg.com/solady/-/solady-0.0.182.tgz#bd8c47f128a3a752358ad052782773966d74c400" + integrity sha512-FW6xo1akJoYpkXMzu58/56FcNU3HYYNamEbnFO3iSibXk0nSHo0DV2Gu/zI3FPg3So5CCX6IYli1TT1IWATnvg== + solidity-ast@^0.4.51: version "0.4.55" resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.55.tgz#00b685e6eefb2e8dfb67df1fe0afbe3b3bfb4b28" diff --git a/test-node.bash b/test-node.bash index 67abdd0e..c7198e84 100755 --- a/test-node.bash +++ b/test-node.bash @@ -2,25 +2,22 @@ set -eu -NITRO_NODE_VERSION=offchainlabs/nitro-node:v3.5.5-90ee45c +NITRO_NODE_VERSION=offchainlabs/nitro-node:v3.6.5-89cef87 BLOCKSCOUT_VERSION=offchainlabs/blockscout:v1.1.0-0e716c8 -DEFAULT_NITRO_CONTRACTS_VERSION="v2.1.1-beta.0" +# nitro-contract workaround for testnode +# 1. authorizing validator signer key since validator wallet is buggy +# - gas estimation sent from 0x0000 lead to balance and permission error +DEFAULT_NITRO_CONTRACTS_VERSION="v3.1.0" DEFAULT_TOKEN_BRIDGE_VERSION="v1.2.2" -# The is the latest bold-merge commit in nitro-contracts at the time -DEFAULT_BOLD_CONTRACTS_VERSION="42d80e40" - # Set default versions if not overriden by provided env vars : ${NITRO_CONTRACTS_BRANCH:=$DEFAULT_NITRO_CONTRACTS_VERSION} -: ${BOLD_CONTRACTS_BRANCH:=$DEFAULT_BOLD_CONTRACTS_VERSION} : ${TOKEN_BRIDGE_BRANCH:=$DEFAULT_TOKEN_BRIDGE_VERSION} export NITRO_CONTRACTS_BRANCH -export BOLD_CONTRACTS_BRANCH export TOKEN_BRIDGE_BRANCH echo "Using NITRO_CONTRACTS_BRANCH: $NITRO_CONTRACTS_BRANCH" -echo "Using BOLD_CONTRACTS_BRANCH: $BOLD_CONTRACTS_BRANCH" echo "Using TOKEN_BRIDGE_BRANCH: $TOKEN_BRIDGE_BRANCH" mydir=`dirname $0` @@ -49,7 +46,6 @@ blockscout=false tokenbridge=false l3node=false consensusclient=false -boldupgrade=false redundantsequencers=0 l3_custom_fee_token=false l3_custom_fee_token_pricer=false @@ -217,10 +213,6 @@ while [[ $# -gt 0 ]]; do l1chainid=1337 shift ;; - --bold-upgrade) - boldupgrade=true - shift - ;; --l3node) l3node=true shift @@ -319,8 +311,8 @@ while [[ $# -gt 0 ]]; do echo --no-build-dev-nitro don\'t rebuild dev nitro docker image echo --build-dev-blockscout rebuild dev blockscout docker image echo --no-build-dev-blockscout don\'t rebuild dev blockscout docker image - echo --build-utils rebuild scripts, rollupcreator, boldupgrader, token bridge docker images - echo --no-build-utils don\'t rebuild scripts, rollupcreator, boldupgrader, token bridge docker images + echo --build-utils rebuild scripts, rollupcreator, token bridge docker images + echo --no-build-utils don\'t rebuild scripts, rollupcreator, token bridge docker images echo --force-build-utils force rebuilding utils, useful if NITRO_CONTRACTS_ or TOKEN_BRIDGE_BRANCH changes echo echo script runs inside a separate docker. For SCRIPT-ARGS, run $0 script --help @@ -392,14 +384,13 @@ if $dev_blockscout && $build_dev_blockscout; then fi if $build_utils; then - LOCAL_BUILD_NODES="scripts rollupcreator boldupgrader" + LOCAL_BUILD_NODES="scripts rollupcreator" # always build tokenbridge in CI mode to avoid caching issues if $tokenbridge || $l3_token_bridge || $ci; then LOCAL_BUILD_NODES="$LOCAL_BUILD_NODES tokenbridge" fi if [ "$ci" == true ]; then - # workaround to cache docker layers and keep using docker-compose in CI docker buildx bake --allow=fs=/tmp --file docker-compose.yaml --file docker-compose-ci-cache.json $LOCAL_BUILD_NODES else UTILS_NOCACHE="" @@ -482,7 +473,7 @@ if $force_init; then echo == create l1 traffic docker compose run scripts send-l1 --ethamount 1000 --to user_l1user --wait - docker compose run scripts send-l1 --ethamount 0.0001 --from user_l1user --to user_l1user_b --wait --delay 500 --times 1000000 > /dev/null & + docker compose run scripts send-l1 --ethamount 0.0001 --from user_l1user --to user_l1user --wait --delay 1000 --times 1000000 > /dev/null & l2ownerAddress=`docker compose run scripts print-address --account l2owner | tail -n 1 | tr -d '\r\n'` @@ -591,24 +582,17 @@ if $force_init; then echo == Deploy CacheManager on L2 docker compose run -e CHILD_CHAIN_RPC="http://sequencer:8547" -e CHAIN_OWNER_PRIVKEY=$l2ownerKey rollupcreator deploy-cachemanager-testnode - if $boldupgrade; then - echo == Deploying WETH as BOLD stake token - stakeTokenAddress=`docker compose run scripts create-weth --deployer l2owner --deposit 100 | tail -n 1 | awk '{ print $NF }'` - echo BOLD stake token address: $stakeTokenAddress - docker compose run scripts transfer-erc20 --token $stakeTokenAddress --l1 --amount 100 --from l2owner --to validator - echo == Preparing BOLD upgrade - docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-prepare - # retry this 10 times because the staker might not have made a node yet - for i in {1..10}; do - docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-populate-lookup && break || true - echo "Failed to populate lookup table, retrying..." - sleep 10 - done - docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-local-execute - fi + echo == Deploy Stylus Deployer on L2 + docker compose run scripts create-stylus-deployer --deployer l2owner + + # TODO: remove this once the gas estimation issue is fixed + echo == Gas Estimation workaround + docker compose run scripts send-l1 --ethamount 1 --to address_0x0000000000000000000000000000000000000000 --wait + docker compose run scripts send-l2 --ethamount 1 --to address_0x0000000000000000000000000000000000000000 --wait if $l3node; then echo == Funding l3 users + docker compose run scripts send-l2 --ethamount 1000 --to validator --wait docker compose run scripts send-l2 --ethamount 1000 --to l3owner --wait docker compose run scripts send-l2 --ethamount 1000 --to l3sequencer --wait @@ -622,7 +606,7 @@ if $force_init; then echo == create l2 traffic docker compose run scripts send-l2 --ethamount 100 --to user_traffic_generator --wait - docker compose run scripts send-l2 --ethamount 0.0001 --from user_traffic_generator --to user_fee_token_deployer --wait --delay 500 --times 1000000 > /dev/null & + docker compose run scripts send-l2 --ethamount 0.0001 --from user_traffic_generator --to user_traffic_generator --wait --delay 500 --times 1000000 > /dev/null & echo == Writing l3 chain config l3owneraddress=`docker compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` @@ -685,6 +669,12 @@ if $force_init; then echo == Deploy CacheManager on L3 docker compose run -e CHILD_CHAIN_RPC="http://l3node:3347" -e CHAIN_OWNER_PRIVKEY=$l3ownerkey rollupcreator deploy-cachemanager-testnode + echo == Deploy Stylus Deployer on L3 + docker compose run scripts create-stylus-deployer --deployer l3owner --l3 + + echo == create l3 traffic + docker compose run scripts send-l3 --ethamount 10 --to user_traffic_generator --wait + docker compose run scripts send-l3 --ethamount 0.0001 --from user_traffic_generator --to user_traffic_generator --wait --delay 5000 --times 1000000 > /dev/null & fi fi diff --git a/tokenbridge/Dockerfile b/tokenbridge/Dockerfile index 475a68a6..785dfb5a 100644 --- a/tokenbridge/Dockerfile +++ b/tokenbridge/Dockerfile @@ -5,6 +5,7 @@ ARG TOKEN_BRIDGE_BRANCH=main WORKDIR /workspace RUN git clone --no-checkout https://github.com/OffchainLabs/token-bridge-contracts.git ./ && \ git checkout ${TOKEN_BRIDGE_BRANCH} && \ + git submodule update --init --recursive && \ rm -rf .git && \ git init && git add . && git -c user.name="user" -c user.email="user@example.com" commit -m "Initial commit" RUN yarn install && yarn cache clean