From bb87eef8be59586c4608da8495ea6ae2a2848730 Mon Sep 17 00:00:00 2001 From: Inphi Date: Thu, 26 Sep 2024 14:17:55 -0400 Subject: [PATCH] cannon: Consistent state serialization (#12151) * cannon: Consistent state serialization * nosilent cmp * fix run input * add elf target dep --- cannon/Makefile | 23 ++++++++++++++++++++++- cannon/mipsevm/memory/memory.go | 8 +++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/cannon/Makefile b/cannon/Makefile index 7dfc39c44023..ea9a29ebb5c2 100644 --- a/cannon/Makefile +++ b/cannon/Makefile @@ -43,6 +43,26 @@ contract: test: elf contract go test -v ./... +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 "" + @cmp ./bin/prestate-other.bin.gz ./bin/prestate.bin.gz + @if [ $$? -eq 0 ]; then \ + echo "Generated identical prestates"; \ + else \ + echo "Generated different prestates"; \ + exit 1; \ + fi + $$OTHER_CANNON run --proof-at '=0' --stop-at '=100000000' --input=./bin/prestate.bin.gz --output ./bin/out-other.bin.gz --meta "" + ./bin/cannon run --proof-at '=0' --stop-at '=100000000' --input=./bin/prestate.bin.gz --output ./bin/out.bin.gz --meta "" + @cmp ./bin/out-other.bin.gz ./bin/out.bin.gz + @if [ $$? -eq 0 ]; then \ + echo "Generated identical states"; \ + else \ + echo "Generated different prestates"; \ + exit 1; \ + fi + fuzz: # Common vm tests go test $(FUZZLDFLAGS) -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallBrk ./mipsevm/tests @@ -65,4 +85,5 @@ fuzz: clean \ test \ lint \ - fuzz + fuzz \ + diff-%-cannon diff --git a/cannon/mipsevm/memory/memory.go b/cannon/mipsevm/memory/memory.go index 392a0482c48e..ea5c279763b3 100644 --- a/cannon/mipsevm/memory/memory.go +++ b/cannon/mipsevm/memory/memory.go @@ -6,9 +6,11 @@ import ( "fmt" "io" "math/bits" + "slices" "sort" "github.com/ethereum/go-ethereum/crypto" + "golang.org/x/exp/maps" ) // Note: 2**12 = 4 KiB, the min phys page size in the Go runtime. @@ -299,7 +301,11 @@ func (m *Memory) Serialize(out io.Writer) error { if err := binary.Write(out, binary.BigEndian, uint32(m.PageCount())); err != nil { return err } - for pageIndex, page := range m.pages { + indexes := maps.Keys(m.pages) + // iterate sorted map keys for consistent serialization + slices.Sort(indexes) + for _, pageIndex := range indexes { + page := m.pages[pageIndex] if err := binary.Write(out, binary.BigEndian, pageIndex); err != nil { return err }