github.com/karalabe/go-ethereum@v0.8.5/tests/vm/gh_test.go (about) 1 package vm 2 3 import ( 4 "bytes" 5 "math/big" 6 "strconv" 7 "testing" 8 9 "github.com/ethereum/go-ethereum/core/types" 10 "github.com/ethereum/go-ethereum/ethdb" 11 "github.com/ethereum/go-ethereum/ethutil" 12 "github.com/ethereum/go-ethereum/logger" 13 "github.com/ethereum/go-ethereum/state" 14 "github.com/ethereum/go-ethereum/tests/helper" 15 ) 16 17 type Account struct { 18 Balance string 19 Code string 20 Nonce string 21 Storage map[string]string 22 } 23 24 type Log struct { 25 AddressF string `json:"address"` 26 DataF string `json:"data"` 27 TopicsF []string `json:"topics"` 28 BloomF string `json:"bloom"` 29 } 30 31 func (self Log) Address() []byte { return ethutil.Hex2Bytes(self.AddressF) } 32 func (self Log) Data() []byte { return ethutil.Hex2Bytes(self.DataF) } 33 func (self Log) RlpData() interface{} { return nil } 34 func (self Log) Topics() [][]byte { 35 t := make([][]byte, len(self.TopicsF)) 36 for i, topic := range self.TopicsF { 37 t[i] = ethutil.Hex2Bytes(topic) 38 } 39 return t 40 } 41 42 func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject { 43 obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db) 44 obj.SetBalance(ethutil.Big(account.Balance)) 45 46 if ethutil.IsHex(account.Code) { 47 account.Code = account.Code[2:] 48 } 49 obj.SetCode(ethutil.Hex2Bytes(account.Code)) 50 obj.SetNonce(ethutil.Big(account.Nonce).Uint64()) 51 52 return obj 53 } 54 55 type Env struct { 56 CurrentCoinbase string 57 CurrentDifficulty string 58 CurrentGasLimit string 59 CurrentNumber string 60 CurrentTimestamp interface{} 61 PreviousHash string 62 } 63 64 type VmTest struct { 65 Callcreates interface{} 66 //Env map[string]string 67 Env Env 68 Exec map[string]string 69 Transaction map[string]string 70 Logs []Log 71 Gas string 72 Out string 73 Post map[string]Account 74 Pre map[string]Account 75 } 76 77 func RunVmTest(p string, t *testing.T) { 78 tests := make(map[string]VmTest) 79 helper.CreateFileTests(t, p, &tests) 80 81 for name, test := range tests { 82 helper.Logger.SetLogLevel(4) 83 if name != "TransactionNonceCheck2" { 84 continue 85 } 86 db, _ := ethdb.NewMemDatabase() 87 statedb := state.New(nil, db) 88 for addr, account := range test.Pre { 89 obj := StateObjectFromAccount(db, addr, account) 90 statedb.SetStateObject(obj) 91 for a, v := range account.Storage { 92 obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v))) 93 } 94 } 95 96 // XXX Yeah, yeah... 97 env := make(map[string]string) 98 env["currentCoinbase"] = test.Env.CurrentCoinbase 99 env["currentDifficulty"] = test.Env.CurrentDifficulty 100 env["currentGasLimit"] = test.Env.CurrentGasLimit 101 env["currentNumber"] = test.Env.CurrentNumber 102 env["previousHash"] = test.Env.PreviousHash 103 if n, ok := test.Env.CurrentTimestamp.(float64); ok { 104 env["currentTimestamp"] = strconv.Itoa(int(n)) 105 } else { 106 env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) 107 } 108 109 var ( 110 ret []byte 111 gas *big.Int 112 err error 113 logs state.Logs 114 ) 115 116 isVmTest := len(test.Exec) > 0 117 if isVmTest { 118 ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) 119 } else { 120 ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) 121 } 122 123 rexp := helper.FromHex(test.Out) 124 if bytes.Compare(rexp, ret) != 0 { 125 t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) 126 } 127 128 if isVmTest { 129 if len(test.Gas) == 0 && err == nil { 130 t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) 131 } else { 132 gexp := ethutil.Big(test.Gas) 133 if gexp.Cmp(gas) != 0 { 134 t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) 135 } 136 } 137 } 138 139 for addr, account := range test.Post { 140 obj := statedb.GetStateObject(helper.FromHex(addr)) 141 if obj == nil { 142 continue 143 } 144 145 if len(test.Exec) == 0 { 146 if obj.Balance().Cmp(ethutil.Big(account.Balance)) != 0 { 147 t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(ethutil.Big(account.Balance), obj.Balance())) 148 } 149 } 150 151 for addr, value := range account.Storage { 152 v := obj.GetState(helper.FromHex(addr)).Bytes() 153 vexp := helper.FromHex(value) 154 155 if bytes.Compare(v, vexp) != 0 { 156 t.Errorf("%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)) 157 } 158 } 159 } 160 161 if len(test.Logs) > 0 { 162 for i, log := range test.Logs { 163 genBloom := ethutil.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 64) 164 if !bytes.Equal(genBloom, ethutil.Hex2Bytes(log.BloomF)) { 165 t.Errorf("bloom mismatch") 166 } 167 } 168 } 169 } 170 logger.Flush() 171 } 172 173 // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. 174 func TestVMArithmetic(t *testing.T) { 175 const fn = "../files/VMTests/vmArithmeticTest.json" 176 RunVmTest(fn, t) 177 } 178 179 func TestSystemOperations(t *testing.T) { 180 const fn = "../files/VMTests/vmSystemOperationsTest.json" 181 RunVmTest(fn, t) 182 } 183 184 func TestBitwiseLogicOperation(t *testing.T) { 185 const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json" 186 RunVmTest(fn, t) 187 } 188 189 func TestBlockInfo(t *testing.T) { 190 const fn = "../files/VMTests/vmBlockInfoTest.json" 191 RunVmTest(fn, t) 192 } 193 194 func TestEnvironmentalInfo(t *testing.T) { 195 const fn = "../files/VMTests/vmEnvironmentalInfoTest.json" 196 RunVmTest(fn, t) 197 } 198 199 func TestFlowOperation(t *testing.T) { 200 const fn = "../files/VMTests/vmIOandFlowOperationsTest.json" 201 RunVmTest(fn, t) 202 } 203 204 func TestPushDupSwap(t *testing.T) { 205 const fn = "../files/VMTests/vmPushDupSwapTest.json" 206 RunVmTest(fn, t) 207 } 208 209 func TestVMSha3(t *testing.T) { 210 const fn = "../files/VMTests/vmSha3Test.json" 211 RunVmTest(fn, t) 212 } 213 214 func TestVm(t *testing.T) { 215 const fn = "../files/VMTests/vmtests.json" 216 RunVmTest(fn, t) 217 } 218 219 func TestVmLog(t *testing.T) { 220 const fn = "../files/VMTests/vmLogTest.json" 221 RunVmTest(fn, t) 222 } 223 224 func TestStateSystemOperations(t *testing.T) { 225 const fn = "../files/StateTests/stSystemOperationsTest.json" 226 RunVmTest(fn, t) 227 } 228 229 func TestStatePreCompiledContracts(t *testing.T) { 230 const fn = "../files/StateTests/stPreCompiledContracts.json" 231 RunVmTest(fn, t) 232 } 233 234 func TestStateRecursiveCreate(t *testing.T) { 235 const fn = "../files/StateTests/stRecursiveCreate.json" 236 RunVmTest(fn, t) 237 } 238 239 func TestStateSpecial(t *testing.T) { 240 const fn = "../files/StateTests/stSpecialTest.json" 241 RunVmTest(fn, t) 242 } 243 244 func TestStateRefund(t *testing.T) { 245 const fn = "../files/StateTests/stRefundTest.json" 246 RunVmTest(fn, t) 247 } 248 249 func TestStateBlockHash(t *testing.T) { 250 const fn = "../files/StateTests/stBlockHashTest.json" 251 RunVmTest(fn, t) 252 } 253 254 func TestStateInitCode(t *testing.T) { 255 const fn = "../files/StateTests/stInitCodeTest.json" 256 RunVmTest(fn, t) 257 } 258 259 func TestStateLog(t *testing.T) { 260 const fn = "../files/StateTests/stLogTests.json" 261 RunVmTest(fn, t) 262 } 263 264 func TestStateTransaction(t *testing.T) { 265 t.Skip() 266 const fn = "../files/StateTests/stTransactionTest.json" 267 RunVmTest(fn, t) 268 }