aboutsummaryrefslogtreecommitdiffstats
path: root/tests/helper
diff options
context:
space:
mode:
Diffstat (limited to 'tests/helper')
-rw-r--r--tests/helper/common.go11
-rw-r--r--tests/helper/init.go20
-rw-r--r--tests/helper/readers.go42
-rw-r--r--tests/helper/trie.go31
-rw-r--r--tests/helper/vm.go156
5 files changed, 260 insertions, 0 deletions
diff --git a/tests/helper/common.go b/tests/helper/common.go
new file mode 100644
index 000000000..6a071968d
--- /dev/null
+++ b/tests/helper/common.go
@@ -0,0 +1,11 @@
+package helper
+
+import "github.com/ethereum/go-ethereum/ethutil"
+
+func FromHex(h string) []byte {
+ if ethutil.IsHex(h) {
+ h = h[2:]
+ }
+
+ return ethutil.Hex2Bytes(h)
+}
diff --git a/tests/helper/init.go b/tests/helper/init.go
new file mode 100644
index 000000000..578314e20
--- /dev/null
+++ b/tests/helper/init.go
@@ -0,0 +1,20 @@
+package helper
+
+import (
+ "log"
+ "os"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+ logpkg "github.com/ethereum/go-ethereum/logger"
+)
+
+var Logger logpkg.LogSystem
+var Log = logpkg.NewLogger("TEST")
+
+func init() {
+ Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel)
+ logpkg.AddLogSystem(Logger)
+
+ ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
+ ethutil.Config.Db, _ = NewMemDatabase()
+}
diff --git a/tests/helper/readers.go b/tests/helper/readers.go
new file mode 100644
index 000000000..03313aeda
--- /dev/null
+++ b/tests/helper/readers.go
@@ -0,0 +1,42 @@
+package helper
+
+import (
+ "encoding/json"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "testing"
+)
+
+func readJSON(t *testing.T, reader io.Reader, value interface{}) {
+ data, err := ioutil.ReadAll(reader)
+ err = json.Unmarshal(data, &value)
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func CreateHttpTests(t *testing.T, uri string, value interface{}) {
+ resp, err := http.Get(uri)
+ if err != nil {
+ t.Error(err)
+
+ return
+ }
+ defer resp.Body.Close()
+
+ readJSON(t, resp.Body, value)
+}
+
+func CreateFileTests(t *testing.T, fn string, value interface{}) {
+ file, err := os.Open(fn)
+ if err != nil {
+ t.Error(err)
+
+ return
+ }
+ defer file.Close()
+
+ readJSON(t, file, value)
+}
diff --git a/tests/helper/trie.go b/tests/helper/trie.go
new file mode 100644
index 000000000..32432cc7a
--- /dev/null
+++ b/tests/helper/trie.go
@@ -0,0 +1,31 @@
+package helper
+
+import "github.com/ethereum/go-ethereum/trie"
+
+type MemDatabase struct {
+ db map[string][]byte
+}
+
+func NewMemDatabase() (*MemDatabase, error) {
+ db := &MemDatabase{db: make(map[string][]byte)}
+ return db, nil
+}
+func (db *MemDatabase) Put(key []byte, value []byte) {
+ db.db[string(key)] = value
+}
+func (db *MemDatabase) Get(key []byte) ([]byte, error) {
+ return db.db[string(key)], nil
+}
+func (db *MemDatabase) Delete(key []byte) error {
+ delete(db.db, string(key))
+ return nil
+}
+func (db *MemDatabase) Print() {}
+func (db *MemDatabase) Close() {}
+func (db *MemDatabase) LastKnownTD() []byte { return nil }
+
+func NewTrie() *trie.Trie {
+ db, _ := NewMemDatabase()
+
+ return trie.New(db, "")
+}
diff --git a/tests/helper/vm.go b/tests/helper/vm.go
new file mode 100644
index 000000000..e174e0892
--- /dev/null
+++ b/tests/helper/vm.go
@@ -0,0 +1,156 @@
+package helper
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/state"
+ "github.com/ethereum/go-ethereum/vm"
+)
+
+type Env struct {
+ depth int
+ state *state.StateDB
+ skipTransfer bool
+ Gas *big.Int
+
+ origin []byte
+ parent []byte
+ coinbase []byte
+
+ number *big.Int
+ time int64
+ difficulty *big.Int
+ gasLimit *big.Int
+
+ logs state.Logs
+}
+
+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 = ethutil.Hex2Bytes(exeValues["caller"])
+ env.parent = ethutil.Hex2Bytes(envValues["previousHash"])
+ env.coinbase = ethutil.Hex2Bytes(envValues["currentCoinbase"])
+ env.number = ethutil.Big(envValues["currentNumber"])
+ env.time = ethutil.Big(envValues["currentTimestamp"]).Int64()
+ env.difficulty = ethutil.Big(envValues["currentDifficulty"])
+ env.gasLimit = ethutil.Big(envValues["currentGasLimit"])
+ env.Gas = new(big.Int)
+
+ return env
+}
+
+func (self *Env) Origin() []byte { return self.origin }
+func (self *Env) BlockNumber() *big.Int { return self.number }
+func (self *Env) PrevHash() []byte { return self.parent }
+func (self *Env) Coinbase() []byte { return self.coinbase }
+func (self *Env) Time() int64 { return self.time }
+func (self *Env) Difficulty() *big.Int { return self.difficulty }
+func (self *Env) BlockHash() []byte { return nil }
+func (self *Env) State() *state.StateDB { return self.state }
+func (self *Env) GasLimit() *big.Int { return self.gasLimit }
+func (self *Env) AddLog(log state.Log) {
+ self.logs = append(self.logs, 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 {
+ return vm.Transfer(from, to, amount)
+}
+
+func (self *Env) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution {
+ exec := core.NewExecution(self, addr, data, gas, price, value)
+ exec.SkipTransfer = self.skipTransfer
+
+ return exec
+}
+
+func (self *Env) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ 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.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) {
+ exe := self.vm(caller.Address(), data, gas, price, value)
+ return exe.Call(addr, caller)
+}
+
+func (self *Env) Create(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ClosureRef) {
+ exe := self.vm(addr, data, gas, price, value)
+ return exe.Create(caller)
+}
+
+func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
+ var (
+ to = FromHex(exec["address"])
+ from = FromHex(exec["caller"])
+ data = FromHex(exec["data"])
+ gas = ethutil.Big(exec["gas"])
+ price = ethutil.Big(exec["gasPrice"])
+ value = ethutil.Big(exec["value"])
+ )
+
+ caller := state.GetOrNewStateObject(from)
+
+ vmenv := NewEnvFromMap(state, env, exec)
+ vmenv.skipTransfer = true
+ ret, err := vmenv.Call(caller, to, data, gas, price, value)
+
+ return ret, vmenv.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(ethutil.Hex2Bytes(tx["secretKey"])))
+ to = FromHex(tx["to"])
+ data = FromHex(tx["data"])
+ gas = ethutil.Big(tx["gasLimit"])
+ price = ethutil.Big(tx["gasPrice"])
+ value = ethutil.Big(tx["value"])
+ caddr = FromHex(env["currentCoinbase"])
+ )
+
+ coinbase := statedb.GetOrNewStateObject(caddr)
+ coinbase.SetGasPool(ethutil.Big(env["currentGasLimit"]))
+
+ message := NewMessage(keyPair.Address(), to, data, value, gas, price)
+ Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
+ st := core.NewStateTransition(coinbase, message, statedb, nil)
+ vmenv := NewEnvFromMap(statedb, env, tx)
+ vmenv.origin = keyPair.Address()
+ st.Env = vmenv
+ ret, err := st.TransitionState()
+ statedb.Update(vmenv.Gas)
+
+ return ret, vmenv.logs, vmenv.Gas, err
+}
+
+type Message struct {
+ from, to []byte
+ value, gas, price *big.Int
+ data []byte
+}
+
+func NewMessage(from, to, data []byte, value, gas, price *big.Int) Message {
+ return Message{from, to, value, gas, price, data}
+}
+
+func (self Message) Hash() []byte { return nil }
+func (self Message) From() []byte { return self.from }
+func (self Message) To() []byte { 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 0 }
+func (self Message) Data() []byte { return self.data }