github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/tests/block_test_util.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser 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 // The go-ethereum library 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 Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package tests 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "io" 24 "math/big" 25 "path/filepath" 26 "runtime" 27 "strconv" 28 "strings" 29 "time" 30 31 "github.com/ethereum/go-ethereum/accounts" 32 "github.com/ethereum/go-ethereum/common" 33 "github.com/ethereum/go-ethereum/core" 34 "github.com/ethereum/go-ethereum/core/state" 35 "github.com/ethereum/go-ethereum/core/types" 36 "github.com/ethereum/go-ethereum/crypto" 37 "github.com/ethereum/go-ethereum/eth" 38 "github.com/ethereum/go-ethereum/ethdb" 39 "github.com/ethereum/go-ethereum/logger/glog" 40 "github.com/ethereum/go-ethereum/rlp" 41 ) 42 43 // Block Test JSON Format 44 type BlockTest struct { 45 Genesis *types.Block 46 47 Json *btJSON 48 preAccounts map[string]btAccount 49 } 50 51 type btJSON struct { 52 Blocks []btBlock 53 GenesisBlockHeader btHeader 54 Pre map[string]btAccount 55 PostState map[string]btAccount 56 } 57 58 type btBlock struct { 59 BlockHeader *btHeader 60 Rlp string 61 Transactions []btTransaction 62 UncleHeaders []*btHeader 63 } 64 65 type btAccount struct { 66 Balance string 67 Code string 68 Nonce string 69 Storage map[string]string 70 PrivateKey string 71 } 72 73 type btHeader struct { 74 Bloom string 75 Coinbase string 76 MixHash string 77 Nonce string 78 Number string 79 ParentHash string 80 ReceiptTrie string 81 SeedHash string 82 StateRoot string 83 TransactionsTrie string 84 UncleHash string 85 86 ExtraData string 87 Difficulty string 88 GasLimit string 89 GasUsed string 90 Timestamp string 91 } 92 93 type btTransaction struct { 94 Data string 95 GasLimit string 96 GasPrice string 97 Nonce string 98 R string 99 S string 100 To string 101 V string 102 Value string 103 } 104 105 func RunBlockTestWithReader(r io.Reader, skipTests []string) error { 106 btjs := make(map[string]*btJSON) 107 if err := readJson(r, &btjs); err != nil { 108 return err 109 } 110 111 bt, err := convertBlockTests(btjs) 112 if err != nil { 113 return err 114 } 115 116 if err := runBlockTests(bt, skipTests); err != nil { 117 return err 118 } 119 return nil 120 } 121 122 func RunBlockTest(file string, skipTests []string) error { 123 btjs := make(map[string]*btJSON) 124 if err := readJsonFile(file, &btjs); err != nil { 125 return err 126 } 127 128 bt, err := convertBlockTests(btjs) 129 if err != nil { 130 return err 131 } 132 if err := runBlockTests(bt, skipTests); err != nil { 133 return err 134 } 135 return nil 136 } 137 138 func runBlockTests(bt map[string]*BlockTest, skipTests []string) error { 139 skipTest := make(map[string]bool, len(skipTests)) 140 for _, name := range skipTests { 141 skipTest[name] = true 142 } 143 144 for name, test := range bt { 145 // if the test should be skipped, return 146 if skipTest[name] { 147 glog.Infoln("Skipping block test", name) 148 continue 149 } 150 151 // test the block 152 if err := runBlockTest(test); err != nil { 153 return fmt.Errorf("%s: %v", name, err) 154 } 155 glog.Infoln("Block test passed: ", name) 156 157 } 158 return nil 159 160 } 161 func runBlockTest(test *BlockTest) error { 162 cfg := test.makeEthConfig() 163 cfg.GenesisBlock = test.Genesis 164 165 ethereum, err := eth.New(cfg) 166 if err != nil { 167 return err 168 } 169 170 err = ethereum.Start() 171 if err != nil { 172 return err 173 } 174 175 // import pre accounts 176 statedb, err := test.InsertPreState(ethereum) 177 if err != nil { 178 return fmt.Errorf("InsertPreState: %v", err) 179 } 180 181 err = test.TryBlocksInsert(ethereum.ChainManager()) 182 if err != nil { 183 return err 184 } 185 186 if err = test.ValidatePostState(statedb); err != nil { 187 return fmt.Errorf("post state validation failed: %v", err) 188 } 189 return nil 190 } 191 192 func (test *BlockTest) makeEthConfig() *eth.Config { 193 ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore")) 194 195 return ð.Config{ 196 DataDir: common.DefaultDataDir(), 197 Verbosity: 5, 198 Etherbase: common.Address{}, 199 AccountManager: accounts.NewManager(ks), 200 NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, 201 } 202 } 203 204 // InsertPreState populates the given database with the genesis 205 // accounts defined by the test. 206 func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, error) { 207 db := ethereum.ChainDb() 208 statedb := state.New(common.Hash{}, db) 209 for addrString, acct := range t.preAccounts { 210 addr, err := hex.DecodeString(addrString) 211 if err != nil { 212 return nil, err 213 } 214 code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x")) 215 if err != nil { 216 return nil, err 217 } 218 balance, ok := new(big.Int).SetString(acct.Balance, 0) 219 if !ok { 220 return nil, err 221 } 222 nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64) 223 if err != nil { 224 return nil, err 225 } 226 227 if acct.PrivateKey != "" { 228 privkey, err := hex.DecodeString(strings.TrimPrefix(acct.PrivateKey, "0x")) 229 err = crypto.ImportBlockTestKey(privkey) 230 err = ethereum.AccountManager().TimedUnlock(common.BytesToAddress(addr), "", 999999*time.Second) 231 if err != nil { 232 return nil, err 233 } 234 } 235 236 obj := statedb.CreateAccount(common.HexToAddress(addrString)) 237 obj.SetCode(code) 238 obj.SetBalance(balance) 239 obj.SetNonce(nonce) 240 for k, v := range acct.Storage { 241 statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v)) 242 } 243 } 244 // sync objects to trie 245 statedb.SyncObjects() 246 // sync trie to disk 247 statedb.Sync() 248 249 if !bytes.Equal(t.Genesis.Root().Bytes(), statedb.Root().Bytes()) { 250 return nil, fmt.Errorf("computed state root does not match genesis block %x %x", t.Genesis.Root().Bytes()[:4], statedb.Root().Bytes()[:4]) 251 } 252 return statedb, nil 253 } 254 255 /* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II 256 257 Whether a block is valid or not is a bit subtle, it's defined by presence of 258 blockHeader, transactions and uncleHeaders fields. If they are missing, the block is 259 invalid and we must verify that we do not accept it. 260 261 Since some tests mix valid and invalid blocks we need to check this for every block. 262 263 If a block is invalid it does not necessarily fail the test, if it's invalidness is 264 expected we are expected to ignore it and continue processing and then validate the 265 post state. 266 */ 267 func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error { 268 // insert the test blocks, which will execute all transactions 269 for _, b := range t.Json.Blocks { 270 cb, err := mustConvertBlock(b) 271 if err != nil { 272 if b.BlockHeader == nil { 273 continue // OK - block is supposed to be invalid, continue with next block 274 } else { 275 return fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err) 276 } 277 } 278 // RLP decoding worked, try to insert into chain: 279 _, err = chainManager.InsertChain(types.Blocks{cb}) 280 if err != nil { 281 if b.BlockHeader == nil { 282 continue // OK - block is supposed to be invalid, continue with next block 283 } else { 284 return fmt.Errorf("Block insertion into chain failed: %v", err) 285 } 286 } 287 if b.BlockHeader == nil { 288 return fmt.Errorf("Block insertion should have failed") 289 } 290 err = t.validateBlockHeader(b.BlockHeader, cb.Header()) 291 if err != nil { 292 return fmt.Errorf("Block header validation failed: %v", err) 293 } 294 } 295 return nil 296 } 297 298 func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error { 299 expectedBloom := mustConvertBytes(h.Bloom) 300 if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) { 301 return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes()) 302 } 303 304 expectedCoinbase := mustConvertBytes(h.Coinbase) 305 if !bytes.Equal(expectedCoinbase, h2.Coinbase.Bytes()) { 306 return fmt.Errorf("Coinbase: expected: %v, decoded: %v", expectedCoinbase, h2.Coinbase.Bytes()) 307 } 308 309 expectedMixHashBytes := mustConvertBytes(h.MixHash) 310 if !bytes.Equal(expectedMixHashBytes, h2.MixDigest.Bytes()) { 311 return fmt.Errorf("MixHash: expected: %v, decoded: %v", expectedMixHashBytes, h2.MixDigest.Bytes()) 312 } 313 314 expectedNonce := mustConvertBytes(h.Nonce) 315 if !bytes.Equal(expectedNonce, h2.Nonce[:]) { 316 return fmt.Errorf("Nonce: expected: %v, decoded: %v", expectedNonce, h2.Nonce) 317 } 318 319 expectedNumber := mustConvertBigInt(h.Number, 16) 320 if expectedNumber.Cmp(h2.Number) != 0 { 321 return fmt.Errorf("Number: expected: %v, decoded: %v", expectedNumber, h2.Number) 322 } 323 324 expectedParentHash := mustConvertBytes(h.ParentHash) 325 if !bytes.Equal(expectedParentHash, h2.ParentHash.Bytes()) { 326 return fmt.Errorf("Parent hash: expected: %v, decoded: %v", expectedParentHash, h2.ParentHash.Bytes()) 327 } 328 329 expectedReceiptHash := mustConvertBytes(h.ReceiptTrie) 330 if !bytes.Equal(expectedReceiptHash, h2.ReceiptHash.Bytes()) { 331 return fmt.Errorf("Receipt hash: expected: %v, decoded: %v", expectedReceiptHash, h2.ReceiptHash.Bytes()) 332 } 333 334 expectedTxHash := mustConvertBytes(h.TransactionsTrie) 335 if !bytes.Equal(expectedTxHash, h2.TxHash.Bytes()) { 336 return fmt.Errorf("Tx hash: expected: %v, decoded: %v", expectedTxHash, h2.TxHash.Bytes()) 337 } 338 339 expectedStateHash := mustConvertBytes(h.StateRoot) 340 if !bytes.Equal(expectedStateHash, h2.Root.Bytes()) { 341 return fmt.Errorf("State hash: expected: %v, decoded: %v", expectedStateHash, h2.Root.Bytes()) 342 } 343 344 expectedUncleHash := mustConvertBytes(h.UncleHash) 345 if !bytes.Equal(expectedUncleHash, h2.UncleHash.Bytes()) { 346 return fmt.Errorf("Uncle hash: expected: %v, decoded: %v", expectedUncleHash, h2.UncleHash.Bytes()) 347 } 348 349 expectedExtraData := mustConvertBytes(h.ExtraData) 350 if !bytes.Equal(expectedExtraData, h2.Extra) { 351 return fmt.Errorf("Extra data: expected: %v, decoded: %v", expectedExtraData, h2.Extra) 352 } 353 354 expectedDifficulty := mustConvertBigInt(h.Difficulty, 16) 355 if expectedDifficulty.Cmp(h2.Difficulty) != 0 { 356 return fmt.Errorf("Difficulty: expected: %v, decoded: %v", expectedDifficulty, h2.Difficulty) 357 } 358 359 expectedGasLimit := mustConvertBigInt(h.GasLimit, 16) 360 if expectedGasLimit.Cmp(h2.GasLimit) != 0 { 361 return fmt.Errorf("GasLimit: expected: %v, decoded: %v", expectedGasLimit, h2.GasLimit) 362 } 363 expectedGasUsed := mustConvertBigInt(h.GasUsed, 16) 364 if expectedGasUsed.Cmp(h2.GasUsed) != 0 { 365 return fmt.Errorf("GasUsed: expected: %v, decoded: %v", expectedGasUsed, h2.GasUsed) 366 } 367 368 expectedTimestamp := mustConvertBigInt(h.Timestamp, 16) 369 if expectedTimestamp.Cmp(h2.Time) != 0 { 370 return fmt.Errorf("Timestamp: expected: %v, decoded: %v", expectedTimestamp, h2.Time) 371 } 372 373 return nil 374 } 375 376 func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error { 377 for addrString, acct := range t.preAccounts { 378 // XXX: is is worth it checking for errors here? 379 addr, err := hex.DecodeString(addrString) 380 if err != nil { 381 return err 382 } 383 code, err := hex.DecodeString(strings.TrimPrefix(acct.Code, "0x")) 384 if err != nil { 385 return err 386 } 387 balance, ok := new(big.Int).SetString(acct.Balance, 0) 388 if !ok { 389 return err 390 } 391 nonce, err := strconv.ParseUint(prepInt(16, acct.Nonce), 16, 64) 392 if err != nil { 393 return err 394 } 395 396 // address is indirectly verified by the other fields, as it's the db key 397 code2 := statedb.GetCode(common.BytesToAddress(addr)) 398 balance2 := statedb.GetBalance(common.BytesToAddress(addr)) 399 nonce2 := statedb.GetNonce(common.BytesToAddress(addr)) 400 if !bytes.Equal(code2, code) { 401 return fmt.Errorf("account code mismatch, addr, found, expected: ", addrString, hex.EncodeToString(code2), hex.EncodeToString(code)) 402 } 403 if balance2.Cmp(balance) != 0 { 404 return fmt.Errorf("account balance mismatch, addr, found, expected: ", addrString, balance2, balance) 405 } 406 if nonce2 != nonce { 407 return fmt.Errorf("account nonce mismatch, addr, found, expected: ", addrString, nonce2, nonce) 408 } 409 } 410 return nil 411 } 412 413 func convertBlockTests(in map[string]*btJSON) (map[string]*BlockTest, error) { 414 out := make(map[string]*BlockTest) 415 for name, test := range in { 416 var err error 417 if out[name], err = convertBlockTest(test); err != nil { 418 return out, fmt.Errorf("bad test %q: %v", name, err) 419 } 420 } 421 return out, nil 422 } 423 424 func convertBlockTest(in *btJSON) (out *BlockTest, err error) { 425 // the conversion handles errors by catching panics. 426 // you might consider this ugly, but the alternative (passing errors) 427 // would be much harder to read. 428 defer func() { 429 if recovered := recover(); recovered != nil { 430 buf := make([]byte, 64<<10) 431 buf = buf[:runtime.Stack(buf, false)] 432 err = fmt.Errorf("%v\n%s", recovered, buf) 433 } 434 }() 435 out = &BlockTest{preAccounts: in.Pre, Json: in} 436 out.Genesis = mustConvertGenesis(in.GenesisBlockHeader) 437 return out, err 438 } 439 440 func mustConvertGenesis(testGenesis btHeader) *types.Block { 441 hdr := mustConvertHeader(testGenesis) 442 hdr.Number = big.NewInt(0) 443 b := types.NewBlockWithHeader(hdr) 444 b.Td = new(big.Int) 445 return b 446 } 447 448 func mustConvertHeader(in btHeader) *types.Header { 449 // hex decode these fields 450 header := &types.Header{ 451 //SeedHash: mustConvertBytes(in.SeedHash), 452 MixDigest: mustConvertHash(in.MixHash), 453 Bloom: mustConvertBloom(in.Bloom), 454 ReceiptHash: mustConvertHash(in.ReceiptTrie), 455 TxHash: mustConvertHash(in.TransactionsTrie), 456 Root: mustConvertHash(in.StateRoot), 457 Coinbase: mustConvertAddress(in.Coinbase), 458 UncleHash: mustConvertHash(in.UncleHash), 459 ParentHash: mustConvertHash(in.ParentHash), 460 Extra: mustConvertBytes(in.ExtraData), 461 GasUsed: mustConvertBigInt(in.GasUsed, 16), 462 GasLimit: mustConvertBigInt(in.GasLimit, 16), 463 Difficulty: mustConvertBigInt(in.Difficulty, 16), 464 Time: mustConvertBigInt(in.Timestamp, 16), 465 Nonce: types.EncodeNonce(mustConvertUint(in.Nonce, 16)), 466 } 467 return header 468 } 469 470 func mustConvertBlock(testBlock btBlock) (*types.Block, error) { 471 var b types.Block 472 r := bytes.NewReader(mustConvertBytes(testBlock.Rlp)) 473 err := rlp.Decode(r, &b) 474 return &b, err 475 } 476 477 func mustConvertBytes(in string) []byte { 478 if in == "0x" { 479 return []byte{} 480 } 481 h := unfuckFuckedHex(strings.TrimPrefix(in, "0x")) 482 out, err := hex.DecodeString(h) 483 if err != nil { 484 panic(fmt.Errorf("invalid hex: %q: ", h, err)) 485 } 486 return out 487 } 488 489 func mustConvertHash(in string) common.Hash { 490 out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) 491 if err != nil { 492 panic(fmt.Errorf("invalid hex: %q", in)) 493 } 494 return common.BytesToHash(out) 495 } 496 497 func mustConvertAddress(in string) common.Address { 498 out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) 499 if err != nil { 500 panic(fmt.Errorf("invalid hex: %q", in)) 501 } 502 return common.BytesToAddress(out) 503 } 504 505 func mustConvertBloom(in string) types.Bloom { 506 out, err := hex.DecodeString(strings.TrimPrefix(in, "0x")) 507 if err != nil { 508 panic(fmt.Errorf("invalid hex: %q", in)) 509 } 510 return types.BytesToBloom(out) 511 } 512 513 func mustConvertBigInt(in string, base int) *big.Int { 514 in = prepInt(base, in) 515 out, ok := new(big.Int).SetString(in, base) 516 if !ok { 517 panic(fmt.Errorf("invalid integer: %q", in)) 518 } 519 return out 520 } 521 522 func mustConvertUint(in string, base int) uint64 { 523 in = prepInt(base, in) 524 out, err := strconv.ParseUint(in, base, 64) 525 if err != nil { 526 panic(fmt.Errorf("invalid integer: %q", in)) 527 } 528 return out 529 } 530 531 func LoadBlockTests(file string) (map[string]*BlockTest, error) { 532 btjs := make(map[string]*btJSON) 533 if err := readJsonFile(file, &btjs); err != nil { 534 return nil, err 535 } 536 537 return convertBlockTests(btjs) 538 } 539 540 // Nothing to see here, please move along... 541 func prepInt(base int, s string) string { 542 if base == 16 { 543 if strings.HasPrefix(s, "0x") { 544 s = s[2:] 545 } 546 if len(s) == 0 { 547 s = "00" 548 } 549 s = nibbleFix(s) 550 } 551 return s 552 } 553 554 // don't ask 555 func unfuckFuckedHex(almostHex string) string { 556 return nibbleFix(strings.Replace(almostHex, "v", "", -1)) 557 } 558 559 func nibbleFix(s string) string { 560 if len(s)%2 != 0 { 561 s = "0" + s 562 } 563 return s 564 }