forked from cerc-io/plugeth
quad mem
This commit is contained in:
parent
fe7ab662f0
commit
c1ef19bef9
@ -28,6 +28,8 @@ type Env struct {
|
|||||||
gasLimit *big.Int
|
gasLimit *big.Int
|
||||||
|
|
||||||
logs state.Logs
|
logs state.Logs
|
||||||
|
|
||||||
|
vmTest bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB) *Env {
|
func NewEnv(state *state.StateDB) *Env {
|
||||||
@ -92,20 +94,38 @@ func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Executi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *Env) Call(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
|
if self.vmTest && self.depth > 0 {
|
||||||
|
caller.ReturnGas(gas, price)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
ret, err := exe.Call(addr, caller)
|
ret, err := exe.Call(addr, caller)
|
||||||
self.Gas = exe.Gas
|
self.Gas = exe.Gas
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
|
|
||||||
}
|
}
|
||||||
func (self *Env) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
func (self *Env) CallCode(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
|
||||||
|
if self.vmTest && self.depth > 0 {
|
||||||
|
caller.ReturnGas(gas, price)
|
||||||
|
}
|
||||||
exe := self.vm(caller.Address(), data, gas, price, value)
|
exe := self.vm(caller.Address(), data, gas, price, value)
|
||||||
return exe.Call(addr, caller)
|
return exe.Call(addr, caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Env) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
func (self *Env) Create(caller vm.ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
|
||||||
exe := self.vm(addr, data, gas, price, value)
|
exe := self.vm(addr, data, gas, price, value)
|
||||||
|
if self.vmTest {
|
||||||
|
caller.ReturnGas(gas, price)
|
||||||
|
|
||||||
|
nonce := self.state.GetNonce(caller.Address())
|
||||||
|
obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))
|
||||||
|
|
||||||
|
return nil, nil, obj
|
||||||
|
} else {
|
||||||
return exe.Create(caller)
|
return exe.Create(caller)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
|
func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
|
||||||
@ -123,6 +143,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log
|
|||||||
caller := state.GetOrNewStateObject(from)
|
caller := state.GetOrNewStateObject(from)
|
||||||
|
|
||||||
vmenv := NewEnvFromMap(state, env, exec)
|
vmenv := NewEnvFromMap(state, env, exec)
|
||||||
|
vmenv.vmTest = true
|
||||||
vmenv.skipTransfer = true
|
vmenv.skipTransfer = true
|
||||||
vmenv.initial = true
|
vmenv.initial = true
|
||||||
ret, err := vmenv.Call(caller, to, data, gas, price, value)
|
ret, err := vmenv.Call(caller, to, data, gas, price, value)
|
||||||
|
@ -79,12 +79,10 @@ func RunVmTest(p string, t *testing.T) {
|
|||||||
helper.CreateFileTests(t, p, &tests)
|
helper.CreateFileTests(t, p, &tests)
|
||||||
|
|
||||||
for name, test := range tests {
|
for name, test := range tests {
|
||||||
/*
|
|
||||||
helper.Logger.SetLogLevel(4)
|
helper.Logger.SetLogLevel(4)
|
||||||
if name != "log1_nonEmptyMem_logMemSize1_logMemStart31" {
|
if name != "env1" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
statedb := state.New(nil, db)
|
statedb := state.New(nil, db)
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
|
@ -43,7 +43,7 @@ var (
|
|||||||
GasStorageMod = big.NewInt(5000)
|
GasStorageMod = big.NewInt(5000)
|
||||||
GasLogBase = big.NewInt(2000)
|
GasLogBase = big.NewInt(2000)
|
||||||
GasLogTopic = big.NewInt(2000)
|
GasLogTopic = big.NewInt(2000)
|
||||||
GasLogData = big.NewInt(8)
|
GasLogByte = big.NewInt(8)
|
||||||
GasCreate = big.NewInt(32000)
|
GasCreate = big.NewInt(32000)
|
||||||
GasCreateByte = big.NewInt(300)
|
GasCreateByte = big.NewInt(300)
|
||||||
GasCall = big.NewInt(40)
|
GasCall = big.NewInt(40)
|
||||||
@ -57,11 +57,13 @@ var (
|
|||||||
RefundSuicide = big.NewInt(24000)
|
RefundSuicide = big.NewInt(24000)
|
||||||
|
|
||||||
GasMemWord = big.NewInt(3)
|
GasMemWord = big.NewInt(3)
|
||||||
GasQuadCoeffWord = big.NewInt(1)
|
GasQuadCoeffDenom = big.NewInt(512)
|
||||||
GasContractByte = big.NewInt(200)
|
GasContractByte = big.NewInt(200)
|
||||||
GasTransaction = big.NewInt(21000)
|
GasTransaction = big.NewInt(21000)
|
||||||
GasTxDataNonzeroByte = big.NewInt(37)
|
GasTxDataNonzeroByte = big.NewInt(37)
|
||||||
GasTxZeroByte = big.NewInt(2)
|
GasTxZeroByte = big.NewInt(2)
|
||||||
|
GasExp = big.NewInt(10)
|
||||||
|
GasExpByte = big.NewInt(10)
|
||||||
|
|
||||||
GasSha3Base = big.NewInt(30)
|
GasSha3Base = big.NewInt(30)
|
||||||
GasSha3Word = big.NewInt(6)
|
GasSha3Word = big.NewInt(6)
|
||||||
|
30
vm/vm.go
30
vm/vm.go
@ -812,6 +812,7 @@ var _baseCheck = map[OpCode]req{
|
|||||||
COINBASE: {0, GasQuickStep},
|
COINBASE: {0, GasQuickStep},
|
||||||
TIMESTAMP: {0, GasQuickStep},
|
TIMESTAMP: {0, GasQuickStep},
|
||||||
NUMBER: {0, GasQuickStep},
|
NUMBER: {0, GasQuickStep},
|
||||||
|
CALLDATASIZE: {0, GasQuickStep},
|
||||||
DIFFICULTY: {0, GasQuickStep},
|
DIFFICULTY: {0, GasQuickStep},
|
||||||
GASLIMIT: {0, GasQuickStep},
|
GASLIMIT: {0, GasQuickStep},
|
||||||
POP: {0, GasQuickStep},
|
POP: {0, GasQuickStep},
|
||||||
@ -862,9 +863,11 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
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)
|
||||||
|
gas.Set(GasFastestStep)
|
||||||
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
||||||
n := int(op - DUP1 + 1)
|
n := int(op - DUP1 + 1)
|
||||||
stack.require(n)
|
stack.require(n)
|
||||||
|
gas.Set(GasFastestStep)
|
||||||
case LOG0, LOG1, LOG2, LOG3, LOG4:
|
case LOG0, LOG1, LOG2, LOG3, LOG4:
|
||||||
n := int(op - LOG0)
|
n := int(op - LOG0)
|
||||||
stack.require(n + 2)
|
stack.require(n + 2)
|
||||||
@ -873,11 +876,11 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
|
|
||||||
gas.Add(gas, GasLogBase)
|
gas.Add(gas, GasLogBase)
|
||||||
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
|
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
|
||||||
gas.Add(gas, new(big.Int).Mul(mSize, GasLogData))
|
gas.Add(gas, new(big.Int).Mul(mSize, GasLogByte))
|
||||||
|
|
||||||
newMemSize = calcMemSize(mStart, mSize)
|
newMemSize = calcMemSize(mStart, mSize)
|
||||||
case EXP:
|
case EXP:
|
||||||
gas.Add(gas, big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes())+1)))
|
gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()))), GasExpByte))
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
stack.require(2)
|
stack.require(2)
|
||||||
|
|
||||||
@ -935,7 +938,7 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
gas.Add(gas, GasCallNewAccount)
|
gas.Add(gas, GasCallNewAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(stack.data[stack.Len()].Bytes()) > 0 {
|
if len(stack.data[stack.Len()-1].Bytes()) > 0 {
|
||||||
gas.Add(gas, GasCallValueTransfer)
|
gas.Add(gas, GasCallValueTransfer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,11 +956,24 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
|
|||||||
newMemSize.Mul(newMemSize, u256(32))
|
newMemSize.Mul(newMemSize, u256(32))
|
||||||
|
|
||||||
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(GasMemWord, memGasUsage)
|
//memGasUsage.Mul(GasMemWord, memGasUsage)
|
||||||
memGasUsage.Div(memGasUsage, u256(32))
|
//memGasUsage.Div(memGasUsage, u256(32))
|
||||||
|
|
||||||
gas.Add(gas, memGasUsage)
|
//Old: full_memory_gas_cost = W + floor(W*W / 1024), W = words in memory
|
||||||
|
oldSize := toWordSize(big.NewInt(int64(mem.Len())))
|
||||||
|
linCoef := new(big.Int).Mul(oldSize, GasMemWord)
|
||||||
|
pow := new(big.Int)
|
||||||
|
pow.Exp(oldSize, ethutil.Big2, Zero)
|
||||||
|
quadCoef := new(big.Int).Div(pow, GasQuadCoeffDenom)
|
||||||
|
oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
||||||
|
|
||||||
|
linCoef = new(big.Int).Mul(newMemSize, GasMemWord)
|
||||||
|
pow.Exp(newMemSize, ethutil.Big2, Zero)
|
||||||
|
quadCoef = new(big.Int).Div(pow, GasQuadCoeffDenom)
|
||||||
|
newTotalFee := new(big.Int).Add(linCoef, quadCoef)
|
||||||
|
|
||||||
|
gas.Add(gas, new(big.Int).Sub(newTotalFee, oldTotalFee))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user