All Stack requirements are now checked prior to reduring gas.
This commit is contained in:
parent
29b8a0bc5f
commit
06aa74e7df
@ -138,13 +138,31 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
addStepGasUsage(GasStep)
|
addStepGasUsage(GasStep)
|
||||||
|
|
||||||
var newMemSize *big.Int = ethutil.Big0
|
var newMemSize *big.Int = ethutil.Big0
|
||||||
|
// Stack Check, memory resize & gas phase
|
||||||
switch op {
|
switch op {
|
||||||
|
// Stack checks only
|
||||||
|
case NOT, CALLDATALOAD, POP, JUMP, NEG: // 1
|
||||||
|
require(1)
|
||||||
|
case ADD, SUB, DIV, SDIV, MOD, SMOD, EXP, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE: // 2
|
||||||
|
require(2)
|
||||||
|
case ADDMOD, MULMOD: // 3
|
||||||
|
require(3)
|
||||||
|
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
|
||||||
|
n := int(op - SWAP1 + 2)
|
||||||
|
require(n)
|
||||||
|
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
||||||
|
n := int(op - DUP1 + 1)
|
||||||
|
require(n)
|
||||||
|
// Gas only
|
||||||
case STOP:
|
case STOP:
|
||||||
gas.Set(ethutil.Big0)
|
gas.Set(ethutil.Big0)
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
|
require(1)
|
||||||
|
|
||||||
gas.Set(ethutil.Big0)
|
gas.Set(ethutil.Big0)
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
gas.Set(GasSLoad)
|
gas.Set(GasSLoad)
|
||||||
|
// Memory resize & Gas
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
var mult *big.Int
|
var mult *big.Int
|
||||||
y, x := stack.Peekn()
|
y, x := stack.Peekn()
|
||||||
@ -158,6 +176,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
}
|
}
|
||||||
gas = new(big.Int).Mul(mult, GasSStore)
|
gas = new(big.Int).Mul(mult, GasSStore)
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
|
require(1)
|
||||||
gas.Set(GasBalance)
|
gas.Set(GasBalance)
|
||||||
case MSTORE:
|
case MSTORE:
|
||||||
require(2)
|
require(2)
|
||||||
@ -239,7 +258,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
switch op {
|
switch op {
|
||||||
// 0x20 range
|
// 0x20 range
|
||||||
case ADD:
|
case ADD:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v + %v", y, x)
|
self.Printf(" %v + %v", y, x)
|
||||||
|
|
||||||
@ -251,7 +269,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SUB:
|
case SUB:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v - %v", y, x)
|
self.Printf(" %v - %v", y, x)
|
||||||
|
|
||||||
@ -263,7 +280,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case MUL:
|
case MUL:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v * %v", y, x)
|
self.Printf(" %v * %v", y, x)
|
||||||
|
|
||||||
@ -275,7 +291,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case DIV:
|
case DIV:
|
||||||
require(2)
|
|
||||||
x, y := stack.Pop(), stack.Pop()
|
x, y := stack.Pop(), stack.Pop()
|
||||||
self.Printf(" %v / %v", x, y)
|
self.Printf(" %v / %v", x, y)
|
||||||
|
|
||||||
@ -289,7 +304,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
// Pop result back on the stack
|
// Pop result back on the stack
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SDIV:
|
case SDIV:
|
||||||
require(2)
|
|
||||||
x, y := S256(stack.Pop()), S256(stack.Pop())
|
x, y := S256(stack.Pop()), S256(stack.Pop())
|
||||||
|
|
||||||
self.Printf(" %v / %v", x, y)
|
self.Printf(" %v / %v", x, y)
|
||||||
@ -312,7 +326,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
self.Printf(" = %v", base)
|
self.Printf(" = %v", base)
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case MOD:
|
case MOD:
|
||||||
require(2)
|
|
||||||
x, y := stack.Pop(), stack.Pop()
|
x, y := stack.Pop(), stack.Pop()
|
||||||
|
|
||||||
self.Printf(" %v %% %v", x, y)
|
self.Printf(" %v %% %v", x, y)
|
||||||
@ -328,7 +341,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
self.Printf(" = %v", base)
|
self.Printf(" = %v", base)
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case SMOD:
|
case SMOD:
|
||||||
require(2)
|
|
||||||
x, y := S256(stack.Pop()), S256(stack.Pop())
|
x, y := S256(stack.Pop()), S256(stack.Pop())
|
||||||
|
|
||||||
self.Printf(" %v %% %v", x, y)
|
self.Printf(" %v %% %v", x, y)
|
||||||
@ -352,7 +364,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
|
|
||||||
case EXP:
|
case EXP:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
|
|
||||||
self.Printf(" %v ** %v", y, x)
|
self.Printf(" %v ** %v", y, x)
|
||||||
@ -365,14 +376,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case NEG:
|
case NEG:
|
||||||
require(1)
|
|
||||||
base.Sub(Pow256, stack.Pop())
|
base.Sub(Pow256, stack.Pop())
|
||||||
|
|
||||||
base = U256(base)
|
base = U256(base)
|
||||||
|
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case LT:
|
case LT:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v < %v", y, x)
|
self.Printf(" %v < %v", y, x)
|
||||||
// x < y
|
// x < y
|
||||||
@ -382,7 +391,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
}
|
}
|
||||||
case GT:
|
case GT:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v > %v", y, x)
|
self.Printf(" %v > %v", y, x)
|
||||||
|
|
||||||
@ -394,7 +402,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SLT:
|
case SLT:
|
||||||
require(2)
|
|
||||||
y, x := S256(stack.Pop()), S256(stack.Pop())
|
y, x := S256(stack.Pop()), S256(stack.Pop())
|
||||||
self.Printf(" %v < %v", y, x)
|
self.Printf(" %v < %v", y, x)
|
||||||
// x < y
|
// x < y
|
||||||
@ -404,7 +411,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
}
|
}
|
||||||
case SGT:
|
case SGT:
|
||||||
require(2)
|
|
||||||
y, x := S256(stack.Pop()), S256(stack.Pop())
|
y, x := S256(stack.Pop()), S256(stack.Pop())
|
||||||
self.Printf(" %v > %v", y, x)
|
self.Printf(" %v > %v", y, x)
|
||||||
|
|
||||||
@ -416,7 +422,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EQ:
|
case EQ:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v == %v", y, x)
|
self.Printf(" %v == %v", y, x)
|
||||||
|
|
||||||
@ -427,7 +432,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
}
|
}
|
||||||
case NOT:
|
case NOT:
|
||||||
require(1)
|
|
||||||
x := stack.Pop()
|
x := stack.Pop()
|
||||||
if x.Cmp(ethutil.BigFalse) > 0 {
|
if x.Cmp(ethutil.BigFalse) > 0 {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
@ -437,25 +441,21 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
// 0x10 range
|
// 0x10 range
|
||||||
case AND:
|
case AND:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v & %v", y, x)
|
self.Printf(" %v & %v", y, x)
|
||||||
|
|
||||||
stack.Push(base.And(y, x))
|
stack.Push(base.And(y, x))
|
||||||
case OR:
|
case OR:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v | %v", y, x)
|
self.Printf(" %v | %v", y, x)
|
||||||
|
|
||||||
stack.Push(base.Or(y, x))
|
stack.Push(base.Or(y, x))
|
||||||
case XOR:
|
case XOR:
|
||||||
require(2)
|
|
||||||
x, y := stack.Popn()
|
x, y := stack.Popn()
|
||||||
self.Printf(" %v ^ %v", y, x)
|
self.Printf(" %v ^ %v", y, x)
|
||||||
|
|
||||||
stack.Push(base.Xor(y, x))
|
stack.Push(base.Xor(y, x))
|
||||||
case BYTE:
|
case BYTE:
|
||||||
require(2)
|
|
||||||
val, th := stack.Popn()
|
val, th := stack.Popn()
|
||||||
|
|
||||||
if th.Cmp(big.NewInt(32)) < 0 {
|
if th.Cmp(big.NewInt(32)) < 0 {
|
||||||
@ -470,7 +470,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case ADDMOD:
|
case ADDMOD:
|
||||||
require(3)
|
|
||||||
|
|
||||||
x := stack.Pop()
|
x := stack.Pop()
|
||||||
y := stack.Pop()
|
y := stack.Pop()
|
||||||
@ -485,7 +484,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
stack.Push(base)
|
stack.Push(base)
|
||||||
case MULMOD:
|
case MULMOD:
|
||||||
require(3)
|
|
||||||
|
|
||||||
x := stack.Pop()
|
x := stack.Pop()
|
||||||
y := stack.Pop()
|
y := stack.Pop()
|
||||||
@ -502,7 +500,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
// 0x20 range
|
// 0x20 range
|
||||||
case SHA3:
|
case SHA3:
|
||||||
require(2)
|
|
||||||
size, offset := stack.Popn()
|
size, offset := stack.Popn()
|
||||||
data := ethcrypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
|
data := ethcrypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
|
||||||
|
|
||||||
@ -515,7 +512,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" => %x", closure.Address())
|
self.Printf(" => %x", closure.Address())
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
require(1)
|
|
||||||
|
|
||||||
addr := stack.Pop().Bytes()
|
addr := stack.Pop().Bytes()
|
||||||
balance := state.GetBalance(addr)
|
balance := state.GetBalance(addr)
|
||||||
@ -541,7 +537,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" => %v", value)
|
self.Printf(" => %v", value)
|
||||||
case CALLDATALOAD:
|
case CALLDATALOAD:
|
||||||
require(1)
|
|
||||||
var (
|
var (
|
||||||
offset = stack.Pop()
|
offset = stack.Pop()
|
||||||
data = make([]byte, 32)
|
data = make([]byte, 32)
|
||||||
@ -675,7 +670,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" => 0x%x", data.Bytes())
|
self.Printf(" => 0x%x", data.Bytes())
|
||||||
case POP:
|
case POP:
|
||||||
require(1)
|
|
||||||
stack.Pop()
|
stack.Pop()
|
||||||
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)
|
||||||
@ -692,21 +686,18 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
|
self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
|
||||||
case MLOAD:
|
case MLOAD:
|
||||||
require(1)
|
|
||||||
offset := stack.Pop()
|
offset := stack.Pop()
|
||||||
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
||||||
stack.Push(val)
|
stack.Push(val)
|
||||||
|
|
||||||
self.Printf(" => 0x%x", val.Bytes())
|
self.Printf(" => 0x%x", val.Bytes())
|
||||||
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
|
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
|
||||||
require(2)
|
|
||||||
// Pop value of the stack
|
// Pop value of the stack
|
||||||
val, mStart := stack.Popn()
|
val, mStart := stack.Popn()
|
||||||
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
|
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
|
||||||
|
|
||||||
self.Printf(" => 0x%x", val)
|
self.Printf(" => 0x%x", val)
|
||||||
case MSTORE8:
|
case MSTORE8:
|
||||||
require(2)
|
|
||||||
off := stack.Pop()
|
off := stack.Pop()
|
||||||
val := stack.Pop()
|
val := stack.Pop()
|
||||||
|
|
||||||
@ -714,14 +705,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" => [%v] 0x%x", off, val)
|
self.Printf(" => [%v] 0x%x", off, val)
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
require(1)
|
|
||||||
loc := stack.Pop()
|
loc := stack.Pop()
|
||||||
val := ethutil.BigD(state.GetState(closure.Address(), loc.Bytes()))
|
val := ethutil.BigD(state.GetState(closure.Address(), loc.Bytes()))
|
||||||
stack.Push(val)
|
stack.Push(val)
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case SSTORE:
|
case SSTORE:
|
||||||
require(2)
|
|
||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
state.SetState(closure.Address(), loc.Bytes(), val)
|
state.SetState(closure.Address(), loc.Bytes(), val)
|
||||||
|
|
||||||
@ -732,13 +721,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case JUMP:
|
case JUMP:
|
||||||
require(1)
|
|
||||||
|
|
||||||
jump(stack.Pop())
|
jump(stack.Pop())
|
||||||
|
|
||||||
continue
|
continue
|
||||||
case JUMPI:
|
case JUMPI:
|
||||||
require(2)
|
|
||||||
cond, pos := stack.Popn()
|
cond, pos := stack.Popn()
|
||||||
|
|
||||||
if cond.Cmp(ethutil.BigTrue) >= 0 {
|
if cond.Cmp(ethutil.BigTrue) >= 0 {
|
||||||
@ -756,7 +743,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
stack.Push(closure.Gas)
|
stack.Push(closure.Gas)
|
||||||
// 0x60 range
|
// 0x60 range
|
||||||
case CREATE:
|
case CREATE:
|
||||||
require(3)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
@ -801,8 +787,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
self.Dbg.SetCode(closure.Code)
|
self.Dbg.SetCode(closure.Code)
|
||||||
}
|
}
|
||||||
case CALL, CALLCODE:
|
case CALL, CALLCODE:
|
||||||
require(7)
|
|
||||||
|
|
||||||
self.Endl()
|
self.Endl()
|
||||||
|
|
||||||
gas := stack.Pop()
|
gas := stack.Pop()
|
||||||
@ -842,7 +826,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
require(2)
|
|
||||||
size, offset := stack.Popn()
|
size, offset := stack.Popn()
|
||||||
ret := mem.Get(offset.Int64(), size.Int64())
|
ret := mem.Get(offset.Int64(), size.Int64())
|
||||||
|
|
||||||
@ -850,7 +833,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|||||||
|
|
||||||
return closure.Return(ret), nil
|
return closure.Return(ret), nil
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
require(1)
|
|
||||||
|
|
||||||
receiver := state.GetOrNewStateObject(stack.Pop().Bytes())
|
receiver := state.GetOrNewStateObject(stack.Pop().Bytes())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user