New gas prices model
This commit is contained in:
parent
73c52d1677
commit
b383ff0b96
@ -28,11 +28,13 @@ type StateQuery interface {
|
|||||||
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
func CalcDifficulty(block, parent *types.Block) *big.Int {
|
||||||
diff := new(big.Int)
|
diff := new(big.Int)
|
||||||
|
|
||||||
adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
|
//adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
|
||||||
if block.Time() >= parent.Time()+8 {
|
//if block.Time() >= parent.Time()+8 {
|
||||||
diff.Sub(parent.Difficulty(), adjust)
|
adjust := new(big.Int).Div(parent.Difficulty(), big.NewInt(2048))
|
||||||
} else {
|
if (block.Time() - parent.Time()) < 8 {
|
||||||
diff.Add(parent.Difficulty(), adjust)
|
diff.Add(parent.Difficulty(), adjust)
|
||||||
|
} else {
|
||||||
|
diff.Sub(parent.Difficulty(), adjust)
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
|
@ -12,6 +12,12 @@ import (
|
|||||||
|
|
||||||
const tryJit = false
|
const tryJit = false
|
||||||
|
|
||||||
|
var (
|
||||||
|
GasTx = big.NewInt(21000)
|
||||||
|
GasTxNonZeroByte = big.NewInt(37)
|
||||||
|
GasTxZeroByte = big.NewInt(2)
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The State transitioning model
|
* The State transitioning model
|
||||||
*
|
*
|
||||||
@ -170,7 +176,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
|
|||||||
//sender.Nonce += 1
|
//sender.Nonce += 1
|
||||||
|
|
||||||
// Transaction gas
|
// Transaction gas
|
||||||
if err = self.UseGas(vm.GasTx); err != nil {
|
if err = self.UseGas(GasTx); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,9 +184,9 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
|
|||||||
var dgas int64
|
var dgas int64
|
||||||
for _, byt := range self.data {
|
for _, byt := range self.data {
|
||||||
if byt != 0 {
|
if byt != 0 {
|
||||||
dgas += vm.GasData.Int64()
|
dgas += GasTxNonZeroByte.Int64()
|
||||||
} else {
|
} else {
|
||||||
dgas += 1 // This is 1/5. If GasData changes this fails
|
dgas += GasTxZeroByte.Int64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = self.UseGas(big.NewInt(dgas)); err != nil {
|
if err = self.UseGas(big.NewInt(dgas)); err != nil {
|
||||||
|
@ -32,23 +32,23 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
|
|||||||
|
|
||||||
// SHA256
|
// SHA256
|
||||||
string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31)/32 + 1)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasSha256)
|
n.Mul(n, GasSha256Word)
|
||||||
return n
|
return n.Add(n, GasSha256Base)
|
||||||
}, sha256Func},
|
}, sha256Func},
|
||||||
|
|
||||||
// RIPEMD160
|
// RIPEMD160
|
||||||
string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31)/32 + 1)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasRipemd)
|
n.Mul(n, GasRipemdWord)
|
||||||
return n
|
return n.Add(n, GasRipemdBase)
|
||||||
}, ripemd160Func},
|
}, ripemd160Func},
|
||||||
|
|
||||||
string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
|
||||||
n := big.NewInt(int64(l+31)/32 + 1)
|
n := big.NewInt(int64(l+31) / 32)
|
||||||
n.Mul(n, GasMemCpy)
|
n.Mul(n, GasIdentityWord)
|
||||||
|
|
||||||
return n
|
return n.Add(n, GasIdentityBase)
|
||||||
}, memCpy},
|
}, memCpy},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
64
vm/common.go
64
vm/common.go
@ -31,26 +31,48 @@ func NewVm(env Environment) VirtualMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GasStep = big.NewInt(1)
|
GasQuickStep = big.NewInt(2)
|
||||||
GasSha = big.NewInt(10)
|
GasFastestStep = big.NewInt(3)
|
||||||
GasSLoad = big.NewInt(20)
|
GasFastStep = big.NewInt(5)
|
||||||
GasSStore = big.NewInt(100)
|
GasMidStep = big.NewInt(8)
|
||||||
GasSStoreRefund = big.NewInt(100)
|
GasSlowStep = big.NewInt(10)
|
||||||
GasBalance = big.NewInt(20)
|
GasExtStep = big.NewInt(20)
|
||||||
GasCreate = big.NewInt(100)
|
|
||||||
GasCall = big.NewInt(20)
|
GasStorageGet = big.NewInt(50)
|
||||||
GasCreateByte = big.NewInt(5)
|
GasStorageAdd = big.NewInt(20000)
|
||||||
GasSha3Byte = big.NewInt(10)
|
GasStorageMod = big.NewInt(5000)
|
||||||
GasSha256Byte = big.NewInt(50)
|
GasLogBase = big.NewInt(2000)
|
||||||
GasRipemdByte = big.NewInt(50)
|
GasLogTopic = big.NewInt(2000)
|
||||||
GasMemory = big.NewInt(1)
|
GasLogData = big.NewInt(8)
|
||||||
GasData = big.NewInt(5)
|
GasCreate = big.NewInt(32000)
|
||||||
GasTx = big.NewInt(500)
|
GasCreateByte = big.NewInt(300)
|
||||||
GasLog = big.NewInt(32)
|
GasCall = big.NewInt(40)
|
||||||
GasSha256 = big.NewInt(50)
|
GasCallValueTransfer = big.NewInt(6700)
|
||||||
GasRipemd = big.NewInt(50)
|
GasCallNewAccount = big.NewInt(25000)
|
||||||
GasEcrecover = big.NewInt(500)
|
GasReturn = big.NewInt(0)
|
||||||
GasMemCpy = big.NewInt(1)
|
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)
|
Pow256 = ethutil.BigPow(2, 256)
|
||||||
|
|
||||||
@ -59,6 +81,8 @@ var (
|
|||||||
|
|
||||||
U256 = ethutil.U256
|
U256 = ethutil.U256
|
||||||
S256 = ethutil.S256
|
S256 = ethutil.S256
|
||||||
|
|
||||||
|
Zero = ethutil.Big0
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxCallDepth = 1025
|
const MaxCallDepth = 1025
|
||||||
|
211
vm/vm.go
211
vm/vm.go
@ -769,27 +769,97 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
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)
|
var (
|
||||||
addStepGasUsage := func(amount *big.Int) {
|
gas = new(big.Int)
|
||||||
if amount.Cmp(ethutil.Big0) >= 0 {
|
newMemSize *big.Int = new(big.Int)
|
||||||
gas.Add(gas, amount)
|
)
|
||||||
}
|
baseCheck(op, stack, gas)
|
||||||
}
|
|
||||||
|
|
||||||
addStepGasUsage(GasStep)
|
|
||||||
|
|
||||||
var newMemSize *big.Int = ethutil.Big0
|
|
||||||
var additionalGas *big.Int = new(big.Int)
|
|
||||||
// Stack Check, memory resize & gas phase
|
// Stack Check, memory resize & gas phase
|
||||||
switch op {
|
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:
|
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
|
||||||
n := int(op - SWAP1 + 2)
|
n := int(op - SWAP1 + 2)
|
||||||
stack.require(n)
|
stack.require(n)
|
||||||
@ -800,112 +870,83 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
n := int(op - LOG0)
|
n := int(op - LOG0)
|
||||||
stack.require(n + 2)
|
stack.require(n + 2)
|
||||||
|
|
||||||
gas.Set(GasLog)
|
|
||||||
addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
|
|
||||||
|
|
||||||
mSize, mStart := stack.Peekn()
|
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)
|
newMemSize = calcMemSize(mStart, mSize)
|
||||||
case EXP:
|
case EXP:
|
||||||
stack.require(2)
|
gas.Add(gas, big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes())+1)))
|
||||||
|
|
||||||
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
|
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
stack.require(2)
|
stack.require(2)
|
||||||
|
|
||||||
var mult *big.Int
|
var g *big.Int
|
||||||
y, x := stack.Peekn()
|
y, x := stack.Peekn()
|
||||||
val := statedb.GetState(context.Address(), x.Bytes())
|
val := statedb.GetState(context.Address(), x.Bytes())
|
||||||
if len(val) == 0 && len(y.Bytes()) > 0 {
|
if len(val) == 0 && len(y.Bytes()) > 0 {
|
||||||
// 0 => non 0
|
// 0 => non 0
|
||||||
mult = ethutil.Big3
|
g = GasStorageAdd
|
||||||
} else if len(val) > 0 && len(y.Bytes()) == 0 {
|
} 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 {
|
} else {
|
||||||
// non 0 => non 0 (or 0 => 0)
|
// non 0 => non 0 (or 0 => 0)
|
||||||
mult = ethutil.Big1
|
g = GasStorageMod
|
||||||
}
|
}
|
||||||
gas.Set(new(big.Int).Mul(mult, GasSStore))
|
gas.Set(g)
|
||||||
case BALANCE:
|
|
||||||
stack.require(1)
|
|
||||||
gas.Set(GasBalance)
|
|
||||||
case MSTORE:
|
|
||||||
stack.require(2)
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
||||||
case MLOAD:
|
case MLOAD:
|
||||||
stack.require(1)
|
|
||||||
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
||||||
case MSTORE8:
|
case MSTORE8:
|
||||||
stack.require(2)
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), u256(1))
|
newMemSize = calcMemSize(stack.Peek(), u256(1))
|
||||||
case RETURN:
|
case RETURN:
|
||||||
stack.require(2)
|
|
||||||
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
||||||
case SHA3:
|
case SHA3:
|
||||||
stack.require(2)
|
|
||||||
gas.Set(GasSha)
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
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:
|
case CALLDATACOPY:
|
||||||
stack.require(3)
|
|
||||||
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-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:
|
case CODECOPY:
|
||||||
stack.require(3)
|
|
||||||
|
|
||||||
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-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])
|
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:
|
case CALL, CALLCODE:
|
||||||
stack.require(7)
|
gas.Add(gas, stack.data[stack.Len()-1])
|
||||||
gas.Set(GasCall)
|
|
||||||
addStepGasUsage(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])
|
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
|
||||||
y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
|
y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
|
||||||
|
|
||||||
newMemSize = ethutil.BigMax(x, y)
|
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])
|
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 {
|
if newMemSize.Cmp(ethutil.Big0) > 0 {
|
||||||
newMemSize.Add(newMemSize, u256(31))
|
newMemSize.Add(newMemSize, u256(31))
|
||||||
newMemSize.Div(newMemSize, u256(32))
|
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 {
|
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
|
||||||
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
|
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
|
||||||
memGasUsage.Mul(GasMemory, memGasUsage)
|
memGasUsage.Mul(GasMemWord, memGasUsage)
|
||||||
memGasUsage.Div(memGasUsage, u256(32))
|
memGasUsage.Div(memGasUsage, u256(32))
|
||||||
|
|
||||||
addStepGasUsage(memGasUsage)
|
gas.Add(gas, memGasUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user