From d9d4f63cd4e3c9388ea8425e9d41f63af030c77c Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Fri, 22 Aug 2014 17:57:33 +0200
Subject: Don't add ...

---
 ethvm/vm.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 873a80c44..347ebcfe6 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -631,12 +631,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			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)
+			n := int(op - DUP1)
 			stack.Dupn(n)
 
 			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
 		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
-			n := int(op - SWAP1 + 1)
+			n := int(op - SWAP1)
 			x, y := stack.Swapn(n)
 
 			self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
-- 
cgit v1.2.3


From 3f904bf3acb5779f68834ebca95825ea1990f85b Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Mon, 25 Aug 2014 11:29:42 +0200
Subject: Implemented POST

---
 ethvm/vm.go | 261 ++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 191 insertions(+), 70 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 347ebcfe6..924a861ca 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -1,6 +1,7 @@
 package ethvm
 
 import (
+	"container/list"
 	"fmt"
 	"math"
 	"math/big"
@@ -18,11 +19,6 @@ type Debugger interface {
 }
 
 type Vm struct {
-	// Stack for processing contracts
-	stack *Stack
-	// non-persistent key/value memory storage
-	mem map[string]*big.Int
-
 	env Environment
 
 	Verbose bool
@@ -40,6 +36,8 @@ type Vm struct {
 	Fn          string
 
 	Recoverable bool
+
+	queue *list.List
 }
 
 type Environment interface {
@@ -66,7 +64,7 @@ func New(env Environment) *Vm {
 		lt = LogTyDiff
 	}
 
-	return &Vm{env: env, logTy: lt, Recoverable: true}
+	return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()}
 }
 
 func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
@@ -215,6 +213,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			newMemSize = stack.data[stack.Len()-2].Uint64() + stack.data[stack.Len()-3].Uint64()
 		}
 
+		// BUG This will break on overflows. https://github.com/ethereum/eth-go/issues/47
 		newMemSize = (newMemSize + 31) / 32 * 32
 		if newMemSize > uint64(mem.Len()) {
 			m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
@@ -711,6 +710,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 				err          error
 				value        = stack.Pop()
 				size, offset = stack.Popn()
+				input        = mem.Get(offset.Int64(), size.Int64())
+				gas          = new(big.Int).Set(closure.Gas)
 
 				// Snapshot the current stack so we are able to
 				// revert back to it later.
@@ -726,37 +727,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 			self.Printf(" (*) %x", addr).Endl()
 
-			msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
-				To: addr, From: closure.Address(),
-				Origin: self.env.Origin(),
-				Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
-				Value: value,
-			})
-
-			// Create a new contract
-			contract := self.env.State().NewStateObject(addr)
-			if contract.Balance.Cmp(value) >= 0 {
-				closure.object.SubAmount(value)
-				contract.AddAmount(value)
-
-				// Set the init script
-				initCode := mem.Get(offset.Int64(), size.Int64())
-				msg.Input = initCode
-
-				// Transfer all remaining gas to the new
-				// contract so it may run the init script
-				gas := new(big.Int).Set(closure.Gas)
-				closure.UseGas(closure.Gas)
-
-				// Create the closure
-				c := NewClosure(msg, closure, contract, initCode, gas, closure.Price)
-				// Call the closure and set the return value as
-				// main script.
-				contract.Code, _, err = c.Call(self, nil)
-			} else {
-				err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
-			}
+			closure.UseGas(closure.Gas)
 
+			msg := NewMessage(self, addr, input, gas, closure.Price, value)
+			ret, err := msg.Exec(closure)
 			if err != nil {
 				stack.Push(ethutil.BigFalse)
 
@@ -765,10 +739,55 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 				self.Printf("CREATE err %v", err)
 			} else {
-				stack.Push(ethutil.BigD(addr))
+				msg.object.Code = ret
 
-				msg.Output = contract.Code
+				stack.Push(ethutil.BigD(addr))
 			}
