Skip to content

Commit

Permalink
cannon: Implement 64-bit Solidity VM
Browse files Browse the repository at this point in the history
- Implements 64-bit Cannon (with multithreading) in MIPS64.sol
- Re-enable differential testing for 64-bit VMs
  • Loading branch information
Inphi committed Oct 26, 2024
1 parent f26d865 commit 7010229
Show file tree
Hide file tree
Showing 16 changed files with 2,429 additions and 167 deletions.
5 changes: 4 additions & 1 deletion cannon/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ sanitize-program:
contract:
cd ../packages/contracts-bedrock && forge build

test: elf contract
test: elf contract test64
go test -v ./...

test64: elf contract
go test -tags=cannon64 -run '(TestEVM.*64|TestHelloEVM|TestClaimEVM)' ./mipsevm/tests

diff-%-cannon: cannon elf
$$OTHER_CANNON load-elf --type $* --path ./testdata/example/bin/hello.elf --out ./bin/prestate-other.bin.gz --meta ""
./bin/cannon load-elf --type $* --path ./testdata/example/bin/hello.elf --out ./bin/prestate.bin.gz --meta ""
Expand Down
3 changes: 2 additions & 1 deletion cannon/mipsevm/exec/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package exec
import (
"fmt"

"github.com/ethereum-optimism/optimism/cannon/mipsevm/arch"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/memory"
)

Expand Down Expand Up @@ -37,7 +38,7 @@ func (m *MemoryTrackerImpl) TrackMemAccess(effAddr Word) {
// TrackMemAccess2 creates a proof for a memory access following a call to TrackMemAccess
// This is used to generate proofs for contiguous memory accesses within the same step
func (m *MemoryTrackerImpl) TrackMemAccess2(effAddr Word) {
if m.memProofEnabled && m.lastMemAccess+4 != effAddr {
if m.memProofEnabled && m.lastMemAccess+arch.WordSizeBytes != effAddr {
panic(fmt.Errorf("unexpected disjointed mem access at %08x, last memory access is at %08x buffered", effAddr, m.lastMemAccess))
}
m.lastMemAccess = effAddr
Expand Down
6 changes: 3 additions & 3 deletions cannon/mipsevm/exec/mips_instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func ExecuteMipsInstruction(insn uint32, opcode uint32, fun uint32, rs, rt, mem
w := uint32(SelectSubWord(rs, mem, 4, false))
val := w >> (24 - (rs&3)*8)
mask := uint32(0xFFFFFFFF) >> (24 - (rs&3)*8)
lwrResult := ((uint32(rt) & ^mask) | val) & 0xFFFFFFFF
lwrResult := (uint32(rt) & ^mask) | val
if rs&3 == 3 { // loaded bit 31
return SignExtend(Word(lwrResult), 32)
} else {
Expand Down Expand Up @@ -530,13 +530,13 @@ func HandleHiLo(cpu *mipsevm.CpuScalars, registers *[32]Word, fun uint32, rs Wor
cpu.HI = SignExtend(Word(acc>>32), 32)
cpu.LO = SignExtend(Word(uint32(acc)), 32)
case 0x1a: // div
if rt == 0 {
if uint32(rt) == 0 {
panic("instruction divide by zero")
}
cpu.HI = SignExtend(Word(int32(rs)%int32(rt)), 32)
cpu.LO = SignExtend(Word(int32(rs)/int32(rt)), 32)
case 0x1b: // divu
if rt == 0 {
if uint32(rt) == 0 {
panic("instruction divide by zero")
}
cpu.HI = SignExtend(Word(uint32(rs)%uint32(rt)), 32)
Expand Down
24 changes: 11 additions & 13 deletions cannon/mipsevm/tests/evm_common64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/ethereum-optimism/optimism/cannon/mipsevm/arch"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/testutil"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -134,12 +133,12 @@ func TestEVMSingleStep_Operators64(t *testing.T) {

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts)
})
}
}

func TestEVMSingleStep_Shift(t *testing.T) {
func TestEVMSingleStep_Shift64(t *testing.T) {
cases := []struct {
name string
rd Word
Expand Down Expand Up @@ -190,7 +189,8 @@ func TestEVMSingleStep_Shift(t *testing.T) {
for i, tt := range cases {
testName := fmt.Sprintf("%v %v", v.Name, tt.name)
t.Run(testName, func(t *testing.T) {
goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPCAndNextPC(0))
pc := Word(0x0)
goVm := v.VMFactory(nil, os.Stdout, os.Stderr, testutil.CreateLogger(), testutil.WithRandomization(int64(i)), testutil.WithPCAndNextPC(pc))
state := goVm.GetState()
var insn uint32
var rtReg uint32
Expand All @@ -200,7 +200,7 @@ func TestEVMSingleStep_Shift(t *testing.T) {
insn = rtReg<<16 | rdReg<<11 | tt.sa<<6 | tt.funct
state.GetRegistersRef()[rdReg] = tt.rd
state.GetRegistersRef()[rtReg] = tt.rt
testutil.StoreInstruction(state.GetMemory(), 0, insn)
testutil.StoreInstruction(state.GetMemory(), pc, insn)
step := state.GetStep()

// Setup expectations
Expand All @@ -213,7 +213,7 @@ func TestEVMSingleStep_Shift(t *testing.T) {

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts)
})
}
}
Expand Down Expand Up @@ -455,12 +455,12 @@ func TestEVMSingleStep_LoadStore64(t *testing.T) {

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts)
})
}
}

func TestEVMSingleStep_DivMult(t *testing.T) {
func TestEVMSingleStep_DivMult64(t *testing.T) {
cases := []struct {
name string
rs Word
Expand Down Expand Up @@ -560,15 +560,13 @@ func TestEVMSingleStep_DivMult(t *testing.T) {
stepWitness, err := goVm.Step(true)
require.NoError(t, err)
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, nil)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts)
}
})
}
}

func TestEVMSingleStepBranch64(t *testing.T) {
var tracer *tracing.Hooks

func TestEVMSingleStep_Branch64(t *testing.T) {
versions := GetMipsVersionTestCases(t)
cases := []struct {
name string
Expand Down Expand Up @@ -651,7 +649,7 @@ func TestEVMSingleStepBranch64(t *testing.T) {

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts, tracer)
testutil.ValidateEVM(t, stepWitness, step, goVm, v.StateHashFn, v.Contracts)
})
}
}
Expand Down
Loading

0 comments on commit 7010229

Please sign in to comment.