github.com/theQRL/go-zond@v0.1.1/zond/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  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/theQRL/go-zond/common"
    24  	"github.com/theQRL/go-zond/core"
    25  	"github.com/theQRL/go-zond/core/rawdb"
    26  	"github.com/theQRL/go-zond/core/types"
    27  	"github.com/theQRL/go-zond/core/vm"
    28  	"github.com/theQRL/go-zond/crypto"
    29  	"github.com/theQRL/go-zond/zond/tracers/logger"
    30  	"github.com/theQRL/go-zond/params"
    31  	"github.com/theQRL/go-zond/tests"
    32  )
    33  
    34  func BenchmarkTransactionTrace(b *testing.B) {
    35  	key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    36  	from := crypto.PubkeyToAddress(key.PublicKey)
    37  	gas := uint64(1000000) // 1M gas
    38  	to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
    39  	signer := types.LatestSignerForChainID(big.NewInt(1337))
    40  	tx, err := types.SignNewTx(key, signer,
    41  		&types.LegacyTx{
    42  			Nonce:    1,
    43  			GasPrice: big.NewInt(500),
    44  			Gas:      gas,
    45  			To:       &to,
    46  		})
    47  	if err != nil {
    48  		b.Fatal(err)
    49  	}
    50  	txContext := vm.TxContext{
    51  		Origin:   from,
    52  		GasPrice: tx.GasPrice(),
    53  	}
    54  	context := vm.BlockContext{
    55  		CanTransfer: core.CanTransfer,
    56  		Transfer:    core.Transfer,
    57  		Coinbase:    common.Address{},
    58  		BlockNumber: new(big.Int).SetUint64(uint64(5)),
    59  		Time:        5,
    60  		Difficulty:  big.NewInt(0xffffffff),
    61  		GasLimit:    gas,
    62  		BaseFee:     big.NewInt(8),
    63  	}
    64  	alloc := core.GenesisAlloc{}
    65  	// The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns
    66  	// the address
    67  	loop := []byte{
    68  		byte(vm.JUMPDEST), //  [ count ]
    69  		byte(vm.PUSH1), 0, // jumpdestination
    70  		byte(vm.JUMP),
    71  	}
    72  	alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{
    73  		Nonce:   1,
    74  		Code:    loop,
    75  		Balance: big.NewInt(1),
    76  	}
    77  	alloc[from] = core.GenesisAccount{
    78  		Nonce:   1,
    79  		Code:    []byte{},
    80  		Balance: big.NewInt(500000000000000),
    81  	}
    82  	triedb, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc, false, rawdb.HashScheme)
    83  	defer triedb.Close()
    84  
    85  	// Create the tracer, the EVM environment and run it
    86  	tracer := logger.NewStructLogger(&logger.Config{
    87  		Debug: false,
    88  		//DisableStorage: true,
    89  		//EnableMemory: false,
    90  		//EnableReturnData: false,
    91  	})
    92  	evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer})
    93  	msg, err := core.TransactionToMessage(tx, signer, nil)
    94  	if err != nil {
    95  		b.Fatalf("failed to prepare transaction for tracing: %v", err)
    96  	}
    97  	b.ResetTimer()
    98  	b.ReportAllocs()
    99  
   100  	for i := 0; i < b.N; i++ {
   101  		snap := statedb.Snapshot()
   102  		st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
   103  		_, err = st.TransitionDb()
   104  		if err != nil {
   105  			b.Fatal(err)
   106  		}
   107  		statedb.RevertToSnapshot(snap)
   108  		if have, want := len(tracer.StructLogs()), 244752; have != want {
   109  			b.Fatalf("trace wrong, want %d steps, have %d", want, have)
   110  		}
   111  		tracer.Reset()
   112  	}
   113  }
   114  
   115  func TestMemCopying(t *testing.T) {
   116  	for i, tc := range []struct {
   117  		memsize  int64
   118  		offset   int64
   119  		size     int64
   120  		wantErr  string
   121  		wantSize int
   122  	}{
   123  		{0, 0, 100, "", 100},    // Should pad up to 100
   124  		{0, 100, 0, "", 0},      // No need to pad (0 size)
   125  		{100, 50, 100, "", 100}, // Should pad 100-150
   126  		{100, 50, 5, "", 5},     // Wanted range fully within memory
   127  		{100, -50, 0, "offset or size must not be negative", 0},                        // Errror
   128  		{0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0},    // Errror
   129  		{10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Errror
   130  
   131  	} {
   132  		mem := vm.NewMemory()
   133  		mem.Resize(uint64(tc.memsize))
   134  		cpy, err := GetMemoryCopyPadded(mem, tc.offset, tc.size)
   135  		if want := tc.wantErr; want != "" {
   136  			if err == nil {
   137  				t.Fatalf("test %d: want '%v' have no error", i, want)
   138  			}
   139  			if have := err.Error(); want != have {
   140  				t.Fatalf("test %d: want '%v' have '%v'", i, want, have)
   141  			}
   142  			continue
   143  		}
   144  		if err != nil {
   145  			t.Fatalf("test %d: unexpected error: %v", i, err)
   146  		}
   147  		if want, have := tc.wantSize, len(cpy); have != want {
   148  			t.Fatalf("test %d: want %v have %v", i, want, have)
   149  		}
   150  	}
   151  }