diff --git a/cannon/cmd/run.go b/cannon/cmd/run.go index f4d57a114d5aeca7ea1e8c1995b896ecf56dd020..df1870d73554cb70151b63bd786fe3cb35353f31 100644 --- a/cannon/cmd/run.go +++ b/cannon/cmd/run.go @@ -23,6 +23,13 @@ import ( ) var ( + RunType = &cli.StringFlag{ + Name: "type", + Usage: "VM type to run. Options are 'cannon' (default)", + Value: "cannon", + // TODO(client-pod#903): This should be required once we have additional vm types + Required: false, + } RunInputFlag = &cli.PathFlag{ Name: "input", Usage: "path of input JSON state. Stdin if left empty.", @@ -250,14 +257,20 @@ func Guard(proc *os.ProcessState, fn StepFn) StepFn { var _ mipsevm.PreimageOracle = (*ProcessPreimageOracle)(nil) +type VMType string + +var cannonVMType VMType = "cannon" + func Run(ctx *cli.Context) error { if ctx.Bool(RunPProfCPU.Name) { defer profile.Start(profile.NoShutdownHook, profile.ProfilePath("."), profile.CPUProfile).Stop() } - state, err := jsonutil.LoadJSON[mipsevm.State](ctx.Path(RunInputFlag.Name)) - if err != nil { - return err + var vmType VMType + if vmTypeStr := ctx.String(RunType.Name); vmTypeStr == string(cannonVMType) { + vmType = cannonVMType + } else { + return fmt.Errorf("unknown VM type %q", vmType) } guestLogger := Logger(os.Stderr, log.LevelInfo) @@ -349,53 +362,65 @@ func Run(ctx *cli.Context) error { } } - us := mipsevm.NewInstrumentedState(state, po, outLog, errLog) - debugProgram := ctx.Bool(RunDebugFlag.Name) - if debugProgram { - if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { - return fmt.Errorf("cannot enable debug mode without a metadata file") + var vm mipsevm.FPVM + var debugProgram bool + if vmType == cannonVMType { + cannon, err := mipsevm.NewInstrumentedStateFromFile(ctx.Path(RunInputFlag.Name), po, outLog, errLog) + if err != nil { + return err } - if err := us.InitDebug(meta); err != nil { - return fmt.Errorf("failed to initialize debug mode: %w", err) + debugProgram = ctx.Bool(RunDebugFlag.Name) + if debugProgram { + if metaPath := ctx.Path(RunMetaFlag.Name); metaPath == "" { + return fmt.Errorf("cannot enable debug mode without a metadata file") + } + if err := cannon.InitDebug(meta); err != nil { + return fmt.Errorf("failed to initialize debug mode: %w", err) + } } + vm = cannon + } else { + return fmt.Errorf("unknown VM type %q", vmType) } + proofFmt := ctx.String(RunProofFmtFlag.Name) snapshotFmt := ctx.String(RunSnapshotFmtFlag.Name) - stepFn := us.Step + stepFn := vm.Step if po.cmd != nil { stepFn = Guard(po.cmd.ProcessState, stepFn) } start := time.Now() - startStep := state.Step + + state := vm.GetState() + startStep := state.GetStep() // avoid symbol lookups every instruction by preparing a matcher func sleepCheck := meta.SymbolMatcher("runtime.notesleep") - for !state.Exited { - if state.Step%100 == 0 { // don't do the ctx err check (includes lock) too often + for !state.GetExited() { + step := state.GetStep() + if step%100 == 0 { // don't do the ctx err check (includes lock) too often if err := ctx.Context.Err(); err != nil { return err } } - step := state.Step - if infoAt(state) { delta := time.Since(start) l.Info("processing", "step", step, - "pc", mipsevm.HexU32(state.Cpu.PC), - "insn", mipsevm.HexU32(state.Memory.GetMemory(state.Cpu.PC)), + "pc", mipsevm.HexU32(state.GetPC()), + "insn", mipsevm.HexU32(state.GetMemory().GetMemory(state.GetPC())), "ips", float64(step-startStep)/(float64(delta)/float64(time.Second)), - "pages", state.Memory.PageCount(), - "mem", state.Memory.Usage(), - "name", meta.LookupSymbol(state.Cpu.PC), + "pages", state.GetMemory().PageCount(), + "mem", state.GetMemory().Usage(), + "name", meta.LookupSymbol(state.GetPC()), ) } - if sleepCheck(state.Cpu.PC) { // don't loop forever when we get stuck because of an unexpected bad program + if sleepCheck(state.GetPC()) { // don't loop forever when we get stuck because of an unexpected bad program return fmt.Errorf("got stuck in Go sleep at step %d", step) } @@ -411,21 +436,14 @@ func Run(ctx *cli.Context) error { } if proofAt(state) { - preStateHash, err := state.EncodeWitness().StateHash() - if err != nil { - return fmt.Errorf("failed to hash prestate witness: %w", err) - } witness, err := stepFn(true) if err != nil { - return fmt.Errorf("failed at proof-gen step %d (PC: %08x): %w", step, state.Cpu.PC, err) - } - postStateHash, err := state.EncodeWitness().StateHash() - if err != nil { - return fmt.Errorf("failed to hash poststate witness: %w", err) + return fmt.Errorf("failed at proof-gen step %d (PC: %08x): %w", step, state.GetPC(), err) } + _, postStateHash := state.EncodeWitness() proof := &Proof{ Step: step, - Pre: preStateHash, + Pre: witness.StateHash, Post: postStateHash, StateData: witness.State, ProofData: witness.MemProof, @@ -441,11 +459,11 @@ func Run(ctx *cli.Context) error { } else { _, err = stepFn(false) if err != nil { - return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.Cpu.PC, err) + return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.GetPC(), err) } } - lastPreimageKey, lastPreimageValue, lastPreimageOffset := us.LastPreimage() + lastPreimageKey, lastPreimageValue, lastPreimageOffset := vm.LastPreimage() if lastPreimageOffset != ^uint32(0) { if stopAtAnyPreimage { l.Info("Stopping at preimage read") @@ -464,16 +482,16 @@ func Run(ctx *cli.Context) error { } } } - l.Info("Execution stopped", "exited", state.Exited, "code", state.ExitCode) + l.Info("Execution stopped", "exited", state.GetExited(), "code", state.GetExitCode()) if debugProgram { - us.Traceback() + vm.Traceback() } if err := jsonutil.WriteJSON(ctx.Path(RunOutputFlag.Name), state, OutFilePerm); err != nil { return fmt.Errorf("failed to write state output: %w", err) } if debugInfoFile := ctx.Path(RunDebugInfoFlag.Name); debugInfoFile != "" { - if err := jsonutil.WriteJSON(debugInfoFile, us.GetDebugInfo(), OutFilePerm); err != nil { + if err := jsonutil.WriteJSON(debugInfoFile, vm.GetDebugInfo(), OutFilePerm); err != nil { return fmt.Errorf("failed to write benchmark data: %w", err) } } @@ -486,6 +504,7 @@ var RunCommand = &cli.Command{ Description: "Run VM step(s) and generate proof data to replicate onchain. See flags to match when to output a proof, a snapshot, or to stop early.", Action: Run, Flags: []cli.Flag{ + RunType, RunInputFlag, RunOutputFlag, RunProofAtFlag, diff --git a/cannon/cmd/witness.go b/cannon/cmd/witness.go index c2f38daa362199d705c1beb2ff3511ea9822ed06..c869f2b4cf86bac10be4ba7ed0ff3a6b90f1ae12 100644 --- a/cannon/cmd/witness.go +++ b/cannon/cmd/witness.go @@ -30,11 +30,7 @@ func Witness(ctx *cli.Context) error { if err != nil { return fmt.Errorf("invalid input state (%v): %w", input, err) } - witness := state.EncodeWitness() - h, err := witness.StateHash() - if err != nil { - return fmt.Errorf("failed to compute witness hash: %w", err) - } + witness, h := state.EncodeWitness() if output != "" { if err := os.WriteFile(output, witness, 0755); err != nil { return fmt.Errorf("writing output to %v: %w", output, err) diff --git a/cannon/mipsevm/evm_test.go b/cannon/mipsevm/evm_test.go index 14c53220c432e9fb3cab88f15ad603b8a11fd314..edc6675f55815e82ca137b2857aca7238f470406 100644 --- a/cannon/mipsevm/evm_test.go +++ b/cannon/mipsevm/evm_test.go @@ -196,7 +196,7 @@ func TestEVM(t *testing.T) { evmPost := evm.Step(t, stepWitness) // verify the post-state matches. // TODO: maybe more readable to decode the evmPost state, and do attribute-wise comparison. - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equalf(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM at step %d", state.Step) } @@ -243,7 +243,7 @@ func TestEVMSingleStep(t *testing.T) { evm := NewMIPSEVM(contracts, addrs) evm.SetTracer(tracer) evmPost := evm.Step(t, stepWitness) - goPost := us.state.EncodeWitness() + goPost, _ := us.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -421,7 +421,7 @@ func TestEVMSysWriteHint(t *testing.T) { evm := NewMIPSEVM(contracts, addrs) evm.SetTracer(tracer) evmPost := evm.Step(t, stepWitness) - goPost := us.state.EncodeWitness() + goPost, _ := us.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -459,8 +459,9 @@ func TestEVMFault(t *testing.T) { require.Panics(t, func() { _, _ = us.Step(true) }) insnProof := initialState.Memory.MerkleProof(0) + encodedWitness, _ := initialState.EncodeWitness() stepWitness := &StepWitness{ - State: initialState.EncodeWitness(), + State: encodedWitness, MemProof: insnProof[:], } input := encodeStepInput(t, stepWitness, LocalContext{}, contracts.MIPS) @@ -509,7 +510,7 @@ func TestHelloEVM(t *testing.T) { evmPost := evm.Step(t, stepWitness) // verify the post-state matches. // TODO: maybe more readable to decode the evmPost state, and do attribute-wise comparison. - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") } @@ -560,7 +561,7 @@ func TestClaimEVM(t *testing.T) { evm.SetTracer(tracer) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") } diff --git a/cannon/mipsevm/fuzz_evm_test.go b/cannon/mipsevm/fuzz_evm_test.go index 9b11f9363c931ae9a11798ba19db9680b1119784..06b77a10247fd20d376f53386538ad92aeb76026 100644 --- a/cannon/mipsevm/fuzz_evm_test.go +++ b/cannon/mipsevm/fuzz_evm_test.go @@ -61,7 +61,7 @@ func FuzzStateSyscallBrk(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -112,7 +112,7 @@ func FuzzStateSyscallClone(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -173,7 +173,7 @@ func FuzzStateSyscallMmap(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -223,7 +223,7 @@ func FuzzStateSyscallExitGroup(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -288,7 +288,7 @@ func FuzzStateSyscallFcntl(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -340,7 +340,7 @@ func FuzzStateHintRead(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -406,7 +406,7 @@ func FuzzStatePreimageRead(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -466,7 +466,7 @@ func FuzzStateHintWrite(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) @@ -521,7 +521,7 @@ func FuzzStatePreimageWrite(f *testing.F) { evm := NewMIPSEVM(contracts, addrs) evmPost := evm.Step(t, stepWitness) - goPost := goState.state.EncodeWitness() + goPost, _ := goState.state.EncodeWitness() require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(), "mipsevm produced different state than EVM") }) diff --git a/cannon/mipsevm/iface.go b/cannon/mipsevm/iface.go new file mode 100644 index 0000000000000000000000000000000000000000..2cc8f939fcebdec9138c5a1cc9f613c2719066ad --- /dev/null +++ b/cannon/mipsevm/iface.go @@ -0,0 +1,39 @@ +package mipsevm + +import "github.com/ethereum/go-ethereum/common" + +type FPVMState interface { + GetMemory() *Memory + + // GetPC returns the currently executing program counter + GetPC() uint32 + + // GetStep returns the current VM step + GetStep() uint64 + + // GetExited returns whether the state exited bit is set + GetExited() bool + + // GetExitCode returns the exit code + GetExitCode() uint8 + + // EncodeWitness returns the witness for the current state and the state hash + EncodeWitness() (witness []byte, hash common.Hash) +} + +type FPVM interface { + // GetState returns the current state of the VM. The FPVMState is updated by successive calls to Step + GetState() FPVMState + + // Step executes a single instruction and returns the witness for the step + Step(includeProof bool) (*StepWitness, error) + + // LastPreimage returns the last preimage accessed by the VM + LastPreimage() (preimageKey [32]byte, preimage []byte, preimageOffset uint32) + + // Traceback prints a traceback of the program to the console + Traceback() + + // GetDebugInfo returns debug information about the VM + GetDebugInfo() *DebugInfo +} diff --git a/cannon/mipsevm/instrumented.go b/cannon/mipsevm/instrumented.go index 011c7c4d06309f90b2a2686fd14b622a7464453a..fad3e541c1a185783a408d4b47e6d6daa2a4d773 100644 --- a/cannon/mipsevm/instrumented.go +++ b/cannon/mipsevm/instrumented.go @@ -3,6 +3,8 @@ package mipsevm import ( "errors" "io" + + "github.com/ethereum-optimism/optimism/op-service/jsonutil" ) type PreimageOracle interface { @@ -48,6 +50,19 @@ func NewInstrumentedState(state *State, po PreimageOracle, stdOut, stdErr io.Wri } } +func NewInstrumentedStateFromFile(stateFile string, po PreimageOracle, stdOut, stdErr io.Writer) (*InstrumentedState, error) { + state, err := jsonutil.LoadJSON[State](stateFile) + if err != nil { + return nil, err + } + return &InstrumentedState{ + state: state, + stdOut: stdOut, + stdErr: stdErr, + preimageOracle: &trackingOracle{po: po}, + }, nil +} + func (m *InstrumentedState) InitDebug(meta *Metadata) error { if meta == nil { return errors.New("metadata is nil") @@ -64,9 +79,11 @@ func (m *InstrumentedState) Step(proof bool) (wit *StepWitness, err error) { if proof { insnProof := m.state.Memory.MerkleProof(m.state.Cpu.PC) + encodedWitness, stateHash := m.state.EncodeWitness() wit = &StepWitness{ - State: m.state.EncodeWitness(), - MemProof: insnProof[:], + State: encodedWitness, + StateHash: stateHash, + MemProof: insnProof[:], } } err = m.mipsStep() @@ -89,11 +106,15 @@ func (m *InstrumentedState) LastPreimage() ([32]byte, []byte, uint32) { return m.lastPreimageKey, m.lastPreimage, m.lastPreimageOffset } -func (d *InstrumentedState) GetDebugInfo() *DebugInfo { +func (m *InstrumentedState) GetState() FPVMState { + return m.state +} + +func (m *InstrumentedState) GetDebugInfo() *DebugInfo { return &DebugInfo{ - Pages: d.state.Memory.PageCount(), - NumPreimageRequests: d.preimageOracle.numPreimageRequests, - TotalPreimageSize: d.preimageOracle.totalPreimageSize, + Pages: m.state.Memory.PageCount(), + NumPreimageRequests: m.preimageOracle.numPreimageRequests, + TotalPreimageSize: m.preimageOracle.totalPreimageSize, } } diff --git a/cannon/mipsevm/state.go b/cannon/mipsevm/state.go index c8a681f23e37eb9436722f89e4c454fa8a115f13..474f800219690ae65f4cc9a774235481eca9d4a1 100644 --- a/cannon/mipsevm/state.go +++ b/cannon/mipsevm/state.go @@ -104,13 +104,23 @@ func (s *State) UnmarshalJSON(data []byte) error { return nil } +func (s *State) GetPC() uint32 { return s.Cpu.PC } + +func (s *State) GetExitCode() uint8 { return s.ExitCode } + +func (s *State) GetExited() bool { return s.Exited } + func (s *State) GetStep() uint64 { return s.Step } func (s *State) VMStatus() uint8 { return vmStatus(s.Exited, s.ExitCode) } -func (s *State) EncodeWitness() StateWitness { +func (s *State) GetMemory() *Memory { + return s.Memory +} + +func (s *State) EncodeWitness() ([]byte, common.Hash) { out := make([]byte, 0) memRoot := s.Memory.MerkleRoot() out = append(out, memRoot[:]...) @@ -131,7 +141,7 @@ func (s *State) EncodeWitness() StateWitness { for _, r := range s.Registers { out = binary.BigEndian.AppendUint32(out, r) } - return out + return out, stateHashFromWitness(out) } type StateWitness []byte @@ -147,14 +157,20 @@ func (sw StateWitness) StateHash() (common.Hash, error) { if len(sw) != 226 { return common.Hash{}, fmt.Errorf("Invalid witness length. Got %d, expected 226", len(sw)) } + return stateHashFromWitness(sw), nil +} +func stateHashFromWitness(sw []byte) common.Hash { + if len(sw) != 226 { + panic("Invalid witness length") + } hash := crypto.Keccak256Hash(sw) offset := 32*2 + 4*6 exitCode := sw[offset] exited := sw[offset+1] status := vmStatus(exited == 1, exitCode) hash[0] = status - return hash, nil + return hash } func vmStatus(exited bool, exitCode uint8) uint8 { diff --git a/cannon/mipsevm/state_test.go b/cannon/mipsevm/state_test.go index dfb90674ec78ae902fcc339e2988ecc83bc2cf8d..fe36267926cacbb6683650ebc2743c84c4a91cc7 100644 --- a/cannon/mipsevm/state_test.go +++ b/cannon/mipsevm/state_test.go @@ -104,9 +104,7 @@ func TestStateHash(t *testing.T) { ExitCode: c.exitCode, } - actualWitness := state.EncodeWitness() - actualStateHash, err := StateWitness(actualWitness).StateHash() - require.NoError(t, err, "Error hashing witness") + actualWitness, actualStateHash := state.EncodeWitness() require.Equal(t, len(actualWitness), StateWitnessSize, "Incorrect witness size") expectedWitness := make(StateWitness, 226) @@ -118,7 +116,7 @@ func TestStateHash(t *testing.T) { exited = 1 } expectedWitness[exitedOffset+1] = uint8(exited) - require.Equal(t, expectedWitness[:], actualWitness[:], "Incorrect witness") + require.EqualValues(t, expectedWitness[:], actualWitness[:], "Incorrect witness") expectedStateHash := crypto.Keccak256Hash(actualWitness) expectedStateHash[0] = vmStatus(c.exited, c.exitCode) diff --git a/cannon/mipsevm/witness.go b/cannon/mipsevm/witness.go index 58039a86ea32ca22a0358dd0c233f004c31129a5..ef75db69c65c39bb3286488a6e5c907816b91a33 100644 --- a/cannon/mipsevm/witness.go +++ b/cannon/mipsevm/witness.go @@ -6,7 +6,8 @@ type LocalContext common.Hash type StepWitness struct { // encoded state witness - State []byte + State []byte + StateHash common.Hash MemProof []byte diff --git a/op-challenger/game/fault/trace/cannon/prestate.go b/op-challenger/game/fault/trace/cannon/prestate.go index 67d7c55389c2756e5ef3a5941dd9dac1c27fe8b7..3853e619567ba99169fdf919e997b881be65a9b9 100644 --- a/op-challenger/game/fault/trace/cannon/prestate.go +++ b/op-challenger/game/fault/trace/cannon/prestate.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/ethereum-optimism/optimism/cannon/mipsevm" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" ) @@ -22,26 +21,23 @@ func NewPrestateProvider(prestate string) *CannonPrestateProvider { return &CannonPrestateProvider{prestate: prestate} } -func (p *CannonPrestateProvider) absolutePreState() ([]byte, error) { +func (p *CannonPrestateProvider) absolutePreState() ([]byte, common.Hash, error) { state, err := parseState(p.prestate) if err != nil { - return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) + return nil, common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) } - return state.EncodeWitness(), nil + witness, hash := state.EncodeWitness() + return witness, hash, nil } func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) { if p.prestateCommitment != (common.Hash{}) { return p.prestateCommitment, nil } - state, err := p.absolutePreState() + _, hash, err := p.absolutePreState() if err != nil { return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) } - hash, err := mipsevm.StateWitness(state).StateHash() - if err != nil { - return common.Hash{}, fmt.Errorf("cannot hash absolute pre-state: %w", err) - } p.prestateCommitment = hash return hash, nil } diff --git a/op-challenger/game/fault/trace/cannon/prestate_test.go b/op-challenger/game/fault/trace/cannon/prestate_test.go index a8616f1711808af738ff7ec8e401677dd4c1c556..9dadbbc94ff8dc9cd9ffa7256884cd2f33a6ed7e 100644 --- a/op-challenger/game/fault/trace/cannon/prestate_test.go +++ b/op-challenger/game/fault/trace/cannon/prestate_test.go @@ -56,8 +56,7 @@ func TestAbsolutePreStateCommitment(t *testing.T) { Step: 0, Registers: [32]uint32{}, } - expected, err := state.EncodeWitness().StateHash() - require.NoError(t, err) + _, expected := state.EncodeWitness() require.Equal(t, expected, actual) }) diff --git a/op-challenger/game/fault/trace/cannon/provider.go b/op-challenger/game/fault/trace/cannon/provider.go index c565b9b39b75df40161b8a7dc679a2292469ca97..7b55035aa190141e3dd2e2b524bd59ec63ea0032 100644 --- a/op-challenger/game/fault/trace/cannon/provider.go +++ b/op-challenger/game/fault/trace/cannon/provider.go @@ -132,11 +132,7 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P p.lastStep = state.Step - 1 // Extend the trace out to the full length using a no-op instruction that doesn't change any state // No execution is done, so no proof-data or oracle values are required. - witness := state.EncodeWitness() - witnessHash, err := mipsevm.StateWitness(witness).StateHash() - if err != nil { - return nil, fmt.Errorf("cannot hash witness: %w", err) - } + witness, witnessHash := state.EncodeWitness() proof := &utils.ProofData{ ClaimValue: witnessHash, StateData: hexutil.Bytes(witness), diff --git a/op-challenger/game/fault/trace/cannon/provider_test.go b/op-challenger/game/fault/trace/cannon/provider_test.go index 94277ed88399b1ef6e90860f3b693ff47ffa657b..87f6105c4279b14eab639c5a460760d1d0bbef0f 100644 --- a/op-challenger/game/fault/trace/cannon/provider_test.go +++ b/op-challenger/game/fault/trace/cannon/provider_test.go @@ -57,8 +57,7 @@ func TestGet(t *testing.T) { value, err := provider.Get(context.Background(), PositionFromTraceIndex(provider, big.NewInt(7000))) require.NoError(t, err) require.Contains(t, generator.generated, 7000, "should have tried to generate the proof") - stateHash, err := generator.finalState.EncodeWitness().StateHash() - require.NoError(t, err) + _, stateHash := generator.finalState.EncodeWitness() require.Equal(t, stateHash, value) }) @@ -149,7 +148,7 @@ func TestGetStepData(t *testing.T) { require.NoError(t, err) require.Contains(t, generator.generated, 7000, "should have tried to generate the proof") - witness := generator.finalState.EncodeWitness() + witness, _ := generator.finalState.EncodeWitness() require.EqualValues(t, witness, preimage) require.Equal(t, []byte{}, proof) require.Nil(t, data) @@ -190,7 +189,8 @@ func TestGetStepData(t *testing.T) { require.NoError(t, err) require.Empty(t, generator.generated, "should not have to generate the proof again") - require.EqualValues(t, initGenerator.finalState.EncodeWitness(), preimage) + encodedWitness, _ := initGenerator.finalState.EncodeWitness() + require.EqualValues(t, encodedWitness, preimage) require.Empty(t, proof) require.Nil(t, data) })