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",
......
This diff is collapsed.
......@@ -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