github.com/klaytn/klaytn@v1.10.2/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 "reflect" 30 "testing" 31 "time" 32 33 "github.com/stretchr/testify/assert" 34 35 "github.com/klaytn/klaytn/common" 36 ) 37 38 func jsonMustCompact(data []byte) []byte { 39 compactedBuffer := new(bytes.Buffer) 40 err := json.Compact(compactedBuffer, data) 41 if err != nil { 42 panic(err) 43 } 44 return compactedBuffer.Bytes() 45 } 46 47 func genAddressPtr(addr string) *common.Address { 48 ret := common.HexToAddress(addr) 49 return &ret 50 } 51 52 func TestInternalTxTrace_MarshalJSON(t *testing.T) { 53 type fields struct { 54 Type string 55 From *common.Address 56 To *common.Address 57 Value string 58 Gas uint64 59 GasUsed uint64 60 Input string 61 Output string 62 Error error 63 Time time.Duration 64 Calls []*InternalTxTrace 65 Reverted *RevertedInfo 66 } 67 tests := []struct { 68 name string 69 fields fields 70 want []byte 71 }{ 72 { 73 name: "revert_test", 74 fields: fields{ 75 Type: CALL.String(), 76 From: genAddressPtr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"), 77 To: genAddressPtr("0xabbcd5b340c80b5f1c0545c04c987b87310296ae"), 78 Value: "0x0", 79 Gas: 2971112, 80 GasUsed: 195, 81 Input: "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000", 82 Error: errExecutionReverted, 83 Reverted: &RevertedInfo{ 84 Contract: genAddressPtr("0xabbcd5b340c80b5f1c0545c04c987b87310296ae"), 85 }, 86 }, 87 want: jsonMustCompact([]byte(`{ 88 "type": "CALL", 89 "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", 90 "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae", 91 "value": "0x0", 92 "gas": "0x2d55e8", 93 "gasUsed": "0xc3", 94 "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000", 95 "error": "execution reverted", 96 "reverted": { 97 "contract": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae" 98 } 99 }`)), 100 }, 101 { 102 name: "delegatecall_test", 103 fields: fields{ 104 Type: DELEGATECALL.String(), 105 From: genAddressPtr("0x2074f91470365144df78c333948814fe4158af5a"), 106 To: genAddressPtr("0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c"), 107 Gas: 179, 108 GasUsed: 122, 109 Input: "0xc605f76c", 110 Output: "0x", 111 }, 112 want: jsonMustCompact([]byte(`{ 113 "type": "DELEGATECALL", 114 "from": "0x2074f91470365144df78c333948814fe4158af5a", 115 "to": "0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c", 116 "gas": "0xb3", 117 "gasUsed": "0x7a", 118 "input": "0xc605f76c", 119 "output": "0x" 120 }`)), 121 }, 122 { 123 name: "create2_test", 124 fields: fields{ 125 Type: CREATE2.String(), 126 From: genAddressPtr("0xe213d8b68ca3d01e51a6dba669de59ac9a8359ee"), 127 To: genAddressPtr("0xd3204138864ad97dbfe703cf7281f6b3397c6003"), 128 Value: "0x0", 129 Gas: 11341, 130 GasUsed: 10784, 131 Input: "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 132 Output: "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 133 }, 134 want: jsonMustCompact([]byte(`{ 135 "type": "CREATE2", 136 "from": "0xe213d8b68ca3d01e51a6dba669de59ac9a8359ee", 137 "to": "0xd3204138864ad97dbfe703cf7281f6b3397c6003", 138 "value": "0x0", 139 "gas": "0x2c4d", 140 "gasUsed": "0x2a20", 141 "input": "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 142 "output": "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029" 143 }`)), 144 }, 145 { 146 name: "create_test", 147 fields: fields{ 148 Type: CREATE.String(), 149 From: genAddressPtr("0x13e4acefe6a6700604929946e70e6443e4e73447"), 150 To: genAddressPtr("0x7dc9c9730689ff0b0fd506c67db815f12d90a448"), 151 Value: "0x0", 152 Gas: 385286, 153 GasUsed: 385286, 154 Input: "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 155 Output: "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 156 }, 157 want: jsonMustCompact([]byte(`{ 158 "type": "CREATE", 159 "from": "0x13e4acefe6a6700604929946e70e6443e4e73447", 160 "to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448", 161 "value": "0x0", 162 "gas": "0x5e106", 163 "gasUsed": "0x5e106", 164 "input": "0x6080604052348015600f57600080fd5b50604051602080608183398101806040526020811015602d57600080fd5b810190808051906020019092919050505050603580604c6000396000f3fe6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029", 165 "output": "0x6080604052600080fdfea165627a7a72305820c577c5325e4c667e8439f998d616e74110a14fb5b185afe46d8443bbfd9c3d710029" 166 }`)), 167 }, 168 { 169 name: "call_test", 170 fields: fields{ 171 Type: CALL.String(), 172 From: genAddressPtr("0x3693da93b9d5e63cb4804b8813c8214a76724485"), 173 To: genAddressPtr("0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c"), 174 Value: "0x0", 175 Gas: 179, 176 GasUsed: 122, 177 Input: "0xc605f76c", 178 Output: "0x", 179 }, 180 want: jsonMustCompact([]byte(`{ 181 "type": "CALL", 182 "from": "0x3693da93b9d5e63cb4804b8813c8214a76724485", 183 "to": "0x13cf0d18bcb898efd4e85ae2bb65a443ab86023c", 184 "value": "0x0", 185 "gas": "0xb3", 186 "gasUsed": "0x7a", 187 "input": "0xc605f76c", 188 "output": "0x" 189 }`)), 190 }, 191 { 192 name: "simple_call_test", 193 fields: fields{ 194 Type: CALL.String(), 195 From: genAddressPtr("0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe"), 196 To: genAddressPtr("0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5"), 197 Value: "0x6f05b59d3b20000", 198 Input: "0x", 199 }, 200 want: jsonMustCompact([]byte(`{ 201 "type": "CALL", 202 "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", 203 "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", 204 "value": "0x6f05b59d3b20000", 205 "input": "0x" 206 }`)), 207 }, 208 { 209 name: "staticcall_test", 210 fields: fields{ 211 Type: OpCode(STATICCALL).String(), 212 From: genAddressPtr("0xbadc777c579b497ede07fa6ff93bdf4e31793f24"), 213 To: genAddressPtr("0x920fd5070602feaea2e251e9e7238b6c376bcae5"), 214 Gas: 179, 215 GasUsed: 122, 216 Input: "0xc605f76c", 217 Output: "0x", 218 }, 219 want: jsonMustCompact([]byte(`{ 220 "type": "STATICCALL", 221 "from": "0xbadc777c579b497ede07fa6ff93bdf4e31793f24", 222 "to": "0x920fd5070602feaea2e251e9e7238b6c376bcae5", 223 "gas": "0xb3", 224 "gasUsed": "0x7a", 225 "input": "0xc605f76c", 226 "output": "0x" 227 }`)), 228 }, 229 { 230 name: "selfdestruct_test", 231 fields: fields{ 232 Type: OpCode(SELFDESTRUCT).String(), 233 }, 234 want: []byte(`{"type":"SELFDESTRUCT"}`), 235 }, 236 } 237 for _, tt := range tests { 238 t.Run(tt.name, func(t *testing.T) { 239 i := InternalTxTrace{ 240 Type: tt.fields.Type, 241 From: tt.fields.From, 242 To: tt.fields.To, 243 Value: tt.fields.Value, 244 Gas: tt.fields.Gas, 245 GasUsed: tt.fields.GasUsed, 246 Input: tt.fields.Input, 247 Output: tt.fields.Output, 248 Error: tt.fields.Error, 249 Time: tt.fields.Time, 250 Calls: tt.fields.Calls, 251 Reverted: tt.fields.Reverted, 252 } 253 got, err := i.MarshalJSON() 254 assert.Nil(t, err) 255 if !reflect.DeepEqual(got, tt.want) { 256 t.Errorf("MarshalJSON() got = %v, want %v", string(got), string(tt.want)) 257 } 258 }) 259 } 260 } 261 262 func TestInternalTxTracer_result_invalidOutput(t *testing.T) { 263 tracer := NewInternalTxTracer() 264 tracer.ctx["error"] = errEvmExecutionReverted 265 // An 8 bytes value that might cause a string version error or out-of-range error. 266 tracer.ctx["output"] = "0x08c379a0000000000000000000000000000000000000000000000000ffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff" 267 268 _, err := tracer.GetResult() 269 if err != nil { 270 t.Fatal(err) 271 } 272 }