Skip to content

Commit

Permalink
tests: external evm benchmarks (ethereum#24050)
Browse files Browse the repository at this point in the history
* tests: add ipsilon/evm-benchmarks git submodule

* tests: plug-in evm-benchmarks
  • Loading branch information
chfast authored Jan 28, 2022
1 parent abd49a6 commit 64c53ed
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
path = tests/testdata
url = https://github.com/ethereum/tests
shallow = true
[submodule "evm-benchmarks"]
path = tests/evm-benchmarks
url = https://github.com/ipsilon/evm-benchmarks
shallow = true
1 change: 1 addition & 0 deletions tests/evm-benchmarks
Submodule evm-benchmarks added at 849b3e
1 change: 1 addition & 0 deletions tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var (
transactionTestDir = filepath.Join(baseDir, "TransactionTests")
rlpTestDir = filepath.Join(baseDir, "RLPTests")
difficultyTestDir = filepath.Join(baseDir, "BasicTests")
benchmarksDir = filepath.Join(".", "evm-benchmarks", "benchmarks")
)

func readJSON(reader io.Reader, value interface{}) error {
Expand Down
121 changes: 121 additions & 0 deletions tests/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ import (
"bufio"
"bytes"
"fmt"
"math/big"
"os"
"path/filepath"
"reflect"
"strings"
"testing"

"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
)
Expand Down Expand Up @@ -61,6 +68,7 @@ func TestState(t *testing.T) {
for _, dir := range []string{
stateTestDir,
legacyStateTestDir,
benchmarksDir,
} {
st.walk(t, dir, func(t *testing.T, name string, test *StateTest) {
for _, subtest := range test.Subtests() {
Expand Down Expand Up @@ -131,3 +139,116 @@ func withTrace(t *testing.T, gasLimit uint64, test func(vm.Config) error) {
// t.Logf("EVM output: 0x%x", tracer.Output())
// t.Logf("EVM error: %v", tracer.Error())
}

func BenchmarkEVM(b *testing.B) {
// Walk the directory.
dir := benchmarksDir
dirinfo, err := os.Stat(dir)
if os.IsNotExist(err) || !dirinfo.IsDir() {
fmt.Fprintf(os.Stderr, "can't find test files in %s, did you clone the evm-benchmarks submodule?\n", dir)
b.Skip("missing test files")
}
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if ext := filepath.Ext(path); ext == ".json" {
name := filepath.ToSlash(strings.TrimPrefix(strings.TrimSuffix(path, ext), dir+string(filepath.Separator)))
b.Run(name, func(b *testing.B) { runBenchmarkFile(b, path) })
}
return nil
})
if err != nil {
b.Fatal(err)
}
}

func runBenchmarkFile(b *testing.B, path string) {
m := make(map[string]StateTest)
if err := readJSONFile(path, &m); err != nil {
b.Fatal(err)
return
}
if len(m) != 1 {
b.Fatal("expected single benchmark in a file")
return
}
for _, t := range m {
runBenchmark(b, &t)
}
}

func runBenchmark(b *testing.B, t *StateTest) {
for _, subtest := range t.Subtests() {
subtest := subtest
key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)

b.Run(key, func(b *testing.B) {
vmconfig := vm.Config{}

config, eips, err := GetChainConfig(subtest.Fork)
if err != nil {
b.Error(err)
return
}
vmconfig.ExtraEips = eips
block := t.genesis(config).ToBlock(nil)
_, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, false)

var baseFee *big.Int
if config.IsLondon(new(big.Int)) {
baseFee = t.json.Env.BaseFee
if baseFee == nil {
// Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to
// parent - 2 : 0xa as the basefee for 'this' context.
baseFee = big.NewInt(0x0a)
}
}
post := t.json.Post[subtest.Fork][subtest.Index]
msg, err := t.json.Tx.toMessage(post, baseFee)
if err != nil {
b.Error(err)
return
}

// Try to recover tx with current signer
if len(post.TxBytes) != 0 {
var ttx types.Transaction
err := ttx.UnmarshalBinary(post.TxBytes)
if err != nil {
b.Error(err)
return
}

if _, err := types.Sender(types.LatestSigner(config), &ttx); err != nil {
b.Error(err)
return
}
}

// Prepare the EVM.
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
context.GetHash = vmTestBlockHash
context.BaseFee = baseFee
evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)

// Create "contract" for sender to cache code analysis.
sender := vm.NewContract(vm.AccountRef(msg.From()), vm.AccountRef(msg.From()),
nil, 0)

b.ResetTimer()
for n := 0; n < b.N; n++ {
// Execute the message.
snapshot := statedb.Snapshot()
_, _, err = evm.Call(sender, *msg.To(), msg.Data(), msg.Gas(), msg.Value())
if err != nil {
b.Error(err)
return
}
statedb.RevertToSnapshot(snapshot)
}

})
}
}

0 comments on commit 64c53ed

Please sign in to comment.