github.com/platonnetwork/platon-go@v0.7.6/eth/tracers/tracers_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package tracers 18 19 import ( 20 "testing" 21 22 "github.com/PlatONnetwork/PlatON-Go/common" 23 "github.com/PlatONnetwork/PlatON-Go/common/hexutil" 24 "github.com/PlatONnetwork/PlatON-Go/common/math" 25 "github.com/PlatONnetwork/PlatON-Go/core" 26 ) 27 28 // To generate a new callTracer test, copy paste the makeTest method below into 29 // a Geth console and call it with a transaction hash you which to export. 30 31 /* 32 // makeTest generates a callTracer test by running a prestate reassembled and a 33 // call trace run, assembling all the gathered information into a test case. 34 var makeTest = function(tx, rewind) { 35 // Generate the genesis block from the block, transaction and prestate data 36 var block = eth.getBlock(eth.getTransaction(tx).blockHash); 37 var genesis = eth.getBlock(block.parentHash); 38 39 delete genesis.gasUsed; 40 delete genesis.logsBloom; 41 delete genesis.parentHash; 42 delete genesis.receiptsRoot; 43 delete genesis.sha3Uncles; 44 delete genesis.size; 45 delete genesis.transactions; 46 delete genesis.transactionsRoot; 47 delete genesis.uncles; 48 49 genesis.gasLimit = genesis.gasLimit.toString(); 50 genesis.number = genesis.number.toString(); 51 genesis.timestamp = genesis.timestamp.toString(); 52 53 genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind}); 54 for (var key in genesis.alloc) { 55 genesis.alloc[key].nonce = genesis.alloc[key].nonce.toString(); 56 } 57 genesis.config = admin.nodeInfo.protocols.eth.config; 58 59 // Generate the call trace and produce the test input 60 var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind}); 61 delete result.time; 62 63 console.log(JSON.stringify({ 64 genesis: genesis, 65 context: { 66 number: block.number.toString(), 67 difficulty: block.difficulty, 68 timestamp: block.timestamp.toString(), 69 gasLimit: block.gasLimit.toString(), 70 miner: block.miner, 71 }, 72 input: eth.getRawTransaction(tx), 73 result: result, 74 }, null, 2)); 75 } 76 */ 77 78 // callTrace is the result of a callTracer run. 79 type callTrace struct { 80 Type string `json:"type"` 81 From common.Address `json:"from"` 82 To common.Address `json:"to"` 83 Input hexutil.Bytes `json:"input"` 84 Output hexutil.Bytes `json:"output"` 85 Gas *hexutil.Uint64 `json:"gas,omitempty"` 86 GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"` 87 Value *hexutil.Big `json:"value,omitempty"` 88 Error string `json:"error,omitempty"` 89 Calls []callTrace `json:"calls,omitempty"` 90 } 91 92 type callContext struct { 93 Number math.HexOrDecimal64 `json:"number"` 94 Difficulty *math.HexOrDecimal256 `json:"difficulty"` 95 Time math.HexOrDecimal64 `json:"timestamp"` 96 GasLimit math.HexOrDecimal64 `json:"gasLimit"` 97 Miner common.Address `json:"miner"` 98 } 99 100 // callTracerTest defines a single test to check the call tracer against. 101 type callTracerTest struct { 102 Genesis *core.Genesis `json:"genesis"` 103 Context *callContext `json:"context"` 104 Input string `json:"input"` 105 Result *callTrace `json:"result"` 106 } 107 108 // Iterates over all the input-output datasets in the tracer test harness and 109 // runs the JavaScript tracers against them. 110 func TestCallTracer(t *testing.T) { 111 // TODO test 112 /*files, err := ioutil.ReadDir("testdata") 113 if err != nil { 114 t.Fatalf("failed to retrieve tracer test suite: %v", err) 115 } 116 for _, file := range files { 117 if !strings.HasPrefix(file.Name(), "call_tracer_") { 118 continue 119 } 120 file := file // capture range variable 121 t.Run(camel(strings.TrimSuffix(strings.TrimPrefix(file.Name(), "call_tracer_"), ".json")), func(t *testing.T) { 122 t.Parallel() 123 124 // Call tracer test found, read if from disk 125 blob, err := ioutil.ReadFile(filepath.Join("testdata", file.Name())) 126 if err != nil { 127 t.Fatalf("failed to read testcase: %v", err) 128 } 129 test := new(callTracerTest) 130 if err := json.Unmarshal(blob, test); err != nil { 131 t.Fatalf("failed to parse testcase: %v", err) 132 } 133 // Configure a blockchain with the given prestate 134 tx := new(types.Transaction) 135 if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil { 136 t.Fatalf("failed to parse testcase input: %v", err) 137 } 138 signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number))) 139 origin, _ := signer.Sender(tx) 140 141 context := vm.Context{ 142 CanTransfer: core.CanTransfer, 143 Transfer: core.Transfer, 144 Origin: origin, 145 Coinbase: test.Context.Miner, 146 BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), 147 Time: new(big.Int).SetUint64(uint64(test.Context.Time)), 148 Difficulty: (*big.Int)(test.Context.Difficulty), 149 GasLimit: uint64(test.Context.GasLimit), 150 GasPrice: tx.GasPrice(), 151 } 152 statedb := tests.MakePreState(ethdb.NewMemDatabase(), test.Genesis.Alloc) 153 154 // Create the tracer, the EVM environment and run it 155 tracer, err := New("callTracer") 156 if err != nil { 157 t.Fatalf("failed to create call tracer: %v", err) 158 } 159 evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) 160 161 msg, err := tx.AsMessage(signer) 162 if err != nil { 163 t.Fatalf("failed to prepare transaction for tracing: %v", err) 164 } 165 st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) 166 if _, _, _, err = st.TransitionDb(); err != nil { 167 t.Fatalf("failed to execute transaction: %v", err) 168 } 169 // Retrieve the trace result and compare against the etalon 170 res, err := tracer.GetResult() 171 if err != nil { 172 t.Fatalf("failed to retrieve trace result: %v", err) 173 } 174 ret := new(callTrace) 175 if err := json.Unmarshal(res, ret); err != nil { 176 t.Fatalf("failed to unmarshal trace result: %v", err) 177 } 178 if !reflect.DeepEqual(ret, test.Result) { 179 t.Fatalf("trace mismatch: have %+v, want %+v", ret, test.Result) 180 } 181 }) 182 }*/ 183 }