diff options
Diffstat (limited to 'vm')
-rw-r--r-- | vm/common.go | 1 | ||||
-rw-r--r-- | vm/environment.go | 1 | ||||
-rw-r--r-- | vm/log.go | 9 | ||||
-rw-r--r-- | vm/stack.go | 12 | ||||
-rw-r--r-- | vm/types.go | 10 | ||||
-rw-r--r-- | vm/vm.go | 2 | ||||
-rw-r--r-- | vm/vm_debug.go | 33 |
7 files changed, 59 insertions, 9 deletions
diff --git a/vm/common.go b/vm/common.go index 3b0d735ba..c73744506 100644 --- a/vm/common.go +++ b/vm/common.go @@ -29,6 +29,7 @@ var ( GasMemory = big.NewInt(1) GasData = big.NewInt(5) GasTx = big.NewInt(500) + GasLog = big.NewInt(32) Pow256 = ethutil.BigPow(2, 256) diff --git a/vm/environment.go b/vm/environment.go index af67c4179..b8013856e 100644 --- a/vm/environment.go +++ b/vm/environment.go @@ -20,6 +20,7 @@ type Environment interface { BlockHash() []byte GasLimit() *big.Int Transfer(from, to Account, amount *big.Int) error + AddLog(Log) } type Object interface { diff --git a/vm/log.go b/vm/log.go new file mode 100644 index 000000000..954d2ec91 --- /dev/null +++ b/vm/log.go @@ -0,0 +1,9 @@ +package vm + +import "math/big" + +type Log struct { + Address []byte + Topics []*big.Int + Data []byte +} diff --git a/vm/stack.go b/vm/stack.go index 55fdb6d15..69ded6562 100644 --- a/vm/stack.go +++ b/vm/stack.go @@ -139,6 +139,18 @@ func (m *Memory) Get(offset, size int64) []byte { return nil } +func (self *Memory) Geti(offset, size int64) (cpy []byte) { + if len(self.store) > int(offset) { + s := int64(math.Min(float64(len(self.store)), float64(offset+size))) + cpy = make([]byte, size) + copy(cpy, self.store[offset:offset+s]) + + return + } + + return +} + func (m *Memory) Len() int { return len(m.store) } diff --git a/vm/types.go b/vm/types.go index 6fb9a5c95..53178fa43 100644 --- a/vm/types.go +++ b/vm/types.go @@ -18,7 +18,7 @@ const ( MOD = 0x06 SMOD = 0x07 EXP = 0x08 - NEG = 0x09 + BNOT = 0x09 LT = 0x0a GT = 0x0b SLT = 0x0c @@ -144,6 +144,12 @@ const ( SWAP15 = 0x9e SWAP16 = 0x9f + LOG0 = 0xa0 + LOG1 = 0xa1 + LOG2 = 0xa2 + LOG3 = 0xa3 + LOG4 = 0xa4 + // 0xf0 range - closures CREATE = 0xf0 CALL = 0xf1 @@ -166,7 +172,7 @@ var opCodeToString = map[OpCode]string{ MOD: "MOD", SMOD: "SMOD", EXP: "EXP", - NEG: "NEG", + BNOT: "BNOT", LT: "LT", GT: "GT", SLT: "SLT", @@ -268,7 +268,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { U256(base) stack.Push(base) - case NEG: + case BNOT: require(1) base.Sub(Pow256, stack.Pop()) diff --git a/vm/vm_debug.go b/vm/vm_debug.go index a30339e2b..13446d6c0 100644 --- a/vm/vm_debug.go +++ b/vm/vm_debug.go @@ -141,7 +141,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { // Stack Check, memory resize & gas phase switch op { // Stack checks only - case NOT, CALLDATALOAD, POP, JUMP, NEG: // 1 + case NOT, CALLDATALOAD, POP, JUMP, BNOT: // 1 require(1) case ADD, SUB, DIV, SDIV, MOD, SMOD, EXP, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE: // 2 require(2) @@ -153,6 +153,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: n := int(op - DUP1 + 1) require(n) + case LOG0, LOG1, LOG2, LOG3, LOG4: + n := int(op - LOG0) + require(n + 2) + + mSize, mStart := stack.Peekn() + gas.Set(GasLog) + addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog)) + addStepGasUsage(new(big.Int).Add(mSize, mStart)) // Gas only case STOP: gas.Set(ethutil.Big0) @@ -168,13 +176,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { y, x := stack.Peekn() val := closure.GetStorage(x) if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 { - mult = ethutil.Big2 + // 0 => non 0 + mult = ethutil.Big3 } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 { + //state.AddBalance(closure.caller.Address(), new(big.Int).Mul(big.NewInt(100), closure.Price)) mult = ethutil.Big0 } else { + // non 0 => non 0 mult = ethutil.Big1 } - gas = new(big.Int).Mul(mult, GasSStore) + gas.Set(new(big.Int).Mul(mult, GasSStore)) case BALANCE: require(1) gas.Set(GasBalance) @@ -375,10 +386,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" = %v", base) stack.Push(base) - case NEG: - base.Sub(Pow256, stack.Pop()) + case BNOT: + base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1) - base = U256(base) + // Not needed + //base = U256(base) stack.Push(base) case LT: @@ -685,6 +697,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { x, y := stack.Swapn(n) self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes()) + case LOG0, LOG1, LOG2, LOG3, LOG4: + n := int(op - LOG0) + topics := make([]*big.Int, n) + mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64() + data := mem.Geti(mStart, mSize) + for i := 0; i < n; i++ { + topics[i] = stack.Pop() + } + self.env.AddLog(Log{closure.Address(), topics, data}) case MLOAD: offset := stack.Pop() val := ethutil.BigD(mem.Get(offset.Int64(), 32)) |