diff --git a/.github/workflows/e2e-op-historical-proof.yml b/.github/workflows/e2e-op-historical-proof.yml index 4a43032a909..d8a3782283c 100644 --- a/.github/workflows/e2e-op-historical-proof.yml +++ b/.github/workflows/e2e-op-historical-proof.yml @@ -22,11 +22,13 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: true - name: Set up Go uses: actions/setup-go@v6 with: - go-version: '1.23' + go-version: '1.24.0' - name: Cache Go modules uses: actions/cache@v4 @@ -51,25 +53,20 @@ jobs: - uses: jdx/mise-action@v3 - - name: Run kurtosis + - name: build op-reth run: | - kurtosis engine start - + make build-op + # disable coverage for now # - name: Build op-reth with coverage # working-directory: crates/optimism/tests # run: | # make build-with-cov - - name: Run DEVNET - working-directory: crates/optimism/tests - run: | - make all DEVNET=opgeth-seq-opreth-val - - name: Run ${{ matrix.go_pkg_name }} e2e tests working-directory: crates/optimism/tests run: | - make test-e2e-kurtosis GO_PKG_NAME=${{ matrix.go_pkg_name }} DEVNET=opgeth-seq-opreth-val + make test-e2e-sysgo GO_PKG_NAME=${{ matrix.go_pkg_name }} OP_DEVSTACK_PROOF_SEQUENCER_EL=op-geth OP_DEVSTACK_PROOF_VALIDATOR_EL=op-reth # disable coverage for now # - name: Flush coverage data @@ -128,11 +125,13 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: true - name: Set up Go uses: actions/setup-go@v6 with: - go-version: '1.23' + go-version: '1.24.0' - name: Cache Go modules uses: actions/cache@v4 @@ -157,19 +156,14 @@ jobs: - uses: jdx/mise-action@v3 - - name: Run kurtosis - run: | - kurtosis engine start - - - name: Run DEVNET - working-directory: crates/optimism/tests + - name: build op-reth run: | - make all DEVNET=opreth-seq-opgeth-val + make build-op - name: Run ${{ matrix.go_pkg_name }} e2e tests working-directory: crates/optimism/tests run: | - make test-e2e-kurtosis GO_PKG_NAME=${{ matrix.go_pkg_name }} DEVNET=opreth-seq-opgeth-val + make test-e2e-sysgo GO_PKG_NAME=${{ matrix.go_pkg_name }} OP_DEVSTACK_PROOF_SEQUENCER_EL=op-reth OP_DEVSTACK_PROOF_VALIDATOR_EL=op-geth e2e-op-historical-proof-success: name: e2e-op-historical-proof-success diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..e02e7532277 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "crates/optimism/tests/optimism"] + path = crates/optimism/tests/optimism + url = https://github.com/dhyaniarun1993/optimism.git diff --git a/crates/optimism/tests/Makefile b/crates/optimism/tests/Makefile index 3a582dfd73e..ff6eebe75e6 100644 --- a/crates/optimism/tests/Makefile +++ b/crates/optimism/tests/Makefile @@ -6,19 +6,26 @@ KURTOSIS_PACKAGE := github.com/ethpandaops/optimism-package@998796c0f3bb478d63d7 DEVNET ?= opgeth-seq-opreth-val GO_PKG_NAME ?= proofs/core SOURCE_DIR := $(shell pwd) +OP_DEVSTACK_PROOF_SEQUENCER_EL ?= op-geth +OP_DEVSTACK_PROOF_VALIDATOR_EL ?= op-reth -.PHONY: all build build-contracts run clean help +.PHONY: all build-docker build-contracts unzip-contract-artifacts update-packages run clean help # Default target -all: build run +all: build-docker run -# Build the op-reth Docker image +# Build op-reth build: + @echo "Building op-reth binary..." + cd ../../../ && make build-op + +# Build the op-reth Docker image +build-docker: @echo "Building $(DOCKER_IMAGE_NAME):$(DOCKER_TAG) Docker image..." cd ../../../ && docker build -f $(notdir $(DOCKERFILE_PATH)) -t $(DOCKER_IMAGE_NAME):$(DOCKER_TAG) . # Build coverage-enabled op-reth Docker image -build-with-cov: +build-docker-with-cov: @echo "Building coverage-enabled $(DOCKER_IMAGE_NAME):cov Docker image..." cd ../../../ && docker build \ --build-arg RUSTFLAGS="-Cinstrument-coverage" \ @@ -41,6 +48,19 @@ build-contracts: @echo "Building contracts with forge..." @cd "$(SOURCE_DIR)/proofs/contracts" && forge build || { echo "forge build failed"; exit 1; } +# Unzip contract artifacts +unzip-contract-artifacts: + @echo "Unzipping contract artifacts..." + mkdir -p "$(SOURCE_DIR)/artifacts/src"; \ + tar --zstd -xf "$(SOURCE_DIR)/artifacts/compressed/artifacts.tzst" -C "$(SOURCE_DIR)/artifacts/src" + +# Update contract artifacts from the optimism submodule +update-packages: + @echo "Updating contract artifacts from optimism submodule..." + cd "$(SOURCE_DIR)/optimism/op-deployer" && just build-contracts copy-contract-artifacts + mkdir -p "$(SOURCE_DIR)/artifacts/compressed" + cp "$(SOURCE_DIR)/optimism/op-deployer/pkg/deployer/artifacts/forge-artifacts/artifacts.tzst" "$(SOURCE_DIR)/artifacts/compressed/artifacts.tzst" + # Run E2E tests using Kurtosis test-e2e-kurtosis: build-contracts @echo "Running E2E tests with Kurtosis for $(DEVNET)" @@ -48,12 +68,24 @@ test-e2e-kurtosis: build-contracts if [ ! -z "$(DEVNET_CUSTOM_PATH)" ]; then \ DEVNET_PATH="$(DEVNET_CUSTOM_PATH)"; \ fi; \ - export OP_DEPLOYER_ARTIFACTS="$(SOURCE_DIR)/artifacts"; \ + export OP_DEPLOYER_ARTIFACTS="$(SOURCE_DIR)/artifacts/src/forge-artifacts"; \ export DEVNET_ENV_URL="ktnative://$(DEVNET)$$DEVNET_PATH"; \ export DISABLE_OP_E2E_LEGACY=true; \ export DEVSTACK_ORCHESTRATOR=sysext; \ go test -count=1 -timeout 40m -v ./$(GO_PKG_NAME) +# Run E2E tests using Sysgo +test-e2e-sysgo: unzip-contract-artifacts build-contracts + @echo "Running E2E tests with Sysgo" + export OP_DEPLOYER_ARTIFACTS="$(SOURCE_DIR)/artifacts/src/forge-artifacts"; \ + export DISABLE_OP_E2E_LEGACY=true; \ + export DEVSTACK_ORCHESTRATOR=sysgo; \ + export OP_RETH_ENABLE_PROOF_HISTORY=true; \ + export OP_RETH_EXEC_PATH="${SOURCE_DIR}/../../../target/release/op-reth"; \ + export OP_DEVSTACK_PROOF_SEQUENCER_EL=$(OP_DEVSTACK_PROOF_SEQUENCER_EL); \ + export OP_DEVSTACK_PROOF_VALIDATOR_EL=$(OP_DEVSTACK_PROOF_VALIDATOR_EL); \ + go test -count=1 -timeout 40m -v ./$(GO_PKG_NAME) + # Stop and clean Kurtosis services clean: @echo "Cleaning up Kurtosis services..." diff --git a/crates/optimism/tests/artifacts/.gitignore b/crates/optimism/tests/artifacts/.gitignore new file mode 100644 index 00000000000..e1b09822c79 --- /dev/null +++ b/crates/optimism/tests/artifacts/.gitignore @@ -0,0 +1,2 @@ +forge-artifacts +src \ No newline at end of file diff --git a/crates/optimism/tests/artifacts/compressed/README.md b/crates/optimism/tests/artifacts/compressed/README.md new file mode 100644 index 00000000000..cc09a725873 --- /dev/null +++ b/crates/optimism/tests/artifacts/compressed/README.md @@ -0,0 +1,2 @@ +Artifacts in this directory will be embedded inside the `op-deployer` binary. The directory can be populated by running +`make unzip-contract-artifacts`. \ No newline at end of file diff --git a/crates/optimism/tests/artifacts/compressed/artifacts.tzst b/crates/optimism/tests/artifacts/compressed/artifacts.tzst new file mode 100644 index 00000000000..2b42ab4bc8e Binary files /dev/null and b/crates/optimism/tests/artifacts/compressed/artifacts.tzst differ diff --git a/crates/optimism/tests/go.mod b/crates/optimism/tests/go.mod index a700a0caad3..7d5782f2902 100644 --- a/crates/optimism/tests/go.mod +++ b/crates/optimism/tests/go.mod @@ -1,13 +1,20 @@ module github.com/op-rs/op-geth -go 1.23.11 +go 1.24.0 // We're using the "develop" branch of the Optimism repo to include the latest changes to the `devstack` package. require github.com/ethereum-optimism/optimism v1.14.2-0.20251022171045-db70e5fc3b09 +require ( + github.com/BurntSushi/toml v1.5.0 + github.com/bmatcuk/doublestar/v4 v4.8.1 + github.com/ethereum/go-ethereum v1.16.3 + github.com/stretchr/testify v1.10.0 + golang.org/x/sync v0.14.0 +) + require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect - github.com/BurntSushi/toml v1.5.0 // indirect github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -37,7 +44,7 @@ require ( github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect - github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -57,8 +64,7 @@ require ( github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.4-0.20251001155152-4eb15ccedf7e // indirect github.com/ethereum-optimism/superchain-registry/validation v0.0.0-20251009180028-9b4658b9b7af // indirect - github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect - github.com/ethereum/go-ethereum v1.16.3 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -98,7 +104,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/raft v1.7.3 // indirect github.com/hashicorp/raft-boltdb/v2 v2.3.1 // indirect - github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect + github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.3.2 // indirect github.com/honeycombio/otel-config-go v1.17.0 // indirect @@ -140,7 +146,7 @@ require ( github.com/lmittmann/w3 v0.19.5 // indirect github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mholt/archiver v3.1.1+incompatible // indirect @@ -219,12 +225,10 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.12.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.10.0 // indirect - github.com/supranational/blst v0.3.14 // indirect + github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.12 // indirect github.com/urfave/cli/v2 v2.27.6 // indirect github.com/wlynxg/anet v0.0.4 // indirect @@ -258,8 +262,7 @@ require ( golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.38.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/sys v0.31.0 // indirect + golang.org/x/sys v0.36.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.25.0 // indirect golang.org/x/time v0.11.0 // indirect @@ -274,4 +277,6 @@ require ( lukechampine.com/blake3 v1.3.0 // indirect ) -replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101603.0-rc.1 +replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101603.3-rc.3 + +replace github.com/ethereum-optimism/optimism => ./optimism diff --git a/crates/optimism/tests/go.sum b/crates/optimism/tests/go.sum index 8ed7300a4e2..7542f6d1a03 100644 --- a/crates/optimism/tests/go.sum +++ b/crates/optimism/tests/go.sum @@ -51,6 +51,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= +github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -133,8 +135,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= -github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= @@ -197,18 +199,12 @@ github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.4-0.20251001155152-4eb15ccedf7e h1:iy1vBIzACYUyOVyoADUwvAiq2eOPC0yVsDUdolPwQjk= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.4-0.20251001155152-4eb15ccedf7e/go.mod h1:DYj7+vYJ4cIB7zera9mv4LcAynCL5u4YVfoeUu6Wa+w= -github.com/ethereum-optimism/op-geth v1.101603.0-rc.1 h1:gTAlQu6QwaZyG2hW6fDhLkXeftVNHC5RCl4P0eBXH8U= -github.com/ethereum-optimism/op-geth v1.101603.0-rc.1/go.mod h1:Ct2QjqZ2UKgvvgKLLYzoh/DBicJZB8DXsv45DgEjcco= -github.com/ethereum-optimism/optimism v1.13.8-0.20250924162823-d10392338bb9 h1:ktb42rLgDquxPjGKPVFVGZfkSe/o/XO2BGAQxZkLxKY= -github.com/ethereum-optimism/optimism v1.13.8-0.20250924162823-d10392338bb9/go.mod h1:++y04HFPGAmqsAVOwxs0RVWpKmheU6cE5gC82ncpal0= -github.com/ethereum-optimism/optimism v1.14.1 h1:b0SHe1yYuZQ7OyS0wPm/Voz+1Odet12ysDbhC37HWFU= -github.com/ethereum-optimism/optimism v1.14.1/go.mod h1:9ZU5+bFd1wyAWOI4UDntXbW3JOubBJQMlcOXadtkFjQ= -github.com/ethereum-optimism/optimism v1.14.2-0.20251022171045-db70e5fc3b09 h1:oKGXMOSlVmXIznfE82FYyUoQCnv1El6aLAsg01fZtH4= -github.com/ethereum-optimism/optimism v1.14.2-0.20251022171045-db70e5fc3b09/go.mod h1:yaXUskLOabt7KakEIRvqXeGFZ2tdh+yGotQqmEYL7bo= +github.com/ethereum-optimism/op-geth v1.101603.3-rc.3 h1:KGpZouRMsMcl9MWOmYKJi+XR1gTT9/2STANv1G7oaNA= +github.com/ethereum-optimism/op-geth v1.101603.3-rc.3/go.mod h1:Wiy9cngs7ll1slc/dcHHRVuGhozWOpF1y6f31xENR7k= github.com/ethereum-optimism/superchain-registry/validation v0.0.0-20251009180028-9b4658b9b7af h1:WWz0gJM/boaUImtJnROecPirAerKCLpAU4m6Tx0ArOg= github.com/ethereum-optimism/superchain-registry/validation v0.0.0-20251009180028-9b4658b9b7af/go.mod h1:NZ816PzLU1TLv1RdAvYAb6KWOj4Zm5aInT0YpDVml2Y= -github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= -github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= +github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -377,8 +373,8 @@ github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4Z github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/hashicorp/raft-boltdb/v2 v2.3.1 h1:ackhdCNPKblmOhjEU9+4lHSJYFkJd6Jqyvj6eW9pwkc= github.com/hashicorp/raft-boltdb/v2 v2.3.1/go.mod h1:n4S+g43dXF1tqDT+yzcXHhXM6y7MrlUd3TTwGRcUvQE= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= @@ -516,13 +512,12 @@ github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -819,8 +814,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= -github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= @@ -831,8 +826,6 @@ github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYN github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1057,7 +1050,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1067,8 +1059,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/crates/optimism/tests/optimism b/crates/optimism/tests/optimism new file mode 160000 index 00000000000..85d5905ae58 --- /dev/null +++ b/crates/optimism/tests/optimism @@ -0,0 +1 @@ +Subproject commit 85d5905ae5836a45e8651db90bf64787d84aed26 diff --git a/crates/optimism/tests/proofs/core/account_proofs_test.go b/crates/optimism/tests/proofs/core/account_proofs_test.go index c45d7fcdb58..15772bdafab 100644 --- a/crates/optimism/tests/proofs/core/account_proofs_test.go +++ b/crates/optimism/tests/proofs/core/account_proofs_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -19,7 +18,7 @@ import ( func TestL2MultipleTransactionsInDifferentBlocks(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) const numAccounts = 2 const initialFunding = 10 @@ -29,7 +28,7 @@ func TestL2MultipleTransactionsInDifferentBlocks(gt *testing.T) { recipientAddr := recipient.Address() // Block 1: Send transaction from first account - currentBlock := sys.L2EL.WaitForBlock() + currentBlock := sys.L2ELSequencerNode().WaitForBlock() t.Logf("Current L2 block number: %d", currentBlock.Number) transferAmount := eth.Ether(1) @@ -40,11 +39,12 @@ func TestL2MultipleTransactionsInDifferentBlocks(gt *testing.T) { require.Equal(t, types.ReceiptStatusSuccessful, receipt1.Status) t.Logf("Transaction 1 included in block: %d", receipt1.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt1.BlockNumber.Uint64()) utils.FetchAndVerifyProofs(t, sys, accounts[0].Address(), []common.Hash{}, receipt1.BlockNumber.Uint64()) - sys.L2EL.WaitForBlockNumber(currentBlock.Number + 1) + sys.L2ELSequencerNode().WaitForBlockNumber(currentBlock.Number + 1) // Block 2: Send transaction from second account - currentBlock = sys.L2EL.WaitForBlock() + currentBlock = sys.L2ELSequencerNode().WaitForBlock() t.Logf("Current L2 block number: %d", currentBlock.Number) tx2 := accounts[1].Transfer(recipientAddr, transferAmount) @@ -54,6 +54,7 @@ func TestL2MultipleTransactionsInDifferentBlocks(gt *testing.T) { require.Equal(t, types.ReceiptStatusSuccessful, receipt2.Status) t.Logf("Transaction 2 included in block: %d", receipt2.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt2.BlockNumber.Uint64()) utils.FetchAndVerifyProofs(t, sys, accounts[1].Address(), []common.Hash{}, receipt2.BlockNumber.Uint64()) // Also verify we can get proofs for account 0 at block 2 (different block height) @@ -67,7 +68,7 @@ func TestL2MultipleTransactionsInDifferentBlocks(gt *testing.T) { func TestL2MultipleTransactionsInSingleBlock(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) const numAccounts = 2 const initialFunding = 10 @@ -96,6 +97,7 @@ func TestL2MultipleTransactionsInSingleBlock(gt *testing.T) { require.Equal(t, types.ReceiptStatusSuccessful, receipt1.Status) t.Logf("Transaction 1 included in block %d", receipt1.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt1.BlockNumber.Uint64()) // Txns can land in the same or different blocks depending on timing. if receipt0.BlockNumber.Uint64() == receipt1.BlockNumber.Uint64() { t.Logf("Both transactions included in the same L2 block: %d", receipt0.BlockNumber.Uint64()) diff --git a/crates/optimism/tests/proofs/core/execute_payload_test.go b/crates/optimism/tests/proofs/core/execute_payload_test.go index 16b7cdeb4a7..43b991d980d 100644 --- a/crates/optimism/tests/proofs/core/execute_payload_test.go +++ b/crates/optimism/tests/proofs/core/execute_payload_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/txplan" "github.com/ethereum/go-ethereum/common" @@ -14,9 +13,9 @@ import ( func TestExecutePayloadSuccess(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) user := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther) - opRethELNode, _ := utils.IdentifyELNodes(sys.L2EL, sys.L2ELB) + opRethELNode := sys.RethL2ELNode() plannedTxOption := user.PlanTransfer(user.Address(), eth.OneWei) plannedTx := txplan.NewPlannedTx(plannedTxOption) @@ -68,9 +67,9 @@ func TestExecutePayloadSuccess(gt *testing.T) { func TestExecutePayloadWithInvalidParentHash(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) user := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther) - opRethELNode, _ := utils.IdentifyELNodes(sys.L2EL, sys.L2ELB) + opRethELNode := sys.RethL2ELNode() plannedTxOption := user.PlanTransfer(user.Address(), eth.OneWei) plannedTx := txplan.NewPlannedTx(plannedTxOption) diff --git a/crates/optimism/tests/proofs/core/execution_witness_test.go b/crates/optimism/tests/proofs/core/execution_witness_test.go index c8932cfe63f..2cbbc2b73e8 100644 --- a/crates/optimism/tests/proofs/core/execution_witness_test.go +++ b/crates/optimism/tests/proofs/core/execution_witness_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -27,8 +26,8 @@ type ExecutionWitness struct { // and that the response contains valid state, codes, keys, and headers data. func TestDebugExecutionWitness(gt *testing.T) { t := devtest.SerialT(gt) - sys := presets.NewSingleChainMultiNode(t) - opRethELNode, _ := utils.IdentifyELNodes(sys.L2EL, sys.L2ELB) + sys := utils.NewMixedOpProofPreset(t) + opRethELNode := sys.RethL2ELNode() // Create a funded account and recipient account := sys.FunderL2.NewFundedEOA(eth.Ether(10)) @@ -36,7 +35,7 @@ func TestDebugExecutionWitness(gt *testing.T) { recipientAddr := recipient.Address() // Wait for current block - currentBlock := sys.L2EL.WaitForBlock() + currentBlock := sys.L2ELSequencerNode().WaitForBlock() t.Logf("Current L2 block number: %d", currentBlock.Number) // Send a transaction to create some state changes @@ -49,6 +48,7 @@ func TestDebugExecutionWitness(gt *testing.T) { require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) t.Logf("Transaction included in block: %d", receipt.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt.BlockNumber.Uint64()) l2RethClient := opRethELNode.Escape().L2EthClient() // Get the block to inspect the state changes diff --git a/crates/optimism/tests/proofs/core/init_test.go b/crates/optimism/tests/proofs/core/init_test.go index cb59fb7f9fd..df6fe1ec27d 100644 --- a/crates/optimism/tests/proofs/core/init_test.go +++ b/crates/optimism/tests/proofs/core/init_test.go @@ -4,10 +4,11 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/op-rs/op-geth/proofs/utils" ) // TestMain creates the test-setups against the shared backend func TestMain(m *testing.M) { // Other setups may be added here, hydrated from the same orchestrator - presets.DoMain(m, presets.WithSingleChainMultiNode()) + presets.DoMain(m, utils.WithMixedOpProofPreset()) } diff --git a/crates/optimism/tests/proofs/core/resyncing_test.go b/crates/optimism/tests/proofs/core/resyncing_test.go index 948343b9ae5..1e7722a3055 100644 --- a/crates/optimism/tests/proofs/core/resyncing_test.go +++ b/crates/optimism/tests/proofs/core/resyncing_test.go @@ -5,7 +5,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" @@ -18,7 +17,7 @@ func TestResyncing(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) alice := sys.FunderL2.NewFundedEOA(eth.OneEther) bob := sys.FunderL2.NewFundedEOA(eth.OneEther) @@ -30,8 +29,8 @@ func TestResyncing(gt *testing.T) { t.Logf("Stopping validator L2 CL and EL to simulate downtime") // According to devnet config, `B` will be the validator node. - sys.L2ELB.Stop() - sys.L2CLB.Stop() + sys.L2ELValidatorNode().Stop() + sys.L2CLValidator.Stop() var blockNumbers []uint64 // produce some transactions while the node is down @@ -45,13 +44,13 @@ func TestResyncing(gt *testing.T) { // restart the node and ensure it can sync the missing blocks t.Logf("Restarting validator L2 CL and EL to resync") - sys.L2ELB.Start() - sys.L2CLB.Start() + sys.L2ELValidatorNode().Start() + sys.L2CLValidator.Start() time.Sleep(3 * time.Second) err = wait.For(t.Ctx(), 2*time.Second, func() (bool, error) { - status := sys.L2CLB.SyncStatus() + status := sys.L2CLValidator.SyncStatus() return status.UnsafeL2.Number > blockNumbers[len(blockNumbers)-1], nil }) require.NoError(gt, err, "Validator L2 CL failed to resync to latest block") diff --git a/crates/optimism/tests/proofs/core/simple_storage_test.go b/crates/optimism/tests/proofs/core/simple_storage_test.go index cab1b89d7bb..e2c59f69000 100644 --- a/crates/optimism/tests/proofs/core/simple_storage_test.go +++ b/crates/optimism/tests/proofs/core/simple_storage_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/op-rs/op-geth/proofs/utils" @@ -14,13 +13,14 @@ import ( func TestStorageProofUsingSimpleStorageContract(gt *testing.T) { t := devtest.SerialT(gt) - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) user := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther) // deploy contract via helper contract, receipt := utils.DeploySimpleStorage(t, user) t.Logf("contract deployed at address %s in L2 block %d", contract.Address().Hex(), receipt.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt.BlockNumber.Uint64()) // fetch and verify initial proof (should be zeroed storage) utils.FetchAndVerifyProofs(t, sys, contract.Address(), []common.Hash{common.HexToHash("0x0")}, receipt.BlockNumber.Uint64()) @@ -48,6 +48,7 @@ func TestStorageProofUsingSimpleStorageContract(gt *testing.T) { }) t.Logf("reset setValue transaction included in L2 block %d", callRes.BlockNumber) + sys.L2ELValidatorNode().WaitForBlockNumber(callRes.BlockNumber.Uint64()) // for each case, get proof and verify for _, c := range cases { utils.FetchAndVerifyProofs(t, sys, contract.Address(), []common.Hash{common.HexToHash("0x0")}, c.Block) @@ -61,13 +62,14 @@ func TestStorageProofUsingSimpleStorageContract(gt *testing.T) { func TestStorageProofUsingMultiStorageContract(gt *testing.T) { t := devtest.SerialT(gt) - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) user := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther) // deploy contract via helper contract, receipt := utils.DeployMultiStorage(t, user) t.Logf("contract deployed at address %s in L2 block %d", contract.Address().Hex(), receipt.BlockNumber.Uint64()) + sys.L2ELValidatorNode().WaitForBlockNumber(receipt.BlockNumber.Uint64()) // fetch and verify initial proof (should be zeroed storage) utils.FetchAndVerifyProofs(t, sys, contract.Address(), []common.Hash{common.HexToHash("0x0"), common.HexToHash("0x1")}, receipt.BlockNumber.Uint64()) @@ -104,6 +106,7 @@ func TestStorageProofUsingMultiStorageContract(gt *testing.T) { }) t.Logf("reset setValues transaction included in L2 block %d", callRes.BlockNumber) + sys.L2ELValidatorNode().WaitForBlockNumber(callRes.BlockNumber.Uint64()) // for each case, get proof and verify for _, c := range cases { var slots []common.Hash @@ -118,7 +121,7 @@ func TestStorageProofUsingMultiStorageContract(gt *testing.T) { func TestTokenVaultStorageProofs(gt *testing.T) { t := devtest.SerialT(gt) - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) // funder EOA that will deploy / interact alice := sys.FunderL2.NewFundedEOA(eth.OneEther) bob := sys.FunderL2.NewFundedEOA(eth.OneEther) @@ -147,6 +150,8 @@ func TestTokenVaultStorageProofs(gt *testing.T) { deactBlock := deactRes.BlockNumber.Uint64() t.Logf("deactivateAllowance included in block %d", deactBlock) + sys.L2ELValidatorNode().WaitForBlockNumber(deactBlock) + // balance slot for user balanceSlot := contract.GetBalanceSlot(userAddr) // nested allowance slot owner=user, spender=spenderAddr diff --git a/crates/optimism/tests/proofs/prune/init_test.go b/crates/optimism/tests/proofs/prune/init_test.go index 7581ceb775b..bd9082e259d 100644 --- a/crates/optimism/tests/proofs/prune/init_test.go +++ b/crates/optimism/tests/proofs/prune/init_test.go @@ -4,10 +4,11 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/op-rs/op-geth/proofs/utils" ) // TestMain creates the test-setups against the shared backend func TestMain(m *testing.M) { // Other setups may be added here, hydrated from the same orchestrator - presets.DoMain(m, presets.WithSingleChainMultiNode()) + presets.DoMain(m, utils.WithMixedOpProofPreset()) } diff --git a/crates/optimism/tests/proofs/prune/prune_test.go b/crates/optimism/tests/proofs/prune/prune_test.go index 8df5088fcb9..50c9a8f8ae2 100644 --- a/crates/optimism/tests/proofs/prune/prune_test.go +++ b/crates/optimism/tests/proofs/prune/prune_test.go @@ -5,7 +5,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/apis" "github.com/op-rs/op-geth/proofs/utils" "github.com/stretchr/testify/require" @@ -13,11 +12,11 @@ import ( func TestPruneProofStorage(gt *testing.T) { t := devtest.SerialT(gt) - sys := presets.NewSingleChainMultiNode(t) + sys := utils.NewMixedOpProofPreset(t) var proofWindow = uint64(200) // Defined in the devnet yaml var pruneDetectTimeout = time.Minute * 5 // An expected time within the prune should be detected. - opRethELNode, _ := utils.IdentifyELNodes(sys.L2EL, sys.L2ELB) + opRethELNode := sys.RethL2ELNode() syncStatus := getProofSyncStatus(t, opRethELNode.Escape().EthClient()) t.Log("Initial sync status:", syncStatus) diff --git a/crates/optimism/tests/proofs/reorg/init_test.go b/crates/optimism/tests/proofs/reorg/init_test.go index ba575c9fd03..cfcf49cbe55 100644 --- a/crates/optimism/tests/proofs/reorg/init_test.go +++ b/crates/optimism/tests/proofs/reorg/init_test.go @@ -4,10 +4,11 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/op-rs/op-geth/proofs/utils" ) // TestMain creates the test-setups against the shared backend func TestMain(m *testing.M) { // Other setups may be added here, hydrated from the same orchestrator - presets.DoMain(m, presets.WithNewSingleChainMultiNodeWithTestSeq()) + presets.DoMain(m, utils.WithMixedOpProofPreset()) } diff --git a/crates/optimism/tests/proofs/reorg/reorg_test.go b/crates/optimism/tests/proofs/reorg/reorg_test.go index 2ca6e80f50a..9aee9a8f095 100644 --- a/crates/optimism/tests/proofs/reorg/reorg_test.go +++ b/crates/optimism/tests/proofs/reorg/reorg_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/txplan" "github.com/ethereum-optimism/optimism/op-test-sequencer/sequencer/seqtypes" @@ -20,8 +19,7 @@ func TestReorgUsingAccountProof(gt *testing.T) { t := devtest.SerialT(gt) ctx := t.Ctx() - sys := presets.NewSingleChainMultiNodeWithTestSeq(t) - opRethELNode, _ := utils.IdentifyELNodes(sys.L2EL, sys.L2ELB) + sys := utils.NewMixedOpProofPreset(t) l := sys.Log ia := sys.TestSequencer.Escape().ControlAPI(sys.L2Chain.ChainID()) @@ -87,13 +85,13 @@ func TestReorgUsingAccountProof(gt *testing.T) { }) } - sys.L2CL.StopSequencer() + sys.L2CLSequencer.StopSequencer() var divergenceBlockNumber uint64 var originalRef eth.L2BlockRef // prepare and sequence a conflicting block for the L2A chain { - divergenceBlockRef := opRethELNode.BlockRefByNumber(divergenceHead.Number) + divergenceBlockRef := sys.L2ELSequencerNode().BlockRefByNumber(divergenceHead.Number) l.Info("Expect to reorg the chain on block", "number", divergenceBlockRef.Number, "head", divergenceHead, "parent", divergenceBlockRef.ParentID().Hash) divergenceBlockNumber = divergenceBlockRef.Number @@ -148,7 +146,7 @@ func TestReorgUsingAccountProof(gt *testing.T) { { l.Info("Sequencing with op-test-sequencer (no L1 origin override)") err := ia.New(ctx, seqtypes.BuildOpts{ - Parent: opRethELNode.BlockRefByLabel(eth.Unsafe).Hash, + Parent: sys.L2ELSequencerNode().BlockRefByLabel(eth.Unsafe).Hash, L1Origin: nil, }) require.NoError(t, err, "Expected to be able to create a new block job for sequencing on op-test-sequencer, but got error") @@ -160,17 +158,16 @@ func TestReorgUsingAccountProof(gt *testing.T) { } // continue sequencing with consensus node (op-node) - sys.L2CL.StartSequencer() + sys.L2CLSequencer.StartSequencer() for i := 0; i < 3; i++ { sys.L2Chain.WaitForBlock() } - // wait for the reorg to be processed - // todo: replace with proof status sync based wait - time.Sleep(30 * time.Second) + latestBlock := sys.L2Chain.WaitForBlock() + sys.L2ELValidatorNode().WaitForBlockNumber(latestBlock.Number) - reorgedRef_A, err := opRethELNode.Escape().EthClient().BlockRefByNumber(ctx, divergenceBlockNumber) + reorgedRef_A, err := sys.L2ELSequencerNode().Escape().EthClient().BlockRefByNumber(ctx, divergenceBlockNumber) require.NoError(t, err, "Expected to be able to call BlockRefByNumber API, but got error") l.Info("Reorged chain on divergence block number (prior the reorg)", "number", divergenceBlockNumber, "head", originalRef.Hash, "parent", originalRef.ParentID().Hash) @@ -180,6 +177,6 @@ func TestReorgUsingAccountProof(gt *testing.T) { // verify that the accounts involved in the conflicting blocks for _, c := range cases { - utils.FetchAndVerifyProofs(t, &sys.SingleChainMultiNode, c.addr, c.slots, c.Block) + utils.FetchAndVerifyProofs(t, sys, c.addr, c.slots, c.Block) } } diff --git a/crates/optimism/tests/proofs/utils/preset.go b/crates/optimism/tests/proofs/utils/preset.go new file mode 100644 index 00000000000..7e284d111d5 --- /dev/null +++ b/crates/optimism/tests/proofs/utils/preset.go @@ -0,0 +1,327 @@ +package utils + +import ( + "os" + "strings" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" + "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" + "github.com/ethereum-optimism/optimism/op-devstack/devtest" + "github.com/ethereum-optimism/optimism/op-devstack/dsl" + "github.com/ethereum-optimism/optimism/op-devstack/presets" + "github.com/ethereum-optimism/optimism/op-devstack/shim" + "github.com/ethereum-optimism/optimism/op-devstack/stack" + "github.com/ethereum-optimism/optimism/op-devstack/stack/match" + "github.com/ethereum-optimism/optimism/op-devstack/sysgo" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/intentbuilder" + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type L2ELClient string + +const ( + L2ELClientGeth L2ELClient = "geth" + L2ELClientReth L2ELClient = "reth" +) + +type L2ELNodeID struct { + stack.L2ELNodeID + Client L2ELClient +} + +type L2ELNode struct { + *dsl.L2ELNode + Client L2ELClient +} + +type MixedOpProofPreset struct { + Log log.Logger + T devtest.T + ControlPlane stack.ControlPlane + + L1Network *dsl.L1Network + L1EL *dsl.L1ELNode + + L2Chain *dsl.L2Network + L2Batcher *dsl.L2Batcher + + L2ELSequencer *L2ELNode + L2CLSequencer *dsl.L2CLNode + + L2ELValidator *L2ELNode + L2CLValidator *dsl.L2CLNode + + Wallet *dsl.HDWallet + + FaucetL1 *dsl.Faucet + FaucetL2 *dsl.Faucet + FunderL1 *dsl.Funder + FunderL2 *dsl.Funder + + TestSequencer *dsl.TestSequencer +} + +func (m *MixedOpProofPreset) L2Network() *dsl.L2Network { + return m.L2Chain +} + +func (m *MixedOpProofPreset) L2ELSequencerNode() *dsl.L2ELNode { + return m.L2ELSequencer.L2ELNode +} + +func (m *MixedOpProofPreset) L2ELValidatorNode() *dsl.L2ELNode { + return m.L2ELValidator.L2ELNode +} + +// GethL2ELNode returns first L2 EL nodes that are running op-geth +func (m *MixedOpProofPreset) GethL2ELNode() *dsl.L2ELNode { + if m.L2ELSequencer.Client == L2ELClientGeth { + return m.L2ELSequencer.L2ELNode + } + + if m.L2ELValidator.Client == L2ELClientGeth { + return m.L2ELValidator.L2ELNode + } + + return nil +} + +// RethL2ELNode returns first L2 EL nodes that are running op-reth +func (m *MixedOpProofPreset) RethL2ELNode() *dsl.L2ELNode { + if m.L2ELSequencer.Client == L2ELClientReth { + return m.L2ELSequencer.L2ELNode + } + + if m.L2ELValidator.Client == L2ELClientReth { + return m.L2ELValidator.L2ELNode + } + return nil +} + +func WithMixedOpProofPreset() stack.CommonOption { + return stack.MakeCommon(DefaultMixedOpProofSystem(&DefaultMixedOpProofSystemIDs{})) +} + +func L2NodeMatcher[ + I interface { + comparable + Key() string + }, E stack.Identifiable[I]](value ...string) stack.Matcher[I, E] { + return match.MatchElemFn[I, E](func(elem E) bool { + for _, v := range value { + if !strings.Contains(elem.ID().Key(), v) { + return false + } + } + return true + }) +} + +func NewMixedOpProofPreset(t devtest.T) *MixedOpProofPreset { + system := shim.NewSystem(t) + orch := presets.Orchestrator() + orch.Hydrate(system) + + t.Gate().Equal(len(system.L2Networks()), 1, "expected exactly one L2 network") + t.Gate().Equal(len(system.L1Networks()), 1, "expected exactly one L1 network") + + l1Net := system.L1Network(match.FirstL1Network) + l2Net := system.L2Network(match.Assume(t, match.L2ChainA)) + + t.Gate().GreaterOrEqual(len(l2Net.L2CLNodes()), 2, "expected at least two L2CL nodes") + + sequencerCL := l2Net.L2CLNode(match.Assume(t, match.WithSequencerActive(t.Ctx()))) + sequencerELInner := l2Net.L2ELNode(match.Assume(t, match.EngineFor(sequencerCL))) + var sequencerEL *L2ELNode + if strings.Contains(sequencerELInner.ID().String(), "op-reth") { + sequencerEL = &L2ELNode{ + L2ELNode: dsl.NewL2ELNode(sequencerELInner, orch.ControlPlane()), + Client: L2ELClientReth, + } + } else if strings.Contains(sequencerELInner.ID().String(), "op-geth") { + sequencerEL = &L2ELNode{ + L2ELNode: dsl.NewL2ELNode(sequencerELInner, orch.ControlPlane()), + Client: L2ELClientGeth, + } + } else { + t.Error("unexpected L2EL client for sequencer") + t.FailNow() + } + + verifierCL := l2Net.L2CLNode(match.Assume(t, + match.And( + match.Not(match.WithSequencerActive(t.Ctx())), + match.Not(sequencerCL.ID()), + ))) + verifierELInner := l2Net.L2ELNode(match.Assume(t, + match.And( + match.EngineFor(verifierCL), + match.Not(sequencerEL.ID()), + ))) + var verifierEL *L2ELNode + if strings.Contains(verifierELInner.ID().String(), "op-reth") { + verifierEL = &L2ELNode{ + L2ELNode: dsl.NewL2ELNode(verifierELInner, orch.ControlPlane()), + Client: L2ELClientReth, + } + } else if strings.Contains(verifierELInner.ID().String(), "op-geth") { + verifierEL = &L2ELNode{ + L2ELNode: dsl.NewL2ELNode(verifierELInner, orch.ControlPlane()), + Client: L2ELClientGeth, + } + } else { + t.Error("unexpected L2EL client for verifier") + t.FailNow() + } + + out := &MixedOpProofPreset{ + Log: t.Logger(), + T: t, + ControlPlane: orch.ControlPlane(), + L1Network: dsl.NewL1Network(l1Net), + L1EL: dsl.NewL1ELNode(l1Net.L1ELNode(match.Assume(t, match.FirstL1EL))), + L2Chain: dsl.NewL2Network(l2Net, orch.ControlPlane()), + L2Batcher: dsl.NewL2Batcher(l2Net.L2Batcher(match.Assume(t, match.FirstL2Batcher))), + L2ELSequencer: sequencerEL, + L2CLSequencer: dsl.NewL2CLNode(sequencerCL, orch.ControlPlane()), + L2ELValidator: verifierEL, + L2CLValidator: dsl.NewL2CLNode(verifierCL, orch.ControlPlane()), + Wallet: dsl.NewRandomHDWallet(t, 30), // Random for test isolation + FaucetL2: dsl.NewFaucet(l2Net.Faucet(match.Assume(t, match.FirstFaucet))), + + TestSequencer: dsl.NewTestSequencer(system.TestSequencer(match.Assume(t, match.FirstTestSequencer))), + } + out.FaucetL1 = dsl.NewFaucet(out.L1Network.Escape().Faucet(match.Assume(t, match.FirstFaucet))) + out.FunderL1 = dsl.NewFunder(out.Wallet, out.FaucetL1, out.L1EL) + out.FunderL2 = dsl.NewFunder(out.Wallet, out.FaucetL2, out.L2ELSequencer) + return out +} + +type DefaultMixedOpProofSystemIDs struct { + L1 stack.L1NetworkID + L1EL stack.L1ELNodeID + L1CL stack.L1CLNodeID + + L2 stack.L2NetworkID + + L2CLSequencer stack.L2CLNodeID + L2ELSequencer L2ELNodeID + + L2CLValidator stack.L2CLNodeID + L2ELValidator L2ELNodeID + + L2Batcher stack.L2BatcherID + L2Proposer stack.L2ProposerID + L2Challenger stack.L2ChallengerID + + TestSequencer stack.TestSequencerID +} + +func NewDefaultMixedOpProofSystemIDs(l1ID, l2ID eth.ChainID) DefaultMixedOpProofSystemIDs { + ids := DefaultMixedOpProofSystemIDs{ + L1: stack.L1NetworkID(l1ID), + L1EL: stack.NewL1ELNodeID("l1", l1ID), + L1CL: stack.NewL1CLNodeID("l1", l1ID), + L2: stack.L2NetworkID(l2ID), + L2CLSequencer: stack.NewL2CLNodeID("sequencer", l2ID), + L2CLValidator: stack.NewL2CLNodeID("validator", l2ID), + L2Batcher: stack.NewL2BatcherID("main", l2ID), + L2Proposer: stack.NewL2ProposerID("main", l2ID), + L2Challenger: stack.NewL2ChallengerID("main", l2ID), + TestSequencer: "test-sequencer", + } + + // default to op-geth for sequencer and op-reth for validator + if os.Getenv("OP_DEVSTACK_PROOF_SEQUENCER_EL") == "op-reth" { + ids.L2ELSequencer = L2ELNodeID{ + L2ELNodeID: stack.NewL2ELNodeID("sequencer-op-reth", l2ID), + Client: L2ELClientReth, + } + } else { + ids.L2ELSequencer = L2ELNodeID{ + L2ELNodeID: stack.NewL2ELNodeID("sequencer-op-geth", l2ID), + Client: L2ELClientGeth, + } + } + + if os.Getenv("OP_DEVSTACK_PROOF_VALIDATOR_EL") == "op-geth" { + ids.L2ELValidator = L2ELNodeID{ + L2ELNodeID: stack.NewL2ELNodeID("validator-op-geth", l2ID), + Client: L2ELClientGeth, + } + } else { + ids.L2ELValidator = L2ELNodeID{ + L2ELNodeID: stack.NewL2ELNodeID("validator-op-reth", l2ID), + Client: L2ELClientReth, + } + } + + return ids +} + +func DefaultMixedOpProofSystem(dest *DefaultMixedOpProofSystemIDs) stack.Option[*sysgo.Orchestrator] { + ids := NewDefaultMixedOpProofSystemIDs(sysgo.DefaultL1ID, sysgo.DefaultL2AID) + return defaultMixedOpProofSystemOpts(&ids, dest) +} + +func defaultMixedOpProofSystemOpts(src, dest *DefaultMixedOpProofSystemIDs) stack.CombinedOption[*sysgo.Orchestrator] { + opt := stack.Combine[*sysgo.Orchestrator]() + opt.Add(stack.BeforeDeploy(func(o *sysgo.Orchestrator) { + o.P().Logger().Info("Setting up") + })) + + opt.Add(sysgo.WithMnemonicKeys(devkeys.TestMnemonic)) + + // Get artifacts path + artifactsPath := os.Getenv("OP_DEPLOYER_ARTIFACTS") + if artifactsPath == "" { + panic("OP_DEPLOYER_ARTIFACTS is not set") + } + + opt.Add(sysgo.WithDeployer(), + sysgo.WithDeployerPipelineOption( + sysgo.WithDeployerCacheDir(artifactsPath), + ), + sysgo.WithDeployerOptions( + func(_ devtest.P, _ devkeys.Keys, builder intentbuilder.Builder) { + builder.WithL1ContractsLocator(artifacts.MustNewFileLocator(artifactsPath)) + builder.WithL2ContractsLocator(artifacts.MustNewFileLocator(artifactsPath)) + }, + sysgo.WithCommons(src.L1.ChainID()), + sysgo.WithPrefundedL2(src.L1.ChainID(), src.L2.ChainID()), + ), + ) + + opt.Add(sysgo.WithL1Nodes(src.L1EL, src.L1CL)) + + // Spawn L2 sequencer nodes + if src.L2ELSequencer.Client == L2ELClientReth { + opt.Add(sysgo.WithOpReth(src.L2ELSequencer.L2ELNodeID)) + } else { + opt.Add(sysgo.WithOpGeth(src.L2ELSequencer.L2ELNodeID)) + } + opt.Add(sysgo.WithL2CLNode(src.L2CLSequencer, src.L1CL, src.L1EL, src.L2ELSequencer.L2ELNodeID, sysgo.L2CLSequencer())) + + // Spawn L2 validator nodes + if src.L2ELValidator.Client == L2ELClientReth { + opt.Add(sysgo.WithOpReth(src.L2ELValidator.L2ELNodeID)) + } else { + opt.Add(sysgo.WithOpGeth(src.L2ELValidator.L2ELNodeID)) + } + opt.Add(sysgo.WithL2CLNode(src.L2CLValidator, src.L1CL, src.L1EL, src.L2ELValidator.L2ELNodeID)) + + opt.Add(sysgo.WithBatcher(src.L2Batcher, src.L1EL, src.L2CLSequencer, src.L2ELSequencer.L2ELNodeID)) + opt.Add(sysgo.WithProposer(src.L2Proposer, src.L1EL, &src.L2CLSequencer, nil)) + + opt.Add(sysgo.WithFaucets([]stack.L1ELNodeID{src.L1EL}, []stack.L2ELNodeID{src.L2ELSequencer.L2ELNodeID})) + + opt.Add(sysgo.WithTestSequencer(src.TestSequencer, src.L1CL, src.L2CLSequencer, src.L1EL, src.L2ELSequencer.L2ELNodeID)) + + opt.Add(stack.Finally(func(orch *sysgo.Orchestrator) { + *dest = *src + })) + + return opt +} diff --git a/crates/optimism/tests/proofs/utils/proof.go b/crates/optimism/tests/proofs/utils/proof.go index c0dc1fb1c77..16a6287b9be 100644 --- a/crates/optimism/tests/proofs/utils/proof.go +++ b/crates/optimism/tests/proofs/utils/proof.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-devstack/devtest" - "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -105,14 +104,14 @@ func VerifyProof(res *eth.AccountResult, stateRoot common.Hash) error { } // FetchAndVerifyProofs fetches account proofs from both L2EL and L2ELB for the given address -func FetchAndVerifyProofs(t devtest.T, sys *presets.SingleChainMultiNode, address common.Address, slots []common.Hash, block uint64) { +func FetchAndVerifyProofs(t devtest.T, sys *MixedOpProofPreset, address common.Address, slots []common.Hash, block uint64) { ctx := t.Ctx() - gethProofRes, err := sys.L2EL.Escape().L2EthClient().GetProof(ctx, address, slots, hexutil.Uint64(block).String()) + gethProofRes, err := sys.GethL2ELNode().Escape().L2EthClient().GetProof(ctx, address, slots, hexutil.Uint64(block).String()) if err != nil { require.NoError(t, err, "failed to get proof from L2EL at block %d", block) } - rethProofRes, err := sys.L2ELB.Escape().L2EthClient().GetProof(ctx, address, slots, hexutil.Uint64(block).String()) + rethProofRes, err := sys.RethL2ELNode().Escape().L2EthClient().GetProof(ctx, address, slots, hexutil.Uint64(block).String()) if err != nil { require.NoError(t, err, "failed to get proof from L2ELB at block %d", block) } @@ -121,7 +120,7 @@ func FetchAndVerifyProofs(t devtest.T, sys *presets.SingleChainMultiNode, addres require.Equal(t, gethProofRes, rethProofRes, "geth and reth proofs should match") - blockInfo, err := sys.L2EL.Escape().L2EthClient().InfoByNumber(ctx, block) + blockInfo, err := sys.GethL2ELNode().Escape().L2EthClient().InfoByNumber(ctx, block) if err != nil { require.NoError(t, err, "failed to get block info for block %d", block) } diff --git a/crates/optimism/tests/proofs/utils/utils.go b/crates/optimism/tests/proofs/utils/utils.go index 405f53889ca..e47fdc47e15 100644 --- a/crates/optimism/tests/proofs/utils/utils.go +++ b/crates/optimism/tests/proofs/utils/utils.go @@ -64,19 +64,3 @@ func DeployContract(t devtest.T, user *dsl.EOA, bin []byte) (common.Address, *ty return res.ContractAddress, res } - -// IdentifyELNodes returns the reth and geth EL nodes based on their IDs. -func IdentifyELNodes(el *dsl.L2ELNode, elB *dsl.L2ELNode) (opRethELNode *dsl.L2ELNode, opGethELNode *dsl.L2ELNode) { - if strings.Contains(el.ID().Key(), "op-reth") { - return el, elB - } - return elB, el -} - -// IdentifyCLNodes returns the reth and geth CL nodes based on their IDs. -func IdentifyCLNodes(cl *dsl.L2CLNode, clB *dsl.L2CLNode) (opRethCLNode *dsl.L2CLNode, opGethCLNode *dsl.L2CLNode) { - if strings.Contains(cl.ID().Key(), "op-reth") { - return cl, clB - } - return clB, cl -}