+			/*
+					msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
+						To: addr, From: closure.Address(),
+						Origin: self.env.Origin(),
+						Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
+						Value: value,
+					})
+
+					// Create a new contract
+					contract := self.env.State().NewStateObject(addr)
+					if contract.Balance.Cmp(value) >= 0 {
+						closure.object.SubAmount(value)
+						contract.AddAmount(value)
+
+						// Set the init script
+						initCode := mem.Get(offset.Int64(), size.Int64())
+						msg.Input = initCode
+
+						// Transfer all remaining gas to the new
+						// contract so it may run the init script
+						gas := new(big.Int).Set(closure.Gas)
+						closure.UseGas(closure.Gas)
+
+						// Create the closure
+						c := NewClosure(msg, closure, contract, initCode, gas, closure.Price)
+						// Call the closure and set the return value as
+						// main script.
+						contract.Code, _, err = c.Call(self, nil)
+					} else {
+						err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
+					}
+
+				if err != nil {
+					stack.Push(ethutil.BigFalse)
+
+					// Revert the state as it was before.
+					self.env.State().Set(snapshot)
+
+					self.Printf("CREATE err %v", err)
+				} else {
+					stack.Push(ethutil.BigD(addr))
+
+					msg.Output = contract.Code
+				}
+			*/
 			self.Endl()
 
 			// Debug hook
@@ -791,51 +810,88 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			// Get the arguments from the memory
 			args := mem.Get(inOffset.Int64(), inSize.Int64())
 
-			msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
-				To: addr.Bytes(), From: closure.Address(),
-				Input:  args,
-				Origin: self.env.Origin(),
-				Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
-				Value: value,
-			})
-
-			if closure.object.Balance.Cmp(value) < 0 {
-				vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
-
-				closure.ReturnGas(gas, nil)
+			snapshot := self.env.State().Copy()
 
+			msg := NewMessage(self, addr.Bytes(), args, gas, closure.Price, value)
+			ret, err := msg.Exec(closure)
+			if err != nil {
 				stack.Push(ethutil.BigFalse)
+
+				self.env.State().Set(snapshot)
 			} else {
-				snapshot := self.env.State().Copy()
+				stack.Push(ethutil.BigTrue)
+
+				mem.Set(retOffset.Int64(), retSize.Int64(), ret)
+			}
+
+			// Debug hook
+			if self.Dbg != nil {
+				self.Dbg.SetCode(closure.Code)
+			}
 
-				stateObject := self.env.State().GetOrNewStateObject(addr.Bytes())
+			/*
+				msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
+					To: addr.Bytes(), From: closure.Address(),
+					Input:  args,
+					Origin: self.env.Origin(),
+					Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
+					Value: value,
+				})
 
-				closure.object.SubAmount(value)
-				stateObject.AddAmount(value)
+				if closure.object.Balance.Cmp(value) < 0 {
+					vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
+
+					closure.ReturnGas(gas, nil)
 
-				// Create a new callable closure
-				c := NewClosure(msg, closure, stateObject, stateObject.Code, gas, closure.Price)
-				// Executer the closure and get the return value (if any)
-				ret, _, err := c.Call(self, args)
-				if err != nil {
 					stack.Push(ethutil.BigFalse)
+				} else {
+					snapshot := self.env.State().Copy()
 
-					vmlogger.Debugf("Closure execution failed. %v\n", err)
+					stateObject := self.env.State().GetOrNewStateObject(addr.Bytes())
 
-					self.env.State().Set(snapshot)
-				} else {
-					stack.Push(ethutil.BigTrue)
+					closure.object.SubAmount(value)
+					stateObject.AddAmount(value)
 
-					mem.Set(retOffset.Int64(), retSize.Int64(), ret)
-				}
+					// Create a new callable closure
+					c := NewClosure(msg, closure, stateObject, stateObject.Code, gas, closure.Price)
+					// Executer the closure and get the return value (if any)
+					ret, _, err := c.Call(self, args)
+					if err != nil {
+						stack.Push(ethutil.BigFalse)
 
-				msg.Output = ret
+						vmlogger.Debugf("Closure execution failed. %v\n", err)
 
-				// Debug hook
-				if self.Dbg != nil {
-					self.Dbg.SetCode(closure.Code)
+						self.env.State().Set(snapshot)
+					} else {
+						stack.Push(ethutil.BigTrue)
+
+						mem.Set(retOffset.Int64(), retSize.Int64(), ret)
+					}
+
+					msg.Output = ret
+
+					// Debug hook
+					if self.Dbg != nil {
+						self.Dbg.SetCode(closure.Code)
+					}
 				}
-			}
+			*/
+		case POST:
+			require(6)
+
+			self.Endl()
+
+			gas := stack.Pop()
+			// Pop gas and value of the stack.
+			value, addr := stack.Popn()
+			// Pop input size and offset
+			inSize, inOffset := stack.Popn()
+			// Get the arguments from the memory
+			args := mem.Get(inOffset.Int64(), inSize.Int64())
+
+			msg := NewMessage(self, addr.Bytes(), args, gas, closure.Price, value)
+
+			msg.Postpone()
 		case RETURN:
 			require(2)
 			size, offset := stack.Popn()
@@ -887,6 +943,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 	}
 }
 
