Skip to content

Commit 4d88974

Browse files
authored
cmd/evm: add tests for evm t8n (#23507)
1 parent 067084f commit 4d88974

File tree

17 files changed

+424
-31
lines changed

17 files changed

+424
-31
lines changed

cmd/evm/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ Example:
208208
]
209209
}
210210
```
211-
When applying this, using a reward of `0x08`
211+
When applying this, using a reward of `0x80`
212212
Output:
213213
```json
214214
{

cmd/evm/internal/t8ntool/transition.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ func (n *NumberedError) Error() string {
6565
return fmt.Sprintf("ERROR(%d): %v", n.errorCode, n.err.Error())
6666
}
6767

68-
func (n *NumberedError) Code() int {
68+
func (n *NumberedError) ExitCode() int {
6969
return n.errorCode
7070
}
7171

72+
// compile-time conformance test
73+
var (
74+
_ cli.ExitCoder = (*NumberedError)(nil)
75+
)
76+
7277
type input struct {
7378
Alloc core.GenesisAlloc `json:"alloc,omitempty"`
7479
Env *stEnv `json:"env,omitempty"`
@@ -409,15 +414,15 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
409414
return err
410415
}
411416
if len(stdOutObject) > 0 {
412-
b, err := json.MarshalIndent(stdOutObject, "", " ")
417+
b, err := json.MarshalIndent(stdOutObject, "", " ")
413418
if err != nil {
414419
return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
415420
}
416421
os.Stdout.Write(b)
417422
os.Stdout.Write([]byte("\n"))
418423
}
419424
if len(stdErrObject) > 0 {
420-
b, err := json.MarshalIndent(stdErrObject, "", " ")
425+
b, err := json.MarshalIndent(stdErrObject, "", " ")
421426
if err != nil {
422427
return NewError(ErrorJson, fmt.Errorf("failed marshalling output: %v", err))
423428
}

cmd/evm/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func main() {
195195
if err := app.Run(os.Args); err != nil {
196196
code := 1
197197
if ec, ok := err.(*t8ntool.NumberedError); ok {
198-
code = ec.Code()
198+
code = ec.ExitCode()
199199
}
200200
fmt.Fprintln(os.Stderr, err)
201201
os.Exit(code)

cmd/evm/t8n_test.go

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"reflect"
8+
"strings"
9+
"testing"
10+
11+
"github.com/docker/docker/pkg/reexec"
12+
"github.com/ethereum/go-ethereum/internal/cmdtest"
13+
)
14+
15+
func TestMain(m *testing.M) {
16+
// Run the app if we've been exec'd as "ethkey-test" in runEthkey.
17+
reexec.Register("evm-test", func() {
18+
if err := app.Run(os.Args); err != nil {
19+
fmt.Fprintln(os.Stderr, err)
20+
os.Exit(1)
21+
}
22+
os.Exit(0)
23+
})
24+
// check if we have been reexec'd
25+
if reexec.Init() {
26+
return
27+
}
28+
os.Exit(m.Run())
29+
}
30+
31+
type testT8n struct {
32+
*cmdtest.TestCmd
33+
}
34+
35+
type t8nInput struct {
36+
inAlloc string
37+
inTxs string
38+
inEnv string
39+
stFork string
40+
stReward string
41+
}
42+
43+
func (args *t8nInput) get(base string) []string {
44+
var out []string
45+
if opt := args.inAlloc; opt != "" {
46+
out = append(out, "--input.alloc")
47+
out = append(out, fmt.Sprintf("%v/%v", base, opt))
48+
}
49+
if opt := args.inTxs; opt != "" {
50+
out = append(out, "--input.txs")
51+
out = append(out, fmt.Sprintf("%v/%v", base, opt))
52+
}
53+
if opt := args.inEnv; opt != "" {
54+
out = append(out, "--input.env")
55+
out = append(out, fmt.Sprintf("%v/%v", base, opt))
56+
}
57+
if opt := args.stFork; opt != "" {
58+
out = append(out, "--state.fork", opt)
59+
}
60+
if opt := args.stReward; opt != "" {
61+
out = append(out, "--state.reward", opt)
62+
}
63+
return out
64+
}
65+
66+
type t8nOutput struct {
67+
alloc bool
68+
result bool
69+
body bool
70+
}
71+
72+
func (args *t8nOutput) get() (out []string) {
73+
out = append(out, "t8n")
74+
if args.body {
75+
out = append(out, "--output.body", "stdout")
76+
} else {
77+
out = append(out, "--output.body", "") // empty means ignore
78+
}
79+
if args.result {
80+
out = append(out, "--output.result", "stdout")
81+
} else {
82+
out = append(out, "--output.result", "")
83+
}
84+
if args.alloc {
85+
out = append(out, "--output.alloc", "stdout")
86+
} else {
87+
out = append(out, "--output.alloc", "")
88+
}
89+
return out
90+
}
91+
92+
func TestT8n(t *testing.T) {
93+
tt := new(testT8n)
94+
tt.TestCmd = cmdtest.NewTestCmd(t, tt)
95+
for i, tc := range []struct {
96+
base string
97+
input t8nInput
98+
output t8nOutput
99+
expExitCode int
100+
expOut string
101+
}{
102+
{ // Test exit (3) on bad config
103+
base: "./testdata/1",
104+
input: t8nInput{
105+
"alloc.json", "txs.json", "env.json", "Frontier+1346", "",
106+
},
107+
output: t8nOutput{alloc: true, result: true},
108+
expExitCode: 3,
109+
},
110+
{
111+
base: "./testdata/1",
112+
input: t8nInput{
113+
"alloc.json", "txs.json", "env.json", "Byzantium", "",
114+
},
115+
output: t8nOutput{alloc: true, result: true},
116+
expOut: "exp.json",
117+
},
118+
{ // blockhash test
119+
base: "./testdata/3",
120+
input: t8nInput{
121+
"alloc.json", "txs.json", "env.json", "Berlin", "",
122+
},
123+
output: t8nOutput{alloc: true, result: true},
124+
expOut: "exp.json",
125+
},
126+
{ // missing blockhash test
127+
base: "./testdata/4",
128+
input: t8nInput{
129+
"alloc.json", "txs.json", "env.json", "Berlin", "",
130+
},
131+
output: t8nOutput{alloc: true, result: true},
132+
expExitCode: 4,
133+
},
134+
{ // Ommer test
135+
base: "./testdata/5",
136+
input: t8nInput{
137+
"alloc.json", "txs.json", "env.json", "Byzantium", "0x80",
138+
},
139+
output: t8nOutput{alloc: true, result: true},
140+
expOut: "exp.json",
141+
},
142+
{ // Sign json transactions
143+
base: "./testdata/13",
144+
input: t8nInput{
145+
"alloc.json", "txs.json", "env.json", "London", "",
146+
},
147+
output: t8nOutput{body: true},
148+
expOut: "exp.json",
149+
},
150+
{ // Already signed transactions
151+
base: "./testdata/13",
152+
input: t8nInput{
153+
"alloc.json", "signed_txs.rlp", "env.json", "London", "",
154+
},
155+
output: t8nOutput{result: true},
156+
expOut: "exp2.json",
157+
},
158+
{ // Difficulty calculation - no uncles
159+
base: "./testdata/14",
160+
input: t8nInput{
161+
"alloc.json", "txs.json", "env.json", "London", "",
162+
},
163+
output: t8nOutput{result: true},
164+
expOut: "exp.json",
165+
},
166+
{ // Difficulty calculation - with uncles
167+
base: "./testdata/14",
168+
input: t8nInput{
169+
"alloc.json", "txs.json", "env.uncles.json", "London", "",
170+
},
171+
output: t8nOutput{result: true},
172+
expOut: "exp2.json",
173+
},
174+
} {
175+
176+
args := append(tc.output.get(), tc.input.get(tc.base)...)
177+
tt.Run("evm-test", args...)
178+
tt.Logf("args: %v\n", strings.Join(args, " "))
179+
// Compare the expected output, if provided
180+
if tc.expOut != "" {
181+
want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut))
182+
if err != nil {
183+
t.Fatalf("test %d: could not read expected output: %v", i, err)
184+
}
185+
have := tt.Output()
186+
ok, err := cmpJson(have, want)
187+
switch {
188+
case err != nil:
189+
t.Fatalf("test %d, json parsing failed: %v", i, err)
190+
case !ok:
191+
t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want))
192+
}
193+
}
194+
tt.WaitExit()
195+
if have, want := tt.ExitStatus(), tc.expExitCode; have != want {
196+
t.Fatalf("test %d: wrong exit code, have %d, want %d", i, have, want)
197+
}
198+
}
199+
}
200+
201+
// cmpJson compares the JSON in two byte slices.
202+
func cmpJson(a, b []byte) (bool, error) {
203+
var j, j2 interface{}
204+
if err := json.Unmarshal(a, &j); err != nil {
205+
return false, err
206+
}
207+
if err := json.Unmarshal(b, &j2); err != nil {
208+
return false, err
209+
}
210+
return reflect.DeepEqual(j2, j), nil
211+
}

