Commit bbd8b86f authored by Adrian Sutton's avatar Adrian Sutton

op-challenger: Support multiple trace types in the config.

parent 7203324a
......@@ -46,14 +46,14 @@ func TestLogLevel(t *testing.T) {
func TestDefaultCLIOptionsMatchDefaultConfig(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(config.TraceTypeAlphabet))
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, config.TraceTypeAlphabet, true, datadir)
defaultCfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, true, datadir, config.TraceTypeAlphabet)
// Add in the extra CLI options required when using alphabet trace type
defaultCfg.AlphabetTrace = alphabetTrace
require.Equal(t, defaultCfg, cfg)
}
func TestDefaultConfigIsValid(t *testing.T) {
cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, config.TraceTypeAlphabet, true, datadir)
cfg := config.NewConfig(common.HexToAddress(gameFactoryAddressValue), l1EthRpc, true, datadir, config.TraceTypeAlphabet)
// Add in options that are required based on the specific trace type
// To avoid needing to specify unused options, these aren't included in the params for NewConfig
cfg.AlphabetTrace = alphabetTrace
......@@ -82,7 +82,7 @@ func TestTraceType(t *testing.T) {
traceType := traceType
t.Run("Valid_"+traceType.String(), func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(traceType))
require.Equal(t, traceType, cfg.TraceType)
require.Equal(t, []config.TraceType{traceType}, cfg.TraceTypes)
})
}
......
......@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"runtime"
"slices"
"time"
"github.com/ethereum/go-ethereum/common"
......@@ -15,7 +16,7 @@ import (
)
var (
ErrMissingTraceType = errors.New("missing trace type")
ErrMissingTraceType = errors.New("no supported trace types specified")
ErrMissingDatadir = errors.New("missing datadir")
ErrMaxConcurrencyZero = errors.New("max concurrency must not be 0")
ErrMissingCannonL2 = errors.New("missing cannon L2")
......@@ -108,7 +109,7 @@ type Config struct {
MaxConcurrency uint // Maximum number of threads to use when progressing games
PollInterval time.Duration // Polling interval for latest-block subscription when using an HTTP RPC provider
TraceType TraceType // Type of trace
TraceTypes []TraceType // Type of traces supported
// Specific to the alphabet trace provider
AlphabetTrace string // String for the AlphabetTraceProvider
......@@ -135,9 +136,9 @@ type Config struct {
func NewConfig(
gameFactoryAddress common.Address,
l1EthRpc string,
traceType TraceType,
agreeWithProposedOutput bool,
datadir string,
supportedTraceTypes ...TraceType,
) Config {
return Config{
L1EthRpc: l1EthRpc,
......@@ -147,7 +148,7 @@ func NewConfig(
AgreeWithProposedOutput: agreeWithProposedOutput,
TraceType: traceType,
TraceTypes: supportedTraceTypes,
TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc, txmgr.DefaultChallengerFlagValues),
MetricsConfig: opmetrics.DefaultCLIConfig(),
......@@ -161,6 +162,10 @@ func NewConfig(
}
}
func (c Config) TraceTypeEnabled(t TraceType) bool {
return slices.Contains(c.TraceTypes, t)
}
func (c Config) Check() error {
if c.L1EthRpc == "" {
return ErrMissingL1EthRPC
......@@ -168,7 +173,7 @@ func (c Config) Check() error {
if c.GameFactoryAddress == (common.Address{}) {
return ErrMissingGameFactoryAddress
}
if c.TraceType == "" {
if len(c.TraceTypes) == 0 {
return ErrMissingTraceType
}
if c.Datadir == "" {
......@@ -177,12 +182,12 @@ func (c Config) Check() error {
if c.MaxConcurrency == 0 {
return ErrMaxConcurrencyZero
}
if c.TraceType == TraceTypeOutputCannon {
if c.TraceTypeEnabled(TraceTypeOutputCannon) {
if c.RollupRpc == "" {
return ErrMissingRollupRpc
}
}
if c.TraceType == TraceTypeCannon || c.TraceType == TraceTypeOutputCannon {
if c.TraceTypeEnabled(TraceTypeCannon) || c.TraceTypeEnabled(TraceTypeOutputCannon) {
if c.CannonBin == "" {
return ErrMissingCannonBin
}
......@@ -220,7 +225,7 @@ func (c Config) Check() error {
return ErrMissingCannonInfoFreq
}
}
if c.TraceType == TraceTypeAlphabet && c.AlphabetTrace == "" {
if c.TraceTypeEnabled(TraceTypeAlphabet) && c.AlphabetTrace == "" {
return ErrMissingAlphabetTrace
}
if err := c.TxMgrConfig.Check(); err != nil {
......
......@@ -25,7 +25,7 @@ var (
)
func validConfig(traceType TraceType) Config {
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, traceType, agreeWithProposedOutput, validDatadir)
cfg := NewConfig(validGameFactoryAddress, validL1EthRpc, agreeWithProposedOutput, validDatadir, traceType)
switch traceType {
case TraceTypeAlphabet:
cfg.AlphabetTrace = validAlphabetTrace
......@@ -194,3 +194,26 @@ func TestNetworkMustBeValid(t *testing.T) {
cfg.CannonNetwork = "unknown"
require.ErrorIs(t, cfg.Check(), ErrCannonNetworkUnknown)
}
func TestRequireConfigForAllSupportedTraceTypes(t *testing.T) {
cfg := validConfig(TraceTypeCannon)
cfg.TraceTypes = []TraceType{TraceTypeCannon, TraceTypeOutputCannon, TraceTypeAlphabet}
// Set all required options and check its valid
cfg.RollupRpc = validRollupRpc
cfg.AlphabetTrace = validAlphabetTrace
require.NoError(t, cfg.Check())
// Require output cannon specific args
cfg.RollupRpc = ""
require.ErrorIs(t, cfg.Check(), ErrMissingRollupRpc)
cfg.RollupRpc = validRollupRpc
// Require cannon specific args
cfg.CannonL2 = ""
require.ErrorIs(t, cfg.Check(), ErrMissingCannonL2)
cfg.CannonL2 = validCannonL2
// Require alphabet specific args
cfg.AlphabetTrace = ""
require.ErrorIs(t, cfg.Check(), ErrMissingAlphabetTrace)
}
......@@ -272,7 +272,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
return &config.Config{
// Required Flags
L1EthRpc: ctx.String(L1EthRpcFlag.Name),
TraceType: traceTypeFlag,
TraceTypes: []config.TraceType{traceTypeFlag},
GameFactoryAddress: gameFactoryAddress,
GameAllowlist: allowedGames,
GameWindow: ctx.Duration(GameWindowFlag.Name),
......
......@@ -35,8 +35,7 @@ func RegisterGameTypes(
txMgr txmgr.TxManager,
client bind.ContractCaller,
) {
switch cfg.TraceType {
case config.TraceTypeCannon:
if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
provider, err := cannon.NewTraceProvider(ctx, logger, m, cfg, client, dir, addr, gameDepth)
if err != nil {
......@@ -52,7 +51,8 @@ func RegisterGameTypes(
return NewGamePlayer(ctx, logger, m, cfg, dir, game.Proxy, txMgr, client, resourceCreator)
}
registry.RegisterGameType(cannonGameType, playerCreator)
case config.TraceTypeAlphabet:
}
if cfg.TraceTypeEnabled(config.TraceTypeAlphabet) {
resourceCreator := func(addr common.Address, gameDepth uint64, dir string) (faultTypes.TraceProvider, faultTypes.OracleUpdater, error) {
provider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth)
updater := alphabet.NewOracleUpdater(logger)
......
......@@ -24,7 +24,7 @@ func TestGenerateProof(t *testing.T) {
input := "starting.json"
tempDir := t.TempDir()
dir := filepath.Join(tempDir, "gameDir")
cfg := config.NewConfig(common.Address{0xbb}, "http://localhost:8888", config.TraceTypeCannon, true, tempDir)
cfg := config.NewConfig(common.Address{0xbb}, "http://localhost:8888", true, tempDir, config.TraceTypeCannon)
cfg.CannonAbsolutePreState = "pre.json"
cfg.CannonBin = "./bin/cannon"
cfg.CannonServer = "./bin/op-program"
......
......@@ -126,7 +126,7 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st
func NewChallengerConfig(t *testing.T, l1Endpoint string, options ...Option) *config.Config {
// Use the NewConfig method to ensure we pick up any defaults that are set.
cfg := config.NewConfig(common.Address{}, l1Endpoint, config.TraceTypeAlphabet, true, t.TempDir())
cfg := config.NewConfig(common.Address{}, l1Endpoint, true, t.TempDir(), config.TraceTypeAlphabet)
cfg.TxMgrConfig.NumConfirmations = 1
cfg.TxMgrConfig.ReceiptQueryInterval = 1 * time.Second
if cfg.MaxConcurrency > 4 {
......
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