Skip to content
Merged
34 changes: 17 additions & 17 deletions op-challenger/cmd/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var (
network = "op-mainnet"
testNetwork = "op-sepolia"
l2EthRpc = "http://example.com:9545"
supervisorRpc = "http://example.com/supervisor"
superRpc = "http://example.com/super"
cannonBin = "./bin/cannon"
cannonServer = "./bin/op-program"
cannonPreState = "./pre.json"
Expand Down Expand Up @@ -95,15 +95,15 @@ func TestL1Beacon(t *testing.T) {
})
}

func TestOpSupervisor(t *testing.T) {
func TestSuperNodeRpc(t *testing.T) {
t.Run("RequiredForSuperCannon", func(t *testing.T) {
verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supervisor-rpc"))
verifyArgsInvalid(t, "flag supernode-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supernode-rpc"))
})
t.Run("RequiredForSuperPermissioned", func(t *testing.T) {
verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supervisor-rpc"))
verifyArgsInvalid(t, "flag supernode-rpc is required", addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supernode-rpc"))
})
t.Run("RequiredForSuperCannonKona", func(t *testing.T) {
verifyArgsInvalid(t, "flag supervisor-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supervisor-rpc"))
verifyArgsInvalid(t, "flag supernode-rpc is required", addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supernode-rpc"))
})

for _, gameType := range gameTypes.SupportedGameTypes {
Expand All @@ -113,26 +113,26 @@ func TestOpSupervisor(t *testing.T) {
}

t.Run("NotRequiredForGameType-"+gameType.String(), func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(gameType, "--supervisor-rpc"))
configForArgs(t, addRequiredArgsExcept(gameType, "--supernode-rpc"))
})
}

t.Run("Valid-SuperCannon", func(t *testing.T) {
url := "http://localhost/supervisor"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supervisor-rpc", "--supervisor-rpc", url))
require.Equal(t, url, cfg.SupervisorRPC)
url := "http://localhost/super"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonGameType, "--supernode-rpc", "--supernode-rpc", url))
require.Equal(t, url, cfg.SuperRPC)
})

t.Run("Valid-SuperPermissioned", func(t *testing.T) {
url := "http://localhost/supervisor"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supervisor-rpc", "--supervisor-rpc", url))
require.Equal(t, url, cfg.SupervisorRPC)
url := "http://localhost/super"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperPermissionedGameType, "--supernode-rpc", "--supernode-rpc", url))
require.Equal(t, url, cfg.SuperRPC)
})

t.Run("Valid-SuperCannonKona", func(t *testing.T) {
url := "http://localhost/supervisor"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supervisor-rpc", "--supervisor-rpc", url))
require.Equal(t, url, cfg.SupervisorRPC)
url := "http://localhost/super"
cfg := configForArgs(t, addRequiredArgsExcept(gameTypes.SuperCannonKonaGameType, "--supernode-rpc", "--supernode-rpc", url))
require.Equal(t, url, cfg.SuperRPC)
})
}