cmd/evm/testdata/1/exp.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"alloc": {
3+
"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
4+
"balance": "0xfeed1a9d",
5+
"nonce": "0x1"
6+
},
7+
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
8+
"balance": "0x5ffd4878be161d74",
9+
"nonce": "0xac"
10+
},
11+
"0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
12+
"balance": "0xa410"
13+
}
14+
},
15+
"result": {
16+
"stateRoot": "0x84208a19bc2b46ada7445180c1db162be5b39b9abc8c0a54b05d32943eae4e13",
17+
"txRoot": "0xc4761fd7b87ff2364c7c60b6c5c8d02e522e815328aaea3f20e3b7b7ef52c42d",
18+
"receiptRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
19+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
20+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
21+
"receipts": [
22+
{
23+
"root": "0x",
24+
"status": "0x1",
25+
"cumulativeGasUsed": "0x5208",
26+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
27+
"logs": null,
28+
"transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673",
29+
"contractAddress": "0x0000000000000000000000000000000000000000",
30+
"gasUsed": "0x5208",
31+
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
32+
"transactionIndex": "0x0"
33+
}
34+
],
35+
"rejected": [
36+
{
37+
"index": 1,
38+
"error": "nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
39+
}
40+
],
41+
"currentDifficulty": "0x20000"
42+
}
43+
}

