Commit e51600b4 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Migrate config over to supporting multiple L2s (#13833)

* op-challenger: Migrate config over to supporting multiple L2s

* op-challenger: Update flags to support multiple L2s

* op-dispute-mon: Keep the single network flag logic
parent 7755aac3
......@@ -173,6 +173,10 @@ func TestGameFactoryAddress(t *testing.T) {
verifyArgsInvalid(t, "flag game-factory-address or network is required", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address"))
})
t.Run("RequiredWhenMultipleNetworksSupplied", func(t *testing.T) {
verifyArgsInvalid(t, "flag game-factory-address required when multiple networks specified", addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network", "op-sepolia,op-mainnet"))
})
t.Run("Valid", func(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--game-factory-address="+addr.Hex()))
......@@ -205,7 +209,7 @@ func TestNetwork(t *testing.T) {
addr := common.Address{0xbb, 0xcc, 0xdd}
cfg := configForArgs(t, addRequiredArgsExcept(types.TraceTypeAlphabet, "--game-factory-address", "--network=1234", "--game-factory-address="+addr.Hex()))
require.Equal(t, addr, cfg.GameFactoryAddress)
require.Equal(t, "1234", cfg.Cannon.Network)
require.Equal(t, []string{"1234"}, cfg.Cannon.Networks)
})
}
......@@ -473,7 +477,7 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(traceType))
require.Equal(t, l2EthRpc, cfg.L2Rpc)
require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs)
})
})
......@@ -549,12 +553,12 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) {
delete(args, "--game-factory-address")
args["--network"] = "op-sepolia"
cfg := configForArgs(t, toArgList(args))
require.Equal(t, "op-sepolia", cfg.Asterisc.Network)
require.Equal(t, []string{"op-sepolia"}, cfg.Asterisc.Networks)
})
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork))
require.Equal(t, testNetwork, cfg.Asterisc.Network)
require.Equal(t, []string{testNetwork}, cfg.Asterisc.Networks)
})
})
......@@ -565,7 +569,7 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json"))
require.Equal(t, "rollup.json", cfg.Asterisc.RollupConfigPath)
require.Equal(t, []string{"rollup.json"}, cfg.Asterisc.RollupConfigPaths)
})
})
......@@ -576,7 +580,7 @@ func TestAsteriscBaseRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--rollup-config=rollup.json", "--l2-genesis=genesis.json"))
require.Equal(t, "genesis.json", cfg.Asterisc.L2GenesisPath)
require.Equal(t, []string{"genesis.json"}, cfg.Asterisc.L2GenesisPaths)
})
})
}
......@@ -590,7 +594,7 @@ func TestAlphabetRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(types.TraceTypeAlphabet))
require.Equal(t, l2EthRpc, cfg.L2Rpc)
require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs)
})
})
}
......@@ -694,7 +698,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgs(traceType))
require.Equal(t, l2EthRpc, cfg.L2Rpc)
require.Equal(t, []string{l2EthRpc}, cfg.L2Rpcs)
})
})
......@@ -776,7 +780,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--network", testNetwork))
require.Equal(t, testNetwork, cfg.Cannon.Network)
require.Equal(t, []string{testNetwork}, cfg.Cannon.Networks)
})
})
......@@ -795,7 +799,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json"))
require.Equal(t, "rollup.json", cfg.Cannon.RollupConfigPath)
require.Equal(t, []string{"rollup.json"}, cfg.Cannon.RollupConfigPaths)
})
})
......@@ -806,7 +810,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--network", "--cannon-rollup-config=rollup.json", "--cannon-l2-genesis=genesis.json"))
require.Equal(t, "genesis.json", cfg.Cannon.L2GenesisPath)
require.Equal(t, []string{"genesis.json"}, cfg.Cannon.L2GenesisPaths)
})
})
}
......
......@@ -75,9 +75,9 @@ type Config struct {
TraceTypes []types.TraceType // Type of traces supported
RollupRpc string // L2 Rollup RPC Url
SupervisorRPC string // L2 supervisor RPC URL
L2Rpc string // L2 RPC Url
RollupRpc string // L2 Rollup RPC Url
SupervisorRPC string // L2 supervisor RPC URL
L2Rpcs []string // L2 RPC Url
// Specific to the cannon trace provider
Cannon vm.Config
......@@ -112,7 +112,7 @@ func NewConfig(
L1EthRpc: l1EthRpc,
L1Beacon: l1BeaconApi,
RollupRpc: l2RollupRpc,
L2Rpc: l2EthRpc,
L2Rpcs: []string{l2EthRpc},
GameFactoryAddress: gameFactoryAddress,
MaxConcurrency: uint(runtime.NumCPU()),
PollInterval: DefaultPollInterval,
......@@ -131,7 +131,7 @@ func NewConfig(
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
L2s: []string{l2EthRpc},
SnapshotFreq: DefaultCannonSnapshotFreq,
InfoFreq: DefaultCannonInfoFreq,
DebugInfo: true,
......@@ -141,7 +141,7 @@ func NewConfig(
VmType: types.TraceTypeAsterisc,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
L2s: []string{l2EthRpc},
SnapshotFreq: DefaultAsteriscSnapshotFreq,
InfoFreq: DefaultAsteriscInfoFreq,
BinarySnapshots: true,
......@@ -150,7 +150,7 @@ func NewConfig(
VmType: types.TraceTypeAsteriscKona,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
L2s: []string{l2EthRpc},
SnapshotFreq: DefaultAsteriscSnapshotFreq,
InfoFreq: DefaultAsteriscInfoFreq,
BinarySnapshots: true,
......@@ -170,7 +170,7 @@ func (c Config) Check() error {
if c.L1Beacon == "" {
return ErrMissingL1Beacon
}
if c.L2Rpc == "" {
if len(c.L2Rpcs) == 0 {
return ErrMissingL2Rpc
}
if c.GameFactoryAddress == (common.Address{}) {
......
......@@ -80,7 +80,7 @@ func applyValidConfigForCannon(t *testing.T, cfg *Config) {
cfg.Cannon.VmBin = vmBin
cfg.Cannon.Server = server
cfg.CannonAbsolutePreStateBaseURL = validCannonAbsolutePreStateBaseURL
cfg.Cannon.Network = validCannonNetwork
cfg.Cannon.Networks = []string{validCannonNetwork}
}
func applyValidConfigForAsterisc(t *testing.T, cfg *Config) {
......@@ -94,7 +94,7 @@ func applyValidConfigForAsterisc(t *testing.T, cfg *Config) {
cfg.Asterisc.VmBin = vmBin
cfg.Asterisc.Server = server
cfg.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutePreStateBaseURL
cfg.Asterisc.Network = validAsteriscNetwork
cfg.Asterisc.Networks = []string{validAsteriscNetwork}
}
func applyValidConfigForAsteriscKona(t *testing.T, cfg *Config) {
......@@ -108,7 +108,7 @@ func applyValidConfigForAsteriscKona(t *testing.T, cfg *Config) {
cfg.AsteriscKona.VmBin = vmBin
cfg.AsteriscKona.Server = server
cfg.AsteriscKonaAbsolutePreStateBaseURL = validAsteriscKonaAbsolutePreStateBaseURL
cfg.AsteriscKona.Network = validAsteriscKonaNetwork
cfg.AsteriscKona.Networks = []string{validAsteriscKonaNetwork}
}
func validConfig(t *testing.T, traceType types.TraceType) Config {
......@@ -224,7 +224,7 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) {
config := validConfig(t, traceType)
config.L2Rpc = ""
config.L2Rpcs = nil
require.ErrorIs(t, config.Check(), ErrMissingL2Rpc)
})
......@@ -246,51 +246,43 @@ func TestCannonRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestCannonNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = ""
cfg.Cannon.RollupConfigPath = ""
cfg.Cannon.L2GenesisPath = "genesis.json"
cfg.Cannon.Networks = nil
cfg.Cannon.RollupConfigPaths = nil
cfg.Cannon.L2GenesisPaths = []string{"genesis.json"}
require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig)
})
t.Run(fmt.Sprintf("TestCannonNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = ""
cfg.Cannon.RollupConfigPath = "foo.json"
cfg.Cannon.L2GenesisPath = ""
cfg.Cannon.Networks = nil
cfg.Cannon.RollupConfigPaths = []string{"foo.json"}
cfg.Cannon.L2GenesisPaths = nil
require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) {
t.Run(fmt.Sprintf("TestMaySpecifyNetworkAndCustomConfigs-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = validCannonNetwork
cfg.Cannon.RollupConfigPath = "foo.json"
cfg.Cannon.L2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndRollupConfig)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = validCannonNetwork
cfg.Cannon.RollupConfigPath = ""
cfg.Cannon.L2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndL2Genesis)
cfg.Cannon.Networks = []string{validCannonNetwork}
cfg.Cannon.RollupConfigPaths = []string{"foo.json"}
cfg.Cannon.L2GenesisPaths = []string{"genesis.json"}
require.NoError(t, cfg.Check())
})
t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = "unknown"
cfg.Cannon.Networks = []string{"unknown"}
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown)
})
t.Run(fmt.Sprintf("TestNetworkMayBeAnyChainID-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = "467294"
cfg.Cannon.Networks = []string{"467294"}
require.NoError(t, cfg.Check())
})
t.Run(fmt.Sprintf("TestNetworkInvalidWhenNotEntirelyNumeric-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Cannon.Network = "467294a"
cfg.Cannon.Networks = []string{"467294a"}
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown)
})
......@@ -360,7 +352,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) {
config := validConfig(t, traceType)
config.L2Rpc = ""
config.L2Rpcs = nil
require.ErrorIs(t, config.Check(), ErrMissingL2Rpc)
})
......@@ -382,39 +374,31 @@ func TestAsteriscRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Asterisc.Network = ""
cfg.Asterisc.RollupConfigPath = ""
cfg.Asterisc.L2GenesisPath = "genesis.json"
cfg.Asterisc.Networks = nil
cfg.Asterisc.RollupConfigPaths = nil
cfg.Asterisc.L2GenesisPaths = []string{"genesis.json"}
require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig)
})
t.Run(fmt.Sprintf("TestAsteriscNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Asterisc.Network = ""
cfg.Asterisc.RollupConfigPath = "foo.json"
cfg.Asterisc.L2GenesisPath = ""
cfg.Asterisc.Networks = nil
cfg.Asterisc.RollupConfigPaths = []string{"foo.json"}
cfg.Asterisc.L2GenesisPaths = nil
require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Asterisc.Network = validAsteriscNetwork
cfg.Asterisc.RollupConfigPath = "foo.json"
cfg.Asterisc.L2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndRollupConfig)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) {
t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfigs-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Asterisc.Network = validAsteriscNetwork
cfg.Asterisc.RollupConfigPath = ""
cfg.Asterisc.L2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndL2Genesis)
cfg.Asterisc.Networks = []string{validAsteriscNetwork}
cfg.Asterisc.RollupConfigPaths = []string{"foo.json"}
cfg.Asterisc.L2GenesisPaths = []string{"genesis.json"}
require.NoError(t, cfg.Check())
})
t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.Asterisc.Network = "unknown"
cfg.Asterisc.Networks = []string{"unknown"}
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown)
})
......@@ -484,7 +468,7 @@ func TestAsteriscKonaRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) {
config := validConfig(t, traceType)
config.L2Rpc = ""
config.L2Rpcs = nil
require.ErrorIs(t, config.Check(), ErrMissingL2Rpc)
})
......@@ -506,39 +490,31 @@ func TestAsteriscKonaRequiredArgs(t *testing.T) {
t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.AsteriscKona.Network = ""
cfg.AsteriscKona.RollupConfigPath = ""
cfg.AsteriscKona.L2GenesisPath = "genesis.json"
cfg.AsteriscKona.Networks = nil
cfg.AsteriscKona.RollupConfigPaths = nil
cfg.AsteriscKona.L2GenesisPaths = []string{"genesis.json"}
require.ErrorIs(t, cfg.Check(), vm.ErrMissingRollupConfig)
})
t.Run(fmt.Sprintf("TestAsteriscKonaNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.AsteriscKona.Network = ""
cfg.AsteriscKona.RollupConfigPath = "foo.json"
cfg.AsteriscKona.L2GenesisPath = ""
cfg.AsteriscKona.Networks = nil
cfg.AsteriscKona.RollupConfigPaths = []string{"foo.json"}
cfg.AsteriscKona.L2GenesisPaths = nil
require.ErrorIs(t, cfg.Check(), vm.ErrMissingL2Genesis)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.AsteriscKona.Network = validAsteriscKonaNetwork
cfg.AsteriscKona.RollupConfigPath = "foo.json"
cfg.AsteriscKona.L2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndRollupConfig)
})
t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) {
t.Run(fmt.Sprintf("MaySpecifyNetworkAndCustomConfig-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.AsteriscKona.Network = validAsteriscKonaNetwork
cfg.AsteriscKona.RollupConfigPath = ""
cfg.AsteriscKona.L2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkAndL2Genesis)
cfg.AsteriscKona.Networks = []string{validAsteriscKonaNetwork}
cfg.AsteriscKona.RollupConfigPaths = []string{"foo.json"}
cfg.AsteriscKona.L2GenesisPaths = []string{"genesis.json"}
require.NoError(t, cfg.Check())
})
t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) {
cfg := validConfig(t, traceType)
cfg.AsteriscKona.Network = "unknown"
cfg.AsteriscKona.Networks = []string{"unknown"}
require.ErrorIs(t, cfg.Check(), vm.ErrNetworkUnknown)
})
......
......@@ -54,7 +54,11 @@ var (
Usage: "HTTP provider URL for the rollup node",
EnvVars: prefixEnvVars("ROLLUP_RPC"),
}
NetworkFlag = flags.CLINetworkFlag(EnvVarPrefix, "")
NetworkFlag = &cli.StringSliceFlag{
Name: flags.NetworkFlagName,
Usage: fmt.Sprintf("Predefined network selection. Available networks: %s", strings.Join(chaincfg.AvailableNetworks(), ", ")),
EnvVars: prefixEnvVars("NETWORK"),
}
FactoryAddressFlag = &cli.StringFlag{
Name: "game-factory-address",
Usage: "Address of the fault game factory contract.",
......@@ -84,9 +88,9 @@ var (
EnvVars: prefixEnvVars("MAX_CONCURRENCY"),
Value: uint(runtime.NumCPU()),
}
L2EthRpcFlag = &cli.StringFlag{
L2EthRpcFlag = &cli.StringSliceFlag{
Name: "l2-eth-rpc",
Usage: "L2 Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)",
Usage: "URLs of L2 JSON-RPC endpoints to use (eth and debug namespace required)",
EnvVars: prefixEnvVars("L2_ETH_RPC"),
}
MaxPendingTransactionsFlag = &cli.Uint64Flag{
......@@ -116,16 +120,16 @@ var (
}
})
RollupConfigFlag = NewVMFlag("rollup-config", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag {
return &cli.StringFlag{
return &cli.StringSliceFlag{
Name: name,
Usage: "Rollup chain parameters " + traceTypeInfo,
EnvVars: envVars,
}
})
L2GenesisFlag = NewVMFlag("l2-genesis", EnvVarPrefix, faultDisputeVMs, func(name string, envVars []string, traceTypeInfo string) cli.Flag {
return &cli.StringFlag{
return &cli.StringSliceFlag{
Name: name,
Usage: "Path to the op-geth genesis file " + traceTypeInfo,
Usage: "Paths to the op-geth genesis file " + traceTypeInfo,
EnvVars: envVars,
}
})
......@@ -435,26 +439,30 @@ func FactoryAddress(ctx *cli.Context) (common.Address, error) {
}
return gameFactoryAddress, nil
}
if ctx.IsSet(flags.NetworkFlagName) {
chainName := ctx.String(flags.NetworkFlagName)
chainCfg := chaincfg.ChainByName(chainName)
if chainCfg == nil {
var opts []string
for _, cfg := range superchain.OPChains {
opts = append(opts, cfg.Chain+"-"+cfg.Superchain)
}
return common.Address{}, fmt.Errorf("unknown chain: %v (Valid options: %v)", chainName, strings.Join(opts, ", "))
}
addrs, ok := superchain.Addresses[chainCfg.ChainID]
if !ok {
return common.Address{}, fmt.Errorf("no addresses available for chain %v", chainName)
}
if addrs.DisputeGameFactoryProxy == (superchain.Address{}) {
return common.Address{}, fmt.Errorf("dispute factory proxy not available for chain %v", chainName)
networks := ctx.StringSlice(flags.NetworkFlagName)
if len(networks) > 1 {
return common.Address{}, fmt.Errorf("flag %v required when multiple networks specified", FactoryAddressFlag.Name)
}
if len(networks) == 0 {
return common.Address{}, fmt.Errorf("flag %v or %v is required", FactoryAddressFlag.Name, flags.NetworkFlagName)
}
network := networks[0]
chainCfg := chaincfg.ChainByName(network)
if chainCfg == nil {
var opts []string
for _, cfg := range superchain.OPChains {
opts = append(opts, cfg.Chain+"-"+cfg.Superchain)
}
return common.Address(addrs.DisputeGameFactoryProxy), nil
return common.Address{}, fmt.Errorf("unknown chain: %v (Valid options: %v)", network, strings.Join(opts, ", "))
}
addrs, ok := superchain.Addresses[chainCfg.ChainID]
if !ok {
return common.Address{}, fmt.Errorf("no addresses available for chain %v", network)
}
if addrs.DisputeGameFactoryProxy == (superchain.Address{}) {
return common.Address{}, fmt.Errorf("dispute factory proxy not available for chain %v", network)
}
return common.Address{}, fmt.Errorf("flag %v or %v is required", FactoryAddressFlag.Name, flags.NetworkFlagName)
return common.Address(addrs.DisputeGameFactoryProxy), nil
}
// NewConfigFromCLI parses the Config from the provided flags or environment variables.
......@@ -523,10 +531,10 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
if err != nil {
return nil, err
}
network := ctx.String(flags.NetworkFlagName)
networks := ctx.StringSlice(flags.NetworkFlagName)
l1EthRpc := ctx.String(L1EthRpcFlag.Name)
l1Beacon := ctx.String(L1BeaconFlag.Name)
l2Rpc := ctx.String(L2EthRpcFlag.Name)
l2Rpcs := ctx.StringSlice(L2EthRpcFlag.Name)
return &config.Config{
// Required Flags
L1EthRpc: l1EthRpc,
......@@ -536,60 +544,60 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
GameAllowlist: allowedGames,
GameWindow: ctx.Duration(GameWindowFlag.Name),
MaxConcurrency: maxConcurrency,
L2Rpc: l2Rpc,
L2Rpcs: l2Rpcs,
MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name),
PollInterval: ctx.Duration(HTTPPollInterval.Name),
AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name),
SupervisorRPC: ctx.String(SupervisorRpcFlag.Name),
Cannon: vm.Config{
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2: l2Rpc,
VmBin: ctx.String(CannonBinFlag.Name),
Server: ctx.String(CannonServerFlag.Name),
Network: network,
L2Custom: ctx.Bool(CannonL2CustomFlag.Name),
RollupConfigPath: RollupConfigFlag.String(ctx, types.TraceTypeCannon),
L2GenesisPath: L2GenesisFlag.String(ctx, types.TraceTypeCannon),
SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name),
DebugInfo: true,
BinarySnapshots: true,
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2s: l2Rpcs,
VmBin: ctx.String(CannonBinFlag.Name),
Server: ctx.String(CannonServerFlag.Name),
Networks: networks,
L2Custom: ctx.Bool(CannonL2CustomFlag.Name),
RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeCannon),
L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeCannon),
SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name),
DebugInfo: true,
BinarySnapshots: true,
},
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonAbsolutePreStateBaseURL: cannonPreStatesURL,
Datadir: ctx.String(DatadirFlag.Name),
Asterisc: vm.Config{
VmType: types.TraceTypeAsterisc,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2: l2Rpc,
VmBin: ctx.String(AsteriscBinFlag.Name),
Server: ctx.String(AsteriscServerFlag.Name),
Network: network,
RollupConfigPath: RollupConfigFlag.String(ctx, types.TraceTypeAsterisc),
L2GenesisPath: L2GenesisFlag.String(ctx, types.TraceTypeAsterisc),
SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
BinarySnapshots: true,
VmType: types.TraceTypeAsterisc,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2s: l2Rpcs,
VmBin: ctx.String(AsteriscBinFlag.Name),
Server: ctx.String(AsteriscServerFlag.Name),
Networks: networks,
RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeAsterisc),
L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeAsterisc),
SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
BinarySnapshots: true,
},
AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name),
AsteriscAbsolutePreStateBaseURL: asteriscPreStatesURL,
AsteriscKona: vm.Config{
VmType: types.TraceTypeAsteriscKona,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2: l2Rpc,
VmBin: ctx.String(AsteriscBinFlag.Name),
Server: ctx.String(AsteriscKonaServerFlag.Name),
Network: network,
RollupConfigPath: RollupConfigFlag.String(ctx, types.TraceTypeAsteriscKona),
L2GenesisPath: L2GenesisFlag.String(ctx, types.TraceTypeAsteriscKona),
SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
BinarySnapshots: true,
VmType: types.TraceTypeAsteriscKona,
L1: l1EthRpc,
L1Beacon: l1Beacon,
L2s: l2Rpcs,
VmBin: ctx.String(AsteriscBinFlag.Name),
Server: ctx.String(AsteriscKonaServerFlag.Name),
Networks: networks,
RollupConfigPaths: RollupConfigFlag.StringSlice(ctx, types.TraceTypeAsteriscKona),
L2GenesisPaths: L2GenesisFlag.StringSlice(ctx, types.TraceTypeAsteriscKona),
SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
BinarySnapshots: true,
},
AsteriscKonaAbsolutePreState: ctx.String(AsteriscKonaPreStateFlag.Name),
AsteriscKonaAbsolutePreStateBaseURL: asteriscKonaPreStatesURL,
......
......@@ -57,6 +57,14 @@ func (f *VMFlag) String(ctx *cli.Context, vm types.TraceType) string {
return val
}
func (f *VMFlag) StringSlice(ctx *cli.Context, vm types.TraceType) []string {
val := ctx.StringSlice(f.TraceSpecificFlagName(vm))
if len(val) == 0 {
val = ctx.StringSlice(f.name)
}
return val
}
func (f *VMFlag) SourceFlagName(ctx *cli.Context, vm types.TraceType) string {
vmFlag := f.TraceSpecificFlagName(vm)
if ctx.IsSet(vmFlag) {
......
......@@ -47,10 +47,13 @@ func (c *clientProvider) L2HeaderSource() (utils.L2HeaderSource, error) {
if c.l2HeaderSource != nil {
return c.l2HeaderSource, nil
}
if len(c.cfg.L2Rpcs) != 1 {
return nil, fmt.Errorf("incorrect number of L2 RPCs configured, expected 1 but got %d", len(c.cfg.L2Rpcs))
}
l2Client, err := ethclient.DialContext(c.ctx, c.cfg.L2Rpc)
l2Client, err := ethclient.DialContext(c.ctx, c.cfg.L2Rpcs[0])
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", c.cfg.L2Rpc, err)
return nil, fmt.Errorf("dial l2 client %v: %w", c.cfg.L2Rpcs[0], err)
}
c.l2HeaderSource = l2Client
c.toClose = append(c.toClose, l2Client.Close)
......
......@@ -29,11 +29,9 @@ var (
ErrMissingBin = errors.New("missing bin")
ErrMissingServer = errors.New("missing server")
ErrMissingRollupConfig = errors.New("missing network or rollup config path")
ErrMissingL2Genesis = errors.New("missing network or l2 genesis path")
ErrNetworkAndRollupConfig = errors.New("only specify one of network or rollup config path")
ErrNetworkAndL2Genesis = errors.New("only specify one of network or l2 genesis path")
ErrNetworkUnknown = errors.New("unknown network")
ErrMissingRollupConfig = errors.New("missing network or rollup config path")
ErrMissingL2Genesis = errors.New("missing network or l2 genesis path")
ErrNetworkUnknown = errors.New("unknown network")
)
type Metricer = metrics.TypedVmMetricer
......@@ -48,14 +46,14 @@ type Config struct {
BinarySnapshots bool // Whether to use binary snapshots instead of JSON
// Host Configuration
L1 string
L1Beacon string
L2 string
Server string // Path to the executable that provides the pre-image oracle server
Network string
L2Custom bool
RollupConfigPath string
L2GenesisPath string
L1 string
L1Beacon string
L2s []string
Server string // Path to the executable that provides the pre-image oracle server
Networks []string
L2Custom bool
RollupConfigPaths []string
L2GenesisPaths []string
}
func (c *Config) Check() error {
......@@ -73,24 +71,20 @@ func (c *Config) Check() error {
return fmt.Errorf("%w: %w", ErrMissingServer, err)
}
if c.Network == "" {
if c.RollupConfigPath == "" {
if len(c.Networks) == 0 {
if len(c.RollupConfigPaths) == 0 {
return ErrMissingRollupConfig
}
if c.L2GenesisPath == "" {
if len(c.L2GenesisPaths) == 0 {
return ErrMissingL2Genesis
}
} else {
if c.RollupConfigPath != "" {
return ErrNetworkAndRollupConfig
}
if c.L2GenesisPath != "" {
return ErrNetworkAndL2Genesis
}
if ch := chaincfg.ChainByName(c.Network); ch == nil {
// Check if this looks like a chain ID that could be a custom chain configuration.
if _, err := strconv.ParseUint(c.Network, 10, 32); err != nil {
return fmt.Errorf("%w: %v", ErrNetworkUnknown, c.Network)
for _, network := range c.Networks {
if ch := chaincfg.ChainByName(network); ch == nil {
// Check if this looks like a chain ID that could be a custom chain configuration.
if _, err := strconv.ParseUint(network, 10, 32); err != nil {
return fmt.Errorf("%w: %v", ErrNetworkUnknown, network)
}
}
}
}
......@@ -193,12 +187,12 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64
memoryUsed = fmt.Sprintf("%d", uint64(info.MemoryUsed))
e.metrics.RecordMemoryUsed(uint64(info.MemoryUsed))
e.metrics.RecordSteps(info.Steps)
e.metrics.RecordRmwSuccessCount(uint64(info.RmwSuccessCount))
e.metrics.RecordRmwFailCount(uint64(info.RmwFailCount))
e.metrics.RecordMaxStepsBetweenLLAndSC(uint64(info.MaxStepsBetweenLLAndSC))
e.metrics.RecordReservationInvalidationCount(uint64(info.ReservationInvalidationCount))
e.metrics.RecordForcedPreemptionCount(uint64(info.ForcedPreemptionCount))
e.metrics.RecordIdleStepCountThread0(uint64(info.IdleStepCountThread0))
e.metrics.RecordRmwSuccessCount(info.RmwSuccessCount)
e.metrics.RecordRmwFailCount(info.RmwFailCount)
e.metrics.RecordMaxStepsBetweenLLAndSC(info.MaxStepsBetweenLLAndSC)
e.metrics.RecordReservationInvalidationCount(info.ReservationInvalidationCount)
e.metrics.RecordForcedPreemptionCount(info.ForcedPreemptionCount)
e.metrics.RecordIdleStepCountThread0(info.IdleStepCountThread0)
}
}
e.logger.Info("VM execution complete", "time", execTime, "memory", memoryUsed)
......
......@@ -28,10 +28,10 @@ func TestGenerateProof(t *testing.T) {
VmType: "test",
L1: "http://localhost:8888",
L1Beacon: "http://localhost:9000",
L2: "http://localhost:9999",
L2s: []string{"http://localhost:9999", "http://localhost:9999/two"},
VmBin: "./bin/testvm",
Server: "./bin/testserver",
Network: "op-test",
Networks: []string{"op-test", "op-other"},
SnapshotFreq: 500,
InfoFreq: 900,
}
......@@ -57,7 +57,7 @@ func TestGenerateProof(t *testing.T) {
}
captureExec := func(t *testing.T, cfg Config, proofAt uint64, m Metricer) (string, string, map[string]string) {
executor := NewExecutor(testlog.Logger(t, log.LevelInfo), m, cfg, NewOpProgramServerExecutor(testlog.Logger(t, log.LvlInfo)), prestate, inputs)
executor := NewExecutor(testlog.Logger(t, log.LevelInfo), m, cfg, &noArgServerExecutor{}, prestate, inputs)
executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64, binary bool) (string, error) {
return input, nil
}
......@@ -88,69 +88,8 @@ func TestGenerateProof(t *testing.T) {
return binary, subcommand, args
}
t.Run("Network", func(t *testing.T) {
m := newMetrics()
cfg.Network = "mainnet"
cfg.RollupConfigPath = ""
cfg.L2GenesisPath = ""
cfg.DebugInfo = true
binary, subcommand, args := captureExec(t, cfg, 150_000_000, m)
require.DirExists(t, filepath.Join(dir, PreimagesDir))
require.DirExists(t, filepath.Join(dir, utils.ProofsDir))
require.DirExists(t, filepath.Join(dir, SnapsDir))
require.Equal(t, cfg.VmBin, binary)
require.Equal(t, "run", subcommand)
require.Equal(t, input, args["--input"])
require.Contains(t, args, "--meta")
require.Equal(t, "", args["--meta"])
require.Equal(t, FinalStatePath(dir, cfg.BinarySnapshots), args["--output"])
require.Equal(t, "=150000000", args["--proof-at"])
require.Equal(t, "=150000001", args["--stop-at"])
require.Equal(t, "%500", args["--snapshot-at"])
require.Equal(t, "%900", args["--info-at"])
// Slight quirk of how we pair off args
// The server binary winds up as the key and the first arg --server as the value which has no value
// Then everything else pairs off correctly again
require.Equal(t, "--server", args[cfg.Server])
require.Equal(t, cfg.L1, args["--l1"])
require.Equal(t, cfg.L1Beacon, args["--l1.beacon"])
require.Equal(t, cfg.L2, args["--l2"])
require.Equal(t, filepath.Join(dir, PreimagesDir), args["--datadir"])
require.Equal(t, filepath.Join(dir, utils.ProofsDir, "%d.json.gz"), args["--proof-fmt"])
require.Equal(t, filepath.Join(dir, SnapsDir, "%d.json.gz"), args["--snapshot-fmt"])
require.Equal(t, cfg.Network, args["--network"])
require.NotContains(t, args, "--rollup.config")
require.NotContains(t, args, "--l2.genesis")
// Local game inputs
require.Equal(t, inputs.L1Head.Hex(), args["--l1.head"])
require.Equal(t, inputs.L2Head.Hex(), args["--l2.head"])
require.Equal(t, inputs.L2OutputRoot.Hex(), args["--l2.outputroot"])
require.Equal(t, inputs.L2Claim.Hex(), args["--l2.claim"])
require.Equal(t, "3333", args["--l2.blocknumber"])
// Check metrics
validateMetrics(t, m, info, cfg)
})
t.Run("RollupAndGenesis", func(t *testing.T) {
m := newMetrics()
cfg.Network = ""
cfg.RollupConfigPath = "rollup.json"
cfg.L2GenesisPath = "genesis.json"
cfg.DebugInfo = false
_, _, args := captureExec(t, cfg, 150_000_000, m)
require.NotContains(t, args, "--network")
require.Equal(t, cfg.RollupConfigPath, args["--rollup.config"])
require.Equal(t, cfg.L2GenesisPath, args["--l2.genesis"])
validateMetrics(t, m, info, cfg)
})
t.Run("NoStopAtWhenProofIsMaxUInt", func(t *testing.T) {
m := newMetrics()
cfg.Network = "mainnet"
cfg.RollupConfigPath = "rollup.json"
cfg.L2GenesisPath = "genesis.json"
cfg.DebugInfo = true
_, _, args := captureExec(t, cfg, math.MaxUint64, m)
// stop-at would need to be one more than the proof step which would overflow back to 0
......@@ -161,7 +100,6 @@ func TestGenerateProof(t *testing.T) {
t.Run("BinarySnapshots", func(t *testing.T) {
m := newMetrics()
cfg.Network = "mainnet"
cfg.BinarySnapshots = true
_, _, args := captureExec(t, cfg, 100, m)
require.Equal(t, filepath.Join(dir, SnapsDir, "%d.bin.gz"), args["--snapshot-fmt"])
......@@ -170,7 +108,6 @@ func TestGenerateProof(t *testing.T) {
t.Run("JsonSnapshots", func(t *testing.T) {
m := newMetrics()
cfg.Network = "mainnet"
cfg.BinarySnapshots = false
_, _, args := captureExec(t, cfg, 100, m)
require.Equal(t, filepath.Join(dir, SnapsDir, "%d.json.gz"), args["--snapshot-fmt"])
......@@ -257,3 +194,9 @@ func (c *capturingVmMetrics) RecordIdleStepCountThread0(val uint64) {
}
var _ Metricer = (*capturingVmMetrics)(nil)
type noArgServerExecutor struct{}
func (n *noArgServerExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.LocalGameInputs) ([]string, error) {
return nil, nil
}
......@@ -23,12 +23,15 @@ func NewNativeKonaExecutor() *KonaExecutor {
}
func (s *KonaExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.LocalGameInputs) ([]string, error) {
if len(cfg.L2s) != 1 || len(cfg.RollupConfigPaths) > 1 || len(cfg.Networks) > 1 {
return nil, errors.New("multiple L2s specified but only one supported")
}
args := []string{
cfg.Server,
"single",
"--l1-node-address", cfg.L1,
"--l1-beacon-address", cfg.L1Beacon,
"--l2-node-address", cfg.L2,
"--l2-node-address", cfg.L2s[0],
"--l1-head", inputs.L1Head.Hex(),
"--l2-head", inputs.L2Head.Hex(),
"--l2-output-root", inputs.L2OutputRoot.Hex(),
......@@ -43,14 +46,14 @@ func (s *KonaExecutor) OracleCommand(cfg Config, dataDir string, inputs utils.Lo
args = append(args, "--data-dir", dataDir)
}
if cfg.RollupConfigPath != "" {
args = append(args, "--rollup-config-path", cfg.RollupConfigPath)
if len(cfg.RollupConfigPaths) > 0 {
args = append(args, "--rollup-config-path", cfg.RollupConfigPaths[0])
} else {
if cfg.Network == "" {
if len(cfg.Networks) == 0 {
return nil, errors.New("network is not defined")
}
chainCfg := chaincfg.ChainByName(cfg.Network)
chainCfg := chaincfg.ChainByName(cfg.Networks[0])
args = append(args, "--l2-chain-id", strconv.FormatUint(chainCfg.ChainID, 10))
}
......
......@@ -15,9 +15,9 @@ func TestKonaFillHostCommand(t *testing.T) {
cfg := Config{
L1: "http://localhost:8888",
L1Beacon: "http://localhost:9000",
L2: "http://localhost:9999",
L2s: []string{"http://localhost:9999"},
Server: "./bin/mockserver",
Network: "op-mainnet",
Networks: []string{"op-mainnet"},
}
inputs := utils.LocalGameInputs{
L1Head: common.Hash{0x11},
......
......@@ -2,6 +2,7 @@ package vm
import (
"errors"
"strings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum/go-ethereum/common"
......@@ -31,7 +32,7 @@ func (s *KonaSuperExecutor) OracleCommand(cfg Config, dataDir string, inputs uti
"super",
"--l1-node-address", cfg.L1,
"--l1-beacon-address", cfg.L1Beacon,
"--l2-node-addresses", cfg.L2,
"--l2-node-addresses", strings.Join(cfg.L2s, ","),
"--l1-head", inputs.L1Head.Hex(),
"--agreed-l2-pre-state", common.Bytes2Hex(inputs.AgreedPreState),
"--claimed-l2-post-state", inputs.L2Claim.Hex(),
......@@ -45,8 +46,8 @@ func (s *KonaSuperExecutor) OracleCommand(cfg Config, dataDir string, inputs uti
args = append(args, "--data-dir", dataDir)
}
if cfg.RollupConfigPath != "" {
args = append(args, "--rollup-config-paths", cfg.RollupConfigPath)
if len(cfg.RollupConfigPaths) != 0 {
args = append(args, "--rollup-config-paths", strings.Join(cfg.RollupConfigPaths, ","))
}
return args, nil
......
......@@ -2,6 +2,7 @@ package vm
import (
"context"
"strings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum/go-ethereum/log"
......@@ -22,7 +23,7 @@ func (s *OpProgramServerExecutor) OracleCommand(cfg Config, dataDir string, inpu
cfg.Server, "--server",
"--l1", cfg.L1,
"--l1.beacon", cfg.L1Beacon,
"--l2", cfg.L2,
"--l2", strings.Join(cfg.L2s, ","),
"--datadir", dataDir,
"--l1.head", inputs.L1Head.Hex(),
"--l2.head", inputs.L2Head.Hex(),
......@@ -30,14 +31,14 @@ func (s *OpProgramServerExecutor) OracleCommand(cfg Config, dataDir string, inpu
"--l2.claim", inputs.L2Claim.Hex(),
"--l2.blocknumber", inputs.L2BlockNumber.Text(10),
}
if cfg.Network != "" {
args = append(args, "--network", cfg.Network)
if len(cfg.Networks) != 0 {
args = append(args, "--network", strings.Join(cfg.Networks, ","))
}
if cfg.RollupConfigPath != "" {
args = append(args, "--rollup.config", cfg.RollupConfigPath)
if len(cfg.RollupConfigPaths) != 0 {
args = append(args, "--rollup.config", strings.Join(cfg.RollupConfigPaths, ","))
}
if cfg.L2GenesisPath != "" {
args = append(args, "--l2.genesis", cfg.L2GenesisPath)
if len(cfg.L2GenesisPaths) != 0 {
args = append(args, "--l2.genesis", strings.Join(cfg.L2GenesisPaths, ","))
}
var logLevel string
if s.logger.Enabled(context.Background(), log.LevelTrace) {
......
......@@ -4,6 +4,7 @@ import (
"fmt"
"log/slog"
"math/big"
"strings"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
......@@ -34,7 +35,7 @@ func TestOpProgramFillHostCommand(t *testing.T) {
cfg := Config{
L1: "http://localhost:8888",
L1Beacon: "http://localhost:9000",
L2: "http://localhost:9999",
L2s: []string{"http://localhost:9999", "http://localhost:9999/two"},
Server: "./bin/mockserver",
}
inputs := utils.LocalGameInputs{
......@@ -54,7 +55,7 @@ func TestOpProgramFillHostCommand(t *testing.T) {
require.Equal(t, "--server", pairs[cfg.Server])
require.Equal(t, cfg.L1, pairs["--l1"])
require.Equal(t, cfg.L1Beacon, pairs["--l1.beacon"])
require.Equal(t, cfg.L2, pairs["--l2"])
require.Equal(t, strings.Join(cfg.L2s, ","), pairs["--l2"])
require.Equal(t, dir, pairs["--datadir"])
require.Equal(t, inputs.L1Head.Hex(), pairs["--l1.head"])
require.Equal(t, inputs.L2Head.Hex(), pairs["--l2.head"])
......@@ -73,12 +74,19 @@ func TestOpProgramFillHostCommand(t *testing.T) {
t.Run("WithNetwork", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.Network = "op-test"
c.Networks = []string{"op-test"}
})
require.Equal(t, "op-test", pairs["--network"])
})
t.Run("WithL2ChainID", func(t *testing.T) {
t.Run("WithMultipleNetworks", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.Networks = []string{"op-test", "op-other"}
})
require.Equal(t, "op-test,op-other", pairs["--network"])
})
t.Run("WithL2Custom", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.L2Custom = true
})
......@@ -87,23 +95,37 @@ func TestOpProgramFillHostCommand(t *testing.T) {
t.Run("WithRollupConfigPath", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.RollupConfigPath = "rollup.config.json"
c.RollupConfigPaths = []string{"rollup.config.json"}
})
require.Equal(t, "rollup.config.json", pairs["--rollup.config"])
})
t.Run("WithMultipleRollupConfigPaths", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.RollupConfigPaths = []string{"rollup.config.json", "rollup2.json"}
})
require.Equal(t, "rollup.config.json,rollup2.json", pairs["--rollup.config"])
})
t.Run("WithL2GenesisPath", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.L2GenesisPath = "genesis.json"
c.L2GenesisPaths = []string{"genesis.json"}
})
require.Equal(t, "genesis.json", pairs["--l2.genesis"])
})
t.Run("WithMultipleL2GenesisPaths", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.L2GenesisPaths = []string{"genesis.json", "genesis2.json"}
})
require.Equal(t, "genesis.json,genesis2.json", pairs["--l2.genesis"])
})
t.Run("WithAllExtras", func(t *testing.T) {
pairs := oracleCommand(t, log.LvlInfo, func(c *Config) {
c.Network = "op-test"
c.RollupConfigPath = "rollup.config.json"
c.L2GenesisPath = "genesis.json"
c.Networks = []string{"op-test"}
c.RollupConfigPaths = []string{"rollup.config.json"}
c.L2GenesisPaths = []string{"genesis.json"}
})
require.Equal(t, "op-test", pairs["--network"])
require.Equal(t, "rollup.config.json", pairs["--rollup.config"])
......
......@@ -2,9 +2,11 @@ package flags
import (
"fmt"
"strings"
challengerFlags "github.com/ethereum-optimism/optimism/op-challenger/flags"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-service/flags"
"github.com/ethereum-optimism/superchain-registry/superchain"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-dispute-mon/config"
......@@ -115,7 +117,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
if err := CheckRequired(ctx); err != nil {
return nil, err
}
gameFactoryAddress, err := challengerFlags.FactoryAddress(ctx)
gameFactoryAddress, err := FactoryAddress(ctx)
if err != nil {
return nil, err
}
......@@ -165,3 +167,34 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
PprofConfig: pprofConfig,
}, nil
}
func FactoryAddress(ctx *cli.Context) (common.Address, error) {
// Use FactoryAddressFlag in preference to Network. Allows overriding the default dispute game factory.
if ctx.IsSet(GameFactoryAddressFlag.Name) {
gameFactoryAddress, err := opservice.ParseAddress(ctx.String(GameFactoryAddressFlag.Name))
if err != nil {
return common.Address{}, err
}
return gameFactoryAddress, nil
}
if ctx.IsSet(flags.NetworkFlagName) {
chainName := ctx.String(flags.NetworkFlagName)
chainCfg := chaincfg.ChainByName(chainName)
if chainCfg == nil {
var opts []string
for _, cfg := range superchain.OPChains {
opts = append(opts, cfg.Chain+"-"+cfg.Superchain)
}
return common.Address{}, fmt.Errorf("unknown chain: %v (Valid options: %v)", chainName, strings.Join(opts, ", "))
}
addrs, ok := superchain.Addresses[chainCfg.ChainID]
if !ok {
return common.Address{}, fmt.Errorf("no addresses available for chain %v", chainName)
}
if addrs.DisputeGameFactoryProxy == (superchain.Address{}) {
return common.Address{}, fmt.Errorf("dispute factory proxy not available for chain %v", chainName)
}
return common.Address(addrs.DisputeGameFactoryProxy), nil
}
return common.Address{}, fmt.Errorf("flag %v or %v is required", GameFactoryAddressFlag.Name, flags.NetworkFlagName)
}
......@@ -8,7 +8,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
......@@ -48,16 +47,13 @@ func RunKonaNative(
rollupCfgPaths[i] = rollupConfigPath
}
joinedRollupCfgPaths := strings.Join(rollupCfgPaths, ",")
joinedL2Rpcs := strings.Join(l2Rpcs, ",")
// Run the fault proof program from the state transition from L2 block L2Blocknumber - 1 -> L2BlockNumber.
vmCfg := vm.Config{
L1: l1Rpc,
L1Beacon: l1BeaconRpc,
L2: joinedL2Rpcs,
RollupConfigPath: joinedRollupCfgPaths,
Server: konaHostPath,
L1: l1Rpc,
L1Beacon: l1BeaconRpc,
L2s: l2Rpcs,
RollupConfigPaths: rollupCfgPaths,
Server: konaHostPath,
}
inputs := utils.LocalGameInputs{
L1Head: fixtureInputs.L1Head,
......
......@@ -137,13 +137,13 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config,
require.NoError(err, "marshall l2 genesis config")
genesisFile := filepath.Join(c.Datadir, "l2-genesis.json")
require.NoError(os.WriteFile(genesisFile, genesisBytes, 0o644))
c.Cannon.L2GenesisPath = genesisFile
c.Cannon.L2GenesisPaths = []string{genesisFile}
rollupBytes, err := json.Marshal(rollupCfg)
require.NoError(err, "marshall rollup config")
rollupFile := filepath.Join(c.Datadir, "rollup.json")
require.NoError(os.WriteFile(rollupFile, rollupBytes, 0o644))
c.Cannon.RollupConfigPath = rollupFile
c.Cannon.RollupConfigPaths = []string{rollupFile}
}
func WithCannon(t *testing.T, system System) Option {
......
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