tracers_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. package tracers
  17. import (
  18. "math/big"
  19. "testing"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/common/hexutil"
  22. "github.com/ethereum/go-ethereum/core"
  23. "github.com/ethereum/go-ethereum/core/rawdb"
  24. "github.com/ethereum/go-ethereum/core/types"
  25. "github.com/ethereum/go-ethereum/core/vm"
  26. "github.com/ethereum/go-ethereum/crypto"
  27. "github.com/ethereum/go-ethereum/params"
  28. "github.com/ethereum/go-ethereum/tests"
  29. )
  30. // callTrace is the result of a callTracer run.
  31. type callTrace struct {
  32. Type string `json:"type"`
  33. From common.Address `json:"from"`
  34. To common.Address `json:"to"`
  35. Input hexutil.Bytes `json:"input"`
  36. Output hexutil.Bytes `json:"output"`
  37. Gas *hexutil.Uint64 `json:"gas,omitempty"`
  38. GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"`
  39. Value *hexutil.Big `json:"value,omitempty"`
  40. Error string `json:"error,omitempty"`
  41. Calls []callTrace `json:"calls,omitempty"`
  42. }
  43. func BenchmarkTransactionTrace(b *testing.B) {
  44. key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  45. from := crypto.PubkeyToAddress(key.PublicKey)
  46. gas := uint64(1000000) // 1M gas
  47. to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
  48. signer := types.LatestSignerForChainID(big.NewInt(1337))
  49. tx, err := types.SignNewTx(key, signer,
  50. &types.LegacyTx{
  51. Nonce: 1,
  52. GasPrice: big.NewInt(500),
  53. Gas: gas,
  54. To: &to,
  55. })
  56. if err != nil {
  57. b.Fatal(err)
  58. }
  59. txContext := vm.TxContext{
  60. Origin: from,
  61. GasPrice: tx.GasPrice(),
  62. }
  63. context := vm.BlockContext{
  64. CanTransfer: core.CanTransfer,
  65. Transfer: core.Transfer,
  66. Coinbase: common.Address{},
  67. BlockNumber: new(big.Int).SetUint64(uint64(5)),
  68. Time: new(big.Int).SetUint64(uint64(5)),
  69. Difficulty: big.NewInt(0xffffffff),
  70. GasLimit: gas,
  71. }
  72. alloc := core.GenesisAlloc{}
  73. // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns
  74. // the address
  75. loop := []byte{
  76. byte(vm.JUMPDEST), // [ count ]
  77. byte(vm.PUSH1), 0, // jumpdestination
  78. byte(vm.JUMP),
  79. }
  80. alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{
  81. Nonce: 1,
  82. Code: loop,
  83. Balance: big.NewInt(1),
  84. }
  85. alloc[from] = core.GenesisAccount{
  86. Nonce: 1,
  87. Code: []byte{},
  88. Balance: big.NewInt(500000000000000),
  89. }
  90. _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc, false)
  91. // Create the tracer, the EVM environment and run it
  92. tracer := vm.NewStructLogger(&vm.LogConfig{
  93. Debug: false,
  94. //DisableStorage: true,
  95. //EnableMemory: false,
  96. //EnableReturnData: false,
  97. })
  98. evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Debug: true, Tracer: tracer})
  99. msg, err := tx.AsMessage(signer)
  100. if err != nil {
  101. b.Fatalf("failed to prepare transaction for tracing: %v", err)
  102. }
  103. b.ResetTimer()
  104. b.ReportAllocs()
  105. for i := 0; i < b.N; i++ {
  106. snap := statedb.Snapshot()
  107. st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
  108. _, err = st.TransitionDb()
  109. if err != nil {
  110. b.Fatal(err)
  111. }
  112. statedb.RevertToSnapshot(snap)
  113. if have, want := len(tracer.StructLogs()), 244752; have != want {
  114. b.Fatalf("trace wrong, want %d steps, have %d", want, have)
  115. }
  116. tracer.Reset()
  117. }
  118. }