Expand Down Expand Up @@ -1023,7 +1023,7 @@ func requiredArgs(gameType gameTypes.GameType) map[string]string {

func addRequiredSuperCannonArgs(args map[string]string) {
addRequiredCannonBaseArgs(args)
args["--supervisor-rpc"] = supervisorRpc
args["--supernode-rpc"] = superRpc
}

func addRequiredCannonArgs(args map[string]string) {
Expand Down Expand Up @@ -1056,7 +1056,7 @@ func addRequiredCannonKonaBaseArgs(args map[string]string) {

func addRequiredSuperCannonKonaArgs(args map[string]string) {
addRequiredCannonKonaBaseArgs(args)
args["--supervisor-rpc"] = supervisorRpc
args["--supernode-rpc"] = superRpc
}

func toArgList(req map[string]string) []string {
Expand Down
23 changes: 12 additions & 11 deletions op-challenger/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ var (
ErrMissingCannonKonaInfoFreq = errors.New("missing cannon kona info freq")
ErrMissingDepsetConfig = errors.New("missing network or depset config path")

ErrMissingRollupRpc = errors.New("missing rollup rpc url")
ErrMissingSupervisorRpc = errors.New("missing supervisor rpc url")
ErrMissingRollupRpc = errors.New("missing rollup rpc url")
ErrMissingSuperRpc = errors.New("missing super rpc url")
)

const (
Expand Down Expand Up @@ -72,9 +72,10 @@ type Config struct {

GameTypes []gameTypes.GameType // Type of games supported

RollupRpc string // L2 Rollup RPC Url
SupervisorRPC string // L2 supervisor RPC URL
L2Rpcs []string // L2 RPC Url
RollupRpc string // L2 Rollup RPC Url
SuperRPC string // L2 RPC URL for super roots
UseSuperNode bool // Temporary: True to use op-supernode APIs, false for op-supervisor APIs
L2Rpcs []string // L2 RPC Url

// Specific to the cannon trace provider
Cannon vm.Config
Expand Down Expand Up @@ -108,15 +109,15 @@ func NewInteropConfig(
gameFactoryAddress common.Address,
l1EthRpc string,
l1BeaconApi string,
supervisorRpc string,
superRpc string,
l2Rpcs []string,
datadir string,
supportedGameTypes ...gameTypes.GameType,
) Config {
return Config{
L1EthRpc: l1EthRpc,
L1Beacon: l1BeaconApi,
SupervisorRPC: supervisorRpc,
SuperRPC: superRpc,
L2Rpcs: l2Rpcs,
GameFactoryAddress: gameFactoryAddress,
MaxConcurrency: uint(runtime.NumCPU()),
Expand Down Expand Up @@ -235,8 +236,8 @@ func (c Config) Check() error {
return ErrMaxConcurrencyZero
}
if c.GameTypeEnabled(gameTypes.SuperCannonGameType) || c.GameTypeEnabled(gameTypes.SuperPermissionedGameType) {
if c.SupervisorRPC == "" {
return ErrMissingSupervisorRpc
if c.SuperRPC == "" {
return ErrMissingSuperRpc
}

if len(c.Cannon.Networks) == 0 && c.Cannon.DepsetConfigPath == "" {
Expand All @@ -255,8 +256,8 @@ func (c Config) Check() error {
}
}
if c.GameTypeEnabled(gameTypes.SuperCannonKonaGameType) {
if c.SupervisorRPC == "" {
return ErrMissingSupervisorRpc
if c.SuperRPC == "" {
return ErrMissingSuperRpc
}

if len(c.CannonKona.Networks) == 0 && c.CannonKona.DepsetConfigPath == "" {
Expand Down
14 changes: 7 additions & 7 deletions op-challenger/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
validDatadir = "/tmp/data"
validL2Rpc = "http://localhost:9545"
validRollupRpc = "http://localhost:8555"
validSupervisorRpc = "http://localhost/supervisor"
validSuperRpc = "http://localhost/super"

nonExistingFile = "path/to/nonexistent/file"

Expand Down Expand Up @@ -66,7 +66,7 @@ func ensureExists(path string) error {
}

func applyValidConfigForSuperCannon(t *testing.T, cfg *Config) {
cfg.SupervisorRPC = validSupervisorRpc
cfg.SuperRPC = validSuperRpc
applyValidConfigForCannon(t, cfg)
}

Expand Down Expand Up @@ -99,7 +99,7 @@ func applyValidConfigForCannonKona(t *testing.T, cfg *Config) {
}

func applyValidConfigForSuperCannonKona(t *testing.T, cfg *Config) {
cfg.SupervisorRPC = validSupervisorRpc
cfg.SuperRPC = validSuperRpc
applyValidConfigForCannonKona(t, cfg)
}

Expand Down Expand Up @@ -530,19 +530,19 @@ func TestRollupRpcNotRequiredForInterop(t *testing.T) {
})
}

func TestSupervisorRpc(t *testing.T) {
func TestSuperRpc(t *testing.T) {
for _, gameType := range gameTypes.SupportedGameTypes {
gameType := gameType
if gameType == gameTypes.SuperCannonGameType || gameType == gameTypes.SuperPermissionedGameType || gameType == gameTypes.SuperCannonKonaGameType {
t.Run("RequiredFor"+gameType.String(), func(t *testing.T) {
config := validConfig(t, gameType)
config.SupervisorRPC = ""
require.ErrorIs(t, config.Check(), ErrMissingSupervisorRpc)
config.SuperRPC = ""
require.ErrorIs(t, config.Check(), ErrMissingSuperRpc)
})
} else {
t.Run("NotRequiredFor"+gameType.String(), func(t *testing.T) {
config := validConfig(t, gameType)
config.SupervisorRPC = ""
config.SuperRPC = ""
require.NoError(t, config.Check())
})
}
Expand Down
20 changes: 10 additions & 10 deletions op-challenger/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ var (
Usage: "Address of L1 Beacon API endpoint to use",
EnvVars: prefixEnvVars("L1_BEACON"),
}
SupervisorRpcFlag = &cli.StringFlag{
Name: "supervisor-rpc",
Usage: "Provider URL for supervisor RPC",
EnvVars: prefixEnvVars("SUPERVISOR_RPC"),
SuperNodeRpcFlag = &cli.StringFlag{
Name: "supernode-rpc",
Usage: "Provider URL for supernode roots",
EnvVars: prefixEnvVars("SUPERNODE_RPC"),
}
RollupRpcFlag = &cli.StringFlag{
Name: "rollup-rpc",
Expand Down Expand Up @@ -267,7 +267,7 @@ var optionalFlags = []cli.Flag{
FactoryAddressFlag,
GameTypesFlag,
MaxConcurrencyFlag,
SupervisorRpcFlag,
SuperNodeRpcFlag,
L2EthRpcFlag,
L2ExperimentalEthRpcFlag,
MaxPendingTransactionsFlag,
Expand Down Expand Up @@ -338,8 +338,8 @@ func CheckCannonBaseFlags(ctx *cli.Context) error {
}

func CheckSuperCannonFlags(ctx *cli.Context) error {
if !ctx.IsSet(SupervisorRpcFlag.Name) {
return fmt.Errorf("flag %v is required", SupervisorRpcFlag.Name)
if !ctx.IsSet(SuperNodeRpcFlag.Name) {
return fmt.Errorf("flag %v is required", SuperNodeRpcFlag.Name)
}
if !ctx.IsSet(flags.NetworkFlagName) &&
!(RollupConfigFlag.IsSet(ctx, gameTypes.CannonGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonGameType) && DepsetConfigFlag.IsSet(ctx, gameTypes.CannonGameType)) {
Expand All @@ -356,8 +356,8 @@ func CheckSuperCannonFlags(ctx *cli.Context) error {
}

func CheckSuperCannonKonaFlags(ctx *cli.Context) error {
if !ctx.IsSet(SupervisorRpcFlag.Name) {
return fmt.Errorf("flag %v is required", SupervisorRpcFlag.Name)
if !ctx.IsSet(SuperNodeRpcFlag.Name) {
return fmt.Errorf("flag %v is required", SuperNodeRpcFlag.Name)
}
if !ctx.IsSet(flags.NetworkFlagName) &&
!(RollupConfigFlag.IsSet(ctx, gameTypes.CannonKonaGameType) && L2GenesisFlag.IsSet(ctx, gameTypes.CannonKonaGameType) && DepsetConfigFlag.IsSet(ctx, gameTypes.CannonKonaGameType)) {
Expand Down Expand Up @@ -601,7 +601,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
MinUpdateInterval: ctx.Duration(MinUpdateInterval.Name),
AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name),
SupervisorRPC: ctx.String(SupervisorRpcFlag.Name),
SuperRPC: ctx.String(SuperNodeRpcFlag.Name),
Cannon: vm.Config{
VmType: gameTypes.CannonGameType,
L1: l1EthRpc,
Expand Down
16 changes: 16 additions & 0 deletions op-challenger/game/client/noop_sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package client

import (
"context"

"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/eth"
)

type NoopSyncStatusValidator struct{}

func (n *NoopSyncStatusValidator) ValidateNodeSynced(_ context.Context, _ eth.BlockID) error {
return nil
}

var _ types.SyncValidator = (*NoopSyncStatusValidator)(nil)
44 changes: 29 additions & 15 deletions op-challenger/game/client/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@ package client

import (
"context"
"errors"
"fmt"

"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)

var ErrNotInSync = errors.New("local node too far behind")

type Provider struct {
ctx context.Context
logger log.Logger
cfg *config.Config
l1Client *ethclient.Client
caller *batching.MultiCaller

l2EL *ethclient.Client
rollupClient *sources.RollupClient
syncValidator *RollupSyncStatusValidator
supervisorClient *sources.SupervisorClient
toClose []func()
l2EL *ethclient.Client
rollupClient *sources.RollupClient
syncValidator *RollupSyncStatusValidator
supervisorClient *sources.SupervisorClient
superSyncValidator types.SyncValidator
superNodeClient *sources.SuperNodeClient
toClose []func()
}

func NewProvider(ctx context.Context, logger log.Logger, cfg *config.Config, l1Client *ethclient.Client) *Provider {
Expand Down Expand Up @@ -96,12 +96,26 @@ func (c *Provider) RollupClients() (*sources.RollupClient, *RollupSyncStatusVali
return rollupClient, c.syncValidator, nil
}

func (c *Provider) SuperchainClients() (*sources.SupervisorClient, *SupervisorSyncValidator, error) {
supervisorClient, err := dial.DialSupervisorClientWithTimeout(c.ctx, c.logger, c.cfg.SupervisorRPC)
if err != nil {
return nil, nil, fmt.Errorf("failed to dial supervisor: %w", err)
func (c *Provider) SuperchainClients() (*sources.SupervisorClient, *sources.SuperNodeClient, types.SyncValidator, error) {
if c.supervisorClient != nil || c.superNodeClient != nil {
return c.supervisorClient, c.superNodeClient, c.superSyncValidator, nil
}
if c.cfg.UseSuperNode {
superNodeClient, err := dial.DialSuperNodeClientWithTimeout(c.ctx, c.logger, c.cfg.SuperRPC)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to dial supernode: %w", err)
}
c.superNodeClient = superNodeClient
c.superSyncValidator = &NoopSyncStatusValidator{}
c.toClose = append(c.toClose, superNodeClient.Close)
} else {
supervisorClient, err := dial.DialSupervisorClientWithTimeout(c.ctx, c.logger, c.cfg.SuperRPC)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to dial supervisor: %w", err)
}
c.supervisorClient = supervisorClient
c.superSyncValidator = NewSupervisorSyncValidator(supervisorClient)
c.toClose = append(c.toClose, supervisorClient.Close)
}
c.supervisorClient = supervisorClient
c.toClose = append(c.toClose, supervisorClient.Close)
return supervisorClient, NewSupervisorSyncValidator(supervisorClient), nil
return c.supervisorClient, c.superNodeClient, c.superSyncValidator, nil
}
3 changes: 2 additions & 1 deletion op-challenger/game/client/rollup_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/eth"
)

Expand All @@ -27,7 +28,7 @@ func (s *RollupSyncStatusValidator) ValidateNodeSynced(ctx context.Context, game
return fmt.Errorf("failed to retrieve local node sync status: %w", err)
}
if syncStatus.CurrentL1.Number <= gameL1Head.Number {
return fmt.Errorf("%w require L1 block above %v but at %v", ErrNotInSync, gameL1Head.Number, syncStatus.CurrentL1.Number)
return fmt.Errorf("%w require L1 block above %v but at %v", types.ErrNotInSync, gameL1Head.Number, syncStatus.CurrentL1.Number)
}
return nil
}
5 changes: 3 additions & 2 deletions op-challenger/game/client/rollup_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"testing"

"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -34,7 +35,7 @@ func TestSyncStatusProvider(t *testing.T) {
},
},
statusReqErr: nil,
expected: ErrNotInSync,
expected: types.ErrNotInSync,
},
{
name: "CurrentL1EqualToGameL1Head",
Expand All @@ -45,7 +46,7 @@ func TestSyncStatusProvider(t *testing.T) {
},
},
statusReqErr: nil,
expected: ErrNotInSync,
expected: types.ErrNotInSync,
},
{
name: "CurrentL1AboveGameL1Head",
Expand Down
Loading