Commit fab95d15 authored by protolambda's avatar protolambda

mipsevm: implement mips in Go, no unicorn required anymore

parent 2ab1eb7e
...@@ -170,13 +170,13 @@ func Run(ctx *cli.Context) error { ...@@ -170,13 +170,13 @@ func Run(ctx *cli.Context) error {
if err != nil { if err != nil {
return err return err
} }
mu, err := mipsevm.NewUnicorn() //mu, err := mipsevm.NewUnicorn()
if err != nil { //if err != nil {
return fmt.Errorf("failed to create unicorn emulator: %w", err) // return fmt.Errorf("failed to create unicorn emulator: %w", err)
} //}
if err := mipsevm.LoadUnicorn(state, mu); err != nil { //if err := mipsevm.LoadUnicorn(state, mu); err != nil {
return fmt.Errorf("failed to load state into unicorn emulator: %w", err) // return fmt.Errorf("failed to load state into unicorn emulator: %w", err)
} //}
l := Logger(os.Stderr, log.LvlInfo) l := Logger(os.Stderr, log.LvlInfo)
outLog := &mipsevm.LoggingWriter{Name: "program std-out", Log: l} outLog := &mipsevm.LoggingWriter{Name: "program std-out", Log: l}
errLog := &mipsevm.LoggingWriter{Name: "program std-err", Log: l} errLog := &mipsevm.LoggingWriter{Name: "program std-err", Log: l}
...@@ -207,14 +207,15 @@ func Run(ctx *cli.Context) error { ...@@ -207,14 +207,15 @@ func Run(ctx *cli.Context) error {
proofAt := ctx.Generic(RunProofAtFlag.Name).(*StepMatcherFlag).Matcher() proofAt := ctx.Generic(RunProofAtFlag.Name).(*StepMatcherFlag).Matcher()
snapshotAt := ctx.Generic(RunSnapshotAtFlag.Name).(*StepMatcherFlag).Matcher() snapshotAt := ctx.Generic(RunSnapshotAtFlag.Name).(*StepMatcherFlag).Matcher()
us, err := mipsevm.NewUnicornState(mu, state, po, outLog, errLog) //us, err := mipsevm.NewUnicornState(mu, state, po, outLog, errLog)
if err != nil { //if err != nil {
return fmt.Errorf("failed to setup instrumented VM state: %w", err) // return fmt.Errorf("failed to setup instrumented VM state: %w", err)
} //}
us := mipsevm.NewNonUnicornState(state, po, outLog, errLog)
proofFmt := ctx.String(RunProofFmtFlag.Name) proofFmt := ctx.String(RunProofFmtFlag.Name)
snapshotFmt := ctx.String(RunSnapshotFmtFlag.Name) snapshotFmt := ctx.String(RunSnapshotFmtFlag.Name)
stepFn := us.Step stepFn := us.NonUnicornStep
if po.cmd != nil { if po.cmd != nil {
stepFn = Guard(po.cmd.ProcessState, stepFn) stepFn = Guard(po.cmd.ProcessState, stepFn)
} }
...@@ -262,7 +263,7 @@ func Run(ctx *cli.Context) error { ...@@ -262,7 +263,7 @@ func Run(ctx *cli.Context) error {
return fmt.Errorf("failed to write proof data: %w", err) return fmt.Errorf("failed to write proof data: %w", err)
} }
} else { } else {
_, err = us.Step(false) _, err = stepFn(false)
if err != nil { if err != nil {
return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.PC, err) return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.PC, err)
} }
......
...@@ -84,7 +84,7 @@ func TestEVM(t *testing.T) { ...@@ -84,7 +84,7 @@ func TestEVM(t *testing.T) {
insn := state.Memory.GetMemory(state.PC) insn := state.Memory.GetMemory(state.PC)
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn) t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
stepWitness, err := us.Step(true) stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err) require.NoError(t, err)
input := stepWitness.EncodeStepInput() input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000) startingGas := uint64(30_000_000)
...@@ -156,7 +156,7 @@ func TestHelloEVM(t *testing.T) { ...@@ -156,7 +156,7 @@ func TestHelloEVM(t *testing.T) {
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn) t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
} }
stepWitness, err := us.Step(true) stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err) require.NoError(t, err)
input := stepWitness.EncodeStepInput() input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000) startingGas := uint64(30_000_000)
...@@ -232,7 +232,7 @@ func TestClaimEVM(t *testing.T) { ...@@ -232,7 +232,7 @@ func TestClaimEVM(t *testing.T) {
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn) t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
} }
stepWitness, err := us.Step(true) stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err) require.NoError(t, err)
input := stepWitness.EncodeStepInput() input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000) startingGas := uint64(30_000_000)
......
This diff is collapsed.
...@@ -74,7 +74,7 @@ func TestState(t *testing.T) { ...@@ -74,7 +74,7 @@ func TestState(t *testing.T) {
if us.state.PC == endAddr { if us.state.PC == endAddr {
break break
} }
_, err := us.Step(false) _, err := us.NonUnicornStep(false)
require.NoError(t, err) require.NoError(t, err)
} }
require.Equal(t, uint32(endAddr), us.state.PC, "must reach end") require.Equal(t, uint32(endAddr), us.state.PC, "must reach end")
...@@ -110,7 +110,7 @@ func TestHello(t *testing.T) { ...@@ -110,7 +110,7 @@ func TestHello(t *testing.T) {
if us.state.Exited { if us.state.Exited {
break break
} }
_, err := us.Step(false) _, err := us.NonUnicornStep(false)
require.NoError(t, err) require.NoError(t, err)
} }
...@@ -217,7 +217,7 @@ func TestClaim(t *testing.T) { ...@@ -217,7 +217,7 @@ func TestClaim(t *testing.T) {
if us.state.Exited { if us.state.Exited {
break break
} }
_, err := us.Step(false) _, err := us.NonUnicornStep(false)
require.NoError(t, err) require.NoError(t, err)
} }
......
...@@ -55,6 +55,15 @@ const ( ...@@ -55,6 +55,15 @@ const (
MipsEINVAL = 0x16 MipsEINVAL = 0x16
) )
func NewNonUnicornState(state *State, po PreimageOracle, stdOut, stdErr io.Writer) *UnicornState {
return &UnicornState{
state: state,
stdOut: stdOut,
stdErr: stdErr,
preimageOracle: po,
}
}
func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, stdErr io.Writer) (*UnicornState, error) { func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, stdErr io.Writer) (*UnicornState, error) {
m := &UnicornState{ m := &UnicornState{
mu: mu, mu: mu,
...@@ -299,6 +308,34 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std ...@@ -299,6 +308,34 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
return m, nil return m, nil
} }
func (m *UnicornState) NonUnicornStep(proof bool) (wit *StepWitness, err error) {
m.memProofEnabled = proof
m.lastMemAccess = ^uint32(0)
m.lastPreimageOffset = ^uint32(0)
if proof {
insnProof := m.state.Memory.MerkleProof(m.state.PC)
wit = &StepWitness{
state: m.state.EncodeWitness(),
memProof: insnProof[:],
}
}
err = m.mipsStep()
if err != nil {
return nil, err
}
if proof {
wit.memProof = append(wit.memProof, m.memProof[:]...)
if m.lastPreimageOffset != ^uint32(0) {
wit.preimageOffset = m.lastPreimageOffset
wit.preimageKey = m.lastPreimageKey
wit.preimageValue = m.lastPreimage
}
}
return
}
func (m *UnicornState) Step(proof bool) (wit *StepWitness, err error) { func (m *UnicornState) Step(proof bool) (wit *StepWitness, err error) {
defer func() { // pre-image oracle or emulator hooks might panic defer func() { // pre-image oracle or emulator hooks might panic
if a := recover(); a != nil { if a := recover(); a != nil {
......
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