github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/eth/tracers/tracer_test.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package tracers 13 14 import ( 15 "bytes" 16 "encoding/json" 17 "errors" 18 "math/big" 19 "testing" 20 "time" 21 22 "github.com/Sberex/go-sberex/common" 23 "github.com/Sberex/go-sberex/core/vm" 24 "github.com/Sberex/go-sberex/params" 25 ) 26 27 type account struct{} 28 29 func (account) SubBalance(amount *big.Int) {} 30 func (account) AddBalance(amount *big.Int) {} 31 func (account) SetAddress(common.Address) {} 32 func (account) Value() *big.Int { return nil } 33 func (account) SetBalance(*big.Int) {} 34 func (account) SetNonce(uint64) {} 35 func (account) Balance() *big.Int { return nil } 36 func (account) Address() common.Address { return common.Address{} } 37 func (account) ReturnGas(*big.Int) {} 38 func (account) SetCode(common.Hash, []byte) {} 39 func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} 40 41 func runTrace(tracer *Tracer) (json.RawMessage, error) { 42 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 43 44 contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) 45 contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} 46 47 _, err := env.Interpreter().Run(contract, []byte{}) 48 if err != nil { 49 return nil, err 50 } 51 return tracer.GetResult() 52 } 53 54 func TestTracing(t *testing.T) { 55 tracer, err := New("{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}") 56 if err != nil { 57 t.Fatal(err) 58 } 59 60 ret, err := runTrace(tracer) 61 if err != nil { 62 t.Fatal(err) 63 } 64 if !bytes.Equal(ret, []byte("3")) { 65 t.Errorf("Expected return value to be 3, got %s", string(ret)) 66 } 67 } 68 69 func TestStack(t *testing.T) { 70 tracer, err := New("{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}") 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 ret, err := runTrace(tracer) 76 if err != nil { 77 t.Fatal(err) 78 } 79 if !bytes.Equal(ret, []byte("[0,1,2]")) { 80 t.Errorf("Expected return value to be [0,1,2], got %s", string(ret)) 81 } 82 } 83 84 func TestOpcodes(t *testing.T) { 85 tracer, err := New("{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}") 86 if err != nil { 87 t.Fatal(err) 88 } 89 90 ret, err := runTrace(tracer) 91 if err != nil { 92 t.Fatal(err) 93 } 94 if !bytes.Equal(ret, []byte("[\"PUSH1\",\"PUSH1\",\"STOP\"]")) { 95 t.Errorf("Expected return value to be [\"PUSH1\",\"PUSH1\",\"STOP\"], got %s", string(ret)) 96 } 97 } 98 99 func TestHalt(t *testing.T) { 100 t.Skip("duktape doesn't support abortion") 101 102 timeout := errors.New("stahp") 103 tracer, err := New("{step: function() { while(1); }, result: function() { return null; }}") 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 go func() { 109 time.Sleep(1 * time.Second) 110 tracer.Stop(timeout) 111 }() 112 113 if _, err = runTrace(tracer); err.Error() != "stahp in server-side tracer function 'step'" { 114 t.Errorf("Expected timeout error, got %v", err) 115 } 116 } 117 118 func TestHaltBetweenSteps(t *testing.T) { 119 tracer, err := New("{step: function() {}, fault: function() {}, result: function() { return null; }}") 120 if err != nil { 121 t.Fatal(err) 122 } 123 124 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 125 contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) 126 127 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 128 timeout := errors.New("stahp") 129 tracer.Stop(timeout) 130 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 131 132 if _, err := tracer.GetResult(); err.Error() != timeout.Error() { 133 t.Errorf("Expected timeout error, got %v", err) 134 } 135 }