Commit 98038608 authored by Inphi's avatar Inphi Committed by GitHub

op-challenger: Improve GameType typing (#11012)

parent 1440a519
...@@ -4,10 +4,10 @@ import ( ...@@ -4,10 +4,10 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/flags"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/tools" "github.com/ethereum-optimism/optimism/op-challenger/tools"
opservice "github.com/ethereum-optimism/optimism/op-service" opservice "github.com/ethereum-optimism/optimism/op-service"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
...@@ -22,7 +22,7 @@ var ( ...@@ -22,7 +22,7 @@ var (
Name: "trace-type", Name: "trace-type",
Usage: "Trace types to support.", Usage: "Trace types to support.",
EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "TRACE_TYPE"), EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "TRACE_TYPE"),
Value: config.TraceTypeCannon.String(), Value: types.TraceTypeCannon.String(),
} }
OutputRootFlag = &cli.StringFlag{ OutputRootFlag = &cli.StringFlag{
Name: "output-root", Name: "output-root",
......
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/config" "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/cliapp"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -38,13 +39,13 @@ var ( ...@@ -38,13 +39,13 @@ var (
func TestLogLevel(t *testing.T) { func TestLogLevel(t *testing.T) {
t.Run("RejectInvalid", func(t *testing.T) { t.Run("RejectInvalid", func(t *testing.T) {
verifyArgsInvalid(t, "unknown level: foo", addRequiredArgs(config.TraceTypeAlphabet, "--log.level=foo")) verifyArgsInvalid(t, "unknown level: foo", addRequiredArgs(types.TraceTypeAlphabet, "--log.level=foo"))
}) })
for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} { for _, lvl := range []string{"trace", "debug", "info", "error", "crit"} {
lvl := lvl lvl := lvl
t.Run("AcceptValid_"+lvl, func(t *testing.T) { t.Run("AcceptValid_"+lvl, func(t *testing.T) {
logger, _, err := dryRunWithArgs(addRequiredArgs(config.TraceTypeAlphabet, "--log.level", lvl)) logger, _, err := dryRunWithArgs(addRequiredArgs(types.TraceTypeAlphabet, "--log.level", lvl))
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, logger) require.NotNil(t, logger)
}) })
...@@ -52,24 +53,24 @@ func TestLogLevel(t *testing.T) { ...@@ -52,24 +53,24 @@ func TestLogLevel(t *testing.T) {
} }
func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) { func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet)) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet))
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, config.TraceTypeAlphabet) defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, types.TraceTypeAlphabet)
require.Equal(t, defaultCfg, cfg) require.Equal(t, defaultCfg, cfg)
} }
func TestDefaultConfigIsValid(t *testing.T) { func TestDefaultConfigIsValid(t *testing.T) {
cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, config.TraceTypeAlphabet) cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, types.TraceTypeAlphabet)
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
} }
func TestL1ETHRPCAddress(t *testing.T) { func TestL1ETHRPCAddress(t *testing.T) {
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
verifyArgsInvalid(t, "flag l1-eth-rpc is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-eth-rpc")) verifyArgsInvalid(t, "flag l1-eth-rpc is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-eth-rpc"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
url := "http://example.com:8888" url := "http://example.com:8888"
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-eth-rpc", "--l1-eth-rpc="+url)) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-eth-rpc", "--l1-eth-rpc="+url))
require.Equal(t, url, cfg.L1EthRpc) require.Equal(t, url, cfg.L1EthRpc)
require.Equal(t, url, cfg.TxMgrConfig.L1RPCURL) require.Equal(t, url, cfg.TxMgrConfig.L1RPCURL)
}) })
...@@ -77,91 +78,91 @@ func TestL1ETHRPCAddress(t *testing.T) { ...@@ -77,91 +78,91 @@ func TestL1ETHRPCAddress(t *testing.T) {
func TestL1Beacon(t *testing.T) { func TestL1Beacon(t *testing.T) {
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-beacon")) verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-beacon"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
url := "http://example.com:8888" url := "http://example.com:8888"
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--l1-beacon", "--l1-beacon="+url)) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-beacon", "--l1-beacon="+url))
require.Equal(t, url, cfg.L1Beacon) require.Equal(t, url, cfg.L1Beacon)
}) })
} }
func TestTraceType(t *testing.T) { func TestTraceType(t *testing.T) {
t.Run("Default", func(t *testing.T) { t.Run("Default", func(t *testing.T) {
expectedDefault := config.TraceTypeCannon expectedDefault := types.TraceTypeCannon
cfg := configForArgs(t, addRequiredArgsExcept(expectedDefault, "--trace-type")) cfg := configForArgs(t, addRequiredArgsExcept(expectedDefault, "--trace-type"))
require.Equal(t, []config.TraceType{expectedDefault}, cfg.TraceTypes) require.Equal(t, []types.TraceType{expectedDefault}, cfg.TraceTypes)
}) })
for _, traceType := range config.TraceTypes { for _, traceType := range types.TraceTypes {
traceType := traceType traceType := traceType
t.Run("Valid_"+traceType.String(), func(t *testing.T) { t.Run("Valid_"+traceType.String(), func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(traceType)) cfg := configForArgs(t, addRequiredArgs(traceType))
require.Equal(t, []config.TraceType{traceType}, cfg.TraceTypes) require.Equal(t, []types.TraceType{traceType}, cfg.TraceTypes)
}) })
} }
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
verifyArgsInvalid(t, "unknown trace type: \"foo\"", addRequiredArgsExcept(config.TraceTypeAlphabet, "--trace-type", "--trace-type=foo")) verifyArgsInvalid(t, "unknown trace type: \"foo\"", addRequiredArgsExcept(types.TraceTypeAlphabet, "--trace-type", "--trace-type=foo"))
}) })
} }
func TestMultipleTraceTypes(t *testing.T) { func TestMultipleTraceTypes(t *testing.T) {
t.Run("WithAllOptions", func(t *testing.T) { t.Run("WithAllOptions", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon) argsMap := requiredArgs(types.TraceTypeCannon)
// Add Asterisc required flags // Add Asterisc required flags
addRequiredAsteriscArgs(argsMap) addRequiredAsteriscArgs(argsMap)
args := toArgList(argsMap) args := toArgList(argsMap)
// Add extra trace types (cannon is already specified) // Add extra trace types (cannon is already specified)
args = append(args, args = append(args,
"--trace-type", config.TraceTypeAlphabet.String()) "--trace-type", types.TraceTypeAlphabet.String())
args = append(args, args = append(args,
"--trace-type", config.TraceTypePermissioned.String()) "--trace-type", types.TraceTypePermissioned.String())
args = append(args, args = append(args,
"--trace-type", config.TraceTypeAsterisc.String()) "--trace-type", types.TraceTypeAsterisc.String())
cfg := configForArgs(t, args) cfg := configForArgs(t, args)
require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeAlphabet, config.TraceTypePermissioned, config.TraceTypeAsterisc}, cfg.TraceTypes) require.Equal(t, []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet, types.TraceTypePermissioned, types.TraceTypeAsterisc}, cfg.TraceTypes)
}) })
t.Run("WithSomeOptions", func(t *testing.T) { t.Run("WithSomeOptions", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon) argsMap := requiredArgs(types.TraceTypeCannon)
args := toArgList(argsMap) args := toArgList(argsMap)
// Add extra trace types (cannon is already specified) // Add extra trace types (cannon is already specified)
args = append(args, args = append(args,
"--trace-type", config.TraceTypeAlphabet.String()) "--trace-type", types.TraceTypeAlphabet.String())
cfg := configForArgs(t, args) cfg := configForArgs(t, args)
require.Equal(t, []config.TraceType{config.TraceTypeCannon, config.TraceTypeAlphabet}, cfg.TraceTypes) require.Equal(t, []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet}, cfg.TraceTypes)
}) })
t.Run("SpecifySameOptionMultipleTimes", func(t *testing.T) { t.Run("SpecifySameOptionMultipleTimes", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon) argsMap := requiredArgs(types.TraceTypeCannon)
args := toArgList(argsMap) args := toArgList(argsMap)
// Add cannon trace type again // Add cannon trace type again
args = append(args, "--trace-type", config.TraceTypeCannon.String()) args = append(args, "--trace-type", types.TraceTypeCannon.String())
// We're fine with the same option being listed multiple times, just deduplicate them. // We're fine with the same option being listed multiple times, just deduplicate them.
cfg := configForArgs(t, args) cfg := configForArgs(t, args)
require.Equal(t, []config.TraceType{config.TraceTypeCannon}, cfg.TraceTypes) require.Equal(t, []types.TraceType{types.TraceTypeCannon}, cfg.TraceTypes)
}) })
} }
func TestGameFactoryAddress(t *testing.T) { func TestGameFactoryAddress(t *testing.T) {
t.Run("RequiredWhenNetworkNotSupplied", func(t *testing.T) { t.Run("RequiredWhenNetworkNotSupplied", func(t *testing.T) {
verifyArgsInvalid(t, "flag game-factory-address or network is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address")) verifyArgsInvalid(t, "flag game-factory-address or network is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd} addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address="+addr.Hex())) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address="+addr.Hex()))
require.Equal(t, addr, cfg.GameFactoryAddress) require.Equal(t, addr, cfg.GameFactoryAddress)
}) })
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address=foo")) verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address=foo"))
}) })
t.Run("OverridesNetwork", func(t *testing.T) { t.Run("OverridesNetwork", func(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd} addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address", addr.Hex(), "--network", "op-sepolia")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address", addr.Hex(), "--network", "op-sepolia"))
require.Equal(t, addr, cfg.GameFactoryAddress) require.Equal(t, addr, cfg.GameFactoryAddress)
}) })
} }
...@@ -169,42 +170,42 @@ func TestGameFactoryAddress(t *testing.T) { ...@@ -169,42 +170,42 @@ func TestGameFactoryAddress(t *testing.T) {
func TestNetwork(t *testing.T) { func TestNetwork(t *testing.T) {
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
opSepoliaChainId := uint64(11155420) opSepoliaChainId := uint64(11155420)
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address", "--network=op-sepolia")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=op-sepolia"))
require.EqualValues(t, superchain.Addresses[opSepoliaChainId].DisputeGameFactoryProxy, cfg.GameFactoryAddress) require.EqualValues(t, superchain.Addresses[opSepoliaChainId].DisputeGameFactoryProxy, cfg.GameFactoryAddress)
}) })
t.Run("UnknownNetwork", func(t *testing.T) { t.Run("UnknownNetwork", func(t *testing.T) {
verifyArgsInvalid(t, "unknown chain: not-a-network", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-factory-address", "--network=not-a-network")) verifyArgsInvalid(t, "unknown chain: not-a-network", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=not-a-network"))
}) })
} }
func TestGameAllowlist(t *testing.T) { func TestGameAllowlist(t *testing.T) {
t.Run("Optional", func(t *testing.T) { t.Run("Optional", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist"))
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd} addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist="+addr.Hex())) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist="+addr.Hex()))
require.Contains(t, cfg.GameAllowlist, addr) require.Contains(t, cfg.GameAllowlist, addr)
}) })
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(config.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist=foo")) verifyArgsInvalid(t, "invalid address: foo", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-allowlist", "--game-allowlist=foo"))
}) })
} }
func TestTxManagerFlagsSupported(t *testing.T) { func TestTxManagerFlagsSupported(t *testing.T) {
// Not a comprehensive list of flags, just enough to sanity check the txmgr.CLIFlags were defined // Not a comprehensive list of flags, just enough to sanity check the txmgr.CLIFlags were defined
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--"+txmgr.NumConfirmationsFlagName, "7")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--"+txmgr.NumConfirmationsFlagName, "7"))
require.Equal(t, uint64(7), cfg.TxMgrConfig.NumConfirmations) require.Equal(t, uint64(7), cfg.TxMgrConfig.NumConfirmations)
} }
func TestMaxConcurrency(t *testing.T) { func TestMaxConcurrency(t *testing.T) {
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
expected := uint(345) expected := uint(345)
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--max-concurrency", "345")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "345"))
require.Equal(t, expected, cfg.MaxConcurrency) require.Equal(t, expected, cfg.MaxConcurrency)
}) })
...@@ -212,26 +213,26 @@ func TestMaxConcurrency(t *testing.T) { ...@@ -212,26 +213,26 @@ func TestMaxConcurrency(t *testing.T) {
verifyArgsInvalid( verifyArgsInvalid(
t, t,
"invalid value \"abc\" for flag -max-concurrency", "invalid value \"abc\" for flag -max-concurrency",
addRequiredArgs(config.TraceTypeAlphabet, "--max-concurrency", "abc")) addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "abc"))
}) })
t.Run("Zero", func(t *testing.T) { t.Run("Zero", func(t *testing.T) {
verifyArgsInvalid( verifyArgsInvalid(
t, t,
"max-concurrency must not be 0", "max-concurrency must not be 0",
addRequiredArgs(config.TraceTypeAlphabet, "--max-concurrency", "0")) addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "0"))
}) })
} }
func TestMaxPendingTx(t *testing.T) { func TestMaxPendingTx(t *testing.T) {
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
expected := uint64(345) expected := uint64(345)
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "345")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "345"))
require.Equal(t, expected, cfg.MaxPendingTx) require.Equal(t, expected, cfg.MaxPendingTx)
}) })
t.Run("Zero", func(t *testing.T) { t.Run("Zero", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "0")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "0"))
require.Equal(t, uint64(0), cfg.MaxPendingTx) require.Equal(t, uint64(0), cfg.MaxPendingTx)
}) })
...@@ -239,19 +240,19 @@ func TestMaxPendingTx(t *testing.T) { ...@@ -239,19 +240,19 @@ func TestMaxPendingTx(t *testing.T) {
verifyArgsInvalid( verifyArgsInvalid(
t, t,
"invalid value \"abc\" for flag -max-pending-tx", "invalid value \"abc\" for flag -max-pending-tx",
addRequiredArgs(config.TraceTypeAlphabet, "--max-pending-tx", "abc")) addRequiredArgs(types.TraceTypeAlphabet, "--max-pending-tx", "abc"))
}) })
} }
func TestPollInterval(t *testing.T) { func TestPollInterval(t *testing.T) {
t.Run("UsesDefault", func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon))
require.Equal(t, config.DefaultPollInterval, cfg.PollInterval) require.Equal(t, config.DefaultPollInterval, cfg.PollInterval)
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
expected := 100 * time.Second expected := 100 * time.Second
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--http-poll-interval", "100s")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--http-poll-interval", "100s"))
require.Equal(t, expected, cfg.PollInterval) require.Equal(t, expected, cfg.PollInterval)
}) })
...@@ -259,16 +260,16 @@ func TestPollInterval(t *testing.T) { ...@@ -259,16 +260,16 @@ func TestPollInterval(t *testing.T) {
verifyArgsInvalid( verifyArgsInvalid(
t, t,
"invalid value \"abc\" for flag -http-poll-interval", "invalid value \"abc\" for flag -http-poll-interval",
addRequiredArgs(config.TraceTypeAlphabet, "--http-poll-interval", "abc")) addRequiredArgs(types.TraceTypeAlphabet, "--http-poll-interval", "abc"))
}) })
} }
func TestAsteriscRequiredArgs(t *testing.T) { func TestAsteriscRequiredArgs(t *testing.T) {
for _, traceType := range []config.TraceType{config.TraceTypeAsterisc} { for _, traceType := range []types.TraceType{types.TraceTypeAsterisc} {
traceType := traceType traceType := traceType
t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-bin")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-bin"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -283,7 +284,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -283,7 +284,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-server")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-server"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -298,7 +299,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -298,7 +299,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-prestate")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestate"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -313,7 +314,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -313,7 +314,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-prestates-url")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-prestates-url"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -418,7 +419,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -418,7 +419,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscNetwork-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscNetwork-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-network")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-network"))
}) })
t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) { t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) {
...@@ -448,7 +449,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -448,7 +449,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-rollup-config")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-rollup-config"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
...@@ -459,7 +460,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -459,7 +460,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscL2Genesis-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestAsteriscL2Genesis-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-l2-genesis")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--asterisc-l2-genesis"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
...@@ -471,29 +472,29 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -471,29 +472,29 @@ func TestAsteriscRequiredArgs(t *testing.T) {
} }
func TestAlphabetRequiredArgs(t *testing.T) { func TestAlphabetRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestL2Rpc-%v", config.TraceTypeAlphabet), func(t *testing.T) { t.Run(fmt.Sprintf("TestL2Rpc-%v", types.TraceTypeAlphabet), func(t *testing.T) {
t.Run("RequiredForAlphabetTrace", func(t *testing.T) { t.Run("RequiredForAlphabetTrace", func(t *testing.T) {
verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(config.TraceTypeAlphabet, "--l2-eth-rpc")) verifyArgsInvalid(t, "flag l2-eth-rpc is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l2-eth-rpc"))
}) })
t.Run("ValidLegacy", func(t *testing.T) { t.Run("ValidLegacy", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--l2-eth-rpc", fmt.Sprintf("--cannon-l2=%s", l2EthRpc))) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--l2-eth-rpc", fmt.Sprintf("--cannon-l2=%s", l2EthRpc)))
require.Equal(t, l2EthRpc, cfg.L2Rpc) require.Equal(t, l2EthRpc, cfg.L2Rpc)
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet)) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet))
require.Equal(t, l2EthRpc, cfg.L2Rpc) require.Equal(t, l2EthRpc, cfg.L2Rpc)
}) })
}) })
} }
func TestCannonRequiredArgs(t *testing.T) { func TestCannonRequiredArgs(t *testing.T) {
for _, traceType := range []config.TraceType{config.TraceTypeCannon, config.TraceTypePermissioned} { for _, traceType := range []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned} {
traceType := traceType traceType := traceType
t.Run(fmt.Sprintf("TestCannonBin-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonBin-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-bin")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-bin"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -508,7 +509,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -508,7 +509,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonServer-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonServer-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-server")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-server"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -523,7 +524,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -523,7 +524,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-prestate")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-prestate"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -538,7 +539,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -538,7 +539,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-prestates-url")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-prestates-url"))
}) })
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
...@@ -639,7 +640,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -639,7 +640,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonNetwork-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonNetwork-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-network")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-network"))
}) })
t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) { t.Run("NotRequiredWhenRollupAndGenesIsSpecified", func(t *testing.T) {
...@@ -669,7 +670,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -669,7 +670,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-rollup-config")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-rollup-config"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
...@@ -680,7 +681,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -680,7 +681,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2-genesis")) configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--cannon-l2-genesis"))
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
...@@ -692,7 +693,7 @@ func TestCannonRequiredArgs(t *testing.T) { ...@@ -692,7 +693,7 @@ func TestCannonRequiredArgs(t *testing.T) {
} }
func TestDataDir(t *testing.T) { func TestDataDir(t *testing.T) {
for _, traceType := range config.TraceTypes { for _, traceType := range types.TraceTypes {
traceType := traceType traceType := traceType
t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) {
...@@ -701,13 +702,13 @@ func TestDataDir(t *testing.T) { ...@@ -701,13 +702,13 @@ func TestDataDir(t *testing.T) {
} }
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeCannon, "--datadir", "--datadir=/foo/bar/cannon")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeCannon, "--datadir", "--datadir=/foo/bar/cannon"))
require.Equal(t, "/foo/bar/cannon", cfg.Datadir) require.Equal(t, "/foo/bar/cannon", cfg.Datadir)
}) })
} }
func TestRollupRpc(t *testing.T) { func TestRollupRpc(t *testing.T) {
for _, traceType := range config.TraceTypes { for _, traceType := range types.TraceTypes {
traceType := traceType traceType := traceType
t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) { t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) {
...@@ -716,59 +717,59 @@ func TestRollupRpc(t *testing.T) { ...@@ -716,59 +717,59 @@ func TestRollupRpc(t *testing.T) {
} }
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon)) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon))
require.Equal(t, rollupRpc, cfg.RollupRpc) require.Equal(t, rollupRpc, cfg.RollupRpc)
}) })
} }
func TestGameWindow(t *testing.T) { func TestGameWindow(t *testing.T) {
t.Run("UsesDefault", func(t *testing.T) { t.Run("UsesDefault", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet)) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet))
require.Equal(t, config.DefaultGameWindow, cfg.GameWindow) require.Equal(t, config.DefaultGameWindow, cfg.GameWindow)
}) })
t.Run("Valid", func(t *testing.T) { t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--game-window=1m")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--game-window=1m"))
require.Equal(t, time.Minute, cfg.GameWindow) require.Equal(t, time.Minute, cfg.GameWindow)
}) })
t.Run("ParsesDefault", func(t *testing.T) { t.Run("ParsesDefault", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--game-window=672h")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--game-window=672h"))
require.Equal(t, config.DefaultGameWindow, cfg.GameWindow) require.Equal(t, config.DefaultGameWindow, cfg.GameWindow)
}) })
} }
func TestUnsafeAllowInvalidPrestate(t *testing.T) { func TestUnsafeAllowInvalidPrestate(t *testing.T) {
t.Run("DefaultsToFalse", func(t *testing.T) { t.Run("DefaultsToFalse", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--unsafe-allow-invalid-prestate")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--unsafe-allow-invalid-prestate"))
require.False(t, cfg.AllowInvalidPrestate) require.False(t, cfg.AllowInvalidPrestate)
}) })
t.Run("EnabledWithNoValue", func(t *testing.T) { t.Run("EnabledWithNoValue", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate"))
require.True(t, cfg.AllowInvalidPrestate) require.True(t, cfg.AllowInvalidPrestate)
}) })
t.Run("EnabledWithTrue", func(t *testing.T) { t.Run("EnabledWithTrue", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate=true")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate=true"))
require.True(t, cfg.AllowInvalidPrestate) require.True(t, cfg.AllowInvalidPrestate)
}) })
t.Run("DisabledWithFalse", func(t *testing.T) { t.Run("DisabledWithFalse", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeCannon, "--unsafe-allow-invalid-prestate=false")) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeCannon, "--unsafe-allow-invalid-prestate=false"))
require.False(t, cfg.AllowInvalidPrestate) require.False(t, cfg.AllowInvalidPrestate)
}) })
} }
func TestAdditionalBondClaimants(t *testing.T) { func TestAdditionalBondClaimants(t *testing.T) {
t.Run("DefaultsToEmpty", func(t *testing.T) { t.Run("DefaultsToEmpty", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--additional-bond-claimants")) cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--additional-bond-claimants"))
require.Empty(t, cfg.AdditionalBondClaimants) require.Empty(t, cfg.AdditionalBondClaimants)
}) })
t.Run("Valid-Single", func(t *testing.T) { t.Run("Valid-Single", func(t *testing.T) {
claimant := common.Address{0xaa} claimant := common.Address{0xaa}
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", claimant.Hex())) cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", claimant.Hex()))
require.Contains(t, cfg.AdditionalBondClaimants, claimant) require.Contains(t, cfg.AdditionalBondClaimants, claimant)
require.Len(t, cfg.AdditionalBondClaimants, 1) require.Len(t, cfg.AdditionalBondClaimants, 1)
}) })
...@@ -777,7 +778,7 @@ func TestAdditionalBondClaimants(t *testing.T) { ...@@ -777,7 +778,7 @@ func TestAdditionalBondClaimants(t *testing.T) {
claimant1 := common.Address{0xaa} claimant1 := common.Address{0xaa}
claimant2 := common.Address{0xbb} claimant2 := common.Address{0xbb}
claimant3 := common.Address{0xcc} claimant3 := common.Address{0xcc}
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet, cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet,
"--additional-bond-claimants", fmt.Sprintf("%v,%v,%v", claimant1.Hex(), claimant2.Hex(), claimant3.Hex()))) "--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, claimant1)
require.Contains(t, cfg.AdditionalBondClaimants, claimant2) require.Contains(t, cfg.AdditionalBondClaimants, claimant2)
...@@ -787,14 +788,14 @@ func TestAdditionalBondClaimants(t *testing.T) { ...@@ -787,14 +788,14 @@ func TestAdditionalBondClaimants(t *testing.T) {
t.Run("Invalid-Single", func(t *testing.T) { t.Run("Invalid-Single", func(t *testing.T) {
verifyArgsInvalid(t, "invalid additional claimant", verifyArgsInvalid(t, "invalid additional claimant",
addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", "nope")) addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", "nope"))
}) })
t.Run("Invalid-Multiple", func(t *testing.T) { t.Run("Invalid-Multiple", func(t *testing.T) {
claimant1 := common.Address{0xaa} claimant1 := common.Address{0xaa}
claimant2 := common.Address{0xbb} claimant2 := common.Address{0xbb}
verifyArgsInvalid(t, "invalid additional claimant", verifyArgsInvalid(t, "invalid additional claimant",
addRequiredArgs(config.TraceTypeAlphabet, "--additional-bond-claimants", fmt.Sprintf("%v,nope,%v", claimant1.Hex(), claimant2.Hex()))) addRequiredArgs(types.TraceTypeAlphabet, "--additional-bond-claimants", fmt.Sprintf("%v,nope,%v", claimant1.Hex(), claimant2.Hex())))
}) })
} }
...@@ -825,19 +826,19 @@ func dryRunWithArgs(cliArgs []string) (log.Logger, config.Config, error) { ...@@ -825,19 +826,19 @@ func dryRunWithArgs(cliArgs []string) (log.Logger, config.Config, error) {
return logger, *cfg, err return logger, *cfg, err
} }
func addRequiredArgs(traceType config.TraceType, args ...string) []string { func addRequiredArgs(traceType types.TraceType, args ...string) []string {
req := requiredArgs(traceType) req := requiredArgs(traceType)
combined := toArgList(req) combined := toArgList(req)
return append(combined, args...) return append(combined, args...)
} }
func addRequiredArgsExcept(traceType config.TraceType, name string, optionalArgs ...string) []string { func addRequiredArgsExcept(traceType types.TraceType, name string, optionalArgs ...string) []string {
req := requiredArgs(traceType) req := requiredArgs(traceType)
delete(req, name) delete(req, name)
return append(toArgList(req), optionalArgs...) return append(toArgList(req), optionalArgs...)
} }
func requiredArgs(traceType config.TraceType) map[string]string { func requiredArgs(traceType types.TraceType) map[string]string {
args := map[string]string{ args := map[string]string{
"--l1-eth-rpc": l1EthRpc, "--l1-eth-rpc": l1EthRpc,
"--l1-beacon": l1Beacon, "--l1-beacon": l1Beacon,
...@@ -848,9 +849,9 @@ func requiredArgs(traceType config.TraceType) map[string]string { ...@@ -848,9 +849,9 @@ func requiredArgs(traceType config.TraceType) map[string]string {
"--datadir": datadir, "--datadir": datadir,
} }
switch traceType { switch traceType {
case config.TraceTypeCannon, config.TraceTypePermissioned: case types.TraceTypeCannon, types.TraceTypePermissioned:
addRequiredCannonArgs(args) addRequiredCannonArgs(args)
case config.TraceTypeAsterisc: case types.TraceTypeAsterisc:
addRequiredAsteriscArgs(args) addRequiredAsteriscArgs(args)
} }
return args return args
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-node/chaincfg" "github.com/ethereum-optimism/optimism/op-node/chaincfg"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/oppprof" "github.com/ethereum-optimism/optimism/op-service/oppprof"
...@@ -50,45 +51,6 @@ var ( ...@@ -50,45 +51,6 @@ var (
ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network") ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network")
) )
type TraceType string
const (
TraceTypeAlphabet TraceType = "alphabet"
TraceTypeFast TraceType = "fast"
TraceTypeCannon TraceType = "cannon"
TraceTypeAsterisc TraceType = "asterisc"
TraceTypePermissioned TraceType = "permissioned"
)
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned, TraceTypeAsterisc, TraceTypeFast}
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 {
for _, t := range TraceTypes {
if t == value {
return true
}
}
return false
}
const ( const (
DefaultPollInterval = time.Second * 12 DefaultPollInterval = time.Second * 12
DefaultCannonSnapshotFreq = uint(1_000_000_000) DefaultCannonSnapshotFreq = uint(1_000_000_000)
...@@ -122,7 +84,7 @@ type Config struct { ...@@ -122,7 +84,7 @@ type Config struct {
SelectiveClaimResolution bool // Whether to only resolve claims for the claimants in AdditionalBondClaimants union [TxSender.From()] SelectiveClaimResolution bool // Whether to only resolve claims for the claimants in AdditionalBondClaimants union [TxSender.From()]
TraceTypes []TraceType // Type of traces supported TraceTypes []types.TraceType // Type of traces supported
RollupRpc string // L2 Rollup RPC Url RollupRpc string // L2 Rollup RPC Url
...@@ -152,7 +114,7 @@ func NewConfig( ...@@ -152,7 +114,7 @@ func NewConfig(
l2RollupRpc string, l2RollupRpc string,
l2EthRpc string, l2EthRpc string,
datadir string, datadir string,
supportedTraceTypes ...TraceType, supportedTraceTypes ...types.TraceType,
) Config { ) Config {
return Config{ return Config{
L1EthRpc: l1EthRpc, L1EthRpc: l1EthRpc,
...@@ -174,7 +136,7 @@ func NewConfig( ...@@ -174,7 +136,7 @@ func NewConfig(
Datadir: datadir, Datadir: datadir,
Cannon: vm.Config{ Cannon: vm.Config{
VmType: TraceTypeCannon.String(), VmType: types.TraceTypeCannon,
L1: l1EthRpc, L1: l1EthRpc,
L1Beacon: l1BeaconApi, L1Beacon: l1BeaconApi,
L2: l2EthRpc, L2: l2EthRpc,
...@@ -182,7 +144,7 @@ func NewConfig( ...@@ -182,7 +144,7 @@ func NewConfig(
InfoFreq: DefaultCannonInfoFreq, InfoFreq: DefaultCannonInfoFreq,
}, },
Asterisc: vm.Config{ Asterisc: vm.Config{
VmType: TraceTypeAsterisc.String(), VmType: types.TraceTypeAsterisc,
L1: l1EthRpc, L1: l1EthRpc,
L1Beacon: l1BeaconApi, L1Beacon: l1BeaconApi,
L2: l2EthRpc, L2: l2EthRpc,
...@@ -193,7 +155,7 @@ func NewConfig( ...@@ -193,7 +155,7 @@ func NewConfig(
} }
} }
func (c Config) TraceTypeEnabled(t TraceType) bool { func (c Config) TraceTypeEnabled(t types.TraceType) bool {
return slices.Contains(c.TraceTypes, t) return slices.Contains(c.TraceTypes, t)
} }
...@@ -222,7 +184,7 @@ func (c Config) Check() error { ...@@ -222,7 +184,7 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 { if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero return ErrMaxConcurrencyZero
} }
if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypePermissioned) { if c.TraceTypeEnabled(types.TraceTypeCannon) || c.TraceTypeEnabled(types.TraceTypePermissioned) {
if c.Cannon.VmBin == "" { if c.Cannon.VmBin == "" {
return ErrMissingCannonBin return ErrMissingCannonBin
} }
...@@ -260,7 +222,7 @@ func (c Config) Check() error { ...@@ -260,7 +222,7 @@ func (c Config) Check() error {
return ErrMissingCannonInfoFreq return ErrMissingCannonInfoFreq
} }
} }
if c.TraceTypeEnabled(TraceTypeAsterisc) { if c.TraceTypeEnabled(types.TraceTypeAsterisc) {
if c.Asterisc.VmBin == "" { if c.Asterisc.VmBin == "" {
return ErrMissingAsteriscBin return ErrMissingAsteriscBin
} }
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
) )
...@@ -32,8 +33,8 @@ var ( ...@@ -32,8 +33,8 @@ var (
validAsteriscAbsolutPreStateBaseURL, _ = url.Parse("http://localhost/bar/") validAsteriscAbsolutPreStateBaseURL, _ = url.Parse("http://localhost/bar/")
) )
var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned} var cannonTraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned}
var asteriscTraceTypes = []TraceType{TraceTypeAsterisc} var asteriscTraceTypes = []types.TraceType{types.TraceTypeAsterisc}
func applyValidConfigForCannon(cfg *Config) { func applyValidConfigForCannon(cfg *Config) {
cfg.Cannon.VmBin = validCannonBin cfg.Cannon.VmBin = validCannonBin
...@@ -49,12 +50,12 @@ func applyValidConfigForAsterisc(cfg *Config) { ...@@ -49,12 +50,12 @@ func applyValidConfigForAsterisc(cfg *Config) {
cfg.Asterisc.Network = validAsteriscNetwork cfg.Asterisc.Network = validAsteriscNetwork
} }
func validConfig(traceType TraceType) Config { func validConfig(traceType types.TraceType) Config {
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validRollupRpc, validL2Rpc, validDatadir, traceType) cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validRollupRpc, validL2Rpc, validDatadir, traceType)
if traceType == TraceTypeCannon || traceType == TraceTypePermissioned { if traceType == types.TraceTypeCannon || traceType == types.TraceTypePermissioned {
applyValidConfigForCannon(&cfg) applyValidConfigForCannon(&cfg)
} }
if traceType == TraceTypeAsterisc { if traceType == types.TraceTypeAsterisc {
applyValidConfigForAsterisc(&cfg) applyValidConfigForAsterisc(&cfg)
} }
return cfg return cfg
...@@ -62,7 +63,7 @@ func validConfig(traceType TraceType) Config { ...@@ -62,7 +63,7 @@ func validConfig(traceType TraceType) Config {
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid // TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func TestValidConfigIsValid(t *testing.T) { func TestValidConfigIsValid(t *testing.T) {
for _, traceType := range TraceTypes { for _, traceType := range types.TraceTypes {
traceType := traceType traceType := traceType
t.Run(traceType.String(), func(t *testing.T) { t.Run(traceType.String(), func(t *testing.T) {
err := validConfig(traceType).Check() err := validConfig(traceType).Check()
...@@ -73,38 +74,38 @@ func TestValidConfigIsValid(t *testing.T) { ...@@ -73,38 +74,38 @@ func TestValidConfigIsValid(t *testing.T) {
func TestTxMgrConfig(t *testing.T) { func TestTxMgrConfig(t *testing.T) {
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
config.TxMgrConfig = txmgr.CLIConfig{} config.TxMgrConfig = txmgr.CLIConfig{}
require.Equal(t, config.Check().Error(), "must provide a L1 RPC url") require.Equal(t, config.Check().Error(), "must provide a L1 RPC url")
}) })
} }
func TestL1EthRpcRequired(t *testing.T) { func TestL1EthRpcRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
config.L1EthRpc = "" config.L1EthRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC) require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC)
} }
func TestL1BeaconRequired(t *testing.T) { func TestL1BeaconRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
config.L1Beacon = "" config.L1Beacon = ""
require.ErrorIs(t, config.Check(), ErrMissingL1Beacon) require.ErrorIs(t, config.Check(), ErrMissingL1Beacon)
} }
func TestGameFactoryAddressRequired(t *testing.T) { func TestGameFactoryAddressRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
config.GameFactoryAddress = common.Address{} config.GameFactoryAddress = common.Address{}
require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress) require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress)
} }
func TestSelectiveClaimResolutionNotRequired(t *testing.T) { func TestSelectiveClaimResolutionNotRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
require.Equal(t, false, config.SelectiveClaimResolution) require.Equal(t, false, config.SelectiveClaimResolution)
require.NoError(t, config.Check()) require.NoError(t, config.Check())
} }
func TestGameAllowlistNotRequired(t *testing.T) { func TestGameAllowlistNotRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(types.TraceTypeCannon)
config.GameAllowlist = []common.Address{} config.GameAllowlist = []common.Address{}
require.NoError(t, config.Check()) require.NoError(t, config.Check())
} }
...@@ -322,33 +323,33 @@ func TestAsteriscRequiredArgs(t *testing.T) { ...@@ -322,33 +323,33 @@ func TestAsteriscRequiredArgs(t *testing.T) {
} }
func TestDatadirRequired(t *testing.T) { func TestDatadirRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet) config := validConfig(types.TraceTypeAlphabet)
config.Datadir = "" config.Datadir = ""
require.ErrorIs(t, config.Check(), ErrMissingDatadir) require.ErrorIs(t, config.Check(), ErrMissingDatadir)
} }
func TestMaxConcurrency(t *testing.T) { func TestMaxConcurrency(t *testing.T) {
t.Run("Required", func(t *testing.T) { t.Run("Required", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet) config := validConfig(types.TraceTypeAlphabet)
config.MaxConcurrency = 0 config.MaxConcurrency = 0
require.ErrorIs(t, config.Check(), ErrMaxConcurrencyZero) require.ErrorIs(t, config.Check(), ErrMaxConcurrencyZero)
}) })
t.Run("DefaultToNumberOfCPUs", func(t *testing.T) { t.Run("DefaultToNumberOfCPUs", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet) config := validConfig(types.TraceTypeAlphabet)
require.EqualValues(t, runtime.NumCPU(), config.MaxConcurrency) require.EqualValues(t, runtime.NumCPU(), config.MaxConcurrency)
}) })
} }
func TestHttpPollInterval(t *testing.T) { func TestHttpPollInterval(t *testing.T) {
t.Run("Default", func(t *testing.T) { t.Run("Default", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet) config := validConfig(types.TraceTypeAlphabet)
require.EqualValues(t, DefaultPollInterval, config.PollInterval) require.EqualValues(t, DefaultPollInterval, config.PollInterval)
}) })
} }
func TestRollupRpcRequired(t *testing.T) { func TestRollupRpcRequired(t *testing.T) {
for _, traceType := range TraceTypes { for _, traceType := range types.TraceTypes {
traceType := traceType traceType := traceType
t.Run(traceType.String(), func(t *testing.T) { t.Run(traceType.String(), func(t *testing.T) {
config := validConfig(traceType) config := validConfig(traceType)
...@@ -359,8 +360,8 @@ func TestRollupRpcRequired(t *testing.T) { ...@@ -359,8 +360,8 @@ func TestRollupRpcRequired(t *testing.T) {
} }
func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) { func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) {
cfg := validConfig(TraceTypeCannon) cfg := validConfig(types.TraceTypeCannon)
cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAlphabet} cfg.TraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet}
// Set all required options and check its valid // Set all required options and check its valid
cfg.RollupRpc = validRollupRpc cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
...@@ -377,8 +378,8 @@ func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) { ...@@ -377,8 +378,8 @@ func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) {
} }
func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) { func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) {
cfg := validConfig(TraceTypeAsterisc) cfg := validConfig(types.TraceTypeAsterisc)
cfg.TraceTypes = []TraceType{TraceTypeAsterisc, TraceTypeAlphabet} cfg.TraceTypes = []types.TraceType{types.TraceTypeAsterisc, types.TraceTypeAlphabet}
// Set all required options and check its valid // Set all required options and check its valid
cfg.RollupRpc = validRollupRpc cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
...@@ -395,10 +396,10 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) { ...@@ -395,10 +396,10 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) {
} }
func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) { func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) {
cfg := validConfig(TraceTypeCannon) cfg := validConfig(types.TraceTypeCannon)
applyValidConfigForAsterisc(&cfg) applyValidConfigForAsterisc(&cfg)
cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAsterisc, TraceTypeAlphabet, TraceTypeFast} cfg.TraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypeAsterisc, types.TraceTypeAlphabet, types.TraceTypeFast}
// Set all required options and check its valid // Set all required options and check its valid
cfg.RollupRpc = validRollupRpc cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check()) require.NoError(t, cfg.Check())
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-service/flags" "github.com/ethereum-optimism/optimism/op-service/flags"
"github.com/ethereum-optimism/superchain-registry/superchain" "github.com/ethereum-optimism/superchain-registry/superchain"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -61,9 +62,9 @@ var ( ...@@ -61,9 +62,9 @@ var (
} }
TraceTypeFlag = &cli.StringSliceFlag{ TraceTypeFlag = &cli.StringSliceFlag{
Name: "trace-type", Name: "trace-type",
Usage: "The trace types to support. Valid options: " + openum.EnumString(config.TraceTypes), Usage: "The trace types to support. Valid options: " + openum.EnumString(types.TraceTypes),
EnvVars: prefixEnvVars("TRACE_TYPE"), EnvVars: prefixEnvVars("TRACE_TYPE"),
Value: cli.NewStringSlice(config.TraceTypeCannon.String()), Value: cli.NewStringSlice(types.TraceTypeCannon.String()),
} }
DatadirFlag = &cli.StringFlag{ DatadirFlag = &cli.StringFlag{
Name: "datadir", Name: "datadir",
...@@ -339,7 +340,7 @@ func CheckAsteriscFlags(ctx *cli.Context) error { ...@@ -339,7 +340,7 @@ func CheckAsteriscFlags(ctx *cli.Context) error {
return nil return nil
} }
func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error { func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error {
for _, f := range requiredFlags { for _, f := range requiredFlags {
if !ctx.IsSet(f.Names()[0]) { if !ctx.IsSet(f.Names()[0]) {
return fmt.Errorf("flag %s is required", f.Names()[0]) return fmt.Errorf("flag %s is required", f.Names()[0])
...@@ -351,26 +352,26 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error { ...@@ -351,26 +352,26 @@ func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error {
} }
for _, traceType := range traceTypes { for _, traceType := range traceTypes {
switch traceType { switch traceType {
case config.TraceTypeCannon, config.TraceTypePermissioned: case types.TraceTypeCannon, types.TraceTypePermissioned:
if err := CheckCannonFlags(ctx); err != nil { if err := CheckCannonFlags(ctx); err != nil {
return err return err
} }
case config.TraceTypeAsterisc: case types.TraceTypeAsterisc:
if err := CheckAsteriscFlags(ctx); err != nil { if err := CheckAsteriscFlags(ctx); err != nil {
return err return err
} }
case config.TraceTypeAlphabet, config.TraceTypeFast: case types.TraceTypeAlphabet, types.TraceTypeFast:
default: default:
return fmt.Errorf("invalid trace type. must be one of %v", config.TraceTypes) return fmt.Errorf("invalid trace type. must be one of %v", types.TraceTypes)
} }
} }
return nil return nil
} }
func parseTraceTypes(ctx *cli.Context) ([]config.TraceType, error) { func parseTraceTypes(ctx *cli.Context) ([]types.TraceType, error) {
var traceTypes []config.TraceType var traceTypes []types.TraceType
for _, typeName := range ctx.StringSlice(TraceTypeFlag.Name) { for _, typeName := range ctx.StringSlice(TraceTypeFlag.Name) {
traceType := new(config.TraceType) traceType := new(types.TraceType)
if err := traceType.Set(typeName); err != nil { if err := traceType.Set(typeName); err != nil {
return nil, err return nil, err
} }
...@@ -514,7 +515,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro ...@@ -514,7 +515,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
AdditionalBondClaimants: claimants, AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name), RollupRpc: ctx.String(RollupRpcFlag.Name),
Cannon: vm.Config{ Cannon: vm.Config{
VmType: config.TraceTypeCannon.String(), VmType: types.TraceTypeCannon,
L1: l1EthRpc, L1: l1EthRpc,
L1Beacon: l1Beacon, L1Beacon: l1Beacon,
L2: l2Rpc, L2: l2Rpc,
...@@ -530,7 +531,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro ...@@ -530,7 +531,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
CannonAbsolutePreStateBaseURL: cannonPrestatesURL, CannonAbsolutePreStateBaseURL: cannonPrestatesURL,
Datadir: ctx.String(DatadirFlag.Name), Datadir: ctx.String(DatadirFlag.Name),
Asterisc: vm.Config{ Asterisc: vm.Config{
VmType: config.TraceTypeAsterisc.String(), VmType: types.TraceTypeAsterisc,
L1: l1EthRpc, L1: l1EthRpc,
L1Beacon: l1Beacon, L1Beacon: l1Beacon,
L2: l2Rpc, L2: l2Rpc,
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "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" "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"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
...@@ -76,7 +77,7 @@ func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, bl ...@@ -76,7 +77,7 @@ func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, bl
return f.decodeGame(idx, result), nil return f.decodeGame(idx, result), nil
} }
func (f *DisputeGameFactoryContract) GetGameImpl(ctx context.Context, gameType uint32) (common.Address, error) { func (f *DisputeGameFactoryContract) GetGameImpl(ctx context.Context, gameType faultTypes.GameType) (common.Address, error) {
defer f.metrics.StartContractRequest("GetGameImpl")() defer f.metrics.StartContractRequest("GetGameImpl")()
result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameImpls, gameType)) result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameImpls, gameType))
if err != nil { if err != nil {
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "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" "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"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
...@@ -190,7 +191,7 @@ func TestGetGameFromParameters(t *testing.T) { ...@@ -190,7 +191,7 @@ func TestGetGameFromParameters(t *testing.T) {
func TestGetGameImpl(t *testing.T) { func TestGetGameImpl(t *testing.T) {
stubRpc, factory := setupDisputeGameFactoryTest(t) stubRpc, factory := setupDisputeGameFactoryTest(t)
gameType := uint32(3) gameType := faultTypes.CannonGameType
gameImplAddr := common.Address{0xaa} gameImplAddr := common.Address{0xaa}
stubRpc.SetResponse( stubRpc.SetResponse(
factoryAddr, factoryAddr,
...@@ -198,7 +199,7 @@ func TestGetGameImpl(t *testing.T) { ...@@ -198,7 +199,7 @@ func TestGetGameImpl(t *testing.T) {
rpcblock.Latest, rpcblock.Latest,
[]interface{}{gameType}, []interface{}{gameType},
[]interface{}{gameImplAddr}) []interface{}{gameImplAddr})
actual, err := factory.GetGameImpl(context.Background(), gameType) actual, err := factory.GetGameImpl(context.Background(), faultTypes.CannonGameType)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, gameImplAddr, actual) require.Equal(t, gameImplAddr, actual)
} }
......
...@@ -30,8 +30,8 @@ import ( ...@@ -30,8 +30,8 @@ import (
type CloseFunc func() type CloseFunc func()
type Registry interface { type Registry interface {
RegisterGameType(gameType uint32, creator scheduler.PlayerCreator) RegisterGameType(gameType faultTypes.GameType, creator scheduler.PlayerCreator)
RegisterBondContract(gameType uint32, creator claims.BondContractCreator) RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator)
} }
type OracleRegistry interface { type OracleRegistry interface {
...@@ -73,27 +73,27 @@ func RegisterGameTypes( ...@@ -73,27 +73,27 @@ func RegisterGameTypes(
} }
syncValidator := newSyncStatusValidator(rollupClient) syncValidator := newSyncStatusValidator(rollupClient)
if cfg.TraceTypeEnabled(config.TraceTypeCannon) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeCannon) {
if err := registerCannon(faultTypes.CannonGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { if err := registerCannon(faultTypes.CannonGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil {
return nil, fmt.Errorf("failed to register cannon game type: %w", err) return nil, fmt.Errorf("failed to register cannon game type: %w", err)
} }
} }
if cfg.TraceTypeEnabled(config.TraceTypePermissioned) { if cfg.TraceTypeEnabled(faultTypes.TraceTypePermissioned) {
if err := registerCannon(faultTypes.PermissionedGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { if err := registerCannon(faultTypes.PermissionedGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil {
return nil, fmt.Errorf("failed to register permissioned cannon game type: %w", err) return nil, fmt.Errorf("failed to register permissioned cannon game type: %w", err)
} }
} }
if cfg.TraceTypeEnabled(config.TraceTypeAsterisc) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsterisc) {
if err := registerAsterisc(faultTypes.AsteriscGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { if err := registerAsterisc(faultTypes.AsteriscGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil {
return nil, fmt.Errorf("failed to register asterisc game type: %w", err) return nil, fmt.Errorf("failed to register asterisc game type: %w", err)
} }
} }
if cfg.TraceTypeEnabled(config.TraceTypeFast) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) {
if err := registerAlphabet(faultTypes.FastGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, syncValidator, rollupClient, l2Client, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil { if err := registerAlphabet(faultTypes.FastGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, syncValidator, rollupClient, l2Client, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil {
return nil, fmt.Errorf("failed to register fast game type: %w", err) return nil, fmt.Errorf("failed to register fast game type: %w", err)
} }
} }
if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeAlphabet) {
if err := registerAlphabet(faultTypes.AlphabetGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, syncValidator, rollupClient, l2Client, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil { if err := registerAlphabet(faultTypes.AlphabetGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, syncValidator, rollupClient, l2Client, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil {
return nil, fmt.Errorf("failed to register alphabet game type: %w", err) return nil, fmt.Errorf("failed to register alphabet game type: %w", err)
} }
...@@ -102,7 +102,7 @@ func RegisterGameTypes( ...@@ -102,7 +102,7 @@ func RegisterGameTypes(
} }
func registerAlphabet( func registerAlphabet(
gameType uint32, gameType faultTypes.GameType,
registry Registry, registry Registry,
oracles OracleRegistry, oracles OracleRegistry,
ctx context.Context, ctx context.Context,
...@@ -167,7 +167,7 @@ func registerAlphabet( ...@@ -167,7 +167,7 @@ func registerAlphabet(
return nil return nil
} }
func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, gameType uint32) error { func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, gameType faultTypes.GameType) error {
implAddr, err := gameFactory.GetGameImpl(ctx, gameType) implAddr, err := gameFactory.GetGameImpl(ctx, gameType)
if err != nil { if err != nil {
return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err) return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err)
...@@ -185,7 +185,7 @@ func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegis ...@@ -185,7 +185,7 @@ func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegis
} }
func registerAsterisc( func registerAsterisc(
gameType uint32, gameType faultTypes.GameType,
registry Registry, registry Registry,
oracles OracleRegistry, oracles OracleRegistry,
ctx context.Context, ctx context.Context,
...@@ -278,7 +278,7 @@ func registerAsterisc( ...@@ -278,7 +278,7 @@ func registerAsterisc(
} }
func registerCannon( func registerCannon(
gameType uint32, gameType faultTypes.GameType,
registry Registry, registry Registry,
oracles OracleRegistry, oracles OracleRegistry,
ctx context.Context, ctx context.Context,
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
...@@ -19,7 +20,7 @@ type Metricer interface { ...@@ -19,7 +20,7 @@ type Metricer interface {
} }
type Config struct { type Config struct {
VmType string VmType types.TraceType
L1 string L1 string
L1Beacon string L1Beacon string
L2 string L2 string
...@@ -121,6 +122,6 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64 ...@@ -121,6 +122,6 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64
e.logger.Info("Generating trace", "proof", end, "cmd", e.cfg.VmBin, "args", strings.Join(args, ", ")) e.logger.Info("Generating trace", "proof", end, "cmd", e.cfg.VmBin, "args", strings.Join(args, ", "))
execStart := time.Now() execStart := time.Now()
err = e.cmdExecutor(ctx, e.logger.New("proof", end), e.cfg.VmBin, args...) err = e.cmdExecutor(ctx, e.logger.New("proof", end), e.cfg.VmBin, args...)
e.metrics.RecordVmExecutionTime(e.cfg.VmType, time.Since(execStart)) e.metrics.RecordVmExecutionTime(e.cfg.VmType.String(), time.Since(execStart))
return err return err
} }
...@@ -3,6 +3,8 @@ package types ...@@ -3,6 +3,8 @@ package types
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"math"
"math/big" "math/big"
"time" "time"
...@@ -18,14 +20,94 @@ var ( ...@@ -18,14 +20,94 @@ var (
ErrL2BlockNumberValid = errors.New("l2 block number is valid") ErrL2BlockNumberValid = errors.New("l2 block number is valid")
) )
type GameType uint32
const (
CannonGameType GameType = 0
PermissionedGameType GameType = 1
AsteriscGameType GameType = 2
FastGameType GameType = 254
AlphabetGameType GameType = 255
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 FastGameType:
return "fast"
case AlphabetGameType:
return "alphabet"
default:
return fmt.Sprintf("<invalid: %d>", t)
}
}
type TraceType string
const ( const (
CannonGameType uint32 = 0 TraceTypeAlphabet TraceType = "alphabet"
PermissionedGameType uint32 = 1 TraceTypeFast TraceType = "fast"
AsteriscGameType uint32 = 2 TraceTypeCannon TraceType = "cannon"
FastGameType uint32 = 254 TraceTypeAsterisc TraceType = "asterisc"
AlphabetGameType uint32 = 255 TraceTypePermissioned TraceType = "permissioned"
) )
var TraceTypes = []TraceType{TraceTypeAlphabet, TraceTypeCannon, TraceTypePermissioned, TraceTypeAsterisc, TraceTypeFast}
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 {
for _, t := range TraceTypes {
if t == value {
return true
}
}
return false
}
func (t TraceType) GameType() GameType {
switch t {
case TraceTypeCannon:
return CannonGameType
case TraceTypePermissioned:
return PermissionedGameType
case TraceTypeAsterisc:
return AsteriscGameType
case TraceTypeFast:
return FastGameType
case TraceTypeAlphabet:
return AlphabetGameType
default:
return UnknownGameType
}
}
type ClockReader interface { type ClockReader interface {
Now() time.Time Now() time.Time
} }
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/claims" "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/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types" "github.com/ethereum-optimism/optimism/op-challenger/game/types"
) )
...@@ -12,27 +13,27 @@ import ( ...@@ -12,27 +13,27 @@ import (
var ErrUnsupportedGameType = errors.New("unsupported game type") var ErrUnsupportedGameType = errors.New("unsupported game type")
type GameTypeRegistry struct { type GameTypeRegistry struct {
types map[uint32]scheduler.PlayerCreator types map[faultTypes.GameType]scheduler.PlayerCreator
bondCreators map[uint32]claims.BondContractCreator bondCreators map[faultTypes.GameType]claims.BondContractCreator
} }
func NewGameTypeRegistry() *GameTypeRegistry { func NewGameTypeRegistry() *GameTypeRegistry {
return &GameTypeRegistry{ return &GameTypeRegistry{
types: make(map[uint32]scheduler.PlayerCreator), types: make(map[faultTypes.GameType]scheduler.PlayerCreator),
bondCreators: make(map[uint32]claims.BondContractCreator), bondCreators: make(map[faultTypes.GameType]claims.BondContractCreator),
} }
} }
// RegisterGameType registers a scheduler.PlayerCreator to use for a specific game type. // 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. // Panics if the same game type is registered multiple times, since this indicates a significant programmer error.
func (r *GameTypeRegistry) RegisterGameType(gameType uint32, creator scheduler.PlayerCreator) { func (r *GameTypeRegistry) RegisterGameType(gameType faultTypes.GameType, creator scheduler.PlayerCreator) {
if _, ok := r.types[gameType]; ok { if _, ok := r.types[gameType]; ok {
panic(fmt.Errorf("duplicate creator registered for game type: %v", gameType)) panic(fmt.Errorf("duplicate creator registered for game type: %v", gameType))
} }
r.types[gameType] = creator r.types[gameType] = creator
} }
func (r *GameTypeRegistry) RegisterBondContract(gameType uint32, creator claims.BondContractCreator) { func (r *GameTypeRegistry) RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator) {
if _, ok := r.bondCreators[gameType]; ok { if _, ok := r.bondCreators[gameType]; ok {
panic(fmt.Errorf("duplicate bond contract registered for game type: %v", gameType)) panic(fmt.Errorf("duplicate bond contract registered for game type: %v", gameType))
} }
...@@ -41,7 +42,7 @@ func (r *GameTypeRegistry) RegisterBondContract(gameType uint32, creator claims. ...@@ -41,7 +42,7 @@ func (r *GameTypeRegistry) RegisterBondContract(gameType uint32, creator claims.
// CreatePlayer creates a new game player for the given game, using the specified directory for persisting data. // 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) { func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
creator, ok := r.types[game.GameType] creator, ok := r.types[faultTypes.GameType(game.GameType)]
if !ok { if !ok {
return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType) return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType)
} }
...@@ -49,7 +50,7 @@ func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (sc ...@@ -49,7 +50,7 @@ func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (sc
} }
func (r *GameTypeRegistry) CreateBondContract(game types.GameMetadata) (claims.BondContract, error) { func (r *GameTypeRegistry) CreateBondContract(game types.GameMetadata) (claims.BondContract, error) {
creator, ok := r.bondCreators[game.GameType] creator, ok := r.bondCreators[faultTypes.GameType(game.GameType)]
if !ok { if !ok {
return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType) return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType)
} }
......
...@@ -50,7 +50,7 @@ func (g *GameCallerCreator) CreateContract(ctx context.Context, game gameTypes.G ...@@ -50,7 +50,7 @@ func (g *GameCallerCreator) CreateContract(ctx context.Context, game gameTypes.G
if fdg, ok := g.cache.Get(game.Proxy); ok { if fdg, ok := g.cache.Get(game.Proxy); ok {
return fdg, nil return fdg, nil
} }
switch game.GameType { switch faultTypes.GameType(game.GameType) {
case faultTypes.CannonGameType, faultTypes.PermissionedGameType, faultTypes.AsteriscGameType, faultTypes.AlphabetGameType: case faultTypes.CannonGameType, faultTypes.PermissionedGameType, faultTypes.AsteriscGameType, faultTypes.AlphabetGameType:
fdg, err := contracts.NewFaultDisputeGameContract(ctx, g.m, game.Proxy, g.caller) fdg, err := contracts.NewFaultDisputeGameContract(ctx, g.m, game.Proxy, g.caller)
if err != nil { if err != nil {
......
...@@ -29,15 +29,15 @@ func TestMetadataCreator_CreateContract(t *testing.T) { ...@@ -29,15 +29,15 @@ func TestMetadataCreator_CreateContract(t *testing.T) {
}{ }{
{ {
name: "validCannonGameType", name: "validCannonGameType",
game: types.GameMetadata{GameType: faultTypes.CannonGameType, Proxy: fdgAddr}, game: types.GameMetadata{GameType: uint32(faultTypes.CannonGameType), Proxy: fdgAddr},
}, },
{ {
name: "validAsteriscGameType", name: "validAsteriscGameType",
game: types.GameMetadata{GameType: faultTypes.AsteriscGameType, Proxy: fdgAddr}, game: types.GameMetadata{GameType: uint32(faultTypes.AsteriscGameType), Proxy: fdgAddr},
}, },
{ {
name: "validAlphabetGameType", name: "validAlphabetGameType",
game: types.GameMetadata{GameType: faultTypes.AlphabetGameType, Proxy: fdgAddr}, game: types.GameMetadata{GameType: uint32(faultTypes.AlphabetGameType), Proxy: fdgAddr},
}, },
{ {
name: "InvalidGameType", name: "InvalidGameType",
......
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
challenger "github.com/ethereum-optimism/optimism/op-challenger" challenger "github.com/ethereum-optimism/optimism/op-challenger"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
...@@ -122,20 +123,20 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config, ...@@ -122,20 +123,20 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config,
func WithCannon(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) Option { func WithCannon(t *testing.T, rollupCfg *rollup.Config, l2Genesis *core.Genesis) Option {
return func(c *config.Config) { return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeCannon) c.TraceTypes = append(c.TraceTypes, types.TraceTypeCannon)
applyCannonConfig(c, t, rollupCfg, l2Genesis) applyCannonConfig(c, t, rollupCfg, l2Genesis)
} }
} }
func WithAlphabet() Option { func WithAlphabet() Option {
return func(c *config.Config) { return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet) c.TraceTypes = append(c.TraceTypes, types.TraceTypeAlphabet)
} }
} }
func WithFastGames() Option { func WithFastGames() Option {
return func(c *config.Config) { return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeFast) c.TraceTypes = append(c.TraceTypes, types.TraceTypeFast)
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment