github.com/klaytn/klaytn@v1.10.2/datasync/chaindatafetcher/kas/repository_traces_test.go (about) 1 // Copyright 2020 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package kas 18 19 import ( 20 "testing" 21 22 "github.com/klaytn/klaytn/common" 23 24 "github.com/klaytn/klaytn/blockchain/types" 25 26 "github.com/klaytn/klaytn/blockchain/vm" 27 "github.com/stretchr/testify/assert" 28 ) 29 30 // A specific types of transaction returns empty trace result which is defined as a variable `emptyTraceResult`. 31 // As a result of the tracing, `reflect.DeepEqual` returns an error while comparing with the not-initialized slice. 32 func TestRepository_isEmptyTraceResult(t *testing.T) { 33 // right empty result. 34 data := &vm.InternalTxTrace{ 35 Value: "0x0", 36 Calls: []*vm.InternalTxTrace{}, 37 } 38 assert.True(t, isEmptyTraceResult(data)) 39 40 // wrong empty result. 41 data = &vm.InternalTxTrace{ 42 Value: "0x0", 43 } 44 assert.False(t, isEmptyTraceResult(data)) 45 } 46 47 func makeOffset(offset int64) *int64 { 48 return &offset 49 } 50 51 func makeEntryTx() *Tx { 52 txhash := genRandomHash() 53 return &Tx{ 54 TransactionId: 100000000000, 55 TransactionHash: txhash.Bytes(), 56 Status: int(types.ReceiptStatusSuccessful), 57 Timestamp: 1, 58 TypeInt: int(types.TxTypeLegacyTransaction), 59 } 60 } 61 62 func makeInternalTrace(callType, value string, from *common.Address, to *common.Address) *vm.InternalTxTrace { 63 return &vm.InternalTxTrace{ 64 Type: callType, 65 From: from, 66 To: to, 67 Value: value, 68 } 69 } 70 71 func makeExpectedInternalTx(offset int64, entryTx *Tx, trace *vm.InternalTxTrace) *Tx { 72 return &Tx{ 73 TransactionId: entryTx.TransactionId + offset, 74 FromAddr: trace.From.Bytes(), 75 ToAddr: trace.To.Bytes(), 76 Value: trace.Value, 77 TransactionHash: entryTx.TransactionHash, 78 Status: entryTx.Status, 79 Timestamp: entryTx.Timestamp, 80 TypeInt: entryTx.TypeInt, 81 Internal: true, 82 } 83 } 84 85 func TestRepository_transformToInternalTx(t *testing.T) { 86 type args struct { 87 trace *vm.InternalTxTrace 88 offset *int64 89 entryTx *Tx 90 isFirstCall bool 91 } 92 93 // valid test case 94 entryTx := makeEntryTx() 95 trace := makeInternalTrace("TEST", "0x1", genRandomAddress(), genRandomAddress()) 96 args1 := args{trace, makeOffset(1), entryTx, false} 97 expected1 := []*Tx{makeExpectedInternalTx(2, entryTx, trace)} 98 99 // valid test case 2 100 entryTx2 := makeEntryTx() 101 trace2 := makeInternalTrace("TEST", "0x1", genRandomAddress(), genRandomAddress()) 102 innerTrace := makeInternalTrace("TEST", "0x2", genRandomAddress(), genRandomAddress()) 103 trace2.Calls = []*vm.InternalTxTrace{innerTrace} 104 args2 := args{trace2, makeOffset(0), entryTx2, false} 105 106 expected2 := []*Tx{ 107 makeExpectedInternalTx(1, entryTx2, trace2), 108 makeExpectedInternalTx(2, entryTx2, innerTrace), 109 } 110 111 tests := []struct { 112 name string 113 args args 114 expected []*Tx 115 err error 116 }{ 117 { 118 name: "success_valid_internal_tx", 119 args: args1, 120 expected: expected1, 121 err: nil, 122 }, 123 { 124 name: "success_valid_internal_tx_with_inner_calls", 125 args: args2, 126 expected: expected2, 127 err: nil, 128 }, 129 { 130 name: "fail_noOpcodeError", 131 args: args{ 132 trace: makeInternalTrace("", "0x1", genRandomAddress(), genRandomAddress()), 133 offset: makeOffset(0), 134 entryTx: makeEntryTx(), 135 isFirstCall: false, 136 }, 137 expected: nil, 138 err: noOpcodeError, 139 }, 140 { 141 name: "fail_noFromFieldError", 142 args: args{ 143 trace: makeInternalTrace("TEST", "0x1", nil, genRandomAddress()), 144 offset: makeOffset(0), 145 entryTx: makeEntryTx(), 146 isFirstCall: false, 147 }, 148 expected: nil, 149 err: noFromFieldError, 150 }, 151 { 152 name: "fail_noToFieldError", 153 args: args{ 154 trace: makeInternalTrace("TEST", "0x1", genRandomAddress(), nil), 155 offset: makeOffset(0), 156 entryTx: makeEntryTx(), 157 isFirstCall: false, 158 }, 159 expected: nil, 160 err: noToFieldError, 161 }, 162 { 163 name: "success_ignore_selfdestruct", 164 args: args{ 165 trace: makeInternalTrace(selfDestructType, "0x1", genRandomAddress(), genRandomAddress()), 166 offset: makeOffset(0), 167 entryTx: makeEntryTx(), 168 isFirstCall: false, 169 }, 170 expected: nil, 171 err: nil, 172 }, 173 { 174 name: "success_ignore_firstCall", 175 args: args{ 176 trace: makeInternalTrace("TEST", "0x1", genRandomAddress(), genRandomAddress()), 177 offset: makeOffset(0), 178 entryTx: makeEntryTx(), 179 isFirstCall: true, 180 }, 181 expected: nil, 182 err: nil, 183 }, 184 { 185 name: "success_empty_value", 186 args: args{ 187 trace: makeInternalTrace("TEST", "", genRandomAddress(), genRandomAddress()), 188 offset: makeOffset(0), 189 entryTx: makeEntryTx(), 190 isFirstCall: false, 191 }, 192 expected: nil, 193 err: nil, 194 }, 195 } 196 197 for _, tt := range tests { 198 t.Run(tt.name, func(t *testing.T) { 199 got, err := transformToInternalTx(tt.args.trace, tt.args.offset, tt.args.entryTx, tt.args.isFirstCall) 200 assert.Equal(t, tt.expected, got) 201 assert.Equal(t, tt.err, err) 202 }) 203 } 204 }