+func (self *Vm) Queue() *list.List {
+	return self.queue
+}
+
 func (self *Vm) Printf(format string, v ...interface{}) *Vm {
 	if self.Verbose && self.logTy == LogTyPretty {
 		self.logStr += fmt.Sprintf(format, v...)
@@ -918,3 +978,64 @@ func ensure256(x *big.Int) {
 		x.SetInt64(0)
 	}
 }
+
+type Message struct {
+	vm                *Vm
+	closure           *Closure
+	address, input    []byte
+	gas, price, value *big.Int
+	object            *ethstate.StateObject
+}
+
+func NewMessage(vm *Vm, address, input []byte, gas, gasPrice, value *big.Int) *Message {
+	return &Message{vm: vm, address: address, input: input, gas: gas, price: gasPrice, value: value}
+}
+
+func (self *Message) Postpone() {
+	self.vm.queue.PushBack(self)
+}
+
+func (self *Message) Exec(caller ClosureRef) (ret []byte, err error) {
+	queue := self.vm.queue
+	self.vm.queue = list.New()
+
+	defer func() {
+		if err == nil {
+			queue.PushBackList(self.vm.queue)
+		}
+
+		self.vm.queue = queue
+	}()
+
+	msg := self.vm.env.State().Manifest().AddMessage(&ethstate.Message{
+		To: self.address, From: caller.Address(),
+		Input:  self.input,
+		Origin: self.vm.env.Origin(),
+		Block:  self.vm.env.BlockHash(), Timestamp: self.vm.env.Time(), Coinbase: self.vm.env.Coinbase(), Number: self.vm.env.BlockNumber(),
+		Value: self.value,
+	})
+
+	object := caller.Object()
+	if object.Balance.Cmp(self.value) < 0 {
+		caller.ReturnGas(self.gas, self.price)
+
+		err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, object.Balance)
+	} else {
+		stateObject := self.vm.env.State().GetOrNewStateObject(self.address)
+		self.object = stateObject
+
+		caller.Object().SubAmount(self.value)
+		stateObject.AddAmount(self.value)
+
+		// Create a new callable closure
+		c := NewClosure(msg, caller, object, object.Code, self.gas, self.price)
+		// Executer the closure and get the return value (if any)
+		ret, _, err = c.Call(self.vm, self.input)
+
+		msg.Output = ret
+
+		return ret, err
+	}
+
+	return
+}
-- 
cgit v1.2.3