cmd/evm/testdata/13/exp.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"body": "0xf8d2b86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"
3+
}

cmd/evm/testdata/13/exp2.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"result": {
3+
"stateRoot": "0xe4b924a6adb5959fccf769d5b7bb2f6359e26d1e76a2443c5a91a36d826aef61",
4+
"txRoot": "0x013509c8563d41c0ae4bf38f2d6d19fc6512a1d0d6be045079c8c9f68bf45f9d",
5+
"receiptRoot": "0xa532a08aa9f62431d6fe5d924951b8efb86ed3c54d06fee77788c3767dd13420",
6+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
7+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
8+
"receipts": [
9+
{
10+
"type": "0x2",
11+
"root": "0x",
12+
"status": "0x0",
13+
"cumulativeGasUsed": "0x84d0",
14+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
15+
"logs": null,
16+
"transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
17+
"contractAddress": "0x0000000000000000000000000000000000000000",
18+
"gasUsed": "0x84d0",
19+
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
20+
"transactionIndex": "0x0"
21+
},
22+
{
23+
"type": "0x2",
24+
"root": "0x",
25+
"status": "0x0",
26+
"cumulativeGasUsed": "0x109a0",
27+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
28+
"logs": null,
29+
"transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
30+
"contractAddress": "0x0000000000000000000000000000000000000000",
31+
"gasUsed": "0x84d0",
32+
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
33+
"transactionIndex": "0x1"
34+
}
35+
],
36+
"currentDifficulty": "0x20000"
37+
}
38+
}

cmd/evm/testdata/13/signed_txs.rlp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"0xf8d2b86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"

cmd/evm/testdata/14/env.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"currentGasLimit": "0x750a163df65e8a",
44
"currentBaseFee": "0x500",
55
"currentNumber": "12800000",
6-
"currentTimestamp": "10015",
6+
"currentTimestamp": "100015",
77
"parentTimestamp" : "99999",
88
"parentDifficulty" : "0x2000000000000"
99
}

cmd/evm/testdata/14/env.uncles.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"currentGasLimit": "0x750a163df65e8a",
44
"currentBaseFee": "0x500",
55
"currentNumber": "12800000",
6-
"currentTimestamp": "10035",
6+
"currentTimestamp": "100035",
77
"parentTimestamp" : "99999",
88
"parentDifficulty" : "0x2000000000000",
99
"parentUncleHash" : "0x000000000000000000000000000000000000000000000000000000000000beef"

0 commit comments

Comments
 (0)