|
|
@@ -3,6 +3,7 @@ package tests
|
|
|
import (
|
|
|
"bytes"
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
"math/big"
|
|
|
"strconv"
|
|
|
|
|
|
@@ -15,100 +16,133 @@ import (
|
|
|
"github.com/ethereum/go-ethereum/logger/glog"
|
|
|
)
|
|
|
|
|
|
-func RunStateTest(p string) error {
|
|
|
- skipTest := make(map[string]bool, len(stateSkipTests))
|
|
|
- for _, name := range stateSkipTests {
|
|
|
- skipTest[name] = true
|
|
|
+func RunStateTestWithReader(r io.Reader) error {
|
|
|
+ tests := make(map[string]VmTest)
|
|
|
+ if err := readJson(r, &tests); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
+ if err := runStateTests(tests); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func RunStateTest(p string) error {
|
|
|
tests := make(map[string]VmTest)
|
|
|
- readTestFile(p, &tests)
|
|
|
+ if err := readJsonFile(p, &tests); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := runStateTests(tests); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func runStateTests(tests map[string]VmTest) error {
|
|
|
+ skipTest := make(map[string]bool, len(StateSkipTests))
|
|
|
+ for _, name := range StateSkipTests {
|
|
|
+ skipTest[name] = true
|
|
|
+ }
|
|
|
|
|
|
for name, test := range tests {
|
|
|
if skipTest[name] {
|
|
|
glog.Infoln("Skipping state test", name)
|
|
|
return nil
|
|
|
}
|
|
|
- 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.HexToHash(s))
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- // 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)
|
|
|
+ if err := runStateTest(test); err != nil {
|
|
|
+ return fmt.Errorf("%s: %s\n", name, err.Error())
|
|
|
}
|
|
|
|
|
|
- var (
|
|
|
- ret []byte
|
|
|
- // gas *big.Int
|
|
|
- // err error
|
|
|
- logs state.Logs
|
|
|
- )
|
|
|
+ glog.Infoln("State test passed: ", name)
|
|
|
+ //fmt.Println(string(statedb.Dump()))
|
|
|
+ }
|
|
|
+ return nil
|
|
|
|
|
|
- ret, logs, _, _ = RunState(statedb, env, test.Transaction)
|
|
|
+}
|
|
|
|
|
|
- // // Compare expected and actual return
|
|
|
- rexp := common.FromHex(test.Out)
|
|
|
- if bytes.Compare(rexp, ret) != 0 {
|
|
|
- return fmt.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
|
|
|
+func runStateTest(test VmTest) error {
|
|
|
+ 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.HexToHash(v))
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // check post state
|
|
|
- for addr, account := range test.Post {
|
|
|
- obj := statedb.GetStateObject(common.HexToAddress(addr))
|
|
|
- if obj == nil {
|
|
|
- continue
|
|
|
- }
|
|
|
+ // 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)
|
|
|
+ }
|
|
|
|
|
|
- if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
|
|
|
- return fmt.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()))
|
|
|
- }
|
|
|
+ var (
|
|
|
+ ret []byte
|
|
|
+ // gas *big.Int
|
|
|
+ // err error
|
|
|
+ logs state.Logs
|
|
|
+ )
|
|
|
|
|
|
- if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
|
|
|
- return fmt.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
|
|
|
- }
|
|
|
+ ret, logs, _, _ = RunState(statedb, env, test.Transaction)
|
|
|
+
|
|
|
+ // // Compare expected and actual return
|
|
|
+ rexp := common.FromHex(test.Out)
|
|
|
+ if bytes.Compare(rexp, ret) != 0 {
|
|
|
+ return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret)
|
|
|
+ }
|
|
|
|
|
|
- for addr, value := range account.Storage {
|
|
|
- v := obj.GetState(common.HexToHash(addr)).Bytes()
|
|
|
- vexp := common.FromHex(value)
|
|
|
+ // check post state
|
|
|
+ for addr, account := range test.Post {
|
|
|
+ obj := statedb.GetStateObject(common.HexToAddress(addr))
|
|
|
+ if obj == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
|
|
|
- if bytes.Compare(v, vexp) != 0 {
|
|
|
- return fmt.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))
|
|
|
- }
|
|
|
- }
|
|
|
+ if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
|
|
|
+ return fmt.Errorf("(%x) balance failed. Expected %v, got %v => %v\n", obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
|
|
|
}
|
|
|
|
|
|
- statedb.Sync()
|
|
|
- //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
|
|
|
- if common.HexToHash(test.PostStateRoot) != statedb.Root() {
|
|
|
- return fmt.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
|
|
|
+ if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
|
|
|
+ return fmt.Errorf("(%x) nonce failed. Expected %v, got %v\n", obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
|
|
|
}
|
|
|
|
|
|
- // check logs
|
|
|
- if len(test.Logs) > 0 {
|
|
|
- lerr := checkLogs(test.Logs, logs)
|
|
|
- if lerr != nil {
|
|
|
- return fmt.Errorf("'%s' ", name, lerr.Error())
|
|
|
+ for addr, value := range account.Storage {
|
|
|
+ v := obj.GetState(common.HexToHash(addr)).Bytes()
|
|
|
+ vexp := common.FromHex(value)
|
|
|
+
|
|
|
+ if bytes.Compare(v, vexp) != 0 {
|
|
|
+ return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v))
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- glog.Infoln("State test passed: ", name)
|
|
|
- //fmt.Println(string(statedb.Dump()))
|
|
|
+ statedb.Sync()
|
|
|
+ //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
|
|
|
+ if common.HexToHash(test.PostStateRoot) != statedb.Root() {
|
|
|
+ return fmt.Errorf("Post state root error. Expected %s, got %x", test.PostStateRoot, statedb.Root())
|
|
|
}
|
|
|
+
|
|
|
+ // check logs
|
|
|
+ if len(test.Logs) > 0 {
|
|
|
+ if err := checkLogs(test.Logs, logs); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return nil
|
|
|
}
|
|
|
|