Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testcases for EELS-bugs #140

Merged
merged 9 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions cmd/minimizer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ var fullTraceFlag = &cli.BoolFlag{
"looking for a differing stateroot.",
}

var patienceFlag = &cli.UintFlag{
Name: "patience",
Usage: "If set to a high value, the minmizer will spend more time retrying it's various minimization routines",
Value: 5,
}

func initApp() *cli.App {
app := cli.NewApp()
app.Name = filepath.Base(os.Args[0])
app.Authors = []*cli.Author{{Name: "Martin Holst Swende"}}
app.Usage = "Test-case minimizer"
app.Flags = append(app.Flags, common.VmFlags...)
app.Flags = append(app.Flags, fullTraceFlag)
app.Flags = append(app.Flags, fullTraceFlag, patienceFlag)
app.Action = startFuzzer
return app
}
Expand All @@ -64,6 +70,7 @@ func startFuzzer(c *cli.Context) error {
var (
testPath = c.Args().First()
compareFn func(path string, c *cli.Context) (bool, error)
patience = c.Int(patienceFlag.Name)
)
compareFn = func(path string, c *cli.Context) (bool, error) {
agree, err := common.RootsEqual(path, c)
Expand Down Expand Up @@ -131,13 +138,15 @@ func startFuzzer(c *cli.Context) error {
}

// Try decreasing gas
gas := sort.Search(int(gst[testname].Tx.GasLimit[0]), func(i int) bool {
gst[testname].Tx.GasLimit[0] = uint64(i)
log.Info("Mutating gas", "value", i)
return !inConsensus()
})
// And restore the gas again
gst[testname].Tx.GasLimit[0] = uint64(gas)
{
gas := sort.Search(int(gst[testname].Tx.GasLimit[0]), func(i int) bool {
gst[testname].Tx.GasLimit[0] = uint64(i)
log.Info("Mutating gas", "value", i)
return !inConsensus()
})
// And restore the gas again
gst[testname].Tx.GasLimit[0] = uint64(gas)
}

// Try removing accounts
for target, acc := range gst[testname].Pre {
Expand Down Expand Up @@ -176,7 +185,7 @@ func startFuzzer(c *cli.Context) error {
// restore it
acc.Code = m.current
gst[testname].Pre[target] = acc
if fails > 5 {
if fails > patience {
break
}
}
Expand Down Expand Up @@ -210,7 +219,7 @@ func startFuzzer(c *cli.Context) error {
// restore it
acc.Code = m.current
gst[testname].Pre[target] = acc
if fails > 5 {
if fails > patience {
break
}
}
Expand Down
5 changes: 2 additions & 3 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ RUN apt-get install -qy --no-install-recommends openjdk-17-jre

# Install execution-specs (EELS)
RUN apt-get install -qy --no-install-recommends pipx git && \
git clone https://github.com/ethereum/execution-specs.git --branch statetests --depth 1 && \
git clone https://github.com/ethereum/execution-specs.git --branch forks/cancun --depth 1 && \
PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/ pipx install './execution-specs/[test]'
ENV EELS_BIN=/ethereum-spec-evm

Expand All @@ -158,7 +158,7 @@ COPY --from=golang-builder /go/go-ethereum/build/bin/evm /gethvm
ENV GETH_BIN=/gethvm

COPY --from=golang-builder /erigon_vm /erigon_vm
COPY --from=golang-builder /go/pkg/mod/github.com/erigontech/silkworm-go@v0.14.0/lib/linux_x64/libsilkworm_capi.so /lib/libsilkworm_capi.so
COPY --from=golang-builder /go/pkg/mod/github.com/erigontech/silkworm-go@v0.15.0/lib/linux_x64/libsilkworm_capi.so /lib/libsilkworm_capi.so
ENV ERIG_BIN=/erigon_vm

COPY --from=golang-builder /evmstate /nimbvm
Expand All @@ -180,7 +180,6 @@ RUN ln -s /evmtool/bin/evm besu-vm
ENV BESU_BIN=/evmtool/bin/evm

COPY readme_docker.md /README.md
COPY entrypoint.sh /entrypoint.sh

ENV FUZZ_CLIENTS="--gethbatch=$GETH_BIN \
--nethbatch=$NETH_BIN \
Expand Down
58 changes: 58 additions & 0 deletions examples/create2_bug/00002797-mixed-67.min.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"00002797-mixed-67": {
"env": {
"currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty": "0x200000",
"currentRandom": "0x0000000000000000000000000000000000000000000000000000000000020000",
"currentGasLimit": "0x26e1f476fe1e22",
"currentNumber": "0x1",
"currentTimestamp": "0x3e8",
"previousHash": "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d",
"currentBaseFee": "0x10"
},
"pre": {
"0x00000000000000000000000000000000000000f1": {
"code": "0x6043605060ab607060cc606c609251194465049d3a5b5b0172fd5b623153803c715b7c8482055e49071233651b6a11531063346aa0fa774654f57b",
"storage": {},
"balance": "0x0",
"nonce": "0x0"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"code": "0x",
"storage": {},
"balance": "0xffffffffff",
"nonce": "0x0"
}
},
"transaction": {
"gasPrice": "0x10",
"nonce": "0x0",
"to": "0x00000000000000000000000000000000000000f1",
"data": [
"0xbf71a3a5d0"
],
"gasLimit": [
"0x1ff81"
],
"value": [
"0x392aca"
],
"sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
},
"out": "0x",
"post": {
"Cancun": [
{
"hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"logs": "0x0000000000000000000000000000000000000000000000000000000000000000",
"indexes": {
"data": 0,
"gas": 0,
"value": 0
}
}
]
}
}
}
13 changes: 13 additions & 0 deletions examples/create2_bug/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## CREATE2 initcode-size check bug

This example builds a testcase for https://github.com/ethereum/execution-specs/issues/915


This program does a CREATE2 which fails. The CREATE2 can fail for two reasons:

1. it is way to large initcode. This failure exits the current scope.
2. it tries to use too large endowment. This failure fails the create2-op, butdoes not exit the current scope.

The consensus-correct way to fail is 1).

Finished testcase: [./create2_test.json]
58 changes: 58 additions & 0 deletions examples/create2_bug/create2_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"tstore_test-1": {
"env": {
"currentCoinbase": "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty": "0x200000",
"currentRandom": "0x0000000000000000000000000000000000000000000000000000000000020000",
"currentGasLimit": "0x26e1f476fe1e22",
"currentNumber": "0x1",
"currentTimestamp": "0x3e8",
"previousHash": "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d",
"currentBaseFee": "0x10"
},
"pre": {
"0x00000000000000000000000000000000000000aa": {
"code": "0x5f5f5f620200005f6342f17fb3f56001600155",
"storage": {},
"balance": "0x0",
"nonce": "0x0"
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"code": "0x",
"storage": {},
"balance": "0xffffffffff",
"nonce": "0x0"
}
},
"transaction": {
"gasPrice": "0x16",
"nonce": "0x0",
"to": "0x00000000000000000000000000000000000000AA",
"data": [
"0x"
],
"gasLimit": [
"0x7a1200"
],
"value": [
"0x01"
],
"sender": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
},
"out": "0x",
"post": {
"Cancun": [
{
"hash": "0xb59e5b7317c5173c8595643fd5bf9d8721d25b1ef95ec5b69ccd10eea5fdf036",
"logs": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"indexes": {
"data": 0,
"gas": 0,
"value": 0
}
}
]
}
}
}
8 changes: 8 additions & 0 deletions examples/create2_bug/expected.trace.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{"pc":0,"op":95,"gas":"0x79bff8","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":1,"op":95,"gas":"0x79bff6","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":2,"op":95,"gas":"0x79bff4","gasCost":"0x2","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":3,"op":98,"gas":"0x79bff2","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH3"}
{"pc":7,"op":95,"gas":"0x79bfef","gasCost":"0x2","memSize":0,"stack":["0x0","0x0","0x0","0x20000"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":8,"op":99,"gas":"0x79bfed","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x20000","0x0"],"depth":1,"refund":0,"opName":"PUSH4"}
{"pc":13,"op":245,"gas":"0x79bfea","gasCost":"0x7d00","memSize":0,"stack":["0x0","0x0","0x0","0x20000","0x0","0x42f17fb3"],"depth":1,"refund":0,"opName":"CREATE2","error":"out of gas"}
{"output":"","gasUsed":"0x79bff8","error":"out of gas"}
83 changes: 83 additions & 0 deletions examples/create2_bug/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2019 Martin Holst Swende, Hubert Ritzdorf
// This file is part of the goevmlab library.
//
// The library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the goevmlab library. If not, see <http://www.gnu.org/licenses/>.

package main

import (
"encoding/json"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/goevmlab/fuzzing"
"github.com/holiman/goevmlab/ops"
"github.com/holiman/goevmlab/program"
"os"
)

func main() {
if err := makeTest(); err != nil {
fmt.Printf("error: %v\n", err)
}
}

func makeTest() error {
gst := fuzzing.BasicStateTest("Cancun")

a := common.HexToAddress("0xaa")
// This program does a CREATE2 which fails. The CREATE2 can fail for two reasons:
// 1: it is way to large initcode. This failure exits the current scope.
// 2: it tries to use too large endowment. This failure fails the create2-op, but
// does not exit the current scope.
//
// The consensus-correct way to fail is 1).
{
aa := program.NewProgram()
aa.Push0() // gas
aa.Push0() // input
aa.Push0() //salt
aa.Push(0x20000) // size
aa.Push0() // offset
aa.Push(1123123123) // endowment
aa.Op(ops.CREATE2)
// Make a mark on the state
aa.Sstore(1, 1)
gst.AddAccount(a, fuzzing.GenesisAccount{
Code: aa.Bytecode(),
Balance: big.NewInt(0),
Storage: make(map[common.Hash]common.Hash),
})
}

// The transaction from sender to a
{
fuzzing.AddTransaction(&a, gst)
}
traceOut, err := os.Create("expected.trace.jsonl")
if err != nil {
return err
}
defer traceOut.Close()
if err := gst.Fill(traceOut); err != nil {
return err
}
t := gst.ToGeneralStateTest("tstore_test-1")
output, err := json.MarshalIndent(t, "", " ")
if err != nil {
return err
}
return os.WriteFile("create2_test.json", output, 0777)
}
16 changes: 16 additions & 0 deletions examples/tstore_bug-2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## TSTORE bug #1

This example builds a testcase for https://github.com/ethereum/execution-specs/issues/917

The bug is pretty subtle, it pertains to T-storage inside contract deployments.

1. `a`: Run a `CREATE2`
2. `b`: In the initcode, `SSTORE(slot:1, value:1)`
3. `b`: Return too large bytecode, thus failing the creation
4. `a`: Run the `CREATE2` again
5. `b`: check `SLOAD(slot:1)`. If this is non-zero, we have hit the bug.

The testcase implements one way of doing it.

Finished testcase: [./tstore_test-2.json]

33 changes: 33 additions & 0 deletions examples/tstore_bug-2/expected.trace.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{"pc":0,"op":127,"gas":"0x79bff8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH32"}
{"pc":33,"op":96,"gas":"0x79bff5","gasCost":"0x3","memSize":0,"stack":["0x60015c61600a0361600060015d6000f300000000000000000000000000000000"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":35,"op":82,"gas":"0x79bff2","gasCost":"0x6","memSize":0,"stack":["0x60015c61600a0361600060015d6000f300000000000000000000000000000000","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}
{"pc":36,"op":95,"gas":"0x79bfec","gasCost":"0x2","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":37,"op":96,"gas":"0x79bfea","gasCost":"0x3","memSize":32,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":39,"op":95,"gas":"0x79bfe7","gasCost":"0x2","memSize":32,"stack":["0x0","0x20"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":40,"op":95,"gas":"0x79bfe5","gasCost":"0x2","memSize":32,"stack":["0x0","0x20","0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":41,"op":245,"gas":"0x79bfe3","gasCost":"0x7d08","memSize":32,"stack":["0x0","0x20","0x0","0x0"],"depth":1,"refund":0,"opName":"CREATE2"}
{"pc":0,"op":96,"gas":"0x775dd0","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":92,"gas":"0x775dcd","gasCost":"0x64","memSize":0,"stack":["0x1"],"depth":2,"refund":0,"opName":"TLOAD"}
{"pc":3,"op":97,"gas":"0x775d69","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"}
{"pc":6,"op":3,"gas":"0x775d66","gasCost":"0x3","memSize":0,"stack":["0x0","0x600a"],"depth":2,"refund":0,"opName":"SUB"}
{"pc":7,"op":97,"gas":"0x775d63","gasCost":"0x3","memSize":0,"stack":["0x600a"],"depth":2,"refund":0,"opName":"PUSH2"}
{"pc":10,"op":96,"gas":"0x775d60","gasCost":"0x3","memSize":0,"stack":["0x600a","0x6000"],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":12,"op":93,"gas":"0x775d5d","gasCost":"0x64","memSize":0,"stack":["0x600a","0x6000","0x1"],"depth":2,"refund":0,"opName":"TSTORE"}
{"pc":13,"op":96,"gas":"0x775cf9","gasCost":"0x3","memSize":0,"stack":["0x600a"],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":15,"op":243,"gas":"0x775cf6","gasCost":"0xd86","memSize":0,"stack":["0x600a","0x0"],"depth":2,"refund":0,"opName":"RETURN"}
{"pc":42,"op":95,"gas":"0x1e50b","gasCost":"0x2","memSize":32,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":43,"op":96,"gas":"0x1e509","gasCost":"0x3","memSize":32,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":45,"op":95,"gas":"0x1e506","gasCost":"0x2","memSize":32,"stack":["0x0","0x0","0x20"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":46,"op":95,"gas":"0x1e504","gasCost":"0x2","memSize":32,"stack":["0x0","0x0","0x20","0x0"],"depth":1,"refund":0,"opName":"PUSH0"}
{"pc":47,"op":245,"gas":"0x1e502","gasCost":"0x7d08","memSize":32,"stack":["0x0","0x0","0x20","0x0","0x0"],"depth":1,"refund":0,"opName":"CREATE2"}
{"pc":0,"op":96,"gas":"0x1625b","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":92,"gas":"0x16258","gasCost":"0x64","memSize":0,"stack":["0x1"],"depth":2,"refund":0,"opName":"TLOAD"}
{"pc":3,"op":97,"gas":"0x161f4","gasCost":"0x3","memSize":0,"stack":["0x0"],"depth":2,"refund":0,"opName":"PUSH2"}
{"pc":6,"op":3,"gas":"0x161f1","gasCost":"0x3","memSize":0,"stack":["0x0","0x600a"],"depth":2,"refund":0,"opName":"SUB"}
{"pc":7,"op":97,"gas":"0x161ee","gasCost":"0x3","memSize":0,"stack":["0x600a"],"depth":2,"refund":0,"opName":"PUSH2"}
{"pc":10,"op":96,"gas":"0x161eb","gasCost":"0x3","memSize":0,"stack":["0x600a","0x6000"],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":12,"op":93,"gas":"0x161e8","gasCost":"0x64","memSize":0,"stack":["0x600a","0x6000","0x1"],"depth":2,"refund":0,"opName":"TSTORE"}
{"pc":13,"op":96,"gas":"0x16184","gasCost":"0x3","memSize":0,"stack":["0x600a"],"depth":2,"refund":0,"opName":"PUSH1"}
{"pc":15,"op":243,"gas":"0x16181","gasCost":"0xd86","memSize":0,"stack":["0x600a","0x0"],"depth":2,"refund":0,"opName":"RETURN"}
{"pc":48,"op":0,"gas":"0x59f","gasCost":"0x0","memSize":32,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"STOP"}
{"output":"","gasUsed":"0x79ba59"}
Loading