New gas prices model
This commit is contained in:
		@@ -28,11 +28,13 @@ type StateQuery interface {
 | 
			
		||||
func CalcDifficulty(block, parent *types.Block) *big.Int {
 | 
			
		||||
	diff := new(big.Int)
 | 
			
		||||
 | 
			
		||||
	adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
 | 
			
		||||
	if block.Time() >= parent.Time()+8 {
 | 
			
		||||
		diff.Sub(parent.Difficulty(), adjust)
 | 
			
		||||
	} else {
 | 
			
		||||
	//adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
 | 
			
		||||
	//if block.Time() >= parent.Time()+8 {
 | 
			
		||||
	adjust := new(big.Int).Div(parent.Difficulty(), big.NewInt(2048))
 | 
			
		||||
	if (block.Time() - parent.Time()) < 8 {
 | 
			
		||||
		diff.Add(parent.Difficulty(), adjust)
 | 
			
		||||
	} else {
 | 
			
		||||
		diff.Sub(parent.Difficulty(), adjust)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return diff
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,12 @@ import (
 | 
			
		||||
 | 
			
		||||
const tryJit = false
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	GasTx            = big.NewInt(21000)
 | 
			
		||||
	GasTxNonZeroByte = big.NewInt(37)
 | 
			
		||||
	GasTxZeroByte    = big.NewInt(2)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The State transitioning model
 | 
			
		||||
 *
 | 
			
		||||
@@ -170,7 +176,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 | 
			
		||||
	//sender.Nonce += 1
 | 
			
		||||
 | 
			
		||||
	// Transaction gas
 | 
			
		||||
	if err = self.UseGas(vm.GasTx); err != nil {
 | 
			
		||||
	if err = self.UseGas(GasTx); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -178,9 +184,9 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 | 
			
		||||
	var dgas int64
 | 
			
		||||
	for _, byt := range self.data {
 | 
			
		||||
		if byt != 0 {
 | 
			
		||||
			dgas += vm.GasData.Int64()
 | 
			
		||||
			dgas += GasTxNonZeroByte.Int64()
 | 
			
		||||
		} else {
 | 
			
		||||
			dgas += 1 // This is 1/5. If GasData changes this fails
 | 
			
		||||
			dgas += GasTxZeroByte.Int64()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err = self.UseGas(big.NewInt(dgas)); err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,23 +32,23 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
 | 
			
		||||
 | 
			
		||||
		// SHA256
 | 
			
		||||
		string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
 | 
			
		||||
			n := big.NewInt(int64(l+31)/32 + 1)
 | 
			
		||||
			n.Mul(n, GasSha256)
 | 
			
		||||
			return n
 | 
			
		||||
			n := big.NewInt(int64(l+31) / 32)
 | 
			
		||||
			n.Mul(n, GasSha256Word)
 | 
			
		||||
			return n.Add(n, GasSha256Base)
 | 
			
		||||
		}, sha256Func},
 | 
			
		||||
 | 
			
		||||
		// RIPEMD160
 | 
			
		||||
		string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
 | 
			
		||||
			n := big.NewInt(int64(l+31)/32 + 1)
 | 
			
		||||
			n.Mul(n, GasRipemd)
 | 
			
		||||
			return n
 | 
			
		||||
			n := big.NewInt(int64(l+31) / 32)
 | 
			
		||||
			n.Mul(n, GasRipemdWord)
 | 
			
		||||
			return n.Add(n, GasRipemdBase)
 | 
			
		||||
		}, ripemd160Func},
 | 
			
		||||
 | 
			
		||||
		string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
 | 
			
		||||
			n := big.NewInt(int64(l+31)/32 + 1)
 | 
			
		||||
			n.Mul(n, GasMemCpy)
 | 
			
		||||
			n := big.NewInt(int64(l+31) / 32)
 | 
			
		||||
			n.Mul(n, GasIdentityWord)
 | 
			
		||||
 | 
			
		||||
			return n
 | 
			
		||||
			return n.Add(n, GasIdentityBase)
 | 
			
		||||
		}, memCpy},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								vm/common.go
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								vm/common.go
									
									
									
									
									
								
							@@ -31,26 +31,48 @@ func NewVm(env Environment) VirtualMachine {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	GasStep         = big.NewInt(1)
 | 
			
		||||
	GasSha          = big.NewInt(10)
 | 
			
		||||
	GasSLoad        = big.NewInt(20)
 | 
			
		||||
	GasSStore       = big.NewInt(100)
 | 
			
		||||
	GasSStoreRefund = big.NewInt(100)
 | 
			
		||||
	GasBalance      = big.NewInt(20)
 | 
			
		||||
	GasCreate       = big.NewInt(100)
 | 
			
		||||
	GasCall         = big.NewInt(20)
 | 
			
		||||
	GasCreateByte   = big.NewInt(5)
 | 
			
		||||
	GasSha3Byte     = big.NewInt(10)
 | 
			
		||||
	GasSha256Byte   = big.NewInt(50)
 | 
			
		||||
	GasRipemdByte   = big.NewInt(50)
 | 
			
		||||
	GasMemory       = big.NewInt(1)
 | 
			
		||||
	GasData         = big.NewInt(5)
 | 
			
		||||
	GasTx           = big.NewInt(500)
 | 
			
		||||
	GasLog          = big.NewInt(32)
 | 
			
		||||
	GasSha256       = big.NewInt(50)
 | 
			
		||||
	GasRipemd       = big.NewInt(50)
 | 
			
		||||
	GasEcrecover    = big.NewInt(500)
 | 
			
		||||
	GasMemCpy       = big.NewInt(1)
 | 
			
		||||
	GasQuickStep   = big.NewInt(2)
 | 
			
		||||
	GasFastestStep = big.NewInt(3)
 | 
			
		||||
	GasFastStep    = big.NewInt(5)
 | 
			
		||||
	GasMidStep     = big.NewInt(8)
 | 
			
		||||
	GasSlowStep    = big.NewInt(10)
 | 
			
		||||
	GasExtStep     = big.NewInt(20)
 | 
			
		||||
 | 
			
		||||
	GasStorageGet        = big.NewInt(50)
 | 
			
		||||
	GasStorageAdd        = big.NewInt(20000)
 | 
			
		||||
	GasStorageMod        = big.NewInt(5000)
 | 
			
		||||
	GasLogBase           = big.NewInt(2000)
 | 
			
		||||
	GasLogTopic          = big.NewInt(2000)
 | 
			
		||||
	GasLogData           = big.NewInt(8)
 | 
			
		||||
	GasCreate            = big.NewInt(32000)
 | 
			
		||||
	GasCreateByte        = big.NewInt(300)
 | 
			
		||||
	GasCall              = big.NewInt(40)
 | 
			
		||||
	GasCallValueTransfer = big.NewInt(6700)
 | 
			
		||||
	GasCallNewAccount    = big.NewInt(25000)
 | 
			
		||||
	GasReturn            = big.NewInt(0)
 | 
			
		||||
	GasStop              = big.NewInt(0)
 | 
			
		||||
	GasJumpDest          = big.NewInt(1)
 | 
			
		||||
 | 
			
		||||
	RefundStorage = big.NewInt(15000)
 | 
			
		||||
	RefundSuicide = big.NewInt(24000)
 | 
			
		||||
 | 
			
		||||
	GasMemWord           = big.NewInt(3)
 | 
			
		||||
	GasQuadCoeffWord     = big.NewInt(1)
 | 
			
		||||
	GasContractByte      = big.NewInt(200)
 | 
			
		||||
	GasTransaction       = big.NewInt(21000)
 | 
			
		||||
	GasTxDataNonzeroByte = big.NewInt(37)
 | 
			
		||||
	GasTxZeroByte        = big.NewInt(2)
 | 
			
		||||
 | 
			
		||||
	GasSha3Base     = big.NewInt(30)
 | 
			
		||||
	GasSha3Word     = big.NewInt(6)
 | 
			
		||||
	GasSha256Base   = big.NewInt(60)
 | 
			
		||||
	GasSha256Word   = big.NewInt(12)
 | 
			
		||||
	GasRipemdBase   = big.NewInt(600)
 | 
			
		||||
	GasRipemdWord   = big.NewInt(12)
 | 
			
		||||
	GasEcrecover    = big.NewInt(3000)
 | 
			
		||||
	GasIdentityBase = big.NewInt(15)
 | 
			
		||||
	GasIdentityWord = big.NewInt(3)
 | 
			
		||||
	GasCopyWord     = big.NewInt(3)
 | 
			
		||||
 | 
			
		||||
	Pow256 = ethutil.BigPow(2, 256)
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +81,8 @@ var (
 | 
			
		||||
 | 
			
		||||
	U256 = ethutil.U256
 | 
			
		||||
	S256 = ethutil.S256
 | 
			
		||||
 | 
			
		||||
	Zero = ethutil.Big0
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const MaxCallDepth = 1025
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										209
									
								
								vm/vm.go
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								vm/vm.go
									
									
									
									
									
								
							@@ -769,27 +769,97 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
 | 
			
		||||
	gas := new(big.Int)
 | 
			
		||||
	addStepGasUsage := func(amount *big.Int) {
 | 
			
		||||
		if amount.Cmp(ethutil.Big0) >= 0 {
 | 
			
		||||
			gas.Add(gas, amount)
 | 
			
		||||
		}
 | 
			
		||||
type req struct {
 | 
			
		||||
	stack int
 | 
			
		||||
	gas   *big.Int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _baseCheck = map[OpCode]req{
 | 
			
		||||
	//       Req Stack  Gas price
 | 
			
		||||
	ADD:          {2, GasFastestStep},
 | 
			
		||||
	LT:           {2, GasFastestStep},
 | 
			
		||||
	GT:           {2, GasFastestStep},
 | 
			
		||||
	SLT:          {2, GasFastestStep},
 | 
			
		||||
	SGT:          {2, GasFastestStep},
 | 
			
		||||
	EQ:           {2, GasFastestStep},
 | 
			
		||||
	ISZERO:       {1, GasFastestStep},
 | 
			
		||||
	SUB:          {2, GasFastestStep},
 | 
			
		||||
	AND:          {2, GasFastestStep},
 | 
			
		||||
	OR:           {2, GasFastestStep},
 | 
			
		||||
	XOR:          {2, GasFastestStep},
 | 
			
		||||
	NOT:          {1, GasFastestStep},
 | 
			
		||||
	BYTE:         {2, GasFastestStep},
 | 
			
		||||
	CALLDATALOAD: {1, GasFastestStep},
 | 
			
		||||
	CALLDATACOPY: {3, GasFastestStep},
 | 
			
		||||
	MLOAD:        {1, GasFastestStep},
 | 
			
		||||
	MSTORE:       {2, GasFastestStep},
 | 
			
		||||
	MSTORE8:      {2, GasFastestStep},
 | 
			
		||||
	CODECOPY:     {3, GasFastestStep},
 | 
			
		||||
	MUL:          {2, GasFastStep},
 | 
			
		||||
	DIV:          {2, GasFastStep},
 | 
			
		||||
	SDIV:         {2, GasFastStep},
 | 
			
		||||
	MOD:          {2, GasFastStep},
 | 
			
		||||
	SMOD:         {2, GasFastStep},
 | 
			
		||||
	SIGNEXTEND:   {2, GasFastStep},
 | 
			
		||||
	ADDMOD:       {3, GasMidStep},
 | 
			
		||||
	MULMOD:       {3, GasMidStep},
 | 
			
		||||
	JUMP:         {1, GasMidStep},
 | 
			
		||||
	JUMPI:        {2, GasSlowStep},
 | 
			
		||||
	EXP:          {2, GasSlowStep},
 | 
			
		||||
	ADDRESS:      {0, GasQuickStep},
 | 
			
		||||
	ORIGIN:       {0, GasQuickStep},
 | 
			
		||||
	CALLER:       {0, GasQuickStep},
 | 
			
		||||
	CALLVALUE:    {0, GasQuickStep},
 | 
			
		||||
	CODESIZE:     {0, GasQuickStep},
 | 
			
		||||
	GASPRICE:     {0, GasQuickStep},
 | 
			
		||||
	COINBASE:     {0, GasQuickStep},
 | 
			
		||||
	TIMESTAMP:    {0, GasQuickStep},
 | 
			
		||||
	NUMBER:       {0, GasQuickStep},
 | 
			
		||||
	DIFFICULTY:   {0, GasQuickStep},
 | 
			
		||||
	GASLIMIT:     {0, GasQuickStep},
 | 
			
		||||
	POP:          {0, GasQuickStep},
 | 
			
		||||
	PC:           {0, GasQuickStep},
 | 
			
		||||
	MSIZE:        {0, GasQuickStep},
 | 
			
		||||
	GAS:          {0, GasQuickStep},
 | 
			
		||||
	BLOCKHASH:    {1, GasExtStep},
 | 
			
		||||
	BALANCE:      {0, GasExtStep},
 | 
			
		||||
	EXTCODESIZE:  {1, GasExtStep},
 | 
			
		||||
	EXTCODECOPY:  {4, GasExtStep},
 | 
			
		||||
	SLOAD:        {1, GasStorageGet},
 | 
			
		||||
	SSTORE:       {2, Zero},
 | 
			
		||||
	SHA3:         {1, GasSha3Base},
 | 
			
		||||
	CREATE:       {3, GasCreate},
 | 
			
		||||
	CALL:         {7, GasCall},
 | 
			
		||||
	CALLCODE:     {7, GasCall},
 | 
			
		||||
	JUMPDEST:     {0, GasJumpDest},
 | 
			
		||||
	SUICIDE:      {1, Zero},
 | 
			
		||||
	RETURN:       {2, Zero},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func baseCheck(op OpCode, stack *Stack, gas *big.Int) {
 | 
			
		||||
	if r, ok := _baseCheck[op]; ok {
 | 
			
		||||
		stack.require(r.stack)
 | 
			
		||||
 | 
			
		||||
		gas.Add(gas, r.gas)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	addStepGasUsage(GasStep)
 | 
			
		||||
func toWordSize(size *big.Int) *big.Int {
 | 
			
		||||
	tmp := new(big.Int)
 | 
			
		||||
	tmp.Add(tmp, u256(31))
 | 
			
		||||
	tmp.Div(tmp, u256(32))
 | 
			
		||||
	return tmp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
 | 
			
		||||
	var (
 | 
			
		||||
		gas                 = new(big.Int)
 | 
			
		||||
		newMemSize *big.Int = new(big.Int)
 | 
			
		||||
	)
 | 
			
		||||
	baseCheck(op, stack, gas)
 | 
			
		||||
 | 
			
		||||
	var newMemSize *big.Int = ethutil.Big0
 | 
			
		||||
	var additionalGas *big.Int = new(big.Int)
 | 
			
		||||
	// Stack Check, memory resize & gas phase
 | 
			
		||||
	switch op {
 | 
			
		||||
	// Stack checks only
 | 
			
		||||
	case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 1
 | 
			
		||||
		stack.require(1)
 | 
			
		||||
	case JUMPI, ADD, SUB, DIV, MUL, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
	case ADDMOD, MULMOD: // 3
 | 
			
		||||
		stack.require(3)
 | 
			
		||||
	case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
 | 
			
		||||
		n := int(op - SWAP1 + 2)
 | 
			
		||||
		stack.require(n)
 | 
			
		||||
@@ -800,112 +870,83 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
 | 
			
		||||
		n := int(op - LOG0)
 | 
			
		||||
		stack.require(n + 2)
 | 
			
		||||
 | 
			
		||||
		gas.Set(GasLog)
 | 
			
		||||
		addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
 | 
			
		||||
 | 
			
		||||
		mSize, mStart := stack.Peekn()
 | 
			
		||||
		addStepGasUsage(mSize)
 | 
			
		||||
 | 
			
		||||
		gas.Add(gas, GasLogBase)
 | 
			
		||||
		gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
 | 
			
		||||
		gas.Add(gas, new(big.Int).Mul(mSize, GasLogData))
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(mStart, mSize)
 | 
			
		||||
	case EXP:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
 | 
			
		||||
		gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1)))
 | 
			
		||||
	// Gas only
 | 
			
		||||
	case STOP:
 | 
			
		||||
		gas.Set(ethutil.Big0)
 | 
			
		||||
	case SUICIDE:
 | 
			
		||||
		stack.require(1)
 | 
			
		||||
 | 
			
		||||
		gas.Set(ethutil.Big0)
 | 
			
		||||
	case SLOAD:
 | 
			
		||||
		stack.require(1)
 | 
			
		||||
 | 
			
		||||
		gas.Set(GasSLoad)
 | 
			
		||||
	// Memory resize & Gas
 | 
			
		||||
		gas.Add(gas, big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes())+1)))
 | 
			
		||||
	case SSTORE:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
 | 
			
		||||
		var mult *big.Int
 | 
			
		||||
		var g *big.Int
 | 
			
		||||
		y, x := stack.Peekn()
 | 
			
		||||
		val := statedb.GetState(context.Address(), x.Bytes())
 | 
			
		||||
		if len(val) == 0 && len(y.Bytes()) > 0 {
 | 
			
		||||
			// 0 => non 0
 | 
			
		||||
			mult = ethutil.Big3
 | 
			
		||||
			g = GasStorageAdd
 | 
			
		||||
		} else if len(val) > 0 && len(y.Bytes()) == 0 {
 | 
			
		||||
			statedb.Refund(self.env.Origin(), GasSStoreRefund)
 | 
			
		||||
			statedb.Refund(self.env.Origin(), RefundStorage)
 | 
			
		||||
 | 
			
		||||
			mult = ethutil.Big0
 | 
			
		||||
			g = GasStorageMod
 | 
			
		||||
		} else {
 | 
			
		||||
			// non 0 => non 0 (or 0 => 0)
 | 
			
		||||
			mult = ethutil.Big1
 | 
			
		||||
			g = GasStorageMod
 | 
			
		||||
		}
 | 
			
		||||
		gas.Set(new(big.Int).Mul(mult, GasSStore))
 | 
			
		||||
	case BALANCE:
 | 
			
		||||
		stack.require(1)
 | 
			
		||||
		gas.Set(GasBalance)
 | 
			
		||||
	case MSTORE:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
		gas.Set(g)
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), u256(32))
 | 
			
		||||
	case MLOAD:
 | 
			
		||||
		stack.require(1)
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), u256(32))
 | 
			
		||||
	case MSTORE8:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), u256(1))
 | 
			
		||||
	case RETURN:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 | 
			
		||||
	case SHA3:
 | 
			
		||||
		stack.require(2)
 | 
			
		||||
		gas.Set(GasSha)
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 | 
			
		||||
		additionalGas.Set(stack.data[stack.Len()-2])
 | 
			
		||||
 | 
			
		||||
		words := toWordSize(stack.data[stack.Len()-2])
 | 
			
		||||
		gas.Add(gas, words.Mul(words, GasSha3Word))
 | 
			
		||||
	case CALLDATACOPY:
 | 
			
		||||
		stack.require(3)
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
 | 
			
		||||
		additionalGas.Set(stack.data[stack.Len()-3])
 | 
			
		||||
 | 
			
		||||
		words := toWordSize(stack.data[stack.Len()-3])
 | 
			
		||||
		gas.Add(gas, words.Mul(words, GasCopyWord))
 | 
			
		||||
	case CODECOPY:
 | 
			
		||||
		stack.require(3)
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
 | 
			
		||||
		additionalGas.Set(stack.data[stack.Len()-3])
 | 
			
		||||
	case EXTCODECOPY:
 | 
			
		||||
		stack.require(4)
 | 
			
		||||
 | 
			
		||||
		words := toWordSize(stack.data[stack.Len()-3])
 | 
			
		||||
		gas.Add(gas, words.Mul(words, GasCopyWord))
 | 
			
		||||
	case EXTCODECOPY:
 | 
			
		||||
		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
 | 
			
		||||
		additionalGas.Set(stack.data[stack.Len()-4])
 | 
			
		||||
 | 
			
		||||
		words := toWordSize(stack.data[stack.Len()-4])
 | 
			
		||||
		gas.Add(gas, words.Mul(words, GasCopyWord))
 | 
			
		||||
	case CREATE:
 | 
			
		||||
		size := new(big.Int).Set(stack.data[stack.Len()-2])
 | 
			
		||||
		gas.Add(gas, size.Mul(size, GasCreateByte))
 | 
			
		||||
	case CALL, CALLCODE:
 | 
			
		||||
		stack.require(7)
 | 
			
		||||
		gas.Set(GasCall)
 | 
			
		||||
		addStepGasUsage(stack.data[stack.Len()-1])
 | 
			
		||||
		gas.Add(gas, stack.data[stack.Len()-1])
 | 
			
		||||
 | 
			
		||||
		if op == CALL {
 | 
			
		||||
			if self.env.State().GetStateObject(stack.data[stack.Len()-2].Bytes()) == nil {
 | 
			
		||||
				gas.Add(gas, GasCallNewAccount)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(stack.data[stack.Len()].Bytes()) > 0 {
 | 
			
		||||
				gas.Add(gas, GasCallValueTransfer)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
 | 
			
		||||
		y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
 | 
			
		||||
 | 
			
		||||
		newMemSize = ethutil.BigMax(x, y)
 | 
			
		||||
	case CREATE:
 | 
			
		||||
		stack.require(3)
 | 
			
		||||
		gas.Set(GasCreate)
 | 
			
		||||
 | 
			
		||||
		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch op {
 | 
			
		||||
	case CALLDATACOPY, CODECOPY, EXTCODECOPY:
 | 
			
		||||
		additionalGas.Add(additionalGas, u256(31))
 | 
			
		||||
		additionalGas.Div(additionalGas, u256(32))
 | 
			
		||||
		addStepGasUsage(additionalGas)
 | 
			
		||||
	case SHA3:
 | 
			
		||||
		additionalGas.Add(additionalGas, u256(31))
 | 
			
		||||
		additionalGas.Div(additionalGas, u256(32))
 | 
			
		||||
		additionalGas.Mul(additionalGas, GasSha3Byte)
 | 
			
		||||
		addStepGasUsage(additionalGas)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if newMemSize.Cmp(ethutil.Big0) > 0 {
 | 
			
		||||
		newMemSize.Add(newMemSize, u256(31))
 | 
			
		||||
		newMemSize.Div(newMemSize, u256(32))
 | 
			
		||||
@@ -913,10 +954,10 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
 | 
			
		||||
 | 
			
		||||
		if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
 | 
			
		||||
			memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
 | 
			
		||||
			memGasUsage.Mul(GasMemory, memGasUsage)
 | 
			
		||||
			memGasUsage.Mul(GasMemWord, memGasUsage)
 | 
			
		||||
			memGasUsage.Div(memGasUsage, u256(32))
 | 
			
		||||
 | 
			
		||||
			addStepGasUsage(memGasUsage)
 | 
			
		||||
			gas.Add(gas, memGasUsage)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user