github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/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/atheioschain/go-atheios/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  	n64 = big.NewInt(64)
    40  )
    41  
    42  // calcGas returns the actual gas cost of the call.
    43  //
    44  // The cost of gas was changed during the homestead price change HF. To allow for EIP150
    45  // to be implemented. The returned gas is gas - base * 63 / 64.
    46  func callGas(gasTable params.GasTable, availableGas, base, callCost *big.Int) *big.Int {
    47  	if gasTable.CreateBySuicide != nil {
    48  		availableGas = new(big.Int).Sub(availableGas, base)
    49  		g := new(big.Int).Div(availableGas, n64)
    50  		g.Sub(availableGas, g)
    51  
    52  		if g.Cmp(callCost) < 0 {
    53  			return g
    54  		}
    55  	}
    56  	return callCost
    57  }
    58  
    59  // baseCheck checks for any stack error underflows
    60  func baseCheck(op OpCode, stack *Stack, gas *big.Int) error {
    61  	// PUSH and DUP are a bit special. They all cost the same but we do want to have checking on stack push limit
    62  	// PUSH is also allowed to calculate the same price for all PUSHes
    63  	// DUP requirements are handled elsewhere (except for the stack limit check)
    64  	if op >= PUSH1 && op <= PUSH32 {
    65  		op = PUSH1
    66  	}
    67  	if op >= DUP1 && op <= DUP16 {
    68  		op = DUP1
    69  	}
    70  
    71  	if r, ok := _baseCheck[op]; ok {
    72  		err := stack.require(r.stackPop)
    73  		if err != nil {
    74  			return err
    75  		}
    76  
    77  		if r.stackPush > 0 && stack.len()-r.stackPop+r.stackPush > int(params.StackLimit.Int64()) {
    78  			return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit.Int64())
    79  		}
    80  
    81  		gas.Add(gas, r.gas)
    82  	}
    83  	return nil
    84  }
    85  
    86  // casts a arbitrary number to the amount of words (sets of 32 bytes)
    87  func toWordSize(size *big.Int) *big.Int {
    88  	tmp := new(big.Int)
    89  	tmp.Add(size, u256(31))
    90  	tmp.Div(tmp, u256(32))
    91  	return tmp
    92  }
    93  
    94  type req struct {
    95  	stackPop  int
    96  	gas       *big.Int
    97  	stackPush int
    98  }
    99  
   100  var _baseCheck = map[OpCode]req{
   101  	// opcode  |  stack pop | gas price | stack push
   102  	ADD:          {2, GasFastestStep, 1},
   103  	LT:           {2, GasFastestStep, 1},
   104  	GT:           {2, GasFastestStep, 1},
   105  	SLT:          {2, GasFastestStep, 1},
   106  	SGT:          {2, GasFastestStep, 1},
   107  	EQ:           {2, GasFastestStep, 1},
   108  	ISZERO:       {1, GasFastestStep, 1},
   109  	SUB:          {2, GasFastestStep, 1},
   110  	AND:          {2, GasFastestStep, 1},
   111  	OR:           {2, GasFastestStep, 1},
   112  	XOR:          {2, GasFastestStep, 1},
   113  	NOT:          {1, GasFastestStep, 1},
   114  	BYTE:         {2, GasFastestStep, 1},
   115  	CALLDATALOAD: {1, GasFastestStep, 1},
   116  	CALLDATACOPY: {3, GasFastestStep, 1},
   117  	MLOAD:        {1, GasFastestStep, 1},
   118  	MSTORE:       {2, GasFastestStep, 0},
   119  	MSTORE8:      {2, GasFastestStep, 0},
   120  	CODECOPY:     {3, GasFastestStep, 0},
   121  	MUL:          {2, GasFastStep, 1},
   122  	DIV:          {2, GasFastStep, 1},
   123  	SDIV:         {2, GasFastStep, 1},
   124  	MOD:          {2, GasFastStep, 1},
   125  	SMOD:         {2, GasFastStep, 1},
   126  	SIGNEXTEND:   {2, GasFastStep, 1},
   127  	ADDMOD:       {3, GasMidStep, 1},
   128  	MULMOD:       {3, GasMidStep, 1},
   129  	JUMP:         {1, GasMidStep, 0},
   130  	JUMPI:        {2, GasSlowStep, 0},
   131  	EXP:          {2, GasSlowStep, 1},
   132  	ADDRESS:      {0, GasQuickStep, 1},
   133  	ORIGIN:       {0, GasQuickStep, 1},
   134  	CALLER:       {0, GasQuickStep, 1},
   135  	CALLVALUE:    {0, GasQuickStep, 1},
   136  	CODESIZE:     {0, GasQuickStep, 1},
   137  	GASPRICE:     {0, GasQuickStep, 1},
   138  	COINBASE:     {0, GasQuickStep, 1},
   139  	TIMESTAMP:    {0, GasQuickStep, 1},
   140  	NUMBER:       {0, GasQuickStep, 1},
   141  	CALLDATASIZE: {0, GasQuickStep, 1},
   142  	DIFFICULTY:   {0, GasQuickStep, 1},
   143  	GASLIMIT:     {0, GasQuickStep, 1},
   144  	POP:          {1, GasQuickStep, 0},
   145  	PC:           {0, GasQuickStep, 1},
   146  	MSIZE:        {0, GasQuickStep, 1},
   147  	GAS:          {0, GasQuickStep, 1},
   148  	BLOCKHASH:    {1, GasExtStep, 1},
   149  	BALANCE:      {1, Zero, 1},
   150  	EXTCODESIZE:  {1, Zero, 1},
   151  	EXTCODECOPY:  {4, Zero, 0},
   152  	SLOAD:        {1, params.SloadGas, 1},
   153  	SSTORE:       {2, Zero, 0},
   154  	SHA3:         {2, params.Sha3Gas, 1},
   155  	CREATE:       {3, params.CreateGas, 1},
   156  	// Zero is calculated in the gasSwitch
   157  	CALL:         {7, Zero, 1},
   158  	CALLCODE:     {7, Zero, 1},
   159  	DELEGATECALL: {6, Zero, 1},
   160  	SELFDESTRUCT: {1, Zero, 0},
   161  	JUMPDEST:     {0, params.JumpdestGas, 0},
   162  	RETURN:       {2, Zero, 0},
   163  	PUSH1:        {0, GasFastestStep, 1},
   164  	DUP1:         {0, Zero, 1},
   165  }