From a63b74e345e83d08b7a85b0602c5087ca4b06075 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Mon, 8 Sep 2014 00:49:25 +0200
Subject: New OPCODES

* EXT- CODECOPY, CODESIZE
---
 ethvm/vm.go | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 924a861ca..2acf52f92 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -197,6 +197,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			require(3)
 
 			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
+		case EXTCODECOPY:
+			require(4)
+
+			newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64()
 		case CALL:
 			require(7)
 			gas.Set(GasCall)
@@ -550,14 +554,32 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			code := closure.Args[cOff : cOff+l]
 
 			mem.Set(mOff, l, code)
-		case CODESIZE:
-			l := big.NewInt(int64(len(closure.Code)))
+		case CODESIZE, EXTCODESIZE:
+			var code []byte
+			if op == EXTCODECOPY {
+				addr := stack.Pop().Bytes()
+
+				code = self.env.State().GetCode(addr)
+			} else {
+				code = closure.Code
+			}
+
+			l := big.NewInt(int64(len(code)))
 			stack.Push(l)
 
 			self.Printf(" => %d", l)
-		case CODECOPY:
+		case CODECOPY, EXTCODECOPY:
+			var code []byte
+			if op == EXTCODECOPY {
+				addr := stack.Pop().Bytes()
+
+				code = self.env.State().GetCode(addr)
+			} else {
+				code = closure.Code
+			}
+
 			var (
-				size = int64(len(closure.Code))
+				size = int64(len(code))
 				mOff = stack.Pop().Int64()
 				cOff = stack.Pop().Int64()
 				l    = stack.Pop().Int64()
@@ -570,9 +592,9 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 				l = 0
 			}
 
-			code := closure.Code[cOff : cOff+l]
+			codeCopy := code[cOff : cOff+l]
 
-			mem.Set(mOff, l, code)
+			mem.Set(mOff, l, codeCopy)
 		case GASPRICE:
 			stack.Push(closure.Price)
 
-- 
cgit v1.2.3


From 29499900160cc2ee88968b74035f0a5c2d4c5af6 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Wed, 10 Sep 2014 00:19:20 +0200
Subject: Added CALLSTATELESS

---
 ethvm/vm.go | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 2acf52f92..9518540e0 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -201,7 +201,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			require(4)
 
 			newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64()
-		case CALL:
+		case CALL, CALLSTATELESS:
 			require(7)
 			gas.Set(GasCall)
 			addStepGasUsage(stack.data[stack.Len()-1])
@@ -752,7 +752,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			closure.UseGas(closure.Gas)
 
 			msg := NewMessage(self, addr, input, gas, closure.Price, value)
