github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/cmd/ethtest/main.go (about) 1 /* 2 This file is part of go-ethereum 3 4 go-ethereum is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 go-ethereum is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 /** 18 * @authors: 19 * Jeffrey Wilcke <i@jev.io> 20 */ 21 22 package main 23 24 import ( 25 "bytes" 26 "encoding/json" 27 "io" 28 "io/ioutil" 29 "log" 30 "os" 31 "strings" 32 33 "github.com/jonasnick/go-ethereum/ethdb" 34 "github.com/jonasnick/go-ethereum/ethutil" 35 "github.com/jonasnick/go-ethereum/logger" 36 "github.com/jonasnick/go-ethereum/state" 37 "github.com/jonasnick/go-ethereum/tests/helper" 38 ) 39 40 type Account struct { 41 Balance string 42 Code string 43 Nonce string 44 Storage map[string]string 45 } 46 47 func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject { 48 obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db) 49 obj.SetBalance(ethutil.Big(account.Balance)) 50 51 if ethutil.IsHex(account.Code) { 52 account.Code = account.Code[2:] 53 } 54 obj.Code = ethutil.Hex2Bytes(account.Code) 55 obj.Nonce = ethutil.Big(account.Nonce).Uint64() 56 57 return obj 58 } 59 60 type VmTest struct { 61 Callcreates interface{} 62 Env map[string]string 63 Exec map[string]string 64 Gas string 65 Out string 66 Post map[string]Account 67 Pre map[string]Account 68 } 69 70 func RunVmTest(r io.Reader) (failed int) { 71 tests := make(map[string]VmTest) 72 73 data, _ := ioutil.ReadAll(r) 74 err := json.Unmarshal(data, &tests) 75 if err != nil { 76 log.Fatalln(err) 77 } 78 79 for name, test := range tests { 80 db, _ := ethdb.NewMemDatabase() 81 state := state.New(nil, db) 82 for addr, account := range test.Pre { 83 obj := StateObjectFromAccount(db, addr, account) 84 state.SetStateObject(obj) 85 } 86 87 ret, _, gas, err := helper.RunVm(state, test.Env, test.Exec) 88 // When an error is returned it doesn't always mean the tests fails. 89 // Have to come up with some conditional failing mechanism. 90 if err != nil { 91 log.Println(err) 92 } 93 94 rexp := helper.FromHex(test.Out) 95 if bytes.Compare(rexp, ret) != 0 { 96 log.Printf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) 97 failed = 1 98 } 99 100 if len(test.Gas) == 0 && err == nil { 101 log.Printf("0 gas indicates error but no error given by VM") 102 failed = 1 103 } else { 104 gexp := ethutil.Big(test.Gas) 105 if gexp.Cmp(gas) != 0 { 106 log.Printf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) 107 failed = 1 108 } 109 } 110 111 for addr, account := range test.Post { 112 obj := state.GetStateObject(helper.FromHex(addr)) 113 for addr, value := range account.Storage { 114 v := obj.GetState(helper.FromHex(addr)).Bytes() 115 vexp := helper.FromHex(value) 116 117 if bytes.Compare(v, vexp) != 0 { 118 log.Printf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address()[0:4], addr, vexp, v, ethutil.BigD(vexp), ethutil.BigD(v)) 119 failed = 1 120 } 121 } 122 } 123 124 logger.Flush() 125 } 126 127 return 128 } 129 130 func main() { 131 helper.Logger.SetLogLevel(5) 132 133 if len(os.Args) > 1 { 134 os.Exit(RunVmTest(strings.NewReader(os.Args[1]))) 135 } else { 136 os.Exit(RunVmTest(os.Stdin)) 137 } 138 }