From f76cc6699ecd995d78cfd980b229473101191137 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Fri, 13 Mar 2015 13:44:15 +0100
Subject: [PATCH] Changed context and ADDMOD, MULMOD

* Cleaned up VM execution. VM run now takes a context
* ADDMOD/MULMOD - removed incorrect cast
---
 core/execution.go     |  6 +++++-
 tests/vm/gh_test.go   |  2 +-
 vm/common.go          |  8 ++++++++
 vm/context.go         | 25 +++++++++++++++----------
 vm/virtual_machine.go |  4 +---
 vm/vm.go              | 23 ++++++++++++++---------
 6 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/core/execution.go b/core/execution.go
index 8f2b5bee1..be45eeeb4 100644
--- a/core/execution.go
+++ b/core/execution.go
@@ -59,7 +59,11 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ContextRef) (ret
 
 	snapshot := env.State().Copy()
 	start := time.Now()
-	ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input)
+
+	context := vm.NewContext(caller, to, self.value, self.Gas, self.price)
+	context.SetCallCode(contextAddr, code)
+
+	ret, err = evm.Run(context, self.input) //self.value, self.Gas, self.price, self.input)
 	chainlogger.Debugf("vm took %v\n", time.Since(start))
 	if err != nil {
 		env.State().Set(snapshot)
diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go
index 959f20463..1e8cd5b51 100644
--- a/tests/vm/gh_test.go
+++ b/tests/vm/gh_test.go
@@ -116,7 +116,6 @@ func RunVmTest(p string, t *testing.T) {
 		} else {
 			ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction)
 		}
-		statedb.Sync()
 
 		rexp := helper.FromHex(test.Out)
 		if bytes.Compare(rexp, ret) != 0 {
@@ -157,6 +156,7 @@ func RunVmTest(p string, t *testing.T) {
 		}
 
 		if !isVmTest {
+			statedb.Sync()
 			if !bytes.Equal(ethutil.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
 				t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
 			}
diff --git a/vm/common.go b/vm/common.go
index b391bb8c2..1cb549228 100644
--- a/vm/common.go
+++ b/vm/common.go
@@ -1,6 +1,7 @@
 package vm
 
 import (
+	"math"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/ethutil"
@@ -117,3 +118,10 @@ func toValue(val *big.Int) interface{} {
 
 	return val
 }
+
+func getCode(code []byte, start, size uint64) []byte {
+	x := uint64(math.Min(float64(start), float64(len(code))))
+	y := uint64(math.Min(float64(x+size), float64(len(code))))
+
+	return ethutil.RightPadBytes(code[x:y], int(size))
+}
diff --git a/vm/context.go b/vm/context.go
index 9ce07bc4a..78712f561 100644
--- a/vm/context.go
+++ b/vm/context.go
@@ -15,21 +15,24 @@ type ContextRef interface {
 
 type Context struct {
 	caller ContextRef
-	object ContextRef
-	Code   []byte
+	self   ContextRef
 
-	Gas, UsedGas, Price *big.Int
+	Code     []byte
+	CodeAddr []byte
+
+	value, Gas, UsedGas, Price *big.Int
 
 	Args []byte
 }
 
 // Create a new context for the given data items
-func NewContext(caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
-	c := &Context{caller: caller, object: object, Code: code, Args: nil}
+func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int) *Context {
+	c := &Context{caller: caller, self: object, Args: nil}
 
 	// Gas should be a pointer so it can safely be reduced through the run
 	// This pointer will be off the state transition
 	c.Gas = gas //new(big.Int).Set(gas)
+	c.value = new(big.Int).Set(value)
 	// In most cases price and value are pointers to transaction objects
 	// and we don't want the transaction's values to change.
 	c.Price = new(big.Int).Set(price)
@@ -62,10 +65,7 @@ func (c *Context) GetRangeValue(x, size uint64) []byte {
 }
 
 func (c *Context) GetCode(x, size uint64) []byte {
-	x = uint64(math.Min(float64(x), float64(len(c.Code))))
-	y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
-
-	return ethutil.RightPadBytes(c.Code[x:y], int(size))
+	return getCode(c.Code, x, size)
 }
 
 func (c *Context) Return(ret []byte) []byte {
@@ -101,9 +101,14 @@ func (c *Context) ReturnGas(gas, price *big.Int) {
  * Set / Get
  */
 func (c *Context) Address() []byte {
-	return c.object.Address()
+	return c.self.Address()
 }
 
 func (self *Context) SetCode(code []byte) {
 	self.Code = code
 }
+
+func (self *Context) SetCallCode(addr, code []byte) {
+	self.Code = code
+	self.CodeAddr = addr
+}
diff --git a/vm/virtual_machine.go b/vm/virtual_machine.go
index 23ac4878f..6db284f42 100644
--- a/vm/virtual_machine.go
+++ b/vm/virtual_machine.go
@@ -1,10 +1,8 @@
 package vm
 
-import "math/big"
-
 type VirtualMachine interface {
 	Env() Environment
-	Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, data []byte) ([]byte, error)
+	Run(context *Context, data []byte) ([]byte, error)
 	Printf(string, ...interface{}) VirtualMachine
 	Endl() VirtualMachine
 }
diff --git a/vm/vm.go b/vm/vm.go
index a818ac47d..58aebeedb 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -32,10 +32,17 @@ func New(env Environment) *Vm {
 	return &Vm{debug: Debug, env: env, logTy: lt, Recoverable: true}
 }
 
-func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
+func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
+	//func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
 	self.env.SetDepth(self.env.Depth() + 1)
 
-	context := NewContext(caller, me, code, gas, price)
+	//context := NewContext(caller, me, code, gas, price)
+	var (
+		caller = context.caller
+		code   = context.Code
+		value  = context.value
+		price  = context.Price
+	)
 
 	self.Printf("(%d) (%x) %x (code=%d) gas: %v (d) %x", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData).Endl()
 
@@ -55,7 +62,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 		}()
 	}
 
-	if p := Precompiled[string(me.Address())]; p != nil {
+	if p := Precompiled[string(context.CodeAddr)]; p != nil {
 		return self.RunPrecompiled(p, callData, context)
 	}
 
@@ -352,7 +359,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 			z := stack.pop()
 
 			if z.Cmp(Zero) > 0 {
-				add := U256(new(big.Int).Add(x, y))
+				add := new(big.Int).Add(x, y)
 				base.Mod(add, z)
 
 				base = U256(base)
@@ -362,13 +369,12 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 
 			stack.push(base)
 		case MULMOD:
-
 			x := stack.pop()
 			y := stack.pop()
 			z := stack.pop()
 
-			mul := new(big.Int).Mul(x, y)
-			if len(z.Bytes()) > 0 { // NOT 0x0
+			if z.Cmp(Zero) > 0 {
+				mul := new(big.Int).Mul(x, y)
 				base.Mod(mul, z)
 
 				U256(base)
@@ -476,13 +482,12 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 			} else {
 				code = context.Code
 			}
-			context := NewContext(nil, nil, code, ethutil.Big0, ethutil.Big0)
 			var (
 				mOff = stack.pop().Uint64()
 				cOff = stack.pop().Uint64()
 				l    = stack.pop().Uint64()
 			)
-			codeCopy := context.GetCode(cOff, l)
+			codeCopy := getCode(code, cOff, l)
 
 			mem.Set(mOff, l, codeCopy)
 
-- 
GitLab