github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/eth/tracers/tracer_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:37</date> 10 //</624450090068611072> 11 12 13 package tracers 14 15 import ( 16 "bytes" 17 "encoding/json" 18 "errors" 19 "math/big" 20 "testing" 21 "time" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core/state" 25 "github.com/ethereum/go-ethereum/core/vm" 26 "github.com/ethereum/go-ethereum/params" 27 ) 28 29 type account struct{} 30 31 func (account) SubBalance(amount *big.Int) {} 32 func (account) AddBalance(amount *big.Int) {} 33 func (account) SetAddress(common.Address) {} 34 func (account) Value() *big.Int { return nil } 35 func (account) SetBalance(*big.Int) {} 36 func (account) SetNonce(uint64) {} 37 func (account) Balance() *big.Int { return nil } 38 func (account) Address() common.Address { return common.Address{} } 39 func (account) ReturnGas(*big.Int) {} 40 func (account) SetCode(common.Hash, []byte) {} 41 func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} 42 43 type dummyStatedb struct { 44 state.StateDB 45 } 46 47 func (*dummyStatedb) GetRefund() uint64 { return 1337 } 48 49 func runTrace(tracer *Tracer) (json.RawMessage, error) { 50 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 51 52 contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) 53 contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} 54 55 _, err := env.Interpreter().Run(contract, []byte{}, false) 56 if err != nil { 57 return nil, err 58 } 59 return tracer.GetResult() 60 } 61 62 func TestTracing(t *testing.T) { 63 tracer, err := New("{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}") 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 ret, err := runTrace(tracer) 69 if err != nil { 70 t.Fatal(err) 71 } 72 if !bytes.Equal(ret, []byte("3")) { 73 t.Errorf("Expected return value to be 3, got %s", string(ret)) 74 } 75 } 76 77 func TestStack(t *testing.T) { 78 tracer, err := New("{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}") 79 if err != nil { 80 t.Fatal(err) 81 } 82 83 ret, err := runTrace(tracer) 84 if err != nil { 85 t.Fatal(err) 86 } 87 if !bytes.Equal(ret, []byte("[0,1,2]")) { 88 t.Errorf("Expected return value to be [0,1,2], got %s", string(ret)) 89 } 90 } 91 92 func TestOpcodes(t *testing.T) { 93 tracer, err := New("{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}") 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 ret, err := runTrace(tracer) 99 if err != nil { 100 t.Fatal(err) 101 } 102 if !bytes.Equal(ret, []byte("[\"PUSH1\",\"PUSH1\",\"STOP\"]")) { 103 t.Errorf("Expected return value to be [\"PUSH1\",\"PUSH1\",\"STOP\"], got %s", string(ret)) 104 } 105 } 106 107 func TestHalt(t *testing.T) { 108 t.Skip("duktape doesn't support abortion") 109 110 timeout := errors.New("stahp") 111 tracer, err := New("{step: function() { while(1); }, result: function() { return null; }}") 112 if err != nil { 113 t.Fatal(err) 114 } 115 116 go func() { 117 time.Sleep(1 * time.Second) 118 tracer.Stop(timeout) 119 }() 120 121 if _, err = runTrace(tracer); err.Error() != "stahp in server-side tracer function 'step'" { 122 t.Errorf("Expected timeout error, got %v", err) 123 } 124 } 125 126 func TestHaltBetweenSteps(t *testing.T) { 127 tracer, err := New("{step: function() {}, fault: function() {}, result: function() { return null; }}") 128 if err != nil { 129 t.Fatal(err) 130 } 131 132 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 133 contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) 134 135 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 136 timeout := errors.New("stahp") 137 tracer.Stop(timeout) 138 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 139 140 if _, err := tracer.GetResult(); err.Error() != timeout.Error() { 141 t.Errorf("Expected timeout error, got %v", err) 142 } 143 } 144