-			ret, err := msg.Exec(closure)
+			ret, err := msg.Exec(addr, closure)
 			if err != nil {
 				stack.Push(ethutil.BigFalse)
 
@@ -816,7 +816,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			if self.Dbg != nil {
 				self.Dbg.SetCode(closure.Code)
 			}
-		case CALL:
+		case CALL, CALLSTATELESS:
 			require(7)
 
 			self.Endl()
@@ -834,8 +834,15 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 			snapshot := self.env.State().Copy()
 
-			msg := NewMessage(self, addr.Bytes(), args, gas, closure.Price, value)
-			ret, err := msg.Exec(closure)
+			var executeAddr []byte
+			if op == CALLSTATELESS {
+				executeAddr = closure.Address()
+			} else {
+				executeAddr = addr.Bytes()
+			}
+
+			msg := NewMessage(self, executeAddr, args, gas, closure.Price, value)
+			ret, err := msg.Exec(addr.Bytes(), closure)
 			if err != nil {
 				stack.Push(ethutil.BigFalse)
 
@@ -1017,7 +1024,11 @@ func (self *Message) Postpone() {
 	self.vm.queue.PushBack(self)
 }
 
-func (self *Message) Exec(caller ClosureRef) (ret []byte, err error) {
+func (self *Message) Addr() []byte {
+	return self.address
+}
+
+func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err error) {
 	queue := self.vm.queue
 	self.vm.queue = list.New()
 
@@ -1049,8 +1060,11 @@ func (self *Message) Exec(caller ClosureRef) (ret []byte, err error) {
 		caller.Object().SubAmount(self.value)
 		stateObject.AddAmount(self.value)
 
+		// Retrieve the executing code
+		code := self.vm.env.State().GetCode(codeAddr)
+
 		// Create a new callable closure
-		c := NewClosure(msg, caller, object, object.Code, self.gas, self.price)
+		c := NewClosure(msg, caller, object, code, self.gas, self.price)
 		// Executer the closure and get the return value (if any)
 		ret, _, err = c.Call(self.vm, self.input)
 
-- 
cgit v1.2.3


From c0187930dc352c645c223e17364623a68413cb74 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Wed, 10 Sep 2014 11:39:11 +0200
Subject: Removed some commented code

---
 ethvm/vm.go | 91 -------------------------------------------------------------
 1 file changed, 91 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 9518540e0..fba8c4a0e 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -765,51 +765,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 				stack.Push(ethutil.BigD(addr))
 			}
-			/*
-					msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
-						To: addr, From: closure.Address(),
-						Origin: self.env.Origin(),
-						Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
-						Value: value,
-					})
-
-					// Create a new contract
-					contract := self.env.State().NewStateObject(addr)
-					if contract.Balance.Cmp(value) >= 0 {
-						closure.object.SubAmount(value)
-						contract.AddAmount(value)
-
-						// Set the init script
-						initCode := mem.Get(offset.Int64(), size.Int64())
-						msg.Input = initCode
-
-						// Transfer all remaining gas to the new
-						// contract so it may run the init script
-						gas := new(big.Int).Set(closure.Gas)
-						closure.UseGas(closure.Gas)
-
-						// Create the closure
-						c := NewClosure(msg, closure, contract, initCode, gas, closure.Price)
-						// Call the closure and set the return value as
-						// main script.
-						contract.Code, _, err = c.Call(self, nil)
-					} else {
-						err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
-					}
-
-				if err != nil {
-					stack.Push(ethutil.BigFalse)
-
-					// Revert the state as it was before.
-					self.env.State().Set(snapshot)
-
-					self.Printf("CREATE err %v", err)
-				} else {
-					stack.Push(ethutil.BigD(addr))
 
-					msg.Output = contract.Code
-				}
-			*/
 			self.Endl()
 
 			// Debug hook
@@ -858,53 +814,6 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 				self.Dbg.SetCode(closure.Code)
 			}
 
-			/*
-				msg := self.env.State().Manifest().AddMessage(&ethstate.Message{
-					To: addr.Bytes(), From: closure.Address(),
-					Input:  args,
-					Origin: self.env.Origin(),
-					Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
-					Value: value,
-				})
-
-				if closure.object.Balance.Cmp(value) < 0 {
-					vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
-
-					closure.ReturnGas(gas, nil)
-
-					stack.Push(ethutil.BigFalse)
-				} else {
-					snapshot := self.env.State().Copy()
-
-					stateObject := self.env.State().GetOrNewStateObject(addr.Bytes())
-
-					closure.object.SubAmount(value)
-					stateObject.AddAmount(value)
-
-					// Create a new callable closure
-					c := NewClosure(msg, closure, stateObject, stateObject.Code, gas, closure.Price)
-					// Executer the closure and get the return value (if any)
-					ret, _, err := c.Call(self, args)
-					if err != nil {
-						stack.Push(ethutil.BigFalse)
-
-						vmlogger.Debugf("Closure execution failed. %v\n", err)
-
-						self.env.State().Set(snapshot)
-					} else {
-						stack.Push(ethutil.BigTrue)
-
-						mem.Set(retOffset.Int64(), retSize.Int64(), ret)
-					}
-
-					msg.Output = ret
-
-					// Debug hook
-					if self.Dbg != nil {
-						self.Dbg.SetCode(closure.Code)
-					}
-				}
-			*/
 		case POST:
 			require(6)
 
-- 
cgit v1.2.3


From 2f614900e82036e3e8f6f6a714efc43e09aca830 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Mon, 15 Sep 2014 01:11:01 +0200
Subject: Updated GHOST

---
 ethvm/vm.go | 57 +++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 20 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index fba8c4a0e..2c516f4f8 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -3,7 +3,6 @@ package ethvm
 import (
 	"container/list"
 	"fmt"
-	"math"
 	"math/big"
 
 	"github.com/ethereum/eth-go/ethcrypto"
@@ -67,6 +66,19 @@ func New(env Environment) *Vm {
 	return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()}
 }
 
+func calcMemSize(off, l *big.Int) *big.Int {
+	if l.Cmp(ethutil.Big0) == 0 {
+		return ethutil.Big0
+	}
+
+	return new(big.Int).Add(off, l)
+}
+
+// Simple helper
+func u256(n int64) *big.Int {
+	return big.NewInt(n)
+}
+
 func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 	if self.Recoverable {
 		// Recover from any require exception
@@ -147,7 +159,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 		addStepGasUsage(GasStep)
 
-		var newMemSize uint64 = 0
+		var newMemSize *big.Int = ethutil.Big0
 		switch op {
 		case STOP:
 			gas.Set(ethutil.Big0)
@@ -171,57 +183,62 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			gas.Set(GasBalance)
 		case MSTORE:
 			require(2)
-			newMemSize = stack.Peek().Uint64() + 32
+			newMemSize = calcMemSize(stack.Peek(), u256(32))
 		case MLOAD:
 			require(1)
 
-			newMemSize = stack.Peek().Uint64() + 32
+			newMemSize = calcMemSize(stack.Peek(), u256(32))
 		case MSTORE8:
 			require(2)
-			newMemSize = stack.Peek().Uint64() + 1
+			newMemSize = calcMemSize(stack.Peek(), u256(1))
 		case RETURN:
 			require(2)
 
-			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
+			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 		case SHA3:
 			require(2)
 
 			gas.Set(GasSha)
 
-			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
+			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 		case CALLDATACOPY:
 			require(3)
 
-			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
+			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
 		case CODECOPY:
 			require(3)
 
-			newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
+			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
 		case EXTCODECOPY:
 			require(4)
 
-			newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64()
+			newMemSize = calcMemSize(stack.data[stack.Len()-1], stack.data[stack.Len()-4])
 		case CALL, CALLSTATELESS:
 			require(7)
 			gas.Set(GasCall)
 			addStepGasUsage(stack.data[stack.Len()-1])
 
-			x := stack.data[stack.Len()-6].Uint64() + stack.data[stack.Len()-7].Uint64()
-			y := stack.data[stack.Len()-4].Uint64() + stack.data[stack.Len()-5].Uint64()
+			x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
+			y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
 
-			newMemSize = uint64(math.Max(float64(x), float64(y)))
+			newMemSize = ethutil.BigMax(x, y)
 		case CREATE:
 			require(3)
 			gas.Set(GasCreate)
 
-			newMemSize = stack.data[stack.Len()-2].Uint64() + stack.data[stack.Len()-3].Uint64()
+			newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
 		}
 
-		// BUG This will break on overflows. https://github.com/ethereum/eth-go/issues/47
-		newMemSize = (newMemSize + 31) / 32 * 32
-		if newMemSize > uint64(mem.Len()) {
-			m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
-			addStepGasUsage(big.NewInt(int64(m)))
+		if newMemSize.Cmp(ethutil.Big0) > 0 {
+			//newMemSize = (newMemSize + 31) / 32 * 32
+			newMemSize = newMemSize.Add(newMemSize, u256(31)).Div(newMemSize, u256(32)).Mul(newMemSize, u256(32))
+			//if newMemSize > uint64(mem.Len()) {
+			if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
+				newMemSize = newMemSize.Sub(newMemSize, u256(int64(mem.Len())))
+				memGasUsage := newMemSize.Mul(GasMemory, newMemSize).Div(newMemSize, u256(32))
+				//m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
+				addStepGasUsage(memGasUsage)
+			}
 		}
 
 		if !closure.UseGas(gas) {
@@ -235,7 +252,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
 		self.Printf(" (g) %-3v (%v)", gas, closure.Gas)
 
-		mem.Resize(newMemSize)
+		mem.Resize(newMemSize.Uint64())
 
 		switch op {
 		case LOG:
-- 
cgit v1.2.3


From 399256b38403f2e95312250d49fca3cada8956b8 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Mon, 15 Sep 2014 22:11:05 +0200
Subject: VM execution fixes

Refactoring caused executing issues
---
 ethvm/vm.go | 49 +++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 2c516f4f8..cfba3820b 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -63,7 +63,7 @@ func New(env Environment) *Vm {
 		lt = LogTyDiff
 	}
 
-	return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()}
+	return &Vm{env: env, logTy: lt, Recoverable: false, queue: list.New()}
 }
 
 func calcMemSize(off, l *big.Int) *big.Int {
@@ -132,15 +132,13 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		// XXX Leave this Println intact. Don't change this to the log system.
 		// Used for creating diffs between implementations
 		if self.logTy == LogTyDiff {
-			/*
-				switch op {
-				case STOP, RETURN, SUICIDE:
-					closure.object.EachStorage(func(key string, value *ethutil.Value) {
-						value.Decode()
-						fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
-					})
-				}
-			*/
+			switch op {
+			case STOP, RETURN, SUICIDE:
+				closure.object.EachStorage(func(key string, value *ethutil.Value) {
+					value.Decode()
+					fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
+				})
+			}
 
 			b := pc.Bytes()
 			if len(b) == 0 {
@@ -230,13 +228,15 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		}
 
 		if newMemSize.Cmp(ethutil.Big0) > 0 {
-			//newMemSize = (newMemSize + 31) / 32 * 32
-			newMemSize = newMemSize.Add(newMemSize, u256(31)).Div(newMemSize, u256(32)).Mul(newMemSize, u256(32))
-			//if newMemSize > uint64(mem.Len()) {
+			newMemSize.Add(newMemSize, u256(31))
+			newMemSize.Div(newMemSize, u256(32))
+			newMemSize.Mul(newMemSize, u256(32))
+
 			if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
-				newMemSize = newMemSize.Sub(newMemSize, u256(int64(mem.Len())))
-				memGasUsage := newMemSize.Mul(GasMemory, newMemSize).Div(newMemSize, u256(32))
-				//m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
+				memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
+				memGasUsage.Mul(GasMemory, memGasUsage)
+				memGasUsage.Div(memGasUsage, u256(32))
+
 				addStepGasUsage(memGasUsage)
 			}
 		}
@@ -669,12 +669,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			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)
+			n := int(op - DUP1 + 1)
 			stack.Dupn(n)
 
 			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
 		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
-			n := int(op - SWAP1)
+			n := int(op - SWAP1 + 2)
 			x, y := stack.Swapn(n)
 
 			self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
@@ -694,12 +694,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			self.Printf(" => 0x%x", val)
 		case MSTORE8:
 			require(2)
-			val, mStart := stack.Popn()
-			//base.And(val, new(big.Int).SetInt64(0xff))
-			//mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256))
-			mem.store[mStart.Int64()] = byte(val.Int64() & 0xff)
+			off := stack.Pop()
+			val := stack.Pop()
 
-			self.Printf(" => 0x%x", val)
+			mem.store[off.Int64()] = byte(val.Int64() & 0xff)
+
+			self.Printf(" => [%v] 0x%x", off, val)
 		case SLOAD:
 			require(1)
 			loc := stack.Pop()
@@ -955,6 +955,7 @@ func (self *Message) Addr() []byte {
 }
 
 func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err error) {
+	fmt.Printf("%x %x\n", codeAddr[0:4], self.address[0:4])
 	queue := self.vm.queue
 	self.vm.queue = list.New()
 
@@ -990,7 +991,7 @@ func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err e
 		code := self.vm.env.State().GetCode(codeAddr)
 
 		// Create a new callable closure
-		c := NewClosure(msg, caller, object, code, self.gas, self.price)
+		c := NewClosure(msg, caller, stateObject, code, self.gas, self.price)
 		// Executer the closure and get the return value (if any)
 		ret, _, err = c.Call(self.vm, self.input)
 
-- 
cgit v1.2.3


From d02024929a3e617c16c5b33e1d245f23fa4f6c7b Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Tue, 16 Sep 2014 11:35:26 +0200
Subject: require 5 for post

---
 ethvm/vm.go | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index cfba3820b..2a4fddbc5 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -63,7 +63,7 @@ func New(env Environment) *Vm {
 		lt = LogTyDiff
 	}
 
-	return &Vm{env: env, logTy: lt, Recoverable: false, queue: list.New()}
+	return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()}
 }
 
 func calcMemSize(off, l *big.Int) *big.Int {
@@ -200,7 +200,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 
 			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 		case CALLDATACOPY:
-			require(3)
+			require(2)
 
 			newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
 		case CODECOPY:
@@ -210,7 +210,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		case EXTCODECOPY:
 			require(4)
 
-			newMemSize = calcMemSize(stack.data[stack.Len()-1], stack.data[stack.Len()-4])
+			newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
 		case CALL, CALLSTATELESS:
 			require(7)
 			gas.Set(GasCall)
@@ -832,7 +832,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			}
 
 		case POST:
-			require(6)
+			require(5)
 
 			self.Endl()
 
@@ -872,6 +872,9 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		default:
 			vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
 
+			// XXX Really?
+			closure.UseGas(closure.Gas)
+
 			return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
 		}
 
