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

op-challenger: Improve GameType typing (#11012)

parent 1440a519
......@@ -4,10 +4,10 @@ import (
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"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"
"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: "trace-type",
Usage: "Trace types to support.",
EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "TRACE_TYPE"),
Value: config.TraceTypeCannon.String(),
Value: types.TraceTypeCannon.String(),
}
OutputRootFlag = &cli.StringFlag{
Name: "output-root",
......
......@@ -14,6 +14,7 @@ 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"
)
......@@ -38,13 +39,13 @@ var (
func TestLogLevel(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"} {
lvl := lvl
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.NotNil(t, logger)
})
......@@ -52,24 +53,24 @@ func TestLogLevel(t *testing.T) {
}
func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet))
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, config.TraceTypeAlphabet)
cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet))
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, l1Beacon, rollupRpc, l2EthRpc, datadir, types.TraceTypeAlphabet)
require.Equal(t, defaultCfg, cfg)
}
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())
}
func TestL1ETHRPCAddress(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) {
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.TxMgrConfig.L1RPCURL)
})
......@@ -77,91 +78,91 @@ 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(config.TraceTypeAlphabet, "--l1-beacon"))
verifyArgsInvalid(t, "flag l1-beacon is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--l1-beacon"))
})
t.Run("Valid", func(t *testing.T) {
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)
})
}
func TestTraceType(t *testing.T) {
t.Run("Default", func(t *testing.T) {
expectedDefault := config.TraceTypeCannon
expectedDefault := types.TraceTypeCannon
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
t.Run("Valid_"+traceType.String(), func(t *testing.T) {
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) {
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) {
t.Run("WithAllOptions", func(t *testing.T) {
argsMap := requiredArgs(config.TraceTypeCannon)
argsMap := requiredArgs(types.TraceTypeCannon)
// Add Asterisc required flags
addRequiredAsteriscArgs(argsMap)
args := toArgList(argsMap)
// Add extra trace types (cannon is already specified)
args = append(args,
"--trace-type", config.TraceTypeAlphabet.String())
"--trace-type", types.TraceTypeAlphabet.String())
args = append(args,
"--trace-type", config.TraceTypePermissioned.String())
"--trace-type", types.TraceTypePermissioned.String())
args = append(args,
"--trace-type", config.TraceTypeAsterisc.String())
"--trace-type", types.TraceTypeAsterisc.String())
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) {
argsMap := requiredArgs(config.TraceTypeCannon)
argsMap := requiredArgs(types.TraceTypeCannon)
args := toArgList(argsMap)
// Add extra trace types (cannon is already specified)
args = append(args,
"--trace-type", config.TraceTypeAlphabet.String())
"--trace-type", types.TraceTypeAlphabet.String())
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) {
argsMap := requiredArgs(config.TraceTypeCannon)
argsMap := requiredArgs(types.TraceTypeCannon)
args := toArgList(argsMap)
// 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.
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) {
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) {
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)
})
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) {
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)
})
}
......@@ -169,42 +170,42 @@ func TestGameFactoryAddress(t *testing.T) {
func TestNetwork(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
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)
})
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) {
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())
})
t.Run("Valid", func(t *testing.T) {
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)
})
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) {
// 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)
}
func TestMaxConcurrency(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
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)
})
......@@ -212,26 +213,26 @@ func TestMaxConcurrency(t *testing.T) {
verifyArgsInvalid(
t,
"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) {
verifyArgsInvalid(
t,
"max-concurrency must not be 0",
addRequiredArgs(config.TraceTypeAlphabet, "--max-concurrency", "0"))
addRequiredArgs(types.TraceTypeAlphabet, "--max-concurrency", "0"))
})
}
func TestMaxPendingTx(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
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)
})
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)
})
......@@ -239,19 +240,19 @@ func TestMaxPendingTx(t *testing.T) {
verifyArgsInvalid(
t,
"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) {
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)
})
t.Run("Valid", func(t *testing.T) {
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)
})
......@@ -259,16 +260,16 @@ func TestPollInterval(t *testing.T) {
verifyArgsInvalid(
t,
"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) {
for _, traceType := range []config.TraceType{config.TraceTypeAsterisc} {
for _, traceType := range []types.TraceType{types.TraceTypeAsterisc} {
traceType := traceType
t.Run(fmt.Sprintf("TestAsteriscBin-%v", traceType), 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) {
......@@ -283,7 +284,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscServer-%v", traceType), 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) {
......@@ -298,7 +299,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestate-%v", traceType), 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) {
......@@ -313,7 +314,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), 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) {
......@@ -418,7 +419,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscNetwork-%v", traceType), 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) {
......@@ -448,7 +449,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscRollupConfig-%v", traceType), 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) {
......@@ -459,7 +460,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscL2Genesis-%v", traceType), 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) {
......@@ -471,29 +472,29 @@ func TestAsteriscRequiredArgs(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) {
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) {
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)
})
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)
})
})
}
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
t.Run(fmt.Sprintf("TestCannonBin-%v", traceType), 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) {
......@@ -508,7 +509,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonServer-%v", traceType), 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) {
......@@ -523,7 +524,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonAbsolutePrestate-%v", traceType), 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) {
......@@ -538,7 +539,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonAbsolutePrestateBaseURL-%v", traceType), 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) {
......@@ -639,7 +640,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonNetwork-%v", traceType), 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) {
......@@ -669,7 +670,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonRollupConfig-%v", traceType), 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) {
......@@ -680,7 +681,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonL2Genesis-%v", traceType), 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) {
......@@ -692,7 +693,7 @@ func TestCannonRequiredArgs(t *testing.T) {
}
func TestDataDir(t *testing.T) {
for _, traceType := range config.TraceTypes {
for _, traceType := range types.TraceTypes {
traceType := traceType
t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) {
......@@ -701,13 +702,13 @@ func TestDataDir(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)
})
}
func TestRollupRpc(t *testing.T) {
for _, traceType := range config.TraceTypes {
for _, traceType := range types.TraceTypes {
traceType := traceType
t.Run(fmt.Sprintf("RequiredFor-%v", traceType), func(t *testing.T) {
......@@ -716,59 +717,59 @@ func TestRollupRpc(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)
})
}
func TestGameWindow(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)
})
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)
})
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)
})
}
func TestUnsafeAllowInvalidPrestate(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)
})
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)
})
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)
})
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)
})
}
func TestAdditionalBondClaimants(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)
})
t.Run("Valid-Single", func(t *testing.T) {
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.Len(t, cfg.AdditionalBondClaimants, 1)
})
......@@ -777,7 +778,7 @@ func TestAdditionalBondClaimants(t *testing.T) {
claimant1 := common.Address{0xaa}
claimant2 := common.Address{0xbb}
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())))
require.Contains(t, cfg.AdditionalBondClaimants, claimant1)
require.Contains(t, cfg.AdditionalBondClaimants, claimant2)
......@@ -787,14 +788,14 @@ func TestAdditionalBondClaimants(t *testing.T) {
t.Run("Invalid-Single", func(t *testing.T) {
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) {
claimant1 := common.Address{0xaa}
claimant2 := common.Address{0xbb}
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) {
return logger, *cfg, err
}
func addRequiredArgs(traceType config.TraceType, args ...string) []string {
func addRequiredArgs(traceType types.TraceType, args ...string) []string {
req := requiredArgs(traceType)
combined := toArgList(req)
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)
delete(req, name)
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{
"--l1-eth-rpc": l1EthRpc,
"--l1-beacon": l1Beacon,
......@@ -848,9 +849,9 @@ func requiredArgs(traceType config.TraceType) map[string]string {
"--datadir": datadir,
}
switch traceType {
case config.TraceTypeCannon, config.TraceTypePermissioned:
case types.TraceTypeCannon, types.TraceTypePermissioned:
addRequiredCannonArgs(args)
case config.TraceTypeAsterisc:
case types.TraceTypeAsterisc:
addRequiredAsteriscArgs(args)
}
return args
......
......@@ -9,6 +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"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/oppprof"
......@@ -50,45 +51,6 @@ var (
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 (
DefaultPollInterval = time.Second * 12
DefaultCannonSnapshotFreq = uint(1_000_000_000)
......@@ -122,7 +84,7 @@ type Config struct {
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
......@@ -152,7 +114,7 @@ func NewConfig(
l2RollupRpc string,
l2EthRpc string,
datadir string,
supportedTraceTypes ...TraceType,
supportedTraceTypes ...types.TraceType,
) Config {
return Config{
L1EthRpc: l1EthRpc,
......@@ -174,7 +136,7 @@ func NewConfig(
Datadir: datadir,
Cannon: vm.Config{
VmType: TraceTypeCannon.String(),
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
......@@ -182,7 +144,7 @@ func NewConfig(
InfoFreq: DefaultCannonInfoFreq,
},
Asterisc: vm.Config{
VmType: TraceTypeAsterisc.String(),
VmType: types.TraceTypeAsterisc,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
......@@ -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)
}
......@@ -222,7 +184,7 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero
}
if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypePermissioned) {
if c.TraceTypeEnabled(types.TraceTypeCannon) || c.TraceTypeEnabled(types.TraceTypePermissioned) {
if c.Cannon.VmBin == "" {
return ErrMissingCannonBin
}
......@@ -260,7 +222,7 @@ func (c Config) Check() error {
return ErrMissingCannonInfoFreq
}
}
if c.TraceTypeEnabled(TraceTypeAsterisc) {
if c.TraceTypeEnabled(types.TraceTypeAsterisc) {
if c.Asterisc.VmBin == "" {
return ErrMissingAsteriscBin
}
......
......@@ -9,6 +9,7 @@ import (
"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"
)
......@@ -32,8 +33,8 @@ var (
validAsteriscAbsolutPreStateBaseURL, _ = url.Parse("http://localhost/bar/")
)
var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned}
var asteriscTraceTypes = []TraceType{TraceTypeAsterisc}
var cannonTraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypePermissioned}
var asteriscTraceTypes = []types.TraceType{types.TraceTypeAsterisc}
func applyValidConfigForCannon(cfg *Config) {
cfg.Cannon.VmBin = validCannonBin
......@@ -49,12 +50,12 @@ func applyValidConfigForAsterisc(cfg *Config) {
cfg.Asterisc.Network = validAsteriscNetwork
}
func validConfig(traceType TraceType) Config {
func validConfig(traceType types.TraceType) Config {
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, validL1BeaconUrl, validRollupRpc, validL2Rpc, validDatadir, traceType)
if traceType == TraceTypeCannon || traceType == TraceTypePermissioned {
if traceType == types.TraceTypeCannon || traceType == types.TraceTypePermissioned {
applyValidConfigForCannon(&cfg)
}
if traceType == TraceTypeAsterisc {
if traceType == types.TraceTypeAsterisc {
applyValidConfigForAsterisc(&cfg)
}
return cfg
......@@ -62,7 +63,7 @@ func validConfig(traceType TraceType) Config {
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func TestValidConfigIsValid(t *testing.T) {
for _, traceType := range TraceTypes {
for _, traceType := range types.TraceTypes {
traceType := traceType
t.Run(traceType.String(), func(t *testing.T) {
err := validConfig(traceType).Check()
......@@ -73,38 +74,38 @@ func TestValidConfigIsValid(t *testing.T) {
func TestTxMgrConfig(t *testing.T) {
t.Run("Invalid", func(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
config.TxMgrConfig = txmgr.CLIConfig{}
require.Equal(t, config.Check().Error(), "must provide a L1 RPC url")
})
}
func TestL1EthRpcRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
config.L1EthRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC)
}
func TestL1BeaconRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
config.L1Beacon = ""
require.ErrorIs(t, config.Check(), ErrMissingL1Beacon)
}
func TestGameFactoryAddressRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
config.GameFactoryAddress = common.Address{}
require.ErrorIs(t, config.Check(), ErrMissingGameFactoryAddress)
}
func TestSelectiveClaimResolutionNotRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
require.Equal(t, false, config.SelectiveClaimResolution)
require.NoError(t, config.Check())
}
func TestGameAllowlistNotRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config := validConfig(types.TraceTypeCannon)
config.GameAllowlist = []common.Address{}
require.NoError(t, config.Check())
}
......@@ -322,33 +323,33 @@ func TestAsteriscRequiredArgs(t *testing.T) {
}
func TestDatadirRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config := validConfig(types.TraceTypeAlphabet)
config.Datadir = ""
require.ErrorIs(t, config.Check(), ErrMissingDatadir)
}
func TestMaxConcurrency(t *testing.T) {
t.Run("Required", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config := validConfig(types.TraceTypeAlphabet)
config.MaxConcurrency = 0
require.ErrorIs(t, config.Check(), ErrMaxConcurrencyZero)
})
t.Run("DefaultToNumberOfCPUs", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config := validConfig(types.TraceTypeAlphabet)
require.EqualValues(t, runtime.NumCPU(), config.MaxConcurrency)
})
}
func TestHttpPollInterval(t *testing.T) {
t.Run("Default", func(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config := validConfig(types.TraceTypeAlphabet)
require.EqualValues(t, DefaultPollInterval, config.PollInterval)
})
}
func TestRollupRpcRequired(t *testing.T) {
for _, traceType := range TraceTypes {
for _, traceType := range types.TraceTypes {
traceType := traceType
t.Run(traceType.String(), func(t *testing.T) {
config := validConfig(traceType)
......@@ -359,8 +360,8 @@ func TestRollupRpcRequired(t *testing.T) {
}
func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeAlphabet}
cfg := validConfig(types.TraceTypeCannon)
cfg.TraceTypes = []types.TraceType{types.TraceTypeCannon, types.TraceTypeAlphabet}
// Set all required options and check its valid
cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check())
......@@ -377,8 +378,8 @@ func TestRequireConfigForMultipleTraceTypesForCannon(t *testing.T) {
}
func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) {
cfg := validConfig(TraceTypeAsterisc)
cfg.TraceTypes = []TraceType{TraceTypeAsterisc, TraceTypeAlphabet}
cfg := validConfig(types.TraceTypeAsterisc)
cfg.TraceTypes = []types.TraceType{types.TraceTypeAsterisc, types.TraceTypeAlphabet}
// Set all required options and check its valid
cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check())
......@@ -395,10 +396,10 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) {
}
func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg := validConfig(types.TraceTypeCannon)
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
cfg.RollupRpc = validRollupRpc
require.NoError(t, cfg.Check())
......
......@@ -8,6 +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"
"github.com/ethereum-optimism/optimism/op-service/flags"
"github.com/ethereum-optimism/superchain-registry/superchain"
"github.com/ethereum/go-ethereum/common"
......@@ -61,9 +62,9 @@ var (
}
TraceTypeFlag = &cli.StringSliceFlag{
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"),
Value: cli.NewStringSlice(config.TraceTypeCannon.String()),
Value: cli.NewStringSlice(types.TraceTypeCannon.String()),
}
DatadirFlag = &cli.StringFlag{
Name: "datadir",
......@@ -339,7 +340,7 @@ func CheckAsteriscFlags(ctx *cli.Context) error {
return nil
}
func CheckRequired(ctx *cli.Context, traceTypes []config.TraceType) error {
func CheckRequired(ctx *cli.Context, traceTypes []types.TraceType) error {
for _, f := range requiredFlags {
if !ctx.IsSet(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 {
}
for _, traceType := range traceTypes {
switch traceType {
case config.TraceTypeCannon, config.TraceTypePermissioned:
case types.TraceTypeCannon, types.TraceTypePermissioned:
if err := CheckCannonFlags(ctx); err != nil {
return err
}
case config.TraceTypeAsterisc:
case types.TraceTypeAsterisc:
if err := CheckAsteriscFlags(ctx); err != nil {
return err
}
case config.TraceTypeAlphabet, config.TraceTypeFast:
case types.TraceTypeAlphabet, types.TraceTypeFast:
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
}
func parseTraceTypes(ctx *cli.Context) ([]config.TraceType, error) {
var traceTypes []config.TraceType
func parseTraceTypes(ctx *cli.Context) ([]types.TraceType, error) {
var traceTypes []types.TraceType
for _, typeName := range ctx.StringSlice(TraceTypeFlag.Name) {
traceType := new(config.TraceType)
traceType := new(types.TraceType)
if err := traceType.Set(typeName); err != nil {
return nil, err
}
......@@ -514,7 +515,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name),
Cannon: vm.Config{
VmType: config.TraceTypeCannon.String(),
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2: l2Rpc,
......@@ -530,7 +531,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
CannonAbsolutePreStateBaseURL: cannonPrestatesURL,
Datadir: ctx.String(DatadirFlag.Name),
Asterisc: vm.Config{
VmType: config.TraceTypeAsterisc.String(),
VmType: types.TraceTypeAsterisc,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2: l2Rpc,
......
......@@ -7,6 +7,7 @@ import (
"math/big"
"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-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
......@@ -76,7 +77,7 @@ func (f *DisputeGameFactoryContract) GetGame(ctx context.Context, idx uint64, bl
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")()
result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameImpls, gameType))
if err != nil {
......
......@@ -8,6 +8,7 @@ import (
"testing"
"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-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
......@@ -190,7 +191,7 @@ func TestGetGameFromParameters(t *testing.T) {
func TestGetGameImpl(t *testing.T) {
stubRpc, factory := setupDisputeGameFactoryTest(t)
gameType := uint32(3)
gameType := faultTypes.CannonGameType
gameImplAddr := common.Address{0xaa}
stubRpc.SetResponse(
factoryAddr,
......@@ -198,7 +199,7 @@ func TestGetGameImpl(t *testing.T) {
rpcblock.Latest,
[]interface{}{gameType},
[]interface{}{gameImplAddr})
actual, err := factory.GetGameImpl(context.Background(), gameType)
actual, err := factory.GetGameImpl(context.Background(), faultTypes.CannonGameType)
require.NoError(t, err)
require.Equal(t, gameImplAddr, actual)
}
......
......@@ -30,8 +30,8 @@ import (
type CloseFunc func()
type Registry interface {
RegisterGameType(gameType uint32, creator scheduler.PlayerCreator)
RegisterBondContract(gameType uint32, creator claims.BondContractCreator)
RegisterGameType(gameType faultTypes.GameType, creator scheduler.PlayerCreator)
RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator)
}
type OracleRegistry interface {
......@@ -73,27 +73,27 @@ func RegisterGameTypes(
}
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 {
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 {
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 {
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 {
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 {
return nil, fmt.Errorf("failed to register alphabet game type: %w", err)
}
......@@ -102,7 +102,7 @@ func RegisterGameTypes(
}
func registerAlphabet(
gameType uint32,
gameType faultTypes.GameType,
registry Registry,
oracles OracleRegistry,
ctx context.Context,
......@@ -167,7 +167,7 @@ func registerAlphabet(
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)
if err != nil {
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
}
func registerAsterisc(
gameType uint32,
gameType faultTypes.GameType,
registry Registry,
oracles OracleRegistry,
ctx context.Context,
......@@ -278,7 +278,7 @@ func registerAsterisc(
}
func registerCannon(
gameType uint32,
gameType faultTypes.GameType,
registry Registry,
oracles OracleRegistry,
ctx context.Context,
......
......@@ -11,6 +11,7 @@ import (
"time"
"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"
)
......@@ -19,7 +20,7 @@ type Metricer interface {
}
type Config struct {
VmType string
VmType types.TraceType
L1 string
L1Beacon string
L2 string
......@@ -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, ", "))
execStart := time.Now()
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
}
......@@ -3,6 +3,8 @@ package types
import (
"context"
"errors"
"fmt"
"math"
"math/big"
"time"
......@@ -18,14 +20,94 @@ var (
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 (
CannonGameType uint32 = 0
PermissionedGameType uint32 = 1
AsteriscGameType uint32 = 2
FastGameType uint32 = 254
AlphabetGameType uint32 = 255
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
}
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 {
Now() time.Time
}
......
......@@ -5,6 +5,7 @@ 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"
)
......@@ -12,27 +13,27 @@ import (
var ErrUnsupportedGameType = errors.New("unsupported game type")
type GameTypeRegistry struct {
types map[uint32]scheduler.PlayerCreator
bondCreators map[uint32]claims.BondContractCreator
types map[faultTypes.GameType]scheduler.PlayerCreator
bondCreators map[faultTypes.GameType]claims.BondContractCreator
}
func NewGameTypeRegistry() *GameTypeRegistry {
return &GameTypeRegistry{
types: make(map[uint32]scheduler.PlayerCreator),
bondCreators: make(map[uint32]claims.BondContractCreator),
types: make(map[faultTypes.GameType]scheduler.PlayerCreator),
bondCreators: make(map[faultTypes.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 uint32, creator scheduler.PlayerCreator) {
func (r *GameTypeRegistry) RegisterGameType(gameType faultTypes.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 uint32, creator claims.BondContractCreator) {
func (r *GameTypeRegistry) RegisterBondContract(gameType faultTypes.GameType, creator claims.BondContractCreator) {
if _, ok := r.bondCreators[gameType]; ok {
panic(fmt.Errorf("duplicate bond contract registered for game type: %v", gameType))
}
......@@ -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.
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 {
return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType)
}
......@@ -49,7 +50,7 @@ func (r *GameTypeRegistry) CreatePlayer(game types.GameMetadata, dir string) (sc
}
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 {
return nil, fmt.Errorf("%w: %v", ErrUnsupportedGameType, game.GameType)
}
......
......@@ -50,7 +50,7 @@ func (g *GameCallerCreator) CreateContract(ctx context.Context, game gameTypes.G
if fdg, ok := g.cache.Get(game.Proxy); ok {
return fdg, nil
}
switch game.GameType {
switch faultTypes.GameType(game.GameType) {
case faultTypes.CannonGameType, faultTypes.PermissionedGameType, faultTypes.AsteriscGameType, faultTypes.AlphabetGameType:
fdg, err := contracts.NewFaultDisputeGameContract(ctx, g.m, game.Proxy, g.caller)
if err != nil {
......
......@@ -29,15 +29,15 @@ func TestMetadataCreator_CreateContract(t *testing.T) {
}{
{
name: "validCannonGameType",
game: types.GameMetadata{GameType: faultTypes.CannonGameType, Proxy: fdgAddr},
game: types.GameMetadata{GameType: uint32(faultTypes.CannonGameType), Proxy: fdgAddr},
},
{
name: "validAsteriscGameType",
game: types.GameMetadata{GameType: faultTypes.AsteriscGameType, Proxy: fdgAddr},
game: types.GameMetadata{GameType: uint32(faultTypes.AsteriscGameType), Proxy: fdgAddr},
},
{
name: "validAlphabetGameType",
game: types.GameMetadata{GameType: faultTypes.AlphabetGameType, Proxy: fdgAddr},
game: types.GameMetadata{GameType: uint32(faultTypes.AlphabetGameType), Proxy: fdgAddr},
},
{
name: "InvalidGameType",
......
......@@ -21,6 +21,7 @@ import (
challenger "github.com/ethereum-optimism/optimism/op-challenger"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup"
......@@ -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 {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeCannon)
c.TraceTypes = append(c.TraceTypes, types.TraceTypeCannon)
applyCannonConfig(c, t, rollupCfg, l2Genesis)
}
}
func WithAlphabet() Option {
return func(c *config.Config) {
c.TraceTypes = append(c.TraceTypes, config.TraceTypeAlphabet)
c.TraceTypes = append(c.TraceTypes, types.TraceTypeAlphabet)
}
}
func WithFastGames() Option {
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