github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:39</date> 10 //</624342638589382656> 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/vm" 25 "github.com/ethereum/go-ethereum/params" 26 ) 27 28 type account struct{} 29 30 func (account) SubBalance(amount *big.Int) {} 31 func (account) AddBalance(amount *big.Int) {} 32 func (account) SetAddress(common.Address) {} 33 func (account) Value() *big.Int { return nil } 34 func (account) SetBalance(*big.Int) {} 35 func (account) SetNonce(uint64) {} 36 func (account) Balance() *big.Int { return nil } 37 func (account) Address() common.Address { return common.Address{} } 38 func (account) ReturnGas(*big.Int) {} 39 func (account) SetCode(common.Hash, []byte) {} 40 func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} 41 42 func runTrace(tracer *Tracer) (json.RawMessage, error) { 43 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 44 45 contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) 46 contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} 47 48 _, err := env.Interpreter().Run(contract, []byte{}) 49 if err != nil { 50 return nil, err 51 } 52 return tracer.GetResult() 53 } 54 55 func TestTracing(t *testing.T) { 56 tracer, err := New("{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}") 57 if err != nil { 58 t.Fatal(err) 59 } 60 61 ret, err := runTrace(tracer) 62 if err != nil { 63 t.Fatal(err) 64 } 65 if !bytes.Equal(ret, []byte("3")) { 66 t.Errorf("Expected return value to be 3, got %s", string(ret)) 67 } 68 } 69 70 func TestStack(t *testing.T) { 71 tracer, err := New("{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}") 72 if err != nil { 73 t.Fatal(err) 74 } 75 76 ret, err := runTrace(tracer) 77 if err != nil { 78 t.Fatal(err) 79 } 80 if !bytes.Equal(ret, []byte("[0,1,2]")) { 81 t.Errorf("Expected return value to be [0,1,2], got %s", string(ret)) 82 } 83 } 84 85 func TestOpcodes(t *testing.T) { 86 tracer, err := New("{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}") 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 ret, err := runTrace(tracer) 92 if err != nil { 93 t.Fatal(err) 94 } 95 if !bytes.Equal(ret, []byte("[\"PUSH1\",\"PUSH1\",\"STOP\"]")) { 96 t.Errorf("Expected return value to be [\"PUSH1\",\"PUSH1\",\"STOP\"], got %s", string(ret)) 97 } 98 } 99 100 func TestHalt(t *testing.T) { 101 t.Skip("duktape doesn't support abortion") 102 103 timeout := errors.New("stahp") 104 tracer, err := New("{step: function() { while(1); }, result: function() { return null; }}") 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 go func() { 110 time.Sleep(1 * time.Second) 111 tracer.Stop(timeout) 112 }() 113 114 if _, err = runTrace(tracer); err.Error() != "stahp in server-side tracer function 'step'" { 115 t.Errorf("Expected timeout error, got %v", err) 116 } 117 } 118 119 func TestHaltBetweenSteps(t *testing.T) { 120 tracer, err := New("{step: function() {}, fault: function() {}, result: function() { return null; }}") 121 if err != nil { 122 t.Fatal(err) 123 } 124 125 env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) 126 contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) 127 128 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 129 timeout := errors.New("stahp") 130 tracer.Stop(timeout) 131 tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) 132 133 if _, err := tracer.GetResult(); err.Error() != timeout.Error() { 134 t.Errorf("Expected timeout error, got %v", err) 135 } 136 } 137