diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index bcad391ee857a..2087107243f48 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -33,6 +33,27 @@ import ( "strings" ) +type result struct { + Error error + Address common.Address +} + +// MarshalJSON marshals as JSON with a hash. +func (r *result) MarshalJSON() ([]byte, error) { + type xx struct { + Error string `json:"error,omitempty"` + Address *common.Address `json:"address,omitempty"` + } + var out xx + if r.Address != (common.Address{}) { + out.Address = &r.Address + } + if r.Error != nil { + out.Error = r.Error.Error() + } + return json.Marshal(out) +} + func Transaction(ctx *cli.Context) error { // Configure the go-ethereum logger glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) @@ -89,20 +110,23 @@ func Transaction(ctx *cli.Context) error { return err } i := -1 + var results []result for it.Next() { i++ var tx types.Transaction err := rlp.DecodeBytes(it.Value(), &tx) if err != nil { - fmt.Printf("error tx %d, %v\n", i, err) + results = append(results, result{Error: err}) continue } sender, err := types.Sender(signer, &tx) if err != nil { - fmt.Printf("error deriving sender, tx %d, %v\n", i, err) + results = append(results, result{Error: err}) continue } - fmt.Printf("sender tx %d: %v\n", i, sender) + results = append(results, result{Address: sender}) } - return nil + out, err := json.MarshalIndent(results, "", " ") + fmt.Println(string(out)) + return err } diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 5af7ee19cc0b8..e59803e668502 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -70,7 +70,6 @@ type t8nOutput struct { } func (args *t8nOutput) get() (out []string) { - out = append(out, "t8n") if args.body { out = append(out, "--output.body", "stdout") } else { @@ -173,7 +172,9 @@ func TestT8n(t *testing.T) { }, } { - args := append(tc.output.get(), tc.input.get(tc.base)...) + args := []string{"t8n"} + args = append(args, tc.output.get()...) + args = append(args, tc.input.get(tc.base)...) tt.Run("evm-test", args...) tt.Logf("args: %v\n", strings.Join(args, " ")) // Compare the expected output, if provided @@ -198,6 +199,86 @@ func TestT8n(t *testing.T) { } } +type t9nInput struct { + inTxs string + stFork string +} + +func (args *t9nInput) get(base string) []string { + var out []string + if opt := args.inTxs; opt != "" { + out = append(out, "--input.txs") + out = append(out, fmt.Sprintf("%v/%v", base, opt)) + } + if opt := args.stFork; opt != "" { + out = append(out, "--state.fork", opt) + } + return out +} + +func TestT9n(t *testing.T) { + tt := new(testT8n) + tt.TestCmd = cmdtest.NewTestCmd(t, tt) + for i, tc := range []struct { + base string + input t9nInput + expExitCode int + expOut string + }{ + { // London txs on homestead + base: "./testdata/15", + input: t9nInput{ + inTxs: "signed_txs.rlp", + stFork: "Homestead", + }, + expOut: "exp.json", + }, + { // London txs on homestead + base: "./testdata/15", + input: t9nInput{ + inTxs: "signed_txs.rlp", + stFork: "London", + }, + expOut: "exp2.json", + }, + { // An RLP list (a blockheader really) + base: "./testdata/15", + input: t9nInput{ + inTxs: "blockheader.rlp", + stFork: "London", + }, + expOut: "exp3.json", + }, + } { + + args := []string{"t9n"} + args = append(args, tc.input.get(tc.base)...) + + tt.Run("evm-test", args...) + tt.Logf("args:\n go run . %v\n", strings.Join(args, " ")) + // Compare the expected output, if provided + if tc.expOut != "" { + want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut)) + if err != nil { + t.Fatalf("test %d: could not read expected output: %v", i, err) + } + have := tt.Output() + ok, err := cmpJson(have, want) + switch { + case err != nil: + t.Logf(string(have)) + t.Fatalf("test %d, json parsing failed: %v", i, err) + case !ok: + t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want)) + } + } + tt.WaitExit() + if have, want := tt.ExitStatus(), tc.expExitCode; have != want { + t.Fatalf("test %d: wrong exit code, have %d, want %d", i, have, want) + } + } +} + // cmpJson compares the JSON in two byte slices. func cmpJson(a, b []byte) (bool, error) { var j, j2 interface{} @@ -209,3 +290,25 @@ func cmpJson(a, b []byte) (bool, error) { } return reflect.DeepEqual(j2, j), nil } + +//func TestFoo(t *testing.T){ +// d, _ := rlp.EncodeToBytes(types.Header{ +// ParentHash: common.Hash{}, +// UncleHash: common.Hash{}, +// Coinbase: common.Address{}, +// Root: common.Hash{}, +// TxHash: common.Hash{}, +// ReceiptHash: common.Hash{}, +// Bloom: types.Bloom{}, +// Difficulty: big.NewInt(123), +// Number: big.NewInt(1), +// GasLimit: 1, +// GasUsed: 2, +// Time: 3, +// Extra: []byte{1,2,3}, +// MixDigest: common.Hash{}, +// Nonce: types.BlockNonce{}, +// BaseFee: nil, +// }) +// fmt.Printf("%x\n", d) +//} diff --git a/cmd/evm/testdata/15/blockheader.rlp b/cmd/evm/testdata/15/blockheader.rlp new file mode 100644 index 0000000000000..1124e8e2da929 --- /dev/null +++ b/cmd/evm/testdata/15/blockheader.rlp @@ -0,0 +1 @@ +"0xf901f0a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b0101020383010203a00000000000000000000000000000000000000000000000000000000000000000880000000000000000" \ No newline at end of file diff --git a/cmd/evm/testdata/15/exp.json b/cmd/evm/testdata/15/exp.json new file mode 100644 index 0000000000000..03d970c5655ca --- /dev/null +++ b/cmd/evm/testdata/15/exp.json @@ -0,0 +1,8 @@ +[ + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + } +] diff --git a/cmd/evm/testdata/15/exp2.json b/cmd/evm/testdata/15/exp2.json new file mode 100644 index 0000000000000..d29499a786fd5 --- /dev/null +++ b/cmd/evm/testdata/15/exp2.json @@ -0,0 +1,8 @@ +[ + { + "address": "0xd02d72e067e77158444ef2020ff2d325f929b363" + }, + { + "address": "0xd02d72e067e77158444ef2020ff2d325f929b363" + } +] diff --git a/cmd/evm/testdata/15/exp3.json b/cmd/evm/testdata/15/exp3.json new file mode 100644 index 0000000000000..6c46d267cf370 --- /dev/null +++ b/cmd/evm/testdata/15/exp3.json @@ -0,0 +1,47 @@ +[ + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + }, + { + "error": "rlp: expected List" + }, + { + "error": "rlp: expected List" + }, + { + "error": "rlp: expected List" + }, + { + "error": "rlp: expected List" + }, + { + "error": "rlp: expected List" + }, + { + "error": "rlp: expected input list for types.AccessListTx" + }, + { + "error": "transaction type not supported" + }, + { + "error": "transaction type not supported" + } +]