Implemented LOG. Closes #159

This commit is contained in:
obscuren
2014-10-27 11:44:16 +01:00
parent 6623500c6b
commit 272d58662c
15 changed files with 81 additions and 11 deletions

View File

@ -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)

View File

@ -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 {

9
vm/log.go Normal file
View File

@ -0,0 +1,9 @@
package vm
import "math/big"
type Log struct {
Address []byte
Topics []*big.Int
Data []byte
}

View File

@ -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)
}

View File

@ -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",

View File

@ -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())

View File

@ -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))