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