-- 
cgit v1.2.3


From f3a93b046e45a293b673a955959666ec5389c4eb Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Thu, 18 Sep 2014 01:02:15 +0200
Subject: Upped protocol version for VM change

---
 ethvm/vm.go | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index 2a4fddbc5..f1c23b370 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -872,8 +872,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		default:
 			vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
 
-			// XXX Really?
-			closure.UseGas(closure.Gas)
+			//panic(fmt.Sprintf("Invalid opcode %x", op))
 
 			return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
 		}
-- 
cgit v1.2.3


From 80261c803a82e51413608a3dc5273c982844d135 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Fri, 19 Sep 2014 13:19:19 +0200
Subject: Fixed deref ptr

---
 ethvm/vm.go | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

(limited to 'ethvm/vm.go')

diff --git a/ethvm/vm.go b/ethvm/vm.go
index f1c23b370..7aff320f9 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -670,9 +670,13 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 			stack.Pop()
 		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
 			n := int(op - DUP1 + 1)
-			stack.Dupn(n)
+			v := stack.Dupn(n)
 
 			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
+
+			if OpCode(closure.Get(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.Get(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
+				fmt.Println(toValue(v))
+			}
 		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
 			n := int(op - SWAP1 + 2)
 			x, y := stack.Swapn(n)
@@ -1004,3 +1008,14 @@ func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err e
 
 	return
 }
+
+// Mainly used for print variables and passing to Print*
+func toValue(val *big.Int) interface{} {
+	// Let's assume a string on right padded zero's
+	b := val.Bytes()
+	if b[0] != 0 && b[len(b)-1] == 0x0 && b[len(b)-2] == 0x0 {
+		return string(b)
+	}
+
+	return val
+}
-- 
cgit v1.2.3