Skip to content

Commit 7a5204d

Browse files
author
Darioush Jalali
authored
move ANT prestate trace test out of eth/tracers/internal (#661)
1 parent 311dbd9 commit 7a5204d

File tree

3 files changed

+137
-14
lines changed

3 files changed

+137
-14
lines changed

eth/tracers/internal/tracetest/prestate_test.go

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ func TestPrestateWithDiffModeTracer(t *testing.T) {
7474
testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t)
7575
}
7676

77-
func TestPrestateWithDiffModeANTTracer(t *testing.T) {
78-
testPrestateDiffTracer("prestateTracer", "prestate_tracer_ant", t)
79-
}
80-
8177
func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
8278
files, err := os.ReadDir(filepath.Join("testdata", dirPath))
8379
if err != nil {
@@ -108,16 +104,14 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
108104
var (
109105
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
110106
context = vm.BlockContext{
111-
CanTransfer: core.CanTransfer,
112-
CanTransferMC: core.CanTransferMC,
113-
Transfer: core.Transfer,
114-
TransferMultiCoin: core.TransferMultiCoin,
115-
Coinbase: test.Context.Miner,
116-
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
117-
Time: uint64(test.Context.Time),
118-
Difficulty: (*big.Int)(test.Context.Difficulty),
119-
GasLimit: uint64(test.Context.GasLimit),
120-
BaseFee: test.Genesis.BaseFee,
107+
CanTransfer: core.CanTransfer,
108+
Transfer: core.Transfer,
109+
Coinbase: test.Context.Miner,
110+
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
111+
Time: uint64(test.Context.Time),
112+
Difficulty: (*big.Int)(test.Context.Difficulty),
113+
GasLimit: uint64(test.Context.GasLimit),
114+
BaseFee: test.Genesis.BaseFee,
121115
}
122116
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
123117
)

plugin/evm/prestate_tracer_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// (c) 2024, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package evm
5+
6+
import (
7+
"encoding/json"
8+
"math/big"
9+
"os"
10+
"path/filepath"
11+
"strings"
12+
"testing"
13+
"unicode"
14+
15+
"github.com/ava-labs/coreth/core"
16+
"github.com/ava-labs/coreth/core/rawdb"
17+
"github.com/ava-labs/coreth/core/types"
18+
"github.com/ava-labs/coreth/core/vm"
19+
"github.com/ava-labs/coreth/eth/tracers"
20+
"github.com/ava-labs/coreth/tests"
21+
"github.com/ethereum/go-ethereum/common"
22+
"github.com/ethereum/go-ethereum/common/math"
23+
)
24+
25+
func TestPrestateWithDiffModeANTTracer(t *testing.T) {
26+
testPrestateDiffTracer("prestateTracer", "prestate_tracer_ant", t)
27+
}
28+
29+
// testPrestateDiffTracer is adapted from the original testPrestateDiffTracer in
30+
// eth/tracers/internal/tracetest/prestate_test.go.
31+
func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
32+
files, err := os.ReadDir(filepath.Join("testdata", dirPath))
33+
if err != nil {
34+
t.Fatalf("failed to retrieve tracer test suite: %v", err)
35+
}
36+
for _, file := range files {
37+
if !strings.HasSuffix(file.Name(), ".json") {
38+
continue
39+
}
40+
file := file // capture range variable
41+
t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) {
42+
t.Parallel()
43+
44+
var (
45+
test = new(testcase)
46+
tx = new(types.Transaction)
47+
)
48+
// Call tracer test found, read if from disk
49+
if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil {
50+
t.Fatalf("failed to read testcase: %v", err)
51+
} else if err := json.Unmarshal(blob, test); err != nil {
52+
t.Fatalf("failed to parse testcase: %v", err)
53+
}
54+
if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
55+
t.Fatalf("failed to parse testcase input: %v", err)
56+
}
57+
// Configure a blockchain with the given prestate
58+
var (
59+
signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
60+
context = vm.BlockContext{
61+
CanTransfer: core.CanTransfer,
62+
CanTransferMC: core.CanTransferMC,
63+
Transfer: core.Transfer,
64+
TransferMultiCoin: core.TransferMultiCoin,
65+
Coinbase: test.Context.Miner,
66+
BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
67+
Time: uint64(test.Context.Time),
68+
Difficulty: (*big.Int)(test.Context.Difficulty),
69+
GasLimit: uint64(test.Context.GasLimit),
70+
BaseFee: test.Genesis.BaseFee,
71+
}
72+
state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
73+
)
74+
defer state.Close()
75+
76+
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
77+
if err != nil {
78+
t.Fatalf("failed to create call tracer: %v", err)
79+
}
80+
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
81+
if err != nil {
82+
t.Fatalf("failed to prepare transaction for tracing: %v", err)
83+
}
84+
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer})
85+
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
86+
if _, err = st.TransitionDb(); err != nil {
87+
t.Fatalf("failed to execute transaction: %v", err)
88+
}
89+
// Retrieve the trace result and compare against the expected
90+
res, err := tracer.GetResult()
91+
if err != nil {
92+
t.Fatalf("failed to retrieve trace result: %v", err)
93+
}
94+
want, err := json.Marshal(test.Result)
95+
if err != nil {
96+
t.Fatalf("failed to marshal test: %v", err)
97+
}
98+
if string(want) != string(res) {
99+
t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want))
100+
}
101+
})
102+
}
103+
}
104+
105+
// testcase defines a single test to check the stateDiff tracer against.
106+
type testcase struct {
107+
Genesis *core.Genesis `json:"genesis"`
108+
Context *callContext `json:"context"`
109+
Input string `json:"input"`
110+
TracerConfig json.RawMessage `json:"tracerConfig"`
111+
Result interface{} `json:"result"`
112+
}
113+
114+
type callContext struct {
115+
Number math.HexOrDecimal64 `json:"number"`
116+
Difficulty *math.HexOrDecimal256 `json:"difficulty"`
117+
Time math.HexOrDecimal64 `json:"timestamp"`
118+
GasLimit math.HexOrDecimal64 `json:"gasLimit"`
119+
Miner common.Address `json:"miner"`
120+
}
121+
122+
// camel converts a snake cased input string into a camel cased output.
123+
func camel(str string) string {
124+
pieces := strings.Split(str, "_")
125+
for i := 1; i < len(pieces); i++ {
126+
pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
127+
}
128+
return strings.Join(pieces, "")
129+
}

0 commit comments

Comments
 (0)