github.com/klaytn/klaytn@v1.12.1/blockchain/vm/internaltx_trace_json_test.go (about)

     1  // Modifications Copyright 2020 The klaytn Authors
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // InternalTxTracer is a full blown transaction tracer that extracts and reports all
    19  // the internal calls made by a transaction, along with any useful information.
    20  //
    21  // This file is derived from eth/tracers/internal/tracers/call_tracer.js (2018/06/04).
    22  // Modified and improved for the klaytn development.
    23  
    24  package vm
    25  
    26  import (
    27  	"bytes"
    28  	"encoding/json"
    29  	"errors"
    30  	"reflect"
    31  	"testing"
    32  	"time"
    33  
    34  	"github.com/stretchr/testify/assert"
    35  
    36  	"github.com/klaytn/klaytn/common"
    37  )
    38  
    39  func jsonMustCompact(data []byte) []byte {
    40  	compactedBuffer := new(bytes.Buffer)
    41  	err := json.Compact(compactedBuffer, data)
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  	return compactedBuffer.Bytes()
    46  }
    47  
    48  func genAddressPtr(addr string) *common.Address {
    49  	ret := common.HexToAddress(addr)
    50  	return &ret
    51  }
    52  
    53  func TestInternalTxTrace_MarshalJSON(t *testing.T) {
    54  	type fields struct {
    55  		Type     string
    56  		From     *common.Address
    57  		To       *common.Address
    58  		Value    string
    59  		Gas      uint64
    60  		GasUsed  uint64
    61  		Input    string
    62  		Output   string
    63  		Error    error
    64  		Time     time.Duration
    65  		Calls    []*InternalTxTrace
    66  		Reverted *RevertedInfo
    67  	}
    68  	tests := []struct {
    69  		name   string
    70  		fields fields
    71  		want   []byte
    72  	}{
    73  		{
    74  			name: "revert_test",
    75  			fields: fields{
    76  				Type:    CALL.String(),
    77  				From:    genAddressPtr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"),
    78  				To:      genAddressPtr("0xabbcd5b340c80b5f1c0545c04c987b87310296ae"),
    79  				Value:   "0x0",
    80  				Gas:     2971112,
    81  				GasUsed: 195,
    82  				Input:   "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000",
    83  				Error:   errExecutionReverted,
    84  				Reverted: &RevertedInfo{
    85  					Contract: genAddressPtr("0xabbcd5b340c80b5f1c0545c04c987b87310296ae"),
    86  				},
    87  			},
    88  			want: jsonMustCompact([]byte(`{
    89  	"type": "CALL",
    90  	"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
    91  	"to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae",
    92  	"value": "0x0",
    93      "gas": "0x2d55e8",
    94      "gasUsed": "0xc3",
    95      "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000",
    96      "error": "execution reverted",
    97      "reverted": {
    98        "contract": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae"
    99      }
   100    }`)),
   101  		},
   102  		{
   103  			name: "delegatecall_test",
   104  			fields: fields{
   105  				Type:    DELEGATECALL.String(),
   106  				From:    genAddressPtr("0x2074f91470365144df78c333948814fe4158af5a"),
   107  				To:      genAddressPtr("0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c"),
   108  				Gas:     179,
   109  				GasUsed: 122,
   110  				Input:   "0xc605f76c",
   111  				Output:  "0x",
   112  			},
   113  			want: jsonMustCompact([]byte(`{
   114  		"type": "DELEGATECALL",
   115          "from": "0x2074f91470365144df78c333948814fe4158af5a",
   116  		"to": "0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c",
   117          "gas": "0xb3",
   118          "gasUsed": "0x7a",
   119          "input": "0xc605f76c",
   120          "output": "0x"
   121  }`)),
   122  		},
   123  		{
   124  			name: "create2_test",
   125  			fields: fields{
   126  				Type:    CREATE2.String(),
   127  				From:    genAddressPtr("0xe213d8b68ca3d01e51a6dba669de59ac9a8359ee"),
   128  				To:      genAddressPtr("0xd3204138864ad97dbfe703cf7281f6b3397c6003"),
   129  				Value:   "0x0",
   130  				Gas:     11341,
   131  				GasUsed: 10784,
   132  				Input:   "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   133  				Output:  "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   134  			},
   135  			want: jsonMustCompact([]byte(`{
   136  		"type": "CREATE2",
   137          "from": "0xe213d8b68ca3d01e51a6dba669de59ac9a8359ee",
   138  		"to": "0xd3204138864ad97dbfe703cf7281f6b3397c6003",
   139  		"value": "0x0",
   140          "gas": "0x2c4d",
   141          "gasUsed": "0x2a20",
   142          "input": "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   143          "output": "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029"
   144  }`)),
   145  		},
   146  		{
   147  			name: "create_test",
   148  			fields: fields{
   149  				Type:    CREATE.String(),
   150  				From:    genAddressPtr("0x13e4acefe6a6700604929946e70e6443e4e73447"),
   151  				To:      genAddressPtr("0x7dc9c9730689ff0b0fd506c67db815f12d90a448"),
   152  				Value:   "0x0",
   153  				Gas:     385286,
   154  				GasUsed: 385286,
   155  				Input:   "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   156  				Output:  "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   157  			},
   158  			want: jsonMustCompact([]byte(`{
   159      "type": "CREATE",
   160      "from": "0x13e4acefe6a6700604929946e70e6443e4e73447",
   161  	"to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448",
   162  	"value": "0x0",
   163      "gas": "0x5e106",
   164      "gasUsed": "0x5e106",
   165      "input": "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029",
   166      "output": "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029"
   167  }`)),
   168  		},
   169  		{
   170  			name: "call_test",
   171  			fields: fields{
   172  				Type:    CALL.String(),
   173  				From:    genAddressPtr("0x3693da93b9d5e63cb4804b8813c8214a76724485"),
   174  				To:      genAddressPtr("0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c"),
   175  				Value:   "0x0",
   176  				Gas:     179,
   177  				GasUsed: 122,
   178  				Input:   "0xc605f76c",
   179  				Output:  "0x",
   180  			},
   181  			want: jsonMustCompact([]byte(`{
   182  	"type": "CALL",
   183  	"from": "0x3693da93b9d5e63cb4804b8813c8214a76724485",
   184  	"to": "0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c",
   185  	"value": "0x0",
   186  	"gas": "0xb3",
   187  	"gasUsed": "0x7a",
   188  	"input": "0xc605f76c",
   189  	"output": "0x"
   190  }`)),
   191  		},
   192  		{
   193  			name: "simple_call_test",
   194  			fields: fields{
   195  				Type:  CALL.String(),
   196  				From:  genAddressPtr("0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe"),
   197  				To:    genAddressPtr("0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5"),
   198  				Value: "0x6f05b59d3b20000",
   199  				Input: "0x",
   200  			},
   201  			want: jsonMustCompact([]byte(`{
   202  		"type": "CALL",
   203          "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
   204  		"to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
   205  		"value": "0x6f05b59d3b20000",
   206          "input": "0x"
   207  }`)),
   208  		},
   209  		{
   210  			name: "staticcall_test",
   211  			fields: fields{
   212  				Type:    OpCode(STATICCALL).String(),
   213  				From:    genAddressPtr("0xbadc777c579b497ede07fa6ff93bdf4e31793f24"),
   214  				To:      genAddressPtr("0x920fd5070602feaea2e251e9e7238b6c376bcae5"),
   215  				Gas:     179,
   216  				GasUsed: 122,
   217  				Input:   "0xc605f76c",
   218  				Output:  "0x",
   219  			},
   220  			want: jsonMustCompact([]byte(`{
   221  		"type": "STATICCALL",
   222          "from": "0xbadc777c579b497ede07fa6ff93bdf4e31793f24",
   223  		"to": "0x920fd5070602feaea2e251e9e7238b6c376bcae5",
   224          "gas": "0xb3",
   225          "gasUsed": "0x7a",
   226          "input": "0xc605f76c",
   227          "output": "0x"
   228  }`)),
   229  		},
   230  		{
   231  			name: "selfdestruct_test",
   232  			fields: fields{
   233  				Type: OpCode(SELFDESTRUCT).String(),
   234  			},
   235  			want: []byte(`{"type":"SELFDESTRUCT"}`),
   236  		},
   237  	}
   238  	for _, tt := range tests {
   239  		t.Run(tt.name, func(t *testing.T) {
   240  			i := InternalTxTrace{
   241  				Type:     tt.fields.Type,
   242  				From:     tt.fields.From,
   243  				To:       tt.fields.To,
   244  				Value:    tt.fields.Value,
   245  				Gas:      tt.fields.Gas,
   246  				GasUsed:  tt.fields.GasUsed,
   247  				Input:    tt.fields.Input,
   248  				Output:   tt.fields.Output,
   249  				Error:    tt.fields.Error,
   250  				Time:     tt.fields.Time,
   251  				Calls:    tt.fields.Calls,
   252  				Reverted: tt.fields.Reverted,
   253  			}
   254  			got, err := i.MarshalJSON()
   255  			assert.Nil(t, err)
   256  			if !reflect.DeepEqual(got, tt.want) {
   257  				t.Errorf("MarshalJSON() got = %v, want %v", string(got), string(tt.want))
   258  			}
   259  		})
   260  	}
   261  }
   262  
   263  func TestInternalTxTracer_result_invalidOutput(t *testing.T) {
   264  	tracer := NewInternalTxTracer()
   265  	tracer.ctx["error"] = errors.New("evm: execution reverted")
   266  	// An 8 bytes value that might cause a string version error or out-of-range error.
   267  	tracer.ctx["output"] = "0x08c379a0000000000000000000000000000000000000000000000000ffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff"
   268  
   269  	_, err := tracer.GetResult()
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  }