diff --git a/.github/workflows/protected.yaml b/.github/workflows/protected.yaml index 4dba40e36b6..020c1fc99cc 100644 --- a/.github/workflows/protected.yaml +++ b/.github/workflows/protected.yaml @@ -61,7 +61,7 @@ jobs: - cannon - op-dripper - op-interop-mon - uses: ethereum-optimism/factory/.github/workflows/docker-bake.yaml@2ff3f9bba03d59a6ad10fdf660ed253f53956188 + uses: ethereum-optimism/factory/.github/workflows/docker-bake.yaml@753bcd4284a6d36eac6e31df2492015ab8650331 with: image_name: ${{ matrix.image_name }} bake_file: docker-bake.hcl @@ -69,6 +69,7 @@ jobs: tag: ${{ needs.prep.outputs.sanitised_ref_name }} gcp_project_id: ${{ vars.GCP_PROJECT_ID_OPLABS_TOOLS_ARTIFACTS }} registry: us-docker.pkg.dev/oplabs-tools-artifacts/oss + attest: true env: | GIT_VERSION=${{ fromJson(needs.prep.outputs.versions)[matrix.image_name] }} KONA_VERSION=${{ needs.prep.outputs.kona_version }} diff --git a/.github/workflows/unprotected.yaml b/.github/workflows/unprotected.yaml index 6fc5e44296c..e8ee041f0aa 100644 --- a/.github/workflows/unprotected.yaml +++ b/.github/workflows/unprotected.yaml @@ -67,14 +67,14 @@ jobs: - cannon - op-dripper - op-interop-mon - uses: ethereum-optimism/factory/.github/workflows/docker-bake.yaml@2ff3f9bba03d59a6ad10fdf660ed253f53956188 + uses: ethereum-optimism/factory/.github/workflows/docker-bake.yaml@753bcd4284a6d36eac6e31df2492015ab8650331 with: image_name: ${{ matrix.image_name }} bake_file: docker-bake.hcl target: ${{ matrix.image_name }} tag: 24h registry: ttl.sh/${{ github.sha }} - push_provenance: false + attest: false env: | GIT_VERSION=${{ fromJson(needs.prep.outputs.versions)[matrix.image_name] }} KONA_VERSION=${{ needs.prep.outputs.kona_version }} diff --git a/op-acceptance-tests/tests/base/disputegame_v2/smoke_test.go b/op-acceptance-tests/tests/base/disputegame_v2/smoke_test.go index 8509a22a85f..b93ad395624 100644 --- a/op-acceptance-tests/tests/base/disputegame_v2/smoke_test.go +++ b/op-acceptance-tests/tests/base/disputegame_v2/smoke_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/gameargs" - challengerTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-devstack/devtest" "github.com/ethereum-optimism/optimism/op-devstack/presets" ) @@ -15,18 +15,18 @@ func TestSmoke(gt *testing.T) { require := t.Require() dgf := sys.DisputeGameFactory() - gameArgs := dgf.GameArgs(challengerTypes.PermissionedGameType) + gameArgs := dgf.GameArgs(gameTypes.PermissionedGameType) require.NotEmpty(gameArgs, "game args is must be set for permissioned v2 dispute games") _, err := gameargs.Parse(gameArgs) require.NoError(err, "Permissioned game args invalid") - gameArgs = dgf.GameArgs(challengerTypes.CannonGameType) + gameArgs = dgf.GameArgs(gameTypes.CannonGameType) require.NotEmpty(gameArgs, "game args is must be set for cannon v2 dispute games") _, err = gameargs.Parse(gameArgs) require.NoError(err, "Permissionless game args invalid") - permissionedGame := dgf.GameImpl(challengerTypes.PermissionedGameType) + permissionedGame := dgf.GameImpl(gameTypes.PermissionedGameType) require.NotEmpty(permissionedGame.Address, "permissioned game impl must be set") - cannonGame := dgf.GameImpl(challengerTypes.CannonGameType) + cannonGame := dgf.GameImpl(gameTypes.CannonGameType) require.NotEmpty(cannonGame.Address, "cannon game impl must be set") } diff --git a/op-acceptance-tests/tests/base/withdrawal/cannon/init_test.go b/op-acceptance-tests/tests/base/withdrawal/cannon/init_test.go index 8ab26ed8957..693c20e9253 100644 --- a/op-acceptance-tests/tests/base/withdrawal/cannon/init_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/cannon/init_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestMain(m *testing.M) { - withdrawal.InitWithGameType(m, types.CannonGameType) + withdrawal.InitWithGameType(m, gameTypes.CannonGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/cannon/withdrawal_test.go b/op-acceptance-tests/tests/base/withdrawal/cannon/withdrawal_test.go index 091d33f234e..324221eebf4 100644 --- a/op-acceptance-tests/tests/base/withdrawal/cannon/withdrawal_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/cannon/withdrawal_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestWithdrawal_Cannon(gt *testing.T) { - withdrawal.TestWithdrawal(gt, faultTypes.CannonGameType) + withdrawal.TestWithdrawal(gt, gameTypes.CannonGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/cannon_kona/init_test.go b/op-acceptance-tests/tests/base/withdrawal/cannon_kona/init_test.go index 663551f0a6f..80e12341b19 100644 --- a/op-acceptance-tests/tests/base/withdrawal/cannon_kona/init_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/cannon_kona/init_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestMain(m *testing.M) { - withdrawal.InitWithGameType(m, types.CannonKonaGameType) + withdrawal.InitWithGameType(m, gameTypes.CannonKonaGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/cannon_kona/withdrawal_test.go b/op-acceptance-tests/tests/base/withdrawal/cannon_kona/withdrawal_test.go index 13f470958d1..72f18178f12 100644 --- a/op-acceptance-tests/tests/base/withdrawal/cannon_kona/withdrawal_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/cannon_kona/withdrawal_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestWithdrawal_CannonKona(gt *testing.T) { - withdrawal.TestWithdrawal(gt, faultTypes.CannonKonaGameType) + withdrawal.TestWithdrawal(gt, gameTypes.CannonKonaGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/permissioned/init_test.go b/op-acceptance-tests/tests/base/withdrawal/permissioned/init_test.go index f25f2451817..0017d530c31 100644 --- a/op-acceptance-tests/tests/base/withdrawal/permissioned/init_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/permissioned/init_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestMain(m *testing.M) { - withdrawal.InitWithGameType(m, types.PermissionedGameType) + withdrawal.InitWithGameType(m, gameTypes.PermissionedGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/permissioned/withdrawal_test.go b/op-acceptance-tests/tests/base/withdrawal/permissioned/withdrawal_test.go index 777c2df3b84..e0715788c3c 100644 --- a/op-acceptance-tests/tests/base/withdrawal/permissioned/withdrawal_test.go +++ b/op-acceptance-tests/tests/base/withdrawal/permissioned/withdrawal_test.go @@ -4,9 +4,9 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/base/withdrawal" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) func TestWithdrawal_Permissioned(gt *testing.T) { - withdrawal.TestWithdrawal(gt, faultTypes.PermissionedGameType) + withdrawal.TestWithdrawal(gt, gameTypes.PermissionedGameType) } diff --git a/op-acceptance-tests/tests/base/withdrawal/withdrawal_test_helper.go b/op-acceptance-tests/tests/base/withdrawal/withdrawal_test_helper.go index abe47939bad..c7d087104d4 100644 --- a/op-acceptance-tests/tests/base/withdrawal/withdrawal_test_helper.go +++ b/op-acceptance-tests/tests/base/withdrawal/withdrawal_test_helper.go @@ -3,14 +3,14 @@ package withdrawal import ( "testing" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-devstack/compat" "github.com/ethereum-optimism/optimism/op-devstack/devtest" "github.com/ethereum-optimism/optimism/op-devstack/presets" "github.com/ethereum-optimism/optimism/op-service/eth" ) -func InitWithGameType(m *testing.M, gameType faultTypes.GameType) { +func InitWithGameType(m *testing.M, gameType gameTypes.GameType) { presets.DoMain(m, presets.WithCompatibleTypes(compat.SysGo), presets.WithMinimal(), @@ -25,7 +25,7 @@ func InitWithGameType(m *testing.M, gameType faultTypes.GameType) { ) } -func TestWithdrawal(gt *testing.T, gameType faultTypes.GameType) { +func TestWithdrawal(gt *testing.T, gameType gameTypes.GameType) { t := devtest.SerialT(gt) sys := presets.NewMinimal(t) require := sys.T.Require() diff --git a/op-challenger/README.md b/op-challenger/README.md index 84d7b53ccda..d217402479b 100644 --- a/op-challenger/README.md +++ b/op-challenger/README.md @@ -35,7 +35,7 @@ Run the `op-challenger` with: ```shell DISPUTE_GAME_FACTORY=$(jq -r .DisputeGameFactoryProxy .devnet/addresses.json) ./op-challenger/bin/op-challenger \ - --trace-type cannon \ + --game-types cannon \ --l1-eth-rpc http://localhost:8545 \ --rollup-rpc http://localhost:9546 \ --game-factory-address $DISPUTE_GAME_FACTORY \ @@ -99,8 +99,7 @@ in the L2 output oracle. * `L2_BLOCK_NUM` the L2 block number the proposed output root is from. * `SIGNER_ARGS` arguments to specify the key to sign transactions with (e.g `--private-key`) -Optionally, you may specify the game type (aka "trace type") using the `--trace-type` -flag, which is set to the cannon trace type by default. +Optionally, you may override the game types to support using the `--game-types` flag. For known networks, the `--game-factory-address` option can be replaced by `--network`. See the `--help` output for a list of predefined networks. @@ -226,10 +225,10 @@ configured with multiple different prestates. This allows testing both the curre the fault proofs virtual machine used by the trace provider. The same CLI options as `op-challenger` itself are supported to configure the trace providers. The additional `--run` -option allows specifying which prestates to use. The format is `traceType/name/prestateHash` where traceType is the -trace type to use with the prestate (e.g cannon or asterisc-kona), name is an arbitrary name for the prestate to use +option allows specifying which prestates to use. The format is `gameType/name/prestateHash` where gameType is the +game type to use with the prestate (e.g cannon or asterisc-kona), name is an arbitrary name for the prestate to use when reporting metrics and prestateHash is the hex encoded absolute prestate commitment to use. If name is omitted the -trace type name is used. If the prestateHash is omitted, the absolute prestate hash used for new games on-chain is used. +game type name is used. If the prestateHash is omitted, the absolute prestate hash used for new games on-chain is used. For example to run both the production cannon prestate and a custom prestate, use `--run cannon,cannon/next-prestate/0x03c1f0d45248190f80430a4c31e24f8108f05f80ff8b16ecb82d20df6b1b43f3`. diff --git a/op-challenger/cmd/create_game.go b/op-challenger/cmd/create_game.go index 073ecff1959..71159e34582 100644 --- a/op-challenger/cmd/create_game.go +++ b/op-challenger/cmd/create_game.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/tools" opservice "github.com/ethereum-optimism/optimism/op-service" oplog "github.com/ethereum-optimism/optimism/op-service/log" @@ -22,7 +22,7 @@ var ( Name: "game-type", Usage: "Game type to create (numeric values).", EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "TRACE_TYPE"), - Value: types.CannonGameType.String(), + Value: gameTypes.CannonGameType.String(), } OutputRootFlag = &cli.StringFlag{ Name: "output-root", diff --git a/op-challenger/cmd/main_test.go b/op-challenger/cmd/main_test.go index 0163da5c091..2e5ae1652b3 100644 --- a/op-challenger/cmd/main_test.go +++ b/op-challenger/cmd/main_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum/go-ethereum/superchain" "github.com/stretchr/testify/require" @@ -14,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-challenger/config" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -41,13 +41,13 @@ var ( func TestLogLevel(t *testing.T) { t.Run("RejectInvalid", func(t *testing.T) { - verifyArgsInvalid(t, "unknown level: foo", addRequiredArgs(types.TraceTypeAlphabet, "--log.level=foo")) + verifyArgsInvalid(t, "unknown level: foo", addRequiredArgs(gameTypes.AlphabetGameType, "--log.level=foo")) }) for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} { lvl := lvl t.Run("AcceptValid_"+lvl, func(t *testing.T) { - logger, _, err := dryRunWithArgs(addRequiredArgs(types.TraceTypeAlphabet, "--log.level", lvl)) + logger, _, err := dryRunWithArgs(addRequiredArgs(gameTypes.AlphabetGameType, "--log.level", lvl)) require.NoError(t, err) require.NotNil(t, logger) }) @@ -57,30 +57,30 @@ func TestLogLevel(t *testing.T) { func TestL2Experimental(t *testing.T) { t.Run("Valid", func(t *testing.T) { url := "http://example.com:8888" - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--l2-experimental-eth-rpc="+url)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--l2-experimental-eth-rpc="+url)) require.Equal(t, url, cfg.Cannon.L2Experimental) }) } func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet)) - defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, types.TraceTypeAlphabet) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType)) + defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, gameTypes.AlphabetGameType) require.Equal(t, defaultCfg, cfg) } func TestDefaultConfigIsValid(t *testing.T) { - cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, types.TraceTypeAlphabet) + cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, gameTypes.AlphabetGameType) require.NoError(t, cfg.Check()) } func TestL1ETHRPCAddress(t *testing.T) { t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag l1-eth-rpc is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-eth-rpc")) + verifyArgsInvalid(t, "flag l1-eth-rpc is required", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l1-eth-rpc")) }) t.Run("Valid", func(t *testing.T) { url := "http://example.com:8888" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-eth-rpc", "--l1-eth-rpc="+url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l1-eth-rpc", "--l1-eth-rpc="+url)) require.Equal(t, url, cfg.L1EthRpc) require.Equal(t, url, cfg.TxMgrConfig.L1RPCURL) }) @@ -88,145 +88,154 @@ func TestL1ETHRPCAddress(t *testing.T) { func TestL1Beacon(t *testing.T) { t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-beacon")) + verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l1-beacon")) }) t.Run("Valid", func(t *testing.T) { url := "http://example.com:8888" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-beacon", "--l1-beacon="+url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l1-beacon", "--l1-beacon="+url)) require.Equal(t, url, cfg.L1Beacon) }) } func TestOpSupervisor(t *testing.T) { t.Run("RequiredForSuperCannon", func(t *testing.T) { - verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(types.TraceTypeSuperCannon, "--supervisor-rpc")) + verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supervisor-rpc")) }) t.Run("RequiredForSuperPermissioned", func(t *testing.T) { - verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(types.TraceTypeSuperPermissioned, "--supervisor-rpc")) + verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supervisor-rpc")) }) t.Run("RequiredForSuperCannonKona", func(t *testing.T) { - verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(types.TraceTypeSuperCannonKona, "--supervisor-rpc")) + verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supervisor-rpc")) }) t.Run("RequiredForSuperAsteriscKona", func(t *testing.T) { - verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(types.TraceTypeSuperAsteriscKona, "--supervisor-rpc")) + verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperAsteriscKonaGameType, "--supervisor-rpc")) }) - for _, traceType := range types.TraceTypes { - traceType := traceType - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned || traceType == types.TraceTypeSuperAsteriscKona || traceType == types.TraceTypeSuperCannonKona { + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType || gameType == gameTypes.SuperAsteriscKonaGameType || gameType == gameTypes.SuperCannonKonaGameType { continue } - t.Run("NotRequiredForTraceType-"+traceType.String(), func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--supervisor-rpc")) + t.Run("NotRequiredForGameType-"+gameType.String(), func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(gameType, "--supervisor-rpc")) }) } t.Run("Valid-SuperCannon", func(t *testing.T) { url := "http://localhost/supervisor" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeSuperCannon, "--supervisor-rpc", "--supervisor-rpc", url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supervisor-rpc", "--supervisor-rpc", url)) require.Equal(t, url, cfg.SupervisorRPC) }) t.Run("Valid-SuperPermissioned", func(t *testing.T) { url := "http://localhost/supervisor" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeSuperPermissioned, "--supervisor-rpc", "--supervisor-rpc", url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supervisor-rpc", "--supervisor-rpc", url)) require.Equal(t, url, cfg.SupervisorRPC) }) t.Run("Valid-SuperCannonKona", func(t *testing.T) { url := "http://localhost/supervisor" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeSuperCannonKona, "--supervisor-rpc", "--supervisor-rpc", url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supervisor-rpc", "--supervisor-rpc", url)) require.Equal(t, url, cfg.SupervisorRPC) }) t.Run("Valid-SuperAsteriscKona", func(t *testing.T) { url := "http://localhost/supervisor" - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeSuperAsteriscKona, "--supervisor-rpc", "--supervisor-rpc", url)) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperAsteriscKonaGameType, "--supervisor-rpc", "--supervisor-rpc", url)) require.Equal(t, url, cfg.SupervisorRPC) }) } -func TestTraceType(t *testing.T) { +func TestGameTypes(t *testing.T) { t.Run("Default", func(t *testing.T) { - expectedDefault := []types.TraceType{types.TraceTypeCannon, types.TraceTypeAsteriscKona, types.TraceTypeCannonKona} - cfg := configForArgs(t, addRequiredArgsForMultipleTracesExcept(expectedDefault, "--trace-type")) - require.Equal(t, expectedDefault, cfg.TraceTypes) + expectedDefault := []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.AsteriscKonaGameType, gameTypes.CannonKonaGameType} + cfg := configForArgs(t, addRequiredArgsForMultipleGameTypesExcept(expectedDefault, "--game-types")) + require.Equal(t, expectedDefault, cfg.GameTypes) }) - for _, traceType := range types.TraceTypes { - traceType := traceType - t.Run("Valid_"+traceType.String(), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) - require.Equal(t, []types.TraceType{traceType}, cfg.TraceTypes) + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + t.Run("Valid_"+gameType.String(), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgs(gameType)) + require.Equal(t, []gameTypes.GameType{gameType}, cfg.GameTypes) }) } t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "unknown trace type: \"foo\"", addRequiredArgsExcept(types.TraceTypeAlphabet, "--trace-type", "--trace-type=foo")) + verifyArgsInvalid(t, "unknown game type: \"foo\"", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-types", "--game-types=foo")) }) + + // Check we provide an alias for --trace-type to preserve backwards compatibility + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + t.Run("TraceTypeAlias-"+gameType.String(), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--game-types", "--trace-type", gameType.String())) + require.Equal(t, []gameTypes.GameType{gameType}, cfg.GameTypes) + }) + } } -func TestMultipleTraceTypes(t *testing.T) { +func TestMultipleGameTypes(t *testing.T) { t.Run("WithAllOptions", func(t *testing.T) { - argsMap := requiredArgs(types.TraceTypeCannon) + argsMap := requiredArgs(gameTypes.CannonGameType) // Add Asterisc required flags addRequiredAsteriscArgs(argsMap) args := toArgList(argsMap) - // Add extra trace types (cannon is already specified) + // Add extra game types (cannon is already specified) args = append(args, - "--trace-type", types.TraceTypeAlphabet.String()) + "--game-types", gameTypes.AlphabetGameType.String()) args = append(args, - "--trace-type", types.TraceTypePermissioned.String()) + "--game-types", gameTypes.PermissionedGameType.String()) args = append(args, - "--trace-type", types.TraceTypeAsterisc.String()) + "--game-types", gameTypes.AsteriscGameType.String()) cfg := configForArgs(t, args) - require.Equal(t, []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet, types.TraceTypePermissioned, types.TraceTypeAsterisc}, cfg.TraceTypes) + require.Equal(t, []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.AlphabetGameType, gameTypes.PermissionedGameType, gameTypes.AsteriscGameType}, cfg.GameTypes) }) t.Run("WithSomeOptions", func(t *testing.T) { - argsMap := requiredArgs(types.TraceTypeCannon) + argsMap := requiredArgs(gameTypes.CannonGameType) args := toArgList(argsMap) - // Add extra trace types (cannon is already specified) + // Add extra game types (cannon is already specified) args = append(args, - "--trace-type", types.TraceTypeAlphabet.String()) + "--game-types", gameTypes.AlphabetGameType.String()) cfg := configForArgs(t, args) - require.Equal(t, []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet}, cfg.TraceTypes) + require.Equal(t, []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.AlphabetGameType}, cfg.GameTypes) }) t.Run("SpecifySameOptionMultipleTimes", func(t *testing.T) { - argsMap := requiredArgs(types.TraceTypeCannon) + argsMap := requiredArgs(gameTypes.CannonGameType) args := toArgList(argsMap) - // Add cannon trace type again - args = append(args, "--trace-type", types.TraceTypeCannon.String()) + // Add cannon game type again + args = append(args, "--game-types", gameTypes.CannonGameType.String()) // We're fine with the same option being listed multiple times, just deduplicate them. cfg := configForArgs(t, args) - require.Equal(t, []types.TraceType{types.TraceTypeCannon}, cfg.TraceTypes) + require.Equal(t, []gameTypes.GameType{gameTypes.CannonGameType}, cfg.GameTypes) }) } func TestGameFactoryAddress(t *testing.T) { t.Run("RequiredWhenNetworkNotSupplied", func(t *testing.T) { - verifyArgsInvalid(t, "flag game-factory-address or network is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address")) + verifyArgsInvalid(t, "flag game-factory-address or network is required", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address")) }) t.Run("RequiredWhenMultipleNetworksSuppliedWithDifferentFactories", func(t *testing.T) { - verifyArgsInvalid(t, "specified networks use different dispute game factories, flag game-factory-address required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network", "op-sepolia,op-mainnet")) + verifyArgsInvalid(t, "specified networks use different dispute game factories, flag game-factory-address required", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--network", "op-sepolia,op-mainnet")) }) t.Run("Valid", func(t *testing.T) { addr := common.Address{0xbb, 0xcc, 0xdd} - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address="+addr.Hex())) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--game-factory-address="+addr.Hex())) require.Equal(t, addr, cfg.GameFactoryAddress) }) t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address=foo")) + verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--game-factory-address=foo")) }) t.Run("OverridesNetwork", func(t *testing.T) { addr := common.Address{0xbb, 0xcc, 0xdd} - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address", addr.Hex(), "--network", "op-sepolia")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--game-factory-address", addr.Hex(), "--network", "op-sepolia")) require.Equal(t, addr, cfg.GameFactoryAddress) }) } @@ -238,17 +247,17 @@ func TestNetwork(t *testing.T) { require.NoError(t, err) opSepoliaCfg, err := opSepolia.Config() require.NoError(t, err) - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=op-sepolia")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--network=op-sepolia")) require.EqualValues(t, *opSepoliaCfg.Addresses.DisputeGameFactoryProxy, cfg.GameFactoryAddress) }) t.Run("UnknownNetwork", func(t *testing.T) { - verifyArgsInvalid(t, "unknown chain: not-a-network", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=not-a-network")) + verifyArgsInvalid(t, "unknown chain: not-a-network", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--network=not-a-network")) }) t.Run("ChainIDAllowedWhenGameFactoryAddressSupplied", func(t *testing.T) { addr := common.Address{0xbb, 0xcc, 0xdd} - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=1234", "--game-factory-address="+addr.Hex())) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-factory-address", "--network=1234", "--game-factory-address="+addr.Hex())) require.Equal(t, addr, cfg.GameFactoryAddress) require.Equal(t, []string{"1234"}, cfg.Cannon.Networks) }) @@ -256,31 +265,31 @@ func TestNetwork(t *testing.T) { func TestGameAllowlist(t *testing.T) { t.Run("Optional", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-allowlist")) require.NoError(t, cfg.Check()) }) t.Run("Valid", func(t *testing.T) { addr := common.Address{0xbb, 0xcc, 0xdd} - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist="+addr.Hex())) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-allowlist", "--game-allowlist="+addr.Hex())) require.Contains(t, cfg.GameAllowlist, addr) }) t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist=foo")) + verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--game-allowlist", "--game-allowlist=foo")) }) } func TestTxManagerFlagsSupported(t *testing.T) { // Not a comprehensive list of flags, just enough to sanity check the txmgr.CLIFlags were defined - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--"+txmgr.NumConfirmationsFlagName, "7")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--"+txmgr.NumConfirmationsFlagName, "7")) require.Equal(t, uint64(7), cfg.TxMgrConfig.NumConfirmations) } func TestMaxConcurrency(t *testing.T) { t.Run("Valid", func(t *testing.T) { expected := uint(345) - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "345")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--max-concurrency", "345")) require.Equal(t, expected, cfg.MaxConcurrency) }) @@ -288,26 +297,26 @@ func TestMaxConcurrency(t *testing.T) { verifyArgsInvalid( t, "invalid value \"abc\" for flag -max-concurrency", - addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "abc")) + addRequiredArgs(gameTypes.AlphabetGameType, "--max-concurrency", "abc")) }) t.Run("Zero", func(t *testing.T) { verifyArgsInvalid( t, "max-concurrency must not be 0", - addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "0")) + addRequiredArgs(gameTypes.AlphabetGameType, "--max-concurrency", "0")) }) } func TestMaxPendingTx(t *testing.T) { t.Run("Valid", func(t *testing.T) { expected := uint64(345) - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "345")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--max-pending-tx", "345")) require.Equal(t, expected, cfg.MaxPendingTx) }) t.Run("Zero", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "0")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--max-pending-tx", "0")) require.Equal(t, uint64(0), cfg.MaxPendingTx) }) @@ -315,19 +324,19 @@ func TestMaxPendingTx(t *testing.T) { verifyArgsInvalid( t, "invalid value \"abc\" for flag -max-pending-tx", - addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "abc")) + addRequiredArgs(gameTypes.AlphabetGameType, "--max-pending-tx", "abc")) }) } func TestPollInterval(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType)) require.Equal(t, config.DefaultPollInterval, cfg.PollInterval) }) t.Run("Valid", func(t *testing.T) { expected := 100 * time.Second - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--http-poll-interval", "100s")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--http-poll-interval", "100s")) require.Equal(t, expected, cfg.PollInterval) }) @@ -335,18 +344,18 @@ func TestPollInterval(t *testing.T) { verifyArgsInvalid( t, "invalid value \"abc\" for flag -http-poll-interval", - addRequiredArgs(types.TraceTypeAlphabet, "--http-poll-interval", "abc")) + addRequiredArgs(gameTypes.AlphabetGameType, "--http-poll-interval", "abc")) }) } func TestMinUpdateInterval(t *testing.T) { t.Run("DefaultsToZero", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType)) require.Equal(t, time.Duration(0), cfg.MinUpdateInterval) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--min-update-interval", "10m")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--min-update-interval", "10m")) require.Equal(t, 10*time.Minute, cfg.MinUpdateInterval) }) @@ -354,175 +363,175 @@ func TestMinUpdateInterval(t *testing.T) { verifyArgsInvalid( t, "invalid value \"abc\" for flag -min-update-interval", - addRequiredArgs(types.TraceTypeAlphabet, "--min-update-interval", "abc")) + addRequiredArgs(gameTypes.AlphabetGameType, "--min-update-interval", "abc")) }) } func TestAsteriscOpProgramRequiredArgs(t *testing.T) { - traceType := types.TraceTypeAsterisc - t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { + gameType := gameTypes.AsteriscGameType + t.Run(fmt.Sprintf("TestAsteriscServer-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-server")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-server")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-server is required", addRequiredArgsExcept(traceType, "--asterisc-server")) + verifyArgsInvalid(t, "flag asterisc-server is required", addRequiredArgsExcept(gameType, "--asterisc-server")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-server", "--asterisc-server=./op-program")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-server", "--asterisc-server=./op-program")) require.Equal(t, "./op-program", cfg.Asterisc.Server) }) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestate")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-prestate")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(gameType, "--asterisc-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestate", "--asterisc-prestate=./pre.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-prestate", "--asterisc-prestate=./pre.json")) require.Equal(t, "./pre.json", cfg.AsteriscAbsolutePreState) }) }) - t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", gameType), func(t *testing.T) { allPrestateOptions := []string{"--prestates-url", "--asterisc-prestates-url", "--asterisc-prestate"} t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(types.TraceTypeAlphabet, allPrestateOptions)) + configForArgs(t, addRequiredArgsExceptArr(gameTypes.AlphabetGameType, allPrestateOptions)) }) t.Run("NotRequiredIfAsteriscPrestatesBaseURLSet", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--asterisc-prestates-url=http://localhost/foo")) + configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--asterisc-prestates-url=http://localhost/foo")) }) t.Run("AsteriscPrestatesBaseURLTakesPrecedence", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--asterisc-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--asterisc-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) require.Equal(t, "http://localhost/foo", cfg.AsteriscAbsolutePreStateBaseURL.String()) }) t.Run("RequiredIfAsteriscPrestatesBaseURLNotSet", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExceptArr(traceType, allPrestateOptions)) + verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExceptArr(gameType, allPrestateOptions)) }) t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=:foo/bar")) + verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=:foo/bar")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=http://localhost/foo")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=http://localhost/foo")) require.Equal(t, "http://localhost/foo", cfg.AsteriscAbsolutePreStateBaseURL.String()) }) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestates-url")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-prestates-url")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + verifyArgsInvalid(t, "flag prestates-url/asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(gameType, "--asterisc-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar")) require.Equal(t, "http://localhost/bar", cfg.AsteriscAbsolutePreStateBaseURL.String()) }) }) } func TestAsteriscKonaRequiredArgs(t *testing.T) { - traceType := types.TraceTypeAsteriscKona - t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { + gameType := gameTypes.AsteriscKonaGameType + t.Run(fmt.Sprintf("TestAsteriscServer-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-server")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-server")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-kona-server is required", addRequiredArgsExcept(traceType, "--asterisc-kona-server")) + verifyArgsInvalid(t, "flag asterisc-kona-server is required", addRequiredArgsExcept(gameType, "--asterisc-kona-server")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-server", "--asterisc-kona-server=./kona-host")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-kona-server", "--asterisc-kona-server=./kona-host")) require.Equal(t, "./kona-host", cfg.AsteriscKona.Server) }) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-prestate")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-prestate")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-kona-prestate")) + verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(gameType, "--asterisc-kona-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-prestate", "--asterisc-kona-prestate=./pre.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-kona-prestate", "--asterisc-kona-prestate=./pre.json")) require.Equal(t, "./pre.json", cfg.AsteriscKonaAbsolutePreState) }) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-prestates-url")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-prestates-url")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-kona-prestate")) + verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExcept(gameType, "--asterisc-kona-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-kona-prestates-url", "--asterisc-kona-prestates-url=http://localhost/bar")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-kona-prestates-url", "--asterisc-kona-prestates-url=http://localhost/bar")) require.Equal(t, "http://localhost/bar", cfg.AsteriscKonaAbsolutePreStateBaseURL.String()) }) }) - t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", gameType), func(t *testing.T) { allPrestateOptions := []string{"--prestates-url", "--asterisc-kona-prestates-url", "--asterisc-kona-prestate"} t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(types.TraceTypeAlphabet, allPrestateOptions)) + configForArgs(t, addRequiredArgsExceptArr(gameTypes.AlphabetGameType, allPrestateOptions)) }) t.Run("NotRequiredIfAsteriscKonaPrestatesBaseURLSet", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--asterisc-kona-prestates-url=http://localhost/foo")) + configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--asterisc-kona-prestates-url=http://localhost/foo")) }) t.Run("AsteriscKonaPrestatesBaseURLTakesPrecedence", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--asterisc-kona-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--asterisc-kona-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) require.Equal(t, "http://localhost/foo", cfg.AsteriscKonaAbsolutePreStateBaseURL.String()) }) t.Run("RequiredIfAsteriscKonaPrestatesBaseURLNotSet", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExceptArr(traceType, allPrestateOptions)) + verifyArgsInvalid(t, "flag prestates-url/asterisc-kona-prestates-url or asterisc-kona-prestate is required", addRequiredArgsExceptArr(gameType, allPrestateOptions)) }) t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=:foo/bar")) + verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=:foo/bar")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=http://localhost/foo")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=http://localhost/foo")) require.Equal(t, "http://localhost/foo", cfg.AsteriscKonaAbsolutePreStateBaseURL.String()) }) }) } // validateCustomNetworkFlagsProhibitedWithNetworkFlag ensures custom network flags are not used simultaneously with the network flag. -// It validates disallowed flag combinations for a given trace type and trace type prefix configuration. -func validateCustomNetworkFlagsProhibitedWithNetworkFlag(t *testing.T, traceType types.TraceType, traceTypeForFlagPrefix types.TraceType, customNetworkFlag string) { - expectedError := fmt.Sprintf("flag network can not be used with rollup-config/%v-rollup-config, l2-genesis/%v-l2-genesis, l1-genesis/%v-l1-genesis or %v", traceTypeForFlagPrefix, traceTypeForFlagPrefix, traceTypeForFlagPrefix, customNetworkFlag) +// It validates disallowed flag combinations for a given game type and game type prefix configuration. +func validateCustomNetworkFlagsProhibitedWithNetworkFlag(t *testing.T, gameType gameTypes.GameType, gameTypeForFlagPrefix gameTypes.GameType, customNetworkFlag string) { + expectedError := fmt.Sprintf("flag network can not be used with rollup-config/%v-rollup-config, l2-genesis/%v-l2-genesis, l1-genesis/%v-l1-genesis or %v", gameTypeForFlagPrefix, gameTypeForFlagPrefix, gameTypeForFlagPrefix, customNetworkFlag) // Test the custom l2 flag - t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndCustomL2Flag-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndCustomL2Flag-%v", gameType), func(t *testing.T) { verifyArgsInvalid( t, expectedError, - addRequiredArgs(traceType, fmt.Sprintf("--%v=true", customNetworkFlag))) + addRequiredArgs(gameType, fmt.Sprintf("--%v=true", customNetworkFlag))) }) // Now test flags with trace-specific permutations @@ -538,114 +547,114 @@ func validateCustomNetworkFlagsProhibitedWithNetworkFlag(t *testing.T, traceType postFix = "-withTraceSpecificPrefix" } - t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAnd%v-%v%v", testName, traceType, postFix), func(t *testing.T) { + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAnd%v-%v%v", testName, gameType, postFix), func(t *testing.T) { var prefix string if withTraceSpecificPrefix { - prefix = fmt.Sprintf("%v-", traceTypeForFlagPrefix) + prefix = fmt.Sprintf("%v-", gameTypeForFlagPrefix) } flagName := fmt.Sprintf("%v%v", prefix, flag) verifyArgsInvalid( t, expectedError, - addRequiredArgs(traceType, fmt.Sprintf("--%v=somevalue.json", flagName))) + addRequiredArgs(gameType, fmt.Sprintf("--%v=somevalue.json", flagName))) }) } } } func TestAsteriscBaseRequiredArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeAsterisc, types.TraceTypeAsteriscKona} { - traceType := traceType - t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), func(t *testing.T) { + for _, gameType := range []gameTypes.GameType{gameTypes.AsteriscGameType, gameTypes.AsteriscKonaGameType} { + gameType := gameType + t.Run(fmt.Sprintf("TestAsteriscBin-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-bin")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-bin")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-bin is required", addRequiredArgsExcept(traceType, "--asterisc-bin")) + verifyArgsInvalid(t, "flag asterisc-bin is required", addRequiredArgsExcept(gameType, "--asterisc-bin")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-bin", "--asterisc-bin=./asterisc")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--asterisc-bin", "--asterisc-bin=./asterisc")) require.Equal(t, "./asterisc", cfg.Asterisc.VmBin) }) }) - t.Run(fmt.Sprintf("TestL2Rpc-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestL2Rpc-%v", gameType), func(t *testing.T) { t.Run("RequiredForAsteriscTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(traceType, "--l2-eth-rpc")) + verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(gameType, "--l2-eth-rpc")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs) }) }) - t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, config.DefaultAsteriscSnapshotFreq, cfg.Asterisc.SnapshotFreq) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType, "--asterisc-snapshot-freq=1234")) + cfg := configForArgs(t, addRequiredArgs(gameType, "--asterisc-snapshot-freq=1234")) require.Equal(t, uint(1234), cfg.Asterisc.SnapshotFreq) }) t.Run("Invalid", func(t *testing.T) { verifyArgsInvalid(t, "invalid value \"abc\" for flag -asterisc-snapshot-freq", - addRequiredArgs(traceType, "--asterisc-snapshot-freq=abc")) + addRequiredArgs(gameType, "--asterisc-snapshot-freq=abc")) }) }) - t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", gameType), func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, config.DefaultAsteriscInfoFreq, cfg.Asterisc.InfoFreq) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType, "--asterisc-info-freq=1234")) + cfg := configForArgs(t, addRequiredArgs(gameType, "--asterisc-info-freq=1234")) require.Equal(t, uint(1234), cfg.Asterisc.InfoFreq) }) t.Run("Invalid", func(t *testing.T) { verifyArgsInvalid(t, "invalid value \"abc\" for flag -asterisc-info-freq", - addRequiredArgs(traceType, "--asterisc-info-freq=abc")) + addRequiredArgs(gameType, "--asterisc-info-freq=abc")) }) }) - t.Run(fmt.Sprintf("TestRequireEitherNetworkOrRollupAndGenesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestRequireEitherNetworkOrRollupAndGenesis-%v", gameType), func(t *testing.T) { verifyArgsInvalid( t, - fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", traceType, traceType), - addRequiredArgsExcept(traceType, "--network")) + fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", gameType, gameType), + addRequiredArgsExcept(gameType, "--network")) verifyArgsInvalid( t, - fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", traceType, traceType), - addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json")) + fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", gameType, gameType), + addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json")) verifyArgsInvalid( t, - fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", traceType, traceType), - addRequiredArgsExcept(traceType, "--network", "--l2-genesis=gensis.json")) + fmt.Sprintf("flag network or rollup-config/%s-rollup-config and l2-genesis/%s-l2-genesis is required", gameType, gameType), + addRequiredArgsExcept(gameType, "--network", "--l2-genesis=gensis.json")) }) - validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, traceType, types.TraceTypeAsteriscKona, "asterisc-kona-l2-custom") + validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, gameType, gameTypes.AsteriscKonaGameType, "asterisc-kona-l2-custom") - t.Run(fmt.Sprintf("TestNetwork-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestNetwork-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--network")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--network")) }) t.Run("NotRequiredWhenRollupAndGenesisSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--network", + configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) }) t.Run("NotRequiredWhenNetworkSpecified", func(t *testing.T) { - args := requiredArgs(traceType) + args := requiredArgs(gameType) delete(args, "--network") delete(args, "--game-factory-address") args["--network"] = "op-sepolia" @@ -654,29 +663,29 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) { }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork)) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--network", testNetwork)) require.Equal(t, []string{testNetwork}, cfg.Asterisc.Networks) }) }) - t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-rollup-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-rollup-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) require.Equal(t, []string{"rollup.json"}, cfg.Asterisc.RollupConfigPaths) }) }) - t.Run(fmt.Sprintf("TestL2Genesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestL2Genesis-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l2-genesis")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l2-genesis")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) require.Equal(t, []string{"genesis.json"}, cfg.Asterisc.L2GenesisPaths) }) }) @@ -684,77 +693,77 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) { } func TestAlphabetRequiredArgs(t *testing.T) { - t.Run(fmt.Sprintf("TestL2Rpc-%v", types.TraceTypeAlphabet), func(t *testing.T) { + t.Run(fmt.Sprintf("TestL2Rpc-%v", gameTypes.AlphabetGameType), func(t *testing.T) { t.Run("RequiredForAlphabetTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l2-eth-rpc")) + verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(gameTypes.AlphabetGameType, "--l2-eth-rpc")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType)) require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs) }) }) } func TestCannonCustomConfigArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned} { - traceType := traceType + for _, gameType := range []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.PermissionedGameType} { + gameType := gameType - t.Run(fmt.Sprintf("TestRequireEitherCannonNetworkOrRollupAndGenesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestRequireEitherCannonNetworkOrRollupAndGenesis-%v", gameType), func(t *testing.T) { verifyArgsInvalid( t, "flag network or rollup-config/cannon-rollup-config and l2-genesis/cannon-l2-genesis is required", - addRequiredArgsExcept(traceType, "--network")) + addRequiredArgsExcept(gameType, "--network")) verifyArgsInvalid( t, "flag network or rollup-config/cannon-rollup-config and l2-genesis/cannon-l2-genesis is required", - addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json")) verifyArgsInvalid( t, "flag network or rollup-config/cannon-rollup-config and l2-genesis/cannon-l2-genesis is required", - addRequiredArgsExcept(traceType, "--network", "--cannon-l2-genesis=gensis.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-l2-genesis=gensis.json")) }) - validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, traceType, types.TraceTypeCannon, "cannon-l2-custom") + validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, gameType, gameTypes.CannonGameType, "cannon-l2-custom") - t.Run(fmt.Sprintf("TestNetwork-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestNetwork-%v", gameType), func(t *testing.T) { t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--network", + configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork)) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--network", testNetwork)) require.Equal(t, []string{testNetwork}, cfg.Cannon.Networks) }) }) - t.Run(fmt.Sprintf("TestSetCannonL2ChainId-%v", traceType), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + t.Run(fmt.Sprintf("TestSetCannonL2ChainId-%v", gameType), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-l2-custom")) require.True(t, cfg.Cannon.L2Custom) }) - t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-rollup-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-rollup-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) require.Equal(t, []string{"rollup.json"}, cfg.Cannon.RollupConfigPaths) }) }) - t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-l2-genesis")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-l2-genesis")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json")) require.Equal(t, []string{"genesis.json"}, cfg.Cannon.L2GenesisPaths) }) }) @@ -762,49 +771,49 @@ func TestCannonCustomConfigArgs(t *testing.T) { } func TestSuperCannonCustomConfigArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned} { - traceType := traceType + for _, gameType := range []gameTypes.GameType{gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType} { + gameType := gameType - t.Run(fmt.Sprintf("TestRequireEitherCannonNetworkOrRollupAndGenesisAndDepset-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestRequireEitherCannonNetworkOrRollupAndGenesisAndDepset-%v", gameType), func(t *testing.T) { expectedErrorMessage := "flag network or rollup-config/cannon-rollup-config, l2-genesis/cannon-l2-genesis and depset-config/cannon-depset-config is required" // Missing all verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network")) + addRequiredArgsExcept(gameType, "--network")) // Missing l2-genesis verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-depset-config=depset.json")) // Missing rollup-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-l2-genesis=gensis.json", "--cannon-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-l2-genesis=gensis.json", "--cannon-depset-config=depset.json")) // Missing depset-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=gensis.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=gensis.json")) }) - validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, traceType, types.TraceTypeCannon, "cannon-l2-custom") + validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, gameType, gameTypes.CannonGameType, "cannon-l2-custom") - t.Run(fmt.Sprintf("TestNetwork-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestNetwork-%v", gameType), func(t *testing.T) { t.Run("NotRequiredWhenRollupGenesisAndDepsetIsSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--network", + configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork)) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--network", testNetwork)) require.Equal(t, []string{testNetwork}, cfg.Cannon.Networks) }) }) - t.Run(fmt.Sprintf("TestSetCannonL2ChainId-%v", traceType), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + t.Run(fmt.Sprintf("TestSetCannonL2ChainId-%v", gameType), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json", @@ -812,36 +821,36 @@ func TestSuperCannonCustomConfigArgs(t *testing.T) { require.True(t, cfg.Cannon.L2Custom) }) - t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-rollup-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-rollup-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) require.Equal(t, []string{"rollup.json"}, cfg.Cannon.RollupConfigPaths) }) }) - t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-l2-genesis")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-l2-genesis")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) require.Equal(t, []string{"genesis.json"}, cfg.Cannon.L2GenesisPaths) }) }) - t.Run(fmt.Sprintf("TestCannonDepsetConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonDepsetConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-depset-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-depset-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json", "--cannon-depset-config=depset.json")) require.Equal(t, "depset.json", cfg.Cannon.DepsetConfigPath) }) }) @@ -849,48 +858,48 @@ func TestSuperCannonCustomConfigArgs(t *testing.T) { } func TestSuperCannonKonaCustomConfigArgs(t *testing.T) { - traceType := types.TraceTypeSuperCannonKona + gameType := gameTypes.SuperCannonKonaGameType - t.Run(fmt.Sprintf("TestRequireEitherCannonKonaNetworkOrRollupAndGenesisAndDepset-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestRequireEitherCannonKonaNetworkOrRollupAndGenesisAndDepset-%v", gameType), func(t *testing.T) { expectedErrorMessage := "flag network or rollup-config/cannon-kona-rollup-config, l2-genesis/cannon-kona-l2-genesis and depset-config/cannon-kona-depset-config is required" // Missing all verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network")) + addRequiredArgsExcept(gameType, "--network")) // Missing l2-genesis verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-depset-config=depset.json")) // Missing rollup-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-kona-l2-genesis=gensis.json", "--cannon-kona-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-kona-l2-genesis=gensis.json", "--cannon-kona-depset-config=depset.json")) // Missing depset-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=gensis.json")) + addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=gensis.json")) }) - validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, traceType, types.TraceTypeCannonKona, "cannon-kona-l2-custom") + validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, gameType, gameTypes.CannonKonaGameType, "cannon-kona-l2-custom") - t.Run(fmt.Sprintf("TestNetwork-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestNetwork-%v", gameType), func(t *testing.T) { t.Run("NotRequiredWhenRollupGenesisAndDepsetIsSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--network", + configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork)) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--network", testNetwork)) require.Equal(t, []string{testNetwork}, cfg.CannonKona.Networks) }) }) - t.Run(fmt.Sprintf("TestSetCannonKonaL2ChainId-%v", traceType), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + t.Run(fmt.Sprintf("TestSetCannonKonaL2ChainId-%v", gameType), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json", @@ -898,85 +907,85 @@ func TestSuperCannonKonaCustomConfigArgs(t *testing.T) { require.True(t, cfg.CannonKona.L2Custom) }) - t.Run(fmt.Sprintf("TestCannonKonaRollupConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonKonaRollupConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-kona-rollup-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-kona-rollup-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) require.Equal(t, []string{"rollup.json"}, cfg.CannonKona.RollupConfigPaths) }) }) - t.Run(fmt.Sprintf("TestCannonKonaL2Genesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonKonaL2Genesis-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-kona-l2-genesis")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-kona-l2-genesis")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) require.Equal(t, []string{"genesis.json"}, cfg.CannonKona.L2GenesisPaths) }) }) - t.Run(fmt.Sprintf("TestCannonKonaDepsetConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonKonaDepsetConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-kona-depset-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-kona-depset-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--cannon-kona-rollup-config=rollup.json", "--cannon-kona-l2-genesis=genesis.json", "--cannon-kona-depset-config=depset.json")) require.Equal(t, "depset.json", cfg.CannonKona.DepsetConfigPath) }) }) } func TestSuperAsteriscKonaCustomConfigArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeSuperAsteriscKona} { - traceType := traceType + for _, gameType := range []gameTypes.GameType{gameTypes.SuperAsteriscKonaGameType} { + gameType := gameType - t.Run(fmt.Sprintf("TestRequireEitherAsteriscKonaNetworkOrRollupAndGenesisAndDepset-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestRequireEitherAsteriscKonaNetworkOrRollupAndGenesisAndDepset-%v", gameType), func(t *testing.T) { expectedErrorMessage := "flag network or rollup-config/asterisc-kona-rollup-config, l2-genesis/asterisc-kona-l2-genesis and depset-config/asterisc-kona-depset-config is required" // Missing all verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network")) + addRequiredArgsExcept(gameType, "--network")) // Missing l2-genesis verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-depset-config=depset.json")) // Missing rollup-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--asterisc-kona-l2-genesis=gensis.json", "--asterisc-kona-depset-config=depset.json")) + addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-l2-genesis=gensis.json", "--asterisc-kona-depset-config=depset.json")) // Missing depset-config verifyArgsInvalid( t, expectedErrorMessage, - addRequiredArgsExcept(traceType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=gensis.json")) + addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=gensis.json")) }) - validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, traceType, types.TraceTypeAsteriscKona, "asterisc-kona-l2-custom") + validateCustomNetworkFlagsProhibitedWithNetworkFlag(t, gameType, gameTypes.AsteriscKonaGameType, "asterisc-kona-l2-custom") - t.Run(fmt.Sprintf("TestNetwork-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestNetwork-%v", gameType), func(t *testing.T) { t.Run("NotRequiredWhenRollupGenesisAndDepsetIsSpecified", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--network", + configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork)) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--network", testNetwork)) require.Equal(t, []string{testNetwork}, cfg.AsteriscKona.Networks) }) }) - t.Run(fmt.Sprintf("TestSetAsteriscL2ChainId-%v", traceType), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + t.Run(fmt.Sprintf("TestSetAsteriscL2ChainId-%v", gameType), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json", @@ -984,36 +993,36 @@ func TestSuperAsteriscKonaCustomConfigArgs(t *testing.T) { require.True(t, cfg.AsteriscKona.L2Custom) }) - t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-rollup-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-rollup-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) require.Equal(t, []string{"rollup.json"}, cfg.AsteriscKona.RollupConfigPaths) }) }) - t.Run(fmt.Sprintf("TestAsteriscL2Genesis-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscL2Genesis-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-l2-genesis")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-l2-genesis")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) require.Equal(t, []string{"genesis.json"}, cfg.AsteriscKona.L2GenesisPaths) }) }) - t.Run(fmt.Sprintf("TestAsteriscDepsetConfig-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscDepsetConfig-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-kona-depset-config")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--asterisc-kona-depset-config")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--asterisc-kona-rollup-config=rollup.json", "--asterisc-kona-l2-genesis=genesis.json", "--asterisc-kona-depset-config=depset.json")) require.Equal(t, "depset.json", cfg.AsteriscKona.DepsetConfigPath) }) }) @@ -1021,167 +1030,167 @@ func TestSuperAsteriscKonaCustomConfigArgs(t *testing.T) { } func TestCannonRequiredArgs(t *testing.T) { - for _, traceType := range []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned, types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned} { - traceType := traceType - t.Run(fmt.Sprintf("TestCannonBin-%v", traceType), func(t *testing.T) { + for _, gameType := range []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.PermissionedGameType, gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType} { + gameType := gameType + t.Run(fmt.Sprintf("TestCannonBin-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-bin")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-bin")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-bin is required", addRequiredArgsExcept(traceType, "--cannon-bin")) + verifyArgsInvalid(t, "flag cannon-bin is required", addRequiredArgsExcept(gameType, "--cannon-bin")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-bin", "--cannon-bin=./cannon")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--cannon-bin", "--cannon-bin=./cannon")) require.Equal(t, "./cannon", cfg.Cannon.VmBin) }) }) - t.Run(fmt.Sprintf("TestCannonServer-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonServer-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-server")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-server")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag cannon-server is required", addRequiredArgsExcept(traceType, "--cannon-server")) + verifyArgsInvalid(t, "flag cannon-server is required", addRequiredArgsExcept(gameType, "--cannon-server")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-server", "--cannon-server=./op-program")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--cannon-server", "--cannon-server=./op-program")) require.Equal(t, "./op-program", cfg.Cannon.Server) }) }) - t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-prestate")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-prestate")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExcept(traceType, "--cannon-prestate")) + verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExcept(gameType, "--cannon-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-prestate", "--cannon-prestate=./pre.json")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--cannon-prestate", "--cannon-prestate=./pre.json")) require.Equal(t, "./pre.json", cfg.CannonAbsolutePreState) }) }) - t.Run(fmt.Sprintf("TestCannonPrestatesBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonPrestatesBaseURL-%v", gameType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-prestates-url")) + configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--cannon-prestates-url")) }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExcept(traceType, "--cannon-prestate")) + verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExcept(gameType, "--cannon-prestate")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--cannon-prestates-url", "--cannon-prestates-url=http://localhost/foo")) + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--cannon-prestates-url", "--cannon-prestates-url=http://localhost/foo")) require.Equal(t, "http://localhost/foo", cfg.CannonAbsolutePreStateBaseURL.String()) }) }) - t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestPrestateBaseURL-%v", gameType), func(t *testing.T) { allPrestateOptions := []string{"--prestates-url", "--cannon-prestates-url", "--cannon-prestate"} t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(types.TraceTypeAlphabet, allPrestateOptions)) + configForArgs(t, addRequiredArgsExceptArr(gameTypes.AlphabetGameType, allPrestateOptions)) }) t.Run("NotRequiredIfCannonPrestatesBaseURLSet", func(t *testing.T) { - configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--cannon-prestates-url=http://localhost/foo")) + configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--cannon-prestates-url=http://localhost/foo")) }) t.Run("CannonPrestatesBaseURLTakesPrecedence", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--cannon-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--cannon-prestates-url=http://localhost/foo", "--prestates-url=http://localhost/bar")) require.Equal(t, "http://localhost/foo", cfg.CannonAbsolutePreStateBaseURL.String()) }) t.Run("RequiredIfCannonPrestatesBaseURLNotSet", func(t *testing.T) { - verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExceptArr(traceType, allPrestateOptions)) + verifyArgsInvalid(t, "flag prestates-url/cannon-prestates-url or cannon-prestate is required", addRequiredArgsExceptArr(gameType, allPrestateOptions)) }) t.Run("Invalid", func(t *testing.T) { - verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=:foo/bar")) + verifyArgsInvalid(t, "invalid prestates-url (:foo/bar)", addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=:foo/bar")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExceptArr(traceType, allPrestateOptions, "--prestates-url=http://localhost/foo")) + cfg := configForArgs(t, addRequiredArgsExceptArr(gameType, allPrestateOptions, "--prestates-url=http://localhost/foo")) require.Equal(t, "http://localhost/foo", cfg.CannonAbsolutePreStateBaseURL.String()) }) }) - t.Run(fmt.Sprintf("TestL2Rpc-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestL2Rpc-%v", gameType), func(t *testing.T) { t.Run("RequiredForCannonTrace", func(t *testing.T) { - verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(traceType, "--l2-eth-rpc")) + verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(gameType, "--l2-eth-rpc")) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs) }) }) - t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, config.DefaultCannonSnapshotFreq, cfg.Cannon.SnapshotFreq) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType, "--cannon-snapshot-freq=1234")) + cfg := configForArgs(t, addRequiredArgs(gameType, "--cannon-snapshot-freq=1234")) require.Equal(t, uint(1234), cfg.Cannon.SnapshotFreq) }) t.Run("Invalid", func(t *testing.T) { verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-snapshot-freq", - addRequiredArgs(traceType, "--cannon-snapshot-freq=abc")) + addRequiredArgs(gameType, "--cannon-snapshot-freq=abc")) }) }) - t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", gameType), func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType)) + cfg := configForArgs(t, addRequiredArgs(gameType)) require.Equal(t, config.DefaultCannonInfoFreq, cfg.Cannon.InfoFreq) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(traceType, "--cannon-info-freq=1234")) + cfg := configForArgs(t, addRequiredArgs(gameType, "--cannon-info-freq=1234")) require.Equal(t, uint(1234), cfg.Cannon.InfoFreq) }) t.Run("Invalid", func(t *testing.T) { verifyArgsInvalid(t, "invalid value \"abc\" for flag -cannon-info-freq", - addRequiredArgs(traceType, "--cannon-info-freq=abc")) + addRequiredArgs(gameType, "--cannon-info-freq=abc")) }) }) } } func TestDepsetConfig(t *testing.T) { - for _, traceType := range types.TraceTypes { - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned { - t.Run("Required-"+traceType.String(), func(t *testing.T) { + for _, gameType := range gameTypes.SupportedGameTypes { + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType { + t.Run("Required-"+gameType.String(), func(t *testing.T) { verifyArgsInvalid(t, "flag network or rollup-config/cannon-rollup-config, l2-genesis/cannon-l2-genesis and depset-config/cannon-depset-config is required", - addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) }) - } else if traceType == types.TraceTypeSuperCannonKona { - t.Run("Required-"+traceType.String(), func(t *testing.T) { + } else if gameType == gameTypes.SuperCannonKonaGameType { + t.Run("Required-"+gameType.String(), func(t *testing.T) { verifyArgsInvalid(t, "flag network or rollup-config/cannon-kona-rollup-config, l2-genesis/cannon-kona-l2-genesis and depset-config/cannon-kona-depset-config is required", - addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) }) - } else if traceType == types.TraceTypeSuperAsteriscKona { - t.Run("Required-"+traceType.String(), func(t *testing.T) { + } else if gameType == gameTypes.SuperAsteriscKonaGameType { + t.Run("Required-"+gameType.String(), func(t *testing.T) { verifyArgsInvalid(t, "flag network or rollup-config/asterisc-kona-rollup-config, l2-genesis/asterisc-kona-l2-genesis and depset-config/asterisc-kona-depset-config is required", - addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) }) } else { - t.Run("NotRequired-"+traceType.String(), func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) + t.Run("NotRequired-"+gameType.String(), func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(gameType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json")) require.Equal(t, "", cfg.Cannon.DepsetConfigPath) }) } @@ -1189,89 +1198,89 @@ func TestDepsetConfig(t *testing.T) { } func TestDataDir(t *testing.T) { - for _, traceType := range types.TraceTypes { - traceType := traceType + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType - t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { - verifyArgsInvalid(t, "flag datadir is required", addRequiredArgsExcept(traceType, "--datadir")) + t.Run(fmt.Sprintf("RequiredFor-%v", gameType), func(t *testing.T) { + verifyArgsInvalid(t, "flag datadir is required", addRequiredArgsExcept(gameType, "--datadir")) }) } t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeCannon, "--datadir", "--datadir=/foo/bar/cannon")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.CannonGameType, "--datadir", "--datadir=/foo/bar/cannon")) require.Equal(t, "/foo/bar/cannon", cfg.Datadir) }) } func TestRollupRpc(t *testing.T) { - for _, traceType := range types.TraceTypes { - traceType := traceType + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned || traceType == types.TraceTypeSuperAsteriscKona || traceType == types.TraceTypeSuperCannonKona { - t.Run(fmt.Sprintf("NotRequiredFor-%v", traceType), func(t *testing.T) { - configForArgs(t, addRequiredArgsExcept(traceType, "--rollup-rpc")) + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType || gameType == gameTypes.SuperAsteriscKonaGameType || gameType == gameTypes.SuperCannonKonaGameType { + t.Run(fmt.Sprintf("NotRequiredFor-%v", gameType), func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(gameType, "--rollup-rpc")) }) } else { - t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { - verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(traceType, "--rollup-rpc")) + t.Run(fmt.Sprintf("RequiredFor-%v", gameType), func(t *testing.T) { + verifyArgsInvalid(t, "flag rollup-rpc is required", addRequiredArgsExcept(gameType, "--rollup-rpc")) }) } } t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType)) require.Equal(t, rollupRpc, cfg.RollupRpc) }) } func TestGameWindow(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType)) require.Equal(t, config.DefaultGameWindow, cfg.GameWindow) }) t.Run("Valid", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--game-window=1m")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--game-window=1m")) require.Equal(t, time.Minute, cfg.GameWindow) }) t.Run("ParsesDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--game-window=672h")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--game-window=672h")) require.Equal(t, config.DefaultGameWindow, cfg.GameWindow) }) } func TestUnsafeAllowInvalidPrestate(t *testing.T) { t.Run("DefaultsToFalse", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--unsafe-allow-invalid-prestate")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--unsafe-allow-invalid-prestate")) require.False(t, cfg.AllowInvalidPrestate) }) t.Run("EnabledWithNoValue", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType, "--unsafe-allow-invalid-prestate")) require.True(t, cfg.AllowInvalidPrestate) }) t.Run("EnabledWithTrue", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate=true")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType, "--unsafe-allow-invalid-prestate=true")) require.True(t, cfg.AllowInvalidPrestate) }) t.Run("DisabledWithFalse", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate=false")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.CannonGameType, "--unsafe-allow-invalid-prestate=false")) require.False(t, cfg.AllowInvalidPrestate) }) } func TestAdditionalBondClaimants(t *testing.T) { t.Run("DefaultsToEmpty", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--additional-bond-claimants")) + cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.AlphabetGameType, "--additional-bond-claimants")) require.Empty(t, cfg.AdditionalBondClaimants) }) t.Run("Valid-Single", func(t *testing.T) { claimant := common.Address{0xaa} - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", claimant.Hex())) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--additional-bond-claimants", claimant.Hex())) require.Contains(t, cfg.AdditionalBondClaimants, claimant) require.Len(t, cfg.AdditionalBondClaimants, 1) }) @@ -1280,7 +1289,7 @@ func TestAdditionalBondClaimants(t *testing.T) { claimant1 := common.Address{0xaa} claimant2 := common.Address{0xbb} claimant3 := common.Address{0xcc} - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--additional-bond-claimants", fmt.Sprintf("%v,%v,%v", claimant1.Hex(), claimant2.Hex(), claimant3.Hex()))) require.Contains(t, cfg.AdditionalBondClaimants, claimant1) require.Contains(t, cfg.AdditionalBondClaimants, claimant2) @@ -1290,25 +1299,25 @@ func TestAdditionalBondClaimants(t *testing.T) { t.Run("Invalid-Single", func(t *testing.T) { verifyArgsInvalid(t, "invalid additional claimant", - addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", "nope")) + addRequiredArgs(gameTypes.AlphabetGameType, "--additional-bond-claimants", "nope")) }) t.Run("Invalid-Multiple", func(t *testing.T) { claimant1 := common.Address{0xaa} claimant2 := common.Address{0xbb} verifyArgsInvalid(t, "invalid additional claimant", - addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", fmt.Sprintf("%v,nope,%v", claimant1.Hex(), claimant2.Hex()))) + addRequiredArgs(gameTypes.AlphabetGameType, "--additional-bond-claimants", fmt.Sprintf("%v,nope,%v", claimant1.Hex(), claimant2.Hex()))) }) } func TestSignerTLS(t *testing.T) { t.Run("EnabledByDefault", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet)) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType)) require.True(t, cfg.TxMgrConfig.SignerCLIConfig.TLSConfig.Enabled) }) t.Run("Disabled", func(t *testing.T) { - cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--signer.tls.enabled=false")) + cfg := configForArgs(t, addRequiredArgs(gameTypes.AlphabetGameType, "--signer.tls.enabled=false")) require.False(t, cfg.TxMgrConfig.SignerCLIConfig.TLSConfig.Enabled) }) } @@ -1340,35 +1349,35 @@ func dryRunWithArgs(cliArgs []string) (log.Logger, config.Config, error) { return logger, *cfg, err } -func addRequiredArgs(traceType types.TraceType, args ...string) []string { - req := requiredArgs(traceType) +func addRequiredArgs(gameType gameTypes.GameType, args ...string) []string { + req := requiredArgs(gameType) combined := toArgList(req) return append(combined, args...) } -func addRequiredArgsExcept(traceType types.TraceType, name string, optionalArgs ...string) []string { - req := requiredArgs(traceType) +func addRequiredArgsExcept(gameType gameTypes.GameType, name string, optionalArgs ...string) []string { + req := requiredArgs(gameType) delete(req, name) return append(toArgList(req), optionalArgs...) } -func addRequiredArgsForMultipleTracesExcept(traceType []types.TraceType, name string, optionalArgs ...string) []string { - req := requiredArgsMultiple(traceType) +func addRequiredArgsForMultipleGameTypesExcept(gameType []gameTypes.GameType, name string, optionalArgs ...string) []string { + req := requiredArgsMultiple(gameType) delete(req, name) return append(toArgList(req), optionalArgs...) } -func addRequiredArgsExceptArr(traceType types.TraceType, names []string, optionalArgs ...string) []string { - req := requiredArgs(traceType) +func addRequiredArgsExceptArr(gameType gameTypes.GameType, names []string, optionalArgs ...string) []string { + req := requiredArgs(gameType) for _, name := range names { delete(req, name) } return append(toArgList(req), optionalArgs...) } -func requiredArgsMultiple(traceType []types.TraceType) map[string]string { +func requiredArgsMultiple(gameType []gameTypes.GameType) map[string]string { args := make(map[string]string) - for _, t := range traceType { + for _, t := range gameType { for name, value := range requiredArgs(t) { args[name] = value } @@ -1376,31 +1385,31 @@ func requiredArgsMultiple(traceType []types.TraceType) map[string]string { return args } -func requiredArgs(traceType types.TraceType) map[string]string { +func requiredArgs(gameType gameTypes.GameType) map[string]string { args := map[string]string{ "--l1-eth-rpc": l1EthRpc, "--l1-beacon": l1Beacon, "--l2-eth-rpc": l2EthRpc, "--game-factory-address": gameFactoryAddressValue, - "--trace-type": traceType.String(), + "--game-types": gameType.String(), "--datadir": datadir, } - switch traceType { - case types.TraceTypeCannon, types.TraceTypePermissioned: + switch gameType { + case gameTypes.CannonGameType, gameTypes.PermissionedGameType: addRequiredCannonArgs(args) - case types.TraceTypeCannonKona: + case gameTypes.CannonKonaGameType: addRequiredCannonKonaArgs(args) - case types.TraceTypeAsterisc: + case gameTypes.AsteriscGameType: addRequiredAsteriscArgs(args) - case types.TraceTypeAsteriscKona: + case gameTypes.AsteriscKonaGameType: addRequiredAsteriscKonaArgs(args) - case types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned: + case gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType: addRequiredSuperCannonArgs(args) - case types.TraceTypeSuperCannonKona: + case gameTypes.SuperCannonKonaGameType: addRequiredSuperCannonKonaArgs(args) - case types.TraceTypeSuperAsteriscKona: + case gameTypes.SuperAsteriscKonaGameType: addRequiredSuperAsteriscKonaArgs(args) - case types.TraceTypeAlphabet, types.TraceTypeFast: + case gameTypes.AlphabetGameType, gameTypes.FastGameType: addRequiredOutputRootArgs(args) } return args diff --git a/op-challenger/cmd/run_trace.go b/op-challenger/cmd/run_trace.go index 07e74fdd79d..e2fee2e800f 100644 --- a/op-challenger/cmd/run_trace.go +++ b/op-challenger/cmd/run_trace.go @@ -4,11 +4,10 @@ import ( "context" "errors" "fmt" - "slices" "strings" "github.com/ethereum-optimism/optimism/op-challenger/flags" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/runner" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/cliapp" @@ -17,7 +16,6 @@ import ( ) var ( - ErrUnknownTraceType = errors.New("unknown trace type") ErrInvalidPrestateHash = errors.New("invalid prestate hash") ) @@ -40,9 +38,9 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er return nil, err } if len(runConfigs) == 0 { - // Default to running on-chain version of each enabled trace type - for _, traceType := range cfg.TraceTypes { - runConfigs = append(runConfigs, runner.RunConfig{TraceType: traceType}) + // Default to running on-chain version of each enabled game type + for _, gameType := range cfg.GameTypes { + runConfigs = append(runConfigs, runner.RunConfig{GameType: gameType}) } } return runner.NewRunner(logger, cfg, runConfigs), nil @@ -63,11 +61,11 @@ var RunTraceCommand = &cli.Command{ var ( RunTraceRunFlag = &cli.StringSliceFlag{ Name: "run", - Usage: "Specify a trace to run. Format is traceType/name/prestateHash where " + - "traceType is the trace type to use with the prestate (e.g cannon or asterisc-kona), " + + Usage: "Specify a trace to run. Format is gameType/name/prestateHash where " + + "gameType is the game type to use with the prestate (e.g cannon or asterisc-kona), " + "name is an arbitrary name for the prestate to use when reporting metrics and" + "prestateHash is the hex encoded absolute prestate commitment to use. " + - "If name is omitted the trace type name is used." + + "If name is omitted the game type name is used." + "If the prestateHash is omitted, the absolute prestate hash used for new games on-chain.", EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "RUN"), } @@ -91,14 +89,15 @@ func parseRunArg(arg string) (runner.RunConfig, error) { if len(opts) == 0 { return runner.RunConfig{}, fmt.Errorf("invalid run config %q", arg) } - cfg.TraceType = types.TraceType(opts[0]) - if !slices.Contains(types.TraceTypes, cfg.TraceType) { - return runner.RunConfig{}, fmt.Errorf("%w %q for run config %q", ErrUnknownTraceType, opts[0], arg) + gameType, err := gameTypes.SupportedGameTypeFromString(opts[0]) + if err != nil { + return runner.RunConfig{}, fmt.Errorf("%w %q for run config %q", err, opts[0], arg) } + cfg.GameType = gameType if len(opts) > 1 { cfg.Name = opts[1] } else { - cfg.Name = cfg.TraceType.String() + cfg.Name = cfg.GameType.String() } if len(opts) > 2 { if strings.HasPrefix(opts[2], "0x") { diff --git a/op-challenger/cmd/run_trace_test.go b/op-challenger/cmd/run_trace_test.go index 0e2512dd1a1..a2b5b664446 100644 --- a/op-challenger/cmd/run_trace_test.go +++ b/op-challenger/cmd/run_trace_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/runner" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -16,13 +16,13 @@ func TestParseRunArg(t *testing.T) { expected runner.RunConfig err error }{ - {arg: "unknown/test1/0x1234", err: ErrUnknownTraceType}, - {arg: "cannon", expected: runner.RunConfig{TraceType: types.TraceTypeCannon, Name: types.TraceTypeCannon.String()}}, - {arg: "asterisc", expected: runner.RunConfig{TraceType: types.TraceTypeAsterisc, Name: types.TraceTypeAsterisc.String()}}, - {arg: "cannon/test1", expected: runner.RunConfig{TraceType: types.TraceTypeCannon, Name: "test1"}}, - {arg: "cannon/test1/0x1234", expected: runner.RunConfig{TraceType: types.TraceTypeCannon, Name: "test1", Prestate: common.HexToHash("0x1234")}}, + {arg: "unknown/test1/0x1234", err: gameTypes.ErrUnknownGameType}, + {arg: "cannon", expected: runner.RunConfig{GameType: gameTypes.CannonGameType, Name: gameTypes.CannonGameType.String()}}, + {arg: "asterisc", expected: runner.RunConfig{GameType: gameTypes.AsteriscGameType, Name: gameTypes.AsteriscGameType.String()}}, + {arg: "cannon/test1", expected: runner.RunConfig{GameType: gameTypes.CannonGameType, Name: "test1"}}, + {arg: "cannon/test1/0x1234", expected: runner.RunConfig{GameType: gameTypes.CannonGameType, Name: "test1", Prestate: common.HexToHash("0x1234")}}, {arg: "cannon/test1/0xinvalid", err: ErrInvalidPrestateHash}, - {arg: "cannon/test1/develop.bin.gz", expected: runner.RunConfig{TraceType: types.TraceTypeCannon, Name: "test1", PrestateFilename: "develop.bin.gz"}}, + {arg: "cannon/test1/develop.bin.gz", expected: runner.RunConfig{GameType: gameTypes.CannonGameType, Name: "test1", PrestateFilename: "develop.bin.gz"}}, } for _, test := range tests { test := test diff --git a/op-challenger/config/config.go b/op-challenger/config/config.go index f73c51ebf69..469fba793f2 100644 --- a/op-challenger/config/config.go +++ b/op-challenger/config/config.go @@ -9,7 +9,7 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/txmgr" @@ -17,7 +17,7 @@ import ( ) var ( - ErrMissingTraceType = errors.New("no supported trace types specified") + ErrMissingGameType = errors.New("no supported game types specified") ErrMissingDatadir = errors.New("missing datadir") ErrMaxConcurrencyZero = errors.New("max concurrency must not be 0") ErrMissingL2Rpc = errors.New("missing L2 rpc url") @@ -80,7 +80,7 @@ type Config struct { SelectiveClaimResolution bool // Whether to only resolve claims for the claimants in AdditionalBondClaimants union [TxSender.From()] - TraceTypes []types.TraceType // Type of traces supported + GameTypes []gameTypes.GameType // Type of games supported RollupRpc string // L2 Rollup RPC Url SupervisorRPC string // L2 supervisor RPC URL @@ -129,7 +129,7 @@ func NewInteropConfig( supervisorRpc string, l2Rpcs []string, datadir string, - supportedTraceTypes ...types.TraceType, + supportedGameTypes ...gameTypes.GameType, ) Config { return Config{ L1EthRpc: l1EthRpc, @@ -140,7 +140,7 @@ func NewInteropConfig( MaxConcurrency: uint(runtime.NumCPU()), PollInterval: DefaultPollInterval, - TraceTypes: supportedTraceTypes, + GameTypes: supportedGameTypes, MaxPendingTx: DefaultMaxPendingTx, @@ -151,7 +151,7 @@ func NewInteropConfig( Datadir: datadir, Cannon: vm.Config{ - VmType: types.TraceTypeCannon, + VmType: gameTypes.CannonGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: l2Rpcs, @@ -161,7 +161,7 @@ func NewInteropConfig( BinarySnapshots: true, }, CannonKona: vm.Config{ - VmType: types.TraceTypeCannonKona, + VmType: gameTypes.CannonKonaGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: l2Rpcs, @@ -171,7 +171,7 @@ func NewInteropConfig( BinarySnapshots: true, }, Asterisc: vm.Config{ - VmType: types.TraceTypeAsterisc, + VmType: gameTypes.AsteriscGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: l2Rpcs, @@ -180,7 +180,7 @@ func NewInteropConfig( BinarySnapshots: true, }, AsteriscKona: vm.Config{ - VmType: types.TraceTypeAsteriscKona, + VmType: gameTypes.AsteriscKonaGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: l2Rpcs, @@ -199,7 +199,7 @@ func NewConfig( l2RollupRpc string, l2EthRpc string, datadir string, - supportedTraceTypes ...types.TraceType, + supportedGameTypes ...gameTypes.GameType, ) Config { return Config{ L1EthRpc: l1EthRpc, @@ -210,7 +210,7 @@ func NewConfig( MaxConcurrency: uint(runtime.NumCPU()), PollInterval: DefaultPollInterval, - TraceTypes: supportedTraceTypes, + GameTypes: supportedGameTypes, MaxPendingTx: DefaultMaxPendingTx, @@ -221,7 +221,7 @@ func NewConfig( Datadir: datadir, Cannon: vm.Config{ - VmType: types.TraceTypeCannon, + VmType: gameTypes.CannonGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: []string{l2EthRpc}, @@ -231,7 +231,7 @@ func NewConfig( BinarySnapshots: true, }, CannonKona: vm.Config{ - VmType: types.TraceTypeCannonKona, + VmType: gameTypes.CannonKonaGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: []string{l2EthRpc}, @@ -241,7 +241,7 @@ func NewConfig( BinarySnapshots: true, }, Asterisc: vm.Config{ - VmType: types.TraceTypeAsterisc, + VmType: gameTypes.AsteriscGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: []string{l2EthRpc}, @@ -250,7 +250,7 @@ func NewConfig( BinarySnapshots: true, }, AsteriscKona: vm.Config{ - VmType: types.TraceTypeAsteriscKona, + VmType: gameTypes.AsteriscKonaGameType, L1: l1EthRpc, L1Beacon: l1BeaconApi, L2s: []string{l2EthRpc}, @@ -262,8 +262,8 @@ func NewConfig( } } -func (c Config) TraceTypeEnabled(t types.TraceType) bool { - return slices.Contains(c.TraceTypes, t) +func (c Config) GameTypeEnabled(t gameTypes.GameType) bool { + return slices.Contains(c.GameTypes, t) } func (c Config) Check() error { @@ -279,8 +279,8 @@ func (c Config) Check() error { if c.GameFactoryAddress == (common.Address{}) { return ErrMissingGameFactoryAddress } - if len(c.TraceTypes) == 0 { - return ErrMissingTraceType + if len(c.GameTypes) == 0 { + return ErrMissingGameType } if c.Datadir == "" { return ErrMissingDatadir @@ -288,7 +288,7 @@ func (c Config) Check() error { if c.MaxConcurrency == 0 { return ErrMaxConcurrencyZero } - if c.TraceTypeEnabled(types.TraceTypeSuperCannon) || c.TraceTypeEnabled(types.TraceTypeSuperPermissioned) { + if c.GameTypeEnabled(gameTypes.SuperCannonGameType) || c.GameTypeEnabled(gameTypes.SuperPermissionedGameType) { if c.SupervisorRPC == "" { return ErrMissingSupervisorRpc } @@ -300,7 +300,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeCannon) || c.TraceTypeEnabled(types.TraceTypePermissioned) { + if c.GameTypeEnabled(gameTypes.CannonGameType) || c.GameTypeEnabled(gameTypes.PermissionedGameType) { if c.RollupRpc == "" { return ErrMissingRollupRpc } @@ -308,7 +308,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeSuperCannonKona) { + if c.GameTypeEnabled(gameTypes.SuperCannonKonaGameType) { if c.SupervisorRPC == "" { return ErrMissingSupervisorRpc } @@ -320,7 +320,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeCannonKona) { + if c.GameTypeEnabled(gameTypes.CannonKonaGameType) { if c.RollupRpc == "" { return ErrMissingRollupRpc } @@ -328,7 +328,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeAsterisc) { + if c.GameTypeEnabled(gameTypes.AsteriscGameType) { if c.RollupRpc == "" { return ErrMissingRollupRpc } @@ -345,7 +345,7 @@ func (c Config) Check() error { return ErrMissingAsteriscInfoFreq } } - if c.TraceTypeEnabled(types.TraceTypeAsteriscKona) { + if c.GameTypeEnabled(gameTypes.AsteriscKonaGameType) { if c.RollupRpc == "" { return ErrMissingRollupRpc } @@ -353,7 +353,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeSuperAsteriscKona) { + if c.GameTypeEnabled(gameTypes.SuperAsteriscKonaGameType) { if c.SupervisorRPC == "" { return ErrMissingSupervisorRpc } @@ -365,7 +365,7 @@ func (c Config) Check() error { return err } } - if c.TraceTypeEnabled(types.TraceTypeAlphabet) || c.TraceTypeEnabled(types.TraceTypeFast) { + if c.GameTypeEnabled(gameTypes.AlphabetGameType) || c.GameTypeEnabled(gameTypes.FastGameType) { if c.RollupRpc == "" { return ErrMissingRollupRpc } diff --git a/op-challenger/config/config_test.go b/op-challenger/config/config_test.go index a681b9d0451..3b1b0107b48 100644 --- a/op-challenger/config/config_test.go +++ b/op-challenger/config/config_test.go @@ -10,10 +10,10 @@ import ( "testing" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-service/txmgr" ) @@ -50,17 +50,17 @@ var ( validCannonKonaAbsolutePreStateBaseURL, _ = url.Parse("http://localhost/bar/") ) -var singleCannonTraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned} -var superCannonTraceTypes = []types.TraceType{types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned} -var allCannonTraceTypes []types.TraceType -var cannonKonaTraceTypes = []types.TraceType{types.TraceTypeCannonKona, types.TraceTypeSuperCannonKona} -var asteriscTraceTypes = []types.TraceType{types.TraceTypeAsterisc} -var asteriscKonaTraceTypes = []types.TraceType{types.TraceTypeAsteriscKona} -var superAsteriscKonaTraceTypes = []types.TraceType{types.TraceTypeSuperAsteriscKona} +var singleCannonGameTypes = []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.PermissionedGameType} +var superCannonGameTypes = []gameTypes.GameType{gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType} +var allCannonGameTypes []gameTypes.GameType +var cannonKonaGameTypes = []gameTypes.GameType{gameTypes.CannonKonaGameType, gameTypes.SuperCannonKonaGameType} +var asteriscGameTypes = []gameTypes.GameType{gameTypes.AsteriscGameType} +var asteriscKonaGameTypes = []gameTypes.GameType{gameTypes.AsteriscKonaGameType} +var superAsteriscKonaGameTypes = []gameTypes.GameType{gameTypes.SuperAsteriscKonaGameType} func init() { - allCannonTraceTypes = append(allCannonTraceTypes, singleCannonTraceTypes...) - allCannonTraceTypes = append(allCannonTraceTypes, superCannonTraceTypes...) + allCannonGameTypes = append(allCannonGameTypes, singleCannonGameTypes...) + allCannonGameTypes = append(allCannonGameTypes, superCannonGameTypes...) } func ensureExists(path string) error { @@ -150,34 +150,34 @@ func applyValidConfigForSuperAsteriscKona(t *testing.T, cfg *Config) { applyValidConfigForAsteriscKona(t, cfg) } -func validConfig(t *testing.T, traceType types.TraceType) Config { - cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validRollupRpc, validL2Rpc, validDatadir, traceType) - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned { +func validConfig(t *testing.T, gameType gameTypes.GameType) Config { + cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validRollupRpc, validL2Rpc, validDatadir, gameType) + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType { applyValidConfigForSuperCannon(t, &cfg) } - if traceType == types.TraceTypeCannon || traceType == types.TraceTypePermissioned { + if gameType == gameTypes.CannonGameType || gameType == gameTypes.PermissionedGameType { applyValidConfigForCannon(t, &cfg) } - if traceType == types.TraceTypeCannonKona { + if gameType == gameTypes.CannonKonaGameType { applyValidConfigForCannonKona(t, &cfg) } - if traceType == types.TraceTypeSuperCannonKona { + if gameType == gameTypes.SuperCannonKonaGameType { applyValidConfigForSuperCannonKona(t, &cfg) } - if traceType == types.TraceTypeAsterisc { + if gameType == gameTypes.AsteriscGameType { applyValidConfigForAsterisc(t, &cfg) } - if traceType == types.TraceTypeAsteriscKona { + if gameType == gameTypes.AsteriscKonaGameType { applyValidConfigForAsteriscKona(t, &cfg) } - if traceType == types.TraceTypeSuperAsteriscKona { + if gameType == gameTypes.SuperAsteriscKonaGameType { applyValidConfigForSuperAsteriscKona(t, &cfg) } return cfg } -func validConfigWithNoNetworks(t *testing.T, traceType types.TraceType) Config { - cfg := validConfig(t, traceType) +func validConfigWithNoNetworks(t *testing.T, gameType gameTypes.GameType) Config { + cfg := validConfig(t, gameType) mutateVmConfig := func(cfg *vm.Config) { cfg.Networks = nil @@ -186,16 +186,16 @@ func validConfigWithNoNetworks(t *testing.T, traceType types.TraceType) Config { cfg.L1GenesisPath = "bar.json" cfg.DepsetConfigPath = "foo.json" } - if slices.Contains(allCannonTraceTypes, traceType) { + if slices.Contains(allCannonGameTypes, gameType) { mutateVmConfig(&cfg.Cannon) } - if slices.Contains(cannonKonaTraceTypes, traceType) { + if slices.Contains(cannonKonaGameTypes, gameType) { mutateVmConfig(&cfg.CannonKona) } - if slices.Contains(asteriscTraceTypes, traceType) { + if slices.Contains(asteriscGameTypes, gameType) { mutateVmConfig(&cfg.Asterisc) } - if slices.Contains(asteriscKonaTraceTypes, traceType) { + if slices.Contains(asteriscKonaGameTypes, gameType) { mutateVmConfig(&cfg.AsteriscKona) } return cfg @@ -203,10 +203,10 @@ func validConfigWithNoNetworks(t *testing.T, traceType types.TraceType) Config { // TestValidConfigIsValid checks that the config provided by validConfig is actually valid func TestValidConfigIsValid(t *testing.T) { - for _, traceType := range types.TraceTypes { - traceType := traceType - t.Run(traceType.String(), func(t *testing.T) { - err := validConfig(t, traceType).Check() + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + t.Run(gameType.String(), func(t *testing.T) { + err := validConfig(t, gameType).Check() require.NoError(t, err) }) } @@ -214,160 +214,160 @@ func TestValidConfigIsValid(t *testing.T) { func TestTxMgrConfig(t *testing.T) { t.Run("Invalid", func(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) config.TxMgrConfig = txmgr.CLIConfig{} require.Equal(t, config.Check().Error(), "must provide a L1 RPC url") }) } func TestL1EthRpcRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) config.L1EthRpc = "" require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC) } func TestL1BeaconRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) config.L1Beacon = "" require.ErrorIs(t, config.Check(), ErrMissingL1Beacon) } func TestGameFactoryAddressRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) config.GameFactoryAddress = common.Address{} require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress) } func TestSelectiveClaimResolutionNotRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) require.Equal(t, false, config.SelectiveClaimResolution) require.NoError(t, config.Check()) } func TestGameAllowlistNotRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeCannon) + config := validConfig(t, gameTypes.CannonGameType) config.GameAllowlist = []common.Address{} require.NoError(t, config.Check()) } func TestCannonRequiredArgs(t *testing.T) { - for _, traceType := range allCannonTraceTypes { - traceType := traceType + for _, gameType := range allCannonGameTypes { + gameType := gameType - t.Run(fmt.Sprintf("TestCannonBinRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonBinRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.Cannon.VmBin = "" require.ErrorIs(t, config.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestCannonServerRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonServerRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.Cannon.Server = "" require.ErrorIs(t, config.Check(), vm.ErrMissingServer) }) - t.Run(fmt.Sprintf("TestCannonAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonAbsolutePreStateOrBaseURLRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonAbsolutePreState = "" config.CannonAbsolutePreStateBaseURL = nil require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState) }) - t.Run(fmt.Sprintf("TestCannonAbsolutePreState-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonAbsolutePreState-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonAbsolutePreState = validCannonAbsolutePreState config.CannonAbsolutePreStateBaseURL = nil require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestCannonAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonAbsolutePreStateBaseURL-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonAbsolutePreState = "" config.CannonAbsolutePreStateBaseURL = validCannonAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAllowSupplyingBothCannonAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAllowSupplyingBothCannonAbsolutePreStateAndBaseURL-%v", gameType), func(t *testing.T) { // Since the prestate baseURL might be inherited from the --prestate-urls option, allow overriding it with a specific prestate - config := validConfig(t, traceType) + config := validConfig(t, gameType) config.CannonAbsolutePreState = validCannonAbsolutePreState config.CannonAbsolutePreStateBaseURL = validCannonAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestL2RpcRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.L2Rpcs = nil require.ErrorIs(t, config.Check(), ErrMissingL2Rpc) }) - t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.Cannon.SnapshotFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingCannonSnapshotFreq) }) }) - t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonInfoFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.Cannon.InfoFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingCannonInfoFreq) }) }) - t.Run(fmt.Sprintf("TestCannonNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestCannonNetworkOrRollupConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.Cannon.RollupConfigPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig) }) - t.Run(fmt.Sprintf("TestCannonNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestCannonNetworkOrL2GenesisRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.Cannon.L2GenesisPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis) }) - t.Run(fmt.Sprintf("TestMaySpecifyNetworkAndCustomConfigs-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestMaySpecifyNetworkAndCustomConfigs-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = []string{validCannonNetwork} cfg.Cannon.RollupConfigPaths = []string{"foo.json"} cfg.Cannon.L2GenesisPaths = []string{"genesis.json"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = []string{"unknown"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestNetworkMayBeAnyChainID-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMayBeAnyChainID-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = []string{"467294"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkInvalidWhenNotEntirelyNumeric-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkInvalidWhenNotEntirelyNumeric-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = []string{"467294a"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestDebugInfoEnabled-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestDebugInfoEnabled-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) require.True(t, cfg.Cannon.DebugInfo) }) - t.Run(fmt.Sprintf("TestVMBinExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestVMBinExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.VmBin = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestServerExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestServerExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Server = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingServer) }) @@ -375,123 +375,123 @@ func TestCannonRequiredArgs(t *testing.T) { } func TestCannonKonaRequiredArgs(t *testing.T) { - for _, traceType := range cannonKonaTraceTypes { - traceType := traceType + for _, gameType := range cannonKonaGameTypes { + gameType := gameType - t.Run(fmt.Sprintf("TestCannonKonaBinRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaBinRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonKona.VmBin = "" require.ErrorIs(t, config.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestCannonKonaServerRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaServerRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonKona.Server = "" require.ErrorIs(t, config.Check(), vm.ErrMissingServer) }) - t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreStateOrBaseURLRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonKonaAbsolutePreState = "" config.CannonKonaAbsolutePreStateBaseURL = nil require.ErrorIs(t, config.Check(), ErrMissingCannonKonaAbsolutePreState) }) - t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreState-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreState-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonKonaAbsolutePreState = validCannonAbsolutePreState config.CannonKonaAbsolutePreStateBaseURL = nil require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaAbsolutePreStateBaseURL-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.CannonKonaAbsolutePreState = "" config.CannonKonaAbsolutePreStateBaseURL = validCannonAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAllowSupplyingBothCannonKonaAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAllowSupplyingBothCannonKonaAbsolutePreStateAndBaseURL-%v", gameType), func(t *testing.T) { // Since the prestate baseURL might be inherited from the --prestate-urls option, allow overriding it with a specific prestate - config := validConfig(t, traceType) + config := validConfig(t, gameType) config.CannonKonaAbsolutePreState = validCannonAbsolutePreState config.CannonKonaAbsolutePreStateBaseURL = validCannonAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestL2RpcRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.L2Rpcs = nil require.ErrorIs(t, config.Check(), ErrMissingL2Rpc) }) - t.Run(fmt.Sprintf("TestCannonKonaSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonKonaSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.CannonKona.SnapshotFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingCannonKonaSnapshotFreq) }) }) - t.Run(fmt.Sprintf("TestCannonKonaInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestCannonKonaInfoFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.CannonKona.InfoFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingCannonKonaInfoFreq) }) }) - t.Run(fmt.Sprintf("TestCannonKonaNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaNetworkOrRollupConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.CannonKona.RollupConfigPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig) }) - t.Run(fmt.Sprintf("TestCannonKonaNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestCannonKonaNetworkOrL2GenesisRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.CannonKona.L2GenesisPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis) }) - t.Run(fmt.Sprintf("TestMaySpecifyNetworkAndCustomConfigs-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestMaySpecifyNetworkAndCustomConfigs-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.Networks = []string{validCannonNetwork} cfg.CannonKona.RollupConfigPaths = []string{"foo.json"} cfg.CannonKona.L2GenesisPaths = []string{"genesis.json"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.Networks = []string{"unknown"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestNetworkMayBeAnyChainID-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMayBeAnyChainID-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.Networks = []string{"467294"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkInvalidWhenNotEntirelyNumeric-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkInvalidWhenNotEntirelyNumeric-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.Networks = []string{"467294a"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestDebugInfoEnabled-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestDebugInfoEnabled-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) require.True(t, cfg.CannonKona.DebugInfo) }) - t.Run(fmt.Sprintf("TestVMBinExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestVMBinExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.VmBin = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestServerExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestServerExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.CannonKona.Server = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingServer) }) @@ -499,10 +499,10 @@ func TestCannonKonaRequiredArgs(t *testing.T) { } func TestDepsetConfig(t *testing.T) { - for _, traceType := range superCannonTraceTypes { - traceType := traceType - t.Run(fmt.Sprintf("TestCannonNetworkOrDepsetConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + for _, gameType := range superCannonGameTypes { + gameType := gameType + t.Run(fmt.Sprintf("TestCannonNetworkOrDepsetConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = nil cfg.Cannon.RollupConfigPaths = []string{"foo.json"} cfg.Cannon.L2GenesisPaths = []string{"genesis.json"} @@ -511,10 +511,10 @@ func TestDepsetConfig(t *testing.T) { }) } - for _, traceType := range superAsteriscKonaTraceTypes { - traceType := traceType - t.Run(fmt.Sprintf("TestAsteriscNetworkOrDepsetConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + for _, gameType := range superAsteriscKonaGameTypes { + gameType := gameType + t.Run(fmt.Sprintf("TestAsteriscNetworkOrDepsetConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.Networks = nil cfg.AsteriscKona.RollupConfigPaths = []string{"foo.json"} cfg.AsteriscKona.L2GenesisPaths = []string{"genesis.json"} @@ -523,10 +523,10 @@ func TestDepsetConfig(t *testing.T) { }) } - for _, traceType := range singleCannonTraceTypes { - traceType := traceType - t.Run(fmt.Sprintf("TestDepsetConfigNotRequired-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + for _, gameType := range singleCannonGameTypes { + gameType := gameType + t.Run(fmt.Sprintf("TestDepsetConfigNotRequired-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Cannon.Networks = nil cfg.Cannon.RollupConfigPaths = []string{"foo.json"} cfg.Cannon.L1GenesisPath = "bar.json" @@ -536,10 +536,10 @@ func TestDepsetConfig(t *testing.T) { }) } - for _, traceType := range asteriscKonaTraceTypes { - traceType := traceType - t.Run(fmt.Sprintf("TestDepsetConfigNotRequired-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + for _, gameType := range asteriscKonaGameTypes { + gameType := gameType + t.Run(fmt.Sprintf("TestDepsetConfigNotRequired-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.Networks = nil cfg.AsteriscKona.RollupConfigPaths = []string{"foo.json"} cfg.AsteriscKona.L1GenesisPath = "bar.json" @@ -551,111 +551,111 @@ func TestDepsetConfig(t *testing.T) { } func TestAsteriscRequiredArgs(t *testing.T) { - for _, traceType := range asteriscTraceTypes { - traceType := traceType + for _, gameType := range asteriscGameTypes { + gameType := gameType - t.Run(fmt.Sprintf("TestAsteriscBinRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscBinRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.Asterisc.VmBin = "" require.ErrorIs(t, config.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestAsteriscServerRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscServerRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.Asterisc.Server = "" require.ErrorIs(t, config.Check(), vm.ErrMissingServer) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateOrBaseURLRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscAbsolutePreState = "" config.AsteriscAbsolutePreStateBaseURL = nil require.ErrorIs(t, config.Check(), ErrMissingAsteriscAbsolutePreState) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePreState-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreState-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscAbsolutePreState = validAsteriscAbsolutePreState config.AsteriscAbsolutePreStateBaseURL = nil require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateBaseURL-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscAbsolutePreState = "" config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAllowSupplingBothAsteriscAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAllowSupplingBothAsteriscAbsolutePreStateAndBaseURL-%v", gameType), func(t *testing.T) { // Since the prestate base URL might be inherited from the --prestate-urls option, allow overriding it with a specific prestate - config := validConfig(t, traceType) + config := validConfig(t, gameType) config.AsteriscAbsolutePreState = validAsteriscAbsolutePreState config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestL2RpcRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.L2Rpcs = nil require.ErrorIs(t, config.Check(), ErrMissingL2Rpc) }) - t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.Asterisc.SnapshotFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscSnapshotFreq) }) }) - t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.Asterisc.InfoFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscInfoFreq) }) }) - t.Run(fmt.Sprintf("TestAsteriscNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscNetworkOrRollupConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.Asterisc.RollupConfigPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig) }) - t.Run(fmt.Sprintf("TestAsteriscNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscNetworkOrL2GenesisRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.Asterisc.L2GenesisPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis) }) - t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfigs-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfigs-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Asterisc.Networks = []string{validAsteriscNetwork} cfg.Asterisc.RollupConfigPaths = []string{"foo.json"} cfg.Asterisc.L2GenesisPaths = []string{"genesis.json"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Asterisc.Networks = []string{"unknown"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestDebugInfoDisabled-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestDebugInfoDisabled-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) require.False(t, cfg.Asterisc.DebugInfo) }) - t.Run(fmt.Sprintf("TestVMBinExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestVMBinExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Asterisc.VmBin = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestServerExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestServerExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.Asterisc.Server = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingServer) }) @@ -663,111 +663,111 @@ func TestAsteriscRequiredArgs(t *testing.T) { } func TestAsteriscKonaRequiredArgs(t *testing.T) { - for _, traceType := range asteriscKonaTraceTypes { - traceType := traceType + for _, gameType := range asteriscKonaGameTypes { + gameType := gameType - t.Run(fmt.Sprintf("TestAsteriscKonaBinRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaBinRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscKona.VmBin = "" require.ErrorIs(t, config.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestAsteriscKonaServerRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaServerRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscKona.Server = "" require.ErrorIs(t, config.Check(), vm.ErrMissingServer) }) - t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreStateOrBaseURLRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscKonaAbsolutePreState = "" config.AsteriscKonaAbsolutePreStateBaseURL = nil require.ErrorIs(t, config.Check(), ErrMissingAsteriscKonaAbsolutePreState) }) - t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreState-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreState-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscKonaAbsolutePreState = validAsteriscKonaAbsolutePreState config.AsteriscKonaAbsolutePreStateBaseURL = nil require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaAbsolutePreStateBaseURL-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.AsteriscKonaAbsolutePreState = "" config.AsteriscKonaAbsolutePreStateBaseURL = validAsteriscKonaAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestAllowSupplyingBothAsteriscKonaAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAllowSupplyingBothAsteriscKonaAbsolutePreStateAndBaseURL-%v", gameType), func(t *testing.T) { // Since the prestate base URL might be inherited from the --prestate-urls option, allow overriding it with a specific prestate - config := validConfig(t, traceType) + config := validConfig(t, gameType) config.AsteriscKonaAbsolutePreState = validAsteriscKonaAbsolutePreState config.AsteriscKonaAbsolutePreStateBaseURL = validAsteriscKonaAbsolutePreStateBaseURL require.NoError(t, config.Check()) }) - t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestL2RpcRequired-%v", gameType), func(t *testing.T) { + config := validConfig(t, gameType) config.L2Rpcs = nil require.ErrorIs(t, config.Check(), ErrMissingL2Rpc) }) - t.Run(fmt.Sprintf("TestAsteriscKonaSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscKonaSnapshotFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.AsteriscKona.SnapshotFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscKonaSnapshotFreq) }) }) - t.Run(fmt.Sprintf("TestAsteriscKonaInfoFreq-%v", traceType), func(t *testing.T) { + t.Run(fmt.Sprintf("TestAsteriscKonaInfoFreq-%v", gameType), func(t *testing.T) { t.Run("MustNotBeZero", func(t *testing.T) { - cfg := validConfig(t, traceType) + cfg := validConfig(t, gameType) cfg.AsteriscKona.InfoFreq = 0 require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscKonaInfoFreq) }) }) - t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrRollupConfigRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.AsteriscKona.RollupConfigPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig) }) - t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { - cfg := validConfigWithNoNetworks(t, traceType) + t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrL2GenesisRequired-%v", gameType), func(t *testing.T) { + cfg := validConfigWithNoNetworks(t, gameType) cfg.AsteriscKona.L2GenesisPaths = nil require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis) }) - t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfig-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfig-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.Networks = []string{validAsteriscKonaNetwork} cfg.AsteriscKona.RollupConfigPaths = []string{"foo.json"} cfg.AsteriscKona.L2GenesisPaths = []string{"genesis.json"} require.NoError(t, cfg.Check()) }) - t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.Networks = []string{"unknown"} require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown) }) - t.Run(fmt.Sprintf("TestDebugInfoDisabled-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestDebugInfoDisabled-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) require.False(t, cfg.AsteriscKona.DebugInfo) }) - t.Run(fmt.Sprintf("TestVMBinExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestVMBinExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.VmBin = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingBin) }) - t.Run(fmt.Sprintf("TestServerExists-%v", traceType), func(t *testing.T) { - cfg := validConfig(t, traceType) + t.Run(fmt.Sprintf("TestServerExists-%v", gameType), func(t *testing.T) { + cfg := validConfig(t, gameType) cfg.AsteriscKona.Server = nonExistingFile require.ErrorIs(t, cfg.Check(), vm.ErrMissingServer) }) @@ -775,39 +775,39 @@ func TestAsteriscKonaRequiredArgs(t *testing.T) { } func TestDatadirRequired(t *testing.T) { - config := validConfig(t, types.TraceTypeAlphabet) + config := validConfig(t, gameTypes.AlphabetGameType) config.Datadir = "" require.ErrorIs(t, config.Check(), ErrMissingDatadir) } func TestMaxConcurrency(t *testing.T) { t.Run("Required", func(t *testing.T) { - config := validConfig(t, types.TraceTypeAlphabet) + config := validConfig(t, gameTypes.AlphabetGameType) config.MaxConcurrency = 0 require.ErrorIs(t, config.Check(), ErrMaxConcurrencyZero) }) t.Run("DefaultToNumberOfCPUs", func(t *testing.T) { - config := validConfig(t, types.TraceTypeAlphabet) + config := validConfig(t, gameTypes.AlphabetGameType) require.EqualValues(t, runtime.NumCPU(), config.MaxConcurrency) }) } func TestHttpPollInterval(t *testing.T) { t.Run("Default", func(t *testing.T) { - config := validConfig(t, types.TraceTypeAlphabet) + config := validConfig(t, gameTypes.AlphabetGameType) require.EqualValues(t, DefaultPollInterval, config.PollInterval) }) } func TestRollupRpcRequired(t *testing.T) { - for _, traceType := range types.TraceTypes { - traceType := traceType - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned || traceType == types.TraceTypeSuperAsteriscKona || traceType == types.TraceTypeSuperCannonKona { + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType || gameType == gameTypes.SuperAsteriscKonaGameType || gameType == gameTypes.SuperCannonKonaGameType { continue } - t.Run(traceType.String(), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run(gameType.String(), func(t *testing.T) { + config := validConfig(t, gameType) config.RollupRpc = "" require.ErrorIs(t, config.Check(), ErrMissingRollupRpc) }) @@ -816,42 +816,42 @@ func TestRollupRpcRequired(t *testing.T) { func TestRollupRpcNotRequiredForInterop(t *testing.T) { t.Run("SuperCannon", func(t *testing.T) { - config := validConfig(t, types.TraceTypeSuperCannon) + config := validConfig(t, gameTypes.SuperCannonGameType) config.RollupRpc = "" require.NoError(t, config.Check()) }) t.Run("SuperPermissioned", func(t *testing.T) { - config := validConfig(t, types.TraceTypeSuperPermissioned) + config := validConfig(t, gameTypes.SuperPermissionedGameType) config.RollupRpc = "" require.NoError(t, config.Check()) }) t.Run("SuperCannonKona", func(t *testing.T) { - config := validConfig(t, types.TraceTypeSuperCannonKona) + config := validConfig(t, gameTypes.SuperCannonKonaGameType) config.RollupRpc = "" require.NoError(t, config.Check()) }) t.Run("SuperAsteriscKona", func(t *testing.T) { - config := validConfig(t, types.TraceTypeSuperAsteriscKona) + config := validConfig(t, gameTypes.SuperAsteriscKonaGameType) config.RollupRpc = "" require.NoError(t, config.Check()) }) } func TestSupervisorRpc(t *testing.T) { - for _, traceType := range types.TraceTypes { - traceType := traceType - if traceType == types.TraceTypeSuperCannon || traceType == types.TraceTypeSuperPermissioned || traceType == types.TraceTypeSuperAsteriscKona || traceType == types.TraceTypeSuperCannonKona { - t.Run("RequiredFor"+traceType.String(), func(t *testing.T) { - config := validConfig(t, traceType) + for _, gameType := range gameTypes.SupportedGameTypes { + gameType := gameType + if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType || gameType == gameTypes.SuperAsteriscKonaGameType || gameType == gameTypes.SuperCannonKonaGameType { + t.Run("RequiredFor"+gameType.String(), func(t *testing.T) { + config := validConfig(t, gameType) config.SupervisorRPC = "" require.ErrorIs(t, config.Check(), ErrMissingSupervisorRpc) }) } else { - t.Run("NotRequiredFor"+traceType.String(), func(t *testing.T) { - config := validConfig(t, traceType) + t.Run("NotRequiredFor"+gameType.String(), func(t *testing.T) { + config := validConfig(t, gameType) config.SupervisorRPC = "" require.NoError(t, config.Check()) }) @@ -859,9 +859,9 @@ func TestSupervisorRpc(t *testing.T) { } } -func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) { - cfg := validConfig(t, types.TraceTypeCannon) - cfg.TraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet} +func TestRequireConfigForMultipleGameTypesForCannon(t *testing.T) { + cfg := validConfig(t, gameTypes.CannonGameType) + cfg.GameTypes = []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.AlphabetGameType} // Set all required options and check its valid cfg.RollupRpc = validRollupRpc require.NoError(t, cfg.Check()) @@ -877,9 +877,9 @@ func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) { require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc) } -func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) { - cfg := validConfig(t, types.TraceTypeAsterisc) - cfg.TraceTypes = []types.TraceType{types.TraceTypeAsterisc, types.TraceTypeAlphabet} +func TestRequireConfigForMultipleGameTypesForAsterisc(t *testing.T) { + cfg := validConfig(t, gameTypes.AsteriscGameType) + cfg.GameTypes = []gameTypes.GameType{gameTypes.AsteriscGameType, gameTypes.AlphabetGameType} // Set all required options and check its valid cfg.RollupRpc = validRollupRpc require.NoError(t, cfg.Check()) @@ -895,11 +895,11 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) { require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc) } -func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) { - cfg := validConfig(t, types.TraceTypeCannon) +func TestRequireConfigForMultipleGameTypesForCannonAndAsterisc(t *testing.T) { + cfg := validConfig(t, gameTypes.CannonGameType) applyValidConfigForAsterisc(t, &cfg) - cfg.TraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypeAsterisc, types.TraceTypeAlphabet, types.TraceTypeFast} + cfg.GameTypes = []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.AsteriscGameType, gameTypes.AlphabetGameType, gameTypes.FastGameType} // Set all required options and check its valid cfg.RollupRpc = validRollupRpc require.NoError(t, cfg.Check()) diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index dfb07af5e32..1a9c4c2efd2 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/flags" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -27,19 +27,24 @@ import ( const EnvVarPrefix = "OP_CHALLENGER" -func prefixEnvVars(name string) []string { - return opservice.PrefixEnvVar(EnvVarPrefix, name) +func prefixEnvVars(names ...string) []string { + + envs := make([]string, 0, len(names)) + for _, name := range names { + envs = append(envs, EnvVarPrefix+"_"+name) + } + return envs } var ( - faultDisputeVMs = []types.TraceType{ - types.TraceTypeCannon, - types.TraceTypeCannonKona, - types.TraceTypeAsterisc, - types.TraceTypeAsteriscKona, - types.TraceTypeSuperCannon, - types.TraceTypeSuperCannonKona, - types.TraceTypeSuperAsteriscKona, + faultDisputeVMs = []gameTypes.GameType{ + gameTypes.CannonGameType, + gameTypes.CannonKonaGameType, + gameTypes.AsteriscGameType, + gameTypes.AsteriscKonaGameType, + gameTypes.SuperCannonGameType, + gameTypes.SuperCannonKonaGameType, + gameTypes.SuperAsteriscKonaGameType, } // Required Flags L1EthRpcFlag = &cli.StringFlag{ @@ -78,11 +83,12 @@ var ( "If empty, the challenger will play all games.", EnvVars: prefixEnvVars("GAME_ALLOWLIST"), } - TraceTypeFlag = &cli.StringSliceFlag{ - Name: "trace-type", - Usage: "The trace types to support. Valid options: " + openum.EnumString(types.TraceTypes), - EnvVars: prefixEnvVars("TRACE_TYPE"), - Value: cli.NewStringSlice(types.TraceTypeCannon.String(), types.TraceTypeAsteriscKona.String(), types.TraceTypeCannonKona.String()), + GameTypesFlag = &cli.StringSliceFlag{ + Name: "game-types", + Aliases: []string{"trace-type"}, // For backwards compatibility + Usage: "The game types to support. Valid options: " + openum.EnumStringer(gameTypes.SupportedGameTypes), + EnvVars: prefixEnvVars("GAME_TYPES", "TRACE_TYPE"), + Value: cli.NewStringSlice(gameTypes.CannonGameType.String(), gameTypes.AsteriscKonaGameType.String(), gameTypes.CannonKonaGameType.String()), } DatadirFlag = &cli.StringFlag{ Name: "datadir", @@ -103,7 +109,7 @@ var ( } L2ExperimentalEthRpcFlag = &cli.StringFlag{ Name: "l2-experimental-eth-rpc", - Usage: "L2 Address of L2 JSON-RPC endpoint to use (eth and debug namespace required with execution witness support) (cannon/asterisc trace type only)", + Usage: "L2 Address of L2 JSON-RPC endpoint to use (eth and debug namespace required with execution witness support) (cannon/asterisc game type only)", EnvVars: prefixEnvVars("L2_EXPERIMENTAL_ETH_RPC"), } MaxPendingTransactionsFlag = &cli.Uint64Flag{ @@ -128,40 +134,40 @@ var ( Usage: "List of addresses to claim bonds for, in addition to the configured transaction sender", EnvVars: prefixEnvVars("ADDITIONAL_BOND_CLAIMANTS"), } - PreStatesURLFlag = NewVMFlag("prestates-url", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag { + PreStatesURLFlag = NewVMFlag("prestates-url", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, gameTypeInfo string) cli.Flag { return &cli.StringFlag{ Name: name, Usage: "Base URL to absolute prestates to use when generating trace data. " + "Prestates in this directory should be name as .bin.gz .json.gz or .json " + - traceTypeInfo, + gameTypeInfo, EnvVars: envVars, } }) - RollupConfigFlag = NewVMFlag("rollup-config", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag { + RollupConfigFlag = NewVMFlag("rollup-config", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, gameTypeInfo string) cli.Flag { return &cli.StringSliceFlag{ Name: name, - Usage: "Rollup chain parameters " + traceTypeInfo, + Usage: "Rollup chain parameters " + gameTypeInfo, EnvVars: envVars, } }) - L2GenesisFlag = NewVMFlag("l2-genesis", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag { + L2GenesisFlag = NewVMFlag("l2-genesis", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, gameTypeInfo string) cli.Flag { return &cli.StringSliceFlag{ Name: name, - Usage: "Paths to the op-geth genesis file " + traceTypeInfo, + Usage: "Paths to the op-geth genesis file " + gameTypeInfo, EnvVars: envVars, } }) - L1GenesisFlag = NewVMFlag("l1-genesis", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag { + L1GenesisFlag = NewVMFlag("l1-genesis", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, gameTypeInfo string) cli.Flag { return &cli.StringFlag{ Name: name, Usage: "Path to the L1 genesis file. Only required if the L1 is not mainnet, sepolia, holesky, or hoodi.", EnvVars: envVars, } }) - DepsetConfigFlag = NewVMFlag("depset-config", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag { + DepsetConfigFlag = NewVMFlag("depset-config", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, gameTypeInfo string) cli.Flag { return &cli.StringFlag{ Name: name, - Usage: "Interop dependency set config file " + traceTypeInfo, + Usage: "Interop dependency set config file " + gameTypeInfo, EnvVars: envVars, } }) @@ -175,39 +181,39 @@ var ( } CannonBinFlag = &cli.StringFlag{ Name: "cannon-bin", - Usage: "Path to cannon executable to use when generating trace data (cannon trace type only)", + Usage: "Path to cannon executable to use when generating trace data (cannon game type only)", EnvVars: prefixEnvVars("CANNON_BIN"), } CannonServerFlag = &cli.StringFlag{ Name: "cannon-server", - Usage: "Path to executable to use as pre-image oracle server when generating trace data (cannon trace type only)", + Usage: "Path to executable to use as pre-image oracle server when generating trace data (cannon game type only)", EnvVars: prefixEnvVars("CANNON_SERVER"), } CannonPreStateFlag = &cli.StringFlag{ Name: "cannon-prestate", - Usage: "Path to absolute prestate to use when generating trace data (cannon trace type only)", + Usage: "Path to absolute prestate to use when generating trace data (cannon game type only)", EnvVars: prefixEnvVars("CANNON_PRESTATE"), } CannonSnapshotFreqFlag = &cli.UintFlag{ Name: "cannon-snapshot-freq", - Usage: "Frequency of cannon snapshots to generate in VM steps (cannon trace type only)", + Usage: "Frequency of cannon snapshots to generate in VM steps (cannon game type only)", EnvVars: prefixEnvVars("CANNON_SNAPSHOT_FREQ"), Value: config.DefaultCannonSnapshotFreq, } CannonInfoFreqFlag = &cli.UintFlag{ Name: "cannon-info-freq", - Usage: "Frequency of cannon info log messages to generate in VM steps (cannon trace type only)", + Usage: "Frequency of cannon info log messages to generate in VM steps (cannon game type only)", EnvVars: prefixEnvVars("CANNON_INFO_FREQ"), Value: config.DefaultCannonInfoFreq, } CannonKonaServerFlag = &cli.StringFlag{ Name: "cannon-kona-server", - Usage: "Path to kona executable to use as pre-image oracle server when generating trace data (cannon-kona trace type only)", + Usage: "Path to kona executable to use as pre-image oracle server when generating trace data (cannon-kona game type only)", EnvVars: prefixEnvVars("CANNON_KONA_SERVER"), } CannonKonaPreStateFlag = &cli.StringFlag{ Name: "cannon-kona-prestate", - Usage: "Path to absolute prestate to use when generating trace data (cannon-kona trace type only)", + Usage: "Path to absolute prestate to use when generating trace data (cannon-kona game type only)", EnvVars: prefixEnvVars("CANNON_KONA_PRESTATE"), } CannonKonaL2CustomFlag = &cli.BoolFlag{ @@ -220,17 +226,17 @@ var ( } AsteriscBinFlag = &cli.StringFlag{ Name: "asterisc-bin", - Usage: "Path to asterisc executable to use when generating trace data (asterisc trace type only)", + Usage: "Path to asterisc executable to use when generating trace data (asterisc game type only)", EnvVars: prefixEnvVars("ASTERISC_BIN"), } AsteriscServerFlag = &cli.StringFlag{ Name: "asterisc-server", - Usage: "Path to executable to use as pre-image oracle server when generating trace data (asterisc trace type only)", + Usage: "Path to executable to use as pre-image oracle server when generating trace data (asterisc game type only)", EnvVars: prefixEnvVars("ASTERISC_SERVER"), } AsteriscKonaServerFlag = &cli.StringFlag{ Name: "asterisc-kona-server", - Usage: "Path to kona executable to use as pre-image oracle server when generating trace data (asterisc-kona trace type only)", + Usage: "Path to kona executable to use as pre-image oracle server when generating trace data (asterisc-kona game type only)", EnvVars: prefixEnvVars("ASTERISC_KONA_SERVER"), } AsteriscKonaL2CustomFlag = &cli.BoolFlag{ @@ -243,23 +249,23 @@ var ( } AsteriscPreStateFlag = &cli.StringFlag{ Name: "asterisc-prestate", - Usage: "Path to absolute prestate to use when generating trace data (asterisc trace type only)", + Usage: "Path to absolute prestate to use when generating trace data (asterisc game type only)", EnvVars: prefixEnvVars("ASTERISC_PRESTATE"), } AsteriscKonaPreStateFlag = &cli.StringFlag{ Name: "asterisc-kona-prestate", - Usage: "Path to absolute prestate to use when generating trace data (asterisc-kona trace type only)", + Usage: "Path to absolute prestate to use when generating trace data (asterisc-kona game type only)", EnvVars: prefixEnvVars("ASTERISC_KONA_PRESTATE"), } AsteriscSnapshotFreqFlag = &cli.UintFlag{ Name: "asterisc-snapshot-freq", - Usage: "Frequency of asterisc snapshots to generate in VM steps (asterisc trace type only)", + Usage: "Frequency of asterisc snapshots to generate in VM steps (asterisc game type only)", EnvVars: prefixEnvVars("ASTERISC_SNAPSHOT_FREQ"), Value: config.DefaultAsteriscSnapshotFreq, } AsteriscInfoFreqFlag = &cli.UintFlag{ Name: "asterisc-info-freq", - Usage: "Frequency of asterisc info log messages to generate in VM steps (asterisc trace type only)", + Usage: "Frequency of asterisc info log messages to generate in VM steps (asterisc game type only)", EnvVars: prefixEnvVars("ASTERISC_INFO_FREQ"), Value: config.DefaultAsteriscInfoFreq, } @@ -307,7 +313,7 @@ var optionalFlags = []cli.Flag{ RollupRpcFlag, NetworkFlag, FactoryAddressFlag, - TraceTypeFlag, + GameTypesFlag, MaxConcurrencyFlag, SupervisorRpcFlag, L2EthRpcFlag, @@ -367,13 +373,13 @@ func checkOutputProviderFlags(ctx *cli.Context) error { func CheckCannonBaseFlags(ctx *cli.Context) error { if ctx.IsSet(flags.NetworkFlagName) && - (RollupConfigFlag.IsSet(ctx, types.TraceTypeCannon) || L2GenesisFlag.IsSet(ctx, types.TraceTypeCannon) || L1GenesisFlag.IsSet(ctx, types.TraceTypeCannon) || ctx.Bool(CannonL2CustomFlag.Name)) { + (RollupConfigFlag.IsSet(ctx, gameTypes.CannonGameType) || L2GenesisFlag.IsSet(ctx, gameTypes.CannonGameType) || L1GenesisFlag.IsSet(ctx, gameTypes.CannonGameType) || ctx.Bool(CannonL2CustomFlag.Name)) { return fmt.Errorf("flag %v can not be used with %v, %v, %v or %v", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(types.TraceTypeCannon), L2GenesisFlag.EitherFlagName(types.TraceTypeCannon), L1GenesisFlag.EitherFlagName(types.TraceTypeCannon), CannonL2CustomFlag.Name) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameTypes.CannonGameType), L2GenesisFlag.EitherFlagName(gameTypes.CannonGameType), L1GenesisFlag.EitherFlagName(gameTypes.CannonGameType), CannonL2CustomFlag.Name) } - if ctx.Bool(CannonL2CustomFlag.Name) && !(RollupConfigFlag.IsSet(ctx, types.TraceTypeCannon) && L2GenesisFlag.IsSet(ctx, types.TraceTypeCannon)) { + if ctx.Bool(CannonL2CustomFlag.Name) && !(RollupConfigFlag.IsSet(ctx, gameTypes.CannonGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonGameType)) { return fmt.Errorf("flag %v and %v must be set when %v is true", - RollupConfigFlag.EitherFlagName(types.TraceTypeCannon), L2GenesisFlag.EitherFlagName(types.TraceTypeCannon), CannonL2CustomFlag.Name) + RollupConfigFlag.EitherFlagName(gameTypes.CannonGameType), L2GenesisFlag.EitherFlagName(gameTypes.CannonGameType), CannonL2CustomFlag.Name) } if !ctx.IsSet(CannonBinFlag.Name) { return fmt.Errorf("flag %s is required", CannonBinFlag.Name) @@ -381,8 +387,8 @@ func CheckCannonBaseFlags(ctx *cli.Context) error { if !ctx.IsSet(CannonServerFlag.Name) { return fmt.Errorf("flag %s is required", CannonServerFlag.Name) } - if !PreStatesURLFlag.IsSet(ctx, types.TraceTypeCannon) && !ctx.IsSet(CannonPreStateFlag.Name) { - return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(types.TraceTypeCannon), CannonPreStateFlag.Name) + if !PreStatesURLFlag.IsSet(ctx, gameTypes.CannonGameType) && !ctx.IsSet(CannonPreStateFlag.Name) { + return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(gameTypes.CannonGameType), CannonPreStateFlag.Name) } return nil } @@ -392,12 +398,12 @@ func CheckSuperCannonFlags(ctx *cli.Context) error { return fmt.Errorf("flag %v is required", SupervisorRpcFlag.Name) } if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, types.TraceTypeCannon) && L2GenesisFlag.IsSet(ctx, types.TraceTypeCannon) && DepsetConfigFlag.IsSet(ctx, types.TraceTypeCannon)) { + !(RollupConfigFlag.IsSet(ctx, gameTypes.CannonGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonGameType) && DepsetConfigFlag.IsSet(ctx, gameTypes.CannonGameType)) { return fmt.Errorf("flag %v or %v, %v and %v is required", flags.NetworkFlagName, - RollupConfigFlag.EitherFlagName(types.TraceTypeCannon), - L2GenesisFlag.EitherFlagName(types.TraceTypeCannon), - DepsetConfigFlag.EitherFlagName(types.TraceTypeCannon)) + RollupConfigFlag.EitherFlagName(gameTypes.CannonGameType), + L2GenesisFlag.EitherFlagName(gameTypes.CannonGameType), + DepsetConfigFlag.EitherFlagName(gameTypes.CannonGameType)) } if err := CheckCannonBaseFlags(ctx); err != nil { return err @@ -410,14 +416,14 @@ func CheckSuperCannonKonaFlags(ctx *cli.Context) error { return fmt.Errorf("flag %v is required", SupervisorRpcFlag.Name) } if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, types.TraceTypeCannonKona) && L2GenesisFlag.IsSet(ctx, types.TraceTypeCannonKona) && DepsetConfigFlag.IsSet(ctx, types.TraceTypeCannonKona)) { + !(RollupConfigFlag.IsSet(ctx, gameTypes.CannonKonaGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonKonaGameType) && DepsetConfigFlag.IsSet(ctx, gameTypes.CannonKonaGameType)) { return fmt.Errorf("flag %v or %v, %v and %v is required", flags.NetworkFlagName, - RollupConfigFlag.EitherFlagName(types.TraceTypeCannonKona), - L2GenesisFlag.EitherFlagName(types.TraceTypeCannonKona), - DepsetConfigFlag.EitherFlagName(types.TraceTypeCannonKona)) + RollupConfigFlag.EitherFlagName(gameTypes.CannonKonaGameType), + L2GenesisFlag.EitherFlagName(gameTypes.CannonKonaGameType), + DepsetConfigFlag.EitherFlagName(gameTypes.CannonKonaGameType)) } - if err := CheckCannonKonaBaseFlags(ctx, types.TraceTypeCannonKona); err != nil { + if err := CheckCannonKonaBaseFlags(ctx, gameTypes.CannonKonaGameType); err != nil { return err } return nil @@ -428,9 +434,9 @@ func CheckCannonFlags(ctx *cli.Context) error { return err } if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, types.TraceTypeCannon) && L2GenesisFlag.IsSet(ctx, types.TraceTypeCannon)) { + !(RollupConfigFlag.IsSet(ctx, gameTypes.CannonGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonGameType)) { return fmt.Errorf("flag %v or %v and %v is required", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(types.TraceTypeCannon), L2GenesisFlag.EitherFlagName(types.TraceTypeCannon)) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameTypes.CannonGameType), L2GenesisFlag.EitherFlagName(gameTypes.CannonGameType)) } if err := CheckCannonBaseFlags(ctx); err != nil { return err @@ -438,16 +444,16 @@ func CheckCannonFlags(ctx *cli.Context) error { return nil } -func CheckCannonKonaBaseFlags(ctx *cli.Context, traceType types.TraceType) error { +func CheckCannonKonaBaseFlags(ctx *cli.Context, gameType gameTypes.GameType) error { if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, traceType) && L2GenesisFlag.IsSet(ctx, traceType)) { + !(RollupConfigFlag.IsSet(ctx, gameType) && L2GenesisFlag.IsSet(ctx, gameType)) { return fmt.Errorf("flag %v or %v and %v is required", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(traceType), L2GenesisFlag.EitherFlagName(traceType)) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameType), L2GenesisFlag.EitherFlagName(gameType)) } if ctx.IsSet(flags.NetworkFlagName) && - (RollupConfigFlag.IsSet(ctx, types.TraceTypeCannonKona) || L2GenesisFlag.IsSet(ctx, types.TraceTypeCannonKona) || L1GenesisFlag.IsSet(ctx, types.TraceTypeCannonKona) || ctx.Bool(CannonKonaL2CustomFlag.Name)) { + (RollupConfigFlag.IsSet(ctx, gameTypes.CannonKonaGameType) || L2GenesisFlag.IsSet(ctx, gameTypes.CannonKonaGameType) || L1GenesisFlag.IsSet(ctx, gameTypes.CannonKonaGameType) || ctx.Bool(CannonKonaL2CustomFlag.Name)) { return fmt.Errorf("flag %v can not be used with %v, %v, %v or %v", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(types.TraceTypeCannonKona), L2GenesisFlag.EitherFlagName(types.TraceTypeCannonKona), L1GenesisFlag.EitherFlagName(types.TraceTypeCannonKona), CannonKonaL2CustomFlag.Name) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameTypes.CannonKonaGameType), L2GenesisFlag.EitherFlagName(gameTypes.CannonKonaGameType), L1GenesisFlag.EitherFlagName(gameTypes.CannonKonaGameType), CannonKonaL2CustomFlag.Name) } if !ctx.IsSet(CannonBinFlag.Name) { return fmt.Errorf("flag %s is required", CannonBinFlag.Name) @@ -459,28 +465,28 @@ func CheckCannonKonaFlags(ctx *cli.Context) error { if err := checkOutputProviderFlags(ctx); err != nil { return err } - if err := CheckCannonKonaBaseFlags(ctx, types.TraceTypeCannonKona); err != nil { + if err := CheckCannonKonaBaseFlags(ctx, gameTypes.CannonKonaGameType); err != nil { return err } if !ctx.IsSet(CannonKonaServerFlag.Name) { return fmt.Errorf("flag %s is required", CannonKonaServerFlag.Name) } - if !PreStatesURLFlag.IsSet(ctx, types.TraceTypeCannonKona) && !ctx.IsSet(CannonKonaPreStateFlag.Name) { - return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(types.TraceTypeCannonKona), CannonKonaPreStateFlag.Name) + if !PreStatesURLFlag.IsSet(ctx, gameTypes.CannonKonaGameType) && !ctx.IsSet(CannonKonaPreStateFlag.Name) { + return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(gameTypes.CannonKonaGameType), CannonKonaPreStateFlag.Name) } return nil } -func CheckAsteriscBaseFlags(ctx *cli.Context, traceType types.TraceType) error { +func CheckAsteriscBaseFlags(ctx *cli.Context, gameType gameTypes.GameType) error { if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, traceType) && L2GenesisFlag.IsSet(ctx, traceType)) { + !(RollupConfigFlag.IsSet(ctx, gameType) && L2GenesisFlag.IsSet(ctx, gameType)) { return fmt.Errorf("flag %v or %v and %v is required", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(traceType), L2GenesisFlag.EitherFlagName(traceType)) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameType), L2GenesisFlag.EitherFlagName(gameType)) } if ctx.IsSet(flags.NetworkFlagName) && - (RollupConfigFlag.IsSet(ctx, types.TraceTypeAsteriscKona) || L2GenesisFlag.IsSet(ctx, types.TraceTypeAsteriscKona) || L1GenesisFlag.IsSet(ctx, types.TraceTypeAsteriscKona) || ctx.Bool(AsteriscKonaL2CustomFlag.Name)) { + (RollupConfigFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) || L2GenesisFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) || L1GenesisFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) || ctx.Bool(AsteriscKonaL2CustomFlag.Name)) { return fmt.Errorf("flag %v can not be used with %v, %v, %v or %v", - flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(types.TraceTypeAsteriscKona), L2GenesisFlag.EitherFlagName(types.TraceTypeAsteriscKona), L1GenesisFlag.EitherFlagName(types.TraceTypeAsteriscKona), AsteriscKonaL2CustomFlag.Name) + flags.NetworkFlagName, RollupConfigFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), L2GenesisFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), L1GenesisFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), AsteriscKonaL2CustomFlag.Name) } if !ctx.IsSet(AsteriscBinFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscBinFlag.Name) @@ -492,14 +498,14 @@ func CheckAsteriscFlags(ctx *cli.Context) error { if err := checkOutputProviderFlags(ctx); err != nil { return err } - if err := CheckAsteriscBaseFlags(ctx, types.TraceTypeAsterisc); err != nil { + if err := CheckAsteriscBaseFlags(ctx, gameTypes.AsteriscGameType); err != nil { return err } if !ctx.IsSet(AsteriscServerFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscServerFlag.Name) } - if !PreStatesURLFlag.IsSet(ctx, types.TraceTypeAsterisc) && !ctx.IsSet(AsteriscPreStateFlag.Name) { - return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(types.TraceTypeAsterisc), AsteriscPreStateFlag.Name) + if !PreStatesURLFlag.IsSet(ctx, gameTypes.AsteriscGameType) && !ctx.IsSet(AsteriscPreStateFlag.Name) { + return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(gameTypes.AsteriscGameType), AsteriscPreStateFlag.Name) } return nil } @@ -508,14 +514,14 @@ func CheckAsteriscKonaFlags(ctx *cli.Context) error { if err := checkOutputProviderFlags(ctx); err != nil { return err } - if err := CheckAsteriscBaseFlags(ctx, types.TraceTypeAsteriscKona); err != nil { + if err := CheckAsteriscBaseFlags(ctx, gameTypes.AsteriscKonaGameType); err != nil { return err } if !ctx.IsSet(AsteriscKonaServerFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscKonaServerFlag.Name) } - if !PreStatesURLFlag.IsSet(ctx, types.TraceTypeAsteriscKona) && !ctx.IsSet(AsteriscKonaPreStateFlag.Name) { - return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(types.TraceTypeAsteriscKona), AsteriscKonaPreStateFlag.Name) + if !PreStatesURLFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) && !ctx.IsSet(AsteriscKonaPreStateFlag.Name) { + return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), AsteriscKonaPreStateFlag.Name) } return nil } @@ -525,26 +531,26 @@ func CheckSuperAsteriscKonaFlags(ctx *cli.Context) error { return fmt.Errorf("flag %v is required", SupervisorRpcFlag.Name) } if !ctx.IsSet(flags.NetworkFlagName) && - !(RollupConfigFlag.IsSet(ctx, types.TraceTypeAsteriscKona) && L2GenesisFlag.IsSet(ctx, types.TraceTypeAsteriscKona) && DepsetConfigFlag.IsSet(ctx, types.TraceTypeAsteriscKona)) { + !(RollupConfigFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) && DepsetConfigFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType)) { return fmt.Errorf("flag %v or %v, %v and %v is required", flags.NetworkFlagName, - RollupConfigFlag.EitherFlagName(types.TraceTypeAsteriscKona), - L2GenesisFlag.EitherFlagName(types.TraceTypeAsteriscKona), - DepsetConfigFlag.EitherFlagName(types.TraceTypeAsteriscKona)) + RollupConfigFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), + L2GenesisFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), + DepsetConfigFlag.EitherFlagName(gameTypes.AsteriscKonaGameType)) } - if err := CheckAsteriscBaseFlags(ctx, types.TraceTypeAsteriscKona); err != nil { + if err := CheckAsteriscBaseFlags(ctx, gameTypes.AsteriscKonaGameType); err != nil { return err } if !ctx.IsSet(AsteriscKonaServerFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscKonaServerFlag.Name) } - if !PreStatesURLFlag.IsSet(ctx, types.TraceTypeAsteriscKona) && !ctx.IsSet(AsteriscKonaPreStateFlag.Name) { - return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(types.TraceTypeAsteriscKona), AsteriscKonaPreStateFlag.Name) + if !PreStatesURLFlag.IsSet(ctx, gameTypes.AsteriscKonaGameType) && !ctx.IsSet(AsteriscKonaPreStateFlag.Name) { + return fmt.Errorf("flag %s or %s is required", PreStatesURLFlag.EitherFlagName(gameTypes.AsteriscKonaGameType), AsteriscKonaPreStateFlag.Name) } return nil } -func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error { +func CheckRequired(ctx *cli.Context, types []gameTypes.GameType) error { for _, f := range requiredFlags { if !ctx.IsSet(f.Names()[0]) { return fmt.Errorf("flag %s is required", f.Names()[0]) @@ -553,59 +559,59 @@ func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error { if !ctx.IsSet(L2EthRpcFlag.Name) { return fmt.Errorf("flag %s is required", L2EthRpcFlag.Name) } - for _, traceType := range traceTypes { - switch traceType { - case types.TraceTypeCannon, types.TraceTypePermissioned: + for _, gameType := range types { + switch gameType { + case gameTypes.CannonGameType, gameTypes.PermissionedGameType: if err := CheckCannonFlags(ctx); err != nil { return err } - case types.TraceTypeCannonKona: + case gameTypes.CannonKonaGameType: if err := CheckCannonKonaFlags(ctx); err != nil { return err } - case types.TraceTypeAsterisc: + case gameTypes.AsteriscGameType: if err := CheckAsteriscFlags(ctx); err != nil { return err } - case types.TraceTypeAsteriscKona: + case gameTypes.AsteriscKonaGameType: if err := CheckAsteriscKonaFlags(ctx); err != nil { return err } - case types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned: + case gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType: if err := CheckSuperCannonFlags(ctx); err != nil { return err } - case types.TraceTypeSuperCannonKona: + case gameTypes.SuperCannonKonaGameType: if err := CheckSuperCannonKonaFlags(ctx); err != nil { return err } - case types.TraceTypeSuperAsteriscKona: + case gameTypes.SuperAsteriscKonaGameType: if err := CheckSuperAsteriscKonaFlags(ctx); err != nil { return err } - case types.TraceTypeAlphabet, types.TraceTypeFast: + case gameTypes.AlphabetGameType, gameTypes.FastGameType: if err := checkOutputProviderFlags(ctx); err != nil { return err } default: - return fmt.Errorf("invalid trace type %v. must be one of %v", traceType, types.TraceTypes) + return fmt.Errorf("invalid game type %v. must be one of %v", gameType, gameTypes.SupportedGameTypes) } } return nil } -func parseTraceTypes(ctx *cli.Context) ([]types.TraceType, error) { - var traceTypes []types.TraceType - for _, typeName := range ctx.StringSlice(TraceTypeFlag.Name) { - traceType := new(types.TraceType) - if err := traceType.Set(typeName); err != nil { +func parseGameTypes(ctx *cli.Context) ([]gameTypes.GameType, error) { + var result []gameTypes.GameType + for _, typeName := range ctx.StringSlice(GameTypesFlag.Name) { + gameType, err := gameTypes.SupportedGameTypeFromString(typeName) + if err != nil { return nil, err } - if !slices.Contains(traceTypes, *traceType) { - traceTypes = append(traceTypes, *traceType) + if !slices.Contains(result, gameType) { + result = append(result, gameType) } } - return traceTypes, nil + return result, nil } type ChainAddressesSource func(network string) (superchain.AddressesConfig, error) @@ -656,11 +662,11 @@ func FactoryAddressForNetworks(networks []string, addressSource ChainAddressesSo // NewConfigFromCLI parses the Config from the provided flags or environment variables. func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, error) { - traceTypes, err := parseTraceTypes(ctx) + enabledGameTypes, err := parseGameTypes(ctx) if err != nil { return nil, err } - if err := CheckRequired(ctx, traceTypes); err != nil { + if err := CheckRequired(ctx, enabledGameTypes); err != nil { return nil, err } gameFactoryAddress, err := FactoryAddress(ctx) @@ -697,30 +703,30 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro } } - getPrestatesUrl := func(traceType types.TraceType) (*url.URL, error) { + getPrestatesUrl := func(gameType gameTypes.GameType) (*url.URL, error) { var preStatesURL *url.URL - if PreStatesURLFlag.IsSet(ctx, traceType) { - val := PreStatesURLFlag.String(ctx, traceType) + if PreStatesURLFlag.IsSet(ctx, gameType) { + val := PreStatesURLFlag.String(ctx, gameType) preStatesURL, err = url.Parse(val) if err != nil { - return nil, fmt.Errorf("invalid %v (%v): %w", PreStatesURLFlag.SourceFlagName(ctx, traceType), val, err) + return nil, fmt.Errorf("invalid %v (%v): %w", PreStatesURLFlag.SourceFlagName(ctx, gameType), val, err) } } return preStatesURL, nil } - cannonPreStatesURL, err := getPrestatesUrl(types.TraceTypeCannon) + cannonPreStatesURL, err := getPrestatesUrl(gameTypes.CannonGameType) if err != nil { return nil, err } - cannonKonaPreStatesURL, err := getPrestatesUrl(types.TraceTypeCannonKona) + cannonKonaPreStatesURL, err := getPrestatesUrl(gameTypes.CannonKonaGameType) if err != nil { return nil, err } - asteriscPreStatesURL, err := getPrestatesUrl(types.TraceTypeAsterisc) + asteriscPreStatesURL, err := getPrestatesUrl(gameTypes.AsteriscGameType) if err != nil { return nil, err } - asteriscKonaPreStatesURL, err := getPrestatesUrl(types.TraceTypeAsteriscKona) + asteriscKonaPreStatesURL, err := getPrestatesUrl(gameTypes.AsteriscKonaGameType) if err != nil { return nil, err } @@ -733,7 +739,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro // Required Flags L1EthRpc: l1EthRpc, L1Beacon: l1Beacon, - TraceTypes: traceTypes, + GameTypes: enabledGameTypes, GameFactoryAddress: gameFactoryAddress, GameAllowlist: allowedGames, GameWindow: ctx.Duration(GameWindowFlag.Name), @@ -746,7 +752,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro RollupRpc: ctx.String(RollupRpcFlag.Name), SupervisorRPC: ctx.String(SupervisorRpcFlag.Name), Cannon: vm.Config{ - VmType: types.TraceTypeCannon, + VmType: gameTypes.CannonGameType, L1: l1EthRpc, L1Beacon: l1Beacon, L2s: l2Rpcs, @@ -755,10 +761,10 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro Server: ctx.String(CannonServerFlag.Name), Networks: networks, L2Custom: ctx.Bool(CannonL2CustomFlag.Name), - RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeCannon), - L1GenesisPath: L1GenesisFlag.String(ctx, types.TraceTypeCannon), - L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeCannon), - DepsetConfigPath: DepsetConfigFlag.String(ctx, types.TraceTypeCannon), + RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, gameTypes.CannonGameType), + L1GenesisPath: L1GenesisFlag.String(ctx, gameTypes.CannonGameType), + L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, gameTypes.CannonGameType), + DepsetConfigPath: DepsetConfigFlag.String(ctx, gameTypes.CannonGameType), SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), DebugInfo: true, @@ -767,7 +773,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), CannonAbsolutePreStateBaseURL: cannonPreStatesURL, CannonKona: vm.Config{ - VmType: types.TraceTypeCannonKona, + VmType: gameTypes.CannonKonaGameType, L1: l1EthRpc, L1Beacon: l1Beacon, L2s: l2Rpcs, @@ -776,10 +782,10 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro Server: ctx.String(CannonKonaServerFlag.Name), Networks: networks, L2Custom: ctx.Bool(CannonKonaL2CustomFlag.Name), - RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeCannonKona), - L1GenesisPath: L1GenesisFlag.String(ctx, types.TraceTypeCannonKona), - L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeCannonKona), - DepsetConfigPath: DepsetConfigFlag.String(ctx, types.TraceTypeCannonKona), + RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, gameTypes.CannonKonaGameType), + L1GenesisPath: L1GenesisFlag.String(ctx, gameTypes.CannonKonaGameType), + L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, gameTypes.CannonKonaGameType), + DepsetConfigPath: DepsetConfigFlag.String(ctx, gameTypes.CannonKonaGameType), SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), DebugInfo: true, @@ -789,7 +795,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro CannonKonaAbsolutePreStateBaseURL: cannonKonaPreStatesURL, Datadir: ctx.String(DatadirFlag.Name), Asterisc: vm.Config{ - VmType: types.TraceTypeAsterisc, + VmType: gameTypes.AsteriscGameType, L1: l1EthRpc, L1Beacon: l1Beacon, L2s: l2Rpcs, @@ -797,10 +803,10 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro VmBin: ctx.String(AsteriscBinFlag.Name), Server: ctx.String(AsteriscServerFlag.Name), Networks: networks, - RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeAsterisc), - L1GenesisPath: L1GenesisFlag.String(ctx, types.TraceTypeAsterisc), - L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeAsterisc), - DepsetConfigPath: DepsetConfigFlag.String(ctx, types.TraceTypeAsterisc), + RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, gameTypes.AsteriscGameType), + L1GenesisPath: L1GenesisFlag.String(ctx, gameTypes.AsteriscGameType), + L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, gameTypes.AsteriscGameType), + DepsetConfigPath: DepsetConfigFlag.String(ctx, gameTypes.AsteriscGameType), SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name), InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name), BinarySnapshots: true, @@ -808,7 +814,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name), AsteriscAbsolutePreStateBaseURL: asteriscPreStatesURL, AsteriscKona: vm.Config{ - VmType: types.TraceTypeAsteriscKona, + VmType: gameTypes.AsteriscKonaGameType, L1: l1EthRpc, L1Beacon: l1Beacon, L2s: l2Rpcs, @@ -817,10 +823,10 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro Server: ctx.String(AsteriscKonaServerFlag.Name), Networks: networks, L2Custom: ctx.Bool(AsteriscKonaL2CustomFlag.Name), - RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeAsteriscKona), - L1GenesisPath: L1GenesisFlag.String(ctx, types.TraceTypeAsteriscKona), - L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeAsteriscKona), - DepsetConfigPath: DepsetConfigFlag.String(ctx, types.TraceTypeAsteriscKona), + RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, gameTypes.AsteriscKonaGameType), + L1GenesisPath: L1GenesisFlag.String(ctx, gameTypes.AsteriscKonaGameType), + L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, gameTypes.AsteriscKonaGameType), + DepsetConfigPath: DepsetConfigFlag.String(ctx, gameTypes.AsteriscKonaGameType), SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name), InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name), BinarySnapshots: true, diff --git a/op-challenger/flags/flags_test.go b/op-challenger/flags/flags_test.go index ca6ae847b7c..f2a7f636ac8 100644 --- a/op-challenger/flags/flags_test.go +++ b/op-challenger/flags/flags_test.go @@ -77,6 +77,7 @@ func TestEnvVarFormat(t *testing.T) { txmgr.FeeLimitMultiplierFlagName, txmgr.TxSendTimeoutFlagName, txmgr.TxNotInMempoolTimeoutFlagName, + GameTypesFlag.Name, // Has multiple env vars for backwards compatibility } t.Run(flagName, func(t *testing.T) { @@ -95,6 +96,11 @@ func TestEnvVarFormat(t *testing.T) { } } +func TestGameTypesFlagEnvVars(t *testing.T) { + envFlags := GameTypesFlag.GetEnvVars() + require.Equal(t, []string{opservice.FlagNameToEnvVarName(GameTypesFlag.Name, "OP_CHALLENGER"), "OP_CHALLENGER_TRACE_TYPE"}, envFlags) +} + func TestResponseDelayFlag(t *testing.T) { t.Run("IncludedInOptionalFlags", func(t *testing.T) { require.Contains(t, optionalFlags, ResponseDelayFlag, "ResponseDelayFlag should be in optionalFlags") diff --git a/op-challenger/flags/vm_flag.go b/op-challenger/flags/vm_flag.go index c7612467bdb..3177641da78 100644 --- a/op-challenger/flags/vm_flag.go +++ b/op-challenger/flags/vm_flag.go @@ -3,23 +3,23 @@ package flags import ( "fmt" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/urfave/cli/v2" ) -type FlagCreator func(name string, envVars []string, traceTypeInfo string) cli.Flag +type FlagCreator func(name string, envVars []string, gameTypeInfo string) cli.Flag // VMFlag defines a set of flags to set a VM specific option. Provides a flag to set the default plus flags to // override the default on a per VM basis. type VMFlag struct { - vms []types.TraceType + vms []gameTypes.GameType name string envVarPrefix string flagCreator FlagCreator } -func NewVMFlag(name string, envVarPrefix string, vms []types.TraceType, flagCreator FlagCreator) *VMFlag { +func NewVMFlag(name string, envVarPrefix string, vms []gameTypes.GameType, flagCreator FlagCreator) *VMFlag { return &VMFlag{ name: name, envVarPrefix: envVarPrefix, @@ -36,7 +36,7 @@ func (f *VMFlag) Flags() []cli.Flag { for _, vm := range f.vms { name := f.TraceSpecificFlagName(vm) envVar := opservice.FlagNameToEnvVarName(name, f.envVarPrefix) - flags = append(flags, f.flagCreator(name, []string{envVar}, fmt.Sprintf("(%v trace type only)", vm))) + flags = append(flags, f.flagCreator(name, []string{envVar}, fmt.Sprintf("(%v game type only)", vm))) } return flags } @@ -45,11 +45,11 @@ func (f *VMFlag) DefaultName() string { return f.name } -func (f *VMFlag) IsSet(ctx *cli.Context, vm types.TraceType) bool { +func (f *VMFlag) IsSet(ctx *cli.Context, vm gameTypes.GameType) bool { return ctx.IsSet(f.TraceSpecificFlagName(vm)) || ctx.IsSet(f.name) } -func (f *VMFlag) String(ctx *cli.Context, vm types.TraceType) string { +func (f *VMFlag) String(ctx *cli.Context, vm gameTypes.GameType) string { val := ctx.String(f.TraceSpecificFlagName(vm)) if val == "" { val = ctx.String(f.name) @@ -57,7 +57,7 @@ func (f *VMFlag) String(ctx *cli.Context, vm types.TraceType) string { return val } -func (f *VMFlag) StringSlice(ctx *cli.Context, vm types.TraceType) []string { +func (f *VMFlag) StringSlice(ctx *cli.Context, vm gameTypes.GameType) []string { val := ctx.StringSlice(f.TraceSpecificFlagName(vm)) if len(val) == 0 { val = ctx.StringSlice(f.name) @@ -65,7 +65,7 @@ func (f *VMFlag) StringSlice(ctx *cli.Context, vm types.TraceType) []string { return val } -func (f *VMFlag) SourceFlagName(ctx *cli.Context, vm types.TraceType) string { +func (f *VMFlag) SourceFlagName(ctx *cli.Context, vm gameTypes.GameType) string { vmFlag := f.TraceSpecificFlagName(vm) if ctx.IsSet(vmFlag) { return vmFlag @@ -73,10 +73,10 @@ func (f *VMFlag) SourceFlagName(ctx *cli.Context, vm types.TraceType) string { return f.name } -func (f *VMFlag) EitherFlagName(vm types.TraceType) string { +func (f *VMFlag) EitherFlagName(vm gameTypes.GameType) string { return fmt.Sprintf("%s/%s", f.DefaultName(), f.TraceSpecificFlagName(vm)) } -func (f *VMFlag) TraceSpecificFlagName(vm types.TraceType) string { +func (f *VMFlag) TraceSpecificFlagName(vm gameTypes.GameType) string { return fmt.Sprintf("%v-%v", vm, f.name) } diff --git a/op-challenger/game/client/provider.go b/op-challenger/game/client/provider.go new file mode 100644 index 00000000000..d827cae977f --- /dev/null +++ b/op-challenger/game/client/provider.go @@ -0,0 +1,107 @@ +package client + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-service/dial" + "github.com/ethereum-optimism/optimism/op-service/sources" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" +) + +var ErrNotInSync = errors.New("local node too far behind") + +type Provider struct { + ctx context.Context + logger log.Logger + cfg *config.Config + l1Client *ethclient.Client + caller *batching.MultiCaller + + l2EL *ethclient.Client + rollupClient *sources.RollupClient + syncValidator *RollupSyncStatusValidator + supervisorClient *sources.SupervisorClient + toClose []func() +} + +func NewProvider(ctx context.Context, logger log.Logger, cfg *config.Config, l1Client *ethclient.Client) *Provider { + return &Provider{ + ctx: ctx, + logger: logger, + cfg: cfg, + l1Client: l1Client, + caller: batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize), + } +} + +func (c *Provider) Close() { + for _, closeFunc := range c.toClose { + closeFunc() + } +} + +func (c *Provider) L1Client() *ethclient.Client { + return c.l1Client +} + +func (c *Provider) MultiCaller() *batching.MultiCaller { + return c.caller +} + +func (c *Provider) SingleChainClients() (*ethclient.Client, *sources.RollupClient, *RollupSyncStatusValidator, error) { + headers, err := c.L2HeaderSource() + if err != nil { + return nil, nil, nil, err + } + rollup, syncValidator, err := c.RollupClients() + if err != nil { + return nil, nil, nil, err + } + return headers, rollup, syncValidator, nil +} + +func (c *Provider) L2HeaderSource() (*ethclient.Client, error) { + if c.l2EL != nil { + return c.l2EL, nil + } + if len(c.cfg.L2Rpcs) != 1 { + return nil, fmt.Errorf("incorrect number of L2 RPCs configured, expected 1 but got %d", len(c.cfg.L2Rpcs)) + } + + l2Client, err := ethclient.DialContext(c.ctx, c.cfg.L2Rpcs[0]) + if err != nil { + return nil, fmt.Errorf("dial l2 client %v: %w", c.cfg.L2Rpcs[0], err) + } + c.l2EL = l2Client + c.toClose = append(c.toClose, l2Client.Close) + return l2Client, nil +} + +func (c *Provider) RollupClients() (*sources.RollupClient, *RollupSyncStatusValidator, error) { + if c.rollupClient != nil { + return c.rollupClient, c.syncValidator, nil + } + rollupClient, err := dial.DialRollupClientWithTimeout(c.ctx, c.logger, c.cfg.RollupRpc) + if err != nil { + return nil, nil, fmt.Errorf("dial rollup client %v: %w", c.cfg.RollupRpc, err) + } + c.rollupClient = rollupClient + c.syncValidator = NewRollupSyncStatusValidator(rollupClient) + c.toClose = append(c.toClose, rollupClient.Close) + return rollupClient, c.syncValidator, nil +} + +func (c *Provider) SuperchainClients() (*sources.SupervisorClient, *SupervisorSyncValidator, error) { + supervisorClient, err := dial.DialSupervisorClientWithTimeout(c.ctx, c.logger, c.cfg.SupervisorRPC) + if err != nil { + return nil, nil, fmt.Errorf("failed to dial supervisor: %w", err) + } + c.supervisorClient = supervisorClient + c.toClose = append(c.toClose, supervisorClient.Close) + return supervisorClient, NewSupervisorSyncValidator(supervisorClient), nil +} diff --git a/op-challenger/game/client/rollup_sync.go b/op-challenger/game/client/rollup_sync.go new file mode 100644 index 00000000000..2b0d47c2214 --- /dev/null +++ b/op-challenger/game/client/rollup_sync.go @@ -0,0 +1,33 @@ +package client + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type syncStatusProvider interface { + SyncStatus(context.Context) (*eth.SyncStatus, error) +} + +type RollupSyncStatusValidator struct { + statusProvider syncStatusProvider +} + +func NewRollupSyncStatusValidator(statusProvider syncStatusProvider) *RollupSyncStatusValidator { + return &RollupSyncStatusValidator{ + statusProvider: statusProvider, + } +} + +func (s *RollupSyncStatusValidator) ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error { + syncStatus, err := s.statusProvider.SyncStatus(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve local node sync status: %w", err) + } + if syncStatus.CurrentL1.Number <= gameL1Head.Number { + return fmt.Errorf("%w require L1 block above %v but at %v", ErrNotInSync, gameL1Head.Number, syncStatus.CurrentL1.Number) + } + return nil +} diff --git a/op-challenger/game/fault/sync_test.go b/op-challenger/game/client/rollup_sync_test.go similarity index 89% rename from op-challenger/game/fault/sync_test.go rename to op-challenger/game/client/rollup_sync_test.go index 59a98957c1d..8914a1956f4 100644 --- a/op-challenger/game/fault/sync_test.go +++ b/op-challenger/game/client/rollup_sync_test.go @@ -1,11 +1,10 @@ -package fault +package client import ( "context" "errors" "testing" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/stretchr/testify/require" ) @@ -35,7 +34,7 @@ func TestSyncStatusProvider(t *testing.T) { }, }, statusReqErr: nil, - expected: types.ErrNotInSync, + expected: ErrNotInSync, }, { name: "CurrentL1EqualToGameL1Head", @@ -46,7 +45,7 @@ func TestSyncStatusProvider(t *testing.T) { }, }, statusReqErr: nil, - expected: types.ErrNotInSync, + expected: ErrNotInSync, }, { name: "CurrentL1AboveGameL1Head", @@ -67,7 +66,7 @@ func TestSyncStatusProvider(t *testing.T) { status: test.syncStatus, err: test.statusReqErr, } - validator := newSyncStatusValidator(provider) + validator := NewRollupSyncStatusValidator(provider) err := validator.ValidateNodeSynced(context.Background(), test.gameL1Head) require.ErrorIs(t, err, test.expected) }) diff --git a/op-challenger/game/client/supervisor.go b/op-challenger/game/client/supervisor.go new file mode 100644 index 00000000000..f4a57ed2519 --- /dev/null +++ b/op-challenger/game/client/supervisor.go @@ -0,0 +1,33 @@ +package client + +import ( + "context" + "fmt" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +type SupervisorSyncStatusProvider interface { + SyncStatus(ctx context.Context) (eth.SupervisorSyncStatus, error) +} + +type SupervisorSyncValidator struct { + syncStatusProvider SupervisorSyncStatusProvider +} + +func NewSupervisorSyncValidator(syncStatusProvider SupervisorSyncStatusProvider) *SupervisorSyncValidator { + return &SupervisorSyncValidator{ + syncStatusProvider: syncStatusProvider, + } +} + +func (s SupervisorSyncValidator) ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error { + syncStatus, err := s.syncStatusProvider.SyncStatus(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve sync status: %w", err) + } + if syncStatus.MinSyncedL1.Number <= gameL1Head.Number { + return fmt.Errorf("%w require L1 block above %v but at %v", ErrNotInSync, gameL1Head.Number, syncStatus.MinSyncedL1.Number) + } + return nil +} diff --git a/op-challenger/game/fault/trace/super/sync_test.go b/op-challenger/game/client/supervisor_test.go similarity index 76% rename from op-challenger/game/fault/trace/super/sync_test.go rename to op-challenger/game/client/supervisor_test.go index 300b52c90ea..44bf124af27 100644 --- a/op-challenger/game/fault/trace/super/sync_test.go +++ b/op-challenger/game/client/supervisor_test.go @@ -1,16 +1,15 @@ -package super +package client import ( "context" "errors" "testing" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/stretchr/testify/require" ) -func TestSyncStatusProvider(t *testing.T) { +func TestSupervisorSyncStatusProvider(t *testing.T) { requestErr := errors.New("boom") tests := []struct { name string @@ -31,7 +30,7 @@ func TestSyncStatusProvider(t *testing.T) { syncStatus: eth.SupervisorSyncStatus{ MinSyncedL1: eth.L1BlockRef{Number: 99}, }, - expectedError: types.ErrNotInSync, + expectedError: ErrNotInSync, }, { name: "MinSyncedL1EqualToGameHead", @@ -39,7 +38,7 @@ func TestSyncStatusProvider(t *testing.T) { syncStatus: eth.SupervisorSyncStatus{ MinSyncedL1: eth.L1BlockRef{Number: 100}, }, - expectedError: types.ErrNotInSync, + expectedError: ErrNotInSync, }, { name: "InSync", @@ -54,22 +53,22 @@ func TestSyncStatusProvider(t *testing.T) { for _, test := range tests { test := test // capture range variable t.Run(test.name, func(t *testing.T) { - stubProvider := &stubSyncStatusProvider{ + stubProvider := &stubSupervisorSyncStatusProvider{ status: test.syncStatus, err: test.statusReqErr, } - validator := NewSyncValidator(stubProvider) + validator := NewSupervisorSyncValidator(stubProvider) err := validator.ValidateNodeSynced(context.Background(), eth.BlockID{Number: test.gameL1Head}) require.ErrorIs(t, err, test.expectedError, "expected error to be %v, got %v", test.expectedError, err) }) } } -type stubSyncStatusProvider struct { +type stubSupervisorSyncStatusProvider struct { status eth.SupervisorSyncStatus err error } -func (f *stubSyncStatusProvider) SyncStatus(ctx context.Context) (eth.SupervisorSyncStatus, error) { +func (f *stubSupervisorSyncStatusProvider) SyncStatus(ctx context.Context) (eth.SupervisorSyncStatus, error) { return f.status, f.err } diff --git a/op-challenger/game/fault/agent.go b/op-challenger/game/fault/agent.go index c76331ce667..72249268bed 100644 --- a/op-challenger/game/fault/agent.go +++ b/op-challenger/game/fault/agent.go @@ -9,17 +9,41 @@ import ( "sync/atomic" "time" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" "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/responder" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/solver" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/generic" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/clock" + "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) +type TxSender interface { + From() common.Address + SendAndWaitSimple(txPurpose string, txs ...txmgr.TxCandidate) error +} + +type GameContract interface { + generic.GenericGameLoader + preimages.PreimageGameContract + responder.GameContract + claims.BondContract + ClaimLoader + GetStatus(ctx context.Context) (gameTypes.GameStatus, error) + GetMaxGameDepth(ctx context.Context) (types.Depth, error) + GetMaxClockDuration(ctx context.Context) (time.Duration, error) + GetOracle(ctx context.Context) (contracts.PreimageOracleContract, error) + GetL1Head(ctx context.Context) (common.Hash, error) +} + // Responder takes a response action & executes. // For full op-challenger this means executing the transaction on chain. type Responder interface { @@ -31,6 +55,7 @@ type Responder interface { } type ClaimLoader interface { + GetClaimCount(ctx context.Context) (uint64, error) GetAllClaims(ctx context.Context, block rpcblock.Block) ([]types.Claim, error) IsL2BlockNumberChallenged(ctx context.Context, block rpcblock.Block) (bool, error) GetClockExtension(ctx context.Context) (time.Duration, error) @@ -39,6 +64,8 @@ type ClaimLoader interface { GetOracle(ctx context.Context) (contracts.PreimageOracleContract, error) } +type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth types.Depth, l1Head eth.BlockID, dir string) (types.TraceAccessor, error) + type Agent struct { metrics metrics.Metricer systemClock clock.Clock @@ -56,6 +83,71 @@ type Agent struct { responseCount atomic.Uint64 // Number of responses made in this game } +func AgentCreator( + systemClock clock.Clock, + l1Clock types.ClockReader, + m metrics.Metricer, + dir string, + txSender TxSender, + loader GameContract, + creator resourceCreator, + selective bool, + claimants []common.Address, + responseDelay time.Duration, + responseDelayAfter uint64, +) generic.ActorCreator { + return func(ctx context.Context, logger log.Logger, l1Head eth.BlockID) (generic.Actor, error) { + maxClockDuration, err := loader.GetMaxClockDuration(ctx) + if err != nil { + return nil, fmt.Errorf("failed to fetch the game duration: %w", err) + } + + gameDepth, err := loader.GetMaxGameDepth(ctx) + if err != nil { + return nil, fmt.Errorf("failed to fetch the game depth: %w", err) + } + + accessor, err := creator(ctx, logger, gameDepth, l1Head, dir) + if err != nil { + return nil, fmt.Errorf("failed to create trace accessor: %w", err) + } + + oracle, err := loader.GetOracle(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load oracle: %w", err) + } + + minLargePreimageSize, err := oracle.MinLargePreimageSize(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load min large preimage size: %w", err) + } + direct := preimages.NewDirectPreimageUploader(logger, txSender, loader) + large := preimages.NewLargePreimageUploader(logger, l1Clock, txSender, oracle) + uploader := preimages.NewSplitPreimageUploader(direct, large, minLargePreimageSize) + responder, err := responder.NewFaultResponder(logger, txSender, loader, uploader, oracle) + if err != nil { + return nil, fmt.Errorf("failed to create the responder: %w", err) + } + + agent := NewAgent( + m, + systemClock, + l1Clock, + loader, + gameDepth, + maxClockDuration, + accessor, + responder, + logger, + selective, + claimants, + responseDelay, + responseDelayAfter, + ) + return agent, nil + } +} + func NewAgent( m metrics.Metricer, systemClock clock.Clock, @@ -126,6 +218,14 @@ func (a *Agent) Act(ctx context.Context) error { return nil } +func (a *Agent) AdditionalStatus(ctx context.Context) ([]any, error) { + claimCount, err := a.loader.GetClaimCount(ctx) + if err != nil { + return nil, err + } + return []any{"claims", claimCount}, nil +} + func (a *Agent) performAction(ctx context.Context, wg *sync.WaitGroup, game types.Game, action types.Action) { defer wg.Done() actionLog := a.log.New("action", action.Type) diff --git a/op-challenger/game/fault/agent_test.go b/op-challenger/game/fault/agent_test.go index 8f274dbe106..669c5a23df0 100644 --- a/op-challenger/game/fault/agent_test.go +++ b/op-challenger/game/fault/agent_test.go @@ -236,6 +236,10 @@ func (s *stubClaimLoader) IsL2BlockNumberChallenged(_ context.Context, _ rpcbloc return s.blockNumChallenged, nil } +func (s *stubClaimLoader) GetClaimCount(_ context.Context) (uint64, error) { + return uint64(len(s.claims)), nil +} + func (s *stubClaimLoader) GetAllClaims(_ context.Context, _ rpcblock.Block) ([]types.Claim, error) { s.callCount++ if s.callCount > s.maxLoads && s.maxLoads != 0 { diff --git a/op-challenger/game/fault/clients.go b/op-challenger/game/fault/clients.go deleted file mode 100644 index edb18e9bdea..00000000000 --- a/op-challenger/game/fault/clients.go +++ /dev/null @@ -1,83 +0,0 @@ -package fault - -import ( - "context" - "fmt" - - "github.com/ethereum-optimism/optimism/op-challenger/config" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/super" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-service/dial" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" -) - -type clientProvider struct { - ctx context.Context - logger log.Logger - cfg *config.Config - l2HeaderSource utils.L2HeaderSource - rollupClient RollupClient - syncValidator *syncStatusValidator - rootProvider super.RootProvider - toClose []CloseFunc -} - -func (c *clientProvider) Close() { - for _, closeFunc := range c.toClose { - closeFunc() - } -} - -func (c *clientProvider) SingleChainClients() (utils.L2HeaderSource, RollupClient, *syncStatusValidator, error) { - headers, err := c.L2HeaderSource() - if err != nil { - return nil, nil, nil, err - } - rollup, err := c.RollupClient() - if err != nil { - return nil, nil, nil, err - } - return headers, rollup, c.syncValidator, nil -} - -func (c *clientProvider) L2HeaderSource() (utils.L2HeaderSource, error) { - if c.l2HeaderSource != nil { - return c.l2HeaderSource, nil - } - if len(c.cfg.L2Rpcs) != 1 { - return nil, fmt.Errorf("incorrect number of L2 RPCs configured, expected 1 but got %d", len(c.cfg.L2Rpcs)) - } - - l2Client, err := ethclient.DialContext(c.ctx, c.cfg.L2Rpcs[0]) - if err != nil { - return nil, fmt.Errorf("dial l2 client %v: %w", c.cfg.L2Rpcs[0], err) - } - c.l2HeaderSource = l2Client - c.toClose = append(c.toClose, l2Client.Close) - return l2Client, nil -} - -func (c *clientProvider) RollupClient() (RollupClient, error) { - if c.rollupClient != nil { - return c.rollupClient, nil - } - rollupClient, err := dial.DialRollupClientWithTimeout(c.ctx, c.logger, c.cfg.RollupRpc) - if err != nil { - return nil, fmt.Errorf("dial rollup client %v: %w", c.cfg.RollupRpc, err) - } - c.rollupClient = rollupClient - c.syncValidator = newSyncStatusValidator(rollupClient) - c.toClose = append(c.toClose, rollupClient.Close) - return rollupClient, nil -} - -func (c *clientProvider) SuperchainClients() (super.RootProvider, *super.SyncValidator, error) { - supervisorClient, err := dial.DialSupervisorClientWithTimeout(c.ctx, c.logger, c.cfg.SupervisorRPC) - if err != nil { - return nil, nil, fmt.Errorf("failed to dial supervisor: %w", err) - } - c.rootProvider = supervisorClient - c.toClose = append(c.toClose, supervisorClient.Close) - return supervisorClient, super.NewSyncValidator(supervisorClient), nil -} diff --git a/op-challenger/game/fault/contracts/detect.go b/op-challenger/game/fault/contracts/detect.go index 32c8b03ed90..9093e88ebc1 100644 --- a/op-challenger/game/fault/contracts/detect.go +++ b/op-challenger/game/fault/contracts/detect.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum/go-ethereum/common" @@ -22,26 +22,26 @@ var ( }]`)) ) -func DetectGameType(ctx context.Context, addr common.Address, caller *batching.MultiCaller) (faultTypes.GameType, error) { +func DetectGameType(ctx context.Context, addr common.Address, caller *batching.MultiCaller) (gameTypes.GameType, error) { result, err := caller.SingleCall(ctx, rpcblock.Latest, batching.NewContractCall(gameTypeABI, addr, methodGameType)) if err != nil { - return faultTypes.UnknownGameType, fmt.Errorf("failed to detect game type: %w", err) + return gameTypes.UnknownGameType, fmt.Errorf("failed to detect game type: %w", err) } - gameType := faultTypes.GameType(result.GetUint32(0)) + gameType := gameTypes.GameType(result.GetUint32(0)) switch gameType { - case faultTypes.CannonGameType, - faultTypes.PermissionedGameType, - faultTypes.CannonKonaGameType, - faultTypes.AsteriscGameType, - faultTypes.AlphabetGameType, - faultTypes.FastGameType, - faultTypes.AsteriscKonaGameType, - faultTypes.SuperCannonGameType, - faultTypes.SuperPermissionedGameType, - faultTypes.SuperCannonKonaGameType, - faultTypes.SuperAsteriscKonaGameType: + case gameTypes.CannonGameType, + gameTypes.PermissionedGameType, + gameTypes.CannonKonaGameType, + gameTypes.AsteriscGameType, + gameTypes.AlphabetGameType, + gameTypes.FastGameType, + gameTypes.AsteriscKonaGameType, + gameTypes.SuperCannonGameType, + gameTypes.SuperPermissionedGameType, + gameTypes.SuperCannonKonaGameType, + gameTypes.SuperAsteriscKonaGameType: return gameType, nil default: - return faultTypes.UnknownGameType, fmt.Errorf("unsupported game type: %d", gameType) + return gameTypes.UnknownGameType, fmt.Errorf("unsupported game type: %d", gameType) } } diff --git a/op-challenger/game/fault/contracts/disputegame.go b/op-challenger/game/fault/contracts/disputegame.go index b1e9ee616f2..5dd756d5099 100644 --- a/op-challenger/game/fault/contracts/disputegame.go +++ b/op-challenger/game/fault/contracts/disputegame.go @@ -6,7 +6,6 @@ import ( "time" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" @@ -35,23 +34,23 @@ type DisputeGameContract interface { } func NewDisputeGameContractForGame(ctx context.Context, metrics metrics.ContractMetricer, caller *batching.MultiCaller, game gameTypes.GameMetadata) (DisputeGameContract, error) { - return NewDisputeGameContract(ctx, metrics, caller, types.GameType(game.GameType), game.Proxy) + return NewDisputeGameContract(ctx, metrics, caller, gameTypes.GameType(game.GameType), game.Proxy) } -func NewDisputeGameContract(ctx context.Context, metrics metrics.ContractMetricer, caller *batching.MultiCaller, gameType types.GameType, addr common.Address) (DisputeGameContract, error) { +func NewDisputeGameContract(ctx context.Context, metrics metrics.ContractMetricer, caller *batching.MultiCaller, gameType gameTypes.GameType, addr common.Address) (DisputeGameContract, error) { switch gameType { - case types.SuperCannonGameType, types.SuperCannonKonaGameType, types.SuperPermissionedGameType, types.SuperAsteriscKonaGameType: + case gameTypes.SuperCannonGameType, gameTypes.SuperCannonKonaGameType, gameTypes.SuperPermissionedGameType, gameTypes.SuperAsteriscKonaGameType: return NewSuperFaultDisputeGameContract(ctx, metrics, addr, caller) - case types.CannonGameType, - types.PermissionedGameType, - types.CannonKonaGameType, - types.AsteriscGameType, - types.AlphabetGameType, - types.FastGameType, - types.AsteriscKonaGameType: + case gameTypes.CannonGameType, + gameTypes.PermissionedGameType, + gameTypes.CannonKonaGameType, + gameTypes.AsteriscGameType, + gameTypes.AlphabetGameType, + gameTypes.FastGameType, + gameTypes.AsteriscKonaGameType: return NewPreInteropFaultDisputeGameContract(ctx, metrics, addr, caller) - case types.OptimisticZKGameType: + case gameTypes.OptimisticZKGameType: return NewOptimisticZKDisputeGameContract(metrics, addr, caller) default: return nil, ErrUnsupportedGameType diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index 526c7f0280a..8d5f3fa2baa 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -81,7 +81,7 @@ func NewFaultDisputeGameContract(ctx context.Context, metrics metrics.ContractMe return nil, fmt.Errorf("failed to detect game type: %w", err) } switch gameType { - case types.SuperCannonGameType, types.SuperCannonKonaGameType, types.SuperPermissionedGameType, types.SuperAsteriscKonaGameType: + case gameTypes.SuperCannonGameType, gameTypes.SuperCannonKonaGameType, gameTypes.SuperPermissionedGameType, gameTypes.SuperAsteriscKonaGameType: return NewSuperFaultDisputeGameContract(ctx, metrics, addr, caller) default: return NewPreInteropFaultDisputeGameContract(ctx, metrics, addr, caller) diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 2cc98abc551..9b3948deb53 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -14,7 +14,7 @@ import ( contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" @@ -39,7 +39,7 @@ var ( type contractVersion struct { version string - gameType faultTypes.GameType + gameType gameTypes.GameType loadAbi func() *abi.ABI } @@ -52,7 +52,7 @@ func (c contractVersion) String() string { } func (c contractVersion) IsSuperGame() bool { - return c.gameType == faultTypes.SuperCannonGameType || c.gameType == faultTypes.SuperPermissionedGameType || c.gameType == faultTypes.SuperAsteriscKonaGameType + return c.gameType == gameTypes.SuperCannonGameType || c.gameType == gameTypes.SuperPermissionedGameType || c.gameType == gameTypes.SuperAsteriscKonaGameType } const ( @@ -68,47 +68,47 @@ const ( var versions = []contractVersion{ { version: vers080, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: func() *abi.ABI { return mustParseAbi(faultDisputeGameAbi020) }, }, { version: vers0180, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: func() *abi.ABI { return mustParseAbi(faultDisputeGameAbi0180) }, }, { version: vers111, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: func() *abi.ABI { return mustParseAbi(faultDisputeGameAbi111) }, }, { version: vers120, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: func() *abi.ABI { return mustParseAbi(faultDisputeGameAbi120) }, }, { version: vers131, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: func() *abi.ABI { return mustParseAbi(faultDisputeGameAbi131) }, }, { version: versLatest, - gameType: faultTypes.CannonGameType, + gameType: gameTypes.CannonGameType, loadAbi: snapshots.LoadFaultDisputeGameABI, }, { version: verSuperCannon, - gameType: faultTypes.SuperCannonGameType, + gameType: gameTypes.SuperCannonGameType, loadAbi: snapshots.LoadSuperFaultDisputeGameABI, }, } @@ -126,7 +126,7 @@ func TestSimpleGetters(t *testing.T) { { methodAlias: "status", method: methodStatus, - result: types.GameStatusChallengerWon, + result: gameTypes.GameStatusChallengerWon, call: func(game FaultDisputeGameContract) (any, error) { return game.GetStatus(context.Background()) }, @@ -192,7 +192,7 @@ func TestSimpleGetters(t *testing.T) { { methodAlias: "resolve", method: methodResolve, - result: types.GameStatusInProgress, + result: gameTypes.GameStatusInProgress, call: func(game FaultDisputeGameContract) (any, error) { return game.CallResolve(context.Background()) }, @@ -581,7 +581,7 @@ func TestGetGameMetadata(t *testing.T) { expectedL2BlockNumber := uint64(123) expectedMaxClockDuration := uint64(456) expectedRootClaim := common.Hash{0x01, 0x02} - expectedStatus := types.GameStatusChallengerWon + expectedStatus := gameTypes.GameStatusChallengerWon expectedL2BlockNumberChallenged := true expectedL2BlockNumberChallenger := common.Address{0xee} block := rpcblock.ByNumber(889) @@ -625,7 +625,7 @@ func TestGetMetadata(t *testing.T) { expectedL1Head := common.Hash{0x0a, 0x0b} expectedL2BlockNumber := uint64(123) expectedRootClaim := common.Hash{0x01, 0x02} - expectedStatus := types.GameStatusChallengerWon + expectedStatus := gameTypes.GameStatusChallengerWon block := rpcblock.ByNumber(889) stubRpc.SetResponse(fdgAddr, methodL1Head, block, nil, []interface{}{expectedL1Head}) if version.IsSuperGame() { @@ -705,7 +705,7 @@ func TestFaultDisputeGame_GetCredit(t *testing.T) { stubRpc, game := setupFaultDisputeGameTest(t, version) addr := common.Address{0x01} expectedCredit := big.NewInt(4284) - expectedStatus := types.GameStatusChallengerWon + expectedStatus := gameTypes.GameStatusChallengerWon stubRpc.SetResponse(fdgAddr, methodCredit, rpcblock.Latest, []interface{}{addr}, []interface{}{expectedCredit}) stubRpc.SetResponse(fdgAddr, methodStatus, rpcblock.Latest, nil, []interface{}{expectedStatus}) diff --git a/op-challenger/game/fault/contracts/gamefactory.go b/op-challenger/game/fault/contracts/gamefactory.go index 6b36392de71..4727d0b9cc5 100644 --- a/op-challenger/game/fault/contracts/gamefactory.go +++ b/op-challenger/game/fault/contracts/gamefactory.go @@ -9,8 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/gameargs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum-optimism/optimism/op-service/txmgr" @@ -39,9 +38,9 @@ var ( //go:embed abis/DisputeGameFactory-1.2.0.json var disputeGameFactoryAbi120 []byte -type gameArgsFunc func(ctx context.Context, caller *batching.MultiCaller, block rpcblock.Block, contract *batching.BoundContract, gameType faultTypes.GameType) ([]byte, error) +type gameArgsFunc func(ctx context.Context, caller *batching.MultiCaller, block rpcblock.Block, contract *batching.BoundContract, gameType gameTypes.GameType) ([]byte, error) -func getGameArgsLatest(ctx context.Context, caller *batching.MultiCaller, block rpcblock.Block, contract *batching.BoundContract, gameType faultTypes.GameType) ([]byte, error) { +func getGameArgsLatest(ctx context.Context, caller *batching.MultiCaller, block rpcblock.Block, contract *batching.BoundContract, gameType gameTypes.GameType) ([]byte, error) { result, err := caller.SingleCall(ctx, block, contract.Call(methodGameArgs, gameType)) if err != nil { return nil, fmt.Errorf("failed to get game args: %w", err) @@ -49,7 +48,7 @@ func getGameArgsLatest(ctx context.Context, caller *batching.MultiCaller, block return result.GetBytes(0), nil } -func getGameArgsNoOp(_ context.Context, _ *batching.MultiCaller, _ rpcblock.Block, _ *batching.BoundContract, _ faultTypes.GameType) ([]byte, error) { +func getGameArgsNoOp(_ context.Context, _ *batching.MultiCaller, _ rpcblock.Block, _ *batching.BoundContract, _ gameTypes.GameType) ([]byte, error) { return nil, nil } @@ -89,9 +88,9 @@ func newDisputeGameFactoryContract(m metrics.ContractMetricer, addr common.Addre } } -func (f *DisputeGameFactoryContract) GetGameFromParameters(ctx context.Context, traceType uint32, outputRoot common.Hash, l2BlockNum uint64) (common.Address, error) { +func (f *DisputeGameFactoryContract) GetGameFromParameters(ctx context.Context, gameType uint32, outputRoot common.Hash, l2BlockNum uint64) (common.Address, error) { defer f.metrics.StartContractRequest("GetGameFromParameters")() - result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGames, traceType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes())) + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGames, gameType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes())) if err != nil { return common.Address{}, fmt.Errorf("failed to fetch game from parameters: %w", err) } @@ -107,16 +106,16 @@ func (f *DisputeGameFactoryContract) GetGameCount(ctx context.Context, blockHash return result.GetBigInt(0).Uint64(), nil } -func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, blockHash common.Hash) (types.GameMetadata, error) { +func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, blockHash common.Hash) (gameTypes.GameMetadata, error) { defer f.metrics.StartContractRequest("GetGame")() result, err := f.multiCaller.SingleCall(ctx, rpcblock.ByHash(blockHash), f.contract.Call(methodGameAtIndex, new(big.Int).SetUint64(idx))) if err != nil { - return types.GameMetadata{}, fmt.Errorf("failed to load game %v: %w", idx, err) + return gameTypes.GameMetadata{}, fmt.Errorf("failed to load game %v: %w", idx, err) } return f.decodeGame(idx, result), nil } -func (f *DisputeGameFactoryContract) getGameImpl(ctx context.Context, gameType faultTypes.GameType) (common.Address, error) { +func (f *DisputeGameFactoryContract) getGameImpl(ctx context.Context, gameType gameTypes.GameType) (common.Address, error) { defer f.metrics.StartContractRequest("GetGameImpl")() result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameImpls, gameType)) if err != nil { @@ -125,7 +124,7 @@ func (f *DisputeGameFactoryContract) getGameImpl(ctx context.Context, gameType f return result.GetAddress(0), nil } -func (f *DisputeGameFactoryContract) HasGameImpl(ctx context.Context, gameType faultTypes.GameType) (bool, error) { +func (f *DisputeGameFactoryContract) HasGameImpl(ctx context.Context, gameType gameTypes.GameType) (bool, error) { impl, err := f.getGameImpl(ctx, gameType) if err != nil { return false, err @@ -133,7 +132,7 @@ func (f *DisputeGameFactoryContract) HasGameImpl(ctx context.Context, gameType f return impl != (common.Address{}), nil } -func (f *DisputeGameFactoryContract) GetGameVm(ctx context.Context, gameType faultTypes.GameType) (*VMContract, error) { +func (f *DisputeGameFactoryContract) GetGameVm(ctx context.Context, gameType gameTypes.GameType) (*VMContract, error) { defer f.metrics.StartContractRequest("GetGameVm")() gameArgs, err := f.getGameArgs(ctx, f.multiCaller, rpcblock.Latest, f.contract, gameType) if err != nil { @@ -155,7 +154,7 @@ func (f *DisputeGameFactoryContract) GetGameVm(ctx context.Context, gameType fau return NewVMContract(args.Vm, f.multiCaller), nil } -func (f *DisputeGameFactoryContract) GetGamePrestate(ctx context.Context, gameType faultTypes.GameType) (common.Hash, error) { +func (f *DisputeGameFactoryContract) GetGamePrestate(ctx context.Context, gameType gameTypes.GameType) (common.Hash, error) { defer f.metrics.StartContractRequest("GetGamePrestate")() gameArgs, err := f.getGameArgs(ctx, f.multiCaller, rpcblock.Latest, f.contract, gameType) if err != nil { @@ -177,7 +176,7 @@ func (f *DisputeGameFactoryContract) GetGamePrestate(ctx context.Context, gameTy return args.AbsolutePrestate, nil } -func (f *DisputeGameFactoryContract) faultDisputeGameForType(ctx context.Context, gameType faultTypes.GameType) (FaultDisputeGameContract, error) { +func (f *DisputeGameFactoryContract) faultDisputeGameForType(ctx context.Context, gameType gameTypes.GameType) (FaultDisputeGameContract, error) { addr, err := f.getGameImpl(ctx, gameType) if err != nil { return nil, err @@ -185,7 +184,7 @@ func (f *DisputeGameFactoryContract) faultDisputeGameForType(ctx context.Context return NewFaultDisputeGameContract(ctx, f.metrics, addr, f.multiCaller) } -func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]types.GameMetadata, error) { +func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]gameTypes.GameMetadata, error) { defer f.metrics.StartContractRequest("GetGamesAtOrAfter")() count, err := f.GetGameCount(ctx, blockHash) if err != nil { @@ -194,7 +193,7 @@ func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, bloc batchSize := uint64(f.multiCaller.BatchSize()) rangeEnd := count - var games []types.GameMetadata + var games []gameTypes.GameMetadata for { if rangeEnd == uint64(0) { // rangeEnd is exclusive so if its 0 we've reached the end. @@ -230,7 +229,7 @@ func (f *DisputeGameFactoryContract) GetGamesAtOrAfter(ctx context.Context, bloc } } -func (f *DisputeGameFactoryContract) GetAllGames(ctx context.Context, blockHash common.Hash) ([]types.GameMetadata, error) { +func (f *DisputeGameFactoryContract) GetAllGames(ctx context.Context, blockHash common.Hash) ([]gameTypes.GameMetadata, error) { defer f.metrics.StartContractRequest("GetAllGames")() count, err := f.GetGameCount(ctx, blockHash) if err != nil { @@ -247,20 +246,20 @@ func (f *DisputeGameFactoryContract) GetAllGames(ctx context.Context, blockHash return nil, fmt.Errorf("failed to fetch games: %w", err) } - var games []types.GameMetadata + var games []gameTypes.GameMetadata for i, result := range results { games = append(games, f.decodeGame(uint64(i), result)) } return games, nil } -func (f *DisputeGameFactoryContract) CreateTx(ctx context.Context, traceType uint32, outputRoot common.Hash, l2BlockNum uint64) (txmgr.TxCandidate, error) { - result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodInitBonds, traceType)) +func (f *DisputeGameFactoryContract) CreateTx(ctx context.Context, gameType uint32, outputRoot common.Hash, l2BlockNum uint64) (txmgr.TxCandidate, error) { + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodInitBonds, gameType)) if err != nil { return txmgr.TxCandidate{}, fmt.Errorf("failed to fetch init bond: %w", err) } initBond := result.GetBigInt(0) - call := f.contract.Call(methodCreateGame, traceType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes()) + call := f.contract.Call(methodCreateGame, gameType, outputRoot, common.BigToHash(big.NewInt(int64(l2BlockNum))).Bytes()) candidate, err := call.ToTxCandidate() if err != nil { return txmgr.TxCandidate{}, err @@ -290,11 +289,11 @@ func (f *DisputeGameFactoryContract) DecodeDisputeGameCreatedLog(rcpt *ethTypes. return common.Address{}, 0, common.Hash{}, fmt.Errorf("%w: %v", ErrEventNotFound, eventDisputeGameCreated) } -func (f *DisputeGameFactoryContract) decodeGame(idx uint64, result *batching.CallResult) types.GameMetadata { +func (f *DisputeGameFactoryContract) decodeGame(idx uint64, result *batching.CallResult) gameTypes.GameMetadata { gameType := result.GetUint32(0) timestamp := result.GetUint64(1) proxy := result.GetAddress(2) - return types.GameMetadata{ + return gameTypes.GameMetadata{ Index: idx, GameType: gameType, Timestamp: timestamp, diff --git a/op-challenger/game/fault/contracts/gamefactory_test.go b/op-challenger/game/fault/contracts/gamefactory_test.go index bda80d025bf..bdd468c49f4 100644 --- a/op-challenger/game/fault/contracts/gamefactory_test.go +++ b/op-challenger/game/fault/contracts/gamefactory_test.go @@ -9,8 +9,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/gameargs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" @@ -104,25 +103,25 @@ func TestLoadGame(t *testing.T) { t.Run(version.String(), func(t *testing.T) { blockHash := common.Hash{0xbb, 0xce} stubRpc, factory := setupDisputeGameFactoryTest(t, version) - game0 := types.GameMetadata{ + game0 := gameTypes.GameMetadata{ Index: 0, GameType: 0, Timestamp: 1234, Proxy: common.Address{0xaa}, } - game1 := types.GameMetadata{ + game1 := gameTypes.GameMetadata{ Index: 1, GameType: 1, Timestamp: 5678, Proxy: common.Address{0xbb}, } - game2 := types.GameMetadata{ + game2 := gameTypes.GameMetadata{ Index: 2, GameType: 99, Timestamp: 9988, Proxy: common.Address{0xcc}, } - expectedGames := []types.GameMetadata{game0, game1, game2} + expectedGames := []gameTypes.GameMetadata{game0, game1, game2} for idx, expected := range expectedGames { expectGetGame(stubRpc, idx, blockHash, expected) actual, err := factory.GetGame(context.Background(), uint64(idx), blockHash) @@ -138,26 +137,26 @@ func TestGetAllGames(t *testing.T) { t.Run(version.String(), func(t *testing.T) { blockHash := common.Hash{0xbb, 0xce} stubRpc, factory := setupDisputeGameFactoryTest(t, version) - game0 := types.GameMetadata{ + game0 := gameTypes.GameMetadata{ Index: 0, GameType: 0, Timestamp: 1234, Proxy: common.Address{0xaa}, } - game1 := types.GameMetadata{ + game1 := gameTypes.GameMetadata{ Index: 1, GameType: 1, Timestamp: 5678, Proxy: common.Address{0xbb}, } - game2 := types.GameMetadata{ + game2 := gameTypes.GameMetadata{ Index: 2, GameType: 99, Timestamp: 9988, Proxy: common.Address{0xcc}, } - expectedGames := []types.GameMetadata{game0, game1, game2} + expectedGames := []gameTypes.GameMetadata{game0, game1, game2} stubRpc.SetResponse(factoryAddr, methodGameCount, rpcblock.ByHash(blockHash), nil, []interface{}{big.NewInt(int64(len(expectedGames)))}) for idx, expected := range expectedGames { expectGetGame(stubRpc, idx, blockHash, expected) @@ -190,9 +189,9 @@ func TestGetAllGamesAtOrAfter(t *testing.T) { t.Run(fmt.Sprintf("Count_%v_Start_%v", test.gameCount, test.earliestGameIdx), func(t *testing.T) { blockHash := common.Hash{0xbb, 0xce} stubRpc, factory := setupDisputeGameFactoryTest(t, version) - var allGames []types.GameMetadata + var allGames []gameTypes.GameMetadata for i := 0; i < test.gameCount; i++ { - allGames = append(allGames, types.GameMetadata{ + allGames = append(allGames, gameTypes.GameMetadata{ Index: uint64(i), GameType: uint32(i), Timestamp: uint64(i), @@ -209,7 +208,7 @@ func TestGetAllGamesAtOrAfter(t *testing.T) { actualGames, err := factory.GetGamesAtOrAfter(context.Background(), blockHash, earliestTimestamp) require.NoError(t, err) // Games come back in descending timestamp order - var expectedGames []types.GameMetadata + var expectedGames []gameTypes.GameMetadata if test.earliestGameIdx < len(allGames) { expectedGames = slices.Clone(allGames[test.earliestGameIdx:]) } @@ -229,17 +228,17 @@ func TestGetGameFromParameters(t *testing.T) { for _, version := range factoryVersions { t.Run(version.String(), func(t *testing.T) { stubRpc, factory := setupDisputeGameFactoryTest(t, version) - traceType := uint32(123) + gameType := uint32(123) outputRoot := common.Hash{0x01} l2BlockNum := common.BigToHash(big.NewInt(456)).Bytes() stubRpc.SetResponse( factoryAddr, methodGames, rpcblock.Latest, - []interface{}{traceType, outputRoot, l2BlockNum}, + []interface{}{gameType, outputRoot, l2BlockNum}, []interface{}{common.Address{0xaa}, uint64(1)}, ) - addr, err := factory.GetGameFromParameters(context.Background(), traceType, outputRoot, uint64(456)) + addr, err := factory.GetGameFromParameters(context.Background(), gameType, outputRoot, uint64(456)) require.NoError(t, err) require.Equal(t, common.Address{0xaa}, addr) }) @@ -250,7 +249,7 @@ func TestHasGameImpl(t *testing.T) { for _, version := range factoryVersions { t.Run(version.String()+"-set", func(t *testing.T) { stubRpc, factory := setupDisputeGameFactoryTest(t, version) - gameType := faultTypes.CannonGameType + gameType := gameTypes.CannonGameType gameImplAddr := common.Address{0xaa} stubRpc.SetResponse( factoryAddr, @@ -258,20 +257,20 @@ func TestHasGameImpl(t *testing.T) { rpcblock.Latest, []interface{}{gameType}, []interface{}{gameImplAddr}) - actual, err := factory.HasGameImpl(context.Background(), faultTypes.CannonGameType) + actual, err := factory.HasGameImpl(context.Background(), gameTypes.CannonGameType) require.NoError(t, err) require.True(t, actual) }) t.Run(version.String()+"-unset", func(t *testing.T) { stubRpc, factory := setupDisputeGameFactoryTest(t, version) - gameType := faultTypes.CannonGameType + gameType := gameTypes.CannonGameType stubRpc.SetResponse( factoryAddr, methodGameImpls, rpcblock.Latest, []interface{}{gameType}, []interface{}{common.Address{}}) - actual, err := factory.HasGameImpl(context.Background(), faultTypes.CannonGameType) + actual, err := factory.HasGameImpl(context.Background(), gameTypes.CannonGameType) require.NoError(t, err) require.False(t, actual) }) @@ -283,7 +282,7 @@ func TestGetGameVM(t *testing.T) { t.Run(fmt.Sprintf("GameArgs-%v", usesGameArgs), func(t *testing.T) { for _, version := range factoryVersions { t.Run(version.String(), func(t *testing.T) { - gameType := faultTypes.CannonGameType + gameType := gameTypes.CannonGameType rpc, factory := setupDisputeGameFactoryTest(t, version) if usesGameArgs { @@ -322,7 +321,7 @@ func TestGetGamePrestate(t *testing.T) { t.Run(fmt.Sprintf("GameArgs-%v", usesGameArgs), func(t *testing.T) { for _, version := range factoryVersions { t.Run(version.String(), func(t *testing.T) { - gameType := faultTypes.CannonGameType + gameType := gameTypes.CannonGameType prestate := common.Hash{92, 4, 6, 12, 4} rpc, factory := setupDisputeGameFactoryTest(t, version) @@ -428,7 +427,7 @@ func TestDecodeDisputeGameCreatedLog(t *testing.T) { } } -func expectGetGame(stubRpc *batchingTest.AbiBasedRpc, idx int, blockHash common.Hash, game types.GameMetadata) { +func expectGetGame(stubRpc *batchingTest.AbiBasedRpc, idx int, blockHash common.Hash, game gameTypes.GameMetadata) { stubRpc.SetResponse( factoryAddr, methodGameAtIndex, @@ -445,13 +444,13 @@ func TestCreateTx(t *testing.T) { for _, version := range factoryVersions { t.Run(version.String(), func(t *testing.T) { stubRpc, factory := setupDisputeGameFactoryTest(t, version) - traceType := uint32(123) + gameType := uint32(123) outputRoot := common.Hash{0x01} l2BlockNum := common.BigToHash(big.NewInt(456)).Bytes() bond := big.NewInt(49284294829) - stubRpc.SetResponse(factoryAddr, methodInitBonds, rpcblock.Latest, []interface{}{traceType}, []interface{}{bond}) - stubRpc.SetResponse(factoryAddr, methodCreateGame, rpcblock.Latest, []interface{}{traceType, outputRoot, l2BlockNum}, nil) - tx, err := factory.CreateTx(context.Background(), traceType, outputRoot, uint64(456)) + stubRpc.SetResponse(factoryAddr, methodInitBonds, rpcblock.Latest, []interface{}{gameType}, []interface{}{bond}) + stubRpc.SetResponse(factoryAddr, methodCreateGame, rpcblock.Latest, []interface{}{gameType, outputRoot, l2BlockNum}, nil) + tx, err := factory.CreateTx(context.Background(), gameType, outputRoot, uint64(456)) require.NoError(t, err) stubRpc.VerifyTxCandidate(tx) require.NotNil(t, tx.Value) @@ -469,7 +468,7 @@ func setupDisputeGameFactoryTest(t *testing.T, version factoryContractVersion) ( return stubRpc, factory } -func setupDisputeGame(rpc *batchingTest.AbiBasedRpc, gameAddr common.Address, gameType faultTypes.GameType) { +func setupDisputeGame(rpc *batchingTest.AbiBasedRpc, gameAddr common.Address, gameType gameTypes.GameType) { rpc.AddContract(gameAddr, snapshots.LoadFaultDisputeGameABI()) rpc.SetResponse(gameAddr, methodVersion, rpcblock.Latest, nil, []interface{}{versLatest}) rpc.SetResponse(gameAddr, methodGameType, rpcblock.Latest, nil, []interface{}{gameType}) diff --git a/op-challenger/game/fault/contracts/optimisticzkdisputegame_test.go b/op-challenger/game/fault/contracts/optimisticzkdisputegame_test.go index aba34618429..9c9a393f2fc 100644 --- a/op-challenger/game/fault/contracts/optimisticzkdisputegame_test.go +++ b/op-challenger/game/fault/contracts/optimisticzkdisputegame_test.go @@ -7,8 +7,7 @@ import ( "time" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" @@ -24,7 +23,7 @@ const ( var zkVersions = []contractVersion{ { version: versZKLatest, - gameType: faultTypes.OptimisticZKGameType, + gameType: gameTypes.OptimisticZKGameType, loadAbi: snapshots.LoadZKDisputeGameABI, }, } @@ -42,7 +41,7 @@ func TestZKSimpleGetters(t *testing.T) { { methodAlias: "status", method: methodStatus, - result: types.GameStatusChallengerWon, + result: gameTypes.GameStatusChallengerWon, call: func(game OptimisticZKDisputeGameContract) (any, error) { return game.GetStatus(context.Background()) }, @@ -58,7 +57,7 @@ func TestZKSimpleGetters(t *testing.T) { { methodAlias: "resolve", method: methodResolve, - result: types.GameStatusInProgress, + result: gameTypes.GameStatusInProgress, call: func(game OptimisticZKDisputeGameContract) (any, error) { return game.CallResolve(context.Background()) }, @@ -105,7 +104,7 @@ func TestZKGetMetadata(t *testing.T) { expectedL1Head := common.Hash{0x0a, 0x0b} expectedL2BlockNumber := uint64(123) expectedRootClaim := common.Hash{0x01, 0x02} - expectedStatus := types.GameStatusChallengerWon + expectedStatus := gameTypes.GameStatusChallengerWon block := rpcblock.ByNumber(889) stubRpc.SetResponse(fdgAddr, methodL1Head, block, nil, []interface{}{expectedL1Head}) stubRpc.SetResponse(fdgAddr, methodL2SequenceNumber, block, nil, []interface{}{new(big.Int).SetUint64(expectedL2BlockNumber)}) diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index a5cd1280f35..4373a371159 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -5,16 +5,16 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-challenger/config" + "github.com/ethereum-optimism/optimism/op-challenger/game/client" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/clock" - "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) @@ -22,8 +22,8 @@ import ( type CloseFunc func() type Registry interface { - RegisterGameType(gameType faultTypes.GameType, creator scheduler.PlayerCreator) - RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator) + RegisterGameType(gameType gameTypes.GameType, creator scheduler.PlayerCreator) + RegisterBondContract(gameType gameTypes.GameType, creator claims.BondContractCreator) } type OracleRegistry interface { @@ -37,11 +37,6 @@ type PrestateSource interface { PrestatePath(ctx context.Context, prestateHash common.Hash) (string, error) } -type RollupClient interface { - outputs.OutputRollupClient - SyncStatusProvider -} - func RegisterGameTypes( ctx context.Context, systemClock clock.Clock, @@ -53,94 +48,92 @@ func RegisterGameTypes( oracles OracleRegistry, txSender TxSender, gameFactory *contracts.DisputeGameFactoryContract, - caller *batching.MultiCaller, - l1HeaderSource L1HeaderSource, + clients *client.Provider, selective bool, claimants []common.Address, -) (CloseFunc, error) { - clients := &clientProvider{ctx: ctx, logger: logger, cfg: cfg} +) error { var registerTasks []*RegisterTask - if cfg.TraceTypeEnabled(faultTypes.TraceTypeCannon) { + if cfg.GameTypeEnabled(gameTypes.CannonGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.CannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewCannonRegisterTask(gameTypes.CannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeCannonKona) { + if cfg.GameTypeEnabled(gameTypes.CannonKonaGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewCannonKonaRegisterTask(faultTypes.CannonKonaGameType, cfg, m, vm.NewKonaExecutor(), l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewCannonKonaRegisterTask(gameTypes.CannonKonaGameType, cfg, m, vm.NewKonaExecutor(), l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeSuperCannon) { + if cfg.GameTypeEnabled(gameTypes.SuperCannonGameType) { rootProvider, syncValidator, err := clients.SuperchainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewSuperCannonRegisterTask(faultTypes.SuperCannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), rootProvider, syncValidator)) + registerTasks = append(registerTasks, NewSuperCannonRegisterTask(gameTypes.SuperCannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), rootProvider, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeSuperCannonKona) { + if cfg.GameTypeEnabled(gameTypes.SuperCannonKonaGameType) { rootProvider, syncValidator, err := clients.SuperchainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewSuperCannonKonaRegisterTask(faultTypes.SuperCannonKonaGameType, cfg, m, vm.NewKonaSuperExecutor(), rootProvider, syncValidator)) + registerTasks = append(registerTasks, NewSuperCannonKonaRegisterTask(gameTypes.SuperCannonKonaGameType, cfg, m, vm.NewKonaSuperExecutor(), rootProvider, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypePermissioned) { + if cfg.GameTypeEnabled(gameTypes.PermissionedGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.PermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewCannonRegisterTask(gameTypes.PermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeSuperPermissioned) { + if cfg.GameTypeEnabled(gameTypes.SuperPermissionedGameType) { rootProvider, syncValidator, err := clients.SuperchainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewSuperCannonRegisterTask(faultTypes.SuperPermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), rootProvider, syncValidator)) + registerTasks = append(registerTasks, NewSuperCannonRegisterTask(gameTypes.SuperPermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), rootProvider, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsterisc) { + if cfg.GameTypeEnabled(gameTypes.AsteriscGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewAsteriscRegisterTask(gameTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsteriscKona) { + if cfg.GameTypeEnabled(gameTypes.AsteriscKonaGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaExecutor(), l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(gameTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaExecutor(), l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeSuperAsteriscKona) { + if cfg.GameTypeEnabled(gameTypes.SuperAsteriscKonaGameType) { rootProvider, syncValidator, err := clients.SuperchainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewSuperAsteriscKonaRegisterTask(faultTypes.SuperAsteriscKonaGameType, cfg, m, vm.NewKonaSuperExecutor(), rootProvider, syncValidator)) + registerTasks = append(registerTasks, NewSuperAsteriscKonaRegisterTask(gameTypes.SuperAsteriscKonaGameType, cfg, m, vm.NewKonaSuperExecutor(), rootProvider, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) { + if cfg.GameTypeEnabled(gameTypes.FastGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.FastGameType, l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewAlphabetRegisterTask(gameTypes.FastGameType, l2HeaderSource, rollupClient, syncValidator)) } - if cfg.TraceTypeEnabled(faultTypes.TraceTypeAlphabet) { + if cfg.GameTypeEnabled(gameTypes.AlphabetGameType) { l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients() if err != nil { - return nil, err + return err } - registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.AlphabetGameType, l2HeaderSource, rollupClient, syncValidator)) + registerTasks = append(registerTasks, NewAlphabetRegisterTask(gameTypes.AlphabetGameType, l2HeaderSource, rollupClient, syncValidator)) } for _, task := range registerTasks { - if err := task.Register(ctx, registry, oracles, systemClock, l1Clock, logger, m, txSender, gameFactory, caller, l1HeaderSource, selective, claimants, cfg.ResponseDelay, cfg.ResponseDelayAfter); err != nil { - return clients.Close, fmt.Errorf("failed to register %v game type: %w", task.gameType, err) + if err := task.Register(ctx, registry, oracles, systemClock, l1Clock, logger, m, txSender, gameFactory, clients.MultiCaller(), clients.L1Client(), selective, claimants, cfg.ResponseDelay, cfg.ResponseDelayAfter); err != nil { + return fmt.Errorf("failed to register %v game type: %w", task.gameType, err) } } - return clients.Close, nil + return nil } diff --git a/op-challenger/game/fault/register_task.go b/op-challenger/game/fault/register_task.go index a5e26500656..dbd10bd2fa4 100644 --- a/op-challenger/game/fault/register_task.go +++ b/op-challenger/game/fault/register_task.go @@ -20,8 +20,9 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/generic" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -32,10 +33,10 @@ import ( ) type RegisterTask struct { - gameType faultTypes.GameType + gameType gameTypes.GameType skipPrestateValidation bool - syncValidator SyncValidator + syncValidator generic.SyncValidator getTopPrestateProvider func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) getBottomPrestateProvider func(ctx context.Context, prestateHash common.Hash) (faultTypes.PrestateProvider, error) @@ -51,21 +52,21 @@ type RegisterTask struct { poststateBlock uint64) (*trace.Accessor, error) } -func NewSuperCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator *super.SyncValidator) *RegisterTask { +func NewSuperCannonRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator generic.SyncValidator) *RegisterTask { return newSuperCannonVMRegisterTaskWithConfig(gameType, cfg, m, serverExecutor, rootProvider, syncValidator, cfg.Cannon, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState) } -func NewSuperCannonKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator *super.SyncValidator) *RegisterTask { +func NewSuperCannonKonaRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator generic.SyncValidator) *RegisterTask { return newSuperCannonVMRegisterTaskWithConfig(gameType, cfg, m, serverExecutor, rootProvider, syncValidator, cfg.CannonKona, cfg.CannonKonaAbsolutePreStateBaseURL, cfg.CannonKonaAbsolutePreState) } func newSuperCannonVMRegisterTaskWithConfig( - gameType faultTypes.GameType, + gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, - syncValidator SyncValidator, + syncValidator generic.SyncValidator, vmCfg vm.Config, preStateBaseURL *url.URL, preState string, @@ -74,7 +75,7 @@ func newSuperCannonVMRegisterTaskWithConfig( return &RegisterTask{ gameType: gameType, syncValidator: syncValidator, - skipPrestateValidation: gameType == faultTypes.SuperPermissionedGameType, + skipPrestateValidation: gameType == gameTypes.SuperPermissionedGameType, getTopPrestateProvider: func(ctx context.Context, prestateTimestamp uint64) (faultTypes.PrestateProvider, error) { return super.NewSuperRootPrestateProvider(rootProvider, prestateTimestamp), nil }, @@ -105,22 +106,22 @@ func newSuperCannonVMRegisterTaskWithConfig( } } -func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask { +func NewCannonRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator generic.SyncValidator) *RegisterTask { return newCannonVMRegisterTaskWithConfig(gameType, cfg, m, serverExecutor, l2Client, rollupClient, syncValidator, cfg.Cannon, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState) } -func NewCannonKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask { +func NewCannonKonaRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator generic.SyncValidator) *RegisterTask { return newCannonVMRegisterTaskWithConfig(gameType, cfg, m, serverExecutor, l2Client, rollupClient, syncValidator, cfg.CannonKona, cfg.CannonKonaAbsolutePreStateBaseURL, cfg.CannonKonaAbsolutePreState) } func newCannonVMRegisterTaskWithConfig( - gameType faultTypes.GameType, + gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, - syncValidator SyncValidator, + syncValidator generic.SyncValidator, vmCfg vm.Config, preStateBaseURL *url.URL, preState string, @@ -132,7 +133,7 @@ func newCannonVMRegisterTaskWithConfig( // Don't validate the absolute prestate or genesis output root for permissioned games // Only trusted actors participate in these games so they aren't expected to reach the step() call and // are often configured without valid prestates but the challenger should still resolve the games. - skipPrestateValidation: gameType == faultTypes.PermissionedGameType, + skipPrestateValidation: gameType == gameTypes.PermissionedGameType, getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) { return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil }, @@ -162,7 +163,7 @@ func newCannonVMRegisterTaskWithConfig( } } -func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask { +func NewAsteriscRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator generic.SyncValidator) *RegisterTask { stateConverter := asterisc.NewStateConverter(cfg.Asterisc) return &RegisterTask{ gameType: gameType, @@ -196,7 +197,7 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m } } -func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask { +func NewAsteriscKonaRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator generic.SyncValidator) *RegisterTask { stateConverter := asterisc.NewStateConverter(cfg.Asterisc) return &RegisterTask{ gameType: gameType, @@ -230,12 +231,12 @@ func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Confi } } -func NewSuperAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator *super.SyncValidator) *RegisterTask { +func NewSuperAsteriscKonaRegisterTask(gameType gameTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, rootProvider super.RootProvider, syncValidator generic.SyncValidator) *RegisterTask { stateConverter := asterisc.NewStateConverter(cfg.AsteriscKona) return &RegisterTask{ gameType: gameType, syncValidator: syncValidator, - skipPrestateValidation: gameType == faultTypes.SuperPermissionedGameType, + skipPrestateValidation: gameType == gameTypes.SuperPermissionedGameType, getTopPrestateProvider: func(ctx context.Context, prestateTimestamp uint64) (faultTypes.PrestateProvider, error) { return super.NewSuperRootPrestateProvider(rootProvider, prestateTimestamp), nil }, @@ -266,7 +267,7 @@ func NewSuperAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config. } } -func NewAlphabetRegisterTask(gameType faultTypes.GameType, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask { +func NewAlphabetRegisterTask(gameType gameTypes.GameType, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator generic.SyncValidator) *RegisterTask { return &RegisterTask{ gameType: gameType, syncValidator: syncValidator, @@ -292,7 +293,7 @@ func NewAlphabetRegisterTask(gameType faultTypes.GameType, l2Client utils.L2Head } func cachePrestates( - gameType faultTypes.GameType, + gameType gameTypes.GameType, stateConverter vm.StateConverter, m caching.Metrics, prestateBaseURL *url.URL, @@ -323,13 +324,13 @@ func (e *RegisterTask) Register( txSender TxSender, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, - l1HeaderSource L1HeaderSource, + l1HeaderSource generic.L1HeaderSource, selective bool, claimants []common.Address, responseDelay time.Duration, responseDelayAfter uint64) error { - playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { + playerCreator := func(game gameTypes.GameMetadata, dir string) (scheduler.GamePlayer, error) { contract, err := contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller) if err != nil { return nil, fmt.Errorf("failed to create fault dispute game contracts: %w", err) @@ -357,27 +358,32 @@ func (e *RegisterTask) Register( if err != nil { return nil, fmt.Errorf("failed to load split depth: %w", err) } - l1HeadID, err := loadL1Head(contract, ctx, l1HeaderSource) - if err != nil { - return nil, err - } prestateProvider, err := e.getTopPrestateProvider(ctx, prestateBlock) if err != nil { return nil, fmt.Errorf("failed to create top prestate provider: %w", err) } - creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, dir string) (faultTypes.TraceAccessor, error) { + creator := func(ctx context.Context, logger log.Logger, gameDepth faultTypes.Depth, l1HeadID eth.BlockID, dir string) (faultTypes.TraceAccessor, error) { accessor, err := e.newTraceAccessor(logger, m, prestateProvider, vmPrestateProvider, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) if err != nil { return nil, err } return accessor, nil } - var validators []Validator + var validators []generic.PrestateValidator if !e.skipPrestateValidation { validators = append(validators, NewPrestateValidator(e.gameType.String(), contract.GetAbsolutePrestateHash, vmPrestateProvider)) validators = append(validators, NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider)) } - return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, e.syncValidator, validators, creator, l1HeaderSource, selective, claimants, responseDelay, responseDelayAfter) + return generic.NewGenericGamePlayer( + ctx, + logger, + game.Proxy, + contract, + e.syncValidator, + validators, + l1HeaderSource, + AgentCreator(systemClock, l1Clock, m, dir, txSender, contract, creator, selective, claimants, responseDelay, responseDelayAfter), + ) } err := registerOracle(ctx, logger, oracles, gameFactory, e.gameType) if err != nil { @@ -385,14 +391,14 @@ func (e *RegisterTask) Register( } registry.RegisterGameType(e.gameType, playerCreator) - contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { + contractCreator := func(game gameTypes.GameMetadata) (claims.BondContract, error) { return contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller) } registry.RegisterBondContract(e.gameType, contractCreator) return nil } -func registerOracle(ctx context.Context, logger log.Logger, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, gameType faultTypes.GameType) error { +func registerOracle(ctx context.Context, logger log.Logger, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, gameType gameTypes.GameType) error { // Check that there is an implementation set for this game type and skip if not. hasImpl, err := gameFactory.HasGameImpl(ctx, gameType) if err != nil { @@ -413,15 +419,3 @@ func registerOracle(ctx context.Context, logger log.Logger, oracles OracleRegist oracles.RegisterOracle(oracle) return nil } - -func loadL1Head(contract contracts.FaultDisputeGameContract, ctx context.Context, l1HeaderSource L1HeaderSource) (eth.BlockID, error) { - l1Head, err := contract.GetL1Head(ctx) - if err != nil { - return eth.BlockID{}, fmt.Errorf("failed to load L1 head: %w", err) - } - l1Header, err := l1HeaderSource.HeaderByHash(ctx, l1Head) - if err != nil { - return eth.BlockID{}, fmt.Errorf("failed to load L1 header: %w", err) - } - return eth.HeaderBlockID(l1Header), nil -} diff --git a/op-challenger/game/fault/register_task_test.go b/op-challenger/game/fault/register_task_test.go index 4aa61860979..5eaeb15f458 100644 --- a/op-challenger/game/fault/register_task_test.go +++ b/op-challenger/game/fault/register_task_test.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/gameargs" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/registry" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/sources/batching" @@ -35,7 +35,7 @@ func TestRegisterOracle_MissingGameImpl(t *testing.T) { logger, logs := testlog.CaptureLogger(t, log.LvlInfo) oracles := registry.NewOracleRegistry() - gameType := faultTypes.CannonGameType + gameType := gameTypes.CannonGameType rpc.SetResponse(gameFactoryAddr, "gameImpls", rpcblock.Latest, []interface{}{gameType}, []interface{}{common.Address{}}) @@ -76,7 +76,7 @@ func TestRegisterOracle_AddsOracle(t *testing.T) { } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { - for _, gameType := range []faultTypes.GameType{faultTypes.CannonGameType, faultTypes.SuperCannonGameType, faultTypes.SuperAsteriscKonaGameType} { + for _, gameType := range []gameTypes.GameType{gameTypes.CannonGameType, gameTypes.SuperCannonGameType, gameTypes.SuperAsteriscKonaGameType} { t.Run(fmt.Sprintf("%v", gameType), func(t *testing.T) { gameFactoryAddr := common.Address{0xaa} gameImplAddr := common.Address{0xbb} @@ -84,9 +84,9 @@ func TestRegisterOracle_AddsOracle(t *testing.T) { oracleAddr := common.Address{0xdd} rpc := test.NewAbiBasedRpc(t, gameFactoryAddr, snapshots.LoadDisputeGameFactoryABI()) rpc.SetResponse(gameFactoryAddr, "version", rpcblock.Latest, nil, []interface{}{testCase.version}) - if gameType == faultTypes.CannonGameType { + if gameType == gameTypes.CannonGameType { rpc.AddContract(gameImplAddr, snapshots.LoadFaultDisputeGameABI()) - } else if gameType == faultTypes.SuperCannonGameType || gameType == faultTypes.SuperAsteriscKonaGameType { + } else if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperAsteriscKonaGameType { rpc.AddContract(gameImplAddr, snapshots.LoadSuperFaultDisputeGameABI()) } else { t.Fatalf("game type %v not supported", gameType) diff --git a/op-challenger/game/fault/sync.go b/op-challenger/game/fault/sync.go deleted file mode 100644 index badbca1bc40..00000000000 --- a/op-challenger/game/fault/sync.go +++ /dev/null @@ -1,34 +0,0 @@ -package fault - -import ( - "context" - "fmt" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/eth" -) - -type SyncStatusProvider interface { - SyncStatus(context.Context) (*eth.SyncStatus, error) -} - -type syncStatusValidator struct { - statusProvider SyncStatusProvider -} - -func newSyncStatusValidator(statusProvider SyncStatusProvider) *syncStatusValidator { - return &syncStatusValidator{ - statusProvider: statusProvider, - } -} - -func (s *syncStatusValidator) ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error { - syncStatus, err := s.statusProvider.SyncStatus(ctx) - if err != nil { - return fmt.Errorf("failed to retrieve local node sync status: %w", err) - } - if syncStatus.CurrentL1.Number <= gameL1Head.Number { - return fmt.Errorf("%w require L1 block above %v but at %v", types.ErrNotInSync, gameL1Head.Number, syncStatus.CurrentL1.Number) - } - return nil -} diff --git a/op-challenger/game/fault/trace/super/sync.go b/op-challenger/game/fault/trace/super/sync.go deleted file mode 100644 index ec7348c739b..00000000000 --- a/op-challenger/game/fault/trace/super/sync.go +++ /dev/null @@ -1,34 +0,0 @@ -package super - -import ( - "context" - "fmt" - - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" - "github.com/ethereum-optimism/optimism/op-service/eth" -) - -type SyncValidator struct { - syncStatusProvider SyncStatusProvider -} - -type SyncStatusProvider interface { - SyncStatus(ctx context.Context) (eth.SupervisorSyncStatus, error) -} - -func NewSyncValidator(syncStatusProvider SyncStatusProvider) *SyncValidator { - return &SyncValidator{ - syncStatusProvider: syncStatusProvider, - } -} - -func (s SyncValidator) ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error { - syncStatus, err := s.syncStatusProvider.SyncStatus(ctx) - if err != nil { - return fmt.Errorf("failed to retrieve sync status: %w", err) - } - if syncStatus.MinSyncedL1.Number <= gameL1Head.Number { - return fmt.Errorf("%w require L1 block above %v but at %v", types.ErrNotInSync, gameL1Head.Number, syncStatus.MinSyncedL1.Number) - } - return nil -} diff --git a/op-challenger/game/fault/trace/vm/executor.go b/op-challenger/game/fault/trace/vm/executor.go index 38fe3791c84..f6908b95bed 100644 --- a/op-challenger/game/fault/trace/vm/executor.go +++ b/op-challenger/game/fault/trace/vm/executor.go @@ -12,11 +12,11 @@ import ( "strings" "time" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/log" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-service/jsonutil" @@ -41,7 +41,7 @@ type Metricer = metrics.TypedVmMetricer type Config struct { // VM Configuration - VmType types.TraceType + VmType gameTypes.GameType VmBin string // Path to the vm executable to run when generating trace data SnapshotFreq uint // Frequency of snapshots to create when executing (in VM instructions) InfoFreq uint // Frequency of progress log messages (in VM instructions) diff --git a/op-challenger/game/fault/trace/vm/executor_test.go b/op-challenger/game/fault/trace/vm/executor_test.go index 55b7ab24037..d6bdf48fedd 100644 --- a/op-challenger/game/fault/trace/vm/executor_test.go +++ b/op-challenger/game/fault/trace/vm/executor_test.go @@ -27,7 +27,7 @@ func TestGenerateProof(t *testing.T) { tempDir := t.TempDir() dir := filepath.Join(tempDir, "gameDir") cfg := Config{ - VmType: "test", + VmType: 7248992, L1: "http://localhost:8888", L1Beacon: "http://localhost:9000", L2s: []string{"http://localhost:9999", "http://localhost:9999/two"}, diff --git a/op-challenger/game/fault/types/types.go b/op-challenger/game/fault/types/types.go index 51fe0cf9e13..04269b4b7c2 100644 --- a/op-challenger/game/fault/types/types.go +++ b/op-challenger/game/fault/types/types.go @@ -4,13 +4,10 @@ import ( "context" "encoding/binary" "errors" - "fmt" "math" "math/big" "time" - "slices" - preimage "github.com/ethereum-optimism/optimism/op-preimage" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/common" @@ -21,149 +18,8 @@ import ( var ( ErrGameDepthReached = errors.New("game depth reached") ErrL2BlockNumberValid = errors.New("l2 block number is valid") - ErrNotInSync = errors.New("local node too far behind") -) - -type GameType uint32 - -const ( - CannonGameType GameType = 0 - PermissionedGameType GameType = 1 - AsteriscGameType GameType = 2 - AsteriscKonaGameType GameType = 3 - SuperCannonGameType GameType = 4 - SuperPermissionedGameType GameType = 5 - OPSuccinctGameType GameType = 6 - SuperAsteriscKonaGameType GameType = 7 - CannonKonaGameType GameType = 8 - SuperCannonKonaGameType GameType = 9 - OptimisticZKGameType GameType = 10 - FastGameType GameType = 254 - AlphabetGameType GameType = 255 - KailuaGameType GameType = 1337 - UnknownGameType GameType = math.MaxUint32 -) - -func (t GameType) MarshalText() ([]byte, error) { - return []byte(t.String()), nil -} - -func (t GameType) String() string { - switch t { - case CannonGameType: - return "cannon" - case PermissionedGameType: - return "permissioned" - case AsteriscGameType: - return "asterisc" - case AsteriscKonaGameType: - return "asterisc-kona" - case SuperCannonGameType: - return "super-cannon" - case SuperPermissionedGameType: - return "super-permissioned" - case OPSuccinctGameType: - return "op-succinct" - case SuperAsteriscKonaGameType: - return "super-asterisc-kona" - case CannonKonaGameType: - return "cannon-kona" - case SuperCannonKonaGameType: - return "super-cannon-kona" - case OptimisticZKGameType: - return "optimistic-zk" - case FastGameType: - return "fast" - case AlphabetGameType: - return "alphabet" - case KailuaGameType: - return "kailua" - default: - return fmt.Sprintf("", t) - } -} - -type TraceType string - -const ( - TraceTypeAlphabet TraceType = "alphabet" - TraceTypeFast TraceType = "fast" - TraceTypeCannon TraceType = "cannon" - TraceTypeCannonKona TraceType = "cannon-kona" - TraceTypeAsterisc TraceType = "asterisc" - TraceTypeAsteriscKona TraceType = "asterisc-kona" - TraceTypePermissioned TraceType = "permissioned" - TraceTypeSuperCannon TraceType = "super-cannon" - TraceTypeSuperCannonKona TraceType = "super-cannon-kona" - TraceTypeSuperPermissioned TraceType = "super-permissioned" - TraceTypeSuperAsteriscKona TraceType = "super-asterisc-kona" ) -var TraceTypes = []TraceType{ - TraceTypeAlphabet, - TraceTypeCannon, - TraceTypeCannonKona, - TraceTypePermissioned, - TraceTypeAsterisc, - TraceTypeAsteriscKona, - TraceTypeFast, - TraceTypeSuperCannon, - TraceTypeSuperCannonKona, - TraceTypeSuperPermissioned, - TraceTypeSuperAsteriscKona, -} - -func (t TraceType) String() string { - return string(t) -} - -// Set implements the Set method required by the [cli.Generic] interface. -func (t *TraceType) Set(value string) error { - if !ValidTraceType(TraceType(value)) { - return fmt.Errorf("unknown trace type: %q", value) - } - *t = TraceType(value) - return nil -} - -func (t *TraceType) Clone() any { - cpy := *t - return &cpy -} - -func ValidTraceType(value TraceType) bool { - return slices.Contains(TraceTypes, value) -} - -func (t TraceType) GameType() GameType { - switch t { - case TraceTypeCannon: - return CannonGameType - case TraceTypeCannonKona: - return CannonKonaGameType - case TraceTypePermissioned: - return PermissionedGameType - case TraceTypeAsterisc: - return AsteriscGameType - case TraceTypeAsteriscKona: - return AsteriscKonaGameType - case TraceTypeFast: - return FastGameType - case TraceTypeAlphabet: - return AlphabetGameType - case TraceTypeSuperCannon: - return SuperCannonGameType - case TraceTypeSuperCannonKona: - return SuperCannonKonaGameType - case TraceTypeSuperPermissioned: - return SuperPermissionedGameType - case TraceTypeSuperAsteriscKona: - return SuperAsteriscKonaGameType - default: - return UnknownGameType - } -} - type ClockReader interface { Now() time.Time } diff --git a/op-challenger/game/fault/types/types_test.go b/op-challenger/game/fault/types/types_test.go index 01f63791e97..ca3e25b7e4b 100644 --- a/op-challenger/game/fault/types/types_test.go +++ b/op-challenger/game/fault/types/types_test.go @@ -60,21 +60,3 @@ func TestIsRootPosition(t *testing.T) { }) } } - -func TestKnownGameTypeForEveryTraceType(t *testing.T) { - for _, traceType := range TraceTypes { - traceType := traceType - t.Run(traceType.String(), func(t *testing.T) { - require.NotEqual(t, UnknownGameType, traceType.GameType()) - }) - } -} - -func TestKnownStringForUtilisedGameType(t *testing.T) { - for _, traceType := range TraceTypes { - traceType := traceType - t.Run(traceType.String(), func(t *testing.T) { - require.NotContains(t, traceType.GameType().String(), "invalid") - }) - } -} diff --git a/op-challenger/game/fault/player.go b/op-challenger/game/generic/player.go similarity index 51% rename from op-challenger/game/fault/player.go rename to op-challenger/game/generic/player.go index 7094696af2d..5545a51b709 100644 --- a/op-challenger/game/fault/player.go +++ b/op-challenger/game/generic/player.go @@ -1,36 +1,35 @@ -package fault +package generic import ( "context" "errors" "fmt" - "time" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" - "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/responder" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-challenger/game/client" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum-optimism/optimism/op-challenger/metrics" - "github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" ) -type actor func(ctx context.Context) error +type PrestateValidator interface { + Validate(ctx context.Context) error +} + +type Actor interface { + Act(ctx context.Context) error + AdditionalStatus(ctx context.Context) ([]any, error) +} -type GameInfo interface { +type GenericGameLoader interface { + GetL1Head(context.Context) (common.Hash, error) GetStatus(context.Context) (gameTypes.GameStatus, error) - GetClaimCount(context.Context) (uint64, error) } type SyncValidator interface { // ValidateNodeSynced checks that the local node is sufficiently up to date to play the game. - // It returns types.ErrNotInSync if the node is too far behind. + // It returns client.ErrNotInSync if the node is too far behind. ValidateNodeSynced(ctx context.Context, gameL1Head eth.BlockID) error } @@ -38,58 +37,32 @@ type L1HeaderSource interface { HeaderByHash(context.Context, common.Hash) (*gethTypes.Header, error) } -type TxSender interface { - From() common.Address - SendAndWaitSimple(txPurpose string, txs ...txmgr.TxCandidate) error -} +type ActorCreator func(ctx context.Context, logger log.Logger, l1Head eth.BlockID) (Actor, error) type GamePlayer struct { - act actor - loader GameInfo + actor Actor + loader GenericGameLoader logger log.Logger syncValidator SyncValidator - prestateValidators []Validator + prestateValidators []PrestateValidator status gameTypes.GameStatus gameL1Head eth.BlockID } -type GameContract interface { - preimages.PreimageGameContract - responder.GameContract - claims.BondContract - GameInfo - ClaimLoader - GetStatus(ctx context.Context) (gameTypes.GameStatus, error) - GetMaxGameDepth(ctx context.Context) (types.Depth, error) - GetMaxClockDuration(ctx context.Context) (time.Duration, error) - GetOracle(ctx context.Context) (contracts.PreimageOracleContract, error) - GetL1Head(ctx context.Context) (common.Hash, error) -} - -var actNoop = func(ctx context.Context) error { - return nil -} +type actNoop struct{} -type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth types.Depth, dir string) (types.TraceAccessor, error) +func (a *actNoop) Act(_ context.Context) error { return nil } +func (a *actNoop) AdditionalStatus(_ context.Context) ([]any, error) { return nil, nil } -func NewGamePlayer( +func NewGenericGamePlayer( ctx context.Context, - systemClock clock.Clock, - l1Clock types.ClockReader, logger log.Logger, - m metrics.Metricer, - dir string, addr common.Address, - txSender TxSender, - loader GameContract, + loader GenericGameLoader, syncValidator SyncValidator, - validators []Validator, - creator resourceCreator, + validators []PrestateValidator, l1HeaderSource L1HeaderSource, - selective bool, - claimants []common.Address, - responseDelay time.Duration, - responseDelayAfter uint64, + createActor ActorCreator, ) (*GamePlayer, error) { logger = logger.New("game", addr) @@ -106,30 +79,9 @@ func NewGamePlayer( prestateValidators: validators, status: status, // Act function does nothing because the game is already complete - act: actNoop, + actor: &actNoop{}, }, nil } - - maxClockDuration, err := loader.GetMaxClockDuration(ctx) - if err != nil { - return nil, fmt.Errorf("failed to fetch the game duration: %w", err) - } - - gameDepth, err := loader.GetMaxGameDepth(ctx) - if err != nil { - return nil, fmt.Errorf("failed to fetch the game depth: %w", err) - } - - accessor, err := creator(ctx, logger, gameDepth, dir) - if err != nil { - return nil, fmt.Errorf("failed to create trace accessor: %w", err) - } - - oracle, err := loader.GetOracle(ctx) - if err != nil { - return nil, fmt.Errorf("failed to load oracle: %w", err) - } - l1HeadHash, err := loader.GetL1Head(ctx) if err != nil { return nil, fmt.Errorf("failed to load game L1 head: %w", err) @@ -140,21 +92,13 @@ func NewGamePlayer( } l1Head := eth.HeaderBlockID(l1Header) - minLargePreimageSize, err := oracle.MinLargePreimageSize(ctx) - if err != nil { - return nil, fmt.Errorf("failed to load min large preimage size: %w", err) - } - direct := preimages.NewDirectPreimageUploader(logger, txSender, loader) - large := preimages.NewLargePreimageUploader(logger, l1Clock, txSender, oracle) - uploader := preimages.NewSplitPreimageUploader(direct, large, minLargePreimageSize) - responder, err := responder.NewFaultResponder(logger, txSender, loader, uploader, oracle) + actor, err := createActor(ctx, logger, l1Head) if err != nil { - return nil, fmt.Errorf("failed to create the responder: %w", err) + return nil, fmt.Errorf("failed to create actor: %w", err) } - agent := NewAgent(m, systemClock, l1Clock, loader, gameDepth, maxClockDuration, accessor, responder, logger, selective, claimants, responseDelay, responseDelayAfter) return &GamePlayer{ - act: agent.Act, + actor: actor, loader: loader, logger: logger, status: status, @@ -183,7 +127,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { g.logger.Trace("Skipping completed game") return g.status } - if err := g.syncValidator.ValidateNodeSynced(ctx, g.gameL1Head); errors.Is(err, types.ErrNotInSync) { + if err := g.syncValidator.ValidateNodeSynced(ctx, g.gameL1Head); errors.Is(err, client.ErrNotInSync) { g.logger.Warn("Local node not sufficiently up to date", "err", err) return g.status } else if err != nil { @@ -191,7 +135,7 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { return g.status } g.logger.Trace("Checking if actions are required") - if err := g.act(ctx); err != nil { + if err := g.actor.Act(ctx); err != nil { g.logger.Error("Error when acting on game", "err", err) } status, err := g.loader.GetStatus(ctx) @@ -203,19 +147,20 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) gameTypes.GameStatus { g.status = status if status != gameTypes.GameStatusInProgress { // Release the agent as we will no longer need to act on this game. - g.act = actNoop + g.actor = &actNoop{} } return status } func (g *GamePlayer) logGameStatus(ctx context.Context, status gameTypes.GameStatus) { if status == gameTypes.GameStatusInProgress { - claimCount, err := g.loader.GetClaimCount(ctx) + additionalStatus, err := g.actor.AdditionalStatus(ctx) if err != nil { - g.logger.Error("Failed to get claim count for in progress game", "err", err) + g.logger.Error("Failed to get additional status info for in progress game", "err", err) return } - g.logger.Info("Game info", "claims", claimCount, "status", status) + additionalStatus = append(additionalStatus, "status", g.status) + g.logger.Info("Game info", additionalStatus...) return } g.logger.Info("Game resolved", "status", status) diff --git a/op-challenger/game/fault/player_test.go b/op-challenger/game/generic/player_test.go similarity index 83% rename from op-challenger/game/fault/player_test.go rename to op-challenger/game/generic/player_test.go index 7c05525a882..ba3348e2c25 100644 --- a/op-challenger/game/fault/player_test.go +++ b/op-challenger/game/generic/player_test.go @@ -1,4 +1,4 @@ -package fault +package generic import ( "context" @@ -33,7 +33,7 @@ func TestProgressGame_LogErrorFromAct(t *testing.T) { msgFilter = testlog.NewMessageFilter("Game info") msg := handler.FindLog(levelFilter, msgFilter) require.NotNil(t, msg) - require.Equal(t, uint64(1), msg.AttrValue("claims")) + require.Equal(t, "statusValue", msg.AttrValue("extra")) } func TestProgressGame_LogGameStatus(t *testing.T) { @@ -93,7 +93,7 @@ func TestDoNotActOnCompleteGame(t *testing.T) { // Should have replaced the act function with a noop so callCount doesn't update even when called directly // This allows the agent resources to be GC'd - require.NoError(t, game.act(context.Background())) + require.NoError(t, game.actor.Act(context.Background())) require.Equal(t, 1, gameState.callCount) }) } @@ -113,27 +113,27 @@ func TestValidateLocalNodeSync(t *testing.T) { func TestValidatePrestate(t *testing.T) { tests := []struct { name string - validators []Validator + validators []PrestateValidator errors bool }{ { name: "SingleValidator", - validators: []Validator{&mockValidator{}}, + validators: []PrestateValidator{&mockValidator{}}, errors: false, }, { name: "MultipleValidators", - validators: []Validator{&mockValidator{}, &mockValidator{}}, + validators: []PrestateValidator{&mockValidator{}, &mockValidator{}}, errors: false, }, { name: "SingleValidator_Errors", - validators: []Validator{&mockValidator{true}}, + validators: []PrestateValidator{&mockValidator{true}}, errors: true, }, { name: "MultipleValidators_Errors", - validators: []Validator{&mockValidator{}, &mockValidator{true}}, + validators: []PrestateValidator{&mockValidator{}, &mockValidator{true}}, errors: true, }, } @@ -153,7 +153,7 @@ func TestValidatePrestate(t *testing.T) { } } -var _ Validator = (*mockValidator)(nil) +var _ PrestateValidator = (*mockValidator)(nil) type mockValidator struct { err bool @@ -171,7 +171,7 @@ func setupProgressGameTest(t *testing.T) (*testlog.CapturingHandler, *GamePlayer gameState := &stubGameState{claimCount: 1} syncValidator := &stubSyncValidator{} game := &GamePlayer{ - act: gameState.Act, + actor: gameState, loader: gameState, logger: logger, syncValidator: syncValidator, @@ -199,19 +199,27 @@ type stubGameState struct { Err error } -func (s *stubGameState) Act(ctx context.Context) error { +func (s *stubGameState) AdditionalStatus(_ context.Context) ([]any, error) { + return []any{"extra", "statusValue"}, nil +} + +func (s *stubGameState) Act(_ context.Context) error { s.callCount++ return s.actErr } -func (s *stubGameState) GetStatus(ctx context.Context) (types.GameStatus, error) { +func (s *stubGameState) GetL1Head(_ context.Context) (common.Hash, error) { + return common.Hash{0x1a}, nil +} + +func (s *stubGameState) GetStatus(_ context.Context) (types.GameStatus, error) { return s.status, nil } -func (s *stubGameState) GetClaimCount(ctx context.Context) (uint64, error) { +func (s *stubGameState) GetClaimCount(_ context.Context) (uint64, error) { return s.claimCount, nil } -func (s *stubGameState) GetAbsolutePrestateHash(ctx context.Context) (common.Hash, error) { +func (s *stubGameState) GetAbsolutePrestateHash(_ context.Context) (common.Hash, error) { return common.Hash{}, s.Err } diff --git a/op-challenger/game/registry/registry.go b/op-challenger/game/registry/registry.go index 3e016eb0d83..bf7dc255cfd 100644 --- a/op-challenger/game/registry/registry.go +++ b/op-challenger/game/registry/registry.go @@ -5,35 +5,34 @@ import ( "fmt" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" - "github.com/ethereum-optimism/optimism/op-challenger/game/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" ) var ErrUnsupportedGameType = errors.New("unsupported game type") type GameTypeRegistry struct { - types map[faultTypes.GameType]scheduler.PlayerCreator - bondCreators map[faultTypes.GameType]claims.BondContractCreator + types map[gameTypes.GameType]scheduler.PlayerCreator + bondCreators map[gameTypes.GameType]claims.BondContractCreator } func NewGameTypeRegistry() *GameTypeRegistry { return &GameTypeRegistry{ - types: make(map[faultTypes.GameType]scheduler.PlayerCreator), - bondCreators: make(map[faultTypes.GameType]claims.BondContractCreator), + types: make(map[gameTypes.GameType]scheduler.PlayerCreator), + bondCreators: make(map[gameTypes.GameType]claims.BondContractCreator), } } // RegisterGameType registers a scheduler.PlayerCreator to use for a specific game type. // Panics if the same game type is registered multiple times, since this indicates a significant programmer error. -func (r *GameTypeRegistry) RegisterGameType(gameType faultTypes.GameType, creator scheduler.PlayerCreator) { +func (r *GameTypeRegistry) RegisterGameType(gameType gameTypes.GameType, creator scheduler.PlayerCreator) { if _, ok := r.types[gameType]; ok { panic(fmt.Errorf("duplicate creator registered for game type: %v", gameType)) } r.types[gameType] = creator } -func (r *GameTypeRegistry) RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator) { +func (r *GameTypeRegistry) RegisterBondContract(gameType gameTypes.GameType, creator claims.BondContractCreator) { if _, ok := r.bondCreators[gameType]; ok { panic(fmt.Errorf("duplicate bond contract registered for game type: %v", gameType)) } @@ -41,16 +40,16 @@ func (r *GameTypeRegistry) RegisterBondContract(gameType faultTypes.GameType, cr } // CreatePlayer creates a new game player for the given game, using the specified directory for persisting data. -func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { - creator, ok := r.types[faultTypes.GameType(game.GameType)] +func (r *GameTypeRegistry) CreatePlayer(game gameTypes.GameMetadata, dir string) (scheduler.GamePlayer, error) { + creator, ok := r.types[gameTypes.GameType(game.GameType)] if !ok { return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType) } return creator(game, dir) } -func (r *GameTypeRegistry) CreateBondContract(game types.GameMetadata) (claims.BondContract, error) { - creator, ok := r.bondCreators[faultTypes.GameType(game.GameType)] +func (r *GameTypeRegistry) CreateBondContract(game gameTypes.GameMetadata) (claims.BondContract, error) { + creator, ok := r.bondCreators[gameTypes.GameType(game.GameType)] if !ok { return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType) } diff --git a/op-challenger/game/service.go b/op-challenger/game/service.go index 28f279d455b..eb7be17c098 100644 --- a/op-challenger/game/service.go +++ b/op-challenger/game/service.go @@ -7,6 +7,7 @@ import ( "io" "sync/atomic" + challengerClient "github.com/ethereum-optimism/optimism/op-challenger/game/client" "github.com/ethereum-optimism/optimism/op-challenger/game/keccak" "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/fetcher" "github.com/ethereum-optimism/optimism/op-challenger/sender" @@ -38,7 +39,7 @@ type Service struct { monitor *gameMonitor sched *scheduler.Scheduler - faultGamesCloser fault.CloseFunc + clientProvider *challengerClient.Provider preimages *keccak.LargePreimageScheduler @@ -211,9 +212,8 @@ func (s *Service) initBondClaims() error { func (s *Service) registerGameTypes(ctx context.Context, cfg *config.Config) error { gameTypeRegistry := registry.NewGameTypeRegistry() oracles := registry.NewOracleRegistry() - caller := batching.NewMultiCaller(s.l1Client.Client(), batching.DefaultBatchSize) - closer, err := fault.RegisterGameTypes(ctx, s.systemClock, s.l1Clock, s.logger, s.metrics, cfg, gameTypeRegistry, oracles, s.txSender, s.factoryContract, caller, s.l1Client, cfg.SelectiveClaimResolution, s.claimants) - s.faultGamesCloser = closer + s.clientProvider = challengerClient.NewProvider(ctx, s.logger, cfg, s.l1Client) + err := fault.RegisterGameTypes(ctx, s.systemClock, s.l1Clock, s.logger, s.metrics, cfg, gameTypeRegistry, oracles, s.txSender, s.factoryContract, s.clientProvider, cfg.SelectiveClaimResolution, s.claimants) if err != nil { return err } @@ -272,8 +272,8 @@ func (s *Service) Stop(ctx context.Context) error { result = errors.Join(result, fmt.Errorf("failed to close claimer: %w", err)) } } - if s.faultGamesCloser != nil { - s.faultGamesCloser() + if s.clientProvider != nil { + s.clientProvider.Close() } if s.pprofService != nil { if err := s.pprofService.Stop(ctx); err != nil { diff --git a/op-challenger/game/types/game_type.go b/op-challenger/game/types/game_type.go new file mode 100644 index 00000000000..aec84d80aa0 --- /dev/null +++ b/op-challenger/game/types/game_type.go @@ -0,0 +1,108 @@ +package types + +import ( + "errors" + "fmt" + "math" +) + +var ErrUnknownGameType = errors.New("unknown game type") + +type GameType uint32 + +const ( + CannonGameType GameType = 0 + PermissionedGameType GameType = 1 + AsteriscGameType GameType = 2 + AsteriscKonaGameType GameType = 3 + SuperCannonGameType GameType = 4 + SuperPermissionedGameType GameType = 5 + OPSuccinctGameType GameType = 6 // Not supported by op-challenger + SuperAsteriscKonaGameType GameType = 7 + CannonKonaGameType GameType = 8 + SuperCannonKonaGameType GameType = 9 + OptimisticZKGameType GameType = 10 // Not (yet) supported by op-challenger + FastGameType GameType = 254 + AlphabetGameType GameType = 255 + KailuaGameType GameType = 1337 // Not supported by op-challenger + UnknownGameType GameType = math.MaxUint32 // Not supported by op-challenger +) + +// SupportedGameTypes is the list of game types that are supported by op-challenger. +// Game type codes may be reserved that are not supported by op-challenger. +var SupportedGameTypes = []GameType{ + AlphabetGameType, + CannonGameType, + CannonKonaGameType, + PermissionedGameType, + AsteriscGameType, + AsteriscKonaGameType, + FastGameType, + SuperCannonGameType, + SuperCannonKonaGameType, + SuperPermissionedGameType, + SuperAsteriscKonaGameType, +} + +// Set implements the Set method required by the [cli.Generic] interface. +func (g *GameType) Set(value string) error { + gameType, err := SupportedGameTypeFromString(value) + if err != nil { + return err + } + *g = gameType + return nil +} + +func SupportedGameTypeFromString(s string) (GameType, error) { + for _, candidate := range SupportedGameTypes { + if candidate.String() == s { + return candidate, nil + } + } + return UnknownGameType, fmt.Errorf("%w: %q", ErrUnknownGameType, s) +} + +func (t *GameType) Clone() any { + cpy := *t + return &cpy +} + +func (g GameType) MarshalText() ([]byte, error) { + return []byte(g.String()), nil +} + +func (g GameType) String() string { + switch g { + case CannonGameType: + return "cannon" + case PermissionedGameType: + return "permissioned" + case AsteriscGameType: + return "asterisc" + case AsteriscKonaGameType: + return "asterisc-kona" + case SuperCannonGameType: + return "super-cannon" + case SuperPermissionedGameType: + return "super-permissioned" + case OPSuccinctGameType: + return "op-succinct" + case SuperAsteriscKonaGameType: + return "super-asterisc-kona" + case CannonKonaGameType: + return "cannon-kona" + case SuperCannonKonaGameType: + return "super-cannon-kona" + case OptimisticZKGameType: + return "optimistic-zk" + case FastGameType: + return "fast" + case AlphabetGameType: + return "alphabet" + case KailuaGameType: + return "kailua" + default: + return fmt.Sprintf("", g) + } +} diff --git a/op-challenger/game/types/game_type_test.go b/op-challenger/game/types/game_type_test.go new file mode 100644 index 00000000000..a3631d71fb2 --- /dev/null +++ b/op-challenger/game/types/game_type_test.go @@ -0,0 +1,43 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSetAllSupportedGameTypes(t *testing.T) { + for _, gameType := range SupportedGameTypes { + t.Run(gameType.String(), func(t *testing.T) { + result := new(GameType) + err := result.Set(gameType.String()) + require.NoError(t, err, "failed to set game type") + + require.Equal(t, gameType, *result) + }) + } +} + +func TestGameTypeFromStringForAllSupportedGameTypes(t *testing.T) { + for _, gameType := range SupportedGameTypes { + t.Run(gameType.String(), func(t *testing.T) { + result, err := SupportedGameTypeFromString(gameType.String()) + require.NoError(t, err, "failed to get game type from string") + + require.Equal(t, gameType, result) + }) + } +} + +func TestKnownStringForAllSupportedGameTypes(t *testing.T) { + for _, gameType := range SupportedGameTypes { + t.Run(gameType.String(), func(t *testing.T) { + require.NotContains(t, gameType.String(), "invalid") + }) + } + + t.Run("UnknownGameTypeStringContainsInvalid", func(t *testing.T) { + // Check that the test above would detect if we hit the unknown case + require.Contains(t, GameType(4829482).String(), "invalid") + }) +} diff --git a/op-challenger/runner/factory.go b/op-challenger/runner/factory.go index b5ace96147d..68e71d3427c 100644 --- a/op-challenger/runner/factory.go +++ b/op-challenger/runner/factory.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum/go-ethereum/log" ) @@ -24,12 +25,12 @@ func createTraceProvider( m vm.Metricer, cfg *config.Config, prestateSource prestateFetcher, - traceType types.TraceType, + gameType gameTypes.GameType, localInputs utils.LocalGameInputs, dir string, ) (types.TraceProvider, error) { - switch traceType { - case types.TraceTypeCannon, types.TraceTypeSuperCannon: + switch gameType { + case gameTypes.CannonGameType, gameTypes.SuperCannonGameType: serverExecutor := vm.NewOpProgramServerExecutor(logger) stateConverter := cannon.NewStateConverter(cfg.Cannon) prestate, err := prestateSource.getPrestate(ctx, logger, cfg.CannonAbsolutePreStateBaseURL, cfg.CannonAbsolutePreState, dir, stateConverter) @@ -38,7 +39,7 @@ func createTraceProvider( } prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return cannon.NewTraceProvider(logger, m, cfg.Cannon, serverExecutor, prestateProvider, prestate, localInputs, dir, 42), nil - case types.TraceTypeCannonKona, types.TraceTypeSuperCannonKona: + case gameTypes.CannonKonaGameType, gameTypes.SuperCannonKonaGameType: serverExecutor := vm.NewKonaExecutor() stateConverter := cannon.NewStateConverter(cfg.CannonKona) prestate, err := prestateSource.getPrestate(ctx, logger, cfg.CannonKonaAbsolutePreStateBaseURL, cfg.CannonKonaAbsolutePreState, dir, stateConverter) @@ -47,7 +48,7 @@ func createTraceProvider( } prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return cannon.NewTraceProvider(logger, m, cfg.CannonKona, serverExecutor, prestateProvider, prestate, localInputs, dir, 42), nil - case types.TraceTypeAsterisc: + case gameTypes.AsteriscGameType: serverExecutor := vm.NewOpProgramServerExecutor(logger) stateConverter := asterisc.NewStateConverter(cfg.Asterisc) prestate, err := prestateSource.getPrestate(ctx, logger, cfg.AsteriscAbsolutePreStateBaseURL, cfg.AsteriscAbsolutePreState, dir, stateConverter) @@ -56,7 +57,7 @@ func createTraceProvider( } prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.Asterisc, serverExecutor, prestateProvider, prestate, localInputs, dir, 42), nil - case types.TraceTypeAsteriscKona: + case gameTypes.AsteriscKonaGameType: serverExecutor := vm.NewKonaExecutor() stateConverter := asterisc.NewStateConverter(cfg.AsteriscKona) prestate, err := prestateSource.getPrestate(ctx, logger, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir, stateConverter) @@ -65,7 +66,7 @@ func createTraceProvider( } prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.AsteriscKona, serverExecutor, prestateProvider, prestate, localInputs, dir, 42), nil - case types.TraceTypeSuperAsteriscKona: + case gameTypes.SuperAsteriscKonaGameType: serverExecutor := vm.NewKonaSuperExecutor() stateConverter := asterisc.NewStateConverter(cfg.AsteriscKona) prestate, err := prestateSource.getPrestate(ctx, logger, cfg.AsteriscKonaAbsolutePreStateBaseURL, cfg.AsteriscKonaAbsolutePreState, dir, stateConverter) @@ -75,5 +76,5 @@ func createTraceProvider( prestateProvider := vm.NewPrestateProvider(prestate, stateConverter) return asterisc.NewTraceProvider(logger, m, cfg.AsteriscKona, serverExecutor, prestateProvider, prestate, localInputs, dir, 42), nil } - return nil, errors.New("invalid trace type") + return nil, errors.New("invalid game type") } diff --git a/op-challenger/runner/game_inputs.go b/op-challenger/runner/game_inputs.go index a17126469d4..2814ec5e48e 100644 --- a/op-challenger/runner/game_inputs.go +++ b/op-challenger/runner/game_inputs.go @@ -10,21 +10,22 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/super" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" ) -func createGameInputs(ctx context.Context, log log.Logger, rollupClient *sources.RollupClient, supervisorClient *sources.SupervisorClient, typeName string, traceType types.TraceType) (utils.LocalGameInputs, error) { - switch traceType { - case types.TraceTypeSuperCannon, types.TraceTypeSuperPermissioned, types.TraceTypeSuperAsteriscKona, types.TraceTypeSuperCannonKona: +func createGameInputs(ctx context.Context, log log.Logger, rollupClient *sources.RollupClient, supervisorClient *sources.SupervisorClient, typeName string, gameType gameTypes.GameType) (utils.LocalGameInputs, error) { + switch gameType { + case gameTypes.SuperCannonGameType, gameTypes.SuperPermissionedGameType, gameTypes.SuperAsteriscKonaGameType, gameTypes.SuperCannonKonaGameType: if supervisorClient == nil { - return utils.LocalGameInputs{}, fmt.Errorf("trace type %s requires supervisor rpc to be set", traceType) + return utils.LocalGameInputs{}, fmt.Errorf("game type %s requires supervisor rpc to be set", gameType) } return createGameInputsInterop(ctx, log, supervisorClient, typeName) default: if rollupClient == nil { - return utils.LocalGameInputs{}, fmt.Errorf("trace type %s requires rollup rpc to be set", traceType) + return utils.LocalGameInputs{}, fmt.Errorf("game type %s requires rollup rpc to be set", gameType) } return createGameInputsSingle(ctx, log, rollupClient, typeName) } diff --git a/op-challenger/runner/prestates.go b/op-challenger/runner/prestates.go index ffd8203645e..ecd5746cbc9 100644 --- a/op-challenger/runner/prestates.go +++ b/op-challenger/runner/prestates.go @@ -14,7 +14,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/prestates" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -23,7 +23,7 @@ import ( type OnChainPrestateFetcher struct { m metrics.ContractMetricer gameFactoryAddress common.Address - gameType types.GameType + gameType gameTypes.GameType caller *batching.MultiCaller } diff --git a/op-challenger/runner/runner.go b/op-challenger/runner/runner.go index 53ef8bcfc20..796a9da1897 100644 --- a/op-challenger/runner/runner.go +++ b/op-challenger/runner/runner.go @@ -15,6 +15,7 @@ import ( "sync/atomic" "time" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" @@ -49,7 +50,7 @@ type Metricer interface { } type RunConfig struct { - TraceType types.TraceType + GameType gameTypes.GameType Name string Prestate common.Hash PrestateFilename string @@ -138,44 +139,44 @@ func (r *Runner) loop(ctx context.Context, runConfig RunConfig, rollupClient *so } func (r *Runner) runAndRecordOnce(ctx context.Context, rlog log.Logger, runConfig RunConfig, rollupClient *sources.RollupClient, supervisorClient *sources.SupervisorClient, caller *batching.MultiCaller) { - recordError := func(err error, traceType string, m Metricer, log log.Logger) { + recordError := func(err error, configName string, m Metricer, log log.Logger) { if errors.Is(err, ErrUnexpectedStatusCode) { log.Error("Incorrect status code", "type", runConfig.Name, "err", err) - m.RecordInvalid(traceType) + m.RecordInvalid(configName) } else if errors.Is(err, trace.ErrVMPanic) { log.Error("VM panicked", "type", runConfig.Name) - m.RecordPanic(traceType) + m.RecordPanic(configName) } else if err != nil { log.Error("Failed to run", "type", runConfig.Name, "err", err) - m.RecordFailure(traceType) + m.RecordFailure(configName) } else { log.Info("Successfully verified output root", "type", runConfig.Name) - m.RecordSuccess(traceType) + m.RecordSuccess(configName) } } var prestateSource prestateFetcher if strings.HasPrefix(runConfig.PrestateFilename, "file:") { path := runConfig.PrestateFilename[len("file:"):] - rlog.Info("Using local file prestate", "type", runConfig.TraceType, "path", path) + rlog.Info("Using local file prestate", "type", runConfig.GameType, "path", path) prestateSource = &LocalPrestateFetcher{path: path} } else if runConfig.PrestateFilename != "" { - rlog.Info("Using named prestate", "type", runConfig.TraceType, "filename", runConfig.PrestateFilename) + rlog.Info("Using named prestate", "type", runConfig.GameType, "filename", runConfig.PrestateFilename) prestateSource = &NamedPrestateFetcher{filename: runConfig.PrestateFilename} } else if runConfig.Prestate == (common.Hash{}) { - rlog.Info("Using on chain prestate", "type", runConfig.TraceType) + rlog.Info("Using on chain prestate", "type", runConfig.GameType) prestateSource = &OnChainPrestateFetcher{ m: r.m, gameFactoryAddress: r.cfg.GameFactoryAddress, - gameType: runConfig.TraceType.GameType(), + gameType: runConfig.GameType, caller: caller, } } else { - rlog.Info("Using specific prestate", "type", runConfig.TraceType, "hash", runConfig.Prestate) + rlog.Info("Using specific prestate", "type", runConfig.GameType, "hash", runConfig.Prestate) prestateSource = &HashPrestateFetcher{prestateHash: runConfig.Prestate} } - localInputs, err := createGameInputs(ctx, rlog, rollupClient, supervisorClient, runConfig.Name, runConfig.TraceType) + localInputs, err := createGameInputs(ctx, rlog, rollupClient, supervisorClient, runConfig.Name, runConfig.GameType) if err != nil { recordError(err, runConfig.Name, r.m, rlog) return @@ -189,12 +190,12 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, rlog log.Logger, runConfi recordError(err, runConfig.Name, r.m, rlog) return } - err = r.runOnce(ctx, inputsLogger.With("type", runConfig.Name), runConfig.Name, runConfig.TraceType, prestateSource, localInputs, dir) + err = r.runOnce(ctx, inputsLogger.With("type", runConfig.Name), runConfig.Name, runConfig.GameType, prestateSource, localInputs, dir) recordError(err, runConfig.Name, r.m, rlog) } -func (r *Runner) runOnce(ctx context.Context, logger log.Logger, name string, traceType types.TraceType, prestateSource prestateFetcher, localInputs utils.LocalGameInputs, dir string) error { - provider, err := createTraceProvider(ctx, logger, metrics.NewTypedVmMetrics(r.m, name), r.cfg, prestateSource, traceType, localInputs, dir) +func (r *Runner) runOnce(ctx context.Context, logger log.Logger, name string, gameType gameTypes.GameType, prestateSource prestateFetcher, localInputs utils.LocalGameInputs, dir string) error { + provider, err := createTraceProvider(ctx, logger, metrics.NewTypedVmMetrics(r.m, name), r.cfg, prestateSource, gameType, localInputs, dir) if err != nil { return fmt.Errorf("failed to create trace provider: %w", err) } diff --git a/op-challenger/tools/create_game.go b/op-challenger/tools/create_game.go index 4453a195e1d..74ef1a846a4 100644 --- a/op-challenger/tools/create_game.go +++ b/op-challenger/tools/create_game.go @@ -22,8 +22,8 @@ func NewGameCreator(contract *contracts.DisputeGameFactoryContract, txMgr txmgr. } } -func (g *GameCreator) CreateGame(ctx context.Context, outputRoot common.Hash, traceType uint64, l2BlockNum uint64) (common.Address, error) { - txCandidate, err := g.contract.CreateTx(ctx, uint32(traceType), outputRoot, l2BlockNum) +func (g *GameCreator) CreateGame(ctx context.Context, outputRoot common.Hash, gameType uint64, l2BlockNum uint64) (common.Address, error) { + txCandidate, err := g.contract.CreateTx(ctx, uint32(gameType), outputRoot, l2BlockNum) if err != nil { return common.Address{}, fmt.Errorf("failed to create tx: %w", err) } diff --git a/op-deployer/pkg/deployer/pipeline/dispute_games.go b/op-deployer/pkg/deployer/pipeline/dispute_games.go index 2a0c2ecd4aa..8a6850e5328 100644 --- a/op-deployer/pkg/deployer/pipeline/dispute_games.go +++ b/op-deployer/pkg/deployer/pipeline/dispute_games.go @@ -5,7 +5,7 @@ import ( "math/big" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/gameargs" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state" "github.com/ethereum-optimism/optimism/op-service/eth" @@ -101,7 +101,7 @@ func deployDisputeGame( Proposer: thisIntent.Roles.Proposer, Challenger: thisIntent.Roles.Challenger, } - if game.DisputeGameType == uint32(types.PermissionedGameType) { + if game.DisputeGameType == uint32(gameTypes.PermissionedGameType) { gameArgs = args.PackPermissioned() } else { gameArgs = args.PackPermissionless() diff --git a/op-devstack/dsl/proofs/dispute_game_factory.go b/op-devstack/dsl/proofs/dispute_game_factory.go index 75135df20e0..d8247b4c1d5 100644 --- a/op-devstack/dsl/proofs/dispute_game_factory.go +++ b/op-devstack/dsl/proofs/dispute_game_factory.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/prestates" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-service/eth" safetyTypes "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" @@ -150,13 +151,13 @@ func (f *DisputeGameFactory) GameAtIndex(idx int64) *FaultDisputeGame { return NewFaultDisputeGame(f.t, f.require, gameInfo.Proxy, f.getGameHelper, f.honestTraceForGame, game) } -func (f *DisputeGameFactory) GameImpl(gameType challengerTypes.GameType) *FaultDisputeGame { +func (f *DisputeGameFactory) GameImpl(gameType gameTypes.GameType) *FaultDisputeGame { implAddr := contract.Read(f.dgf.GameImpls(uint32(gameType))) game := bindings.NewFaultDisputeGame(bindings.WithClient(f.ethClient), bindings.WithTo(implAddr), bindings.WithTest(f.t)) return NewFaultDisputeGame(f.t, f.require, implAddr, f.getGameHelper, f.honestTraceForGame, game) } -func (f *DisputeGameFactory) GameArgs(gameType challengerTypes.GameType) []byte { +func (f *DisputeGameFactory) GameArgs(gameType gameTypes.GameType) []byte { return contract.Read(f.dgf.GameArgs(uint32(gameType))) } @@ -175,10 +176,10 @@ func (f *DisputeGameFactory) WaitForGame() *FaultDisputeGame { func (f *DisputeGameFactory) StartSuperCannonGame(eoa *dsl.EOA, opts ...GameOpt) *SuperFaultDisputeGame { f.require.NotNil(f.supervisor, "supervisor is required to start super games") - return f.startSuperCannonGameOfType(eoa, challengerTypes.SuperCannonGameType, opts...) + return f.startSuperCannonGameOfType(eoa, gameTypes.SuperCannonGameType, opts...) } -func (f *DisputeGameFactory) startSuperCannonGameOfType(eoa *dsl.EOA, gameType challengerTypes.GameType, opts ...GameOpt) *SuperFaultDisputeGame { +func (f *DisputeGameFactory) startSuperCannonGameOfType(eoa *dsl.EOA, gameType gameTypes.GameType, opts ...GameOpt) *SuperFaultDisputeGame { cfg := NewGameCfg(opts...) timestamp := cfg.l2SequenceNumber if !cfg.l2SequenceNumberSet { @@ -207,11 +208,11 @@ func (f *DisputeGameFactory) createSuperGameExtraData(timestamp uint64, cfg *Gam } func (f *DisputeGameFactory) StartCannonGame(eoa *dsl.EOA, opts ...GameOpt) *FaultDisputeGame { - return f.startOutputRootGameOfType(eoa, challengerTypes.CannonGameType, f.honestTraceForGame, opts...) + return f.startOutputRootGameOfType(eoa, gameTypes.CannonGameType, f.honestTraceForGame, opts...) } func (f *DisputeGameFactory) StartCannonKonaGame(eoa *dsl.EOA, opts ...GameOpt) *FaultDisputeGame { - return f.startOutputRootGameOfType(eoa, challengerTypes.CannonKonaGameType, f.honestTraceForGame, opts...) + return f.startOutputRootGameOfType(eoa, gameTypes.CannonKonaGameType, f.honestTraceForGame, opts...) } func (f *DisputeGameFactory) honestTraceForGame(game *FaultDisputeGame) challengerTypes.TraceAccessor { @@ -220,7 +221,7 @@ func (f *DisputeGameFactory) honestTraceForGame(game *FaultDisputeGame) challeng } f.require.NotNil(f.challengerCfg, "Challenger config is required to create honest trace") switch game.GameType() { - case challengerTypes.CannonGameType: + case gameTypes.CannonGameType: return f.honestOutputCannonTrace( game, f.challengerCfg.CannonAbsolutePreStateBaseURL, @@ -228,7 +229,7 @@ func (f *DisputeGameFactory) honestTraceForGame(game *FaultDisputeGame) challeng f.challengerCfg.Cannon, vm.NewOpProgramServerExecutor(f.log), ) - case challengerTypes.CannonKonaGameType: + case gameTypes.CannonKonaGameType: return f.honestOutputCannonTrace( game, f.challengerCfg.CannonKonaAbsolutePreStateBaseURL, @@ -288,7 +289,7 @@ func (f *DisputeGameFactory) honestOutputCannonTrace( func (f *DisputeGameFactory) startOutputRootGameOfType( eoa *dsl.EOA, - gameType challengerTypes.GameType, + gameType gameTypes.GameType, honestTraceProvider func(game *FaultDisputeGame) challengerTypes.TraceAccessor, opts ...GameOpt) *FaultDisputeGame { cfg := NewGameCfg(opts...) @@ -318,7 +319,7 @@ func (f *DisputeGameFactory) createOutputGameExtraData(blockNum uint64, cfg *Gam return extraData } -func (f *DisputeGameFactory) createNewGame(eoa *dsl.EOA, gameType challengerTypes.GameType, claim common.Hash, extraData []byte) (*bindings.FaultDisputeGame, common.Address) { +func (f *DisputeGameFactory) createNewGame(eoa *dsl.EOA, gameType gameTypes.GameType, claim common.Hash, extraData []byte) (*bindings.FaultDisputeGame, common.Address) { f.log.Info("Creating dispute game", "gameType", gameType, "claim", claim.Hex(), "extradata", common.Bytes2Hex(extraData)) // Pull some metadata we need to construct a new game @@ -337,7 +338,7 @@ func (f *DisputeGameFactory) createNewGame(eoa *dsl.EOA, gameType challengerType return bindings.NewFaultDisputeGame(bindings.WithClient(f.ethClient), bindings.WithTo(gameAddr), bindings.WithTest(f.t)), gameAddr } -func (f *DisputeGameFactory) initBond(gameType challengerTypes.GameType) eth.ETH { +func (f *DisputeGameFactory) initBond(gameType gameTypes.GameType) eth.ETH { return eth.WeiBig(contract.Read(f.dgf.InitBonds(uint32(gameType)))) } diff --git a/op-devstack/dsl/proofs/fault_dispute_game.go b/op-devstack/dsl/proofs/fault_dispute_game.go index d95a2211f48..01ecd7d2c3a 100644 --- a/op-devstack/dsl/proofs/fault_dispute_game.go +++ b/op-devstack/dsl/proofs/fault_dispute_game.go @@ -53,8 +53,8 @@ func NewFaultDisputeGame( return fdg } -func (g *FaultDisputeGame) GameType() challengerTypes.GameType { - return challengerTypes.GameType(contract.Read(g.game.GameType())) +func (g *FaultDisputeGame) GameType() gameTypes.GameType { + return gameTypes.GameType(contract.Read(g.game.GameType())) } func (g *FaultDisputeGame) MaxDepth() challengerTypes.Depth { diff --git a/op-devstack/dsl/proofs/game_helper.go b/op-devstack/dsl/proofs/game_helper.go index 76e60dc2408..095337e0ea4 100644 --- a/op-devstack/dsl/proofs/game_helper.go +++ b/op-devstack/dsl/proofs/game_helper.go @@ -9,6 +9,7 @@ import ( "path/filepath" challengerTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -138,7 +139,7 @@ func (gs *GameHelper) AuthEOA(eoa *dsl.EOA) *GameHelper { func (gs *GameHelper) CreateGameWithClaims( eoa *dsl.EOA, factory *DisputeGameFactory, - gameType challengerTypes.GameType, + gameType gameTypes.GameType, rootClaim common.Hash, extraData []byte, moves []GameHelperMove, diff --git a/op-devstack/presets/proof.go b/op-devstack/presets/proof.go index ae258ef0410..c40c855e022 100644 --- a/op-devstack/presets/proof.go +++ b/op-devstack/presets/proof.go @@ -1,7 +1,7 @@ package presets import ( - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-devstack/dsl/contract" "github.com/ethereum-optimism/optimism/op-devstack/stack" "github.com/ethereum-optimism/optimism/op-devstack/stack/match" @@ -11,7 +11,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/txintent/contractio" ) -func WithRespectedGameType(gameType faultTypes.GameType) stack.CommonOption { +func WithRespectedGameType(gameType gameTypes.GameType) stack.CommonOption { opts := WithProposerGameType(gameType) opts = stack.Combine(opts, stack.MakeCommon(sysgo.WithRespectedGameType(gameType)), // Set if sysgo is in use @@ -20,13 +20,13 @@ func WithRespectedGameType(gameType faultTypes.GameType) stack.CommonOption { return opts } -func WithAddedGameType(gameType faultTypes.GameType) stack.CommonOption { +func WithAddedGameType(gameType gameTypes.GameType) stack.CommonOption { opts := stack.Combine( stack.MakeCommon(sysgo.WithGameTypeAdded(gameType)), // Add if sysgo is in use RequireGameTypePresent(gameType), // Verify present for other chains ) - if gameType == faultTypes.CannonKonaGameType { + if gameType == gameTypes.CannonKonaGameType { opts = stack.Combine( opts, WithCannonKonaFeatureEnabled(), @@ -36,7 +36,7 @@ func WithAddedGameType(gameType faultTypes.GameType) stack.CommonOption { return opts } -func RequireGameTypePresent(gameType faultTypes.GameType) stack.CommonOption { +func RequireGameTypePresent(gameType gameTypes.GameType) stack.CommonOption { return stack.FnOption[stack.Orchestrator]{ PostHydrateFn: func(sys stack.System) { elNode := sys.L1Network(match.FirstL1Network).L1ELNode(match.FirstL1EL) @@ -53,7 +53,7 @@ func RequireGameTypePresent(gameType faultTypes.GameType) stack.CommonOption { } } -func RequireRespectedGameType(gameType faultTypes.GameType) stack.CommonOption { +func RequireRespectedGameType(gameType gameTypes.GameType) stack.CommonOption { return stack.FnOption[stack.Orchestrator]{ PostHydrateFn: func(sys stack.System) { @@ -73,7 +73,7 @@ func RequireRespectedGameType(gameType faultTypes.GameType) stack.CommonOption { } } -func WithProposerGameType(gameType faultTypes.GameType) stack.CommonOption { +func WithProposerGameType(gameType gameTypes.GameType) stack.CommonOption { return stack.Combine( stack.MakeCommon( sysgo.WithProposerOption(func(id stack.L2ProposerID, cfg *ps.CLIConfig) { diff --git a/op-devstack/shared/challenger/challenger.go b/op-devstack/shared/challenger/challenger.go index 806f31ac881..2b0fa928834 100644 --- a/op-devstack/shared/challenger/challenger.go +++ b/op-devstack/shared/challenger/challenger.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/crypto" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/depset" @@ -153,44 +153,44 @@ func WithCannonKonaConfig(rollupCfgs []*rollup.Config, l1Genesis *core.Genesis, } } -func WithCannonTraceType() Option { +func WithCannonGameType() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeCannon) + c.GameTypes = append(c.GameTypes, gameTypes.CannonGameType) return nil } } -func WithCannonKonaTraceType() Option { +func WithCannonKonaGameType() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeCannonKona) + c.GameTypes = append(c.GameTypes, gameTypes.CannonKonaGameType) return nil } } -func WithPermissionedTraceType() Option { +func WithPermissionedGameType() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypePermissioned) + c.GameTypes = append(c.GameTypes, gameTypes.PermissionedGameType) return nil } } -func WithSuperCannonTraceType() Option { +func WithSuperCannonGameType() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeSuperCannon) + c.GameTypes = append(c.GameTypes, gameTypes.SuperCannonGameType) return nil } } -func WithSuperPermissionedTraceType() Option { +func WithSuperPermissionedGameType() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeSuperPermissioned) + c.GameTypes = append(c.GameTypes, gameTypes.SuperPermissionedGameType) return nil } } func WithFastGames() Option { return func(c *config.Config) error { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeFast) + c.GameTypes = append(c.GameTypes, gameTypes.FastGameType) return nil } } diff --git a/op-devstack/sysgo/add_game_type.go b/op-devstack/sysgo/add_game_type.go index 8dfd5e7ff67..63d674d1d5d 100644 --- a/op-devstack/sysgo/add_game_type.go +++ b/op-devstack/sysgo/add_game_type.go @@ -8,7 +8,7 @@ import ( "runtime" "github.com/ethereum-optimism/optimism/op-chain-ops/devkeys" - "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/manage" "github.com/ethereum-optimism/optimism/op-devstack/devtest" @@ -28,8 +28,8 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -func WithGameTypeAdded(gameType types.GameType) stack.Option[*Orchestrator] { - if gameType == types.PermissionedGameType { +func WithGameTypeAdded(gameType gameTypes.GameType) stack.Option[*Orchestrator] { + if gameType == gameTypes.PermissionedGameType { // Permissioned games are added as part of the initial deployment // so no action required. return stack.Combine[*Orchestrator]() @@ -45,7 +45,7 @@ func WithGameTypeAdded(gameType types.GameType) stack.Option[*Orchestrator] { return opts } -func WithRespectedGameType(gameType types.GameType) stack.Option[*Orchestrator] { +func WithRespectedGameType(gameType gameTypes.GameType) stack.Option[*Orchestrator] { return stack.FnOption[*Orchestrator]{ FinallyFn: func(o *Orchestrator) { for _, l2ChainID := range o.l2Nets.Keys() { @@ -60,7 +60,7 @@ func WithCannonGameTypeAdded(l1ELID stack.L1ELNodeID, l2ChainID eth.ChainID) sta FinallyFn: func(o *Orchestrator) { // TODO(#17867): Rebuild the op-program prestate using the newly minted L2 chain configs before using it. absolutePrestate := getAbsolutePrestate(o.P(), "op-program/bin/prestate-proof-mt64.json") - addGameType(o, absolutePrestate, types.CannonGameType, l1ELID, l2ChainID) + addGameType(o, absolutePrestate, gameTypes.CannonGameType, l1ELID, l2ChainID) }, } } @@ -73,7 +73,7 @@ func WithCannonKonaGameTypeAdded() stack.Option[*Orchestrator] { FinallyFn: func(o *Orchestrator) { absolutePrestate := getCannonKonaAbsolutePrestate(o.P()) for _, l2ChainID := range o.l2Nets.Keys() { - addGameType(o, absolutePrestate, types.CannonKonaGameType, o.l1ELs.Keys()[0], l2ChainID) + addGameType(o, absolutePrestate, gameTypes.CannonKonaGameType, o.l1ELs.Keys()[0], l2ChainID) } }, } @@ -87,7 +87,7 @@ func WithChallengerCannonKonaEnabled() stack.Option[*Orchestrator] { } } -func setRespectedGameType(o *Orchestrator, gameType types.GameType, l1ELID stack.L1ELNodeID, l2ChainID eth.ChainID) { +func setRespectedGameType(o *Orchestrator, gameType gameTypes.GameType, l1ELID stack.L1ELNodeID, l2ChainID eth.ChainID) { t := o.P() require := t.Require() require.NotNil(o.wb, "must have a world builder") @@ -139,7 +139,7 @@ func setRespectedGameType(o *Orchestrator, gameType types.GameType, l1ELID stack require.Equal(rcpt.Status, gethTypes.ReceiptStatusSuccessful, "set respected game type tx did not execute correctly") } -func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType types.GameType, l1ELID stack.L1ELNodeID, l2ChainID eth.ChainID) { +func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType gameTypes.GameType, l1ELID stack.L1ELNodeID, l2ChainID eth.ChainID) { t := o.P() require := t.Require() require.NotNil(o.wb, "must have a world builder") @@ -210,11 +210,11 @@ func addGameType(o *Orchestrator, absolutePrestate common.Hash, gameType types.G transferOwnershipForDelegateCallProxy(t, l1ChainID.ToBig(), l1PAOKey, client, delegateCallProxy, dgf, l1PAO) } -func PrestateForGameType(t devtest.CommonT, gameType types.GameType) common.Hash { +func PrestateForGameType(t devtest.CommonT, gameType gameTypes.GameType) common.Hash { switch gameType { - case types.CannonGameType: + case gameTypes.CannonGameType: return getAbsolutePrestate(t, "op-program/bin/prestate-proof-mt64.json") - case types.CannonKonaGameType: + case gameTypes.CannonKonaGameType: return getCannonKonaAbsolutePrestate(t) default: t.Require().Fail("no prestate available for game type", gameType) diff --git a/op-devstack/sysgo/l2_challenger.go b/op-devstack/sysgo/l2_challenger.go index 7849ffc98d0..5f0999b7eaa 100644 --- a/op-devstack/sysgo/l2_challenger.go +++ b/op-devstack/sysgo/l2_challenger.go @@ -139,13 +139,13 @@ func WithL2ChallengerPostDeploy(orch *Orchestrator, challengerID stack.L2Challen shared.WithPrivKey(challengerSecret), shared.WithDepset(cluster.DepSet()), shared.WithCannonConfig(rollupCfgs, l1Genesis, l2Geneses, prestateVariant), - shared.WithSuperCannonTraceType(), - shared.WithSuperPermissionedTraceType(), + shared.WithSuperCannonGameType(), + shared.WithSuperPermissionedGameType(), } if orch.l2ChallengerOpts.useCannonKonaConfig { options = append(options, shared.WithCannonKonaConfig(rollupCfgs, l1Genesis, l2Geneses), - shared.WithCannonKonaTraceType(), + shared.WithCannonKonaGameType(), ) } cfg, err = shared.NewInteropChallengerConfig(dir, l1EL.UserRPC(), l1CL.beaconHTTPAddr, supervisorNode.UserRPC(), l2ELRPCs, options...) @@ -170,14 +170,14 @@ func WithL2ChallengerPostDeploy(orch *Orchestrator, challengerID stack.L2Challen shared.WithFactoryAddress(disputeGameFactoryAddr), shared.WithPrivKey(challengerSecret), shared.WithCannonConfig(rollupCfgs, l1Genesis, l2Geneses, prestateVariant), - shared.WithCannonTraceType(), - shared.WithPermissionedTraceType(), + shared.WithCannonGameType(), + shared.WithPermissionedGameType(), shared.WithFastGames(), } if orch.l2ChallengerOpts.useCannonKonaConfig { options = append(options, shared.WithCannonKonaConfig(rollupCfgs, l1Genesis, l2Geneses), - shared.WithCannonKonaTraceType(), + shared.WithCannonKonaGameType(), ) } cfg, err = shared.NewPreInteropChallengerConfig(dir, l1EL.UserRPC(), l1CL.beaconHTTPAddr, l2CL.UserRPC(), l2EL.UserRPC(), options...) diff --git a/op-dispute-mon/mon/extract/caller.go b/op-dispute-mon/mon/extract/caller.go index ea6ee0c3af0..366add6e54a 100644 --- a/op-dispute-mon/mon/extract/caller.go +++ b/op-dispute-mon/mon/extract/caller.go @@ -50,18 +50,18 @@ func (g *GameCallerCreator) CreateContract(ctx context.Context, game gameTypes.G if fdg, ok := g.cache.Get(game.Proxy); ok { return fdg, nil } - switch faultTypes.GameType(game.GameType) { - case faultTypes.CannonGameType, - faultTypes.PermissionedGameType, - faultTypes.CannonKonaGameType, - faultTypes.AsteriscGameType, - faultTypes.AlphabetGameType, - faultTypes.FastGameType, - faultTypes.AsteriscKonaGameType, - faultTypes.SuperCannonGameType, - faultTypes.SuperPermissionedGameType, - faultTypes.SuperCannonKonaGameType, - faultTypes.SuperAsteriscKonaGameType: + switch gameTypes.GameType(game.GameType) { + case gameTypes.CannonGameType, + gameTypes.PermissionedGameType, + gameTypes.CannonKonaGameType, + gameTypes.AsteriscGameType, + gameTypes.AlphabetGameType, + gameTypes.FastGameType, + gameTypes.AsteriscKonaGameType, + gameTypes.SuperCannonGameType, + gameTypes.SuperPermissionedGameType, + gameTypes.SuperCannonKonaGameType, + gameTypes.SuperAsteriscKonaGameType: fdg, err := contracts.NewFaultDisputeGameContract(ctx, g.m, game.Proxy, g.caller) if err != nil { return nil, fmt.Errorf("failed to create fault dispute game contract: %w", err) diff --git a/op-dispute-mon/mon/extract/caller_test.go b/op-dispute-mon/mon/extract/caller_test.go index 585ab609392..119223a5431 100644 --- a/op-dispute-mon/mon/extract/caller_test.go +++ b/op-dispute-mon/mon/extract/caller_test.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots" "github.com/ethereum/go-ethereum/common" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-service/sources/batching" batchingTest "github.com/ethereum-optimism/optimism/op-service/sources/batching/test" @@ -29,47 +28,47 @@ func TestMetadataCreator_CreateContract(t *testing.T) { }{ { name: "validCannonGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.CannonGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.CannonGameType), Proxy: fdgAddr}, }, { name: "validPermissionedGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.PermissionedGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.PermissionedGameType), Proxy: fdgAddr}, }, { name: "validCannonKonaGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.CannonKonaGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.CannonKonaGameType), Proxy: fdgAddr}, }, { name: "validAsteriscGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.AsteriscGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.AsteriscGameType), Proxy: fdgAddr}, }, { name: "validAlphabetGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.AlphabetGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.AlphabetGameType), Proxy: fdgAddr}, }, { name: "validFastGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.FastGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.FastGameType), Proxy: fdgAddr}, }, { name: "validAsteriscKonaGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.AsteriscKonaGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.AsteriscKonaGameType), Proxy: fdgAddr}, }, { name: "validSuperCannonGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.SuperCannonGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.SuperCannonGameType), Proxy: fdgAddr}, }, { name: "validSuperPermissionedGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.SuperPermissionedGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.SuperPermissionedGameType), Proxy: fdgAddr}, }, { name: "validSuperCannonKonaGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.SuperCannonKonaGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.SuperCannonKonaGameType), Proxy: fdgAddr}, }, { name: "validSuperAsteriscKonaGameType", - game: types.GameMetadata{GameType: uint32(faultTypes.SuperAsteriscKonaGameType), Proxy: fdgAddr}, + game: types.GameMetadata{GameType: uint32(types.SuperAsteriscKonaGameType), Proxy: fdgAddr}, }, { name: "InvalidGameType", @@ -101,10 +100,10 @@ func TestMetadataCreator_CreateContract(t *testing.T) { func setupMetadataLoaderTest(t *testing.T, gameType uint32) (*batching.MultiCaller, *mockCacheMetrics) { fdgAbi := snapshots.LoadFaultDisputeGameABI() - if gameType == uint32(faultTypes.SuperPermissionedGameType) || - gameType == uint32(faultTypes.SuperCannonGameType) || - gameType == uint32(faultTypes.SuperCannonKonaGameType) || - gameType == uint32(faultTypes.SuperAsteriscKonaGameType) { + if gameType == uint32(types.SuperPermissionedGameType) || + gameType == uint32(types.SuperCannonGameType) || + gameType == uint32(types.SuperCannonKonaGameType) || + gameType == uint32(types.SuperAsteriscKonaGameType) { fdgAbi = snapshots.LoadSuperFaultDisputeGameABI() } stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi) diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go index 2b4816bd53e..4863019a197 100644 --- a/op-e2e/e2eutils/challenger/helper.go +++ b/op-e2e/e2eutils/challenger/helper.go @@ -10,6 +10,7 @@ import ( "testing" "time" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" shared "github.com/ethereum-optimism/optimism/op-devstack/shared/challenger" "github.com/ethereum-optimism/optimism/op-service/crypto" "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/backend/depset" @@ -23,7 +24,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/wait" "github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-service/cliapp" @@ -135,33 +135,33 @@ func handleOptError(t *testing.T, opt shared.Option) Option { func WithCannon(t *testing.T, system System) Option { return func(c *config.Config) { handleOptError(t, shared.WithCannonConfig(system.RollupCfgs(), system.L1Genesis(), system.L2Geneses(), system.PrestateVariant()))(c) - handleOptError(t, shared.WithCannonTraceType())(c) + handleOptError(t, shared.WithCannonGameType())(c) } } func WithPermissioned(t *testing.T, system System) Option { return func(c *config.Config) { handleOptError(t, shared.WithCannonConfig(system.RollupCfgs(), system.L1Genesis(), system.L2Geneses(), system.PrestateVariant()))(c) - handleOptError(t, shared.WithPermissionedTraceType())(c) + handleOptError(t, shared.WithPermissionedGameType())(c) } } func WithSuperCannon(t *testing.T, system System) Option { return func(c *config.Config) { handleOptError(t, shared.WithCannonConfig(system.RollupCfgs(), system.L1Genesis(), system.L2Geneses(), system.PrestateVariant()))(c) - handleOptError(t, shared.WithSuperCannonTraceType())(c) + handleOptError(t, shared.WithSuperCannonGameType())(c) } } func WithAlphabet() Option { return func(c *config.Config) { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeAlphabet) + c.GameTypes = append(c.GameTypes, gameTypes.AlphabetGameType) } } func WithFastGames() Option { return func(c *config.Config) { - c.TraceTypes = append(c.TraceTypes, types.TraceTypeFast) + c.GameTypes = append(c.GameTypes, gameTypes.FastGameType) } } diff --git a/op-e2e/e2eutils/disputegame/cannon_helper.go b/op-e2e/e2eutils/disputegame/cannon_helper.go index 99c26aa5354..c214fb6410d 100644 --- a/op-e2e/e2eutils/disputegame/cannon_helper.go +++ b/op-e2e/e2eutils/disputegame/cannon_helper.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" @@ -465,7 +466,7 @@ func (g *CannonHelper) createCannonTraceProvider(ctx context.Context, l2Node str localContext = split.CreateLocalContext(pre, post) dir := filepath.Join(cfg.Datadir, "cannon-trace") subdir := filepath.Join(dir, localContext.Hex()) - return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.ToTypedVmMetrics(types.TraceTypeCannon.String()), cfg, localInputs, subdir, g.splitGame.MaxDepth(ctx)-splitDepth-1), nil + return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.ToTypedVmMetrics(gameTypes.CannonGameType.String()), cfg, localInputs, subdir, g.splitGame.MaxDepth(ctx)-splitDepth-1), nil }) claims, err := g.splitGame.Game.GetAllClaims(ctx, rpcblock.Latest) diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 33f8050750d..e5fb8c6ca3c 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/super" - challengerTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" shared "github.com/ethereum-optimism/optimism/op-devstack/shared/challenger" "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" @@ -153,7 +153,7 @@ func (h *FactoryHelper) PreimageHelper(ctx context.Context) *preimage.Helper { caller := batching.NewMultiCaller(h.Client.Client(), batching.DefaultBatchSize) dgf, err := contracts.NewDisputeGameFactoryContract(ctx, metrics.NoopContractMetrics, h.FactoryAddr, caller) h.Require.NoError(err) - vm, err := dgf.GetGameVm(ctx, challengerTypes.GameType(cannonGameType)) + vm, err := dgf.GetGameVm(ctx, gameTypes.GameType(cannonGameType)) h.Require.NoError(err) oracle, err := vm.Oracle(ctx) h.Require.NoError(err) diff --git a/op-e2e/e2eutils/disputegame/super_cannon_helper.go b/op-e2e/e2eutils/disputegame/super_cannon_helper.go index 0a0967dfac9..e441a938a18 100644 --- a/op-e2e/e2eutils/disputegame/super_cannon_helper.go +++ b/op-e2e/e2eutils/disputegame/super_cannon_helper.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" @@ -169,7 +170,7 @@ func (g *SuperCannonGameHelper) createSuperCannonTraceProvider(ctx context.Conte localContext = split.CreateLocalContext(pre, post) dir := filepath.Join(cfg.Datadir, "super-cannon-trace") subdir := filepath.Join(dir, localContext.Hex()) - return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.ToTypedVmMetrics(types.TraceTypeCannon.String()), cfg, localInputs, subdir, g.splitGame.MaxDepth(ctx)-splitDepth-1), nil + return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics.ToTypedVmMetrics(gameTypes.SuperCannonGameType.String()), cfg, localInputs, subdir, g.splitGame.MaxDepth(ctx)-splitDepth-1), nil }) claims, err := g.splitGame.Game.GetAllClaims(ctx, rpcblock.Latest) diff --git a/op-e2e/system/e2esys/setup.go b/op-e2e/system/e2esys/setup.go index 17f19f6dcbf..3c19a379a91 100644 --- a/op-e2e/system/e2esys/setup.go +++ b/op-e2e/system/e2esys/setup.go @@ -16,7 +16,7 @@ import ( "testing" "time" - faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/stretchr/testify/require" "golang.org/x/exp/maps" @@ -926,9 +926,9 @@ func (cfg SystemConfig) Start(t *testing.T, startOpts ...StartOption) (*System, } // L2Output Submitter - respectedGameType := faultTypes.PermissionedGameType + respectedGameType := gameTypes.PermissionedGameType if cfg.AllocType == config.AllocTypeFastGame { - respectedGameType = faultTypes.FastGameType + respectedGameType = gameTypes.FastGameType } proposerCLIConfig := &l2os.CLIConfig{ L1EthRpc: sys.EthInstances[RoleL1].UserRPC().RPC(), diff --git a/op-proposer/contracts/disputegamefactory_test.go b/op-proposer/contracts/disputegamefactory_test.go index b3158369591..84c7dae1a98 100644 --- a/op-proposer/contracts/disputegamefactory_test.go +++ b/op-proposer/contracts/disputegamefactory_test.go @@ -204,13 +204,13 @@ func TestHasProposedSince(t *testing.T) { func TestProposalTx(t *testing.T) { stubRpc, factory := setupDisputeGameFactoryTest(t) - traceType := uint32(123) + gameType := uint32(123) outputRoot := common.Hash{0x01} l2BlockNum := common.BigToHash(big.NewInt(456)).Bytes() bond := big.NewInt(49284294829) - stubRpc.SetResponse(factoryAddr, methodInitBonds, rpcblock.Latest, []interface{}{traceType}, []interface{}{bond}) - stubRpc.SetResponse(factoryAddr, methodCreateGame, rpcblock.Latest, []interface{}{traceType, outputRoot, l2BlockNum}, nil) - tx, err := factory.ProposalTx(context.Background(), traceType, outputRoot, uint64(456)) + stubRpc.SetResponse(factoryAddr, methodInitBonds, rpcblock.Latest, []interface{}{gameType}, []interface{}{bond}) + stubRpc.SetResponse(factoryAddr, methodCreateGame, rpcblock.Latest, []interface{}{gameType, outputRoot, l2BlockNum}, nil) + tx, err := factory.ProposalTx(context.Background(), gameType, outputRoot, uint64(456)) require.NoError(t, err) stubRpc.VerifyTxCandidate(tx) require.NotNil(t, tx.Value) diff --git a/op-service/enum/enum.go b/op-service/enum/enum.go index 9b348c806f1..1bf2f21f371 100644 --- a/op-service/enum/enum.go +++ b/op-service/enum/enum.go @@ -1,6 +1,7 @@ package enum import ( + "fmt" "strings" ) @@ -16,3 +17,14 @@ func EnumString[T ~string](values []T) string { } return out.String() } + +func EnumStringer[T fmt.Stringer](values []T) string { + var out strings.Builder + for i, v := range values { + out.WriteString(v.String()) + if i+1 < len(values) { + out.WriteString(", ") + } + } + return out.String() +} diff --git a/packages/contracts-bedrock/interfaces/L1/opcm/IOPContractsManagerContainer.sol b/packages/contracts-bedrock/interfaces/L1/opcm/IOPContractsManagerContainer.sol index 03d11b5304a..fb1351e1ff1 100644 --- a/packages/contracts-bedrock/interfaces/L1/opcm/IOPContractsManagerContainer.sol +++ b/packages/contracts-bedrock/interfaces/L1/opcm/IOPContractsManagerContainer.sol @@ -36,7 +36,7 @@ interface IOPContractsManagerContainer { address storageSetterImpl; } - error OPContractsManagerContractsContainer_DevFeatureInProd(); + error OPContractsManagerContainer_DevFeatureInProd(); function blueprints() external view returns (Blueprints memory); function implementations() external view returns (Implementations memory); diff --git a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContainer.json b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContainer.json index 29b2d118a3d..f81f6cda750 100644 --- a/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContainer.json +++ b/packages/contracts-bedrock/snapshots/abi/OPContractsManagerContainer.json @@ -368,7 +368,7 @@ }, { "inputs": [], - "name": "OPContractsManagerContractsContainer_DevFeatureInProd", + "name": "OPContractsManagerContainer_DevFeatureInProd", "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerContainer.sol b/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerContainer.sol index fc4d18eb151..7775cc485ee 100644 --- a/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerContainer.sol +++ b/packages/contracts-bedrock/src/L1/opcm/OPContractsManagerContainer.sol @@ -63,7 +63,7 @@ contract OPContractsManagerContainer { bytes32 public immutable devFeatureBitmap; /// @notice Thrown when a development feature is enabled in production. - error OPContractsManagerContractsContainer_DevFeatureInProd(); + error OPContractsManagerContainer_DevFeatureInProd(); /// @param _blueprints The blueprint contract addresses. /// @param _implementations The implementation contract addresses. @@ -75,7 +75,7 @@ contract OPContractsManagerContainer { // Development features MUST NOT be enabled on Mainnet. if (block.chainid == 1 && !_isTestingEnvironment() && uint256(_devFeatureBitmap) != 0) { - revert OPContractsManagerContractsContainer_DevFeatureInProd(); + revert OPContractsManagerContainer_DevFeatureInProd(); } } diff --git a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerContainer.t.sol b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerContainer.t.sol new file mode 100644 index 00000000000..8f42a642360 --- /dev/null +++ b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerContainer.t.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing +import { Test } from "forge-std/Test.sol"; + +// Contracts +import { OPContractsManagerContainer } from "src/L1/opcm/OPContractsManagerContainer.sol"; + +// Libraries +import { Constants } from "src/libraries/Constants.sol"; + +/// @title OPContractsManagerContainer_TestInit +/// @notice Shared setup for OPContractsManagerContainer tests. +contract OPContractsManagerContainer_TestInit is Test { + OPContractsManagerContainer.Blueprints internal blueprints; + OPContractsManagerContainer.Implementations internal implementations; + + function setUp() public virtual { + blueprints = OPContractsManagerContainer.Blueprints({ + addressManager: makeAddr("addressManager"), + proxy: makeAddr("proxy"), + proxyAdmin: makeAddr("proxyAdmin"), + l1ChugSplashProxy: makeAddr("l1ChugSplashProxy"), + resolvedDelegateProxy: makeAddr("resolvedDelegateProxy"), + permissionedDisputeGame1: makeAddr("permissionedDisputeGame1"), + permissionedDisputeGame2: makeAddr("permissionedDisputeGame2"), + permissionlessDisputeGame1: makeAddr("permissionlessDisputeGame1"), + permissionlessDisputeGame2: makeAddr("permissionlessDisputeGame2") + }); + + implementations = OPContractsManagerContainer.Implementations({ + superchainConfigImpl: makeAddr("superchainConfigImpl"), + protocolVersionsImpl: makeAddr("protocolVersionsImpl"), + l1ERC721BridgeImpl: makeAddr("l1ERC721BridgeImpl"), + optimismPortalImpl: makeAddr("optimismPortalImpl"), + optimismPortalInteropImpl: makeAddr("optimismPortalInteropImpl"), + ethLockboxImpl: makeAddr("ethLockboxImpl"), + systemConfigImpl: makeAddr("systemConfigImpl"), + optimismMintableERC20FactoryImpl: makeAddr("optimismMintableERC20FactoryImpl"), + l1CrossDomainMessengerImpl: makeAddr("l1CrossDomainMessengerImpl"), + l1StandardBridgeImpl: makeAddr("l1StandardBridgeImpl"), + disputeGameFactoryImpl: makeAddr("disputeGameFactoryImpl"), + anchorStateRegistryImpl: makeAddr("anchorStateRegistryImpl"), + delayedWETHImpl: makeAddr("delayedWETHImpl"), + mipsImpl: makeAddr("mipsImpl"), + faultDisputeGameV2Impl: makeAddr("faultDisputeGameV2Impl"), + permissionedDisputeGameV2Impl: makeAddr("permissionedDisputeGameV2Impl"), + superFaultDisputeGameImpl: makeAddr("superFaultDisputeGameImpl"), + superPermissionedDisputeGameImpl: makeAddr("superPermissionedDisputeGameImpl"), + storageSetterImpl: makeAddr("storageSetterImpl") + }); + } + + /// @notice Deploys a new OPContractsManagerContainer with the given dev feature bitmap. + /// @param _devFeatureBitmap The dev feature bitmap to use. + /// @return The deployed OPContractsManagerContainer. + function _deploy(bytes32 _devFeatureBitmap) internal returns (OPContractsManagerContainer) { + return new OPContractsManagerContainer(blueprints, implementations, _devFeatureBitmap); + } +} + +/// @title OPContractsManagerContainer_Constructor_Test +/// @notice Tests the constructor of OPContractsManagerContainer. +contract OPContractsManagerContainer_Constructor_Test is OPContractsManagerContainer_TestInit { + /// @notice Tests that the constructor succeeds with any dev bitmap when in a test environment. + /// @param _chainId The chain ID to use. + /// @param _devFeatureBitmap The dev feature bitmap to use. + function testFuzz_constructor_devBitmapInTestEnv_succeeds(uint64 _chainId, bytes32 _devFeatureBitmap) public { + // Etch code into the magic testing address so we're recognized as a test env. + vm.etch(Constants.TESTING_ENVIRONMENT_ADDRESS, hex"01"); + + // Set chain ID. + vm.chainId(_chainId); + + OPContractsManagerContainer container = _deploy(_devFeatureBitmap); + + assertEq(container.devFeatureBitmap(), _devFeatureBitmap); + } + + /// @notice Tests that the constructor reverts when dev features are enabled on mainnet without + /// test env. + /// @param _devFeatureBitmap The dev feature bitmap to use. + function testFuzz_constructor_devBitmapOnMainnet_reverts(bytes32 _devFeatureBitmap) public { + // Ensure at least one dev feature is enabled. + _devFeatureBitmap = bytes32(bound(uint256(_devFeatureBitmap), 1, type(uint256).max)); + + // Clear the magic testing address so we're recognized as production. + vm.etch(Constants.TESTING_ENVIRONMENT_ADDRESS, hex""); + + // Set chain ID to mainnet. + vm.chainId(1); + + vm.expectRevert(OPContractsManagerContainer.OPContractsManagerContainer_DevFeatureInProd.selector); + _deploy(_devFeatureBitmap); + } + + /// @notice Tests that the constructor succeeds on mainnet with a zero dev bitmap. + function test_constructor_zeroBitmapOnMainnet_succeeds() public { + // Clear the magic testing address. + vm.etch(Constants.TESTING_ENVIRONMENT_ADDRESS, hex""); + + // Set chain ID to mainnet. + vm.chainId(1); + + OPContractsManagerContainer container = _deploy(bytes32(0)); + + assertEq(container.devFeatureBitmap(), bytes32(0)); + } +} + +/// @title OPContractsManagerContainer_Blueprints_Test +/// @notice Tests the blueprints() getter. +contract OPContractsManagerContainer_Blueprints_Test is OPContractsManagerContainer_TestInit { + /// @notice Tests that blueprints() returns the struct provided at construction. + function test_blueprints_succeeds() public { + OPContractsManagerContainer container = _deploy(bytes32(0)); + + assertEq(abi.encode(container.blueprints()), abi.encode(blueprints)); + } +} + +/// @title OPContractsManagerContainer_Implementations_Test +/// @notice Tests the implementations() getter. +contract OPContractsManagerContainer_Implementations_Test is OPContractsManagerContainer_TestInit { + /// @notice Tests that implementations() returns the struct provided at construction. + function test_implementations_succeeds() public { + OPContractsManagerContainer container = _deploy(bytes32(0)); + + assertEq(abi.encode(container.implementations()), abi.encode(implementations)); + } +} + +/// @title OPContractsManagerContainer_IsDevFeatureEnabled_Test +/// @notice Tests the isDevFeatureEnabled() function. +contract OPContractsManagerContainer_IsDevFeatureEnabled_Test is OPContractsManagerContainer_TestInit { + /// @notice Tests that isDevFeatureEnabled returns true when the feature bit is set. + /// @param _bitIndex The bit index to test. + function testFuzz_isDevFeatureEnabled_bitSet_succeeds(uint8 _bitIndex) public { + bytes32 bitmap = bytes32(uint256(1) << _bitIndex); + bytes32 feature = bytes32(uint256(1) << _bitIndex); + + OPContractsManagerContainer container = _deploy(bitmap); + + assertTrue(container.isDevFeatureEnabled(feature)); + assertFalse(container.isDevFeatureEnabled(bytes32(0))); + } + + /// @notice Tests that isDevFeatureEnabled returns false when the feature bit is not set. + /// @param _bitIndex The bit index to test. + function testFuzz_isDevFeatureEnabled_bitNotSet_succeeds(uint8 _bitIndex) public { + // Create a bitmap with all bits set except the one we're testing. + bytes32 bitmap = bytes32(type(uint256).max ^ (uint256(1) << _bitIndex)); + bytes32 feature = bytes32(uint256(1) << _bitIndex); + + OPContractsManagerContainer container = _deploy(bitmap); + + assertFalse(container.isDevFeatureEnabled(feature)); + } + + /// @notice Tests that isDevFeatureEnabled returns false when the bitmap is zero. + /// @param _feature The feature to check. + function testFuzz_isDevFeatureEnabled_zeroBitmap_succeeds(bytes32 _feature) public { + OPContractsManagerContainer container = _deploy(bytes32(0)); + + assertFalse(container.isDevFeatureEnabled(_feature)); + } + + /// @notice Tests that isDevFeatureEnabled returns true for multiple features set at once. + function test_isDevFeatureEnabled_multipleBitsSet_succeeds() public { + uint256 numFeatures = vm.randomUint(1, 16); + uint256 bitmap; + uint8[] memory bitIndices = new uint8[](numFeatures); + + // Set random bits in the bitmap. + for (uint256 i = 0; i < numFeatures; i++) { + uint8 bitIndex = uint8(vm.randomUint(0, 255)); + bitIndices[i] = bitIndex; + bitmap |= uint256(1) << bitIndex; + } + + OPContractsManagerContainer container = _deploy(bytes32(bitmap)); + + // Verify each feature is enabled. + for (uint256 i = 0; i < numFeatures; i++) { + bytes32 feature = bytes32(uint256(1) << bitIndices[i]); + assertTrue(container.isDevFeatureEnabled(feature)); + } + } +} + +/// @title OPContractsManagerContainer_DevFeatureBitmap_Test +/// @notice Tests the devFeatureBitmap() getter. +contract OPContractsManagerContainer_DevFeatureBitmap_Test is OPContractsManagerContainer_TestInit { + /// @notice Tests that devFeatureBitmap() returns the value provided at construction. + /// @param _devFeatureBitmap The dev feature bitmap to use. + function testFuzz_devFeatureBitmap_succeeds(bytes32 _devFeatureBitmap) public { + OPContractsManagerContainer container = _deploy(_devFeatureBitmap); + + assertEq(container.devFeatureBitmap(), _devFeatureBitmap); + } +} diff --git a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol index 6f69658758a..314edd4beba 100644 --- a/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol +++ b/packages/contracts-bedrock/test/L1/opcm/OPContractsManagerV2.t.sol @@ -10,7 +10,7 @@ import { DisputeGames } from "test/setup/DisputeGames.sol"; import { Config } from "scripts/libraries/Config.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { Claim } from "src/dispute/lib/LibUDT.sol"; -import { GameTypes } from "src/dispute/lib/Types.sol"; +import { GameType, GameTypes } from "src/dispute/lib/Types.sol"; import { DevFeatures } from "src/libraries/DevFeatures.sol"; // Interfaces @@ -119,10 +119,12 @@ contract OPContractsManagerV2_Upgrade_TestInit is CommonTest, DisputeGames { /// @param _opcm The OPCM contract to reference for shared components. /// @param _delegateCaller The address of the delegate caller to use for superchain upgrade. /// @param _revertBytes The bytes of the revert to expect. + /// @param _expectedValidatorErrors The StandardValidator errors to expect. function _runOpcmV2UpgradeAndChecks( IOPContractsManagerV2 _opcm, address _delegateCaller, - bytes memory _revertBytes + bytes memory _revertBytes, + string memory _expectedValidatorErrors ) internal { @@ -199,6 +201,19 @@ contract OPContractsManagerV2_Upgrade_TestInit is CommonTest, DisputeGames { // try to apply to this function call instead. IOPContractsManagerStandardValidator validator = _opcm.standardValidator(); + // Expect validator errors if the user provides them. We always expect the L1PAOMultisig + // and Challenger overrides so we don't need to repeat them here. + if (bytes(_expectedValidatorErrors).length > 0) { + vm.expectRevert( + bytes( + string.concat( + "OPContractsManagerStandardValidator: OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,", + _expectedValidatorErrors + ) + ) + ); + } + // Run the StandardValidator checks. if (isDevFeatureEnabled(DevFeatures.CANNON_KONA)) { validator.validateWithOverrides( @@ -247,14 +262,28 @@ contract OPContractsManagerV2_Upgrade_TestInit is CommonTest, DisputeGames { /// @notice Executes the current V2 upgrade and checks the results. /// @param _delegateCaller The address of the delegate caller to use for the superchain upgrade. function runCurrentUpgradeV2(address _delegateCaller) public { - _runOpcmV2UpgradeAndChecks(opcmV2, _delegateCaller, bytes("")); + _runOpcmV2UpgradeAndChecks(opcmV2, _delegateCaller, bytes(""), ""); } /// @notice Executes the current V2 upgrade and expects reverts. /// @param _delegateCaller The address of the delegate caller to use for the superchain upgrade. /// @param _revertBytes The bytes of the revert to expect. function runCurrentUpgradeV2(address _delegateCaller, bytes memory _revertBytes) public { - _runOpcmV2UpgradeAndChecks(opcmV2, _delegateCaller, _revertBytes); + _runOpcmV2UpgradeAndChecks(opcmV2, _delegateCaller, _revertBytes, ""); + } + + /// @notice Executes the current V2 upgrade and expects reverts. + /// @param _delegateCaller The address of the delegate caller to use for the superchain upgrade. + /// @param _revertBytes The bytes of the revert to expect. + /// @param _expectedValidatorErrors The StandardValidator errors to expect. + function runCurrentUpgradeV2( + address _delegateCaller, + bytes memory _revertBytes, + string memory _expectedValidatorErrors + ) + public + { + _runOpcmV2UpgradeAndChecks(opcmV2, _delegateCaller, _revertBytes, _expectedValidatorErrors); } } @@ -443,6 +472,102 @@ contract OPContractsManagerV2_Upgrade_Test is OPContractsManagerV2_Upgrade_TestI ) ); } + + /// @notice Tests that repeatedly upgrading can enable a previously disabled game type. + function test_upgrade_enableGameType_succeeds() public { + uint256 originalBond = disputeGameFactory.initBonds(GameTypes.CANNON); + + // First, disable Cannon and clear its bond so the factory entry is removed. + v2UpgradeInput.disputeGameConfigs[0].enabled = false; + v2UpgradeInput.disputeGameConfigs[0].initBond = 0; + runCurrentUpgradeV2(chainPAO, hex"", "PLDG-10"); + assertEq(address(disputeGameFactory.gameImpls(GameTypes.CANNON)), address(0), "game impl not cleared"); + + // Re-enable Cannon and restore its bond so that it is re-installed. + v2UpgradeInput.disputeGameConfigs[0].enabled = true; + v2UpgradeInput.disputeGameConfigs[0].initBond = originalBond; + runCurrentUpgradeV2(chainPAO); + assertEq( + address(disputeGameFactory.gameImpls(GameTypes.CANNON)), + opcmV2.implementations().faultDisputeGameV2Impl, + "game impl not restored" + ); + assertEq(disputeGameFactory.initBonds(GameTypes.CANNON), originalBond, "init bond not restored"); + } + + /// @notice Tests that disabling a game type removes it from the factory. + function test_upgrade_disableGameType_succeeds() public { + // Establish the baseline where Cannon is enabled. + runCurrentUpgradeV2(chainPAO); + assertEq( + address(disputeGameFactory.gameImpls(GameTypes.CANNON)), + opcmV2.implementations().faultDisputeGameV2Impl, + "initial game impl mismatch" + ); + + // Disable Cannon and zero its bond, then ensure it is removed. + v2UpgradeInput.disputeGameConfigs[0].enabled = false; + v2UpgradeInput.disputeGameConfigs[0].initBond = 0; + runCurrentUpgradeV2(chainPAO, hex"", "PLDG-10"); + assertEq(address(disputeGameFactory.gameImpls(GameTypes.CANNON)), address(0), "game impl not cleared"); + assertEq(disputeGameFactory.initBonds(GameTypes.CANNON), 0, "init bond not cleared"); + assertEq(disputeGameFactory.gameArgs(GameTypes.CANNON), bytes(""), "game args not cleared"); + } + + /// @notice Tests that the upgrade flow can update the Cannon and Permissioned prestate. + function test_upgrade_updatePrestate_succeeds() public { + skipIfDevFeatureDisabled(DevFeatures.OPCM_V2); + + // Run baseline upgrade and capture the current prestates. + runCurrentUpgradeV2(chainPAO); + assertEq( + _gameArgsAbsolutePrestate(GameTypes.CANNON), + Claim.unwrap(cannonPrestate), + "baseline cannon prestate mismatch" + ); + assertEq( + _gameArgsAbsolutePrestate(GameTypes.PERMISSIONED_CANNON), + Claim.unwrap(cannonPrestate), + "baseline permissioned prestate mismatch" + ); + + // Prepare new prestates. + Claim newPrestate = Claim.wrap(bytes32(keccak256("new cannon prestate"))); + cannonPrestate = newPrestate; + + // Update the dispute game configs to point at the new prestates. + v2UpgradeInput.disputeGameConfigs[0].gameArgs = + abi.encode(IOPContractsManagerV2.FaultDisputeGameConfig({ absolutePrestate: newPrestate })); + v2UpgradeInput.disputeGameConfigs[1].gameArgs = abi.encode( + IOPContractsManagerV2.PermissionedDisputeGameConfig({ + absolutePrestate: newPrestate, + proposer: permissionedGameProposer(disputeGameFactory), + challenger: permissionedGameChallenger(disputeGameFactory) + }) + ); + + // Run the upgrade again and ensure prestates updated. + runCurrentUpgradeV2(chainPAO); + assertEq(_gameArgsAbsolutePrestate(GameTypes.CANNON), Claim.unwrap(newPrestate), "cannon prestate not updated"); + assertEq( + _gameArgsAbsolutePrestate(GameTypes.PERMISSIONED_CANNON), + Claim.unwrap(newPrestate), + "permissioned prestate not updated" + ); + } + + /// @notice Extracts the absolute prestate embedded in a dispute game config. + /// @param _gameType Game type to inspect. + /// @return prestate_ The absolute prestate stored in the factory's game args. + function _gameArgsAbsolutePrestate(GameType _gameType) internal view returns (bytes32 prestate_) { + bytes memory args = disputeGameFactory.gameArgs(_gameType); + if (args.length == 0) { + return bytes32(0); + } + assembly { + prestate_ := mload(add(args, 0x20)) + } + } } /// @title OPContractsManagerV2_UpgradeSuperchain_Test