diff --git a/op-challenger/cmd/main_test.go b/op-challenger/cmd/main_test.go index 62e6cf8f6ed9..067214436be0 100644 --- a/op-challenger/cmd/main_test.go +++ b/op-challenger/cmd/main_test.go @@ -290,7 +290,7 @@ func TestAsteriscRequiredArgs(t *testing.T) { }) t.Run("Required", func(t *testing.T) { - verifyArgsInvalid(t, "flag asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) }) t.Run("Valid", func(t *testing.T) { @@ -299,6 +299,21 @@ func TestAsteriscRequiredArgs(t *testing.T) { }) }) + t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) { + t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) { + configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-prestates-url")) + }) + + t.Run("Required", func(t *testing.T) { + verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate")) + }) + + t.Run("Valid", func(t *testing.T) { + cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar")) + require.Equal(t, "http://localhost/bar", cfg.AsteriscAbsolutePreStateBaseURL.String()) + }) + }) + t.Run(fmt.Sprintf("TestL2Rpc-%v", traceType), func(t *testing.T) { t.Run("NotRequiredForAlphabetTraceLegacy", func(t *testing.T) { configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2")) diff --git a/op-challenger/config/config.go b/op-challenger/config/config.go index 167f8d88ad22..7ed960e7682e 100644 --- a/op-challenger/config/config.go +++ b/op-challenger/config/config.go @@ -37,16 +37,17 @@ var ( ErrCannonNetworkUnknown = errors.New("unknown cannon network") ErrMissingRollupRpc = errors.New("missing rollup rpc url") - ErrMissingAsteriscBin = errors.New("missing asterisc bin") - ErrMissingAsteriscServer = errors.New("missing asterisc server") - ErrMissingAsteriscAbsolutePreState = errors.New("missing asterisc absolute pre-state") - ErrMissingAsteriscSnapshotFreq = errors.New("missing asterisc snapshot freq") - ErrMissingAsteriscInfoFreq = errors.New("missing asterisc info freq") - ErrMissingAsteriscRollupConfig = errors.New("missing asterisc network or rollup config path") - ErrMissingAsteriscL2Genesis = errors.New("missing asterisc network or l2 genesis path") - ErrAsteriscNetworkAndRollupConfig = errors.New("only specify one of network or rollup config path") - ErrAsteriscNetworkAndL2Genesis = errors.New("only specify one of network or l2 genesis path") - ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network") + ErrMissingAsteriscBin = errors.New("missing asterisc bin") + ErrMissingAsteriscServer = errors.New("missing asterisc server") + ErrMissingAsteriscAbsolutePreState = errors.New("missing asterisc absolute pre-state") + ErrAsteriscAbsolutePreStateAndBaseURL = errors.New("only specify one of asterisc absolute pre-state and asterisc absolute pre-state base URL") + ErrMissingAsteriscSnapshotFreq = errors.New("missing asterisc snapshot freq") + ErrMissingAsteriscInfoFreq = errors.New("missing asterisc info freq") + ErrMissingAsteriscRollupConfig = errors.New("missing asterisc network or rollup config path") + ErrMissingAsteriscL2Genesis = errors.New("missing asterisc network or l2 genesis path") + ErrAsteriscNetworkAndRollupConfig = errors.New("only specify one of network or rollup config path") + ErrAsteriscNetworkAndL2Genesis = errors.New("only specify one of network or l2 genesis path") + ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network") ) type TraceType string @@ -137,14 +138,15 @@ type Config struct { CannonInfoFreq uint // Frequency of cannon progress log messages (in VM instructions) // Specific to the asterisc trace provider - AsteriscBin string // Path to the asterisc executable to run when generating trace data - AsteriscServer string // Path to the op-program executable that provides the pre-image oracle server - AsteriscAbsolutePreState string // File to load the absolute pre-state for Asterisc traces from - AsteriscNetwork string - AsteriscRollupConfigPath string - AsteriscL2GenesisPath string - AsteriscSnapshotFreq uint // Frequency of snapshots to create when executing asterisc (in VM instructions) - AsteriscInfoFreq uint // Frequency of asterisc progress log messages (in VM instructions) + AsteriscBin string // Path to the asterisc executable to run when generating trace data + AsteriscServer string // Path to the op-program executable that provides the pre-image oracle server + 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 + AsteriscNetwork string + AsteriscRollupConfigPath string + AsteriscL2GenesisPath string + AsteriscSnapshotFreq uint // Frequency of snapshots to create when executing asterisc (in VM instructions) + AsteriscInfoFreq uint // Frequency of asterisc progress log messages (in VM instructions) MaxPendingTx uint64 // Maximum number of pending transactions (0 == no limit) @@ -277,9 +279,12 @@ func (c Config) Check() error { return fmt.Errorf("%w: %v", ErrAsteriscNetworkUnknown, c.AsteriscNetwork) } } - if c.AsteriscAbsolutePreState == "" { + if c.AsteriscAbsolutePreState == "" && c.AsteriscAbsolutePreStateBaseURL == nil { return ErrMissingAsteriscAbsolutePreState } + if c.AsteriscAbsolutePreState != "" && c.AsteriscAbsolutePreStateBaseURL != nil { + return ErrAsteriscAbsolutePreStateAndBaseURL + } if c.L2Rpc == "" { return ErrMissingL2Rpc } diff --git a/op-challenger/config/config_test.go b/op-challenger/config/config_test.go index be144c38ddff..a673e9ff554f 100644 --- a/op-challenger/config/config_test.go +++ b/op-challenger/config/config_test.go @@ -25,13 +25,15 @@ var ( validL2Rpc = "http://localhost:9545" validRollupRpc = "http://localhost:8555" - validAsteriscBin = "./bin/asterisc" - validAsteriscOpProgramBin = "./bin/op-program" - validAsteriscNetwork = "mainnet" - validAsteriscAbsolutPreState = "pre.json" + validAsteriscBin = "./bin/asterisc" + validAsteriscOpProgramBin = "./bin/op-program" + validAsteriscNetwork = "mainnet" + validAsteriscAbsolutPreState = "pre.json" + validAsteriscAbsolutPreStateBaseURL, _ = url.Parse("http://localhost/bar/") ) var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned} +var asteriscTraceTypes = []TraceType{TraceTypeAsterisc} func applyValidConfigForCannon(cfg *Config) { cfg.CannonBin = validCannonBin @@ -44,7 +46,7 @@ func applyValidConfigForCannon(cfg *Config) { func applyValidConfigForAsterisc(cfg *Config) { cfg.AsteriscBin = validAsteriscBin cfg.AsteriscServer = validAsteriscOpProgramBin - cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState + cfg.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL cfg.AsteriscNetwork = validAsteriscNetwork cfg.L2Rpc = validL2Rpc } @@ -216,6 +218,112 @@ func TestCannonRequiredArgs(t *testing.T) { } } +func TestAsteriscRequiredArgs(t *testing.T) { + for _, traceType := range asteriscTraceTypes { + traceType := traceType + + t.Run(fmt.Sprintf("TestAsteriscBinRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscBin = "" + require.ErrorIs(t, config.Check(), ErrMissingAsteriscBin) + }) + + t.Run(fmt.Sprintf("TestAsteriscServerRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscServer = "" + require.ErrorIs(t, config.Check(), ErrMissingAsteriscServer) + }) + + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscAbsolutePreState = "" + config.AsteriscAbsolutePreStateBaseURL = nil + require.ErrorIs(t, config.Check(), ErrMissingAsteriscAbsolutePreState) + }) + + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreState-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscAbsolutePreState = validAsteriscAbsolutPreState + config.AsteriscAbsolutePreStateBaseURL = nil + require.NoError(t, config.Check()) + }) + + t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscAbsolutePreState = "" + config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL + require.NoError(t, config.Check()) + }) + + t.Run(fmt.Sprintf("TestMustNotSupplyBothAsteriscAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.AsteriscAbsolutePreState = validAsteriscAbsolutPreState + config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL + require.ErrorIs(t, config.Check(), ErrAsteriscAbsolutePreStateAndBaseURL) + }) + + t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) { + config := validConfig(traceType) + config.L2Rpc = "" + require.ErrorIs(t, config.Check(), ErrMissingL2Rpc) + }) + + t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", traceType), func(t *testing.T) { + t.Run("MustNotBeZero", func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscSnapshotFreq = 0 + require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscSnapshotFreq) + }) + }) + + t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", traceType), func(t *testing.T) { + t.Run("MustNotBeZero", func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscInfoFreq = 0 + require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscInfoFreq) + }) + }) + + t.Run(fmt.Sprintf("TestAsteriscNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscNetwork = "" + cfg.AsteriscRollupConfigPath = "" + cfg.AsteriscL2GenesisPath = "genesis.json" + require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscRollupConfig) + }) + + t.Run(fmt.Sprintf("TestAsteriscNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscNetwork = "" + cfg.AsteriscRollupConfigPath = "foo.json" + cfg.AsteriscL2GenesisPath = "" + require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscL2Genesis) + }) + + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscNetwork = validAsteriscNetwork + cfg.AsteriscRollupConfigPath = "foo.json" + cfg.AsteriscL2GenesisPath = "" + require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkAndRollupConfig) + }) + + t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscNetwork = validAsteriscNetwork + cfg.AsteriscRollupConfigPath = "" + cfg.AsteriscL2GenesisPath = "foo.json" + require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkAndL2Genesis) + }) + + t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) { + cfg := validConfig(traceType) + cfg.AsteriscNetwork = "unknown" + require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkUnknown) + }) + } +} + func TestDatadirRequired(t *testing.T) { config := validConfig(TraceTypeAlphabet) config.Datadir = "" @@ -280,6 +388,7 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) { // Require asterisc specific args cfg.AsteriscAbsolutePreState = "" + cfg.AsteriscAbsolutePreStateBaseURL = nil require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscAbsolutePreState) cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState @@ -304,6 +413,7 @@ func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) { // Require asterisc specific args cfg.AsteriscAbsolutePreState = "" + cfg.AsteriscAbsolutePreStateBaseURL = nil require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscAbsolutePreState) cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState diff --git a/op-challenger/flags/flags.go b/op-challenger/flags/flags.go index 3b694240a487..e9a55e971fe9 100644 --- a/op-challenger/flags/flags.go +++ b/op-challenger/flags/flags.go @@ -184,6 +184,12 @@ var ( Usage: "Path to absolute prestate to use when generating trace data (asterisc trace type only)", EnvVars: prefixEnvVars("ASTERISC_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"), + } AsteriscSnapshotFreqFlag = &cli.UintFlag{ Name: "asterisc-snapshot-freq", Usage: "Frequency of asterisc snapshots to generate in VM steps (asterisc trace type only)", @@ -250,6 +256,7 @@ var optionalFlags = []cli.Flag{ AsteriscBinFlag, AsteriscServerFlag, AsteriscPreStateFlag, + AsteriscPreStatesURLFlag, AsteriscSnapshotFreqFlag, AsteriscInfoFreqFlag, GameWindowFlag, @@ -313,8 +320,8 @@ func CheckAsteriscFlags(ctx *cli.Context) error { if !ctx.IsSet(AsteriscServerFlag.Name) { return fmt.Errorf("flag %s is required", AsteriscServerFlag.Name) } - if !ctx.IsSet(AsteriscPreStateFlag.Name) { - return fmt.Errorf("flag %s is required", AsteriscPreStateFlag.Name) + if !ctx.IsSet(AsteriscPreStateFlag.Name) && !ctx.IsSet(AsteriscPreStatesURLFlag.Name) { + return fmt.Errorf("flag %s or %s is required", AsteriscPreStatesURLFlag.Name, AsteriscPreStateFlag.Name) } // CannonL2Flag is checked because it is an alias with L2EthRpcFlag if !ctx.IsSet(CannonL2Flag.Name) && !ctx.IsSet(L2EthRpcFlag.Name) { @@ -426,46 +433,55 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro } cannonPrestatesURL = parsed } + var asteriscPreStatesURL *url.URL + if ctx.IsSet(AsteriscPreStatesURLFlag.Name) { + parsed, err := url.Parse(ctx.String(AsteriscPreStatesURLFlag.Name)) + if err != nil { + return nil, fmt.Errorf("invalid asterisc pre states url (%v): %w", ctx.String(CannonPreStatesURLFlag.Name), err) + } + asteriscPreStatesURL = parsed + } l2Rpc, err := getL2Rpc(ctx, logger) if err != nil { return nil, err } return &config.Config{ // Required Flags - L1EthRpc: ctx.String(L1EthRpcFlag.Name), - L1Beacon: ctx.String(L1BeaconFlag.Name), - TraceTypes: traceTypes, - GameFactoryAddress: gameFactoryAddress, - GameAllowlist: allowedGames, - GameWindow: ctx.Duration(GameWindowFlag.Name), - MaxConcurrency: maxConcurrency, - L2Rpc: l2Rpc, - MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name), - PollInterval: ctx.Duration(HTTPPollInterval.Name), - AdditionalBondClaimants: claimants, - RollupRpc: ctx.String(RollupRpcFlag.Name), - CannonNetwork: ctx.String(CannonNetworkFlag.Name), - CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), - CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name), - CannonBin: ctx.String(CannonBinFlag.Name), - CannonServer: ctx.String(CannonServerFlag.Name), - CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), - CannonAbsolutePreStateBaseURL: cannonPrestatesURL, - Datadir: ctx.String(DatadirFlag.Name), - CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), - CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), - AsteriscNetwork: ctx.String(AsteriscNetworkFlag.Name), - AsteriscRollupConfigPath: ctx.String(AsteriscRollupConfigFlag.Name), - AsteriscL2GenesisPath: ctx.String(AsteriscL2GenesisFlag.Name), - AsteriscBin: ctx.String(AsteriscBinFlag.Name), - AsteriscServer: ctx.String(AsteriscServerFlag.Name), - AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name), - AsteriscSnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name), - AsteriscInfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name), - TxMgrConfig: txMgrConfig, - MetricsConfig: metricsConfig, - PprofConfig: pprofConfig, - SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name), - AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name), + L1EthRpc: ctx.String(L1EthRpcFlag.Name), + L1Beacon: ctx.String(L1BeaconFlag.Name), + TraceTypes: traceTypes, + GameFactoryAddress: gameFactoryAddress, + GameAllowlist: allowedGames, + GameWindow: ctx.Duration(GameWindowFlag.Name), + MaxConcurrency: maxConcurrency, + L2Rpc: l2Rpc, + MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name), + PollInterval: ctx.Duration(HTTPPollInterval.Name), + AdditionalBondClaimants: claimants, + RollupRpc: ctx.String(RollupRpcFlag.Name), + CannonNetwork: ctx.String(CannonNetworkFlag.Name), + CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name), + CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name), + CannonBin: ctx.String(CannonBinFlag.Name), + CannonServer: ctx.String(CannonServerFlag.Name), + CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name), + CannonAbsolutePreStateBaseURL: cannonPrestatesURL, + Datadir: ctx.String(DatadirFlag.Name), + CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name), + CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name), + AsteriscNetwork: ctx.String(AsteriscNetworkFlag.Name), + AsteriscRollupConfigPath: ctx.String(AsteriscRollupConfigFlag.Name), + AsteriscL2GenesisPath: ctx.String(AsteriscL2GenesisFlag.Name), + AsteriscBin: ctx.String(AsteriscBinFlag.Name), + AsteriscServer: ctx.String(AsteriscServerFlag.Name), + AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name), + AsteriscAbsolutePreStateBaseURL: asteriscPreStatesURL, + AsteriscSnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name), + AsteriscInfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name), + 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 d4cc6a7fad01..0b05b1572fc4 100644 --- a/op-challenger/game/fault/register.go +++ b/op-challenger/game/fault/register.go @@ -203,12 +203,27 @@ func registerAsterisc( selective bool, claimants []common.Address, ) error { - asteriscPrestateProvider := asterisc.NewPrestateProvider(cfg.AsteriscAbsolutePreState) + var prestateSource PrestateSource + if cfg.AsteriscAbsolutePreStateBaseURL != nil { + prestateSource = prestates.NewMultiPrestateProvider(cfg.AsteriscAbsolutePreStateBaseURL, filepath.Join(cfg.Datadir, "asterisc-prestates")) + } else { + prestateSource = prestates.NewSinglePrestateSource(cfg.AsteriscAbsolutePreState) + } playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { contract, err := contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller) if err != nil { return nil, fmt.Errorf("failed to create fault dispute game contracts: %w", err) } + requiredPrestatehash, err := contract.GetAbsolutePrestateHash(ctx) + if err != nil { + return nil, fmt.Errorf("failed to load prestate hash for game %v: %w", game.Proxy, err) + } + prestatePath, err := prestateSource.PrestatePath(requiredPrestatehash) + if err != nil { + return nil, fmt.Errorf("required prestate %v not available for game %v: %w", requiredPrestatehash, game.Proxy, err) + } + asteriscPrestateProvider := asterisc.NewPrestateProvider(prestatePath) + oracle, err := contract.GetOracle(ctx) if err != nil { return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err) diff --git a/op-challenger/game/fault/trace/asterisc/provider.go b/op-challenger/game/fault/trace/asterisc/provider.go index fd4cbbbbb778..d2fe316b5cfb 100644 --- a/op-challenger/game/fault/trace/asterisc/provider.go +++ b/op-challenger/game/fault/trace/asterisc/provider.go @@ -36,19 +36,22 @@ type AsteriscTraceProvider struct { gameDepth types.Depth preimageLoader *utils.PreimageLoader + types.PrestateProvider + // lastStep stores the last step in the actual trace if known. 0 indicates unknown. // Cached as an optimisation to avoid repeatedly attempting to execute beyond the end of the trace. lastStep uint64 } -func NewTraceProvider(logger log.Logger, m AsteriscMetricer, cfg *config.Config, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProvider { +func NewTraceProvider(logger log.Logger, m AsteriscMetricer, cfg *config.Config, prestateProvider types.PrestateProvider, localInputs utils.LocalGameInputs, dir string, gameDepth types.Depth) *AsteriscTraceProvider { return &AsteriscTraceProvider{ - logger: logger, - dir: dir, - prestate: cfg.AsteriscAbsolutePreState, - generator: NewExecutor(logger, m, cfg, localInputs), - gameDepth: gameDepth, - preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(utils.PreimageDir(dir)).Get), + logger: logger, + dir: dir, + prestate: cfg.AsteriscAbsolutePreState, + generator: NewExecutor(logger, m, cfg, localInputs), + gameDepth: gameDepth, + preimageLoader: utils.NewPreimageLoader(kvstore.NewDiskKV(utils.PreimageDir(dir)).Get), + PrestateProvider: prestateProvider, } } @@ -93,22 +96,6 @@ func (p *AsteriscTraceProvider) GetStepData(ctx context.Context, pos types.Posit return value, data, oracleData, nil } -func (p *AsteriscTraceProvider) absolutePreState() (*VMState, error) { - state, err := parseState(p.prestate) - if err != nil { - return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - return state, nil -} - -func (p *AsteriscTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { - state, err := p.absolutePreState() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) - } - return state.StateHash, nil -} - // loadProof will attempt to load or generate the proof data at the specified index // If the requested index is beyond the end of the actual trace it is extended with no-op instructions. func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.ProofData, error) { diff --git a/op-challenger/game/fault/trace/asterisc/state.go b/op-challenger/game/fault/trace/asterisc/state.go index 39b1469ff047..b766cda6f50c 100644 --- a/op-challenger/game/fault/trace/asterisc/state.go +++ b/op-challenger/game/fault/trace/asterisc/state.go @@ -3,6 +3,7 @@ package asterisc import ( "encoding/json" "fmt" + "io" "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-service/ioutil" @@ -57,13 +58,17 @@ func parseState(path string) (*VMState, error) { if err != nil { return nil, fmt.Errorf("cannot open state file (%v): %w", path, err) } - defer file.Close() + return parseStateFromReader(file) +} + +func parseStateFromReader(in io.ReadCloser) (*VMState, error) { + defer in.Close() var state VMState - if err := json.NewDecoder(file).Decode(&state); err != nil { - return nil, fmt.Errorf("invalid asterisc VM state (%v): %w", path, err) + if err := json.NewDecoder(in).Decode(&state); err != nil { + return nil, fmt.Errorf("invalid asterisc VM state %w", err) } if err := state.validateState(); err != nil { - return nil, fmt.Errorf("invalid asterisc VM state (%v): %w", path, err) + return nil, fmt.Errorf("invalid asterisc VM state %w", err) } return &state, nil } diff --git a/op-challenger/game/fault/trace/outputs/output_asterisc.go b/op-challenger/game/fault/trace/outputs/output_asterisc.go index f4c119b93e9c..b33662d901cb 100644 --- a/op-challenger/game/fault/trace/outputs/output_asterisc.go +++ b/op-challenger/game/fault/trace/outputs/output_asterisc.go @@ -39,7 +39,7 @@ func NewOutputAsteriscTraceAccessor( if err != nil { return nil, fmt.Errorf("failed to fetch asterisc local inputs: %w", err) } - provider := asterisc.NewTraceProvider(logger, m, cfg, localInputs, subdir, depth) + provider := asterisc.NewTraceProvider(logger, m, cfg, prestateProvider, localInputs, subdir, depth) return provider, nil }