Commit c2dc0abf authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

op-e2e: Support specifying allocs in tests (#12216)

* op-e2e: Support specifying allocs in tests

Previously, the E2E test suite read a hardcoded set of allocs from the `.devnet` directory. There could only be one logical set of allocs per test suite run. To get around this limitation, we added matrix jobs to the CI pipeline that swapped in different versions of the allocs for alt-DA, MT Cannon, fault proofs, and the L2OO. This was very inefficient and complex: most tests don't need to run against multiple versions of the allocs, and were running 4 separate build jobs when only one was needed.

This PR makes it possible for an individual test to request a specific allocs file. We can now run tests for multiple different configurations of the OP Stack - e.g. alt-DA, L2OO and fault proofs - in a single test run.

To make this work, I updated the test suite's initialization method to read alloc files from multiple suffixed `.devnet-` directories. I made a a new `make devnet-allocs-tests` task to generate them. The allocs are then added to a map, and the rest of the tests use getter methods in the `config` package to locate the appropriate configuration structs.

This PR seems large, but most of the modified files contain limited changes to comply with the new API for selecting test configuration based on alloc type. For example, an `allocType` configuration parameter was added to various system config structs and the `DefaultRollupTestParams` variable was made into a method so that it always returns a copy for easy extension. The important logic happens in the following files:

- Makefile
- .circleci/config.yml
- op-e2e/config/init.go

As part of this PR, I also cleaned up a few issues:

- I removed the external OP Geth shim. It wasn't used anywhere, and was introducing a lot of complexity for little gain.
- I refactored some tests to use top-level test methods rather than subtests so that they could be more easily parallelized.
- I removed references to `UseFaultProofs`, `UseAltDA`, and other environment-based test flags from test utilities. We shouldn't be reading from the environment in test utils. Instead, we should pass in the behavior we want to the test utils themselves.

* code review updates

* fix gastoken test

* fixes
parent d05fb505
......@@ -255,28 +255,9 @@ jobs:
FOUNDRY_PROFILE: ci
working_directory: packages/contracts-bedrock
- run:
name: Generate L2OO allocs
name: Generate allocs
command: |
DEVNET_L2OO="true" make devnet-allocs
cp -r .devnet/ .devnet-l2oo/
- run:
name: Generate AltDA allocs
command: |
DEVNET_ALTDA="true" make devnet-allocs
cp -r .devnet/ .devnet-altda/
- run:
name: Generate Generic AltDA allocs
command: |
DEVNET_ALTDA="true" GENERIC_ALTDA="true" make devnet-allocs
cp -r .devnet/ .devnet-altda-generic/
- run:
name: Generate MT-Cannon allocs
command: |
USE_MT_CANNON="true" make devnet-allocs
cp -r .devnet/ .devnet-mt-cannon/
- run:
name: Generate default allocs
command: make devnet-allocs
make devnet-allocs-tests
- save_cache:
name: Save Go modules cache
key: gomod-contracts-build-{{ checksum "go.sum" }}
......@@ -296,9 +277,10 @@ jobs:
- "packages/contracts-bedrock/deploy-config/devnetL1.json"
- "packages/contracts-bedrock/deployments/devnetL1"
- ".devnet"
- ".devnet-standard"
- ".devnet-l2oo"
- ".devnet-altda"
- ".devnet-altda-generic"
- ".devnet-alt-da"
- ".devnet-alt-da-generic"
- ".devnet-mt-cannon"
- notify-failures-on-develop
......@@ -929,39 +911,19 @@ jobs:
description: Slack user or group to mention when notifying of failures
type: string
default: ""
environment:
DEVNET_L2OO: 'false'
OP_E2E_USE_L2OO: 'false'
docker:
- image: <<pipeline.parameters.ci_builder_image>>
resource_class: xlarge
parallelism: <<parameters.parallelism>>
steps:
- checkout
- when:
condition:
equal: ['-l2oo', <<parameters.variant>>]
steps:
- run:
name: Set DEVNET_L2OO = true
command: echo 'export DEVNET_L2OO=true' >> $BASH_ENV
- run:
name: Set OP_E2E_USE_L2OO = true
command: echo 'export OP_E2E_USE_L2OO=true' >> $BASH_ENV
- when:
condition:
equal: ['-altda', <<parameters.variant>>]
steps:
- run:
name: Set OP_E2E_USE_ALTDA = true
command: echo 'export OP_E2E_USE_ALTDA=true' >> $BASH_ENV
- when:
condition:
equal: ['-mt-cannon', <<parameters.variant>>]
steps:
- run:
name: Set OP_E2E_USE_MT_CANNON = true
command: echo 'export OP_E2E_USE_MT_CANNON=true' >> $BASH_ENV
name: Set OP_E2E_ALLOC_TYPE = mt-cannon
command: echo 'export OP_E2E_ALLOC_TYPE=mt-cannon' >> $BASH_ENV
- check-changed:
patterns: op-(.+),cannon,contracts-bedrock
- run:
......@@ -981,12 +943,7 @@ jobs:
name: Load devnet-allocs and artifacts
command: |
mkdir -p .devnet
cp /tmp/workspace/.devnet<<parameters.variant>>/allocs-l2-delta.json .devnet/allocs-l2-delta.json
cp /tmp/workspace/.devnet<<parameters.variant>>/allocs-l2-ecotone.json .devnet/allocs-l2-ecotone.json
cp /tmp/workspace/.devnet<<parameters.variant>>/allocs-l2-fjord.json .devnet/allocs-l2-fjord.json
cp /tmp/workspace/.devnet<<parameters.variant>>/allocs-l2-granite.json .devnet/allocs-l2-granite.json
cp /tmp/workspace/.devnet<<parameters.variant>>/allocs-l1.json .devnet/allocs-l1.json
cp /tmp/workspace/.devnet<<parameters.variant>>/addresses.json .devnet/addresses.json
cp -r /tmp/workspace/.devnet* .
cp -r /tmp/workspace/packages/contracts-bedrock/forge-artifacts packages/contracts-bedrock/forge-artifacts
cp /tmp/workspace/packages/contracts-bedrock/deploy-config/devnetL1.json packages/contracts-bedrock/deploy-config/devnetL1.json
cp -r /tmp/workspace/packages/contracts-bedrock/deployments/devnetL1 packages/contracts-bedrock/deployments/devnetL1
......@@ -1470,21 +1427,15 @@ workflows:
uses_artifacts: true
requires: ["contracts-bedrock-build"]
- go-e2e-test:
name: op-e2e-HTTP-tests<< matrix.variant >>
matrix:
parameters:
variant: ["", "-l2oo"]
name: op-e2e-HTTP-tests
module: op-e2e
target: test-http
parallelism: 4
parallelism: 8
requires:
- go-mod-download
- contracts-bedrock-build
- go-e2e-test:
name: op-e2e-action-tests<< matrix.variant >>
matrix:
parameters:
variant: ["", "-l2oo", "-altda"]
name: op-e2e-action-tests
module: op-e2e
target: test-actions
parallelism: 1
......@@ -1526,7 +1477,6 @@ workflows:
- op-e2e-HTTP-tests
- op-e2e-fault-proof-tests
- op-e2e-action-tests
- op-e2e-action-tests-altda
# Not needed for the devnet but we want to make sure they build successfully
- cannon-docker-build
- op-dispute-mon-docker-build
......
......@@ -34,7 +34,7 @@ packages/contracts-bedrock/deployments/anvil
!.envrc.example
*.log
.devnet
.devnet*
# Ignore local fuzzing results
**/testdata/fuzz/
......
......@@ -206,6 +206,19 @@ devnet-allocs: pre-devnet ## Generates allocations for the local devnet
PYTHONPATH=./bedrock-devnet $(PYTHON) ./bedrock-devnet/main.py --monorepo-dir=. --allocs
.PHONY: devnet-allocs
devnet-allocs-tests:
DEVNET_L2OO=true make devnet-allocs
cp -r .devnet/ .devnet-l2oo/
DEVNET_ALTDA=true make devnet-allocs
cp -r .devnet/ .devnet-alt-da/
DEVNET_ALTDA=false GENERIC_ALTDA=true make devnet-allocs
cp -r .devnet/ .devnet-alt-da-generic/
USE_MT_CANNON=true make devnet-allocs
cp -r .devnet/ .devnet-mt-cannon
make devnet-allocs
cp -r .devnet/ .devnet-standard/
.PHONY: devnet-allocs-tests
devnet-logs: ## Displays logs for the local devnet
@(cd ./ops-bedrock && docker compose logs -f)
.PHONY: devnet-logs
......
......@@ -38,7 +38,6 @@ require (
github.com/multiformats/go-multiaddr-dns v0.3.1
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/gomega v1.34.1
github.com/pkg/errors v0.9.1
github.com/pkg/profile v1.7.0
github.com/prometheus/client_golang v1.20.4
......@@ -86,7 +85,6 @@ require (
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 // indirect
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
......@@ -136,9 +134,6 @@ require (
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect
github.com/kilic/bls12-381 v0.1.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
......@@ -206,9 +201,6 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/protolambda/bls12-381-util v0.1.0 // indirect
github.com/protolambda/zrnt v0.32.2 // indirect
github.com/protolambda/ztyp v0.2.2 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.46.0 // indirect
github.com/quic-go/webtransport-go v0.8.0 // indirect
......@@ -234,7 +226,6 @@ require (
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.etcd.io/bbolt v1.3.5 // indirect
go.uber.org/automaxprocs v1.5.2 // indirect
go.uber.org/dig v1.18.0 // indirect
go.uber.org/fx v1.22.2 // indirect
go.uber.org/mock v0.4.0 // indirect
......
......@@ -165,8 +165,6 @@ github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnm
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao=
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo=
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
......@@ -357,7 +355,6 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w
github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc=
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.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs=
github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
......@@ -394,8 +391,6 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo
github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk=
github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY=
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
......@@ -404,10 +399,6 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I=
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8=
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
......@@ -667,8 +658,6 @@ github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDj
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
......@@ -694,14 +683,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/protolambda/bls12-381-util v0.1.0 h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk=
github.com/protolambda/bls12-381-util v0.1.0/go.mod h1:cdkysJTRpeFeuUVx/TXGDQNMTiRAalk1vQw3TYTHcE4=
github.com/protolambda/ctxlock v0.1.0 h1:rCUY3+vRdcdZXqT07iXgyr744J2DU2LCBIXowYAjBCE=
github.com/protolambda/ctxlock v0.1.0/go.mod h1:vefhX6rIZH8rsg5ZpOJfEDYQOppZi19SfPiGOFrNnwM=
github.com/protolambda/zrnt v0.32.2 h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM=
github.com/protolambda/zrnt v0.32.2/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs=
github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY=
github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
......@@ -827,8 +810,6 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw=
......@@ -964,7 +945,6 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
......
......@@ -19,6 +19,8 @@ import (
type L2AllocsMode string
type L2AllocsModeMap map[L2AllocsMode]*foundry.ForgeAllocs
const (
L2AllocsDelta L2AllocsMode = "delta"
L2AllocsEcotone L2AllocsMode = "ecotone"
......
......@@ -5,6 +5,8 @@ import (
"math/rand"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
"github.com/stretchr/testify/require"
......@@ -54,6 +56,7 @@ func NewL2AltDA(t helpers.Testing, params ...AltDAParam) *L2AltDA {
ChannelTimeout: 12,
L1BlockTime: 12,
UseAltDA: true,
AllocType: config.AllocTypeAltDA,
}
for _, apply := range params {
apply(p)
......@@ -96,7 +99,7 @@ func NewL2AltDA(t helpers.Testing, params ...AltDAParam) *L2AltDA {
AddressCorpora: addresses,
Bindings: helpers.NewL2Bindings(t, cl, engine.GethClient()),
}
alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)))
alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)), p.AllocType)
alice.L2.SetUserEnv(l2UserEnv)
contract, err := bindings.NewDataAvailabilityChallenge(sd.RollupCfg.AltDAConfig.DAChallengeAddress, l1Client)
......@@ -261,10 +264,6 @@ func (a *L2AltDA) ActL1Finalized(t helpers.Testing) {
// Commitment is challenged but never resolved, chain reorgs when challenge window expires.
func TestAltDA_ChallengeExpired(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
harness := NewL2AltDA(t)
......@@ -321,10 +320,6 @@ func TestAltDA_ChallengeExpired(gt *testing.T) {
// Commitment is challenged after sequencer derived the chain but data disappears. A verifier
// derivation pipeline stalls until the challenge is resolved and then resumes with data from the contract.
func TestAltDA_ChallengeResolved(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
harness := NewL2AltDA(t)
......@@ -369,10 +364,6 @@ func TestAltDA_ChallengeResolved(gt *testing.T) {
// DA storage service goes offline while sequencer keeps making blocks. When storage comes back online, it should be able to catch up.
func TestAltDA_StorageError(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
harness := NewL2AltDA(t)
......@@ -398,10 +389,6 @@ func TestAltDA_StorageError(gt *testing.T) {
// L1 chain reorgs a resolved challenge so it expires instead causing
// the l2 chain to reorg as well.
func TestAltDA_ChallengeReorg(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
harness := NewL2AltDA(t)
......@@ -446,10 +433,6 @@ func TestAltDA_ChallengeReorg(gt *testing.T) {
// Sequencer stalls as data is not available, batcher keeps posting, untracked commitments are
// challenged and resolved, then sequencer resumes and catches up.
func TestAltDA_SequencerStalledMultiChallenges(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
a := NewL2AltDA(t)
......@@ -542,9 +525,6 @@ func TestAltDA_SequencerStalledMultiChallenges(gt *testing.T) {
// Verify that finalization happens based on altDA windows.
// based on l2_batcher_test.go L2Finalization
func TestAltDA_Finalization(gt *testing.T) {
if !e2eutils.UseAltDA() {
gt.Skip("AltDA is not enabled")
}
t := helpers.NewDefaultTesting(gt)
a := NewL2AltDA(t)
......
......@@ -19,7 +19,7 @@ import (
)
func setupEIP4844Test(t helpers.Testing, log log.Logger) (*e2eutils.SetupData, *e2eutils.DeployParams, *helpers.L1Miner, *helpers.L2Sequencer, *helpers.L2Engine, *helpers.L2Verifier, *helpers.L2Engine) {
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
genesisActivation := hexutil.Uint64(0)
dp.DeployConfig.L1CancunTimeOffset = &genesisActivation
dp.DeployConfig.L2GenesisCanyonTimeOffset = &genesisActivation
......
......@@ -6,6 +6,8 @@ import (
"math/rand"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -59,6 +61,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
......@@ -129,7 +132,7 @@ func NormalBatcher(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -226,7 +229,7 @@ func L2Finalization(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal
func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -282,7 +285,7 @@ func L2FinalizationWithSparseL1(gt *testing.T, deltaTimeOffset *hexutil.Uint64)
// and the safe L2 head should remain unaltered.
func GarbageBatch(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
p := actionsHelpers.DefaultRollupTestParams
p := actionsHelpers.DefaultRollupTestParams()
dp := e2eutils.MakeDeployParams(t, p)
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
for _, garbageKind := range actionsHelpers.GarbageKinds {
......@@ -363,6 +366,7 @@ func ExtendedTimeWithoutL1Batches(gt *testing.T, deltaTimeOffset *hexutil.Uint64
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
......@@ -419,6 +423,7 @@ func BigL2Txs(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
SequencerWindowSize: 1000,
ChannelTimeout: 200, // give enough space to buffer large amounts of data before submitting it
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
......
......@@ -3,6 +3,8 @@ package derivation
import (
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
altda "github.com/ethereum-optimism/optimism/op-alt-da"
batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags"
"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
......@@ -29,6 +31,7 @@ func TestDeriveChainFromNearL1Genesis(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
// do not activate Delta hardfork for verifier
......
......@@ -47,7 +47,7 @@ func TestBlockTimeBatchType(t *testing.T) {
// This is a regression test against the bug fixed in PR #4566
func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.L2BlockTime = 2
......@@ -158,7 +158,7 @@ func BatchInLastPossibleBlocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// Note: It batches submits when possible.
func LargeL1Gaps(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
dp.DeployConfig.L1BlockTime = 4
dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.SequencerWindowSize = 4
......
......@@ -3,6 +3,8 @@ package derivation
import (
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
......@@ -19,6 +21,7 @@ func TestL2Verifier_SequenceWindow(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 10,
L1BlockTime: 15,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
......
......@@ -6,6 +6,8 @@ import (
"path"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers"
"github.com/ethereum/go-ethereum/common"
......@@ -55,7 +57,7 @@ func TestReorgBatchType(t *testing.T) {
func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams, deltaTimeOffset)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams(), deltaTimeOffset)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
sequencer.ActL2PipelineFull(t)
......@@ -123,7 +125,7 @@ func ReorgOrphanBlock(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func ReorgFlipFlop(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams, deltaTimeOffset)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := actionsHelpers.SetupReorgTest(t, actionsHelpers.DefaultRollupTestParams(), deltaTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
checkVerifEngine := func() {
......@@ -344,6 +346,7 @@ func DeepReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
SequencerWindowSize: 20,
ChannelTimeout: 120,
L1BlockTime: 4,
AllocType: config.AllocTypeStandard,
}, deltaTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg)
l2Client := seqEngine.EthClient()
......@@ -363,7 +366,7 @@ func DeepReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
AddressCorpora: addresses,
Bindings: actionsHelpers.NewL2Bindings(t, l2Client, seqEngine.GethClient()),
}
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)))
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)), config.AllocTypeStandard)
alice.L2.SetUserEnv(l2UserEnv)
// Run one iteration of the L2 derivation pipeline
......@@ -579,7 +582,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
nodeCfg.DataDir = dbPath
return nil
}
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -667,7 +670,7 @@ func RestartOpGeth(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// the alt block is not synced by the verifier, in unsafe and safe sync modes.
func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -694,7 +697,7 @@ func ConflictingL2Blocks(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
AddressCorpora: addresses,
Bindings: actionsHelpers.NewL2Bindings(t, l2Cl, altSeqEng.GethClient()),
}
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234)))
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234)), config.AllocTypeStandard)
alice.L2.SetUserEnv(l2UserEnv)
sequencer.ActL2PipelineFull(t)
......@@ -779,6 +782,7 @@ func SyncAfterReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
SequencerWindowSize: 4,
ChannelTimeout: 2,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := actionsHelpers.SetupReorgTest(t, &testingParams, deltaTimeOffset)
l2Client := seqEngine.EthClient()
......@@ -790,7 +794,7 @@ func SyncAfterReorg(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
AddressCorpora: addresses,
Bindings: actionsHelpers.NewL2Bindings(t, l2Client, seqEngine.GethClient()),
}
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)))
alice := actionsHelpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)), config.AllocTypeStandard)
alice.L2.SetUserEnv(l2UserEnv)
sequencer.ActL2PipelineFull(t)
......
......@@ -53,7 +53,7 @@ func TestSystemConfigBatchType(t *testing.T) {
func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
dp.DeployConfig.L2BlockTime = 2
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
......@@ -228,7 +228,7 @@ func BatcherKeyRotation(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2.
func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
// activating Delta only, not Ecotone and further:
......@@ -363,7 +363,7 @@ func GPOParamsChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// the gas limit change event. And checks if a verifier node can reproduce the same gas limit change.
func GasLimitChange(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......
......@@ -15,7 +15,7 @@ import (
func TestL1Miner_BuildBlock(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner := NewL1Miner(t, log, sd.L1Cfg)
......
......@@ -24,7 +24,7 @@ import (
// Test if we can mock an RPC failure
func TestL1Replica_ActL1RPCFail(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
replica := NewL1Replica(t, log, sd.L1Cfg)
......@@ -46,7 +46,7 @@ func TestL1Replica_ActL1RPCFail(gt *testing.T) {
// Test if we can make the replica sync an artificial L1 chain, rewind it, and reorg it
func TestL1Replica_ActL1Sync(gt *testing.T) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
dp.DeployConfig.L1CancunTimeOffset = nil
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......
......@@ -31,7 +31,7 @@ import (
func TestL2EngineAPI(gt *testing.T) {
t := NewDefaultTesting(gt)
jwtPath := e2eutils.WriteDefaultJWT(t)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
genesisBlock := sd.L2Cfg.ToBlock()
......@@ -107,7 +107,7 @@ func TestL2EngineAPI(gt *testing.T) {
func TestL2EngineAPIBlockBuilding(gt *testing.T) {
t := NewDefaultTesting(gt)
jwtPath := e2eutils.WriteDefaultJWT(t)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
genesisBlock := sd.L2Cfg.ToBlock()
......@@ -208,7 +208,7 @@ func TestL2EngineAPIBlockBuilding(gt *testing.T) {
func TestL2EngineAPIFail(gt *testing.T) {
t := NewDefaultTesting(gt)
jwtPath := e2eutils.WriteDefaultJWT(t)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
engine := NewL2Engine(t, log, sd.L2Cfg, sd.RollupCfg.Genesis.L1, jwtPath)
......@@ -228,7 +228,7 @@ func TestL2EngineAPIFail(gt *testing.T) {
func TestEngineAPITests(t *testing.T) {
test.RunEngineAPITests(t, func(t *testing.T) engineapi.EngineBackend {
jwtPath := e2eutils.WriteDefaultJWT(t)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, DefaultAlloc)
n, _, apiBackend := newBackend(t, sd.L2Cfg, jwtPath, nil)
err := n.Start()
......
......@@ -7,6 +7,8 @@ import (
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
......@@ -21,7 +23,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-proposer/metrics"
"github.com/ethereum-optimism/optimism/op-proposer/proposer"
"github.com/ethereum-optimism/optimism/op-service/dial"
......@@ -38,6 +39,7 @@ type ProposerCfg struct {
DisputeGameType uint32
ProposerKey *ecdsa.PrivateKey
AllowNonFinalized bool
AllocType config.AllocType
}
type L2Proposer struct {
......@@ -51,6 +53,7 @@ type L2Proposer struct {
address common.Address
privKey *ecdsa.PrivateKey
lastTx common.Hash
allocType config.AllocType
}
type fakeTxMgr struct {
......@@ -117,7 +120,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
var l2OutputOracle *bindings.L2OutputOracleCaller
var disputeGameFactory *bindings.DisputeGameFactoryCaller
if e2eutils.UseFaultProofs() {
if cfg.AllocType.UsesProofs() {
disputeGameFactory, err = bindings.NewDisputeGameFactoryCaller(*cfg.DisputeGameFactoryAddr, l1)
require.NoError(t, err)
} else {
......@@ -138,6 +141,7 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
disputeGameFactoryAddr: cfg.DisputeGameFactoryAddr,
address: address,
privKey: cfg.ProposerKey,
allocType: cfg.AllocType,
}
}
......@@ -154,7 +158,7 @@ func (p *L2Proposer) sendTx(t Testing, data []byte) {
require.NoError(t, err)
var addr common.Address
if e2eutils.UseFaultProofs() {
if p.allocType.UsesProofs() {
addr = *p.disputeGameFactoryAddr
} else {
addr = *p.l2OutputOracleAddr
......@@ -222,7 +226,7 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
}
func (p *L2Proposer) fetchNextOutput(t Testing) (*eth.OutputResponse, bool, error) {
if e2eutils.UseFaultProofs() {
if p.allocType.UsesProofs() {
output, shouldPropose, err := p.driver.FetchDGFOutput(t.Ctx())
if err != nil || !shouldPropose {
return nil, false, err
......@@ -258,7 +262,7 @@ func (p *L2Proposer) ActMakeProposalTx(t Testing) {
}
var txData []byte
if e2eutils.UseFaultProofs() {
if p.allocType.UsesProofs() {
tx, err := p.driver.ProposeL2OutputDGFTxCandidate(context.Background(), output)
require.NoError(t, err)
txData = tx.TxData
......
......@@ -26,7 +26,6 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
legacybindings "github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
e2ehelpers "github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
"github.com/ethereum-optimism/optimism/op-node/bindings"
bindingspreview "github.com/ethereum-optimism/optimism/op-node/bindings/preview"
......@@ -43,17 +42,18 @@ type L1Bindings struct {
DisputeGameFactory *bindings.DisputeGameFactory
}
func NewL1Bindings(t Testing, l1Cl *ethclient.Client) *L1Bindings {
optimismPortal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Cl)
func NewL1Bindings(t Testing, l1Cl *ethclient.Client, allocType config.AllocType) *L1Bindings {
l1Deployments := config.L1Deployments(allocType)
optimismPortal, err := bindings.NewOptimismPortal(l1Deployments.OptimismPortalProxy, l1Cl)
require.NoError(t, err)
l2OutputOracle, err := bindings.NewL2OutputOracle(config.L1Deployments.L2OutputOracleProxy, l1Cl)
l2OutputOracle, err := bindings.NewL2OutputOracle(l1Deployments.L2OutputOracleProxy, l1Cl)
require.NoError(t, err)
optimismPortal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, l1Cl)
optimismPortal2, err := bindingspreview.NewOptimismPortal2(l1Deployments.OptimismPortalProxy, l1Cl)
require.NoError(t, err)
disputeGameFactory, err := bindings.NewDisputeGameFactory(config.L1Deployments.DisputeGameFactoryProxy, l1Cl)
disputeGameFactory, err := bindings.NewDisputeGameFactory(l1Deployments.DisputeGameFactoryProxy, l1Cl)
require.NoError(t, err)
return &L1Bindings{
......@@ -309,9 +309,11 @@ type CrossLayerUser struct {
lastL1DepositTxHash common.Hash
lastL2WithdrawalTxHash common.Hash
allocType config.AllocType
}
func NewCrossLayerUser(log log.Logger, priv *ecdsa.PrivateKey, rng *rand.Rand) *CrossLayerUser {
func NewCrossLayerUser(log log.Logger, priv *ecdsa.PrivateKey, rng *rand.Rand, allocType config.AllocType) *CrossLayerUser {
addr := crypto.PubkeyToAddress(priv.PublicKey)
return &CrossLayerUser{
L1: L1User{
......@@ -330,6 +332,7 @@ func NewCrossLayerUser(log log.Logger, priv *ecdsa.PrivateKey, rng *rand.Rand) *
address: addr,
},
},
allocType: allocType,
}
}
......@@ -427,7 +430,7 @@ func (s *CrossLayerUser) getLatestWithdrawalParams(t Testing) (*withdrawals.Prov
var l2OutputBlockNr *big.Int
var l2OutputBlock *types.Block
if e2eutils.UseFaultProofs() {
if s.allocType.UsesProofs() {
latestGame, err := withdrawals.FindLatestGame(t.Ctx(), &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller)
require.NoError(t, err)
l2OutputBlockNr = new(big.Int).SetBytes(latestGame.ExtraData[0:32])
......@@ -444,7 +447,7 @@ func (s *CrossLayerUser) getLatestWithdrawalParams(t Testing) (*withdrawals.Prov
return nil, fmt.Errorf("the latest L2 output is %d and is not past L2 block %d that includes the withdrawal yet, no withdrawal can be proved yet", l2OutputBlock.NumberU64(), l2WithdrawalBlock.NumberU64())
}
if !e2eutils.UseFaultProofs() {
if !s.allocType.UsesProofs() {
finalizationPeriod, err := s.L1.env.Bindings.L2OutputOracle.FINALIZATIONPERIODSECONDS(&bind.CallOpts{})
require.NoError(t, err)
l1Head, err := s.L1.env.EthCl.HeaderByNumber(t.Ctx(), nil)
......@@ -457,7 +460,7 @@ func (s *CrossLayerUser) getLatestWithdrawalParams(t Testing) (*withdrawals.Prov
header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr)
require.NoError(t, err)
params, err := e2ehelpers.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller, &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller)
params, err := e2ehelpers.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller, &s.L1.env.Bindings.DisputeGameFactory.DisputeGameFactoryCaller, &s.L1.env.Bindings.OptimismPortal2.OptimismPortal2Caller, s.allocType)
require.NoError(t, err)
return &params, nil
......@@ -473,7 +476,7 @@ func (s *CrossLayerUser) getDisputeGame(t Testing, params withdrawals.ProvenWith
Data: params.Data,
}
portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, s.L1.env.EthCl)
portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments(s.allocType).OptimismPortalProxy, s.L1.env.EthCl)
require.Nil(t, err)
wdHash, err := wd.Hash()
......
......@@ -6,6 +6,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
bindingspreview "github.com/ethereum-optimism/optimism/op-node/bindings/preview"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -24,6 +26,7 @@ type hardforkScheduledTest struct {
ecotoneTime *hexutil.Uint64
fjordTime *hexutil.Uint64
runToFork string
allocType config.AllocType
}
func (tc *hardforkScheduledTest) SetFork(fork string, v uint64) {
......@@ -51,6 +54,14 @@ func (tc *hardforkScheduledTest) fork(fork string) **hexutil.Uint64 {
}
}
func TestCrossLayerUser_Standard(t *testing.T) {
testCrossLayerUser(t, config.AllocTypeStandard)
}
func TestCrossLayerUser_L2OO(t *testing.T) {
testCrossLayerUser(t, config.AllocTypeL2OO)
}
// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various hardfork configurations:
// - transact on L1
// - transact on L2
......@@ -59,7 +70,7 @@ func (tc *hardforkScheduledTest) fork(fork string) **hexutil.Uint64 {
// - prove tx on L1
// - wait 1 week + 1 second
// - finalize withdrawal on L1
func TestCrossLayerUser(t *testing.T) {
func testCrossLayerUser(t *testing.T, allocType config.AllocType) {
futureTime := uint64(20)
farFutureTime := uint64(2000)
......@@ -75,14 +86,18 @@ func TestCrossLayerUser(t *testing.T) {
fork := fork
t.Run("fork_"+fork, func(t *testing.T) {
t.Run("at_genesis", func(t *testing.T) {
tc := hardforkScheduledTest{}
tc := hardforkScheduledTest{
allocType: allocType,
}
for _, f := range forks[:i+1] { // activate, all up to and incl this fork, at genesis
tc.SetFork(f, 0)
}
runCrossLayerUserTest(t, tc)
})
t.Run("after_genesis", func(t *testing.T) {
tc := hardforkScheduledTest{}
tc := hardforkScheduledTest{
allocType: allocType,
}
for _, f := range forks[:i] { // activate, all up to this fork, at genesis
tc.SetFork(f, 0)
}
......@@ -92,7 +107,9 @@ func TestCrossLayerUser(t *testing.T) {
runCrossLayerUserTest(t, tc)
})
t.Run("not_yet", func(t *testing.T) {
tc := hardforkScheduledTest{}
tc := hardforkScheduledTest{
allocType: allocType,
}
for _, f := range forks[:i] { // activate, all up to this fork, at genesis
tc.SetFork(f, 0)
}
......@@ -109,7 +126,9 @@ func TestCrossLayerUser(t *testing.T) {
func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, DefaultRollupTestParams)
params := DefaultRollupTestParams()
params.AllocType = test.allocType
dp := e2eutils.MakeDeployParams(t, params)
// This overwrites all deploy-config settings,
// so even when the deploy-config defaults change, we test the right transitions.
dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime
......@@ -136,7 +155,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
seq.RollupClient(), miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg))
var proposer *L2Proposer
if e2eutils.UseFaultProofs() {
if test.allocType.UsesProofs() {
optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2(sd.DeploymentsL1.OptimismPortalProxy, miner.EthClient())
require.NoError(t, err)
respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{})
......@@ -148,6 +167,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
DisputeGameType: respectedGameType,
ProposerKey: dp.Secrets.Proposer,
AllowNonFinalized: true,
AllocType: test.allocType,
}, miner.EthClient(), seq.RollupClient())
} else {
proposer = NewL2Proposer(t, log, &ProposerCfg{
......@@ -155,6 +175,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
ProposerKey: dp.Secrets.Proposer,
ProposalRetryInterval: 3 * time.Second,
AllowNonFinalized: true,
AllocType: test.allocType,
}, miner.EthClient(), seq.RollupClient())
}
......@@ -171,7 +192,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
EthCl: l1Cl,
Signer: types.LatestSigner(sd.L1Cfg.Config),
AddressCorpora: addresses,
Bindings: NewL1Bindings(t, l1Cl),
Bindings: NewL1Bindings(t, l1Cl, test.allocType),
}
l2UserEnv := &BasicUserEnv[*L2Bindings]{
EthCl: l2Cl,
......@@ -180,7 +201,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
Bindings: NewL2Bindings(t, l2Cl, l2ProofCl),
}
alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234)))
alice := NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(1234)), test.allocType)
alice.L1.SetUserEnv(l1UserEnv)
alice.L2.SetUserEnv(l2UserEnv)
......@@ -288,7 +309,7 @@ func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
miner.ActL1EndBlock(t)
// If using fault proofs we need to resolve the game
if e2eutils.UseFaultProofs() {
if test.allocType.UsesProofs() {
// Resolve the root claim
alice.ActResolveClaim(t)
miner.ActL1StartBlock(12)(t)
......
package helpers
import (
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-node/node/safedb"
"github.com/ethereum-optimism/optimism/op-node/rollup/interop"
......@@ -10,11 +11,14 @@ import (
"github.com/ethereum/go-ethereum/p2p"
)
var DefaultRollupTestParams = &e2eutils.TestParams{
MaxSequencerDrift: 40,
SequencerWindowSize: 120,
ChannelTimeout: 120,
L1BlockTime: 15,
func DefaultRollupTestParams() *e2eutils.TestParams {
return &e2eutils.TestParams{
MaxSequencerDrift: 40,
SequencerWindowSize: 120,
ChannelTimeout: 120,
L1BlockTime: 15,
AllocType: config.DefaultAllocType,
}
}
var DefaultAlloc = &e2eutils.AllocParams{PrefundTestUsers: true}
......
......@@ -20,7 +20,7 @@ var _ interop.InteropBackend = (*testutils.MockInteropBackend)(nil)
func TestInteropVerifier(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
// Temporary work-around: interop needs to be active, for cross-safety to not be instant.
// The state genesis in this test is pre-interop however.
......
......@@ -4,6 +4,8 @@ import (
"context"
"math/rand"
e2ecfg "github.com/ethereum-optimism/optimism/op-e2e/config"
altda "github.com/ethereum-optimism/optimism/op-alt-da"
batcherFlags "github.com/ethereum-optimism/optimism/op-batcher/flags"
"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
......@@ -90,7 +92,7 @@ func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eut
EthCl: l1EthCl,
Signer: types.LatestSigner(sd.L1Cfg.Config),
AddressCorpora: addresses,
Bindings: helpers.NewL1Bindings(t, l1EthCl),
Bindings: helpers.NewL1Bindings(t, l1EthCl, e2ecfg.AllocTypeStandard),
}
l2UserEnv := &helpers.BasicUserEnv[*helpers.L2Bindings]{
EthCl: l2EthCl,
......@@ -98,10 +100,10 @@ func NewL2FaultProofEnv[c any](t helpers.Testing, testCfg *TestCfg[c], tp *e2eut
AddressCorpora: addresses,
Bindings: helpers.NewL2Bindings(t, l2EthCl, engine.GethClient()),
}
alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)))
alice := helpers.NewCrossLayerUser(log, dp.Secrets.Alice, rand.New(rand.NewSource(0xa57b)), e2ecfg.AllocTypeStandard)
alice.L1.SetUserEnv(l1UserEnv)
alice.L2.SetUserEnv(l2UserEnv)
bob := helpers.NewCrossLayerUser(log, dp.Secrets.Bob, rand.New(rand.NewSource(0xbeef)))
bob := helpers.NewCrossLayerUser(log, dp.Secrets.Bob, rand.New(rand.NewSource(0xbeef)), e2ecfg.AllocTypeStandard)
bob.L1.SetUserEnv(l1UserEnv)
bob.L2.SetUserEnv(l2UserEnv)
......@@ -204,7 +206,7 @@ func (env *L2FaultProofEnv) RunFaultProofProgram(t helpers.Testing, l2ClaimBlock
type TestParam func(p *e2eutils.TestParams)
func NewTestParams(params ...TestParam) *e2eutils.TestParams {
dfault := helpers.DefaultRollupTestParams
dfault := helpers.DefaultRollupTestParams()
for _, apply := range params {
apply(dfault)
}
......
......@@ -5,6 +5,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
actionsHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
upgradesHelpers "github.com/ethereum-optimism/optimism/op-e2e/actions/upgrades/helpers"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
......@@ -23,31 +25,27 @@ import (
// TestProposerBatchType run each proposer-related test case in singular batch mode and span batch mode.
func TestProposerBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, deltaTimeOffset *hexutil.Uint64)
}{
{"RunProposerTest", RunProposerTest},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
deltaTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &deltaTimeOffset)
})
}
t.Run("SingularBatch/Standard", func(t *testing.T) {
runProposerTest(t, nil, config.AllocTypeStandard)
})
t.Run("SingularBatch/L2OO", func(t *testing.T) {
runProposerTest(t, nil, config.AllocTypeL2OO)
})
t.Run("SpanBatch/Standard", func(t *testing.T) {
deltaTimeOffset := hexutil.Uint64(0)
runProposerTest(t, &deltaTimeOffset, config.AllocTypeStandard)
})
t.Run("SpanBatch/L2OO", func(t *testing.T) {
deltaTimeOffset := hexutil.Uint64(0)
runProposerTest(t, &deltaTimeOffset, config.AllocTypeL2OO)
})
}
func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func runProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64, allocType config.AllocType) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
params := actionsHelpers.DefaultRollupTestParams()
params.AllocType = allocType
dp := e2eutils.MakeDeployParams(t, params)
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -58,7 +56,7 @@ func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
rollupSeqCl, miner.EthClient(), seqEngine.EthClient(), seqEngine.EngineClient(t, sd.RollupCfg))
var proposer *actionsHelpers.L2Proposer
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2(sd.DeploymentsL1.OptimismPortalProxy, miner.EthClient())
require.NoError(t, err)
respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{})
......@@ -70,6 +68,7 @@ func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
DisputeGameType: respectedGameType,
ProposerKey: dp.Secrets.Proposer,
AllowNonFinalized: true,
AllocType: allocType,
}, miner.EthClient(), rollupSeqCl)
} else {
proposer = actionsHelpers.NewL2Proposer(t, log, &actionsHelpers.ProposerCfg{
......@@ -77,6 +76,7 @@ func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
ProposerKey: dp.Secrets.Proposer,
ProposalRetryInterval: 3 * time.Second,
AllowNonFinalized: false,
AllocType: allocType,
}, miner.EthClient(), rollupSeqCl)
}
......@@ -118,7 +118,7 @@ func RunProposerTest(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
}
// check that L1 stored the expected output root
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
optimismPortal2Contract, err := bindingspreview.NewOptimismPortal2(sd.DeploymentsL1.OptimismPortalProxy, miner.EthClient())
require.NoError(t, err)
respectedGameType, err := optimismPortal2Contract.RespectedGameType(&bind.CallOpts{})
......
......@@ -14,7 +14,7 @@ import (
func TestRecordSafeHeadUpdates(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
sd, miner, sequencer, verifier, verifierEng, batcher := helpers.SetupSafeDBTest(t, actionsHelpers.DefaultRollupTestParams)
sd, miner, sequencer, verifier, verifierEng, batcher := helpers.SetupSafeDBTest(t, actionsHelpers.DefaultRollupTestParams())
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
sequencer.ActL2PipelineFull(t)
......
......@@ -4,6 +4,8 @@ import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/actions/helpers"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
......@@ -23,6 +25,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
......@@ -92,7 +95,7 @@ func TestL2Sequencer_SequencerDrift(gt *testing.T) {
// while the verifier-codepath only ever sees the valid post-reorg L1 chain.
func TestL2Sequencer_SequencerOnlyReorg(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
miner, _, sequencer := helpers.SetupSequencerTest(t, sd, log)
......
......@@ -67,7 +67,7 @@ func TestSyncBatchType(t *testing.T) {
func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create
......@@ -107,7 +107,7 @@ func DerivationWithFlakyL1RPC(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
upgradesHelpers.ApplyDeltaTimeOffset(dp, deltaTimeOffset)
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelError) // mute all the temporary derivation errors that we forcefully create
......@@ -153,7 +153,7 @@ func FinalizeWhileSyncing(gt *testing.T, deltaTimeOffset *hexutil.Uint64) {
// TestUnsafeSync tests that a verifier properly imports unsafe blocks via gossip.
func TestUnsafeSync(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelInfo)
......@@ -181,7 +181,7 @@ func TestUnsafeSync(gt *testing.T) {
func TestBackupUnsafe(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......@@ -342,7 +342,7 @@ func TestBackupUnsafe(gt *testing.T) {
func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......@@ -475,7 +475,7 @@ func TestBackupUnsafeReorgForkChoiceInputError(gt *testing.T) {
func TestBackupUnsafeReorgForkChoiceNotInputError(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......@@ -694,7 +694,7 @@ func BatchSubmitBlock(t actionsHelpers.Testing, miner *actionsHelpers.L1Miner, s
// when passed a single unsafe block. op-geth can either snap sync or full sync here.
func TestELSync(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelInfo)
......@@ -747,7 +747,7 @@ func PrepareELSyncedNode(t actionsHelpers.Testing, miner *actionsHelpers.L1Miner
// 8. Create 1 more block & batch submit everything & assert that the verifier picked up those blocks
func TestELSyncTransitionstoCL(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
logger := testlog.Logger(t, log.LevelInfo)
......@@ -804,7 +804,7 @@ func TestELSyncTransitionstoCL(gt *testing.T) {
func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
logger := testlog.Logger(t, log.LevelInfo)
......@@ -846,7 +846,7 @@ func TestELSyncTransitionsToCLSyncAfterNodeRestart(gt *testing.T) {
func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, actionsHelpers.DefaultAlloc)
logger := testlog.Logger(t, log.LevelInfo)
......@@ -892,7 +892,7 @@ func TestForcedELSyncCLAfterNodeRestart(gt *testing.T) {
func TestInvalidPayloadInSpanBatch(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......@@ -997,7 +997,7 @@ func TestInvalidPayloadInSpanBatch(gt *testing.T) {
func TestSpanBatchAtomicity_Consolidation(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......@@ -1065,7 +1065,7 @@ func TestSpanBatchAtomicity_Consolidation(gt *testing.T) {
func TestSpanBatchAtomicity_ForceAdvance(gt *testing.T) {
t := actionsHelpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, actionsHelpers.DefaultRollupTestParams())
minTs := hexutil.Uint64(0)
// Activate Delta hardfork
upgradesHelpers.ApplyDeltaTimeOffset(dp, &minTs)
......
......@@ -19,7 +19,7 @@ import (
func TestDencunL1ForkAfterGenesis(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
offset := hexutil.Uint64(24)
dp.DeployConfig.L1CancunTimeOffset = &offset
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
......@@ -62,7 +62,7 @@ func TestDencunL1ForkAfterGenesis(gt *testing.T) {
func TestDencunL1ForkAtGenesis(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset)
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -119,7 +119,7 @@ func verifyEcotoneBlock(gt *testing.T, header *types.Header) {
func TestDencunL2ForkAfterGenesis(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
require.Zero(t, *dp.DeployConfig.L1CancunTimeOffset)
// This test wil fork on the second block
offset := hexutil.Uint64(dp.DeployConfig.L2BlockTime * 2)
......@@ -157,7 +157,7 @@ func TestDencunL2ForkAfterGenesis(gt *testing.T) {
func TestDencunL2ForkAtGenesis(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
require.Zero(t, *dp.DeployConfig.L2GenesisEcotoneTimeOffset)
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
......@@ -195,7 +195,7 @@ func newEngine(t helpers.Testing, sd *e2eutils.SetupData, log log.Logger) *helpe
// TestDencunBlobTxRPC tries to send a Blob tx to the L2 engine via RPC, it should not be accepted.
func TestDencunBlobTxRPC(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -209,7 +209,7 @@ func TestDencunBlobTxRPC(gt *testing.T) {
// TestDencunBlobTxInTxPool tries to insert a blob tx directly into the tx pool, it should not be accepted.
func TestDencunBlobTxInTxPool(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......@@ -222,7 +222,7 @@ func TestDencunBlobTxInTxPool(gt *testing.T) {
// TestDencunBlobTxInclusion tries to send a Blob tx to the L2 engine, it should not be accepted.
func TestDencunBlobTxInclusion(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
sd := e2eutils.Setup(t, dp, helpers.DefaultAlloc)
log := testlog.Logger(t, log.LevelDebug)
......
......@@ -42,7 +42,7 @@ func verifyCodeHashMatches(t helpers.Testing, client *ethclient.Client, address
func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
ecotoneOffset := hexutil.Uint64(4)
log := testlog.Logger(t, log.LevelDebug)
......@@ -240,7 +240,7 @@ func TestEcotoneNetworkUpgradeTransactions(gt *testing.T) {
// TestEcotoneBeforeL1 tests that the L2 Ecotone fork can activate before L1 Dencun does
func TestEcotoneBeforeL1(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
offset := hexutil.Uint64(0)
farOffset := hexutil.Uint64(10000)
dp.DeployConfig.L2GenesisRegolithTimeOffset = &offset
......
......@@ -31,7 +31,7 @@ var (
func TestFjordNetworkUpgradeTransactions(gt *testing.T) {
t := helpers.NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams)
dp := e2eutils.MakeDeployParams(t, helpers.DefaultRollupTestParams())
genesisBlock := hexutil.Uint64(0)
fjordOffset := hexutil.Uint64(2)
......
......@@ -6,6 +6,8 @@ import (
crand "crypto/rand"
"fmt"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"math/big"
"math/rand"
"testing"
......@@ -39,6 +41,7 @@ func TestDropSpanBatchBeforeHardfork(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
// do not activate Delta hardfork for verifier
......@@ -128,6 +131,7 @@ func TestHardforkMiddleOfSpanBatch(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
......@@ -241,6 +245,7 @@ func TestAcceptSingularBatchAfterHardfork(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
minTs := hexutil.Uint64(0)
dp := e2eutils.MakeDeployParams(t, p)
......@@ -327,6 +332,7 @@ func TestMixOfBatchesAfterHardfork(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
minTs := hexutil.Uint64(0)
dp := e2eutils.MakeDeployParams(t, p)
......@@ -418,6 +424,7 @@ func TestSpanBatchEmptyChain(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
minTs := hexutil.Uint64(0)
......@@ -481,6 +488,7 @@ func TestSpanBatchLowThroughputChain(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
dp := e2eutils.MakeDeployParams(t, p)
minTs := hexutil.Uint64(0)
......@@ -595,6 +603,7 @@ func TestBatchEquivalence(gt *testing.T) {
SequencerWindowSize: 24,
ChannelTimeout: 20,
L1BlockTime: 12,
AllocType: config.AllocTypeStandard,
}
// Delta activated deploy config
dp := e2eutils.MakeDeployParams(t, p)
......
package config
import (
"encoding/json"
"errors"
"flag"
"fmt"
"log/slog"
"os"
"path/filepath"
"testing"
"slices"
"time"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -16,7 +13,6 @@ import (
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-e2e/external"
op_service "github.com/ethereum-optimism/optimism/op-service"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
)
......@@ -32,6 +28,35 @@ const (
LegacyLevelTrace
)
type AllocType string
const (
AllocTypeStandard AllocType = "standard"
AllocTypeAltDA AllocType = "alt-da"
AllocTypeL2OO AllocType = "l2oo"
AllocTypeMTCannon AllocType = "mt-cannon"
DefaultAllocType = AllocTypeStandard
)
func (a AllocType) Check() error {
if !slices.Contains(allocTypes, a) {
return fmt.Errorf("unknown alloc type: %q", a)
}
return nil
}
func (a AllocType) UsesProofs() bool {
switch a {
case AllocTypeStandard, AllocTypeMTCannon, AllocTypeAltDA:
return true
default:
return false
}
}
var allocTypes = []AllocType{AllocTypeStandard, AllocTypeAltDA, AllocTypeL2OO, AllocTypeMTCannon}
var (
// All of the following variables are set in the init function
// and read from JSON files on disk that are generated by the
......@@ -39,27 +64,56 @@ var (
// in end to end tests.
// L1Allocs represents the L1 genesis block state.
L1Allocs *foundry.ForgeAllocs
l1AllocsByType = make(map[AllocType]*foundry.ForgeAllocs)
// L1Deployments maps contract names to accounts in the L1
// genesis block state.
L1Deployments *genesis.L1Deployments
l1DeploymentsByType = make(map[AllocType]*genesis.L1Deployments)
// l2Allocs represents the L2 allocs, by hardfork/mode (e.g. delta, ecotone, interop, other)
l2Allocs map[genesis.L2AllocsMode]*foundry.ForgeAllocs
l2AllocsByType = make(map[AllocType]genesis.L2AllocsModeMap)
// DeployConfig represents the deploy config used by the system.
DeployConfig *genesis.DeployConfig
// ExternalL2Shim is the shim to use if external ethereum client testing is
// enabled
ExternalL2Shim string
// ExternalL2TestParms is additional metadata for executing external L2
// tests.
ExternalL2TestParms external.TestParms
deployConfigsByType = make(map[AllocType]*genesis.DeployConfig)
// EthNodeVerbosity is the (legacy geth) level of verbosity to output
EthNodeVerbosity int
)
func init() {
var l1AllocsPath, l2AllocsDir, l1DeploymentsPath, deployConfigPath, externalL2 string
func L1Allocs(allocType AllocType) *foundry.ForgeAllocs {
allocs, ok := l1AllocsByType[allocType]
if !ok {
panic(fmt.Errorf("unknown L1 alloc type: %q", allocType))
}
return allocs.Copy()
}
func L1Deployments(allocType AllocType) *genesis.L1Deployments {
deployments, ok := l1DeploymentsByType[allocType]
if !ok {
panic(fmt.Errorf("unknown L1 deployments type: %q", allocType))
}
return deployments.Copy()
}
func L2Allocs(allocType AllocType, mode genesis.L2AllocsMode) *foundry.ForgeAllocs {
allocsByType, ok := l2AllocsByType[allocType]
if !ok {
panic(fmt.Errorf("unknown L2 alloc type: %q", allocType))
}
allocs, ok := allocsByType[mode]
if !ok {
panic(fmt.Errorf("unknown L2 allocs mode: %q", mode))
}
return allocs.Copy()
}
func DeployConfig(allocType AllocType) *genesis.DeployConfig {
dc, ok := deployConfigsByType[allocType]
if !ok {
panic(fmt.Errorf("unknown deploy config type: %q", allocType))
}
return dc.Copy()
}
func init() {
cwd, err := os.Getwd()
if err != nil {
panic(err)
......@@ -69,19 +123,9 @@ func init() {
panic(err)
}
defaultL1AllocsPath := filepath.Join(root, ".devnet", "allocs-l1.json")
defaultL2AllocsDir := filepath.Join(root, ".devnet")
defaultL1DeploymentsPath := filepath.Join(root, ".devnet", "addresses.json")
defaultDeployConfigPath := filepath.Join(root, "packages", "contracts-bedrock", "deploy-config", "devnetL1.json")
flag.StringVar(&l1AllocsPath, "l1-allocs", defaultL1AllocsPath, "")
flag.StringVar(&l2AllocsDir, "l2-allocs-dir", defaultL2AllocsDir, "")
flag.StringVar(&l1DeploymentsPath, "l1-deployments", defaultL1DeploymentsPath, "")
flag.StringVar(&deployConfigPath, "deploy-config", defaultDeployConfigPath, "")
flag.StringVar(&externalL2, "externalL2", "", "Enable tests with external L2")
flag.IntVar(&EthNodeVerbosity, "ethLogVerbosity", LegacyLevelInfo, "The (legacy geth) level of verbosity to use for the eth node logs")
testing.Init() // Register test flags before parsing
flag.Parse()
for _, allocType := range allocTypes {
initAllocType(root, allocType)
}
// Setup global logger
lvl := log.FromLegacyLevel(EthNodeVerbosity)
......@@ -102,100 +146,81 @@ func init() {
})
}
oplog.SetGlobalLogHandler(handler)
}
if err := allExist(l1AllocsPath, l1DeploymentsPath, deployConfigPath); err != nil {
func initAllocType(root string, allocType AllocType) {
devnetDir := filepath.Join(root, fmt.Sprintf(".devnet-%s", allocType))
l1AllocsPath := filepath.Join(devnetDir, "allocs-l1.json")
l2AllocsDir := devnetDir
l1DeploymentsPath := filepath.Join(devnetDir, "addresses.json")
deployConfigPath := filepath.Join(root, "packages", "contracts-bedrock", "deploy-config", "devnetL1.json")
var missing bool
for _, fp := range []string{devnetDir, l1AllocsPath, l1DeploymentsPath} {
_, err := os.Stat(fp)
if os.IsNotExist(err) {
missing = true
break
}
if err != nil {
panic(err)
}
}
if missing {
log.Warn("allocs file not found, skipping", "allocType", allocType)
return
}
L1Allocs, err = foundry.LoadForgeAllocs(l1AllocsPath)
l1Allocs, err := foundry.LoadForgeAllocs(l1AllocsPath)
if err != nil {
panic(err)
}
l2Allocs = make(map[genesis.L2AllocsMode]*foundry.ForgeAllocs)
l1AllocsByType[allocType] = l1Allocs
l2Alloc := make(map[genesis.L2AllocsMode]*foundry.ForgeAllocs)
mustL2Allocs := func(mode genesis.L2AllocsMode) {
name := "allocs-l2-" + string(mode)
allocs, err := foundry.LoadForgeAllocs(filepath.Join(l2AllocsDir, name+".json"))
if err != nil {
panic(err)
}
l2Allocs[mode] = allocs
l2Alloc[mode] = allocs
}
mustL2Allocs(genesis.L2AllocsGranite)
mustL2Allocs(genesis.L2AllocsFjord)
mustL2Allocs(genesis.L2AllocsEcotone)
mustL2Allocs(genesis.L2AllocsDelta)
L1Deployments, err = genesis.NewL1Deployments(l1DeploymentsPath)
l2AllocsByType[allocType] = l2Alloc
l1Deployments, err := genesis.NewL1Deployments(l1DeploymentsPath)
if err != nil {
panic(err)
}
DeployConfig, err = genesis.NewDeployConfig(deployConfigPath)
l1DeploymentsByType[allocType] = l1Deployments
dc, err := genesis.NewDeployConfig(deployConfigPath)
if err != nil {
panic(err)
}
// Do not use clique in the in memory tests. Otherwise block building
// would be much more complex.
DeployConfig.L1UseClique = false
dc.L1UseClique = false
// Set the L1 genesis block timestamp to now
DeployConfig.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix())
DeployConfig.FundDevAccounts = true
dc.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix())
dc.FundDevAccounts = true
// Speed up the in memory tests
DeployConfig.L1BlockTime = 2
DeployConfig.L2BlockTime = 1
if L1Deployments != nil {
DeployConfig.SetDeployments(L1Deployments)
}
if externalL2 != "" {
if err := initExternalL2(externalL2); err != nil {
panic(fmt.Errorf("could not initialize external L2: %w", err))
}
}
}
func L2Allocs(mode genesis.L2AllocsMode) *foundry.ForgeAllocs {
allocs, ok := l2Allocs[mode]
if !ok {
panic(fmt.Errorf("unknown L2 allocs mode: %q", mode))
}
return allocs.Copy()
dc.L1BlockTime = 2
dc.L2BlockTime = 1
dc.SetDeployments(l1Deployments)
deployConfigsByType[allocType] = dc
}
func initExternalL2(externalL2 string) error {
var err error
ExternalL2Shim, err = filepath.Abs(filepath.Join(externalL2, "shim"))
if err != nil {
return fmt.Errorf("could not compute abs of externalL2Nodes shim: %w", err)
}
_, err = os.Stat(ExternalL2Shim)
if err != nil {
return fmt.Errorf("failed to stat externalL2Nodes path: %w", err)
}
file, err := os.Open(filepath.Join(externalL2, "test_parms.json"))
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil
}
return fmt.Errorf("could not open external L2 test parms: %w", err)
}
defer file.Close()
if err := json.NewDecoder(file).Decode(&ExternalL2TestParms); err != nil {
return fmt.Errorf("could not decode external L2 test parms: %w", err)
func AllocTypeFromEnv() AllocType {
allocType := os.Getenv("OP_E2E_ALLOC_TYPE")
if allocType == "" {
return DefaultAllocType
}
return nil
}
func allExist(filenames ...string) error {
for _, filename := range filenames {
if _, err := os.Stat(filename); err != nil {
fmt.Printf("file %s does not exist, skipping genesis generation\n", filename)
return err
}
out := AllocType(allocType)
if err := out.Check(); err != nil {
panic(err)
}
return nil
return out
}
package devnet
import (
"context"
"log/slog"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/system/bridge"
"github.com/ethereum-optimism/optimism/op-service/testlog"
)
func TestDevnet(t *testing.T) {
lgr := testlog.Logger(t, slog.LevelDebug)
ctx, done := context.WithTimeout(context.Background(), time.Minute)
defer done()
sys, err := NewSystem(ctx, lgr)
require.NoError(t, err)
t.Run("SyncFinalized", func(t *testing.T) {
// SyncFinalized can run in parallel to Withdrawals test, because propopser
// already posts unfinalized output roots in devnet mode.
t.Parallel()
testSyncFinalized(t, sys)
})
t.Run("Withdrawal", func(t *testing.T) {
t.Parallel()
bridge.RunWithdrawalsTest(t, sys)
})
}
func testSyncFinalized(t *testing.T, sys *System) {
const timeout = 4 * time.Minute
ctx, done := context.WithTimeout(context.Background(), timeout)
defer done()
require.EventuallyWithT(t, func(tc *assert.CollectT) {
ss, err := sys.Rollup.SyncStatus(ctx)
assert.NoError(tc, err)
if err != nil {
t.Log(err)
return
}
t.Logf("SyncStatus: %+v", ss)
assert.NotZero(tc, ss.FinalizedL2.Number)
}, timeout, 2*time.Second)
}
package devnet
import (
"context"
"crypto/ecdsa"
"os"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
op_service "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
// TODO(#10968): read from docker-compose.yml
const (
L1RPCURL = "http://127.0.0.1:8545"
L2RPCURL = "http://127.0.0.1:9545"
RollupURL = "http://127.0.0.1:7545"
)
type System struct {
L1 *ethclient.Client
L2 *ethclient.Client
Rollup *sources.RollupClient
Cfg e2esys.SystemConfig
}
func NewSystem(ctx context.Context, lgr log.Logger) (sys *System, err error) {
sys = new(System)
sys.L1, err = dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, L1RPCURL)
if err != nil {
return nil, err
}
sys.L2, err = dial.DialEthClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, L2RPCURL)
if err != nil {
return nil, err
}
sys.Rollup, err = dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, lgr, RollupURL)
if err != nil {
return nil, err
}
secrets, err := e2eutils.DefaultMnemonicConfig.Secrets()
if err != nil {
return nil, err
}
// TODO(#10968): We need to re-read the deploy config because op-e2e/config.init() overwrites
// some deploy config variables. This will be fixed soon.
cwd, err := os.Getwd()
if err != nil {
return nil, err
}
root, err := op_service.FindMonorepoRoot(cwd)
if err != nil {
return nil, err
}
deployConfigPath := filepath.Join(root, "packages", "contracts-bedrock", "deploy-config", "devnetL1.json")
deployConfig, err := genesis.NewDeployConfig(deployConfigPath)
if err != nil {
return nil, err
}
// Incomplete SystemConfig suffices for withdrawal test (only consumer right now)
sys.Cfg = e2esys.SystemConfig{
DeployConfig: deployConfig,
L1Deployments: config.L1Deployments.Copy(),
Secrets: secrets,
}
return sys, nil
}
func (s System) NodeClient(role string) *ethclient.Client {
switch role {
case e2esys.RoleL1:
return s.L1
case e2esys.RoleSeq, e2esys.RoleVerif:
// we have only one L2 node
return s.L2
default:
panic("devnet.System: unknown role: " + role)
}
}
func (s System) RollupClient(string) *sources.RollupClient {
// we ignore role, have only one L2 rollup
return s.Rollup
}
func (s System) Config() e2esys.SystemConfig {
return s.Cfg
}
func (s System) TestAccount(idx int) *ecdsa.PrivateKey {
// first 12 indices are in use by the devnet
return s.Cfg.Secrets.AccountAtIdx(13 + idx)
}
......@@ -2,30 +2,15 @@ package op_e2e
import (
"crypto/md5"
"fmt"
"os"
"runtime"
"strconv"
"strings"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
)
func RunMain(m *testing.M) {
if config.ExternalL2Shim != "" {
fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim)
// As these are integration tests which launch many other processes, the
// default parallelism makes the tests flaky. This change aims to
// reduce the flakiness of these tests.
maxProcs := runtime.NumCPU() / 4
if maxProcs == 0 {
maxProcs = 1
}
runtime.GOMAXPROCS(maxProcs)
}
os.Exit(m.Run())
}
......@@ -67,18 +52,6 @@ func UsesCannon(t e2eutils.TestingBase) {
}
}
func SkipOnFaultProofs(t e2eutils.TestingBase) {
if e2eutils.UseFaultProofs() {
t.Skip("Skipping test for fault proofs")
}
}
func SkipOnL2OO(t e2eutils.TestingBase) {
if e2eutils.UseL2OO() {
t.Skip("Skipping test for L2OO")
}
}
type executorInfo struct {
total uint64
idx uint64
......
......@@ -3,6 +3,8 @@ package e2eutils
import (
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/stretchr/testify/require"
)
......@@ -12,6 +14,7 @@ func TestCollectAddresses(t *testing.T) {
SequencerWindowSize: 120,
ChannelTimeout: 120,
L1BlockTime: 15,
AllocType: config.AllocTypeStandard,
}
dp := MakeDeployParams(t, tp)
alloc := &AllocParams{PrefundTestUsers: true}
......
......@@ -11,6 +11,8 @@ import (
"testing"
"time"
e2econfig "github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-service/crypto"
"github.com/ethereum/go-ethereum/ethclient"
......@@ -23,7 +25,6 @@ import (
challenger "github.com/ethereum-optimism/optimism/op-challenger"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
......@@ -115,12 +116,12 @@ func FindMonorepoRoot(t *testing.T) string {
return ""
}
func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) {
func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis, allocType e2econfig.AllocType) {
require := require.New(t)
root := FindMonorepoRoot(t)
c.Cannon.VmBin = root + "cannon/bin/cannon"
c.Cannon.Server = root + "op-program/bin/op-program"
if e2eutils.UseMTCannon() {
if allocType == e2econfig.AllocTypeMTCannon {
t.Log("Using MT-Cannon absolute prestate")
c.CannonAbsolutePreState = root + "op-program/bin/prestate-mt.bin.gz"
} else {
......@@ -141,17 +142,17 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config,
c.Cannon.RollupConfigPath = rollupFile
}
func WithCannon(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) Option {
func WithCannon(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis, allocType e2econfig.AllocType) Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, types.TraceTypeCannon)
applyCannonConfig(c, t, rollupCfg, l2Genesis)
applyCannonConfig(c, t, rollupCfg, l2Genesis, allocType)
}
}
func WithPermissioned(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) Option {
func WithPermissioned(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis, allocType e2econfig.AllocType) Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, types.TraceTypePermissioned)
applyCannonConfig(c, t, rollupCfg, l2Genesis)
applyCannonConfig(c, t, rollupCfg, l2Genesis, allocType)
}
}
......
......@@ -8,6 +8,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
......@@ -94,6 +96,7 @@ type FactoryHelper struct {
PrivKey *ecdsa.PrivateKey
FactoryAddr common.Address
Factory *bindings.DisputeGameFactory
AllocType config.AllocType
}
type FactoryCfg struct {
......@@ -113,6 +116,10 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem, o
client := system.NodeClient("l1")
chainID, err := client.ChainID(ctx)
require.NoError(err)
allocType := config.AllocTypeFromEnv()
require.True(allocType.UsesProofs(), "AllocType %v does not support proofs", allocType)
factoryCfg := &FactoryCfg{PrivKey: TestKey}
for _, opt := range opts {
opt(factoryCfg)
......@@ -134,6 +141,7 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem, o
PrivKey: factoryCfg.PrivKey,
Factory: factory,
FactoryAddr: factoryAddr,
AllocType: allocType,
}
}
......@@ -208,7 +216,7 @@ func (h *FactoryHelper) startOutputCannonGameOfType(ctx context.Context, l2Node
provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
return &OutputCannonGameHelper{
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, h.PrivKey, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System),
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, h.PrivKey, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System, h.AllocType),
}
}
......@@ -262,7 +270,7 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
return &OutputAlphabetGameHelper{
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, h.PrivKey, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System),
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, h.PrivKey, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System, h.AllocType),
}
}
......
......@@ -35,7 +35,7 @@ type OutputCannonGameHelper struct {
func (g *OutputCannonGameHelper) StartChallenger(ctx context.Context, name string, options ...challenger.Option) *challenger.Helper {
opts := []challenger.Option{
challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis()),
challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis(), g.AllocType),
challenger.WithFactoryAddress(g.FactoryAddr),
challenger.WithGameAddress(g.Addr),
}
......@@ -331,7 +331,7 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context,
func (g *OutputCannonGameHelper) defaultChallengerOptions() []challenger.Option {
return []challenger.Option{
challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis()),
challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis(), g.AllocType),
challenger.WithFactoryAddress(g.FactoryAddr),
challenger.WithGameAddress(g.Addr),
}
......
......@@ -9,6 +9,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
......@@ -40,10 +42,11 @@ type OutputGameHelper struct {
Addr common.Address
CorrectOutputProvider *outputs.OutputTraceProvider
System DisputeSystem
AllocType config.AllocType
}
func NewOutputGameHelper(t *testing.T, require *require.Assertions, client *ethclient.Client, opts *bind.TransactOpts, privKey *ecdsa.PrivateKey,
game contracts.FaultDisputeGameContract, factoryAddr common.Address, addr common.Address, correctOutputProvider *outputs.OutputTraceProvider, system DisputeSystem) *OutputGameHelper {
game contracts.FaultDisputeGameContract, factoryAddr common.Address, addr common.Address, correctOutputProvider *outputs.OutputTraceProvider, system DisputeSystem, allocType config.AllocType) *OutputGameHelper {
return &OutputGameHelper{
T: t,
Require: require,
......@@ -55,6 +58,7 @@ func NewOutputGameHelper(t *testing.T, require *require.Assertions, client *ethc
Addr: addr,
CorrectOutputProvider: correctOutputProvider,
System: system,
AllocType: allocType,
}
}
......
......@@ -39,6 +39,7 @@ type DeployParams struct {
MnemonicConfig *MnemonicConfig
Secrets *Secrets
Addresses *Addresses
AllocType config.AllocType
}
// TestParams parametrizes the most essential rollup configuration parameters
......@@ -48,6 +49,7 @@ type TestParams struct {
ChannelTimeout uint64
L1BlockTime uint64
UseAltDA bool
AllocType config.AllocType
}
func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
......@@ -56,7 +58,7 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
require.NoError(t, err)
addresses := secrets.Addresses()
deployConfig := config.DeployConfig.Copy()
deployConfig := config.DeployConfig(tp.AllocType)
deployConfig.MaxSequencerDrift = tp.MaxSequencerDrift
deployConfig.SequencerWindowSize = tp.SequencerWindowSize
deployConfig.ChannelTimeoutBedrock = tp.ChannelTimeout
......@@ -75,6 +77,7 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
MnemonicConfig: mnemonicCfg,
Secrets: secrets,
Addresses: addresses,
AllocType: tp.AllocType,
}
}
......@@ -110,10 +113,14 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
logger := log.NewLogger(log.DiscardHandler())
require.NoError(t, deployConf.Check(logger))
l1Deployments := config.L1Deployments.Copy()
l1Deployments := config.L1Deployments(deployParams.AllocType)
require.NoError(t, l1Deployments.Check(deployConf))
l1Genesis, err := genesis.BuildL1DeveloperGenesis(deployConf, config.L1Allocs, l1Deployments)
l1Genesis, err := genesis.BuildL1DeveloperGenesis(
deployConf,
config.L1Allocs(deployParams.AllocType),
l1Deployments,
)
require.NoError(t, err, "failed to create l1 genesis")
if alloc.PrefundTestUsers {
for _, addr := range deployParams.Addresses.All() {
......@@ -133,7 +140,7 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
if ecotoneTime := deployConf.EcotoneTime(l1Block.Time()); ecotoneTime != nil && *ecotoneTime == 0 {
allocsMode = genesis.L2AllocsEcotone
}
l2Allocs := config.L2Allocs(allocsMode)
l2Allocs := config.L2Allocs(deployParams.AllocType, allocsMode)
l2Genesis, err := genesis.BuildL2Genesis(deployConf, l2Allocs, l1Block.Header())
require.NoError(t, err, "failed to create l2 genesis")
if alloc.PrefundTestUsers {
......@@ -235,22 +242,3 @@ func ApplyDeployConfigForks(deployConfig *genesis.DeployConfig) {
deployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64)
deployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64)
}
func UseFaultProofs() bool {
return !UseL2OO()
}
func UseL2OO() bool {
return (os.Getenv("OP_E2E_USE_L2OO") == "true" ||
os.Getenv("DEVNET_L2OO") == "true")
}
func UseAltDA() bool {
return (os.Getenv("OP_E2E_USE_ALTDA") == "true" ||
os.Getenv("DEVNET_ALTDA") == "true")
}
func UseMTCannon() bool {
return (os.Getenv("OP_E2E_USE_MT_CANNON") == "true" ||
os.Getenv("USE_MT_CANNON") == "true")
}
......@@ -24,6 +24,7 @@ func TestSetup(t *testing.T) {
SequencerWindowSize: 120,
ChannelTimeout: 120,
L1BlockTime: 15,
AllocType: config.AllocTypeStandard,
}
dp := MakeDeployParams(t, tp)
alloc := &AllocParams{PrefundTestUsers: true}
......@@ -34,6 +35,7 @@ func TestSetup(t *testing.T) {
require.Contains(t, sd.L2Cfg.Alloc, dp.Addresses.Alice)
require.Equal(t, sd.L2Cfg.Alloc[dp.Addresses.Alice].Balance, Ether(1e12))
require.Contains(t, sd.L1Cfg.Alloc, config.L1Deployments.OptimismPortalProxy)
expAllocs := config.L1Deployments(config.DefaultAllocType)
require.Contains(t, sd.L1Cfg.Alloc, expAllocs.AddressManager)
require.Contains(t, sd.L2Cfg.Alloc, predeploys.L1BlockAddr)
}
package external
import (
"bytes"
"encoding/json"
"os"
"strings"
"testing"
)
type Config struct {
DataDir string `json:"data_dir"`
JWTPath string `json:"jwt_path"`
ChainID uint64 `json:"chain_id"`
GasCeil uint64 `json:"gas_ceil"`
GenesisPath string `json:"genesis_path"`
Verbosity uint64 `json:"verbosity"`
// EndpointsReadyPath is the location to write the endpoint configuration file.
// Note, this should be written atomically by writing the JSON, then moving
// it to this path to avoid races. A helper AtomicEncode is provided for
// golang clients.
EndpointsReadyPath string `json:"endpoints_ready_path"`
}
// AtomicEncode json encodes val to path+".atomic" then moves the path+".atomic"
// file to path
func AtomicEncode(path string, val any) error {
atomicPath := path + ".atomic"
atomicFile, err := os.Create(atomicPath)
if err != nil {
return err
}
defer atomicFile.Close()
if err = json.NewEncoder(atomicFile).Encode(val); err != nil {
return err
}
return os.Rename(atomicPath, path)
}
type Endpoints struct {
HTTPEndpoint string `json:"http_endpoint"`
WSEndpoint string `json:"ws_endpoint"`
HTTPAuthEndpoint string `json:"http_auth_endpoint"`
WSAuthEndpoint string `json:"ws_auth_endpoint"`
}
type TestParms struct {
// SkipTests is a map from test name to skip message. The skip message may
// be arbitrary, but the test name should match the skipped test (either
// base, or a sub-test) exactly. Precisely, the skip name must match rune for
// rune starting with the first rune. If the skip name does not match all
// runes, the first mismatched rune must be a '/'.
SkipTests map[string]string `json:"skip_tests"`
}
func (tp TestParms) SkipIfNecessary(t testing.TB) {
if len(tp.SkipTests) == 0 {
return
}
var base bytes.Buffer
for _, name := range strings.Split(t.Name(), "/") {
base.WriteString(name)
if msg, ok := tp.SkipTests[base.String()]; ok {
t.Skip(msg)
}
base.WriteRune('/')
}
}
default: shim op-geth
op-geth:
go build -o op-geth "github.com/ethereum/go-ethereum/cmd/geth"
.PHONY: op-geth
shim: main.go
go build -o shim .
# external_geth shim
This shim is an example of how to write an adapter for an external ethereum
client to allow for its use in the op-e2e tests.
## Invocation
Generally speaking, you can utilize this shim by simply executing:
```
make test-external-geth
```
The `Makefile` is structured such that if you duplicate this directory and
tweak this code, you may simply execute:
```
make test-external-<your-client>
```
and the execution should happen as well.
*NOTE:* Attempting to iterate for development requires explicit rebuilding of
the binary being shimmed. Most likely to accomplish this, you may want to add
initialization code to the TestMain of the e2e to build your binary, or use
some other technique like custom build scripts or IDE integrations which cause
the binary to be rebuilt before executing the tests.
## Arguments
*--config <path>* The config path is a required argument, it points to a JSON
file that contains details of the L2 environment to bring up (including the
`genesis.json` path, the chain ID, the JWT path, and a ready file path). See
the data structures in `op-e2e/external/config.go` for more details.
## Operation
This shim will first execute a process to initialize the op-geth database.
Then, it will start the op-geth process itself. It watches the output of the
process and looks for the lines indicating that the HTTP server and Auth HTTP
server have started up. It then reads the ports which were allocated (because
the requested ports were passed in as ephemeral via the CLI arguments).
## Skipping tests
Although ideally, all tests would be structured such that they may execute
either with an in-process op-geth or with an extra-process ethereum client,
this is not always the case. You may optionally create a `test_parms.json`
file in the `external_<your-client>` directory, as there is in the
`external_geth` directory which specifies a map of tests to skip, and
accompanying skip text. See the `op-e2e/external/config.go` file for more
details.
## Generalization
This shim is included to help document and demonstrates the usage of the
external ethereum process e2e test execution. It is configured to execute in
CI to help ensure that the tests remain compatible with external clients.
To create your own external test client, these files can likely be used as a
starting point, changing the arguments, log scraping, and other details. Or,
depending on the client and your preference, any binary which is capable of
reading and writing the necessary JSON files should be sufficient (though
will be required to replicate some of the parsing and other logic encapsulated
here).
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strconv"
"syscall"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/external"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)
func main() {
var configPath string
flag.StringVar(&configPath, "config", "", "Execute based on the config in this file")
flag.Parse()
if err := run(configPath); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
os.Exit(0)
}
func run(configPath string) error {
if configPath == "" {
return fmt.Errorf("must supply a '--config <path>' flag")
}
configFile, err := os.Open(configPath)
if err != nil {
return fmt.Errorf("could not open config: %w", err)
}
var config external.Config
if err := json.NewDecoder(configFile).Decode(&config); err != nil {
return fmt.Errorf("could not decode config file: %w", err)
}
binPath, err := filepath.Abs("op-geth")
if err != nil {
return fmt.Errorf("could not get absolute path of op-geth")
}
if _, err := os.Stat(binPath); err != nil {
return fmt.Errorf("could not locate op-geth in working directory, did you forget to run '--init'?")
}
fmt.Printf("================== op-geth shim initializing chain config ==========================\n")
if err := initialize(binPath, config); err != nil {
return fmt.Errorf("could not initialize datadir: %s %w", binPath, err)
}
fmt.Printf("================== op-geth shim executing op-geth ==========================\n")
sess, err := execute(binPath, config)
if err != nil {
return fmt.Errorf("could not execute geth: %w", err)
}
defer sess.Close()
fmt.Printf("================== op-geth shim encoding ready-file ==========================\n")
if err := external.AtomicEncode(config.EndpointsReadyPath, sess.endpoints); err != nil {
return fmt.Errorf("could not encode endpoints")
}
fmt.Printf("================== op-geth shim awaiting termination ==========================\n")
sigs := make(chan os.Signal, 1)
defer signal.Stop(sigs)
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
select {
case <-sigs:
fmt.Printf("================== op-geth shim caught signal, killing ==========================\n")
sess.session.Terminate()
return awaitExit(sess.session)
case <-sess.session.Exited:
return fmt.Errorf("geth exited with code %d", sess.session.ExitCode())
case <-time.After(30 * time.Minute):
fmt.Printf("================== op-geth shim timed out, killing ==========================\n")
sess.session.Terminate()
if err := awaitExit(sess.session); err != nil {
fmt.Printf("error killing geth: %v\n", err)
}
return errors.New("geth timed out after 30 minutes")
}
}
func awaitExit(sess *gexec.Session) error {
select {
case <-sess.Exited:
return nil
case <-time.After(5 * time.Second):
sess.Kill()
select {
case <-sess.Exited:
return nil
case <-time.After(30 * time.Second):
return fmt.Errorf("exiting after 30 second timeout")
}
}
}
func initialize(binPath string, config external.Config) error {
cmd := exec.Command(
binPath,
"--datadir", config.DataDir,
"--state.scheme=hash",
"init", config.GenesisPath,
)
return cmd.Run()
}
type gethSession struct {
session *gexec.Session
endpoints *external.Endpoints
}
func (es *gethSession) Close() {
es.session.Terminate()
select {
case <-time.After(5 * time.Second):
es.session.Kill()
case <-es.session.Exited:
}
}
func execute(binPath string, config external.Config) (*gethSession, error) {
if config.Verbosity < 2 {
return nil, fmt.Errorf("a minimum configured verbosity of 2 is required")
}
cmd := exec.Command(
binPath,
"--datadir", config.DataDir,
"--http",
"--http.addr", "127.0.0.1",
"--http.port", "0",
"--http.api", "web3,debug,eth,txpool,net,engine",
"--ws",
"--ws.addr", "127.0.0.1",
"--ws.port", "0",
"--ws.api", "debug,eth,txpool,net,engine",
"--syncmode=full",
"--state.scheme=hash",
"--nodiscover",
"--port", "0",
"--maxpeers", "0",
"--networkid", strconv.FormatUint(config.ChainID, 10),
"--authrpc.addr", "127.0.0.1",
"--authrpc.port", "0",
"--authrpc.jwtsecret", config.JWTPath,
"--gcmode=archive",
"--verbosity", strconv.FormatUint(config.Verbosity, 10),
)
sess, err := gexec.Start(cmd, os.Stdout, os.Stderr)
if err != nil {
return nil, fmt.Errorf("could not start op-geth session: %w", err)
}
matcher := gbytes.Say("HTTP server started\\s*endpoint=127.0.0.1:")
var enginePort, httpPort int
for enginePort == 0 || httpPort == 0 {
match, err := matcher.Match(sess.Err)
if err != nil {
return nil, fmt.Errorf("could not execute matcher")
}
if !match {
if sess.Err.Closed() {
return nil, fmt.Errorf("op-geth exited before announcing http ports")
}
// Wait for a bit more output, then try again
time.Sleep(10 * time.Millisecond)
continue
}
var authString string
var port int
if _, err := fmt.Fscanf(sess.Err, "%d %s", &port, &authString); err != nil && !errors.Is(err, io.EOF) {
return nil, fmt.Errorf("error while reading auth string: %w", err)
}
switch authString {
case "auth=true":
enginePort = port
case "auth=false":
httpPort = port
default:
return nil, fmt.Errorf("unexpected auth string %q", authString)
}
}
return &gethSession{
session: sess,
endpoints: &external.Endpoints{
HTTPEndpoint: fmt.Sprintf("http://127.0.0.1:%d/", httpPort),
WSEndpoint: fmt.Sprintf("ws://127.0.0.1:%d/", httpPort),
HTTPAuthEndpoint: fmt.Sprintf("http://127.0.0.1:%d/", enginePort),
WSAuthEndpoint: fmt.Sprintf("ws://127.0.0.1:%d/", enginePort),
},
}, nil
}
package main
import (
"net"
"net/url"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-service/endpoint"
)
func TestShim(t *testing.T) {
shimPath, err := filepath.Abs("shim")
require.NoError(t, err)
cmd := exec.Command("go", "build", "-o", shimPath, ".")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
require.NoError(t, err)
require.FileExists(t, "shim")
opGethPath, err := filepath.Abs("op-geth")
require.NoError(t, err)
cmd = exec.Command("go", "build", "-o", opGethPath, "github.com/ethereum/go-ethereum/cmd/geth")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
require.NoError(t, err)
require.FileExists(t, "op-geth")
config.EthNodeVerbosity = config.LegacyLevelDebug
ec := (&e2esys.ExternalRunner{
Name: "TestShim",
BinPath: shimPath,
}).Run(t)
t.Cleanup(func() { _ = ec.Close() })
for _, rpcEndpoint := range []string{
ec.UserRPC().(endpoint.HttpRPC).HttpRPC(),
ec.AuthRPC().(endpoint.HttpRPC).HttpRPC(),
ec.UserRPC().(endpoint.WsRPC).WsRPC(),
ec.AuthRPC().(endpoint.WsRPC).WsRPC(),
} {
plainURL, err := url.ParseRequestURI(rpcEndpoint)
require.NoError(t, err)
_, err = net.DialTimeout("tcp", plainURL.Host, time.Second)
require.NoError(t, err, "could not connect to HTTP port")
}
}
{
"skip_tests":{
"TestPendingGasLimit":"This test requires directly modifying go structures and cannot be implemented with flags"
}
}
//go:build tools
package main
import _ "github.com/ethereum/go-ethereum/cmd/geth"
......@@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
......@@ -27,7 +29,7 @@ func TestMultipleGameTypes(t *testing.T) {
// Start a challenger with both cannon and alphabet support
gameFactory.StartChallenger(ctx, "TowerDefense",
challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg),
challenger.WithCannon(t, sys.RollupConfig, sys.L2GenesisCfg, config.AllocTypeFromEnv()),
challenger.WithAlphabet(),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
)
......
......@@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/ethereum-optimism/optimism/op-e2e/config"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
......@@ -26,7 +28,7 @@ func TestPermissionedGameType(t *testing.T) {
gameFactory.StartChallenger(ctx, "TowerDefense",
challenger.WithValidPrestateRequired(),
challenger.WithInvalidCannonPrestate(),
challenger.WithPermissioned(t, sys.RollupConfig, sys.L2GenesisCfg),
challenger.WithPermissioned(t, sys.RollupConfig, sys.L2GenesisCfg, config.AllocTypeFromEnv()),
challenger.WithPrivKey(sys.Cfg.Secrets.Alice),
)
......
......@@ -7,6 +7,8 @@ import (
"path/filepath"
"testing"
e2econfig "github.com/ethereum-optimism/optimism/op-e2e/config"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
......@@ -250,7 +252,7 @@ func runCannon(t *testing.T, ctx context.Context, sys *e2esys.System, inputs uti
l1Beacon := sys.L1BeaconEndpoint().RestHTTP()
rollupEndpoint := sys.RollupEndpoint("sequencer").RPC()
l2Endpoint := sys.NodeEndpoint("sequencer").RPC()
cannonOpts := challenger.WithCannon(t, sys.RollupCfg(), sys.L2Genesis())
cannonOpts := challenger.WithCannon(t, sys.RollupCfg(), sys.L2Genesis(), e2econfig.AllocTypeFromEnv())
dir := t.TempDir()
proofsDir := filepath.Join(dir, "cannon-proofs")
cfg := config.NewConfig(common.Address{}, l1Endpoint, l1Beacon, rollupEndpoint, l2Endpoint, dir)
......
......@@ -56,7 +56,7 @@ type OpGeth struct {
func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*OpGeth, error) {
logger := testlog.Logger(t, log.LevelCrit)
l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs, config.L1Deployments)
l1Genesis, err := genesis.BuildL1DeveloperGenesis(cfg.DeployConfig, config.L1Allocs(config.AllocTypeStandard), config.L1Deployments(config.AllocTypeStandard))
require.NoError(t, err)
l1Block := l1Genesis.ToBlock()
......@@ -69,7 +69,7 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*Op
} else if ecotoneTime := cfg.DeployConfig.EcotoneTime(l1Block.Time()); ecotoneTime != nil && *ecotoneTime <= 0 {
allocsMode = genesis.L2AllocsEcotone
}
l2Allocs := config.L2Allocs(allocsMode)
l2Allocs := config.L2Allocs(config.AllocTypeStandard, allocsMode)
l2Genesis, err := genesis.BuildL2Genesis(cfg.DeployConfig, l2Allocs, l1Block.Header())
require.NoError(t, err)
l2GenesisBlock := l2Genesis.ToBlock()
......@@ -88,20 +88,10 @@ func NewOpGeth(t testing.TB, ctx context.Context, cfg *e2esys.SystemConfig) (*Op
}
var node services.EthInstance
if cfg.ExternalL2Shim == "" {
gethNode, err := geth.InitL2("l2", l2Genesis, cfg.JWTFilePath)
require.NoError(t, err)
require.NoError(t, gethNode.Node.Start())
node = gethNode
} else {
externalNode := (&e2esys.ExternalRunner{
Name: "l2",
BinPath: cfg.ExternalL2Shim,
Genesis: l2Genesis,
JWTPath: cfg.JWTFilePath,
}).Run(t)
node = externalNode
}
gethNode, err := geth.InitL2("l2", l2Genesis, cfg.JWTFilePath)
require.NoError(t, err)
require.NoError(t, gethNode.Node.Start())
node = gethNode
auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.JWTSecret))
l2Node, err := client.NewRPC(ctx, logger, node.AuthRPC().RPC(), client.WithGethRPCOptions(auth))
......
......@@ -10,6 +10,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
......@@ -264,9 +266,17 @@ func TestMixedDepositValidity(t *testing.T) {
}
}
func TestMixedWithdrawalValidity_L2OO(t *testing.T) {
testMixedWithdrawalValidity(t, config.AllocTypeL2OO)
}
func TestMixedWithdrawalValidity_Standard(t *testing.T) {
testMixedWithdrawalValidity(t, config.AllocTypeStandard)
}
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// rejected while unmodified ones are accepted. This runs test cases in different systems.
func TestMixedWithdrawalValidity(t *testing.T) {
func testMixedWithdrawalValidity(t *testing.T, allocType config.AllocType) {
op_e2e.InitParallel(t)
// There are 7 different fields we try modifying to cause a failure, plus one "good" test result we test.
......@@ -279,7 +289,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
op_e2e.InitParallel(t)
// Create our system configuration, funding all accounts we created for L1/L2, and start it
cfg := e2esys.DefaultSystemConfig(t)
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(allocType))
cfg.Nodes["sequencer"].SafeDBPath = t.TempDir()
cfg.DeployConfig.L2BlockTime = 2
require.LessOrEqual(t, cfg.DeployConfig.FinalizationPeriodSeconds, uint64(6))
......@@ -421,7 +431,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// Wait for the finalization period, then we can finalize this withdrawal.
require.NotEqual(t, cfg.L1Deployments.L2OutputOracleProxy, common.Address{})
var blockNumber uint64
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
blockNumber, err = wait.ForGamePublished(ctx, l1Client, cfg.L1Deployments.OptimismPortalProxy, cfg.L1Deployments.DisputeGameFactoryProxy, receipt.BlockNumber)
} else {
blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, cfg.L1Deployments.L2OutputOracleProxy, receipt.BlockNumber)
......@@ -438,7 +448,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
blockCl := ethclient.NewClient(rpcClient)
// Now create the withdrawal
params, err := helpers.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, tx.Hash(), header, l2OutputOracle, disputeGameFactory, optimismPortal2)
params, err := helpers.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, tx.Hash(), header, l2OutputOracle, disputeGameFactory, optimismPortal2, cfg.AllocType)
require.Nil(t, err)
// Obtain our withdrawal parameters
......@@ -527,7 +537,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
} else {
require.NoError(t, err)
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
// Start a challenger to resolve claims and games once the clock expires
factoryHelper := disputegame.NewFactoryHelper(t, ctx, sys)
factoryHelper.StartChallenger(ctx, "Challenger",
......@@ -555,7 +565,7 @@ func TestMixedWithdrawalValidity(t *testing.T) {
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx, withdrawalCancel := context.WithTimeout(context.Background(), 60*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer withdrawalCancel()
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
err = wait.ForWithdrawalCheck(ctx, l1Client, withdrawal, cfg.L1Deployments.OptimismPortalProxy, transactor.Account.L1Opts.From)
require.NoError(t, err)
} else {
......
......@@ -17,7 +17,6 @@ import (
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/sources"
)
......@@ -33,7 +32,7 @@ type CommonSystem interface {
// balance changes on L1 and L2 and has to include gas fees in the balance checks.
// It does not check that the withdrawal can be executed prior to the end of the finality period.
func RunWithdrawalsTest(t *testing.T, sys CommonSystem) {
t.Logf("WithdrawalsTest: running with FP == %t", e2eutils.UseFaultProofs())
t.Logf("WithdrawalsTest: running with allocType == %s", sys.Config().AllocType)
cfg := sys.Config()
l1Client := sys.NodeClient(e2esys.RoleL1)
......@@ -129,7 +128,7 @@ func RunWithdrawalsTest(t *testing.T, sys CommonSystem) {
proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice)
finalizeFee := new(big.Int).Mul(new(big.Int).SetUint64(finalizeReceipt.GasUsed), finalizeReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(proveFee, finalizeFee)
if e2eutils.UseFaultProofs() {
if sys.Config().AllocType.UsesProofs() {
resolveClaimFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveClaimReceipt.GasUsed), resolveClaimReceipt.EffectiveGasPrice)
resolveFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveReceipt.GasUsed), resolveReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(fees, resolveClaimFee)
......
......@@ -4,18 +4,25 @@ import (
"testing"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/stretchr/testify/require"
)
// TestWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the
func TestWithdrawals_L2OO(t *testing.T) {
testWithdrawals(t, config.AllocTypeL2OO)
}
func TestWithdrawals_Standard(t *testing.T) {
testWithdrawals(t, config.AllocTypeStandard)
}
// testWithdrawals checks that a deposit and then withdrawal execution succeeds. It verifies the
// balance changes on L1 and L2 and has to include gas fees in the balance checks.
// It does not check that the withdrawal can be executed prior to the end of the finality period.
func TestWithdrawals(t *testing.T) {
func testWithdrawals(t *testing.T, allocType config.AllocType) {
op_e2e.InitParallel(t)
cfg := e2esys.DefaultSystemConfig(t)
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(allocType))
cfg.DeployConfig.FinalizationPeriodSeconds = 2 // 2s finalization period
cfg.L1FinalizedDistance = 2 // Finalize quick, don't make the proposer wait too long
......
......@@ -67,7 +67,7 @@ func TestBrotliBatcherFjord(t *testing.T) {
cfg.DeployConfig.L2GenesisFjordTimeOffset = &genesisActivation
// set up batcher to use brotli
sys, err := cfg.Start(t, e2esys.SystemConfigOption{Key: "compressionAlgo", Role: "brotli", Action: nil})
sys, err := cfg.Start(t, e2esys.StartOption{Key: "compressionAlgo", Role: "brotli", Action: nil})
require.Nil(t, err, "Error starting up system")
log := testlog.Logger(t, log.LevelInfo)
......
......@@ -34,13 +34,19 @@ import (
"github.com/ethereum/go-ethereum/params"
)
// TestSystem4844E2E runs the SystemE2E test with 4844 enabled on L1, and active on the rollup in
// TestSystem4844E2E* run the SystemE2E test with 4844 enabled on L1, and active on the rollup in
// the op-batcher and verifier. It submits a txpool-blocking transaction before running
// each test to ensure the batcher is able to clear it.
func TestSystem4844E2E(t *testing.T) {
t.Run("calldata", func(t *testing.T) { testSystem4844E2E(t, false, batcherFlags.CalldataType) })
t.Run("single-blob", func(t *testing.T) { testSystem4844E2E(t, false, batcherFlags.BlobsType) })
t.Run("multi-blob", func(t *testing.T) { testSystem4844E2E(t, true, batcherFlags.BlobsType) })
func TestSystem4844E2E_Calldata(t *testing.T) {
testSystem4844E2E(t, false, batcherFlags.CalldataType)
}
func TestSystem4844E2E_SingleBlob(t *testing.T) {
testSystem4844E2E(t, false, batcherFlags.BlobsType)
}
func TestSystem4844E2E_MultiBlob(t *testing.T) {
testSystem4844E2E(t, true, batcherFlags.BlobsType)
}
func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAvailabilityType) {
......@@ -68,7 +74,7 @@ func testSystem4844E2E(t *testing.T, multiBlob bool, daType batcherFlags.DataAva
// is started, as is required by the function.
var jamChan chan error
jamCtx, jamCancel := context.WithTimeout(context.Background(), 20*time.Second)
action := e2esys.SystemConfigOption{
action := e2esys.StartOption{
Key: "beforeBatcherStart",
Action: func(cfg *e2esys.SystemConfig, s *e2esys.System) {
driver := s.BatchSubmitter.TestDriver()
......
......@@ -18,37 +18,28 @@ import (
"github.com/stretchr/testify/require"
)
// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode.
// TestSystemBatchType* run each system e2e test case in singular batch mode and span batch mode.
// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode.
func TestSystemBatchType(t *testing.T) {
tests := []struct {
name string
f func(*testing.T, func(*e2esys.SystemConfig))
}{
{"StopStartBatcher", StopStartBatcher},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SingularBatchType
})
})
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SpanBatchType
})
})
t.Run(test.name+"_SpanBatchMaxBlocks", func(t *testing.T) {
test.f(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SpanBatchType
sc.BatcherMaxBlocksPerSpanBatch = 2
})
})
}
func TestSystemBatchType_SingularBatch(t *testing.T) {
testStartStopBatcher(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SingularBatchType
})
}
func TestSystemBatchType_SpanBatch(t *testing.T) {
testStartStopBatcher(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SpanBatchType
})
}
func TestSystemBatchType_SpanBatchMaxBlocks(t *testing.T) {
testStartStopBatcher(t, func(sc *e2esys.SystemConfig) {
sc.BatcherBatchType = derive.SpanBatchType
sc.BatcherMaxBlocksPerSpanBatch = 2
})
}
func StopStartBatcher(t *testing.T, cfgMod func(*e2esys.SystemConfig)) {
func testStartStopBatcher(t *testing.T, cfgMod func(*e2esys.SystemConfig)) {
op_e2e.InitParallel(t)
cfg := e2esys.DefaultSystemConfig(t)
......
package e2esys
import (
"encoding/json"
"errors"
"math/big"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/external"
"github.com/ethereum-optimism/optimism/op-service/endpoint"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/onsi/gomega/gexec"
"github.com/stretchr/testify/require"
)
type ExternalRunner struct {
Name string
BinPath string
Genesis *core.Genesis
JWTPath string
// 4844: a datadir specifically for tx-pool blobs
BlobPoolPath string
}
type ExternalEthClient struct {
Session *gexec.Session
Endpoints external.Endpoints
}
func (eec *ExternalEthClient) UserRPC() endpoint.RPC {
return endpoint.WsOrHttpRPC{
WsURL: eec.Endpoints.WSEndpoint,
HttpURL: eec.Endpoints.HTTPEndpoint,
}
}
func (eec *ExternalEthClient) AuthRPC() endpoint.RPC {
return endpoint.WsOrHttpRPC{
WsURL: eec.Endpoints.WSAuthEndpoint,
HttpURL: eec.Endpoints.HTTPAuthEndpoint,
}
}
func (eec *ExternalEthClient) Close() error {
eec.Session.Terminate()
select {
case <-time.After(5 * time.Second):
eec.Session.Kill()
select {
case <-time.After(30 * time.Second):
return errors.New("external client failed to terminate")
case <-eec.Session.Exited:
}
case <-eec.Session.Exited:
}
return nil
}
func (er *ExternalRunner) Run(t testing.TB) *ExternalEthClient {
if er.BinPath == "" {
t.Error("no external bin path set")
}
if er.JWTPath == "" {
er.JWTPath = writeDefaultJWT(t)
}
if er.Genesis == nil {
er.Genesis = &core.Genesis{
Alloc: types.GenesisAlloc{
common.Address{1}: types.Account{Balance: big.NewInt(1)},
},
Config: params.OptimismTestConfig,
Difficulty: big.NewInt(0),
}
}
workDir := t.TempDir()
config := external.Config{
DataDir: filepath.Join(workDir, "datadir"),
JWTPath: er.JWTPath,
ChainID: er.Genesis.Config.ChainID.Uint64(),
GenesisPath: filepath.Join(workDir, "genesis.json"),
EndpointsReadyPath: filepath.Join(workDir, "endpoints.json"),
Verbosity: uint64(config.EthNodeVerbosity),
}
err := os.Mkdir(config.DataDir, 0o700)
require.NoError(t, err)
genesisFile, err := os.Create(config.GenesisPath)
require.NoError(t, err)
err = json.NewEncoder(genesisFile).Encode(er.Genesis)
require.NoError(t, err)
configPath := filepath.Join(workDir, "config.json")
configFile, err := os.Create(configPath)
require.NoError(t, err)
err = json.NewEncoder(configFile).Encode(config)
require.NoError(t, err)
cmd := exec.Command(er.BinPath, "--config", configPath)
cmd.Dir = filepath.Dir(er.BinPath)
sess, err := gexec.Start(
cmd,
gexec.NewPrefixedWriter("[extout:"+er.Name+"]", os.Stdout),
gexec.NewPrefixedWriter("[exterr:"+er.Name+"]", os.Stderr),
)
require.NoError(t, err)
// 2 minutes may seem like a long timeout, and, it definitely is. That
// being said, when running these tests with high parallelism turned on, the
// node startup time can be substantial (remember, this usually is a
// multi-step process initializing the database and then starting the
// client).
require.Eventually(
t,
func() bool {
_, err := os.Stat(config.EndpointsReadyPath)
return err == nil
},
2*time.Minute,
10*time.Millisecond,
"external runner did not create ready file at %s within timeout",
config.EndpointsReadyPath,
)
readyFile, err := os.Open(config.EndpointsReadyPath)
require.NoError(t, err)
var endpoints external.Endpoints
err = json.NewDecoder(readyFile).Decode(&endpoints)
require.NoError(t, err)
return &ExternalEthClient{
Session: sess,
Endpoints: endpoints,
}
}
This diff is collapsed.
......@@ -6,13 +6,14 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/config"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/receipts"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
......@@ -30,10 +31,17 @@ func TestMain(m *testing.M) {
op_e2e.RunMain(m)
}
func TestCustomGasToken(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.SkipOnFaultProofs) // Custom Gas Token feature is not yet compatible with fault proofs
func TestCustomGasToken_L2OO(t *testing.T) {
testCustomGasToken(t, config.AllocTypeL2OO)
}
func TestCustomGasToken_Standard(t *testing.T) {
testCustomGasToken(t, config.AllocTypeStandard)
}
cfg := e2esys.DefaultSystemConfig(t)
func testCustomGasToken(t *testing.T, allocType config.AllocType) {
op_e2e.InitParallel(t)
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(allocType))
offset := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisRegolithTimeOffset = &offset
cfg.DeployConfig.L1CancunTimeOffset = &offset
......@@ -183,7 +191,7 @@ func TestCustomGasToken(t *testing.T) {
proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice)
finalizeFee := new(big.Int).Mul(new(big.Int).SetUint64(finalizeReceipt.GasUsed), finalizeReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(proveFee, finalizeFee)
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
resolveClaimFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveClaimReceipt.GasUsed), resolveClaimReceipt.EffectiveGasPrice)
resolveFee := new(big.Int).Mul(new(big.Int).SetUint64(resolveReceipt.GasUsed), resolveReceipt.EffectiveGasPrice)
fees = new(big.Int).Add(fees, resolveClaimFee)
......@@ -329,7 +337,7 @@ func TestCustomGasToken(t *testing.T) {
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", cfg.Secrets.Alice, receipt)
require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status)
require.Equal(t, types.ReceiptStatusSuccessful, finalizeReceipt.Status)
if e2eutils.UseFaultProofs() {
if allocType.UsesProofs() {
require.Equal(t, types.ReceiptStatusSuccessful, resolveClaimReceipt.Status)
require.Equal(t, types.ReceiptStatusSuccessful, resolveReceipt.Status)
}
......
......@@ -16,7 +16,6 @@ import (
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
......@@ -96,7 +95,14 @@ func defaultWithdrawalTxOpts() *WithdrawalTxOpts {
}
}
func ProveAndFinalizeWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvider, l2NodeName string, ethPrivKey *ecdsa.PrivateKey, l2WithdrawalReceipt *types.Receipt) (*types.Receipt, *types.Receipt, *types.Receipt, *types.Receipt) {
func ProveAndFinalizeWithdrawal(
t *testing.T,
cfg e2esys.SystemConfig,
clients ClientProvider,
l2NodeName string,
ethPrivKey *ecdsa.PrivateKey,
l2WithdrawalReceipt *types.Receipt,
) (*types.Receipt, *types.Receipt, *types.Receipt, *types.Receipt) {
params, proveReceipt := ProveWithdrawal(t, cfg, clients, l2NodeName, ethPrivKey, l2WithdrawalReceipt)
finalizeReceipt, resolveClaimReceipt, resolveReceipt := FinalizeWithdrawal(t, cfg, clients.NodeClient("l1"), ethPrivKey, proveReceipt, params)
return proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt
......@@ -107,14 +113,17 @@ func ProveWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvid
ctx, cancel := context.WithTimeout(context.Background(), 40*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer cancel()
allocType := cfg.AllocType
l1Client := clients.NodeClient(e2esys.RoleL1)
var blockNumber uint64
var err error
if e2eutils.UseFaultProofs() {
blockNumber, err = wait.ForGamePublished(ctx, l1Client, config.L1Deployments.OptimismPortalProxy, config.L1Deployments.DisputeGameFactoryProxy, l2WithdrawalReceipt.BlockNumber)
l1Deployments := config.L1Deployments(allocType)
if allocType.UsesProofs() {
blockNumber, err = wait.ForGamePublished(ctx, l1Client, l1Deployments.OptimismPortalProxy, l1Deployments.DisputeGameFactoryProxy, l2WithdrawalReceipt.BlockNumber)
require.NoError(t, err)
} else {
blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, config.L1Deployments.L2OutputOracleProxy, l2WithdrawalReceipt.BlockNumber)
blockNumber, err = wait.ForOutputRootPublished(ctx, l1Client, l1Deployments.L2OutputOracleProxy, l2WithdrawalReceipt.BlockNumber)
require.NoError(t, err)
}
......@@ -128,19 +137,19 @@ func ProveWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvid
header, err := receiptCl.HeaderByNumber(ctx, new(big.Int).SetUint64(blockNumber))
require.NoError(t, err)
oracle, err := bindings.NewL2OutputOracleCaller(config.L1Deployments.L2OutputOracleProxy, l1Client)
oracle, err := bindings.NewL2OutputOracleCaller(l1Deployments.L2OutputOracleProxy, l1Client)
require.NoError(t, err)
factory, err := bindings.NewDisputeGameFactoryCaller(config.L1Deployments.DisputeGameFactoryProxy, l1Client)
factory, err := bindings.NewDisputeGameFactoryCaller(l1Deployments.DisputeGameFactoryProxy, l1Client)
require.NoError(t, err)
portal2, err := bindingspreview.NewOptimismPortal2Caller(config.L1Deployments.OptimismPortalProxy, l1Client)
portal2, err := bindingspreview.NewOptimismPortal2Caller(l1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, l2WithdrawalReceipt.TxHash, header, oracle, factory, portal2)
params, err := ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, blockCl, l2WithdrawalReceipt.TxHash, header, oracle, factory, portal2, allocType)
require.NoError(t, err)
portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client)
portal, err := bindings.NewOptimismPortal(l1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
opts, err := bind.NewKeyedTransactorWithChainID(ethPrivKey, cfg.L1ChainIDBig())
......@@ -170,8 +179,8 @@ func ProveWithdrawal(t *testing.T, cfg e2esys.SystemConfig, clients ClientProvid
return params, proveReceipt
}
func ProveWithdrawalParameters(ctx context.Context, proofCl withdrawals.ProofClient, l2ReceiptCl withdrawals.ReceiptClient, l2BlockCl withdrawals.BlockClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller, disputeGameFactoryContract *bindings.DisputeGameFactoryCaller, optimismPortal2Contract *bindingspreview.OptimismPortal2Caller) (withdrawals.ProvenWithdrawalParameters, error) {
if e2eutils.UseFaultProofs() {
func ProveWithdrawalParameters(ctx context.Context, proofCl withdrawals.ProofClient, l2ReceiptCl withdrawals.ReceiptClient, l2BlockCl withdrawals.BlockClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller, disputeGameFactoryContract *bindings.DisputeGameFactoryCaller, optimismPortal2Contract *bindingspreview.OptimismPortal2Caller, allocType config.AllocType) (withdrawals.ProvenWithdrawalParameters, error) {
if allocType.UsesProofs() {
return withdrawals.ProveWithdrawalParametersFaultProofs(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, disputeGameFactoryContract, optimismPortal2Contract)
} else {
return withdrawals.ProveWithdrawalParameters(ctx, proofCl, l2ReceiptCl, l2BlockCl, txHash, header, l2OutputOracleContract)
......@@ -192,13 +201,16 @@ func FinalizeWithdrawal(t *testing.T, cfg e2esys.SystemConfig, l1Client *ethclie
Data: params.Data,
}
allocType := cfg.AllocType
opts, err := bind.NewKeyedTransactorWithChainID(privKey, cfg.L1ChainIDBig())
require.NoError(t, err)
var resolveClaimReceipt *types.Receipt
var resolveReceipt *types.Receipt
if e2eutils.UseFaultProofs() {
portal2, err := bindingspreview.NewOptimismPortal2(config.L1Deployments.OptimismPortalProxy, l1Client)
l1Deployments := config.L1Deployments(allocType)
if allocType.UsesProofs() {
portal2, err := bindingspreview.NewOptimismPortal2(l1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
wdHash, err := wd.Hash()
......@@ -245,19 +257,17 @@ func FinalizeWithdrawal(t *testing.T, cfg e2esys.SystemConfig, l1Client *ethclie
require.Equal(t, gameTypes.GameStatusDefenderWon, status, "game must have resolved with defender won")
t.Logf("resolve was not needed, the game was already resolved")
}
}
if e2eutils.UseFaultProofs() {
t.Log("FinalizeWithdrawal: waiting for successful withdrawal check...")
err := wait.ForWithdrawalCheck(ctx, l1Client, wd, config.L1Deployments.OptimismPortalProxy, opts.From)
err = wait.ForWithdrawalCheck(ctx, l1Client, wd, l1Deployments.OptimismPortalProxy, opts.From)
require.NoError(t, err)
} else {
t.Log("FinalizeWithdrawal: waiting for finalization...")
err := wait.ForFinalizationPeriod(ctx, l1Client, withdrawalProofReceipt.BlockNumber, config.L1Deployments.L2OutputOracleProxy)
err := wait.ForFinalizationPeriod(ctx, l1Client, withdrawalProofReceipt.BlockNumber, l1Deployments.L2OutputOracleProxy)
require.NoError(t, err)
}
portal, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client)
portal, err := bindings.NewOptimismPortal(l1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
// Finalize withdrawal
......
......@@ -7,19 +7,20 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-node/p2p"
"github.com/ethereum-optimism/optimism/op-node/rollup/driver"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/log"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/opnode"
"github.com/ethereum-optimism/optimism/op-e2e/system/e2esys"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
rollupNode "github.com/ethereum-optimism/optimism/op-node/node"
"github.com/ethereum-optimism/optimism/op-node/p2p"
"github.com/ethereum-optimism/optimism/op-node/rollup/driver"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/retry"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/require"
)
......
......@@ -8,6 +8,8 @@ import (
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
......@@ -20,9 +22,8 @@ import (
)
func TestL2OutputSubmitterFaultProofs(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.SkipOnL2OO)
cfg := e2esys.DefaultSystemConfig(t)
op_e2e.InitParallel(t)
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(config.AllocTypeStandard))
cfg.NonFinalizedProposals = true // speed up the time till we see output proposals
sys, err := cfg.Start(t)
......
......@@ -7,6 +7,7 @@ import (
"time"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth"
......@@ -16,9 +17,9 @@ import (
)
func TestL2OutputSubmitter(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.SkipOnFaultProofs)
op_e2e.InitParallel(t)
cfg := e2esys.DefaultSystemConfig(t)
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(config.AllocTypeL2OO))
cfg.NonFinalizedProposals = true // speed up the time till we see output proposals
sys, err := cfg.Start(t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment