From 7c6ef0ddac91564f31ef852fd4ef1e821db17c2e Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Wed, 10 Jun 2015 14:38:39 -0400
Subject: Separate and identify tests runners

---
 tests/block_test_util.go       |   3 +-
 tests/state_test.go            |  34 +++---
 tests/state_test_util.go       | 181 ++++++++++++++++++++++++++++++++
 tests/transaction_test_util.go |   2 +-
 tests/vm.go                    | 220 ---------------------------------------
 tests/vm_test_util.go          | 230 +++++++++++++++++++++++++++++++++--------
 6 files changed, 387 insertions(+), 283 deletions(-)
 create mode 100644 tests/state_test_util.go
 delete mode 100644 tests/vm.go

diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 224c14283..e60607c0f 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -134,7 +134,8 @@ func runBlockTest(name string, test *BlockTest, t *testing.T) {
 	if err = test.ValidatePostState(statedb); err != nil {
 		t.Fatal("post state validation failed: %v", err)
 	}
-	t.Log("Test passed: ", name)
+	fmt.Println("Block test passed: ", name)
+	// t.Log("Block test passed: ", name)
 }
 
 func testEthConfig() *eth.Config {
diff --git a/tests/state_test.go b/tests/state_test.go
index fa000ec53..dbef7bd0c 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -10,62 +10,62 @@ var stateTestDir = filepath.Join(baseDir, "StateTests")
 
 func TestStateSystemOperations(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateExample(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stExample.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStatePreCompiledContracts(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateRecursiveCreate(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stRecursiveCreate.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateSpecial(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stSpecialTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateRefund(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stRefundTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateBlockHash(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stBlockHashTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateInitCode(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stInitCodeTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateLog(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stLogTests.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateTransaction(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stTransactionTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestCallCreateCallCode(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestMemory(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stMemoryTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestMemoryStress(t *testing.T) {
@@ -73,7 +73,7 @@ func TestMemoryStress(t *testing.T) {
 		t.Skip()
 	}
 	fn := filepath.Join(stateTestDir, "stMemoryStressTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestQuadraticComplexity(t *testing.T) {
@@ -81,22 +81,22 @@ func TestQuadraticComplexity(t *testing.T) {
 		t.Skip()
 	}
 	fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestSolidity(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stSolidityTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestWallet(t *testing.T) {
 	fn := filepath.Join(stateTestDir, "stWalletTest.json")
-	RunVmTest(fn, t)
+	RunStateTest(fn, t)
 }
 
 func TestStateTestsRandom(t *testing.T) {
 	fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
 	for _, fn := range fns {
-		RunVmTest(fn, t)
+		RunStateTest(fn, t)
 	}
 }
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
new file mode 100644
index 000000000..1f481147e
--- /dev/null
+++ b/tests/state_test_util.go
@@ -0,0 +1,181 @@
+package tests
+
+import (
+	"bytes"
+	// "errors"
+	"fmt"
+	"math/big"
+	"strconv"
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/core/state"
+	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/ethdb"
+	// "github.com/ethereum/go-ethereum/logger"
+)
+
+func RunStateTest(p string, t *testing.T) {
+
+	tests := make(map[string]VmTest)
+	CreateFileTests(t, p, &tests)
+
+	for name, test := range tests {
+		/*
+		   vm.Debug = true
+		   glog.SetV(4)
+		   glog.SetToStderr(true)
+		   if name != "Call50000_sha256" {
+		     continue
+		   }
+		*/
+		db, _ := ethdb.NewMemDatabase()
+		statedb := state.New(common.Hash{}, db)
+		for addr, account := range test.Pre {
+			obj := StateObjectFromAccount(db, addr, account)
+			statedb.SetStateObject(obj)
+			for a, v := range account.Storage {
+				obj.SetState(common.HexToHash(a), common.NewValue(common.FromHex(v)))
+			}
+		}
+
+		// XXX Yeah, yeah...
+		env := make(map[string]string)
+		env["currentCoinbase"] = test.Env.CurrentCoinbase
+		env["currentDifficulty"] = test.Env.CurrentDifficulty
+		env["currentGasLimit"] = test.Env.CurrentGasLimit
+		env["currentNumber"] = test.Env.CurrentNumber
+		env["previousHash"] = test.Env.PreviousHash
+		if n, ok := test.Env.CurrentTimestamp.(float64); ok {
+			env["currentTimestamp"] = strconv.Itoa(int(n))
+		} else {
+			env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
+		}
+
+		var (
+			ret []byte
+			// gas  *big.Int
+			// err  error
+			logs state.Logs
+		)
+
+		ret, logs, _, _ = RunState(statedb, env, test.Transaction)
+
+		switch name {
+		// the memory required for these tests (4294967297 bytes) would take too much time.
+		// on 19 May 2015 decided to skip these tests their output.
+		case "mload32bitBound_return", "mload32bitBound_return2":
+		default:
+			rexp := common.FromHex(test.Out)
+			if bytes.Compare(rexp, ret) != 0 {
+				t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
+			}
+		}
+
+		for addr, account := range test.Post {
+			obj := statedb.GetStateObject(common.HexToAddress(addr))
+			if obj == nil {
+				continue
+			}
+
+			// if len(test.Exec) == 0 {
+			if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
+				t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
+			}
+
+			// if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
+			//  t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
+			// }
+
+			// }
+
+			for addr, value := range account.Storage {
+				v := obj.GetState(common.HexToHash(addr)).Bytes()
+				vexp := common.FromHex(value)
+
+				if bytes.Compare(v, vexp) != 0 {
+					t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v))
+				}
+			}
+		}
+
+		statedb.Sync()
+		//if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
+		if common.HexToHash(test.PostStateRoot) != statedb.Root() {
+			t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
+		}
+
+		if len(test.Logs) > 0 {
+			if len(test.Logs) != len(logs) {
+				t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs))
+			} else {
+				for i, log := range test.Logs {
+					if common.HexToAddress(log.AddressF) != logs[i].Address {
+						t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address)
+					}
+
+					if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) {
+						t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data)
+					}
+
+					if len(log.TopicsF) != len(logs[i].Topics) {
+						t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
+					} else {
+						for j, topic := range log.TopicsF {
+							if common.HexToHash(topic) != logs[i].Topics[j] {
+								t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j])
+							}
+						}
+					}
+					genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256)
+
+					if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
+						t.Errorf("'%s' bloom mismatch", name)
+					}
+				}
+			}
+		}
+
+		fmt.Println("State test passed: ", name)
+		//fmt.Println(string(statedb.Dump()))
+	}
+	// logger.Flush()
+}
+
+func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
+	var (
+		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
+		data       = common.FromHex(tx["data"])
+		gas        = common.Big(tx["gasLimit"])
+		price      = common.Big(tx["gasPrice"])
+		value      = common.Big(tx["value"])
+		nonce      = common.Big(tx["nonce"]).Uint64()
+		caddr      = common.HexToAddress(env["currentCoinbase"])
+	)
+
+	var to *common.Address
+	if len(tx["to"]) > 2 {
+		t := common.HexToAddress(tx["to"])
+		to = &t
+	}
+	// Set pre compiled contracts
+	vm.Precompiled = vm.PrecompiledContracts()
+
+	snapshot := statedb.Copy()
+	coinbase := statedb.GetOrNewStateObject(caddr)
+	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))
+
+	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
+	vmenv := NewEnvFromMap(statedb, env, tx)
+	vmenv.origin = common.BytesToAddress(keyPair.Address())
+	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
+	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) {
+		statedb.Set(snapshot)
+	}
+	statedb.Update()
+
+	return ret, vmenv.state.Logs(), vmenv.Gas, err
+}
diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go
index 82038c3e8..a6cea972a 100644
--- a/tests/transaction_test_util.go
+++ b/tests/transaction_test_util.go
@@ -42,7 +42,7 @@ func RunTransactionTests(file string, notWorking map[string]bool) error {
 			if err = runTest(in); err != nil {
 				return fmt.Errorf("bad test %s: %v", name, err)
 			}
-			fmt.Println("Test passed:", name)
+			fmt.Println("Transaction test passed:", name)
 		}
 	}
 	return nil
diff --git a/tests/vm.go b/tests/vm.go
deleted file mode 100644
index 52e498ccc..000000000
--- a/tests/vm.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package tests
-
-import (
-	"errors"
-	"math/big"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/vm"
-	"github.com/ethereum/go-ethereum/crypto"
-)
-
-type Env struct {
-	depth        int
-	state        *state.StateDB
-	skipTransfer bool
-	initial      bool
-	Gas          *big.Int
-
-	origin common.Address
-	//parent   common.Hash
-	coinbase common.Address
-
-	number     *big.Int
-	time       int64
-	difficulty *big.Int
-	gasLimit   *big.Int
-
-	vmTest bool
-	logs   []vm.StructLog
-}
-
-func NewEnv(state *state.StateDB) *Env {
-	return &Env{
-		state: state,
-	}
-}
-
-func (self *Env) StructLogs() []vm.StructLog {
-	return self.logs
-}
-
-func (self *Env) AddStructLog(log vm.StructLog) {
-	self.logs = append(self.logs, log)
-}
-
-func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
-	env := NewEnv(state)
-
-	env.origin = common.HexToAddress(exeValues["caller"])
-	//env.parent = common.Hex2Bytes(envValues["previousHash"])
-	env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
-	env.number = common.Big(envValues["currentNumber"])
-	env.time = common.Big(envValues["currentTimestamp"]).Int64()
-	env.difficulty = common.Big(envValues["currentDifficulty"])
-	env.gasLimit = common.Big(envValues["currentGasLimit"])
-	env.Gas = new(big.Int)
-
-	return env
-}
-
-func (self *Env) Origin() common.Address { return self.origin }
-func (self *Env) BlockNumber() *big.Int  { return self.number }
-
-//func (self *Env) PrevHash() []byte      { return self.parent }
-func (self *Env) Coinbase() common.Address { return self.coinbase }
-func (self *Env) Time() int64              { return self.time }
-func (self *Env) Difficulty() *big.Int     { return self.difficulty }
-func (self *Env) State() *state.StateDB    { return self.state }
-func (self *Env) GasLimit() *big.Int       { return self.gasLimit }
-func (self *Env) VmType() vm.Type          { return vm.StdVmTy }
-func (self *Env) GetHash(n uint64) common.Hash {
-	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
-}
-func (self *Env) AddLog(log *state.Log) {
-	self.state.AddLog(log)
-}
-func (self *Env) Depth() int     { return self.depth }
-func (self *Env) SetDepth(i int) { self.depth = i }
-func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
-	if self.skipTransfer {
-		// ugly hack
-		if self.initial {
-			self.initial = false
-			return nil
-		}
-
-		if from.Balance().Cmp(amount) < 0 {
-			return errors.New("Insufficient balance in account")
-		}
-
-		return nil
-	}
-	return vm.Transfer(from, to, amount)
-}
-
-func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
-	exec := core.NewExecution(self, addr, data, gas, price, value)
-
-	return exec
-}
-
-func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
-	if self.vmTest && self.depth > 0 {
-		caller.ReturnGas(gas, price)
-
-		return nil, nil
-	}
-	exe := self.vm(&addr, data, gas, price, value)
-	ret, err := exe.Call(addr, caller)
-	self.Gas = exe.Gas
-
-	return ret, err
-
-}
-func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
-	if self.vmTest && self.depth > 0 {
-		caller.ReturnGas(gas, price)
-
-		return nil, nil
-	}
-
-	caddr := caller.Address()
-	exe := self.vm(&caddr, data, gas, price, value)
-	return exe.Call(addr, caller)
-}
-
-func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
-	exe := self.vm(nil, data, gas, price, value)
-	if self.vmTest {
-		caller.ReturnGas(gas, price)
-
-		nonce := self.state.GetNonce(caller.Address())
-		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))
-
-		return nil, nil, obj
-	} else {
-		return exe.Create(caller)
-	}
-}
-
-func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
-	var (
-		to    = common.HexToAddress(exec["address"])
-		from  = common.HexToAddress(exec["caller"])
-		data  = common.FromHex(exec["data"])
-		gas   = common.Big(exec["gas"])
-		price = common.Big(exec["gasPrice"])
-		value = common.Big(exec["value"])
-	)
-	// Reset the pre-compiled contracts for VM tests.
-	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
-
-	caller := state.GetOrNewStateObject(from)
-
-	vmenv := NewEnvFromMap(state, env, exec)
-	vmenv.vmTest = true
-	vmenv.skipTransfer = true
-	vmenv.initial = true
-	ret, err := vmenv.Call(caller, to, data, gas, price, value)
-
-	return ret, vmenv.state.Logs(), vmenv.Gas, err
-}
-
-func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
-	var (
-		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
-		data       = common.FromHex(tx["data"])
-		gas        = common.Big(tx["gasLimit"])
-		price      = common.Big(tx["gasPrice"])
-		value      = common.Big(tx["value"])
-		nonce      = common.Big(tx["nonce"]).Uint64()
-		caddr      = common.HexToAddress(env["currentCoinbase"])
-	)
-
-	var to *common.Address
-	if len(tx["to"]) > 2 {
-		t := common.HexToAddress(tx["to"])
-		to = &t
-	}
-	// Set pre compiled contracts
-	vm.Precompiled = vm.PrecompiledContracts()
-
-	snapshot := statedb.Copy()
-	coinbase := statedb.GetOrNewStateObject(caddr)
-	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))
-
-	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
-	vmenv := NewEnvFromMap(statedb, env, tx)
-	vmenv.origin = common.BytesToAddress(keyPair.Address())
-	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
-	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) {
-		statedb.Set(snapshot)
-	}
-	statedb.Update()
-
-	return ret, vmenv.state.Logs(), vmenv.Gas, err
-}
-
-type Message struct {
-	from              common.Address
-	to                *common.Address
-	value, gas, price *big.Int
-	data              []byte
-	nonce             uint64
-}
-
-func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
-	return Message{from, to, value, gas, price, data, nonce}
-}
-
-func (self Message) Hash() []byte                  { return nil }
-func (self Message) From() (common.Address, error) { return self.from, nil }
-func (self Message) To() *common.Address           { return self.to }
-func (self Message) GasPrice() *big.Int            { return self.price }
-func (self Message) Gas() *big.Int                 { return self.gas }
-func (self Message) Value() *big.Int               { return self.value }
-func (self Message) Nonce() uint64                 { return self.nonce }
-func (self Message) Data() []byte                  { return self.data }
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
index cf95db80f..3852ba4bf 100644
--- a/tests/vm_test_util.go
+++ b/tests/vm_test_util.go
@@ -2,15 +2,20 @@ package tests
 
 import (
 	"bytes"
+	"errors"
+	"fmt"
 	"math/big"
 	"strconv"
 	"testing"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/ethdb"
-	"github.com/ethereum/go-ethereum/logger"
+	// "github.com/ethereum/go-ethereum/logger"
 )
 
 type Account struct {
@@ -118,32 +123,19 @@ func RunVmTest(p string, t *testing.T) {
 			logs state.Logs
 		)
 
-		isVmTest := len(test.Exec) > 0
-		if isVmTest {
-			ret, logs, gas, err = RunVm(statedb, env, test.Exec)
-		} else {
-			ret, logs, gas, err = RunState(statedb, env, test.Transaction)
-		}
+		ret, logs, gas, err = RunVm(statedb, env, test.Exec)
 
-		switch name {
-		// the memory required for these tests (4294967297 bytes) would take too much time.
-		// on 19 May 2015 decided to skip these tests their output.
-		case "mload32bitBound_return", "mload32bitBound_return2":
-		default:
-			rexp := common.FromHex(test.Out)
-			if bytes.Compare(rexp, ret) != 0 {
-				t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
-			}
+		rexp := common.FromHex(test.Out)
+		if bytes.Compare(rexp, ret) != 0 {
+			t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
 		}
 
-		if isVmTest {
-			if len(test.Gas) == 0 && err == nil {
-				t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
-			} else {
-				gexp := common.Big(test.Gas)
-				if gexp.Cmp(gas) != 0 {
-					t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
-				}
+		if len(test.Gas) == 0 && err == nil {
+			t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
+		} else {
+			gexp := common.Big(test.Gas)
+			if gexp.Cmp(gas) != 0 {
+				t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
 			}
 		}
 
@@ -153,17 +145,6 @@ func RunVmTest(p string, t *testing.T) {
 				continue
 			}
 
-			if len(test.Exec) == 0 {
-				if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
-					t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
-				}
-
-				if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
-					t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
-				}
-
-			}
-
 			for addr, value := range account.Storage {
 				v := obj.GetState(common.HexToHash(addr))
 				vexp := common.HexToHash(value)
@@ -174,14 +155,6 @@ func RunVmTest(p string, t *testing.T) {
 			}
 		}
 
-		if !isVmTest {
-			statedb.Sync()
-			//if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
-			if common.HexToHash(test.PostStateRoot) != statedb.Root() {
-				t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
-			}
-		}
-
 		if len(test.Logs) > 0 {
 			if len(test.Logs) != len(logs) {
 				t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs))
@@ -212,7 +185,176 @@ func RunVmTest(p string, t *testing.T) {
 				}
 			}
 		}
+
+		fmt.Println("VM test passed: ", name)
+
 		//fmt.Println(string(statedb.Dump()))
 	}
-	logger.Flush()
+	// logger.Flush()
+}
+
+type Env struct {
+	depth        int
+	state        *state.StateDB
+	skipTransfer bool
+	initial      bool
+	Gas          *big.Int
+
+	origin common.Address
+	//parent   common.Hash
+	coinbase common.Address
+
+	number     *big.Int
+	time       int64
+	difficulty *big.Int
+	gasLimit   *big.Int
+
+	logs state.Logs
+
+	vmTest bool
+}
+
+func NewEnv(state *state.StateDB) *Env {
+	return &Env{
+		state: state,
+	}
+}
+
+func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
+	env := NewEnv(state)
+
+	env.origin = common.HexToAddress(exeValues["caller"])
+	//env.parent = common.Hex2Bytes(envValues["previousHash"])
+	env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
+	env.number = common.Big(envValues["currentNumber"])
+	env.time = common.Big(envValues["currentTimestamp"]).Int64()
+	env.difficulty = common.Big(envValues["currentDifficulty"])
+	env.gasLimit = common.Big(envValues["currentGasLimit"])
+	env.Gas = new(big.Int)
+
+	return env
+}
+
+func (self *Env) Origin() common.Address { return self.origin }
+func (self *Env) BlockNumber() *big.Int  { return self.number }
+
+//func (self *Env) PrevHash() []byte      { return self.parent }
+func (self *Env) Coinbase() common.Address { return self.coinbase }
+func (self *Env) Time() int64              { return self.time }
+func (self *Env) Difficulty() *big.Int     { return self.difficulty }
+func (self *Env) State() *state.StateDB    { return self.state }
+func (self *Env) GasLimit() *big.Int       { return self.gasLimit }
+func (self *Env) VmType() vm.Type          { return vm.StdVmTy }
+func (self *Env) GetHash(n uint64) common.Hash {
+	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
+}
+func (self *Env) AddLog(log *state.Log) {
+	self.state.AddLog(log)
+}
+func (self *Env) Depth() int     { return self.depth }
+func (self *Env) SetDepth(i int) { self.depth = i }
+func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
+	if self.skipTransfer {
+		// ugly hack
+		if self.initial {
+			self.initial = false
+			return nil
+		}
+
+		if from.Balance().Cmp(amount) < 0 {
+			return errors.New("Insufficient balance in account")
+		}
+
+		return nil
+	}
+	return vm.Transfer(from, to, amount)
+}
+
+func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
+	exec := core.NewExecution(self, addr, data, gas, price, value)
+
+	return exec
+}
+
+func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
+	if self.vmTest && self.depth > 0 {
+		caller.ReturnGas(gas, price)
+
+		return nil, nil
+	}
+	exe := self.vm(&addr, data, gas, price, value)
+	ret, err := exe.Call(addr, caller)
+	self.Gas = exe.Gas
+
+	return ret, err
+
+}
+func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
+	if self.vmTest && self.depth > 0 {
+		caller.ReturnGas(gas, price)
+
+		return nil, nil
+	}
+
+	caddr := caller.Address()
+	exe := self.vm(&caddr, data, gas, price, value)
+	return exe.Call(addr, caller)
 }
+
+func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
+	exe := self.vm(nil, data, gas, price, value)
+	if self.vmTest {
+		caller.ReturnGas(gas, price)
+
+		nonce := self.state.GetNonce(caller.Address())
+		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))
+
+		return nil, nil, obj
+	} else {
+		return exe.Create(caller)
+	}
+}
+
+func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
+	var (
+		to    = common.HexToAddress(exec["address"])
+		from  = common.HexToAddress(exec["caller"])
+		data  = common.FromHex(exec["data"])
+		gas   = common.Big(exec["gas"])
+		price = common.Big(exec["gasPrice"])
+		value = common.Big(exec["value"])
+	)
+	// Reset the pre-compiled contracts for VM tests.
+	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
+
+	caller := state.GetOrNewStateObject(from)
+
+	vmenv := NewEnvFromMap(state, env, exec)
+	vmenv.vmTest = true
+	vmenv.skipTransfer = true
+	vmenv.initial = true
+	ret, err := vmenv.Call(caller, to, data, gas, price, value)
+
+	return ret, vmenv.state.Logs(), vmenv.Gas, err
+}
+
+type Message struct {
+	from              common.Address
+	to                *common.Address
+	value, gas, price *big.Int
+	data              []byte
+	nonce             uint64
+}
+
+func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
+	return Message{from, to, value, gas, price, data, nonce}
+}
+
+func (self Message) Hash() []byte                  { return nil }
+func (self Message) From() (common.Address, error) { return self.from, nil }
+func (self Message) To() *common.Address           { return self.to }
+func (self Message) GasPrice() *big.Int            { return self.price }
+func (self Message) Gas() *big.Int                 { return self.gas }
+func (self Message) Value() *big.Int               { return self.value }
+func (self Message) Nonce() uint64                 { return self.nonce }
+func (self Message) Data() []byte                  { return self.data }
-- 
cgit v1.2.3