gas.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2015 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 vm
  17. import (
  18. "fmt"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/params"
  21. )
  22. var (
  23. GasQuickStep = big.NewInt(2)
  24. GasFastestStep = big.NewInt(3)
  25. GasFastStep = big.NewInt(5)
  26. GasMidStep = big.NewInt(8)
  27. GasSlowStep = big.NewInt(10)
  28. GasExtStep = big.NewInt(20)
  29. GasReturn = big.NewInt(0)
  30. GasStop = big.NewInt(0)
  31. GasContractByte = big.NewInt(200)
  32. )
  33. // baseCheck checks for any stack error underflows
  34. func baseCheck(op OpCode, stack *stack, gas *big.Int) error {
  35. // PUSH and DUP are a bit special. They all cost the same but we do want to have checking on stack push limit
  36. // PUSH is also allowed to calculate the same price for all PUSHes
  37. // DUP requirements are handled elsewhere (except for the stack limit check)
  38. if op >= PUSH1 && op <= PUSH32 {
  39. op = PUSH1
  40. }
  41. if op >= DUP1 && op <= DUP16 {
  42. op = DUP1
  43. }
  44. if r, ok := _baseCheck[op]; ok {
  45. err := stack.require(r.stackPop)
  46. if err != nil {
  47. return err
  48. }
  49. if r.stackPush > 0 && stack.len()-r.stackPop+r.stackPush > int(params.StackLimit.Int64()) {
  50. return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit.Int64())
  51. }
  52. gas.Add(gas, r.gas)
  53. }
  54. return nil
  55. }
  56. // casts a arbitrary number to the amount of words (sets of 32 bytes)
  57. func toWordSize(size *big.Int) *big.Int {
  58. tmp := new(big.Int)
  59. tmp.Add(size, u256(31))
  60. tmp.Div(tmp, u256(32))
  61. return tmp
  62. }
  63. type req struct {
  64. stackPop int
  65. gas *big.Int
  66. stackPush int
  67. }
  68. var _baseCheck = map[OpCode]req{
  69. // opcode | stack pop | gas price | stack push
  70. ADD: {2, GasFastestStep, 1},
  71. LT: {2, GasFastestStep, 1},
  72. GT: {2, GasFastestStep, 1},
  73. SLT: {2, GasFastestStep, 1},
  74. SGT: {2, GasFastestStep, 1},
  75. EQ: {2, GasFastestStep, 1},
  76. ISZERO: {1, GasFastestStep, 1},
  77. SUB: {2, GasFastestStep, 1},
  78. AND: {2, GasFastestStep, 1},
  79. OR: {2, GasFastestStep, 1},
  80. XOR: {2, GasFastestStep, 1},
  81. NOT: {1, GasFastestStep, 1},
  82. BYTE: {2, GasFastestStep, 1},
  83. CALLDATALOAD: {1, GasFastestStep, 1},
  84. CALLDATACOPY: {3, GasFastestStep, 1},
  85. MLOAD: {1, GasFastestStep, 1},
  86. MSTORE: {2, GasFastestStep, 0},
  87. MSTORE8: {2, GasFastestStep, 0},
  88. CODECOPY: {3, GasFastestStep, 0},
  89. MUL: {2, GasFastStep, 1},
  90. DIV: {2, GasFastStep, 1},
  91. SDIV: {2, GasFastStep, 1},
  92. MOD: {2, GasFastStep, 1},
  93. SMOD: {2, GasFastStep, 1},
  94. SIGNEXTEND: {2, GasFastStep, 1},
  95. ADDMOD: {3, GasMidStep, 1},
  96. MULMOD: {3, GasMidStep, 1},
  97. JUMP: {1, GasMidStep, 0},
  98. JUMPI: {2, GasSlowStep, 0},
  99. EXP: {2, GasSlowStep, 1},
  100. ADDRESS: {0, GasQuickStep, 1},
  101. ORIGIN: {0, GasQuickStep, 1},
  102. CALLER: {0, GasQuickStep, 1},
  103. CALLVALUE: {0, GasQuickStep, 1},
  104. CODESIZE: {0, GasQuickStep, 1},
  105. GASPRICE: {0, GasQuickStep, 1},
  106. COINBASE: {0, GasQuickStep, 1},
  107. TIMESTAMP: {0, GasQuickStep, 1},
  108. NUMBER: {0, GasQuickStep, 1},
  109. CALLDATASIZE: {0, GasQuickStep, 1},
  110. DIFFICULTY: {0, GasQuickStep, 1},
  111. GASLIMIT: {0, GasQuickStep, 1},
  112. POP: {1, GasQuickStep, 0},
  113. PC: {0, GasQuickStep, 1},
  114. MSIZE: {0, GasQuickStep, 1},
  115. GAS: {0, GasQuickStep, 1},
  116. BLOCKHASH: {1, GasExtStep, 1},
  117. BALANCE: {1, GasExtStep, 1},
  118. EXTCODESIZE: {1, GasExtStep, 1},
  119. EXTCODECOPY: {4, GasExtStep, 0},
  120. SLOAD: {1, params.SloadGas, 1},
  121. SSTORE: {2, Zero, 0},
  122. SHA3: {2, params.Sha3Gas, 1},
  123. CREATE: {3, params.CreateGas, 1},
  124. CALL: {7, params.CallGas, 1},
  125. CALLCODE: {7, params.CallGas, 1},
  126. JUMPDEST: {0, params.JumpdestGas, 0},
  127. SUICIDE: {1, Zero, 0},
  128. RETURN: {2, Zero, 0},
  129. PUSH1: {0, GasFastestStep, 1},
  130. DUP1: {0, Zero, 1},
  131. }