From 06aa74e7df49969fc181ecfcf5652263d74624f5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Oct 2014 10:14:55 +0200 Subject: [PATCH] All Stack requirements are now checked prior to reduring gas. --- vm/vm_debug.go | 56 +++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/vm/vm_debug.go b/vm/vm_debug.go index ba1781109f..fe004046c6 100644 --- a/vm/vm_debug.go +++ b/vm/vm_debug.go @@ -138,13 +138,31 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { addStepGasUsage(GasStep) var newMemSize *big.Int = ethutil.Big0 + // Stack Check, memory resize & gas phase 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: gas.Set(ethutil.Big0) case SUICIDE: + require(1) + gas.Set(ethutil.Big0) case SLOAD: gas.Set(GasSLoad) + // Memory resize & Gas case SSTORE: var mult *big.Int 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) case BALANCE: + require(1) gas.Set(GasBalance) case MSTORE: require(2) @@ -239,7 +258,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { switch op { // 0x20 range case ADD: - require(2) x, y := stack.Popn() 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 stack.Push(base) case SUB: - require(2) x, y := stack.Popn() 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 stack.Push(base) case MUL: - require(2) x, y := stack.Popn() 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 stack.Push(base) case DIV: - require(2) x, y := stack.Pop(), stack.Pop() 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 stack.Push(base) case SDIV: - require(2) x, y := S256(stack.Pop()), S256(stack.Pop()) self.Printf(" %v / %v", x, y) @@ -312,7 +326,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" = %v", base) stack.Push(base) case MOD: - require(2) x, y := stack.Pop(), stack.Pop() self.Printf(" %v %% %v", x, y) @@ -328,7 +341,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" = %v", base) stack.Push(base) case SMOD: - require(2) x, y := S256(stack.Pop()), S256(stack.Pop()) self.Printf(" %v %% %v", x, y) @@ -352,7 +364,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(base) case EXP: - require(2) x, y := stack.Popn() self.Printf(" %v ** %v", y, x) @@ -365,14 +376,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(base) case NEG: - require(1) base.Sub(Pow256, stack.Pop()) base = U256(base) stack.Push(base) case LT: - require(2) x, y := stack.Popn() self.Printf(" %v < %v", y, x) // x < y @@ -382,7 +391,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(ethutil.BigFalse) } case GT: - require(2) x, y := stack.Popn() self.Printf(" %v > %v", y, x) @@ -394,7 +402,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { } case SLT: - require(2) y, x := S256(stack.Pop()), S256(stack.Pop()) self.Printf(" %v < %v", y, x) // x < y @@ -404,7 +411,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(ethutil.BigFalse) } case SGT: - require(2) y, x := S256(stack.Pop()), S256(stack.Pop()) self.Printf(" %v > %v", y, x) @@ -416,7 +422,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { } case EQ: - require(2) x, y := stack.Popn() self.Printf(" %v == %v", y, x) @@ -427,7 +432,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(ethutil.BigFalse) } case NOT: - require(1) x := stack.Pop() if x.Cmp(ethutil.BigFalse) > 0 { stack.Push(ethutil.BigFalse) @@ -437,25 +441,21 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { // 0x10 range case AND: - require(2) x, y := stack.Popn() self.Printf(" %v & %v", y, x) stack.Push(base.And(y, x)) case OR: - require(2) x, y := stack.Popn() self.Printf(" %v | %v", y, x) stack.Push(base.Or(y, x)) case XOR: - require(2) x, y := stack.Popn() self.Printf(" %v ^ %v", y, x) stack.Push(base.Xor(y, x)) case BYTE: - require(2) val, th := stack.Popn() if th.Cmp(big.NewInt(32)) < 0 { @@ -470,7 +470,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(base) case ADDMOD: - require(3) x := stack.Pop() y := stack.Pop() @@ -485,7 +484,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(base) case MULMOD: - require(3) x := stack.Pop() y := stack.Pop() @@ -502,7 +500,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { // 0x20 range case SHA3: - require(2) size, offset := stack.Popn() 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()) case BALANCE: - require(1) addr := stack.Pop().Bytes() balance := state.GetBalance(addr) @@ -541,7 +537,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" => %v", value) case CALLDATALOAD: - require(1) var ( offset = stack.Pop() data = make([]byte, 32) @@ -675,7 +670,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" => 0x%x", data.Bytes()) case POP: - require(1) stack.Pop() case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 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()) case MLOAD: - require(1) offset := stack.Pop() val := ethutil.BigD(mem.Get(offset.Int64(), 32)) stack.Push(val) self.Printf(" => 0x%x", val.Bytes()) case MSTORE: // Store the value at stack top-1 in to memory at location stack top - require(2) // Pop value of the stack val, mStart := stack.Popn() mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256)) self.Printf(" => 0x%x", val) case MSTORE8: - require(2) off := 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) case SLOAD: - require(1) loc := stack.Pop() val := ethutil.BigD(state.GetState(closure.Address(), loc.Bytes())) stack.Push(val) self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) case SSTORE: - require(2) val, loc := stack.Popn() 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()) case JUMP: - require(1) jump(stack.Pop()) continue case JUMPI: - require(2) cond, pos := stack.Popn() if cond.Cmp(ethutil.BigTrue) >= 0 { @@ -756,7 +743,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { stack.Push(closure.Gas) // 0x60 range case CREATE: - require(3) var ( err error @@ -801,8 +787,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Dbg.SetCode(closure.Code) } case CALL, CALLCODE: - require(7) - self.Endl() gas := stack.Pop() @@ -842,7 +826,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { } case RETURN: - require(2) size, offset := stack.Popn() 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 case SUICIDE: - require(1) receiver := state.GetOrNewStateObject(stack.Pop().Bytes())