Skip to content

Commit

Permalink
move ANT prestate trace test out of eth/tracers/internal (#661)
Browse files Browse the repository at this point in the history
  • Loading branch information
darioush authored Sep 30, 2024
1 parent 311dbd9 commit 7a5204d
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 14 deletions.
22 changes: 8 additions & 14 deletions eth/tracers/internal/tracetest/prestate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ func TestPrestateWithDiffModeTracer(t *testing.T) {
testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t)
}

func TestPrestateWithDiffModeANTTracer(t *testing.T) {
testPrestateDiffTracer("prestateTracer", "prestate_tracer_ant", t)
}

func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
files, err := os.ReadDir(filepath.Join("testdata", dirPath))
if err != nil {
Expand Down Expand Up @@ -108,16 +104,14 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
var (
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
context = vm.BlockContext{
CanTransfer: core.CanTransfer,
CanTransferMC: core.CanTransferMC,
Transfer: core.Transfer,
TransferMultiCoin: core.TransferMultiCoin,
Coinbase: test.Context.Miner,
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
Time: uint64(test.Context.Time),
Difficulty: (*big.Int)(test.Context.Difficulty),
GasLimit: uint64(test.Context.GasLimit),
BaseFee: test.Genesis.BaseFee,
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
Coinbase: test.Context.Miner,
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
Time: uint64(test.Context.Time),
Difficulty: (*big.Int)(test.Context.Difficulty),
GasLimit: uint64(test.Context.GasLimit),
BaseFee: test.Genesis.BaseFee,
}
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
)
Expand Down
129 changes: 129 additions & 0 deletions plugin/evm/prestate_tracer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// (c) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
"encoding/json"
"math/big"
"os"
"path/filepath"
"strings"
"testing"
"unicode"

"github.com/ava-labs/coreth/core"
"github.com/ava-labs/coreth/core/rawdb"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/core/vm"
"github.com/ava-labs/coreth/eth/tracers"
"github.com/ava-labs/coreth/tests"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
)

func TestPrestateWithDiffModeANTTracer(t *testing.T) {
testPrestateDiffTracer("prestateTracer", "prestate_tracer_ant", t)
}

// testPrestateDiffTracer is adapted from the original testPrestateDiffTracer in
// eth/tracers/internal/tracetest/prestate_test.go.
func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
files, err := os.ReadDir(filepath.Join("testdata", dirPath))
if err != nil {
t.Fatalf("failed to retrieve tracer test suite: %v", err)
}
for _, file := range files {
if !strings.HasSuffix(file.Name(), ".json") {
continue
}
file := file // capture range variable
t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) {
t.Parallel()

var (
test = new(testcase)
tx = new(types.Transaction)
)
// Call tracer test found, read if from disk
if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil {
t.Fatalf("failed to read testcase: %v", err)
} else if err := json.Unmarshal(blob, test); err != nil {
t.Fatalf("failed to parse testcase: %v", err)
}
if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
t.Fatalf("failed to parse testcase input: %v", err)
}
// Configure a blockchain with the given prestate
var (
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
context = vm.BlockContext{
CanTransfer: core.CanTransfer,
CanTransferMC: core.CanTransferMC,
Transfer: core.Transfer,
TransferMultiCoin: core.TransferMultiCoin,
Coinbase: test.Context.Miner,
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
Time: uint64(test.Context.Time),
Difficulty: (*big.Int)(test.Context.Difficulty),
GasLimit: uint64(test.Context.GasLimit),
BaseFee: test.Genesis.BaseFee,
}
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
)
defer state.Close()

tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err)
}
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer})
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if _, err = st.TransitionDb(); err != nil {
t.Fatalf("failed to execute transaction: %v", err)
}
// Retrieve the trace result and compare against the expected
res, err := tracer.GetResult()
if err != nil {
t.Fatalf("failed to retrieve trace result: %v", err)
}
want, err := json.Marshal(test.Result)
if err != nil {
t.Fatalf("failed to marshal test: %v", err)
}
if string(want) != string(res) {
t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want))
}
})
}
}

// testcase defines a single test to check the stateDiff tracer against.
type testcase struct {
Genesis *core.Genesis `json:"genesis"`
Context *callContext `json:"context"`
Input string `json:"input"`
TracerConfig json.RawMessage `json:"tracerConfig"`
Result interface{} `json:"result"`
}

type callContext struct {
Number math.HexOrDecimal64 `json:"number"`
Difficulty *math.HexOrDecimal256 `json:"difficulty"`
Time math.HexOrDecimal64 `json:"timestamp"`
GasLimit math.HexOrDecimal64 `json:"gasLimit"`
Miner common.Address `json:"miner"`
}

// camel converts a snake cased input string into a camel cased output.
func camel(str string) string {
pieces := strings.Split(str, "_")
for i := 1; i < len(pieces); i++ {
pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
}
return strings.Join(pieces, "")
}

0 comments on commit 7a5204d

Please sign in to comment.