From e3ca49d05ea2d416d5ef2eea508cdce7532b33b5 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 12 Jul 2024 01:16:26 -0400 Subject: [PATCH] feat(challenger): `AsteriscKona` trace type Adds support for the new `asterisc-kona` game type in the `op-challenger` --- op-challenger/config/config.go | 17 +++- op-challenger/flags/flags.go | 52 +++++++++- op-challenger/game/fault/register.go | 23 +++-- .../game/fault/trace/asterisc/provider.go | 4 +- .../game/fault/trace/cannon/provider.go | 4 +- .../fault/trace/outputs/output_asterisc.go | 2 +- .../game/fault/trace/outputs/output_cannon.go | 2 +- op-challenger/game/fault/trace/vm/executor.go | 47 ++++----- .../game/fault/trace/vm/executor_test.go | 2 +- .../game/fault/trace/vm/kona_vm_config.go | 44 +++++++++ .../fault/trace/vm/kona_vm_config_test.go | 44 +++++++++ .../fault/trace/vm/op_program_vm_config.go | 53 ++++++++++ .../trace/vm/op_program_vm_config_test.go | 99 +++++++++++++++++++ op-challenger/game/fault/types/types.go | 4 + .../disputegame/output_cannon_helper.go | 3 +- op-e2e/faultproofs/precompile_test.go | 2 +- 16 files changed, 349 insertions(+), 53 deletions(-) create mode 100644 op-challenger/game/fault/trace/vm/kona_vm_config.go create mode 100644 op-challenger/game/fault/trace/vm/kona_vm_config_test.go create mode 100644 op-challenger/game/fault/trace/vm/op_program_vm_config.go create mode 100644 op-challenger/game/fault/trace/vm/op_program_vm_config_test.go diff --git a/op-challenger/config/config.go b/op-challenger/config/config.go index f2725663cd30f..f57bab2cf3226 100644 --- a/op-challenger/config/config.go +++ b/op-challenger/config/config.go @@ -96,9 +96,12 @@ type Config struct { CannonAbsolutePreStateBaseURL *url.URL // Base URL to retrieve absolute pre-states for Cannon traces from // Specific to the asterisc trace provider - Asterisc vm.Config - AsteriscAbsolutePreState string // File to load the absolute pre-state for Asterisc traces from - AsteriscAbsolutePreStateBaseURL *url.URL // Base URL to retrieve absolute pre-states for Asterisc traces from + Asterisc vm.Config + AsteriscAbsolutePreState string // File to load the absolute pre-state for Asterisc traces from + AsteriscAbsolutePreStateBaseURL *url.URL // Base URL to retrieve absolute pre-states for Asterisc traces from + AsteriscKona vm.Config + AsteriscKonaAbsolutePreState string // File to load the absolute pre-state for AsteriscKona traces from + AsteriscKonaAbsolutePreStateBaseURL *url.URL // Base URL to retrieve absolute pre-states for AsteriscKona traces from MaxPendingTx uint64 // Maximum number of pending transactions (0 == no limit) @@ -151,6 +154,14 @@ func NewConfig( SnapshotFreq: DefaultAsteriscSnapshotFreq, InfoFreq: DefaultAsteriscInfoFreq, }, + AsteriscKona: vm.Config{ + VmType: types.TraceTypeAsteriscKona, + L1: l1EthRpc, + L1Beacon: l1BeaconApi, + L2: l2EthRpc, + SnapshotFreq: DefaultAsteriscSnapshotFreq, + InfoFreq: DefaultAsteriscInfoFreq, + }, GameWindow: DefaultGameWindow, } } diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index c128e0fa759d6..56e1c7847d3c4 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -178,17 +178,33 @@ var ( Usage: "Path to executable to use as pre-image oracle server when generating trace data (asterisc trace type only)", EnvVars: prefixEnvVars("ASTERISC_SERVER"), } + AsteriscKonaServerFlag = &cli.StringFlag{ + Name: "asterisc-kona-server", + Usage: "Path to kona executable to use as pre-image oracle server when generating trace data (asterisc-kona trace type only)", + EnvVars: prefixEnvVars("ASTERISC_KONA_SERVER"), + } AsteriscPreStateFlag = &cli.StringFlag{ Name: "asterisc-prestate", Usage: "Path to absolute prestate to use when generating trace data (asterisc trace type only)", EnvVars: prefixEnvVars("ASTERISC_PRESTATE"), } + AsteriscKonaPreStateFlag = &cli.StringFlag{ + Name: "asterisc-kona-prestate", + Usage: "Path to absolute prestate to use when generating trace data (asterisc-kona trace type only)", + EnvVars: prefixEnvVars("ASTERISC_KONA_PRESTATE"), + } AsteriscPreStatesURLFlag = &cli.StringFlag{ Name: "asterisc-prestates-url", Usage: "Base URL to absolute prestates to use when generating trace data. " + "Prestates in this directory should be name as .json (asterisc trace type only)", EnvVars: prefixEnvVars("ASTERISC_PRESTATES_URL"), } + AsteriscKonaPreStatesURLFlag = &cli.StringFlag{ + Name: "asterisc-kona-prestates-url", + Usage: "Base URL to absolute prestates to use when generating trace data. " + + "Prestates in this directory should be name as .json (asterisc-kona trace type only)", + EnvVars: prefixEnvVars("ASTERISC_KONA_PRESTATES_URL"), + } AsteriscSnapshotFreqFlag = &cli.UintFlag{ Name: "asterisc-snapshot-freq", Usage: "Frequency of asterisc snapshots to generate in VM steps (asterisc trace type only)", @@ -255,8 +271,11 @@ var optionalFlags = []cli.Flag{ AsteriscL2GenesisFlag, AsteriscBinFlag, AsteriscServerFlag, + AsteriscKonaServerFlag, AsteriscPreStateFlag, + AsteriscKonaPreStateFlag, AsteriscPreStatesURLFlag, + AsteriscKonaPreStatesURLFlag, AsteriscSnapshotFreqFlag, AsteriscInfoFreqFlag, GameWindowFlag, @@ -486,6 +505,14 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro } asteriscPreStatesURL = parsed } + var asteriscKonaPreStatesURL *url.URL + if ctx.IsSet(AsteriscKonaPreStatesURLFlag.Name) { + parsed, err := url.Parse(ctx.String(AsteriscKonaPreStatesURLFlag.Name)) + if err != nil { + return nil, fmt.Errorf("invalid asterisc-kona pre states url (%v): %w", ctx.String(AsteriscKonaPreStatesURLFlag.Name), err) + } + asteriscKonaPreStatesURL = parsed + } l2Rpc, err := getL2Rpc(ctx, logger) if err != nil { return nil, err @@ -545,10 +572,25 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro }, AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name), AsteriscAbsolutePreStateBaseURL: asteriscPreStatesURL, - TxMgrConfig: txMgrConfig, - MetricsConfig: metricsConfig, - PprofConfig: pprofConfig, - SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name), - AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name), + AsteriscKona: vm.Config{ + VmType: types.TraceTypeAsteriscKona, + L1: l1EthRpc, + L1Beacon: l1Beacon, + L2: l2Rpc, + VmBin: ctx.String(AsteriscBinFlag.Name), + Server: ctx.String(AsteriscKonaServerFlag.Name), + Network: asteriscNetwork, + RollupConfigPath: ctx.String(AsteriscRollupConfigFlag.Name), + L2GenesisPath: ctx.String(AsteriscL2GenesisFlag.Name), + SnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name), + InfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name), + }, + AsteriscKonaAbsolutePreState: ctx.String(AsteriscKonaPreStateFlag.Name), + AsteriscKonaAbsolutePreStateBaseURL: asteriscKonaPreStatesURL, + TxMgrConfig: txMgrConfig, + MetricsConfig: metricsConfig, + PprofConfig: pprofConfig, + SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name), + AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name), }, nil } diff --git a/op-challenger/game/fault/register.go b/op-challenger/game/fault/register.go index 9637b16addec2..423e70c19646e 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/prestates" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm" faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" @@ -74,20 +75,29 @@ func RegisterGameTypes( syncValidator := newSyncStatusValidator(rollupClient) 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 { + vmConfig := vm.NewOpProgramVmConfig(cfg.Cannon) + if err := registerCannon(faultTypes.CannonGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, vmConfig, 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(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 { + vmConfig := vm.NewOpProgramVmConfig(cfg.Cannon) + if err := registerCannon(faultTypes.PermissionedGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, vmConfig, 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(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 { + vmConfig := vm.NewOpProgramVmConfig(cfg.Asterisc) + if err := registerAsterisc(faultTypes.AsteriscGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, vmConfig, 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(faultTypes.TraceTypeAsteriscKona) { + vmConfig := vm.NewKonaVmConfig(cfg.Asterisc) + if err := registerAsterisc(faultTypes.AsteriscKonaGameType, registry, oracles, ctx, systemClock, l1Clock, logger, m, cfg, vmConfig, syncValidator, rollupClient, txSender, gameFactory, caller, l2Client, l1HeaderSource, selective, claimants); err != nil { + return nil, fmt.Errorf("failed to register asterisc kona game type: %w", err) + } + } 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) @@ -194,6 +204,7 @@ func registerAsterisc( logger log.Logger, m metrics.Metricer, cfg *config.Config, + vmCfg vm.VmConfig, syncValidator SyncValidator, rollupClient outputs.OutputRollupClient, txSender TxSender, @@ -254,7 +265,7 @@ func registerAsterisc( if err != nil { return nil, fmt.Errorf("failed to get asterisc prestate: %w", err) } - accessor, err := outputs.NewOutputAsteriscTraceAccessor(logger, m, cfg.Asterisc, l2Client, prestateProvider, asteriscPrestate, rollupClient, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) + accessor, err := outputs.NewOutputAsteriscTraceAccessor(logger, m, vmCfg, l2Client, prestateProvider, asteriscPrestate, rollupClient, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) if err != nil { return nil, err } @@ -287,6 +298,7 @@ func registerCannon( logger log.Logger, m metrics.Metricer, cfg *config.Config, + vmCfg vm.VmConfig, syncValidator SyncValidator, rollupClient outputs.OutputRollupClient, txSender TxSender, @@ -321,7 +333,6 @@ func registerCannon( } cannonPrestateProvider, err := prestateProviderCache.GetOrCreate(requiredPrestatehash) - if err != nil { return nil, fmt.Errorf("required prestate %v not available for game %v: %w", requiredPrestatehash, game.Proxy, err) } @@ -349,7 +360,7 @@ func registerCannon( if err != nil { return nil, fmt.Errorf("failed to get cannon prestate: %w", err) } - accessor, err := outputs.NewOutputCannonTraceAccessor(logger, m, cfg.Cannon, l2Client, prestateProvider, cannonPrestate, rollupClient, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) + accessor, err := outputs.NewOutputCannonTraceAccessor(logger, m, vmCfg, l2Client, prestateProvider, cannonPrestate, rollupClient, dir, l1HeadID, splitDepth, prestateBlock, poststateBlock) if err != nil { return nil, err } diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index 5c481777b6ce1..761ab947d04d9 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -35,7 +35,7 @@ type AsteriscTraceProvider struct { lastStep uint64 } -func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, prestateProvider types.PrestateProvider, asteriscPrestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProvider { +func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.VmConfig, prestateProvider types.PrestateProvider, asteriscPrestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProvider { return &AsteriscTraceProvider{ logger: logger, dir: dir, @@ -177,7 +177,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi logger: logger, dir: dir, prestate: cfg.AsteriscAbsolutePreState, - generator: vm.NewExecutor(logger, m, cfg.Asterisc, cfg.AsteriscAbsolutePreState, localInputs), + generator: vm.NewExecutor(logger, m, vm.NewOpProgramVmConfig(cfg.Asterisc), cfg.AsteriscAbsolutePreState, localInputs), gameDepth: gameDepth, preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), } diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index 7b55035aa1901..c1c2823f45515 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -38,7 +38,7 @@ type CannonTraceProvider struct { lastStep uint64 } -func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, prestateProvider types.PrestateProvider, prestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProvider { +func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.VmConfig, prestateProvider types.PrestateProvider, prestate string, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *CannonTraceProvider { return &CannonTraceProvider{ logger: logger, dir: dir, @@ -181,7 +181,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi logger: logger, dir: dir, prestate: cfg.CannonAbsolutePreState, - generator: vm.NewExecutor(logger, m, cfg.Cannon, cfg.CannonAbsolutePreState, localInputs), + generator: vm.NewExecutor(logger, m, vm.NewOpProgramVmConfig(cfg.Cannon), cfg.CannonAbsolutePreState, localInputs), gameDepth: gameDepth, preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(vm.PreimageDir(dir)).Get), } diff --git a/op-challenger/game/fault/trace/outputs/output_asterisc.go b/op-challenger/game/fault/trace/outputs/output_asterisc.go index ac129dbb26c82..422eebd858aa8 100644 --- a/op-challenger/game/fault/trace/outputs/output_asterisc.go +++ b/op-challenger/game/fault/trace/outputs/output_asterisc.go @@ -21,7 +21,7 @@ import ( func NewOutputAsteriscTraceAccessor( logger log.Logger, m metrics.Metricer, - cfg vm.Config, + cfg vm.VmConfig, l2Client utils.L2HeaderSource, prestateProvider types.PrestateProvider, asteriscPrestate string, diff --git a/op-challenger/game/fault/trace/outputs/output_cannon.go b/op-challenger/game/fault/trace/outputs/output_cannon.go index ecc710380bfb8..618c14a0bf868 100644 --- a/op-challenger/game/fault/trace/outputs/output_cannon.go +++ b/op-challenger/game/fault/trace/outputs/output_cannon.go @@ -21,7 +21,7 @@ import ( func NewOutputCannonTraceAccessor( logger log.Logger, m metrics.Metricer, - cfg vm.Config, + cfg vm.VmConfig, l2Client utils.L2HeaderSource, prestateProvider types.PrestateProvider, cannonPrestate string, diff --git a/op-challenger/game/fault/trace/vm/executor.go b/op-challenger/game/fault/trace/vm/executor.go index a26133e083b34..0cce73e79b73e 100644 --- a/op-challenger/game/fault/trace/vm/executor.go +++ b/op-challenger/game/fault/trace/vm/executor.go @@ -33,8 +33,13 @@ type Config struct { InfoFreq uint // Frequency of progress log messages (in VM instructions) } +type VmConfig interface { + Cfg() Config + FillHostCommand(args []string, dataDir string, inputs utils.LocalGameInputs) ([]string, error) +} + type Executor struct { - cfg Config + cfg VmConfig logger log.Logger metrics Metricer absolutePreState string @@ -43,7 +48,7 @@ type Executor struct { cmdExecutor CmdExecutor } -func NewExecutor(logger log.Logger, m Metricer, cfg Config, prestate string, inputs utils.LocalGameInputs) *Executor { +func NewExecutor(logger log.Logger, m Metricer, cfg VmConfig, prestate string, inputs utils.LocalGameInputs) *Executor { return &Executor{ cfg: cfg, logger: logger, @@ -63,7 +68,7 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro // DoGenerateProof executes vm from the specified starting trace index until the end trace index. // The proof is stored at the specified directory. -func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64, end uint64, extraVmArgs ...string) error { +func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64, end uint64, extravmConfig ...string) error { snapshotDir := filepath.Join(dir, SnapsDir) start, err := e.selectSnapshot(e.logger, snapshotDir, e.absolutePreState, begin) if err != nil { @@ -77,37 +82,19 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64 "--input", start, "--output", lastGeneratedState, "--meta", "", - "--info-at", "%" + strconv.FormatUint(uint64(e.cfg.InfoFreq), 10), + "--info-at", "%" + strconv.FormatUint(uint64(e.cfg.Cfg().InfoFreq), 10), "--proof-at", "=" + strconv.FormatUint(end, 10), "--proof-fmt", filepath.Join(proofDir, "%d.json.gz"), - "--snapshot-at", "%" + strconv.FormatUint(uint64(e.cfg.SnapshotFreq), 10), + "--snapshot-at", "%" + strconv.FormatUint(uint64(e.cfg.Cfg().SnapshotFreq), 10), "--snapshot-fmt", filepath.Join(snapshotDir, "%d.json.gz"), } if end < math.MaxUint64 { args = append(args, "--stop-at", "="+strconv.FormatUint(end+1, 10)) } - args = append(args, extraVmArgs...) - args = append(args, - "--", - e.cfg.Server, "--server", - "--l1", e.cfg.L1, - "--l1.beacon", e.cfg.L1Beacon, - "--l2", e.cfg.L2, - "--datadir", dataDir, - "--l1.head", e.inputs.L1Head.Hex(), - "--l2.head", e.inputs.L2Head.Hex(), - "--l2.outputroot", e.inputs.L2OutputRoot.Hex(), - "--l2.claim", e.inputs.L2Claim.Hex(), - "--l2.blocknumber", e.inputs.L2BlockNumber.Text(10), - ) - if e.cfg.Network != "" { - args = append(args, "--network", e.cfg.Network) - } - if e.cfg.RollupConfigPath != "" { - args = append(args, "--rollup.config", e.cfg.RollupConfigPath) - } - if e.cfg.L2GenesisPath != "" { - args = append(args, "--l2.genesis", e.cfg.L2GenesisPath) + args = append(args, extravmConfig...) + args, err = e.cfg.FillHostCommand(args, dataDir, e.inputs) + if err != nil { + return err } if err := os.MkdirAll(snapshotDir, 0755); err != nil { @@ -119,9 +106,9 @@ func (e *Executor) DoGenerateProof(ctx context.Context, dir string, begin uint64 if err := os.MkdirAll(proofDir, 0755); err != nil { return fmt.Errorf("could not create proofs directory %v: %w", proofDir, err) } - e.logger.Info("Generating trace", "proof", end, "cmd", e.cfg.VmBin, "args", strings.Join(args, ", ")) + e.logger.Info("Generating trace", "proof", end, "cmd", e.cfg.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.String(), time.Since(execStart)) + err = e.cmdExecutor(ctx, e.logger.New("proof", end), e.cfg.Cfg().VmBin, args...) + e.metrics.RecordVmExecutionTime(e.cfg.Cfg().VmType.String(), time.Since(execStart)) return err } diff --git a/op-challenger/game/fault/trace/vm/executor_test.go b/op-challenger/game/fault/trace/vm/executor_test.go index 00078bd2078e9..b17b1242f1197 100644 --- a/op-challenger/game/fault/trace/vm/executor_test.go +++ b/op-challenger/game/fault/trace/vm/executor_test.go @@ -42,7 +42,7 @@ func TestGenerateProof(t *testing.T) { } captureExec := func(t *testing.T, cfg Config, proofAt uint64) (string, string, map[string]string) { m := &stubVmMetrics{} - executor := NewExecutor(testlog.Logger(t, log.LevelInfo), m, cfg, prestate, inputs) + executor := NewExecutor(testlog.Logger(t, log.LevelInfo), m, NewOpProgramVmConfig(cfg), prestate, inputs) executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) { return input, nil } diff --git a/op-challenger/game/fault/trace/vm/kona_vm_config.go b/op-challenger/game/fault/trace/vm/kona_vm_config.go new file mode 100644 index 0000000000000..91bbe0bc30785 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/kona_vm_config.go @@ -0,0 +1,44 @@ +package vm + +import ( + "errors" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" +) + +type KonaVmConfig struct { + Config +} + +var _ VmConfig = (*KonaVmConfig)(nil) + +func NewKonaVmConfig(vmConfig Config) *KonaVmConfig { + return &KonaVmConfig{ + vmConfig, + } +} + +func (s *KonaVmConfig) Cfg() Config { + return s.Config +} + +func (s *KonaVmConfig) FillHostCommand(args []string, dataDir string, inputs utils.LocalGameInputs) ([]string, error) { + if args == nil { + return nil, errors.New("args is nil") + } + + args = append(args, + "--", + s.Cfg().Server, "--server", + "--l1-node-address", s.Cfg().L1, + "--l1-beacon-address", s.Cfg().L1Beacon, + "--l2-node-address", s.Cfg().L2, + "--data-dir", dataDir, + "--l1-head", inputs.L1Head.Hex(), + "--l2-head", inputs.L2Head.Hex(), + "--l2-output-root", inputs.L2OutputRoot.Hex(), + "--l2-claim", inputs.L2Claim.Hex(), + "--l2-block-number", inputs.L2BlockNumber.Text(10), + ) + return args, nil +} diff --git a/op-challenger/game/fault/trace/vm/kona_vm_config_test.go b/op-challenger/game/fault/trace/vm/kona_vm_config_test.go new file mode 100644 index 0000000000000..b7d4d255d3128 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/kona_vm_config_test.go @@ -0,0 +1,44 @@ +package vm + +import ( + "math/big" + "slices" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestKonaFillHostCommand(t *testing.T) { + dir := "mockdir" + cfg := Config{ + L1: "http://localhost:8888", + L1Beacon: "http://localhost:9000", + L2: "http://localhost:9999", + Server: "./bin/mockserver", + } + inputs := utils.LocalGameInputs{ + L1Head: common.Hash{0x11}, + L2Head: common.Hash{0x22}, + L2OutputRoot: common.Hash{0x33}, + L2Claim: common.Hash{0x44}, + L2BlockNumber: big.NewInt(3333), + } + vmConfig := NewKonaVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + require.True(t, slices.Contains(args, "--")) + require.True(t, slices.Contains(args, "--server")) + require.True(t, slices.Contains(args, "--l1-node-address")) + require.True(t, slices.Contains(args, "--l1-beacon-address")) + require.True(t, slices.Contains(args, "--l2-node-address")) + require.True(t, slices.Contains(args, "--data-dir")) + require.True(t, slices.Contains(args, "--l1-head")) + require.True(t, slices.Contains(args, "--l2-head")) + require.True(t, slices.Contains(args, "--l2-output-root")) + require.True(t, slices.Contains(args, "--l2-claim")) + require.True(t, slices.Contains(args, "--l2-block-number")) +} diff --git a/op-challenger/game/fault/trace/vm/op_program_vm_config.go b/op-challenger/game/fault/trace/vm/op_program_vm_config.go new file mode 100644 index 0000000000000..bd271625bc3ea --- /dev/null +++ b/op-challenger/game/fault/trace/vm/op_program_vm_config.go @@ -0,0 +1,53 @@ +package vm + +import ( + "errors" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" +) + +type OpProgramVmConfig struct { + Config +} + +var _ VmConfig = (*OpProgramVmConfig)(nil) + +func NewOpProgramVmConfig(vmConfig Config) *OpProgramVmConfig { + return &OpProgramVmConfig{ + vmConfig, + } +} + +func (s *OpProgramVmConfig) Cfg() Config { + return s.Config +} + +func (s *OpProgramVmConfig) FillHostCommand(args []string, dataDir string, inputs utils.LocalGameInputs) ([]string, error) { + if args == nil { + return nil, errors.New("args is nil") + } + + args = append(args, + "--", + s.Cfg().Server, "--server", + "--l1", s.Cfg().L1, + "--l1.beacon", s.Cfg().L1Beacon, + "--l2", s.Cfg().L2, + "--datadir", dataDir, + "--l1.head", inputs.L1Head.Hex(), + "--l2.head", inputs.L2Head.Hex(), + "--l2.outputroot", inputs.L2OutputRoot.Hex(), + "--l2.claim", inputs.L2Claim.Hex(), + "--l2.blocknumber", inputs.L2BlockNumber.Text(10), + ) + if s.Network != "" { + args = append(args, "--network", s.Network) + } + if s.RollupConfigPath != "" { + args = append(args, "--rollup.config", s.RollupConfigPath) + } + if s.L2GenesisPath != "" { + args = append(args, "--l2.genesis", s.L2GenesisPath) + } + return args, nil +} diff --git a/op-challenger/game/fault/trace/vm/op_program_vm_config_test.go b/op-challenger/game/fault/trace/vm/op_program_vm_config_test.go new file mode 100644 index 0000000000000..3ab6068602b37 --- /dev/null +++ b/op-challenger/game/fault/trace/vm/op_program_vm_config_test.go @@ -0,0 +1,99 @@ +package vm + +import ( + "math/big" + "slices" + "testing" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestOpProgramFillHostCommand(t *testing.T) { + dir := "mockdir" + cfg := Config{ + L1: "http://localhost:8888", + L1Beacon: "http://localhost:9000", + L2: "http://localhost:9999", + Server: "./bin/mockserver", + } + inputs := utils.LocalGameInputs{ + L1Head: common.Hash{0x11}, + L2Head: common.Hash{0x22}, + L2OutputRoot: common.Hash{0x33}, + L2Claim: common.Hash{0x44}, + L2BlockNumber: big.NewInt(3333), + } + + validateStandard := func(t *testing.T, args []string) { + require.True(t, slices.Contains(args, "--")) + require.True(t, slices.Contains(args, "--server")) + require.True(t, slices.Contains(args, "--l1")) + require.True(t, slices.Contains(args, "--l1.beacon")) + require.True(t, slices.Contains(args, "--l2")) + require.True(t, slices.Contains(args, "--datadir")) + require.True(t, slices.Contains(args, "--l1.head")) + require.True(t, slices.Contains(args, "--l2.head")) + require.True(t, slices.Contains(args, "--l2.outputroot")) + require.True(t, slices.Contains(args, "--l2.claim")) + require.True(t, slices.Contains(args, "--l2.blocknumber")) + } + + t.Run("NoExtras", func(t *testing.T) { + vmConfig := NewOpProgramVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + validateStandard(t, args) + }) + + t.Run("WithNetwork", func(t *testing.T) { + cfg.Network = "op-test" + vmConfig := NewOpProgramVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + validateStandard(t, args) + require.True(t, slices.Contains(args, "--network")) + }) + + t.Run("WithRollupConfigPath", func(t *testing.T) { + cfg.RollupConfigPath = "rollup.config" + vmConfig := NewOpProgramVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + validateStandard(t, args) + require.True(t, slices.Contains(args, "--rollup.config")) + }) + + t.Run("WithL2GenesisPath", func(t *testing.T) { + cfg.L2GenesisPath = "l2.genesis" + vmConfig := NewOpProgramVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + validateStandard(t, args) + require.True(t, slices.Contains(args, "--l2.genesis")) + }) + + t.Run("WithAllExtras", func(t *testing.T) { + cfg.Network = "op-test" + cfg.RollupConfigPath = "rollup.config" + cfg.L2GenesisPath = "l2.genesis" + vmConfig := NewOpProgramVmConfig(cfg) + + args, err := vmConfig.FillHostCommand([]string{}, dir, inputs) + require.NoError(t, err) + + validateStandard(t, args) + require.True(t, slices.Contains(args, "--network")) + require.True(t, slices.Contains(args, "--rollup.config")) + require.True(t, slices.Contains(args, "--l2.genesis")) + }) +} diff --git a/op-challenger/game/fault/types/types.go b/op-challenger/game/fault/types/types.go index aca80577b36ad..d1d887910de88 100644 --- a/op-challenger/game/fault/types/types.go +++ b/op-challenger/game/fault/types/types.go @@ -26,6 +26,7 @@ const ( CannonGameType GameType = 0 PermissionedGameType GameType = 1 AsteriscGameType GameType = 2 + AsteriscKonaGameType GameType = 3 FastGameType GameType = 254 AlphabetGameType GameType = 255 UnknownGameType GameType = math.MaxUint32 @@ -43,6 +44,8 @@ func (t GameType) String() string { return "permissioned" case AsteriscGameType: return "asterisc" + case AsteriscKonaGameType: + return "asterisc-kona" case FastGameType: return "fast" case AlphabetGameType: @@ -59,6 +62,7 @@ const ( TraceTypeFast TraceType = "fast" TraceTypeCannon TraceType = "cannon" TraceTypeAsterisc TraceType = "asterisc" + TraceTypeAsteriscKona TraceType = "asterisc-kona" TraceTypePermissioned TraceType = "permissioned" ) diff --git a/op-e2e/e2eutils/disputegame/output_cannon_helper.go b/op-e2e/e2eutils/disputegame/output_cannon_helper.go index e2f72c4915d96..9475f5234206b 100644 --- a/op-e2e/e2eutils/disputegame/output_cannon_helper.go +++ b/op-e2e/e2eutils/disputegame/output_cannon_helper.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" + "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-challenger/metrics" "github.com/ethereum-optimism/optimism/op-e2e/bindings" @@ -62,7 +63,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) l1Head := g.GetL1Head(ctx) accessor, err := outputs.NewOutputCannonTraceAccessor( - logger, metrics.NoopMetrics, cfg.Cannon, l2Client, prestateProvider, cfg.CannonAbsolutePreState, rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) + logger, metrics.NoopMetrics, vm.NewOpProgramVmConfig(cfg.Cannon), l2Client, prestateProvider, cfg.CannonAbsolutePreState, rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) g.Require.NoError(err, "Failed to create output cannon trace accessor") return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, g.Game, accessor) } diff --git a/op-e2e/faultproofs/precompile_test.go b/op-e2e/faultproofs/precompile_test.go index ab8d0394771dc..0ed9d6cad8b2a 100644 --- a/op-e2e/faultproofs/precompile_test.go +++ b/op-e2e/faultproofs/precompile_test.go @@ -147,7 +147,7 @@ func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs uti cannonOpts(&cfg) logger := testlog.Logger(t, log.LevelInfo).New("role", "cannon") - executor := vm.NewExecutor(logger, metrics.NoopMetrics, cfg.Cannon, cfg.CannonAbsolutePreState, inputs) + executor := vm.NewExecutor(logger, metrics.NoopMetrics, vm.NewOpProgramVmConfig(cfg.Cannon), cfg.CannonAbsolutePreState, inputs) t.Log("Running cannon") err := executor.DoGenerateProof(ctx, proofsDir, math.MaxUint, math.MaxUint, extraVmArgs...)