aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
Diffstat (limited to 'vm')
-rw-r--r--vm/common.go23
-rw-r--r--vm/log.go33
-rw-r--r--vm/vm_debug.go11
-rw-r--r--vm/vm_test.go54
4 files changed, 86 insertions, 35 deletions
diff --git a/vm/common.go b/vm/common.go
index c73744506..16a0b5523 100644
--- a/vm/common.go
+++ b/vm/common.go
@@ -19,17 +19,18 @@ const (
)
var (
- GasStep = big.NewInt(1)
- GasSha = big.NewInt(20)
- GasSLoad = big.NewInt(20)
- GasSStore = big.NewInt(100)
- GasBalance = big.NewInt(20)
- GasCreate = big.NewInt(100)
- GasCall = big.NewInt(20)
- GasMemory = big.NewInt(1)
- GasData = big.NewInt(5)
- GasTx = big.NewInt(500)
- GasLog = big.NewInt(32)
+ GasStep = big.NewInt(1)
+ GasSha = big.NewInt(20)
+ GasSLoad = big.NewInt(20)
+ GasSStore = big.NewInt(100)
+ GasSStoreRefund = big.NewInt(100)
+ GasBalance = big.NewInt(20)
+ GasCreate = big.NewInt(100)
+ GasCall = big.NewInt(20)
+ 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/log.go b/vm/log.go
index 954d2ec91..bc72a0423 100644
--- a/vm/log.go
+++ b/vm/log.go
@@ -1,9 +1,38 @@
package vm
-import "math/big"
+import "github.com/ethereum/go-ethereum/ethutil"
type Log struct {
Address []byte
- Topics []*big.Int
+ Topics [][]byte
Data []byte
}
+
+func NewLogFromValue(decoder *ethutil.Value) Log {
+ log := Log{
+ Address: decoder.Get(0).Bytes(),
+ Data: decoder.Get(2).Bytes(),
+ }
+
+ it := decoder.Get(1).NewIterator()
+ for it.Next() {
+ log.Topics = append(log.Topics, it.Value().Bytes())
+ }
+
+ return log
+}
+
+func (self Log) RlpData() interface{} {
+ return []interface{}{self.Address, ethutil.ByteSliceToInterface(self.Topics), self.Data}
+}
+
+type Logs []Log
+
+func (self Logs) RlpData() interface{} {
+ data := make([]interface{}, len(self))
+ for i, log := range self {
+ data[i] = log.RlpData()
+ }
+
+ return data
+}
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 13446d6c0..b3fbfe341 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -169,9 +169,13 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
gas.Set(ethutil.Big0)
case SLOAD:
+ require(1)
+
gas.Set(GasSLoad)
// Memory resize & Gas
case SSTORE:
+ require(2)
+
var mult *big.Int
y, x := stack.Peekn()
val := closure.GetStorage(x)
@@ -179,7 +183,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
// 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))
+ state.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
+
mult = ethutil.Big0
} else {
// non 0 => non 0
@@ -699,11 +704,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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)
+ topics := make([][]byte, n)
mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64()
data := mem.Geti(mStart, mSize)
for i := 0; i < n; i++ {
- topics[i] = stack.Pop()
+ topics[i] = stack.Pop().Bytes()
}
self.env.AddLog(Log{closure.Address(), topics, data})
case MLOAD:
diff --git a/vm/vm_test.go b/vm/vm_test.go
index 84cca3a9d..8818cc8ec 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -14,22 +14,30 @@ import (
"github.com/ethereum/go-ethereum/ethstate"
"github.com/ethereum/go-ethereum/ethtrie"
"github.com/ethereum/go-ethereum/ethutil"
+ "github.com/obscuren/mutan"
)
-type TestEnv struct {
+type TestEnv struct{}
+
+func (TestEnv) Origin() []byte { return nil }
+func (TestEnv) BlockNumber() *big.Int { return nil }
+func (TestEnv) BlockHash() []byte { return nil }
+func (TestEnv) PrevHash() []byte { return nil }
+func (TestEnv) Coinbase() []byte { return nil }
+func (TestEnv) Time() int64 { return 0 }
+func (TestEnv) GasLimit() *big.Int { return nil }
+func (TestEnv) Difficulty() *big.Int { return nil }
+func (TestEnv) Value() *big.Int { return nil }
+func (TestEnv) AddLog(Log) {}
+
+func (TestEnv) Transfer(from, to Account, amount *big.Int) error {
+ return nil
}
-func (self TestEnv) Origin() []byte { return nil }
-func (self TestEnv) BlockNumber() *big.Int { return nil }
-func (self TestEnv) BlockHash() []byte { return nil }
-func (self TestEnv) PrevHash() []byte { return nil }
-func (self TestEnv) Coinbase() []byte { return nil }
-func (self TestEnv) Time() int64 { return 0 }
-func (self TestEnv) Difficulty() *big.Int { return nil }
-func (self TestEnv) Value() *big.Int { return nil }
-
// This is likely to fail if anything ever gets looked up in the state trie :-)
-func (self TestEnv) State() *ethstate.State { return ethstate.New(ethtrie.New(nil, "")) }
+func (TestEnv) State() *ethstate.State {
+ return ethstate.New(ethtrie.New(nil, ""))
+}
const mutcode = `
var x = 0;
@@ -56,27 +64,35 @@ func setup(level ethlog.LogLevel, typ Type) (*Closure, VirtualMachine) {
return callerClosure, New(TestEnv{}, typ)
}
+var big9 = ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000009")
+
func TestDebugVm(t *testing.T) {
+ if mutan.Version < "0.6" {
+ t.Skip("skipping for mutan version", mutan.Version, " < 0.6")
+ }
+
closure, vm := setup(ethlog.DebugLevel, DebugVmTy)
ret, _, e := closure.Call(vm, nil)
if e != nil {
- fmt.Println("error", e)
+ t.Fatalf("Call returned error: %v", e)
}
-
- if ret[len(ret)-1] != 9 {
- t.Errorf("Expected VM to return 9, got", ret, "instead.")
+ if !bytes.Equal(ret, big9) {
+ t.Errorf("Wrong return value '%x', want '%x'", ret, big9)
}
}
func TestVm(t *testing.T) {
+ if mutan.Version < "0.6" {
+ t.Skip("skipping for mutan version", mutan.Version, " < 0.6")
+ }
+
closure, vm := setup(ethlog.DebugLevel, StandardVmTy)
ret, _, e := closure.Call(vm, nil)
if e != nil {
- fmt.Println("error", e)
+ t.Fatalf("Call returned error: %v", e)
}
-
- if ret[len(ret)-1] != 9 {
- t.Errorf("Expected VM to return 9, got", ret, "instead.")
+ if !bytes.Equal(ret, big9) {
+ t.Errorf("Wrong return value '%x', want '%x'", ret, big9)
}
}