From 3e63a47803c8e236fc2068b5eb01b999a9793cc9 Mon Sep 17 00:00:00 2001 From: geoknee Date: Mon, 2 Sep 2024 11:06:57 +0100 Subject: [PATCH] Squashed commit of the following: commit cbc662a48a979f43e8676687002b65a9963450b0 Merge: 37872112 70e9dbc1 Author: geoknee Date: Fri Aug 30 16:18:49 2024 +0100 Merge remote-tracking branch 'origin/main' into gk/gen-val-met commit 37872112bab558d4015fe7b6ffd1066468e2f7cc Author: George Knee Date: Fri Aug 30 15:40:42 2024 +0100 remove temporarily added chains (#535) * git restore --source=main -- superchain * just codegen * just lint-all * lint * typo commit 7d3ed211f19848ed6cc469ea9c390bda0b88d4d2 Author: George Knee Date: Fri Aug 30 15:06:02 2024 +0100 use dynamic config building in CI (#534) * use dynamic config building in CI This works by having a small workflow run, compute the list of chain ids to run genesis validation checks on, and then modify a subsequent config file which circleci then runs. * add comment * fan in * fix * fix script * Update .circleci/continue_config.yml Co-authored-by: Vinod Damle --------- Co-authored-by: Vinod Damle commit c7e50fe92fa899625eff2d26d1d01e006b01a7ef Author: geoknee Date: Fri Aug 30 11:24:10 2024 +0100 add testGenesisAllocsMetadata commit fa01d6bd8b5f5769478db8a0085d72768ef1daca Author: geoknee Date: Fri Aug 30 11:01:45 2024 +0100 rename commands commit b8ba6a4822f0720fd22c40b8bc94bc63b3d93da7 Author: geoknee Date: Fri Aug 30 11:00:37 2024 +0100 rename test commit 6fafbe40d6d2eccb8386f6707f3d5f3f554582db Author: geoknee Date: Thu Aug 29 23:11:24 2024 +0100 tidy up test script commit b3fcdb2e5a68b60d8d7c095cb0d77af367eedd53 Author: geoknee Date: Thu Aug 29 22:57:02 2024 +0100 remove temporary directory after tests run commit 4cbf38962f79c7d2c5fa752cbf6e00a553267c28 Author: geoknee Date: Thu Aug 29 22:50:08 2024 +0100 dedupe perChainTestName commit 4ebaafc7bd795d2575c4acf9f5e1e7809bbdf2f4 Author: geoknee Date: Thu Aug 29 22:28:25 2024 +0100 improve naming of ci steps commit 732260c53c9a052a83005f2155c7c4e01262e264 Author: geoknee Date: Thu Aug 29 18:39:19 2024 +0100 harmonize op-geth version commit ae24ca104e2b85e761fbc03d5767a04caa26541c Author: geoknee Date: Thu Aug 29 18:36:42 2024 +0100 just tidy-all commit 46c9ec1aa9b3cbe81b1f54d5577e62fae91bf844 Merge: b01525bb 936d40bc Author: geoknee Date: Thu Aug 29 18:36:21 2024 +0100 Merge remote-tracking branch 'origin/main' into gk/gen-val-met commit b01525bb42547758f2205aa50dbe35b66334a2c3 Author: George Knee Date: Thu Aug 29 18:33:39 2024 +0100 Get genesis validation checks to run on CI (#529) * switch to cimg/go:1.22.6-node docker image for genesis validation * remove set -e (nvm.sh exits with code 3, we can apparently just ignore that) * use bash instead of sh * use . instead of source * install pnpm * move optimism-temporary out from under superchain-registry this seems to make go module resolution work as expected * do not allow validate-genesis to timeout * improve pipefail behaviour we allow the scripts which load nvm and gvm to fail * just lint-all * remove all set -e behaviour gives highest chance that validation can succeed * stream output from test helps with debugging, prevents timeouts on circleci * try running as a matrix * add base and base sepolia to genesis validation list (#530) * add base sepolia to genesis validation list * add base mainnet to genesis validation list * Add validation metadata for Lisk mainnet + testnet (#531) * temp: gk/genadd lisk mainnet (revertme) * add lisk metadata for genesis validation * temp: add lisk sepolia (revertme) * add genesis validation metadata for lisk sepolia * Update .circleci/config.yml * add comment commit 1365e25e000a0b666b6f8bbe47fef2d4bc0db2b6 Author: George Knee Date: Wed Aug 28 12:19:48 2024 +0100 use localised, gitignored optimism-temporary directory for genesis validation purposes (#507) commit 679330925e3a3d8910dfef950c6ad824fdd921d0 Author: George Knee Date: Sat Aug 24 17:32:53 2024 +0100 Enhance `add-chain` tool to capture deploy config and monorep commit information (#504) * add-chain: ingest and store deploy-config and genesis-creation commit * remove genesis-system-configs dir we no longer use this * add test data for deploy-config * check errs properly * link validation to add-chain * fix up add-chain e2e tests * simplify test side effect handling * don't bother cleaning up -test genesis validation inputs (They now don't end up bound into the validation package) * tweak spacing * prefer os.ModePerm over 0o777 * typo * typo * remove unused params * use commented constants for metadata defaults * fix clean-add-chain cmd commit bae89c01e60fe011be99c14d62d45c6d3dafccad Author: George Knee Date: Thu Aug 22 13:35:38 2024 +0100 Get mode, metal and zora genesis.allocs validation working (#496) * introduce node_version need to reexamine writeDeploymentsLegacy * fix bug in writeDeploymentsLegacy * fix declaration of legacy deployments and add note * improve diff * use hardhat Deployment type to pad data and avoid unmarshaling errors e.g. on mode * fix writeDeploymentsLegacy, mode now validates! * remove note * introduce GenesisCreationCommand mapping allows metadata file to choose from a list and have chainId automatically injected into command * introduce BuilldCommand mapping * op sepolia validates * remove UseLegacyDeploymentsFormat * remove op mainnet metadata for now * remove op sepolia (it doesn't validate yet) * echo nvm version * just codegen * load nvm * fix * try installing nvm in a step * require node_version to be set * just lint-all * attempt to patch genesis creation source code to make validation work at a wider range of commits * adds metal metadata -- validates! * add zora metadata -- validates! commit 11982b88afa953f68298164f0c2466c417825458 Author: geoknee Date: Tue Aug 20 13:33:49 2024 +0100 introduce boolean switch for using legacy deployments format commit 96b1810e97a3b5e9c152187f2c7f2ba3892bfbc0 Author: geoknee Date: Tue Aug 20 13:29:39 2024 +0100 linting commit 6dbc88ee7ae2a4d07da95dfa259552c9c9e427e0 Author: geoknee Date: Tue Aug 20 13:28:14 2024 +0100 no need to install just commit e28ca59531e3e8400f40968755ca563cb8d1e75b Author: geoknee Date: Tue Aug 20 13:26:47 2024 +0100 install nvm commit ab4ceba13aa2cbd4259e4fa6f58b1bac0d2c93fc Author: geoknee Date: Tue Aug 20 13:22:38 2024 +0100 try removing source command commit f5de7e704cf858067c7d4d57bcdeba84a4b6998c Author: geoknee Date: Tue Aug 20 13:14:32 2024 +0100 introduce monorepoBuildCommand artifact commit 0516b9e361db4716a2fae298da6ced736b4cc3bb Author: geoknee Date: Tue Aug 20 13:03:17 2024 +0100 4801 passes commit d1fbbaa1074d7c0fe6c12567219b3046cfc87762 Author: geoknee Date: Tue Aug 20 13:01:19 2024 +0100 add nvm commit ab1b6e8f254fbf08ae26d7c4e88ba78ac93dd898 Author: geoknee Date: Tue Aug 20 12:46:50 2024 +0100 change format of genesis creation command commit ccbe3dad61dc4113c74eea167b02203ae949255f Author: geoknee Date: Tue Aug 20 12:00:38 2024 +0100 some small fixes chain 480 passes! commit 65a80dd056ef095cae880541638244e6ff62f82f Author: geoknee Date: Tue Aug 20 11:38:47 2024 +0100 add worldchain commit d1aa9453a2a856eadb410c2c793891738992853c Author: geoknee Date: Tue Aug 20 11:29:17 2024 +0100 add sepolia/worldcoin commit 4b4ab94ae9837d2b2f90b501e8b709fb6c0fcbbc Author: geoknee Date: Tue Aug 20 11:24:05 2024 +0100 fix ci config commit 858d754b8ec46e9fbd03943d117c6c4fc88e64a0 Author: geoknee Date: Mon Aug 19 19:27:47 2024 +0100 undo accidental changes commit f99b39639a5b8e8b4007215b6e383fe477df2110 Author: geoknee Date: Mon Aug 19 19:21:40 2024 +0100 add genesis predeploy test, validation metadata for chains 10,34443 and wire up commit 5ec1a6fdd28dfe8b3ed101b27fefff4b71f05582 Author: geoknee Date: Mon Aug 19 17:49:46 2024 +0100 fix go.work version declaration --- .circleci/continue-config.yml | 235 +-------------- .circleci/continue_config.yml | 278 ++++++++++++++++++ .env.example | 9 +- add-chain/e2e_test.go | 7 +- add-chain/flags/flags.go | 12 + add-chain/go.mod | 3 + add-chain/main.go | 62 +++- add-chain/testdata/.env.test | 2 + .../monorepo/deploy-config/sepolia.json | 41 +++ bindings/rust-bindings/etc/configs.toml | 112 +++++++ go.work | 2 +- justfile | 6 +- validation/.gitignore | 5 +- validation/common/common.go | 12 + validation/genesis-allocs_test.go | 21 ++ validation/genesis/commands.go | 42 +++ validation/genesis/config.patch | 13 + validation/genesis/foundry-config.patch | 13 + validation/genesis/genesis-allocs_test.go | 171 +++++++++++ validation/genesis/genesis.go | 63 ++++ validation/genesis/monorepo-outputs.sh | 20 ++ validation/genesis/utils.go | 151 ++++++++++ .../validation-inputs/1135/deploy-config.json | 59 ++++ .../genesis/validation-inputs/1135/meta.toml | 4 + .../validation-inputs/1750/deploy-config.json | 56 ++++ .../genesis/validation-inputs/1750/meta.toml | 4 + .../34443/deploy-config.json | 50 ++++ .../genesis/validation-inputs/34443/meta.toml | 4 + .../validation-inputs/4202/deploy-config.json | 46 +++ .../genesis/validation-inputs/4202/meta.toml | 4 + .../validation-inputs/480/deploy-config.json | 71 +++++ .../genesis/validation-inputs/480/meta.toml | 4 + .../validation-inputs/4801/deploy-config.json | 71 +++++ .../genesis/validation-inputs/4801/meta.toml | 4 + .../7777777/deploy-config.json | 43 +++ .../validation-inputs/7777777/meta.toml | 4 + .../validation-inputs/8453/deploy-config.json | 42 +++ .../genesis/validation-inputs/8453/meta.toml | 4 + .../84532/deploy-config.json | 44 +++ .../genesis/validation-inputs/84532/meta.toml | 4 + .../validation-inputs/generate-test-config.sh | 42 +++ validation/promotion_test.go | 3 +- validation/utils_test.go | 6 - validation/validation_test.go | 5 +- 44 files changed, 1618 insertions(+), 236 deletions(-) create mode 100644 .circleci/continue_config.yml create mode 100644 add-chain/testdata/monorepo/deploy-config/sepolia.json create mode 100644 validation/common/common.go create mode 100644 validation/genesis-allocs_test.go create mode 100644 validation/genesis/commands.go create mode 100644 validation/genesis/config.patch create mode 100644 validation/genesis/foundry-config.patch create mode 100644 validation/genesis/genesis-allocs_test.go create mode 100644 validation/genesis/genesis.go create mode 100755 validation/genesis/monorepo-outputs.sh create mode 100644 validation/genesis/utils.go create mode 100644 validation/genesis/validation-inputs/1135/deploy-config.json create mode 100644 validation/genesis/validation-inputs/1135/meta.toml create mode 100644 validation/genesis/validation-inputs/1750/deploy-config.json create mode 100644 validation/genesis/validation-inputs/1750/meta.toml create mode 100644 validation/genesis/validation-inputs/34443/deploy-config.json create mode 100644 validation/genesis/validation-inputs/34443/meta.toml create mode 100644 validation/genesis/validation-inputs/4202/deploy-config.json create mode 100644 validation/genesis/validation-inputs/4202/meta.toml create mode 100644 validation/genesis/validation-inputs/480/deploy-config.json create mode 100644 validation/genesis/validation-inputs/480/meta.toml create mode 100644 validation/genesis/validation-inputs/4801/deploy-config.json create mode 100644 validation/genesis/validation-inputs/4801/meta.toml create mode 100644 validation/genesis/validation-inputs/7777777/deploy-config.json create mode 100644 validation/genesis/validation-inputs/7777777/meta.toml create mode 100644 validation/genesis/validation-inputs/8453/deploy-config.json create mode 100644 validation/genesis/validation-inputs/8453/meta.toml create mode 100644 validation/genesis/validation-inputs/84532/deploy-config.json create mode 100644 validation/genesis/validation-inputs/84532/meta.toml create mode 100644 validation/genesis/validation-inputs/generate-test-config.sh diff --git a/.circleci/continue-config.yml b/.circleci/continue-config.yml index 2d33833b5..1c1dd63d1 100644 --- a/.circleci/continue-config.yml +++ b/.circleci/continue-config.yml @@ -1,230 +1,27 @@ version: 2.1 -orbs: - go: circleci/go@1.8.0 - node: circleci/node@5.2.0 - slack: circleci/slack@4.10.1 - -commands: - notify-failures-on-main: - description: "Notify Slack for CI job failures" - parameters: - channel: - type: string - steps: - - slack/notify: - channel: << parameters.channel >> - event: fail - template: basic_fail_1 - branch_pattern: main - install-just: - description: "Install just" - steps: - - run: - name: "Install just" - command: | - wget -qO - 'https://proget.makedeb.org/debian-feeds/prebuilt-mpr.pub' | gpg --dearmor | sudo tee /usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg 1> /dev/null - echo "deb [arch=all,$(dpkg --print-architecture) signed-by=/usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg] https://proget.makedeb.org prebuilt-mpr $(lsb_release -cs)" | sudo tee /etc/apt/sources.list.d/prebuilt-mpr.list - sudo apt update - sudo apt install just - install-foundry: - description: "Installs foundry" - steps: - - run: - # need foundry to execute 'cast call' within add-chain script - name: Install foundry - command: | - echo "SHELL=$SHELL" - # Set up directory structure - mkdir -p $HOME/.foundry/bin - echo 'export PATH="$HOME/.foundry/bin:$PATH"' >> $BASH_ENV - source $BASH_ENV - - # Download foundryup and make it executable - curl -sSL "https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup" -o $HOME/.foundry/bin/foundryup - chmod +x $HOME/.foundry/bin/foundryup +# this allows us to use CircleCI's dynamic configuration feature +setup: true - $HOME/.foundry/bin/foundryup - forge --version +orbs: + continuation: circleci/continuation@0.3.1 jobs: - golang-lint: - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - run: just lint-all - - run: - name: check git tree is clean - command: git diff --exit-code - golang-modules-tidy: - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - run: just tidy-all - - run: - name: check git tree is clean - command: git diff --exit-code - golang-test: - shell: /bin/bash -eo pipefail - executor: - name: go/default # is based on cimg/go - tag: '1.21' + setup-genesis-allocs-validation: + macos: + xcode: 14.2.0 + resource_class: macos.m1.medium.gen1 steps: - checkout - - install-just - - install-foundry - - run: - name: run superchain module unit tests - command: just test-superchain - run: - name: run validation module unit tests - command: just test-validation - - run: - name: run add-chain module unit tests - command: just test-add-chain - - notify-failures-on-main: - channel: C03N11M0BBN # to slack channel `notify-ci-failures` - golang-validate-modified: - shell: /bin/bash -eo pipefail - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - install-foundry - - run: - name: run validation checks - command: just validate-modified-chains main # TODO ideally this is the base branch - golang-validate-all: - shell: /bin/bash -eo pipefail - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - install-foundry - - run: - name: run validation checks on all chains - command: just validate "*" - - notify-failures-on-main: - channel: C07GQQZDW1G # to slack channel `notify-superchain-validation-failures` - golang-promotion-test: - shell: /bin/bash -eo pipefail - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - install-foundry - - run: - name: run validation checks - command: just promotion-test - - slack/notify: - event: always - custom: | - { - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": ":control_knobs: The daily report on standard candidate chains is ready!" - }, - "accessory": { - "type": "button", - "text": { - "type": "plain_text", - "text": "👀 View Report", - "emoji": true - }, - "url": "${CIRCLE_BUILD_URL}" - } - }, - { - "type": "divider" - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Click the link to see what validation checks would fail if all candidate chains were promoted to standard (and exclusions removed)." - } - ] - } - ] - } - channel: C07GZVCCUS0 # to slack channel `notify-superchain-promotion-failures` - publish-bot: - environment: - NODE_AUTH_TOKEN: $NPM_TOKEN # Use NPM_TOKEN as the auth token - docker: - - image: cimg/node:18 # Use Node.js 18 - steps: - - checkout - - run: - name: Set deployment token - command: npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" - - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - run: - name: Build and publish package on NPM 📦 - command: pnpm release - check-codegen: - executor: - name: go/default # is based on cimg/go - tag: '1.21' - steps: - - checkout - - install-just - - run: - name: Run codegen - command: just codegen - - run: - name: check git tree is clean - command: git diff --exit-code + name: Generate list of chainids and insert into continue_config.yml file + command: | + bash validation/genesis/validation-inputs/generate-test-config.sh + - continuation/continue: + configuration_path: .circleci/continue_config.yml + parameters: '{}' workflows: - hourly: - jobs: - - golang-validate-all: - context: - - slack - - golang-test: - context: - - slack - triggers: - - schedule: - cron: "0 * * * *" - filters: - branches: - only: - - main - nightly: - jobs: - - golang-promotion-test: - context: - - slack - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - main - pr-checks: + setup: jobs: - - golang-lint - - golang-modules-tidy - - golang-test - - golang-validate-modified - - check-codegen + - setup-genesis-allocs-validation diff --git a/.circleci/continue_config.yml b/.circleci/continue_config.yml new file mode 100644 index 000000000..178fc77a7 --- /dev/null +++ b/.circleci/continue_config.yml @@ -0,0 +1,278 @@ +version: 2.1 +orbs: + go: circleci/go@1.8.0 + node: circleci/node@5.2.0 + slack: circleci/slack@4.10.1 +commands: + notify-failures-on-main: + description: "Notify Slack for CI job failures" + parameters: + channel: + type: string + steps: + - slack/notify: + channel: << parameters.channel >> + event: fail + template: basic_fail_1 + branch_pattern: main + install-just: + steps: + - run: + name: "Install just" + command: | + wget -qO - 'https://proget.makedeb.org/debian-feeds/prebuilt-mpr.pub' | gpg --dearmor | sudo tee /usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg 1> /dev/null + echo "deb [arch=all,$(dpkg --print-architecture) signed-by=/usr/share/keyrings/prebuilt-mpr-archive-keyring.gpg] https://proget.makedeb.org prebuilt-mpr $(lsb_release -cs)" | sudo tee /etc/apt/sources.list.d/prebuilt-mpr.list + sudo apt update + sudo apt install just + install-foundry: + steps: + - run: + # need foundry to execute 'cast call' within add-chain script + name: Install foundry + command: | + echo "SHELL=$SHELL" + # Set up directory structure + mkdir -p $HOME/.foundry/bin + echo 'export PATH="$HOME/.foundry/bin:$PATH"' >> $BASH_ENV + source $BASH_ENV + + # Download foundryup and make it executable + curl -sSL "https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/foundryup" -o $HOME/.foundry/bin/foundryup + chmod +x $HOME/.foundry/bin/foundryup + + $HOME/.foundry/bin/foundryup + forge --version + install-gvm: + steps: + - run: + name: install gvm + command: | + sudo apt-get update + sudo apt-get -yq install curl git mercurial make binutils bison gcc build-essential bsdmainutils + bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) + install-pnpm: + description: "Installs pnpm" + steps: + - run: + name: Install pnpm + command: | + sudo npm install -g pnpm + install-nvm: + description: "Installs nvm" + steps: + - run: + name: Install nvm + command: | + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + source ~/.bashrc + nvm --version +jobs: + golang-lint: + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - run: just lint-all + - run: + name: check git tree is clean + command: git diff --exit-code + golang-modules-tidy: + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - run: just tidy-all + - run: + name: check git tree is clean + command: git diff --exit-code + golang-test: + shell: /bin/bash -eo pipefail + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - install-foundry + - run: + name: run superchain module unit tests + command: just test-superchain + - run: + name: run validation module unit tests + command: just test-validation + - run: + name: run add-chain module unit tests + command: just test-add-chain + - notify-failures-on-main: + channel: C03N11M0BBN # to slack channel `notify-ci-failures` + golang-validate-modified: + shell: /bin/bash -eo pipefail + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - install-foundry + - run: + name: run validation checks + command: just validate-modified-chains main # TODO ideally this is the base branch + golang-validate-all: + shell: /bin/bash -eo pipefail + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - install-foundry + - run: + name: run validation checks on all chains + command: just validate "*" + - notify-failures-on-main: + channel: C07GQQZDW1G # to slack channel `notify-superchain-validation-failures` + golang-promotion-test: + shell: /bin/bash -eo pipefail + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - install-foundry + - run: + name: run validation checks + command: just promotion-test + - slack/notify: + event: always + custom: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":control_knobs: The daily report on standard candidate chains is ready!" + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "👀 View Report", + "emoji": true + }, + "url": "${CIRCLE_BUILD_URL}" + } + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Click the link to see what validation checks would fail if all candidate chains were promoted to standard (and exclusions removed)." + } + ] + } + ] + } + channel: C07GZVCCUS0 # to slack channel `notify-superchain-promotion-reports` + publish-bot: + environment: + NODE_AUTH_TOKEN: $NPM_TOKEN # Use NPM_TOKEN as the auth token + docker: + - image: cimg/node:18 # Use Node.js 18 + steps: + - checkout + - run: + name: Set deployment token + command: npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" + - env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: + name: "Build and publish package on NPM \U0001F4E6" + command: pnpm release + check-codegen: + executor: + name: go/default # is based on cimg/go + tag: '1.21' + steps: + - checkout + - install-just + - run: + name: Run codegen + command: just codegen + - run: + name: check git tree is clean + command: git diff --exit-code + golang-validate-genesis-allocs: + docker: + - image: cimg/go:1.22.6-node + resource_class: medium + parameters: + chainid: + type: string + steps: + - checkout + - install-pnpm + - install-just + - install-foundry + - install-gvm + - install-nvm + - run: just validate-genesis-allocs <> + genesis-allocs-all-ok: + docker: + - image: cimg/go:1.22.6-node + resource_class: medium + steps: + - checkout + - run: echo "Job 1 is running" +workflows: + hourly: + jobs: + - golang-validate-all: + context: + - slack + - golang-test: + context: + - slack + triggers: + - schedule: + cron: "0 * * * *" + filters: + branches: + only: + - main + nightly: + jobs: + - golang-promotion-test: + context: + - slack + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - main + pr-checks: + jobs: + - golang-validate-genesis-allocs: + matrix: + parameters: + chainid: [] # This list will be replaced by the generate_test_config.sh script + - genesis-allocs-all-ok: + requires: [] # This list will be replaced by the generate_test_config.sh script + - golang-lint + - golang-modules-tidy + - golang-test + - golang-validate-modified + - check-codegen diff --git a/.env.example b/.env.example index 6edb20be5..f2ba870ed 100644 --- a/.env.example +++ b/.env.example @@ -21,11 +21,18 @@ SCR_STANDARD_CHAIN_CANDIDATE=false # It is defined for convenience and reuse by other vars below SCR_MONOREPO_DIR=../optimism # path to local "ethereum-optimism/optimism" monorepo -# The following vars point to three input files required for adding a chain +# The following vars point to four input files required for adding a chain # Data will be scraped from these files in order to construct the required registry data +# and for genesis validation purposes. SCR_DEPLOYMENTS_DIR=${SCR_MONOREPO_DIR}/packages/contracts-bedrock/deployments/getting-started SCR_ROLLUP_CONFIG=${SCR_MONOREPO_DIR}/op-node/rollup.json SCR_GENESIS=${SCR_MONOREPO_DIR}/op-node/genesis.json +SCR_DEPLOY_CONFIG=${SCR_MONOREPO_DIR}/packages/contracts-bedrock/deploy-config/getting-started.json + +# This is the commit in the https://github.com/ethereum-optimism/optimism/ repo +# at which the chain's genesis was created. This is necessary to have our validation checks +# recreate the genesis file using identical source code +SCR_GENESIS_CREATION_COMMIT="" # Your chain's endpoint for ETHEREUM JSON-RPC requests SCR_PUBLIC_RPC="http://awe.some.rpc" # new OP Stack L2 RPC URL diff --git a/add-chain/e2e_test.go b/add-chain/e2e_test.go index 138ed2b71..63d525e88 100644 --- a/add-chain/e2e_test.go +++ b/add-chain/e2e_test.go @@ -10,9 +10,9 @@ import ( ) const ( - addressDir = "../superchain/extra/addresses/sepolia/" - configDir = "../superchain/configs/sepolia/" - genesisSystemConfigDir = "../superchain/extra/genesis-system-configs/sepolia/" + addressDir = "../superchain/extra/addresses/sepolia/" + configDir = "../superchain/configs/sepolia/" + validationInputsDir = "../validation/genesis/validation-inputs" ) var tests = []struct { @@ -172,7 +172,6 @@ func checkConfigTOML(t *testing.T, testName, chainShortName string) { func cleanupTestFiles(t *testing.T, chainShortName string) { paths := []string{ addressDir + chainShortName + ".json", - genesisSystemConfigDir + chainShortName + ".json", configDir + chainShortName + ".toml", } diff --git a/add-chain/flags/flags.go b/add-chain/flags/flags.go index 53fc057b9..ec127405e 100644 --- a/add-chain/flags/flags.go +++ b/add-chain/flags/flags.go @@ -70,6 +70,18 @@ var ( Usage: "Filepath to rollup.json input file", Required: true, } + DeployConfigFlag = &cli.StringFlag{ + Name: "deploy-config", + EnvVars: prefixEnvVars("DEPLOY_CONFIG"), + Usage: "Filepath to deploy-config json input file", + Required: true, + } + GenesisCreationCommit = &cli.StringFlag{ + Name: "genesis-creation-commit", + EnvVars: prefixEnvVars("GENESIS_CREATION_COMMIT"), + Usage: "Commit in the https://github.com/ethereum-optimism/optimism/ repo at which the chain's genesis was created", + Required: true, + } GenesisFlag = &cli.StringFlag{ Name: "genesis", EnvVars: prefixEnvVars("GENESIS"), diff --git a/add-chain/go.mod b/add-chain/go.mod index ad03f5d70..951d84173 100644 --- a/add-chain/go.mod +++ b/add-chain/go.mod @@ -4,12 +4,15 @@ go 1.21 replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain +replace github.com/ethereum-optimism/superchain-registry/validation => ../validation + replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101408.0-rc.4.0.20240828150145-60038121c757 require ( github.com/BurntSushi/toml v1.4.0 github.com/ethereum-optimism/optimism v1.9.1-0.20240814195148-0bb2ff57c813 github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20240828144951-4e6edcb7d36c + github.com/ethereum-optimism/superchain-registry/validation v0.0.0-00010101000000-000000000000 github.com/ethereum/go-ethereum v1.14.7 github.com/google/go-cmp v0.6.0 github.com/joho/godotenv v1.5.1 diff --git a/add-chain/main.go b/add-chain/main.go index ea824db11..fd704c6ca 100644 --- a/add-chain/main.go +++ b/add-chain/main.go @@ -3,16 +3,19 @@ package main import ( "fmt" "os" + "path" "path/filepath" "runtime" "strconv" "strings" + "github.com/BurntSushi/toml" "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/superchain-registry/add-chain/cmd" "github.com/ethereum-optimism/superchain-registry/add-chain/config" "github.com/ethereum-optimism/superchain-registry/add-chain/flags" "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/superchain-registry/validation/genesis" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -35,6 +38,8 @@ var app = &cli.App{ flags.GenesisFlag, flags.DeploymentsDirFlag, flags.StandardChainCandidateFlag, + flags.GenesisCreationCommit, + flags.DeployConfigFlag, }, Action: entrypoint, Commands: []*cli.Command{ @@ -88,6 +93,8 @@ func entrypoint(ctx *cli.Context) error { chainName := ctx.String(flags.ChainNameFlag.Name) rollupConfigPath := ctx.String(flags.RollupConfigFlag.Name) + deployConfigPath := ctx.String(flags.DeployConfigFlag.Name) + genesisCreationCommit := ctx.String(flags.GenesisCreationCommit.Name) genesisPath := ctx.String(flags.GenesisFlag.Name) deploymentsDir := ctx.String(flags.DeploymentsDirFlag.Name) chainShortName := ctx.String(flags.ChainShortNameFlag.Name) @@ -109,6 +116,8 @@ func entrypoint(ctx *cli.Context) error { fmt.Printf("Monorepo dir: %s\n", monorepoDir) fmt.Printf("Deployments directory: %s\n", deploymentsDir) fmt.Printf("Rollup config filepath: %s\n", rollupConfigPath) + fmt.Printf("Deploy config filepath: %s\n", deployConfigPath) + fmt.Printf("Genesis creation commit: %s\n", genesisCreationCommit) fmt.Printf("Genesis filepath: %s\n", genesisPath) fmt.Printf("Public RPC endpoint: %s\n", publicRPC) fmt.Printf("Sequencer RPC endpoint: %s\n", sequencerRPC) @@ -169,7 +178,29 @@ func entrypoint(ctx *cli.Context) error { return fmt.Errorf("error generating chain config .yaml file: %w", err) } - fmt.Printf("Wrote config for new chain with identifier %s", rollupConfig.Identifier()) + fmt.Printf("✅ Wrote config for new chain with identifier %s", rollupConfig.Identifier()) + + folderName := fmt.Sprintf("%d", rollupConfig.ChainID) + if runningTests := os.Getenv("SCR_RUN_TESTS"); runningTests == "true" { + folderName = folderName + "-test" + } + genesisValidationInputsDir := filepath.Join(superchainRepoRoot, "validation", "genesis", "validation-inputs", folderName) + err = os.MkdirAll(genesisValidationInputsDir, os.ModePerm) + if err != nil { + return err + } + err = copyDeployConfigFile(deployConfigPath, genesisValidationInputsDir) + if err != nil { + return fmt.Errorf("error copying deploy-config json file: %w", err) + } + fmt.Printf("✅ Copied deploy-config json file to validation module") + + err = writeGenesisValidationMetadata(genesisCreationCommit, genesisValidationInputsDir) + if err != nil { + return fmt.Errorf("error writing genesis validation metadata file: %w", err) + } + fmt.Printf("✅ Wrote genesis validation metadata file") + return nil } @@ -230,3 +261,32 @@ func getGasPayingToken(l1rpcURl string, SystemConfigAddress superchain.Address) return (*superchain.Address)(&result.Addr), nil } + +func copyDeployConfigFile(sourcePath string, targetDir string) error { + data, err := os.ReadFile(sourcePath) + if err != nil { + return err + } + return os.WriteFile(path.Join(targetDir, "deploy-config.json"), data, os.ModePerm) +} + +func writeGenesisValidationMetadata(commit string, targetDir string) error { + // Define default metadata params: + // These may not be sufficient to make the genesis validation work, + // but we address that with some manual trial-and-error intervention + // involving OPLabs engineers after the add-chain command runs. + const defaultNodeVersion = "18.12.1" + const defaultMonorepoBuildCommand = "pnpm" + const defaultGenesisCreationCommand = "opnode1" + vm := genesis.ValidationMetadata{ + GenesisCreationCommit: commit, + NodeVersion: defaultNodeVersion, + MonorepoBuildCommand: defaultMonorepoBuildCommand, + GenesisCreationCommand: defaultGenesisCreationCommand, + } + data, err := toml.Marshal(vm) + if err != nil { + return err + } + return os.WriteFile(path.Join(targetDir, "meta.toml"), data, os.ModePerm) +} diff --git a/add-chain/testdata/.env.test b/add-chain/testdata/.env.test index 0f92df81a..5966155d0 100644 --- a/add-chain/testdata/.env.test +++ b/add-chain/testdata/.env.test @@ -4,6 +4,8 @@ SCR_SUPERCHAIN_TARGET=sepolia # L1 chain name SCR_MONOREPO_DIR=./testdata/monorepo SCR_DEPLOYMENTS_DIR=${SCR_MONOREPO_DIR}/deployments SCR_ROLLUP_CONFIG=${SCR_MONOREPO_DIR}/op-node/rollup.json +SCR_GENESIS_CREATION_COMMIT=somecommit +SCR_DEPLOY_CONFIG=${SCR_MONOREPO_DIR}/deploy-config/sepolia.json SCR_GENESIS=${SCR_MONOREPO_DIR}/op-node/genesis.json SCR_PUBLIC_RPC="http://awe.some.rpc" # L2 RPC URL SCR_SEQUENCER_RPC="http://awe.some.seq.rpc" diff --git a/add-chain/testdata/monorepo/deploy-config/sepolia.json b/add-chain/testdata/monorepo/deploy-config/sepolia.json new file mode 100644 index 000000000..bcc13611f --- /dev/null +++ b/add-chain/testdata/monorepo/deploy-config/sepolia.json @@ -0,0 +1,41 @@ +{ + "finalSystemOwner": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "portalGuardian": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "l1StartingBlockTag": "0x70e5634d09793b1cfaa7d0a2a5d3289a3b2308de1e82f682b4f817fc670f9797", + "l1ChainID": 11155111, + "l2ChainID": 11155420, + "l2BlockTime": 2, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x715b7219D986641DF9eFd9C7Ef01218D528e19ec", + "batchInboxAddress": "0xff00000000000000000000000000000011155420", + "batchSenderAddress": "0x7431310e026B69BFC676C0013E12A1A11411EEc9", + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 0, + "l2OutputOracleProposer": "0x02b1786A85Ec3f71fBbBa46507780dB7cF9014f6", + "l2OutputOracleChallenger": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "finalizationPeriodSeconds": 12, + "proxyAdminOwner": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "baseFeeVaultRecipient": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "l1FeeVaultRecipient": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "sequencerFeeVaultRecipient": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "enableGovernance": true, + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "governanceTokenOwner": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301", + "l2GenesisBlockGasLimit": "0x1c9c380", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "l2GenesisRegolithTimeOffset": "0x0" +} diff --git a/bindings/rust-bindings/etc/configs.toml b/bindings/rust-bindings/etc/configs.toml index 2ab7f8043..1e1177831 100644 --- a/bindings/rust-bindings/etc/configs.toml +++ b/bindings/rust-bindings/etc/configs.toml @@ -137,6 +137,62 @@ PreimageOracle = "0x0000000000000000000000000000000000000000" DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] + name = "World Chain" + chain_id = 480 + public_rpc = "https://worldchain-mainnet-sequencer.g.alchemy.com" + sequencer_rpc = "https://worldchain-mainnet-sequencer.g.alchemy.com" + explorer = "https://worldchain-mainnet-explorer.alchemy.com/" + superchain_level = 0 + standard_chain_candidate = true + batch_inbox_addr = "0xff00000000000000000000000000000000000480" + canyon_time = 0 + delta_time = 0 + ecotone_time = 0 + block_time = 2 + seq_window_size = 3600 + max_sequencer_drift = 1800 + data_availability_type = "eth-da" + [superchains.chains.genesis] + l2_time = 1719335639 + [superchains.chains.genesis.l1] + hash = "0x793daed4743301e00143be5533cd1dce0a741519e9e9c96588a9ad7dbb4d8db4" + number = 20170118 + [superchains.chains.genesis.l2] + hash = "0x70d316d2e0973b62332ba2e9768dd7854298d7ffe77f0409ffdb8d859f2d3fa3" + number = 0 + [superchains.chains.genesis.system_config] + batcherAddress = "0xdBBE3D8c2d2b22A2611c5A94A9a12C2fCD49Eb29" + overhead = "0x00000000000000000000000000000000000000000000000000000000000000bc" + scalar = "0x00000000000000000000000000000000000000000000000000000000000a6fe0" + gasLimit = 100000000 + [superchains.chains.addresses] + SystemConfigOwner = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + ProxyAdminOwner = "0xA4fB12D15Eb85dc9284a7df0AdBC8B696EdbbF1d" + Guardian = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + Challenger = "0xB2aa0C2C4fD6BFCBF699d4c787CD6Cc0dC461a9d" + Proposer = "0x2307278fC8aB0005974A6DeD2FA6d1187333a223" + UnsafeBlockSigner = "0x2270d6eC8E760daA317DD978cFB98C8f144B1f3A" + BatchSubmitter = "0xdBBE3D8c2d2b22A2611c5A94A9a12C2fCD49Eb29" + AddressManager = "0x5891090d5085679714cb0e62f74950a3c19146a8" + L1CrossDomainMessengerProxy = "0xf931a81D18B1766d15695ffc7c1920a62b7e710a" + L1ERC721BridgeProxy = "0x1Df436AfDb2fBB40F1fE8bEd4Fc89A0D0990a8E9" + L1StandardBridgeProxy = "0x470458C91978D2d929704489Ad730DC3E3001113" + L2OutputOracleProxy = "0x19A6d1E9034596196295CF148509796978343c5D" + OptimismMintableERC20FactoryProxy = "0x82Cb528466cF22412d89bdBE9bCF04856790dD0e" + OptimismPortalProxy = "0xd5ec14a83B7d95BE1E2Ac12523e2dEE12Cbeea6C" + SystemConfigProxy = "0x6ab0777fD0e609CE58F939a7F70Fe41F5Aa6300A" + ProxyAdmin = "0xd7405BE7f3e63b094Af6C7C23D5eE33Fd82F872D" + SuperchainConfig = "0xa231f8be37e583f276f93dF516D88a043bfe47E3" + AnchorStateRegistryProxy = "0x1325C4966d17038C5592fb38416AeE85EE73c0cb" + DelayedWETHProxy = "0xF9adF7c9502C5C60352C20a4d22683422DbD061F" + DisputeGameFactoryProxy = "0x0E90dCAFBC242D2C861A20Bb20EC8E7182965a52" + FaultDisputeGame = "0x0000000000000000000000000000000000000000" + MIPS = "0x267b2FFfA613c246Ef995390Ea0a2BaAA16a80Ba" + PermissionedDisputeGame = "0x0000000000000000000000000000000000000000" + PreimageOracle = "0x3941778243E3E80a6a46D149F083825dEdc534BB" + DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] name = "Binary Mainnet" chain_id = 624 @@ -704,6 +760,62 @@ PreimageOracle = "0x0000000000000000000000000000000000000000" DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] + name = "World Chain Sepolia Testnet" + chain_id = 4801 + public_rpc = "" + sequencer_rpc = "https://worldchain-sepolia-sequencer.g.alchemy.com" + explorer = "https://worldchain-sepolia-explorer.alchemy.com/" + superchain_level = 0 + standard_chain_candidate = true + batch_inbox_addr = "0xFf00000000000000000000000000000000484752" + canyon_time = 0 + delta_time = 0 + ecotone_time = 0 + block_time = 2 + seq_window_size = 3600 + max_sequencer_drift = 1800 + data_availability_type = "eth-da" + [superchains.chains.genesis] + l2_time = 1720547424 + [superchains.chains.genesis.l1] + hash = "0xd220bbdf24df6d1611f4ece1d08c64feae914ce6299ab2806c864e30a5289201" + number = 6278018 + [superchains.chains.genesis.l2] + hash = "0xf1deb67ee953f94d8545d2647918687fa8ba1f30fa6103771f11b7c483984070" + number = 0 + [superchains.chains.genesis.system_config] + batcherAddress = "0x0f3ff4731D7a10B89ED79AD1Fd97844d7F66B96d" + overhead = "0x00000000000000000000000000000000000000000000000000000000000000bc" + scalar = "0x00000000000000000000000000000000000000000000000000000000000a6fe0" + gasLimit = 100000000 + [superchains.chains.addresses] + SystemConfigOwner = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + ProxyAdminOwner = "0x945185C01fb641bA3E63a9bdF66575e35a407837" + Guardian = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + Challenger = "0xe78a0A96C5D6aE6C606418ED4A9Ced378cb030A0" + Proposer = "0x77a95104e4025fC8B88A6a0F5FB7Fae20851E414" + UnsafeBlockSigner = "0x3241A7D28eA74E807A5087BA637fB58D8dDcd078" + BatchSubmitter = "0x0f3ff4731D7a10B89ED79AD1Fd97844d7F66B96d" + AddressManager = "0xc50Ba0767A1c0Ef69Cf1D9cd44De52b08589F691" + L1CrossDomainMessengerProxy = "0x7768c821200554d8F359A8902905Ba9eDe5659a9" + L1ERC721BridgeProxy = "0x3580505c56f8560E3777E92Fb27f70fD20c5B493" + L1StandardBridgeProxy = "0xd7DF54b3989855eb66497301a4aAEc33Dbb3F8DE" + L2OutputOracleProxy = "0xc8886f8BAb6Eaeb215aDB5f1c686BF699248300e" + OptimismMintableERC20FactoryProxy = "0x2D272eF54Ee8EF5c2Ff3523559186580b158cd57" + OptimismPortalProxy = "0xFf6EBa109271fe6d4237EeeD4bAb1dD9A77dD1A4" + SystemConfigProxy = "0x166F9406e79A656f12F05247fb8F5DfA6155bCBF" + ProxyAdmin = "0x3a987FE1cb587B0A1808cf9bB7Cbe0E341838319" + SuperchainConfig = "0x4642C5eD3B1568e0F05d73B10d02e6Fb2595aF9a" + AnchorStateRegistryProxy = "0x1517FDD5A31B35f790eA8a3c6cC2F595B1BD4742" + DelayedWETHProxy = "0x4F4B8Adf1af4b61bb62F68b7aF1c37f8A6311663" + DisputeGameFactoryProxy = "0x8cF97Ee616C986a070F5020d973b456D0120C253" + FaultDisputeGame = "0x0000000000000000000000000000000000000000" + MIPS = "0xCEd5c6ca2f32dE7bf43DB981E1cac398D7A978F2" + PermissionedDisputeGame = "0x0000000000000000000000000000000000000000" + PreimageOracle = "0x954C0Fb8083047f37c8Fe954c114f8138614131C" + DAChallengeAddress = "0x0000000000000000000000000000000000000000" + [[superchains.chains]] name = "RACE Testnet" chain_id = 6806 diff --git a/go.work b/go.work index b7935e534..c0f7e3c67 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.21.9 +go 1.21 use ( ./add-chain diff --git a/justfile b/justfile index a0171b29c..4730ad5fd 100644 --- a/justfile +++ b/justfile @@ -45,11 +45,14 @@ test-validation: clean-add-chain validate-modified-chains REF: # Running validation checks only for chains whose config has changed: git diff --merge-base {{REF}} --name-only 'superchain/configs/*.toml' ':(exclude)superchain/**/superchain.toml' | xargs -r awk '/chain_id/ {print $3}' | xargs -I {} just validate {} - # Run validation checks for chains with a name or chain ID matching the supplied regex, example: just validate 10 validate CHAIN_ID: TEST_DIRECTORY=./validation go run gotest.tools/gotestsum@latest --format testname -- -run='TestValidation/.+\({{CHAIN_ID}}\)$' -count=1 +# Run genesis validation (this is separated from other validation checks, because it is not a part of drift detection) +validate-genesis-allocs CHAIN_ID: + TEST_DIRECTORY=./validation/genesis go run gotest.tools/gotestsum@latest --format standard-verbose -- -run='TestGenesisAllocs/.+\({{CHAIN_ID}}\)$' -timeout 0 + promotion-test: TEST_DIRECTORY=./validation go run gotest.tools/gotestsum@latest --format dots -- -run Promotion @@ -57,6 +60,7 @@ promotion-test: clean-add-chain: rm -f superchain/configs/sepolia/testchain_*.toml rm -f superchain/extra/sepolia/testchain_*.json.gz + rm -rf -- validation/genesis/validation-inputs/*-test/ # Tidying all go.mod files tidy-all: tidy-add-chain tidy-superchain tidy-validation diff --git a/validation/.gitignore b/validation/.gitignore index 8d22a37f7..8a5e1f691 100644 --- a/validation/.gitignore +++ b/validation/.gitignore @@ -1,3 +1,6 @@ +# diff tool artifacts generate-rollup-config/output-* generate-genesis/output-* -genesis/optimism-temporary + +# test output artifacts +genesis/validation-inputs/*-test diff --git a/validation/common/common.go b/validation/common/common.go new file mode 100644 index 000000000..fdb5a7dc8 --- /dev/null +++ b/validation/common/common.go @@ -0,0 +1,12 @@ +package common + +import ( + "fmt" + + . "github.com/ethereum-optimism/superchain-registry/superchain" +) + +// PerChainTestName ensures test can easily be filtered by chain name or chain id using the -run=regex testflag. +func PerChainTestName(chain *ChainConfig) string { + return chain.Name + fmt.Sprintf(" (%d)", chain.ChainID) +} diff --git a/validation/genesis-allocs_test.go b/validation/genesis-allocs_test.go new file mode 100644 index 000000000..d40c17751 --- /dev/null +++ b/validation/genesis-allocs_test.go @@ -0,0 +1,21 @@ +package validation + +import ( + "testing" + + . "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/superchain-registry/validation/genesis" + "github.com/stretchr/testify/require" +) + +func testGenesisAllocsMetadata(t *testing.T, chain *ChainConfig) { + // This tests asserts that the a genesis creation commit is stored for + // the chain. It does not perform full genesis allocs validation. + // Full genesis allocs validation is run as a one-off requirement when + // chains are added to the registry and/or when the genesis creation commit itself + // is changed (and may be re-run at other choice moments). + // Therefore the presence of a genesis creation commit ensures that full genesis + // validation has been performed on this chain. + // This test is lightweight and can be run continually. + require.NotEmpty(t, genesis.ValidationInputs[chain.ChainID].GenesisCreationCommit) +} diff --git a/validation/genesis/commands.go b/validation/genesis/commands.go new file mode 100644 index 000000000..09d981316 --- /dev/null +++ b/validation/genesis/commands.go @@ -0,0 +1,42 @@ +package genesis + +import ( + "fmt" + "strings" +) + +type GeneratorFn func(uint64, string) string + +var GenesisCreationCommand = map[string]GeneratorFn{ + "opnode1": opnode1, + "opnode2": opnode2, +} + +func opnode1(chainId uint64, l1rpcURL string) string { + return strings.Join([]string{ + "go run op-node/cmd/main.go genesis l2", + fmt.Sprintf(" --deploy-config=./packages/contracts-bedrock/deploy-config/%d.json", chainId), + " --outfile.l2=expected-genesis.json", + " --outfile.rollup=rollup.json", + fmt.Sprintf("--l1-deployments=./packages/contracts-bedrock/deployments/%d/.deploy", chainId), + fmt.Sprintf("--l1-rpc=%s", l1rpcURL), + }, + " ") +} + +func opnode2(chainId uint64, l1rpcURL string) string { + return strings.Join([]string{ + "go run op-node/cmd/main.go genesis l2", + fmt.Sprintf("--deploy-config=./packages/contracts-bedrock/deploy-config/%d.json", chainId), + "--outfile.l2=expected-genesis.json", + "--outfile.rollup=rollup.json", + fmt.Sprintf("--deployment-dir=./packages/contracts-bedrock/deployments/%d", chainId), + fmt.Sprintf("--l1-rpc=%s", l1rpcURL), + }, + " ") +} + +var BuildCommand = map[string]string{ + "pnpm": "pnpm install --no-frozen-lockfile", + "yarn": "yarn install --no-frozen-lockfile", +} diff --git a/validation/genesis/config.patch b/validation/genesis/config.patch new file mode 100644 index 000000000..18c6f3eae --- /dev/null +++ b/validation/genesis/config.patch @@ -0,0 +1,13 @@ +diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go +index 4c813acd4..42aa795ed 100644 +--- a/op-chain-ops/genesis/config.go ++++ b/op-chain-ops/genesis/config.go +@@ -588,7 +588,7 @@ func NewDeployConfig(path string) (*DeployConfig, error) { + } + + dec := json.NewDecoder(bytes.NewReader(file)) +- dec.DisallowUnknownFields() ++ // dec.DisallowUnknownFields() + + var config DeployConfig + if err := dec.Decode(&config); err != nil { diff --git a/validation/genesis/foundry-config.patch b/validation/genesis/foundry-config.patch new file mode 100644 index 000000000..dcdf635b8 --- /dev/null +++ b/validation/genesis/foundry-config.patch @@ -0,0 +1,13 @@ +diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml +index 3d11af94b..c3d441735 100644 +--- a/packages/contracts-bedrock/foundry.toml ++++ b/packages/contracts-bedrock/foundry.toml +@@ -8,7 +8,7 @@ remappings = [ + '@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/', + '@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/', + '@rari-capital/solmate/=node_modules/@rari-capital/solmate', +- "@cwia/=node_modules/clones-with-immutable-args/src", ++ "@cwia/=node_modules/clones-with-immutable-args", + 'forge-std/=node_modules/forge-std/src', + 'ds-test/=node_modules/ds-test/src' + ] diff --git a/validation/genesis/genesis-allocs_test.go b/validation/genesis/genesis-allocs_test.go new file mode 100644 index 000000000..5a3819b05 --- /dev/null +++ b/validation/genesis/genesis-allocs_test.go @@ -0,0 +1,171 @@ +package genesis + +import ( + "encoding/json" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "runtime" + "strconv" + "testing" + + . "github.com/ethereum-optimism/superchain-registry/superchain" + . "github.com/ethereum-optimism/superchain-registry/validation/common" + + "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/require" +) + +var temporaryOptimismDir string + +// TestMain is the entry point for testing in this package. +func TestMain(m *testing.M) { + // Clone optimism into gitignored temporary directory (if that directory does not yet exist) + // We avoid cloning under the superchain-registry tree, since this causes dependency resolution problems + _, filename, _, ok := runtime.Caller(0) + if !ok { + panic("No caller information") + } + thisDir := filepath.Dir(filename) + temporaryOptimismDir = path.Join(thisDir, "../../../optimism-temporary") + + // Clone the repo if it the folder doesn't exist + _, err := os.Stat(temporaryOptimismDir) + needToClone := os.IsNotExist(err) + if needToClone { + mustExecuteCommandInDir(thisDir, + exec.Command("git", "clone", "https://github.com/ethereum-optimism/optimism.git", temporaryOptimismDir)) + } + + // Run tests + exitVal := m.Run() + + // Teardown code: + // Only if we cloned the directory, now delete it + // This means during local development, one can clone the + // repo manually before running the test to speed up runs. + if needToClone { + if err := os.RemoveAll(temporaryOptimismDir); err != nil { + panic("Failed to remove temp directory: " + err.Error()) + } + } + + // Exit with the result of the tests + os.Exit(exitVal) +} + +func TestGenesisAllocs(t *testing.T) { + for _, chain := range OPChains { + if chain.SuperchainLevel == Standard || chain.StandardChainCandidate { + t.Run(PerChainTestName(chain), func(t *testing.T) { + // Do not run in parallel + testGenesisAllocs(t, chain) + }) + } + } +} + +func testGenesisAllocs(t *testing.T, chain *ChainConfig) { + chainId := chain.ChainID + vis, ok := ValidationInputs[chainId] + + if !ok { + t.Fatalf("Could not validate the genesis of chain %d (no validation metadata)", chainId) + } + + monorepoCommit := vis.GenesisCreationCommit + + // Setup some directory references + thisDir := getDirOfThisFile() + chainIdString := strconv.Itoa(int(chainId)) + validationInputsDir := path.Join(thisDir, "validation-inputs", chainIdString) + monorepoDir := temporaryOptimismDir + contractsDir := path.Join(monorepoDir, "packages/contracts-bedrock") + + // This is preferred to git checkout because it will + // blow away any leftover files from the previous run + t.Logf("🛠️ Resetting monorepo to %s...", monorepoCommit) + mustExecuteCommandInDir(monorepoDir, exec.Command("git", "reset", "--hard", monorepoCommit)) + + t.Log("🛠️ Deleting node_modules...") + mustExecuteCommandInDir(monorepoDir, exec.Command("rm", "-rf", "node_modules")) + mustExecuteCommandInDir(contractsDir, exec.Command("rm", "-rf", "node_modules")) + + t.Log("🛠️ Attempting to apply config.patch...") + mustExecuteCommandInDir(thisDir, exec.Command("cp", "config.patch", monorepoDir)) + _ = executeCommandInDir(monorepoDir, exec.Command("git", "apply", "config.patch")) // continue on error + + t.Log("🛠️ Copying deploy-config, deployments, and wrapper script to temporary dir...") + mustExecuteCommandInDir(validationInputsDir, + exec.Command("cp", "deploy-config.json", path.Join(contractsDir, "deploy-config", chainIdString+".json"))) + err := os.MkdirAll(path.Join(contractsDir, "deployments", chainIdString), os.ModePerm) + if err != nil { + log.Fatalf("Failed to create directory: %v", err) + } + if vis.GenesisCreationCommand == "opnode2" { + err = writeDeploymentsLegacy(chainId, path.Join(contractsDir, "deployments", chainIdString)) + } else { + err = writeDeployments(chainId, path.Join(contractsDir, "deployments", chainIdString)) + } + if err != nil { + log.Fatalf("Failed to write deployments: %v", err) + } + + mustExecuteCommandInDir(thisDir, exec.Command("cp", "./monorepo-outputs.sh", monorepoDir)) + buildCommand := BuildCommand[vis.MonorepoBuildCommand] + if vis.NodeVersion == "" { + panic("must set node_version in meta.toml") + } + creationCommand := GenesisCreationCommand[vis.GenesisCreationCommand](chainId, Superchains[chain.Superchain].Config.L1.PublicRPC) + cmd := exec.Command("bash", "./monorepo-outputs.sh", vis.NodeVersion, buildCommand, creationCommand) + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + t.Fatalf("Failed to get stdout pipe: %v", err) + } + stderrPipe, err := cmd.StderrPipe() + if err != nil { + t.Fatalf("Failed to get stderr pipe: %v", err) + } + // Stream the command's stdout and stderr to the test logger + go streamOutputToLogger(stdoutPipe, t) + go streamOutputToLogger(stderrPipe, t) + + t.Log("🛠️ Regenerating genesis...") + mustExecuteCommandInDir(monorepoDir, cmd) + + t.Log("🛠️ Comparing registry genesis.alloc with regenerated genesis.alloc...") + expectedData, err := os.ReadFile(path.Join(monorepoDir, "expected-genesis.json")) + require.NoError(t, err) + + gen := core.Genesis{} + + err = json.Unmarshal(expectedData, &gen) + require.NoError(t, err) + + expectedData, err = json.MarshalIndent(gen.Alloc, "", " ") + require.NoError(t, err) + + g, err := core.LoadOPStackGenesis(chainId) + require.NoError(t, err) + + gotData, err := json.MarshalIndent(g.Alloc, "", " ") + require.NoError(t, err) + + err = os.WriteFile(path.Join(monorepoDir, "want-alloc.json"), expectedData, os.ModePerm) + require.NoError(t, err) + err = os.WriteFile(path.Join(monorepoDir, "got-alloc.json"), gotData, os.ModePerm) + require.NoError(t, err) + + require.Equal(t, string(expectedData), string(gotData)) +} + +func getDirOfThisFile() string { + _, filename, _, ok := runtime.Caller(0) + if !ok { + panic("No caller information") + } + return filepath.Dir(filename) +} diff --git a/validation/genesis/genesis.go b/validation/genesis/genesis.go new file mode 100644 index 000000000..04f8f859a --- /dev/null +++ b/validation/genesis/genesis.go @@ -0,0 +1,63 @@ +package genesis + +import ( + "embed" + "fmt" + "path" + "strconv" + "strings" + + "github.com/BurntSushi/toml" +) + +//go:embed validation-inputs +var validationInputs embed.FS + +var ValidationInputs map[uint64]ValidationMetadata + +func init() { + ValidationInputs = make(map[uint64]ValidationMetadata) + + chains, err := validationInputs.ReadDir("validation-inputs") + if err != nil { + panic(fmt.Errorf("failed to read validation-inputs dir: %w", err)) + } + // iterate over superchain-target entries + for _, s := range chains { + + if !s.IsDir() { + continue // ignore files, e.g. a readme + } + + // Load superchain-target config + metadata, err := validationInputs.ReadFile(path.Join("validation-inputs", s.Name(), "meta.toml")) + if err != nil { + panic(fmt.Errorf("failed to read metadata file: %w", err)) + } + + m := new(ValidationMetadata) + err = toml.Unmarshal(metadata, m) + if err != nil { + panic(fmt.Errorf("failed to decode metadata file: %w", err)) + } + + if strings.HasSuffix(s.Name(), "-test") { + continue + } + + chainID, err := strconv.Atoi(s.Name()) + if err != nil { + panic(fmt.Errorf("failed to decode chain id from dir name: %w", err)) + } + + ValidationInputs[uint64(chainID)] = *m + + } +} + +type ValidationMetadata struct { + GenesisCreationCommit string `toml:"genesis_creation_commit"` // in https://github.com/ethereum-optimism/optimism/ + NodeVersion string `toml:"node_version"` + MonorepoBuildCommand string `toml:"monorepo_build_command"` + GenesisCreationCommand string `toml:"genesis_creation_command"` +} diff --git a/validation/genesis/monorepo-outputs.sh b/validation/genesis/monorepo-outputs.sh new file mode 100755 index 000000000..405ffe418 --- /dev/null +++ b/validation/genesis/monorepo-outputs.sh @@ -0,0 +1,20 @@ +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + +echo "Installing and selecting correct Node version" +nvm install $1 +nvm use $1 + +echo "Running install command" +eval $2 + +echo "Installing and selecting correct go version" +go_version=$(grep -m 1 '^go ' go.mod | awk '{print $2}') + +# Source the gvm script to load gvm functions into the shell +. ~/.gvm/scripts/gvm +gvm install go${go_version} +gvm use go${go_version} + +echo "Running op-node genesis l2 command" +eval "$3" diff --git a/validation/genesis/utils.go b/validation/genesis/utils.go new file mode 100644 index 000000000..afef8272e --- /dev/null +++ b/validation/genesis/utils.go @@ -0,0 +1,151 @@ +package genesis + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "os" + "os/exec" + "path" + "strings" + "testing" + + . "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum/go-ethereum/common" +) + +func executeCommandInDir(dir string, cmd *exec.Cmd) error { + log.Printf("executing %s", cmd.String()) + cmd.Dir = dir + var outErr bytes.Buffer + cmd.Stdout = os.Stdout + cmd.Stderr = &outErr + err := cmd.Run() + if err != nil { + // error case : status code of command is different from 0 + fmt.Println(outErr.String()) + } + return err +} + +func mustExecuteCommandInDir(dir string, cmd *exec.Cmd) { + err := executeCommandInDir(dir, cmd) + if err != nil { + panic(err) + } +} + +func streamOutputToLogger(reader io.Reader, t *testing.T) { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + t.Log(scanner.Text()) + } + if err := scanner.Err(); err != nil { + t.Errorf("Error reading command output: %v", err) + } +} + +func writeDeployments(chainId uint64, directory string) error { + as := Addresses[chainId] + + data, err := json.Marshal(as) + if err != nil { + return err + } + + err = os.WriteFile(path.Join(directory, ".deploy"), data, os.ModePerm) + if err != nil { + return err + } + return nil +} + +func writeDeploymentsLegacy(chainId uint64, directory string) error { + // Prepare a HardHat Deployment type, we need this whole structure to make things + // work, although it is only the Address field which ends up getting used. + type StorageLayoutEntry struct { + AstId uint `json:"astId"` + Contract string `json:"contract"` + Label string `json:"label"` + Offset uint `json:"offset"` + Slot uint `json:"slot,string"` + Type string `json:"type"` + } + type StorageLayoutType struct { + Encoding string `json:"encoding"` + Label string `json:"label"` + NumberOfBytes uint `json:"numberOfBytes,string"` + Key string `json:"key,omitempty"` + Value string `json:"value,omitempty"` + Base string `json:"base,omitempty"` + } + type StorageLayout struct { + Storage []StorageLayoutEntry `json:"storage"` + Types map[string]StorageLayoutType `json:"types"` + } + type Deployment struct { + Name string + Abi []string `json:"abi"` + Address string `json:"address"` + Args []any `json:"args"` + Bytecode string `json:"bytecode"` + DeployedBytecode string `json:"deployedBytecode"` + Devdoc json.RawMessage `json:"devdoc"` + Metadata string `json:"metadata"` + Receipt json.RawMessage `json:"receipt"` + SolcInputHash string `json:"solcInputHash"` + StorageLayout StorageLayout `json:"storageLayout"` + TransactionHash common.Hash `json:"transactionHash"` + Userdoc json.RawMessage `json:"userdoc"` + } + + // Initialize your struct with some data + data := Addresses[chainId] + + type AddressList2 AddressList // use another type to prevent infinite recursion later on + b := AddressList2(*data) + + o, err := json.Marshal(b) + if err != nil { + return err + } + + out := make(map[string]Address) + err = json.Unmarshal(o, &out) + if err != nil { + return err + } + + for k, v := range out { + text, err := v.MarshalText() + if err != nil || !strings.HasPrefix(string(text), "0x") { + continue + } + // Define the Deployment object, filling in only what we need + jsonData := Deployment{Address: v.String(), Name: k} + + raw, err := json.MarshalIndent(jsonData, "", " ") + if err != nil { + return err + } + + fileName := fmt.Sprintf("%s.json", k) + file, err := os.Create(path.Join(directory, fileName)) + if err != nil { + return fmt.Errorf("failed to create file for field %s: %w", k, err) + } + defer file.Close() + + // Write the JSON content to the file + _, err = file.Write(raw) + if err != nil { + return fmt.Errorf("failed to write JSON to file for field %s: %w", k, err) + } + + fmt.Printf("Created file: %s\n", fileName) + } + return nil +} diff --git a/validation/genesis/validation-inputs/1135/deploy-config.json b/validation/genesis/validation-inputs/1135/deploy-config.json new file mode 100644 index 000000000..0324bd344 --- /dev/null +++ b/validation/genesis/validation-inputs/1135/deploy-config.json @@ -0,0 +1,59 @@ +{ + "l1ChainID": 1, + "l2ChainID": 1135, + "l2BlockTime": 2, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0xb9DE90a90c5E441C483e754FE7341100D5fbaEcA", + "batchInboxAddress": "0xff00000000000000000000000000000000001135", + "batchSenderAddress": "0xa6Ea2f3299b63c53143c993d2d5E60A69Cd6Fe24", + "l1StartingBlockTag": "0xd580bdbd001908860f225c16ddaa08ada64471a68435694760c111253d97ffce", + "l2OutputOracleSubmissionInterval": 10800, + "l2OutputOracleStartingTimestamp": 1714728791, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleProposer": "0x0AbD6da1cE10D1cD6c7C9C14b905786D20f3EB23", + "l2OutputOracleChallenger": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "l2GenesisBlockGasLimit": "0x1c9c380", + "l1BlockTime": 12, + "baseFeeVaultRecipient": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "l1FeeVaultRecipient": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "sequencerFeeVaultRecipient": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "baseFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "baseFeeVaultWithdrawalNetwork": 1, + "l1FeeVaultWithdrawalNetwork": 1, + "sequencerFeeVaultWithdrawalNetwork": 1, + "proxyAdminOwner": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "finalSystemOwner": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "superchainConfigGuardian": "0xBeA2Bc852a160B8547273660E22F4F08C2fa9Bbb", + "finalizationPeriodSeconds": 604800, + "fundDevAccounts": false, + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 1000000, + "enableGovernance": false, + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "governanceTokenOwner": "0xdA6e5640aFB2ED212Ba3a6fd83076e2ad3daD185", + "eip1559Denominator": 1000, + "eip1559DenominatorCanyon": 1000, + "eip1559Elasticity": 20, + "l2GenesisRegolithTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisEcotoneTimeOffset": "0x0", + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameAbsolutePrestate": "0x03cb5216c8cf2902c66127db119ba03a1296205736addc39cfeafc7c14d0bd14", + "faultGameMaxDepth": 73, + "faultGameMaxDuration": 604800, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameSplitDepth": 32, + "preimageOracleMinProposalSize": 1800000, + "preimageOracleChallengePeriod": 86400, + "l1CancunTimeOffset": "0x0" +} diff --git a/validation/genesis/validation-inputs/1135/meta.toml b/validation/genesis/validation-inputs/1135/meta.toml new file mode 100644 index 000000000..b426a1365 --- /dev/null +++ b/validation/genesis/validation-inputs/1135/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "e6ef3a900c42c8722e72c2e2314027f85d12ced5" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/1750/deploy-config.json b/validation/genesis/validation-inputs/1750/deploy-config.json new file mode 100644 index 000000000..2b8347e78 --- /dev/null +++ b/validation/genesis/validation-inputs/1750/deploy-config.json @@ -0,0 +1,56 @@ +{ + "l1StartingBlockTag": "0x2493565ce8472656b7c22377c8d4d8ef5d17f78392c799ca5f2429b01e2c159c", + "l1ChainID": 1, + "l2ChainID": 1750, + "l2BlockTime": 2, + "l1BlockTime": 12, + "finalizationPeriodSeconds": 604800, + "systemConfigOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "finalSystemOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "controller": "0x87A1157dFCc065684DDE31fE202E50238A17Fc44", + "baseFeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l1FeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "sequencerFeeVaultRecipient": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x4a65F5da5e80DEFfEA844eAa15CE130e80605dc5", + "optimismL2FeeRecipient": "0x3A2F5F909d7D3fb62E7Db3193df26078ec563795", + "batchInboxAddress": "0xc83f7D9F2D4A76E81145849381ABA02602373723", + "batchSenderAddress": "0xC94C243f8fb37223F3EB2f7961F7072602A51B8B", + "l2GenesisRegolithTimeOffset": "0x0", + "portalGuardian": "0x4a4962275df8c60a80d3a25faec5aa7de116a746", + "l2OutputOracleSubmissionInterval": 21600, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleProposer": "0xC8187d40AD440328104A52BBed2D8Efc5ab1F1F6", + "l2OutputOracleOwner": "0x8768b38625c73FefC6036b4aAEA84483a23abE5D", + "sequencerFeeVaultWithdrawalNetwork": 0, + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "superchainConfigGuardian": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A", + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisEcotoneTimeOffset": "0x0", + "eip1559DenominatorCanyon": 250, + "proxyAdmin": "0x72d29FD7601083E95e501Cc0DA7c9A9E073600a4", + "proxyAdminOwner": "0xefCf0c8faFB425997870f845e26fC6cA6EE6dD5C", + "optimismBaseFeeRecipient": "0x26F00eac2a7B0DE5D07109A10a284126F4667735", + "optimismL1FeeRecipient": "0x9c8c9743fD2632E0c22E309375D9c8e8A6d38c55", + "l2CrossDomainMessengerOwner": "0xcCf7200E0D99718C8efB9cD5fd4f95F67cf5E854", + "gasPriceOracleOwner": "0x155e6fb8e0f590a15F31a622D85a4cB42b9aB46E", + "l2OutputOracleChallenger": "0x4a4962275df8c60a80d3a25faec5aa7de116a746" +} diff --git a/validation/genesis/validation-inputs/1750/meta.toml b/validation/genesis/validation-inputs/1750/meta.toml new file mode 100644 index 000000000..b642a13b0 --- /dev/null +++ b/validation/genesis/validation-inputs/1750/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "416cdccd2a93f83fe713dea3b0d86889c430dce3" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/34443/deploy-config.json b/validation/genesis/validation-inputs/34443/deploy-config.json new file mode 100644 index 000000000..9d105699c --- /dev/null +++ b/validation/genesis/validation-inputs/34443/deploy-config.json @@ -0,0 +1,50 @@ +{ + "l1StartingBlockTag": "0xf9b1b22a7ef9d13f063ea467bcb70fb6e9f29698ecb7366a2cdf5af2165cacee", + "l1ChainID": 1, + "l2ChainID": 34443, + "l2BlockTime": 2, + "finalizationPeriodSeconds": 604800, + "systemConfigOwner": "0x4a4962275DF8C60a80d3a25faEc5AA7De116A746", + "finalSystemOwner": "0x4a4962275DF8C60a80d3a25faEc5AA7De116A746", + "controller": "0xf4802485d882D8eEa73c8A07D7FaD3B20440f149", + "baseFeeVaultRecipient": "0xed4811010A86F7C39134fbC20206d906AD1176B6", + "l1FeeVaultRecipient": "0xed4811010A86F7C39134fbC20206d906AD1176B6", + "sequencerFeeVaultRecipient": "0xed4811010A86F7C39134fbC20206d906AD1176B6", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0x4a4962275DF8C60a80d3a25faEc5AA7De116A746", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0xa7fA9CA4ac88686A542C0f830d7378eAB4A0278F", + "optimismL2FeeRecipient": "0xB1498F5c779303Dc8A0A533197085ec77Faf9989", + "batchInboxAddress": "0x24E59d9d3Bd73ccC28Dc54062AF7EF7bFF58Bd67", + "batchSenderAddress": "0x99199a22125034c808ff20f377d91187E8050F2E", + "l2GenesisRegolithTimeOffset": "0x0", + "portalGuardian": "0x309Fe2536d01867018D120b40e4676723C53A14C", + "l2OutputOracleSubmissionInterval": 1800, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingBlockNumber": "0x0", + "l2OutputOracleProposer": "0x674F64D64Ddc198db83cd9047dF54BF89cCD0ddB", + "l2OutputOracleOwner": "0x01409dB06A96EA7D10e81BcDD663D8bf745d2eab", + "sequencerFeeVaultWithdrawalNetwork": 0, + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "proxyAdmin": "0xEeeEe4060b1785Da25634449DdC57B44A40457e7", + "proxyAdminOwner": "0xefCf0c8faFB425997870f845e26fC6cA6EE6dD5C", + "optimismBaseFeeRecipient": "0x821DE76f548C46C1D8bf1821E3d177FfB234Ae9D", + "optimismL1FeeRecipient": "0x8BB4202D5e710fBFc6303b39532821eDC28E79d2", + "l2CrossDomainMessengerOwner": "0x17e3Dd82dE9e63614eeC3294640c286e0736F591", + "gasPriceOracleOwner": "0x3Bd5af32fedf8Dc1A9BB60420F2FF0d0368e34D1", + "l2OutputOracleChallenger": "0x309Fe2536d01867018D120b40e4676723C53A14C" +} diff --git a/validation/genesis/validation-inputs/34443/meta.toml b/validation/genesis/validation-inputs/34443/meta.toml new file mode 100644 index 000000000..1e666dad5 --- /dev/null +++ b/validation/genesis/validation-inputs/34443/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "d80c145e0acf23a49c6a6588524f57e32e33b91" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2" diff --git a/validation/genesis/validation-inputs/4202/deploy-config.json b/validation/genesis/validation-inputs/4202/deploy-config.json new file mode 100644 index 000000000..b17292dee --- /dev/null +++ b/validation/genesis/validation-inputs/4202/deploy-config.json @@ -0,0 +1,46 @@ +{ + "finalSystemOwner": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "superchainConfigGuardian": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "l1StartingBlockTag": "0x7d9d6dcec39efe182119f41b1bd2aa7b35b82e43927522afea86d210a4eace4b", + "l1ChainID": 11155111, + "l2ChainID": 4202, + "l2BlockTime": 2, + "l1BlockTime": 12, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x99804980804e9EbE78db89C049fFe36ceaaEF654", + "batchInboxAddress": "0xff00000000000000000000000000000000004202", + "batchSenderAddress": "0x246E119a5BcC2875161b23E4e602e25cEcE96E37", + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 1705312992, + "l2OutputOracleProposer": "0xBbD3a1D90B0Ef416581ACdC6a72046b38D3af9AD", + "l2OutputOracleChallenger": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "finalizationPeriodSeconds": 12, + "proxyAdminOwner": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "baseFeeVaultRecipient": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "l1FeeVaultRecipient": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "sequencerFeeVaultRecipient": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + "gasPriceOracleOverhead": 2100, + "gasPriceOracleScalar": 1000000, + "enableGovernance": true, + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "governanceTokenOwner": "0x19De6D30Bf43654B7244B8adA135E1AA639bF091", + "l2GenesisBlockGasLimit": "0x1c9c380", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisRegolithTimeOffset": "0x0", + "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, + "eip1559Elasticity": 10, + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/validation/genesis/validation-inputs/4202/meta.toml b/validation/genesis/validation-inputs/4202/meta.toml new file mode 100644 index 000000000..2c3c70f20 --- /dev/null +++ b/validation/genesis/validation-inputs/4202/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "28c359620f2b28238163eced79b39335d3a40661" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/480/deploy-config.json b/validation/genesis/validation-inputs/480/deploy-config.json new file mode 100644 index 000000000..cf44d86e3 --- /dev/null +++ b/validation/genesis/validation-inputs/480/deploy-config.json @@ -0,0 +1,71 @@ +{ + "finalSystemOwner": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "superchainConfigGuardian": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "proxyAdminOwner": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "l1StartingBlockTag": "0x793daed4743301e00143be5533cd1dce0a741519e9e9c96588a9ad7dbb4d8db4", + "l1ChainID": 1, + "l2ChainID": 480, + "l2BlockTime": 2, + "l1BlockTime": 12, + "maxSequencerDrift": 1800, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x2270d6eC8E760daA317DD978cFB98C8f144B1f3A", + "batchInboxAddress": "0xff00000000000000000000000000000000000480", + "batchSenderAddress": "0xdbbe3d8c2d2b22a2611c5a94a9a12c2fcd49eb29", + "l2OutputOracleSubmissionInterval": 1800, + "l2OutputOracleStartingTimestamp": 1719335639, + "l2OutputOracleStartingBlockNumber": 0, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "gasPriceOracleBaseFeeScalar": 1368, + "gasPriceOracleBlobBaseFeeScalar": 810949, + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisEcotoneTimeOffset": "0x0", + "l2OutputOracleProposer": "0x2307278fc8ab0005974a6ded2fa6d1187333a223", + "l2OutputOracleChallenger": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisBlockGasLimit": "0x5f5e100", + "baseFeeVaultRecipient": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "l1FeeVaultRecipient": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "sequencerFeeVaultRecipient": "0xb2aa0c2c4fd6bfcbf699d4c787cd6cc0dc461a9d", + "baseFeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "l1FeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + "enableGovernance": true, + "governanceTokenName": "Optimism", + "governanceTokenSymbol": "OP", + "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "finalizationPeriodSeconds": 604800, + "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, + "eip1559Elasticity": 10, + "l2GenesisRegolithTimeOffset": "0x0", + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameMaxDepth": 1, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "faultGameSplitDepth": 0, + "faultGameWithdrawalDelay": 0, + "faultGameClockExtension": 0, + "faultGameMaxClockDuration": 0, + "preimageOracleMinProposalSize": 0, + "preimageOracleChallengePeriod": 0, + "proofMaturityDelaySeconds": 604800, + "disputeGameFinalityDelaySeconds": 302400, + "respectedGameType": 0, + "useFaultProofs": false, + "fundDevAccounts": false, + "usePlasma": false, + "daChallengeWindow": 0, + "daResolveWindow": 0, + "daBondSize": 0, + "daResolverRefundPercentage": 0 +} diff --git a/validation/genesis/validation-inputs/480/meta.toml b/validation/genesis/validation-inputs/480/meta.toml new file mode 100644 index 000000000..aabfd29bf --- /dev/null +++ b/validation/genesis/validation-inputs/480/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "4a3d3fb444f50bed6a6991785ea5634e0efa07a4" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/4801/deploy-config.json b/validation/genesis/validation-inputs/4801/deploy-config.json new file mode 100644 index 000000000..f501b77a9 --- /dev/null +++ b/validation/genesis/validation-inputs/4801/deploy-config.json @@ -0,0 +1,71 @@ +{ + "finalSystemOwner": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "superchainConfigGuardian": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "proxyAdminOwner": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "l1StartingBlockTag": "0xd220bbdf24df6d1611f4ece1d08c64feae914ce6299ab2806c864e30a5289201", + "l1ChainID": 11155111, + "l2ChainID": 4801, + "l2BlockTime": 2, + "l1BlockTime": 12, + "maxSequencerDrift": 1800, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x3241A7D28eA74E807A5087BA637fB58D8dDcd078", + "batchInboxAddress": "0xff00000000000000000000000000000000484752", + "batchSenderAddress": "0x0f3ff4731d7a10b89ed79ad1fd97844d7f66b96d", + "l2OutputOracleSubmissionInterval": 1800, + "l2OutputOracleStartingTimestamp": 1720547424, + "l2OutputOracleStartingBlockNumber": 0, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "gasPriceOracleBaseFeeScalar": 1368, + "gasPriceOracleBlobBaseFeeScalar": 810949, + "l2GenesisCanyonTimeOffset": "0x0", + "l2GenesisDeltaTimeOffset": "0x0", + "l2GenesisEcotoneTimeOffset": "0x0", + "l2OutputOracleProposer": "0x77a95104e4025fc8b88a6a0f5fb7fae20851e414", + "l2OutputOracleChallenger": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisBlockGasLimit": "0x5f5e100", + "baseFeeVaultRecipient": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "l1FeeVaultRecipient": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "sequencerFeeVaultRecipient": "0xe78a0a96c5d6ae6c606418ed4a9ced378cb030a0", + "baseFeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "l1FeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x2386f26fc10000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + "enableGovernance": true, + "governanceTokenName": "Optimism", + "governanceTokenSymbol": "OP", + "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "finalizationPeriodSeconds": 12, + "eip1559Denominator": 50, + "eip1559DenominatorCanyon": 250, + "eip1559Elasticity": 10, + "l2GenesisRegolithTimeOffset": "0x0", + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", + "faultGameMaxDepth": 1, + "faultGameGenesisBlock": 0, + "faultGameGenesisOutputRoot": "0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF", + "faultGameSplitDepth": 0, + "faultGameWithdrawalDelay": 0, + "faultGameClockExtension": 0, + "faultGameMaxClockDuration": 0, + "preimageOracleMinProposalSize": 0, + "preimageOracleChallengePeriod": 0, + "proofMaturityDelaySeconds": 604800, + "disputeGameFinalityDelaySeconds": 302400, + "respectedGameType": 0, + "useFaultProofs": false, + "fundDevAccounts": false, + "usePlasma": false, + "daChallengeWindow": 0, + "daResolveWindow": 0, + "daBondSize": 0, + "daResolverRefundPercentage": 0 +} diff --git a/validation/genesis/validation-inputs/4801/meta.toml b/validation/genesis/validation-inputs/4801/meta.toml new file mode 100644 index 000000000..aabfd29bf --- /dev/null +++ b/validation/genesis/validation-inputs/4801/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "4a3d3fb444f50bed6a6991785ea5634e0efa07a4" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode1" diff --git a/validation/genesis/validation-inputs/7777777/deploy-config.json b/validation/genesis/validation-inputs/7777777/deploy-config.json new file mode 100644 index 000000000..7b670c6a8 --- /dev/null +++ b/validation/genesis/validation-inputs/7777777/deploy-config.json @@ -0,0 +1,43 @@ +{ + "l1StartingBlockTag": "0x10aa183", + "l1ChainID": 1, + "l2ChainID": 7777777, + "l2BlockTime": 2, + "finalizationPeriodSeconds": 604800, + "systemConfigOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "finalSystemOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "controller": "0xEe729F57F0111FD0F660867d0F522f983202a5aF", + "baseFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "l1FeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "sequencerFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "governanceTokenOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "governanceTokenSymbol": "OP", + "governanceTokenName": "Optimism", + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0x3Dc8Dfd0709C835cAd15a6A27e089FF4cF4C9228", + "optimismL2FeeRecipient": "0x63AA492609175d1824dD668BDadF0042E74b0fC8", + "batchInboxAddress": "0x6F54Ca6F6EdE96662024Ffd61BFd18f3f4e34DFf", + "batchSenderAddress": "0x625726c858dBF78c0125436C943Bf4b4bE9d9033", + "l2GenesisRegolithTimeOffset": "0x0", + "portalGuardian": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542", + "l2OutputOracleSubmissionInterval": 180, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleProposer": "0x48247032092e7b0ecf5dEF611ad89eaf3fC888Dd", + "l2OutputOracleOwner": "0xDA1F62857EA7f10444725c6c435235243D623540", + "l2GenesisBlockGasLimit": "0x1c9c380", + "fundDevAccounts": false, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "proxyAdmin": "0x027860cA56cF779371461C14c3a483c94e1aA8a0", + "proxyAdminOwner": "0xb0cCdbD6fe09D2199171BE19450aF249250518A0", + "optimismBaseFeeRecipient": "0xea4591A6e5a31CF0b822A4f563163CeeBeEe4eb1", + "optimismL1FeeRecipient": "0xdD7aCF916c3E3Fb959CA3bB29beFffcAD2e90be6", + "l2CrossDomainMessengerOwner": "0xA53EF9bBec25fdA4b6Da7EF5617565794369A2A5", + "gasPriceOracleOwner": "0x9c3651E0B3CE47A0b17d775077E3d9B712582be0", + "l2OutputOracleChallenger": "0xcA4571b1ecBeC86Ea2E660d242c1c29FcB55Dc72" +} diff --git a/validation/genesis/validation-inputs/7777777/meta.toml b/validation/genesis/validation-inputs/7777777/meta.toml new file mode 100644 index 000000000..6f094fdd5 --- /dev/null +++ b/validation/genesis/validation-inputs/7777777/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "65ec61dde94ffa93342728d324fecf474d228e1f" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2" diff --git a/validation/genesis/validation-inputs/8453/deploy-config.json b/validation/genesis/validation-inputs/8453/deploy-config.json new file mode 100644 index 000000000..6b24a04ab --- /dev/null +++ b/validation/genesis/validation-inputs/8453/deploy-config.json @@ -0,0 +1,42 @@ +{ + "numDeployConfirmations": 1, + "finalSystemOwner": "0x9855054731540A48b28990B63DcF4f33d8AE46A1", + "portalGuardian": "0x14536667Cd30e52C0b458BaACcB9faDA7046E056", + "controller": "0x6606d3c20cc94cc7aa1d430c0e83a5129976153a", + "l1StartingBlockTag": "0x5c13d307623a926cd31415036c8b7fa14572f9dac64528e857a470511fc30771", + "l2GenesisBlockExtraData": "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHlvdS4=", + "l1ChainID": 1, + "l2ChainID": 8453, + "l2BlockTime": 2, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0xAf6E19BE0F9cE7f8afd49a1824851023A8249e8a", + "batchInboxAddress": "0xFf00000000000000000000000000000000008453", + "batchSenderAddress": "0x5050F69a9786F081509234F1a7F4684b5E5b76C9", + "l2OutputOracleSubmissionInterval": 1800, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": 1686789348, + "l2OutputOracleProposer": "0x642229f238fb9dE03374Be34B0eD8D9De80752c5", + "l2OutputOracleChallenger": "0x14536667Cd30e52C0b458BaACcB9faDA7046E056", + "finalizationPeriodSeconds": 604800, + "proxyAdminOwner": "0x76A737DAC0c4eB926bd7d2D68b958A1ae6Ad6993", + "baseFeeVaultRecipient": "0x09C7bAD99688a55a2e83644BFAed09e62bDcCcBA", + "l1FeeVaultRecipient": "0x09C7bAD99688a55a2e83644BFAed09e62bDcCcBA", + "sequencerFeeVaultRecipient": "0x09C7bAD99688a55a2e83644BFAed09e62bDcCcBA", + "baseFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "baseFeeVaultWithdrawalNetwork": 1, + "l1FeeVaultWithdrawalNetwork": 1, + "sequencerFeeVaultWithdrawalNetwork": 1, + "gasPriceOracleOverhead": 188, + "gasPriceOracleScalar": 684000, + "l2GenesisBlockGasLimit": "0x1c9c380", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "l2GenesisBlockCoinbase": "0x4200000000000000000000000000000000000011", + "enableGovernance": false, + "eip1559Denominator": 50, + "eip1559Elasticity": 6, + "l2GenesisRegolithTimeOffset": "0x0" +} diff --git a/validation/genesis/validation-inputs/8453/meta.toml b/validation/genesis/validation-inputs/8453/meta.toml new file mode 100644 index 000000000..acfd32cf1 --- /dev/null +++ b/validation/genesis/validation-inputs/8453/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "a541c8a859d9258ad410598655f189de69adae19" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2" diff --git a/validation/genesis/validation-inputs/84532/deploy-config.json b/validation/genesis/validation-inputs/84532/deploy-config.json new file mode 100644 index 000000000..6a9fe2bdf --- /dev/null +++ b/validation/genesis/validation-inputs/84532/deploy-config.json @@ -0,0 +1,44 @@ +{ + "finalSystemOwner": "0x608081689Fe46936fB2fBDF7552CbB1D80ad4822", + "portalGuardian": "0xA9FF930151130fd19DA1F03E5077AFB7C78F8503", + "l1StartingBlockTag": "0xcac9a83291d4dec146d6f7f69ab2304f23f5be87b1789119a0c5b1e4482444ed", + "l1ChainID": 11155111, + "l2ChainID": 84532, + "l1BlockTime": 12, + "l2BlockTime": 2, + "maxSequencerDrift": 600, + "sequencerWindowSize": 3600, + "channelTimeout": 300, + "p2pSequencerAddress": "0xb830b99c95Ea32300039624Cb567d324D4b1D83C", + "batchInboxAddress": "0xFf00000000000000000000000000000000084532", + "batchSenderAddress": "0x6CDEbe940BC0F26850285cacA097C11c33103E47", + "l2OutputOracleSubmissionInterval": 120, + "l2OutputOracleStartingBlockNumber": 0, + "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleProposer": "0x20044a0d104E9e788A0C984A2B7eAe615afD046b", + "l2OutputOracleChallenger": "0xDa3037Ff70Ac92CD867c683BD807e5A484857405", + "finalizationPeriodSeconds": 12, + "proxyAdminOwner": "0x8937037a0bB08658e5A178C182e60b12f14720ce", + "baseFeeVaultRecipient": "0xc7dE632EC7f11634318856a57c5897f6a0bda3b0", + "l1FeeVaultRecipient": "0x9082AB367EAFe8887a88A1B9970BE2719007Cf6b", + "sequencerFeeVaultRecipient": "0x4cFDfb25b34b5e5E3932dA5C4F080194137AF20F", + "baseFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "l1FeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "sequencerFeeVaultMinimumWithdrawalAmount": "0x1bc16d674ec80000", + "baseFeeVaultWithdrawalNetwork": 0, + "l1FeeVaultWithdrawalNetwork": 0, + "sequencerFeeVaultWithdrawalNetwork": 0, + "gasPriceOracleOverhead": 2100, + "gasPriceOracleScalar": 1000000, + "governanceTokenSymbol": "NA", + "governanceTokenName": "NotApplicable", + "governanceTokenOwner": "0xEb5E931176714636563DC7BE4A10387D911BaE05", + "l2GenesisBlockGasLimit": "0x17D7840", + "l2GenesisBlockBaseFeePerGas": "0x3b9aca00", + "eip1559Denominator": 50, + "eip1559Elasticity": 10, + "l2GenesisRegolithTimeOffset": "0x0", + "systemConfigStartBlock": 0, + "requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", + "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/validation/genesis/validation-inputs/84532/meta.toml b/validation/genesis/validation-inputs/84532/meta.toml new file mode 100644 index 000000000..9b86e9556 --- /dev/null +++ b/validation/genesis/validation-inputs/84532/meta.toml @@ -0,0 +1,4 @@ +genesis_creation_commit = "a7ff5a811612fa338d0a6d6dd72dc2ec9badef6d" +monorepo_build_command = "pnpm" +node_version = "18.12.1" +genesis_creation_command = "opnode2" diff --git a/validation/genesis/validation-inputs/generate-test-config.sh b/validation/genesis/validation-inputs/generate-test-config.sh new file mode 100644 index 000000000..0ae4dbfc3 --- /dev/null +++ b/validation/genesis/validation-inputs/generate-test-config.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -o errexit -o pipefail +set -x + +# Get the list of changed files +targetList=$(git diff --name-only --merge-base main -- validation/genesis/*.toml) + +# Check if targetList is empty +if [ -z "$targetList" ]; then + echo "No matching .toml files found in 'validation/genesis/'. Exiting." + exit 0 +fi + +# Process the targetList to extract directory names and then the base names +targetList=$(echo "$targetList" | xargs dirname | xargs basename) + +# Join the array elements with commas and wrap each element in quotes +targets=$(echo "$targetList" | sed 's/.*/"&"/' | tr '\n' ',') + +# Remove the trailing comma +targets=${targets%,} + +# Wrap in square brackets +targets="[$targets]" + +echo "Will run genesis allocs validation on chains with ids $targets" + +# Now build another array, each element prepended with "golang-validate-genesis-allocs-" +prependedTargets=$(echo "$targetList" | sed 's/.*/"golang-validate-genesis-allocs-&"/' | tr '\n' ',') + +# Remove the trailing comma +prependedTargets=${prependedTargets%,} + +# Wrap in square brackets +prependedTargets="[$prependedTargets]" + +# Install yq +brew install yq + +# Use yq to replace the target-version key +yq e ".workflows.pr-checks.jobs[0].golang-validate-genesis-allocs.matrix.parameters.chainid = $targets" -i .circleci/continue_config.yml +yq e ".workflows.pr-checks.jobs[1].genesis-allocs-all-ok.requires = $prependedTargets" -i .circleci/continue_config.yml diff --git a/validation/promotion_test.go b/validation/promotion_test.go index a11d359ed..28daebc70 100644 --- a/validation/promotion_test.go +++ b/validation/promotion_test.go @@ -4,6 +4,7 @@ import ( "testing" . "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/superchain-registry/validation/common" ) // WARNING: this test must not run along side any other tests, because it mutates global objects. @@ -11,7 +12,7 @@ import ( func TestPromotion(t *testing.T) { for _, chain := range OPChains { chain := chain - t.Run(perChainTestName(chain), func(t *testing.T) { + t.Run(common.PerChainTestName(chain), func(t *testing.T) { t.Parallel() if chain.StandardChainCandidate { // do not allow any test exclusions diff --git a/validation/utils_test.go b/validation/utils_test.go index 33765c866..8ad38b7aa 100644 --- a/validation/utils_test.go +++ b/validation/utils_test.go @@ -5,16 +5,10 @@ import ( "math/big" "testing" - "github.com/ethereum-optimism/superchain-registry/superchain" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// perChainTestName ensures test can easily be filtered by chain name or chain id using the -run=regex testflag. -func perChainTestName(chain *superchain.ChainConfig) string { - return chain.Name + fmt.Sprintf(" (%d)", chain.ChainID) -} - // isBigIntWithinBounds returns true if actual is within bounds, where the bounds are [lower bound, upper bound] and are inclusive. var isBigIntWithinBounds = func(actual *big.Int, bounds [2]*big.Int) bool { if (bounds[1].Cmp(bounds[0])) < 0 { diff --git a/validation/validation_test.go b/validation/validation_test.go index e065df9c0..bfe8de0e0 100644 --- a/validation/validation_test.go +++ b/validation/validation_test.go @@ -4,6 +4,7 @@ import ( "testing" . "github.com/ethereum-optimism/superchain-registry/superchain" + "github.com/ethereum-optimism/superchain-registry/validation/common" ) // Test names @@ -26,6 +27,7 @@ const ( StandardContractVersionsTest = "Standard_Contract_Versions" OptimismPortal2ParamsTest = "Optimism_Portal_2_Params" KeyHandoverTest = "Key_Handover" + GenesisAllocsTest = "Genesis_Allocs_Metadata" ) func TestValidation(t *testing.T) { @@ -33,7 +35,7 @@ func TestValidation(t *testing.T) { // on each OP chain. for _, chain := range OPChains { chain := chain - t.Run(perChainTestName(chain), func(t *testing.T) { + t.Run(common.PerChainTestName(chain), func(t *testing.T) { t.Parallel() testValidation(t, chain) }) @@ -81,6 +83,7 @@ func testStandardCandidate(t *testing.T, chain *ChainConfig) { t.Run(L2SecurityConfigTest, func(t *testing.T) { testL2SecurityConfig(t, chain) }) // Other t.Run(DataAvailabilityTypeTest, func(t *testing.T) { testDataAvailabilityType(t, chain) }) + t.Run(GenesisAllocsTest, func(t *testing.T) { testGenesisAllocsMetadata(t, chain) }) } // testStandard should be applied only to a fully Standard Chain,