github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/neatptc/tracers/tracer_test.go (about)

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