-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move ANT prestate trace test out of eth/tracers/internal (#661)
- Loading branch information
Showing
3 changed files
with
137 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, "") | ||
} |
File renamed without changes.